KiCad PCB EDA Suite
footprint_editor_utils.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
28 #include <fctsys.h>
29 #include <kiface_i.h>
30 #include <kiway.h>
31 #include <kiway_express.h>
32 #include <class_drawpanel.h>
33 #include <pcb_draw_panel_gal.h>
34 #include <confirm.h>
35 #include <gestfich.h>
36 #include <pgm_base.h>
37 #include <trigo.h>
39 #include <kicad_device_context.h>
40 #include <macros.h>
41 #include <invoke_pcb_dialog.h>
42 #include <pcb_layer_widget.h>
43 #include <board_commit.h>
44 #include <view/view.h>
45 #include <class_board.h>
46 #include <class_module.h>
47 #include <class_edge_mod.h>
48 
49 #include <ratsnest_data.h>
50 #include <pcbnew.h>
51 #include <protos.h>
52 #include <pcbnew_id.h>
53 #include <footprint_edit_frame.h>
54 #include <footprint_viewer_frame.h>
55 #include <footprint_tree_pane.h>
56 #include <fp_lib_table.h>
57 #include <widgets/lib_tree.h>
58 #include <collectors.h>
59 #include <tool/tool_manager.h>
60 #include <tools/pcb_actions.h>
61 
63 #include <dialog_move_exact.h>
64 #include <dialog_create_array.h>
66 #include <menus_helpers.h>
67 #include <footprint_wizard_frame.h>
68 #include <config_params.h>
69 
70 #include <functional>
71 using namespace std::placeholders;
72 
73 
74 // Functions defined in block_module_editor, but used here
75 // These 3 functions are used in modedit to rotate, mirror or move the
76 // whole footprint so they are called with force_all = true
77 void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
78 void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
79 void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
80  const wxPoint& translation, double rotation,
81  bool force_all = false );
82 
83 
85 {
86  BOARD_ITEM* item = GetCurItem();
87 
88  if( GetBoard()->m_Modules == NULL )
89  return NULL;
90 
91  GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
92 
93  // Assign to scanList the proper item types desired based on tool type
94  // or hotkey that is in play.
95 
96  const KICAD_T* scanList = NULL;
97 
98  if( aHotKeyCode )
99  {
100  // @todo: add switch here and add calls to PcbGeneralLocateAndDisplay(
101  // int aHotKeyCode ) when searching is needed from a hotkey handler
102  }
103  else
104  {
106  }
107 
108  m_Collector->Collect( GetBoard(), scanList, RefPos( true ), guide );
109 
110  // Remove redundancies: when an item is found, we can remove the module from list
111  if( m_Collector->GetCount() > 1 )
112  {
113  for( int ii = 0; ii < m_Collector->GetCount(); ii++ )
114  {
115  item = (*m_Collector)[ii];
116 
117  if( item->Type() != PCB_MODULE_T )
118  continue;
119 
120  m_Collector->Remove( ii );
121  ii--;
122  }
123  }
124 
125  if( m_Collector->GetCount() <= 1 )
126  {
127  item = (*m_Collector)[0];
128  SetCurItem( item );
129  }
130  else // we can't figure out which item user wants, do popup menu so user can choose
131  {
132  wxMenu itemMenu;
133 
134  // Give a title to the selection menu. It also allows one to close the popup menu without any action
135  AddMenuItem( &itemMenu, wxID_NONE, _( "Clarify Selection" ),
136  KiBitmap( info_xpm ) );
137  itemMenu.AppendSeparator();
138 
139  int limit = std::min( MAX_ITEMS_IN_PICKER, m_Collector->GetCount() );
140 
141  for( int ii = 0; ii<limit; ++ii )
142  {
143  item = (*m_Collector)[ii];
144 
145  wxString text = item->GetSelectMenuText( GetUserUnits() );
146  BITMAP_DEF xpm = item->GetMenuImage();
147 
148  AddMenuItem( &itemMenu,
150  text,
151  KiBitmap( xpm ) );
152  }
153 
154  // this menu's handler is void
155  // PCB_BASE_FRAME::ProcessItemSelection()
156  // and it calls SetCurItem() which in turn calls DisplayInfo() on the
157  // item.
158  m_canvas->SetAbortRequest( true ); // changed in false if an item is selected
159  PopupMenu( &itemMenu ); // m_AbortRequest = false if an item is selected
160 
161  m_canvas->MoveCursorToCrossHair();
162  m_canvas->SetIgnoreMouseEvents( false );
163 
164  // The function ProcessItemSelection() has set the current item, return it.
165  item = GetCurItem();
166  }
167 
168  if( item )
169  {
170  SetMsgPanel( item );
171  }
172 
173  return item;
174 }
175 
176 
177 void FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard( wxCommandEvent& event )
178 {
179  Load_Module_From_BOARD( NULL );
180 }
181 
182 
184 {
185  MODULE* module = LoadFootprint( aFPID );
186 
187  if( !module )
188  return;
189 
190  if( !Clear_Pcb( true ) )
191  return;
192 
193  SetCrossHairPosition( wxPoint( 0, 0 ) );
194  AddModuleToBoard( module );
195 
196  if( GetBoard()->m_Modules )
197  {
199 
200  // if either m_Reference or m_Value are gone, reinstall them -
201  // otherwise you cannot see what you are doing on board
203  TEXTE_MODULE* val = &GetBoard()->m_Modules->Value();
204 
205  if( val && ref )
206  {
207  ref->SetType( TEXTE_MODULE::TEXT_is_REFERENCE ); // just in case ...
208 
209  if( ref->GetLength() == 0 )
210  ref->SetText( wxT( "Ref**" ) );
211 
212  val->SetType( TEXTE_MODULE::TEXT_is_VALUE ); // just in case ...
213 
214  if( val->GetLength() == 0 )
215  val->SetText( wxT( "Val**" ) );
216  }
217  }
218 
219  Zoom_Automatique( false );
220 
221  Update3DView();
222 
223  GetScreen()->ClrModify();
224 
225  updateView();
226  m_canvas->Refresh();
227 
228  m_treePane->GetLibTree()->ExpandLibId( aFPID );
229  m_treePane->GetLibTree()->CenterLibId( aFPID );
230  m_treePane->GetLibTree()->Refresh(); // update highlighting
231 }
232 
233 
235 {
236  int id = event.GetId();
237  wxPoint pos;
238 
239  INSTALL_UNBUFFERED_DC( dc, m_canvas );
240 
241  wxGetMousePosition( &pos.x, &pos.y );
242 
243  pos.y += 20;
244 
245  switch( id )
246  {
247  case wxID_CUT:
248  case wxID_COPY:
269  case ID_POPUP_ZOOM_BLOCK:
273  break;
274 
276  default:
277  if( m_canvas->IsMouseCaptured() )
278  {
279  // for all other commands: stop the move in progress
280  m_canvas->CallEndMouseCapture( &dc );
281  }
282 
284  SetNoToolSelected();
285 
286  break;
287  }
288 
289  switch( id )
290  {
291  case ID_EXIT:
292  Close( true );
293  break;
294 
296  {
298 
299  if( !viewer )
300  {
302  viewer->Show( true );
303  viewer->Zoom_Automatique( false );
304  }
305  else
306  {
307  // On Windows, Raise() does not bring the window on screen, when iconized
308  if( viewer->IsIconized() )
309  viewer->Iconize( false );
310 
311  viewer->Raise();
312 
313  // Raising the window does not set the focus on Linux. This should work on
314  // any platform.
315  if( wxWindow::FindFocus() != viewer )
316  viewer->SetFocus();
317  }
318  }
319  break;
320 
322  if( DeleteModuleFromLibrary( getTargetFPID(), true ) )
323  {
324  if( getTargetFPID() == GetLoadedFPID() )
325  Clear_Pcb( false );
326 
327  SyncLibraryTree( true );
328  }
329  break;
330 
332  {
333  LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId();
334  MODULE* module = CreateNewModule( wxEmptyString );
335 
336  if( !module )
337  break;
338 
339  if( !Clear_Pcb( true ) )
340  break;
341 
342  SetCrossHairPosition( wxPoint( 0, 0 ) );
343  AddModuleToBoard( module );
344 
345  // Initialize data relative to nets and netclasses (for a new
346  // module the defaults are used)
347  // This is mandatory to handle and draw pads
349  module->SetPosition( wxPoint( 0, 0 ) );
350 
351  if( GetBoard()->m_Modules )
353 
354  Zoom_Automatique( false );
355  GetScreen()->SetModify();
356 
357  // If selected from the library tree then go ahead and save it there
358  if( !selected.GetLibNickname().empty() )
359  {
360  LIB_ID fpid = module->GetFPID();
361  fpid.SetLibNickname( selected.GetLibNickname() );
362  module->SetFPID( fpid );
363  SaveFootprint( module );
364  GetScreen()->ClrModify();
365  }
366 
367  updateView();
368  m_canvas->Refresh();
369  Update3DView();
370 
371  SyncLibraryTree( false );
372  }
373  break;
374 
376  {
377  LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId();
378 
379  if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
380  {
381  if( !HandleUnsavedChanges( this, _( "The current footprint has been modified. Save changes?" ),
382  [&]()->bool { return SaveFootprint( GetBoard()->m_Modules ); } ) )
383  {
384  break;
385  }
386  }
387 
389  FRAME_PCB_FOOTPRINT_WIZARD, true, this );
390 
391  if( wizard->ShowModal( NULL, this ) )
392  {
393  // Creates the new footprint from python script wizard
394  MODULE* module = wizard->GetBuiltFootprint();
395 
396  if( module == NULL ) // i.e. if create module command aborted
397  break;
398 
399  Clear_Pcb( false );
400 
401  SetCrossHairPosition( wxPoint( 0, 0 ) );
402 
403  // Add the new object to board
404  AddModuleToBoard( module );
405 
406  // Initialize data relative to nets and netclasses (for a new
407  // module the defaults are used)
408  // This is mandatory to handle and draw pads
410  module->SetPosition( wxPoint( 0, 0 ) );
411  module->ClearFlags();
412 
413  Zoom_Automatique( false );
414  GetScreen()->SetModify();
415 
416  // If selected from the library tree then go ahead and save it there
417  if( !selected.GetLibNickname().empty() )
418  {
419  LIB_ID fpid = module->GetFPID();
420  fpid.SetLibNickname( selected.GetLibNickname() );
421  module->SetFPID( fpid );
422  SaveFootprint( module );
423  GetScreen()->ClrModify();
424  }
425 
426  updateView();
427  m_canvas->Refresh();
428  Update3DView();
429 
430  SyncLibraryTree( false );
431  }
432 
433  wizard->Destroy();
434  }
435  break;
436 
437  case ID_MODEDIT_SAVE:
438  if( getTargetFPID() == GetLoadedFPID() )
439  {
440  if( SaveFootprint( GetBoard()->m_Modules ) )
441  {
442  m_toolManager->GetView()->Update( GetBoard()->m_Modules );
443 
444  if( IsGalCanvasActive() && GetGalCanvas() )
445  GetGalCanvas()->ForceRefresh();
446  else
447  GetCanvas()->Refresh();
448 
449  GetScreen()->ClrModify();
450  }
451  }
452 
453  m_treePane->GetLibTree()->Refresh();
454  break;
455 
456  case ID_MODEDIT_SAVE_AS:
457  if( getTargetFPID().GetLibItemName().empty() )
458  {
459  // Save Library As
460  const wxString& src_libNickname = getTargetFPID().GetLibNickname();
461  wxString src_libFullName = Prj().PcbFootprintLibs()->GetFullURI( src_libNickname );
462 
463  if( SaveLibraryAs( src_libFullName ) )
464  SyncLibraryTree( true );
465  }
466  else if( getTargetFPID() == GetLoadedFPID() )
467  {
468  // Save Board Footprint As
469  MODULE* footprint = GetBoard()->m_Modules;
470 
471  if( footprint && SaveFootprintAs( footprint ) )
472  {
473  m_footprintNameWhenLoaded = footprint->GetFPID().GetLibItemName();
474  m_toolManager->GetView()->Update( GetBoard()->m_Modules );
475  GetScreen()->ClrModify();
476 
477  if( IsGalCanvasActive() && GetGalCanvas() )
478  GetGalCanvas()->ForceRefresh();
479  else
480  GetCanvas()->Refresh();
481 
482  SyncLibraryTree( true );
483  }
484  }
485  else
486  {
487  // Save Selected Footprint As
488  MODULE* footprint = LoadFootprint( getTargetFPID() );
489 
490  if( footprint && SaveFootprintAs( footprint ) )
491  SyncLibraryTree( true );
492  }
493 
494  m_treePane->GetLibTree()->Refresh();
495  break;
496 
498  RevertFootprint();
499  break;
500 
501  case ID_MODEDIT_CUT_PART:
503  if( getTargetFPID().IsValid() )
504  {
505  LIB_ID fpID = getTargetFPID();
506 
507  if( fpID == GetLoadedFPID() )
508  m_copiedModule.reset( new MODULE( *GetBoard()->m_Modules.GetFirst() ) );
509  else
510  m_copiedModule.reset( LoadFootprint( fpID ) );
511 
512  if( id == ID_MODEDIT_CUT_PART )
513  {
514  if( fpID == GetLoadedFPID() )
515  Clear_Pcb( false );
516 
517  DeleteModuleFromLibrary( fpID, false );
518  }
519 
520  SyncLibraryTree( true );
521  }
522  break;
523 
525  if( m_copiedModule && !getTargetFPID().GetLibNickname().empty() )
526  {
527  wxString newLib = getTargetFPID().GetLibNickname();
528  MODULE* newModule( m_copiedModule.get() );
529  wxString newName = newModule->GetFPID().GetLibItemName();
530 
531  while( Prj().PcbFootprintLibs()->FootprintExists( newLib, newName ) )
532  newName += _( "_copy" );
533 
534  newModule->SetFPID( LIB_ID( newLib, newName ) );
535  saveFootprintInLibrary( newModule, newLib );
536 
537  SyncLibraryTree( true );
538  m_treePane->GetLibTree()->SelectLibId( newModule->GetFPID() );
539  }
540  break;
541 
543  SaveFootprintToBoard( true );
544  break;
545 
547  if( ! Clear_Pcb( true ) )
548  break; // //this command is aborted
549 
550  SetCrossHairPosition( wxPoint( 0, 0 ) );
551  Import_Module();
552 
553  if( GetBoard()->m_Modules )
555 
556  GetScreen()->ClrModify();
557  Zoom_Automatique( false );
558  m_canvas->Refresh();
559  Update3DView();
560 
561  break;
562 
564  if( getTargetFPID() == GetLoadedFPID() )
565  Export_Module( GetBoard()->m_Modules );
566  else
567  Export_Module( LoadFootprint( getTargetFPID() ) );
568  break;
569 
571  {
572  wxFileName fn( CreateNewLibrary() );
573  wxString name = fn.GetName();
574 
575  if( !name.IsEmpty() )
576  {
577  LIB_ID newLib( name, wxEmptyString );
578 
579  SyncLibraryTree( true );
580  m_treePane->GetLibTree()->SelectLibId( newLib );
581  }
582  }
583  break;
584 
586  AddLibrary();
587  break;
588 
590  break;
591 
593  LoadModuleFromLibrary( m_treePane->GetLibTree()->GetSelectedLibId() );
594  break;
595 
597  InstallPadOptionsFrame( NULL );
598  break;
599 
600  case ID_MODEDIT_CHECK:
601  // Currently: not implemented
602  break;
603 
605  if( GetBoard()->m_Modules )
606  {
607  SetCurItem( GetBoard()->m_Modules );
608  editFootprintProperties( (MODULE*) GetScreen()->GetCurItem() );
609 
610  m_canvas->Refresh();
611  }
612  break;
613 
615  break;
616 
618  break;
619 
621  m_canvas->MoveCursorToCrossHair();
622  Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), 900, true );
623  m_canvas->Refresh();
624  break;
625 
627  m_canvas->MoveCursorToCrossHair();
628  Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), -900, true );
629  m_canvas->Refresh();
630  break;
631 
633  editFootprintProperties( (MODULE*) GetScreen()->GetCurItem() );
634  m_canvas->MoveCursorToCrossHair();
635  m_canvas->Refresh();
636  break;
637 
639  m_canvas->MoveCursorToCrossHair();
640  StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
641  break;
642 
644  InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() );
645  m_canvas->MoveCursorToCrossHair();
646  break;
647 
649  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
650  DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
651  SetCurItem( NULL );
652  m_canvas->MoveCursorToCrossHair();
653  break;
654 
656  duplicateItems( false );
657  break;
658 
660  duplicateItems( true );
661  break;
662 
664  moveExact();
665  break;
666 
668  createArray();
669  break;
670 
672  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
673  m_canvas->MoveCursorToCrossHair();
674  Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
675  break;
676 
678  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
679  // Calls the global change dialog:
680  PushPadProperties((D_PAD*) GetScreen()->GetCurItem());
681  m_canvas->MoveCursorToCrossHair();
682  break;
683 
685  m_canvas->MoveCursorToCrossHair();
686  Export_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem() );
687  break;
688 
690  InstallTextOptionsFrame( GetScreen()->GetCurItem(), &dc );
691  break;
692 
694  m_canvas->MoveCursorToCrossHair();
695  StartMoveTexteModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
696  break;
697 
699  RotateTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
700  m_canvas->MoveCursorToCrossHair();
701  break;
702 
704  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
705  DeleteTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ) );
706  SetCurItem( NULL );
707  m_canvas->MoveCursorToCrossHair();
708  break;
709 
711  Start_Move_EdgeMod( static_cast<EDGE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
712  m_canvas->MoveCursorToCrossHair();
713  break;
714 
716  m_canvas->MoveCursorToCrossHair();
717 
718  if( GetScreen()->GetCurItem()->IsNew() )
719  {
720  End_Edge_Module( (EDGE_MODULE*) GetScreen()->GetCurItem() );
721  SetCurItem( NULL );
722  }
723  break;
724 
726  InstallGraphicItemPropertiesDialog( GetScreen()->GetCurItem() );
727  break;
728 
730  m_canvas->MoveCursorToCrossHair();
731  Edit_Edge_Width( NULL );
732  m_canvas->Refresh();
733  break;
734 
736  m_canvas->MoveCursorToCrossHair();
737  Edit_Edge_Layer( NULL );
738  m_canvas->Refresh();
739  break;
740 
742  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
743  m_canvas->MoveCursorToCrossHair();
744  RemoveStruct( GetScreen()->GetCurItem() );
745  SetCurItem( NULL );
746  break;
747 
751  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
752  Transform( (MODULE*) GetScreen()->GetCurItem(), id );
753  m_canvas->Refresh();
754  break;
755 
757  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
758  m_canvas->SetAutoPanRequest( false );
759  HandleBlockPlace( &dc );
760  break;
761 
763  GetScreen()->m_BlockLocate.SetCommand( BLOCK_DUPLICATE );
764  GetScreen()->m_BlockLocate.SetMessageBlock( this );
765  m_canvas->SetAutoPanRequest( false );
766  HandleBlockPlace( &dc );
767  break;
768 
769  case ID_POPUP_ZOOM_BLOCK:
770  GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
771  GetScreen()->m_BlockLocate.SetMessageBlock( this );
772  HandleBlockEnd( &dc );
773  break;
774 
776  GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
777  GetScreen()->m_BlockLocate.SetMessageBlock( this );
778  HandleBlockEnd( &dc );
779  break;
780 
782  GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
783  GetScreen()->m_BlockLocate.SetMessageBlock( this );
784  HandleBlockEnd( &dc );
785  break;
786 
788  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
789  GetScreen()->m_BlockLocate.SetMessageBlock( this );
790  HandleBlockEnd( &dc );
791  break;
792 
794  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE_EXACT );
795  GetScreen()->m_BlockLocate.SetMessageBlock( this );
796  HandleBlockEnd( &dc );
797  break;
798 
800  if( GetBoard()->m_Modules )
801  {
802  InvokeDialogImportGfxModule( this, GetBoard()->m_Modules );
803  m_canvas->Refresh();
804  }
805  break;
806 
807  default:
808  wxLogDebug( wxT( "FOOTPRINT_EDIT_FRAME::Process_Special_Functions error" ) );
809  break;
810  }
811 }
812 
813 
815 {
816  LIB_ID oldFPID = aModule->GetFPID();
817 
818  DIALOG_FOOTPRINT_FP_EDITOR dialog( this, aModule );
819  dialog.ShowModal();
820 
821  GetScreen()->GetCurItem()->ClearFlags();
822 
823  updateTitle(); // in case of a name change...
824 }
825 
826 
828 {
829  wxPoint translation;
830  double rotation;
832 
833  DIALOG_MOVE_EXACT dialog( this, translation, rotation, rotationAnchor );
834  int ret = dialog.ShowModal();
835 
836  if( ret == wxID_OK )
837  {
838  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
839 
840  BOARD_ITEM* item = GetScreen()->GetCurItem();
841 
842  item->Move( translation );
843 
844  switch( rotationAnchor )
845  {
847  item->Rotate( item->GetPosition(), rotation );
848  break;
850  item->Rotate( GetScreen()->m_O_Curseur, rotation );
851  break;
852  default:
853  wxFAIL_MSG( "Rotation choice shouldn't have been available in this context." );
854  }
855 
856 
857  item->Rotate( item->GetPosition(), rotation );
858  m_canvas->Refresh();
859  }
860 
861  m_canvas->MoveCursorToCrossHair();
862 }
863 
864 
866 {
867  BOARD_ITEM* item = GetScreen()->GetCurItem();
868 
869  PCB_BASE_EDIT_FRAME::duplicateItem( item, aIncrement );
870 }
871 
872 
873 void FOOTPRINT_EDIT_FRAME::Transform( MODULE* module, int transform )
874 {
875  switch( transform )
876  {
878  RotateMarkedItems( module, wxPoint(0,0), true );
879  break;
880 
882  MirrorMarkedItems( module, wxPoint(0,0), true );
883  break;
884 
886  {
887  wxPoint translation;
888  double rotation;
890 
891  DIALOG_MOVE_EXACT dialog( this, translation, rotation, rotationAnchor );
892 
893  if( dialog.ShowModal() == wxID_OK )
894  {
895  switch( rotationAnchor )
896  {
898  MoveMarkedItemsExactly( module, module->GetPosition() + translation, translation, rotation, true );
899  break;
901  MoveMarkedItemsExactly( module, GetScreen()->m_O_Curseur, translation, rotation, true );
902  break;
903  default:
904  wxFAIL_MSG( "Rotation choice shouldn't have been available in this context." );
905  }
906  }
907 
908  break;
909  }
910 
911  default:
912  DisplayInfoMessage( this, wxT( "Not available" ) );
913  break;
914  }
915 
916  module->CalculateBoundingBox();
917  OnModify();
918 }
919 
920 
921 void FOOTPRINT_EDIT_FRAME::OnVerticalToolbar( wxCommandEvent& aEvent )
922 {
923  int id = aEvent.GetId();
924  int lastToolID = GetToolId();
925 
926  // Stop the current command and deselect the current tool.
927  SetNoToolSelected();
928 
929  switch( id )
930  {
931  case ID_NO_TOOL_SELECTED:
932  break;
933 
934  case ID_ZOOM_SELECTION:
935  // This tool is located on the main toolbar: switch it on or off on click on it
936  if( lastToolID != ID_ZOOM_SELECTION )
937  SetToolID( ID_ZOOM_SELECTION, wxCURSOR_MAGNIFIER, _( "Zoom to selection" ) );
938  else
939  SetNoToolSelected();
940  break;
941 
943  SetToolID( id, wxCURSOR_PENCIL, _( "Add line" ) );
944  break;
945 
946  case ID_MODEDIT_ARC_TOOL:
947  SetToolID( id, wxCURSOR_PENCIL, _( "Add arc" ) );
948  break;
949 
951  SetToolID( id, wxCURSOR_PENCIL, _( "Add circle" ) );
952  break;
953 
955  SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
956  break;
957 
959  SetToolID( id, wxCURSOR_PENCIL, _( "Place anchor" ) );
960  break;
961 
963  SetToolID( id, wxCURSOR_PENCIL, _( "Set grid origin" ) );
964  break;
965 
966  case ID_MODEDIT_PAD_TOOL:
967  if( GetBoard()->m_Modules )
968  {
969  SetToolID( id, wxCURSOR_PENCIL, _( "Add pad" ) );
970  }
971  else
972  {
973  SetToolID( id, wxCURSOR_ARROW, _( "Pad properties" ) );
974  InstallPadOptionsFrame( NULL );
975  SetNoToolSelected();
976  }
977  break;
978 
980  SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
981  break;
982 
984  DisplayError( this, wxT( "Measurement Tool not available in Legacy Toolset" ) );
985  SetNoToolSelected();
986  break;
987 
988  default:
989  wxFAIL_MSG( wxT( "Unknown command id." ) );
990  SetNoToolSelected();
991  }
992 }
993 
994 
996 {
997  if( Item == NULL )
998  return;
999 
1000  switch( Item->Type() )
1001  {
1002  case PCB_PAD_T:
1003  DeletePad( (D_PAD*) Item, false );
1004  break;
1005 
1006  case PCB_MODULE_TEXT_T:
1007  {
1008  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( Item );
1009 
1010  switch( text->GetType() )
1011  {
1013  DisplayError( this, _( "Cannot delete REFERENCE!" ) );
1014  break;
1015 
1017  DisplayError( this, _( "Cannot delete VALUE!" ) );
1018  break;
1019 
1021  DeleteTextModule( text );
1022  }
1023  }
1024  break;
1025 
1026  case PCB_MODULE_EDGE_T:
1027  Delete_Edge_Module( (EDGE_MODULE*) Item );
1028  m_canvas->Refresh();
1029  break;
1030 
1031  case PCB_MODULE_T:
1032  break;
1033 
1034  default:
1035  {
1036  wxString Line;
1037  Line.Printf( wxT( " RemoveStruct: item type %d unknown." ), Item->Type() );
1038  wxMessageBox( Line );
1039  }
1040  break;
1041  }
1042 }
1043 
1045 {
1046  return Settings().Colors().GetItemColor( LAYER_GRID );
1047 }
1048 
1049 
1051 {
1053 
1054  m_Layers->SelectLayer( GetActiveLayer() );
1055  m_Layers->OnLayerSelected();
1056 
1057  if( IsGalCanvasActive() )
1058  {
1059  GetGalCanvas()->SetHighContrastLayer( aLayer );
1060  GetGalCanvas()->Refresh();
1061  }
1062 }
1063 
1064 bool FOOTPRINT_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
1065 {
1066  if( ! Clear_Pcb( true ) )
1067  return false; // //this command is aborted
1068 
1069  SetCrossHairPosition( wxPoint( 0, 0 ) );
1070  Import_Module( aFileSet[0] );
1071 
1072  if( GetBoard()->m_Modules )
1074 
1075  GetScreen()->ClrModify();
1076  Zoom_Automatique( false );
1077  m_canvas->Refresh();
1078 
1079  return true;
1080 }
1081 
1082 
1084 {
1085  const std::string& payload = mail.GetPayload();
1086 
1087  switch( mail.Command() )
1088  {
1089  case MAIL_FP_EDIT:
1090  if( !payload.empty() )
1091  {
1092  wxFileName fpFileName( payload );
1093  wxString libNickname;
1094  wxString msg;
1095 
1096  FP_LIB_TABLE* libTable = Prj().PcbFootprintLibs();
1097  const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( fpFileName.GetPath() );
1098 
1099  if( !libTableRow )
1100  {
1101  msg.Printf( _( "The current configuration does not include the footprint library\n"
1102  "\"%s\".\nUse Manage Footprint Libraries to edit the configuration." ),
1103  fpFileName.GetPath() );
1104  DisplayErrorMessage( this, _( "Library not found in footprint library table." ), msg );
1105  break;
1106  }
1107 
1108  libNickname = libTableRow->GetNickName();
1109 
1110  if( !libTable->HasLibrary( libNickname, true ) )
1111  {
1112  msg.Printf( _( "The library with the nickname \"%s\" is not enabled\n"
1113  "in the current configuration. Use Manage Footprint Libraries to\n"
1114  "edit the configuration." ), libNickname );
1115  DisplayErrorMessage( this, _( "Footprint library not enabled." ), msg );
1116  break;
1117  }
1118 
1119  LIB_ID fpId( libNickname, fpFileName.GetName() );
1120 
1121  if( m_treePane )
1122  {
1123  m_treePane->GetLibTree()->SelectLibId( fpId );
1124  wxCommandEvent event( COMPONENT_SELECTED );
1125  wxPostEvent( m_treePane, event );
1126  }
1127  }
1128 
1129  break;
1130 
1131  default:
1132  ;
1133  }
1134 }
BOARD_ITEM * ModeditLocateAndDisplay(int aHotKeyCode=0)
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
int GetLength() const
void BuildListOfNets()
Definition: class_board.h:735
Class FOOTPRINT_WIZARD_FRAME.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Function HandleUnsavedChanges displays a dialog with Save, Cancel and Discard Changes buttons...
Definition: confirm.cpp:213
Class KIWAY_EXPRESS carries a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition: kiway_express.h:39
TEXTE_MODULE & Reference()
Definition: class_module.h:512
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE...
PNG memory record (file in memory).
Definition: bitmap_types.h:43
bool InvokeDialogImportGfxModule(PCB_BASE_FRAME *aCaller, MODULE *aModule)
shows the modal DIALOG_IMPORT_GFX for importing a DXF file as footprint outlines. ...
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Function DisplayErrorMessage displays an error message with aMessage.
Definition: confirm.cpp:259
This file is part of the common library TODO brief description.
void SetActiveLayer(PCB_LAYER_ID aLayer) override
>
void RemoveStruct(EDA_ITEM *Item)
void OnVerticalToolbar(wxCommandEvent &aEvent)
This file is part of the common library.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
virtual COLOR4D GetGridColor() override
TEXT_TYPE GetType() const
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Function AddMenuItem is an inline helper function to create and insert a menu item with an icon into ...
Definition: bitmap.cpp:223
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
PROJECT & Prj()
Definition: kicad.cpp:292
Class BOARD to handle a board.
Class that computes missing connections on a PCB.
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
Component library viewer main window.
void LoadModuleFromLibrary(LIB_ID aFPID)
void MoveMarkedItemsExactly(MODULE *module, const wxPoint &centre, const wxPoint &translation, double rotation, bool force_all=false)
void MirrorMarkedItems(MODULE *module, wxPoint offset, bool force_all=false)
Mirror marked items, refer to a Vertical axis at position offset Note: because this function is used ...
The common library.
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
void duplicateItem(BOARD_ITEM *aItem, bool aIncrement)
Function duplicateItem Duplicate the specified item This function is shared between pcbnew and modedi...
Definition: edit.cpp:1583
void duplicateItems(bool aIncrement) override
Duplicate the item under the cursor.
virtual wxString GetSelectMenuText(EDA_UNITS_T aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
Definition of class FOOTPRINT_EDIT_FRAME.
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
This file contains miscellaneous commonly used macros and functions.
static const KICAD_T ModulesAndTheirItems[]
A scan list for MODULEs and their items (for Modedit)
Definition: collectors.h:308
void scanList(PTREE *aTree, DSNLEXER *aLexer)
Function scanList reads a sexpr list from the input stream into a new node with key aLexer->CurText()...
Definition: ptree.cpp:55
Definition: id.h:110
const LIB_ID & GetFPID() const
Definition: class_module.h:192
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
virtual void Zoom_Automatique(bool aWarpPointer)
Redraw the screen with best zoom level and the best centering that shows all the page or the board...
class MODULE, a footprint
Definition: typeinfo.h:89
PCB_LAYER_ID
A quick note on layer IDs:
a helper to handle the real device context used in KiCad
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:300
bool empty() const
Definition: utf8.h:108
void editFootprintProperties(MODULE *aFootprint)
Run the Footprint Properties dialog and handle changes made in it.
virtual void Move(const wxPoint &aMoveVector)
Function Move move this object.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:511
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
const LIB_TABLE_ROW * FindRowByURI(const wxString &aURI)
Definition of file extensions used in Kicad.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle)
Function Rotate Rotate this object.
void SetPosition(const wxPoint &aPos) override
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
Function SetActiveLayer will change the currently active layer to aLayer.
void moveExact()
Move the selected item exactly, popping up a dialog to allow the user the enter the move delta...
ROTATION_ANCHOR
void SetType(TEXT_TYPE aType)
virtual const wxPoint GetPosition() const =0
BOARD * GetBoard()
VTBL_ENTRY FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:193
General-puspose messages.
Definition: mail_type.h:52
const std::string & GetPayload()
Function Payload returns the payload, which can be any text but it typicall self identifying s-expres...
Definition: kiway_express.h:62
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
ID_MODEDIT_MEASUREMENT_TOOL
void Process_Special_Functions(wxCommandEvent &event)
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
const wxString & GetNickName() const
see class PGM_BASE
void LoadModuleFromBoard(wxCommandEvent &event)
Called from the main toolbar to load a footprint from board mainly to edit it.
Declaration of the eda_3d_viewer class.
const char * name
Definition: DXF_plotter.cpp:61
DLIST< MODULE > m_Modules
Definition: class_board.h:249
#define INSTALL_UNBUFFERED_DC(name, parent)
void RotateMarkedItems(MODULE *module, wxPoint offset, bool force_all=false)
Rotate marked items, refer to a rotation point at position offset Note: because this function is used...
static bool empty(const wxTextEntryBase *aCtrl)
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:257
#define MAX_ITEMS_IN_PICKER
Command IDs for the printed circuit board editor.
Definition: pcbnew_id.h:14
Module description (excepted pads)
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:391
MAIL_T Command()
Function Command returns the MAIL_T associated with this mail.
Definition: kiway_express.h:52
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:97
EDGE_MODULE class definition.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:277
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
const wxPoint GetPosition() const override
Definition: class_module.h:183
VTBL_ENTRY bool ShowModal(wxString *aResult=NULL, wxWindow *aResultantFocusWindow=NULL)
Function ShowModal puts up this wxFrame as if it were a modal dialog, with all other instantiated wxF...
void SetFPID(const LIB_ID &aFPID)
Definition: class_module.h:193
void KiwayMailIn(KIWAY_EXPRESS &mail) override
Function KiwayMailIn receives KIWAY_EXPRESS messages from other players.
virtual BITMAP_DEF GetMenuImage() const
Function GetMenuImage returns a pointer to an image to be used in menus.
void Transform(MODULE *module, int transform)
Perform a geometric transform on the current footprint.
#define min(a, b)
Definition: auxiliary.h:85
KIWAY Kiway
virtual void SetText(const wxString &aText)
Definition: eda_text.h:154
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39