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-2016 KiCad Developers, see AUTHORS.txt for contributors.
5  * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
29 #include <fctsys.h>
30 #include <kiface_i.h>
31 #include <kiway.h>
32 #include <kiway_express.h>
33 #include <class_drawpanel.h>
34 #include <pcb_draw_panel_gal.h>
35 #include <confirm.h>
36 #include <gestfich.h>
37 #include <pgm_base.h>
38 #include <trigo.h>
40 #include <kicad_device_context.h>
41 #include <macros.h>
42 #include <invoke_pcb_dialog.h>
43 #include <pcb_layer_widget.h>
44 #include <board_commit.h>
45 #include <view/view.h>
46 #include <class_board.h>
47 #include <class_module.h>
48 #include <class_edge_mod.h>
49 
50 #include <ratsnest_data.h>
51 #include <pcbnew.h>
52 #include <protos.h>
53 #include <pcbnew_id.h>
54 #include <footprint_edit_frame.h>
55 #include <footprint_viewer_frame.h>
56 #include <footprint_tree_pane.h>
57 #include <fp_lib_table.h>
58 #include <widgets/lib_tree.h>
59 #include <collectors.h>
60 #include <tool/tool_manager.h>
61 #include <tools/pcb_actions.h>
62 
64 #include <dialog_move_exact.h>
65 #include <dialog_create_array.h>
67 #include <menus_helpers.h>
68 #include <footprint_wizard_frame.h>
69 #include <config_params.h>
70 
71 #include <functional>
72 using namespace std::placeholders;
73 
74 
75 // Functions defined in block_module_editor, but used here
76 // These 3 functions are used in modedit to rotate, mirror or move the
77 // whole footprint so they are called with force_all = true
78 void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
79 void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
80 void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
81  const wxPoint& translation, double rotation,
82  bool force_all = false );
83 
84 
86 {
87  BOARD_ITEM* item = GetCurItem();
88 
89  if( GetBoard()->m_Modules == NULL )
90  return NULL;
91 
92  GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
93 
94  // Assign to scanList the proper item types desired based on tool type
95  // or hotkey that is in play.
96 
97  const KICAD_T* scanList = NULL;
98 
99  if( aHotKeyCode )
100  {
101  // @todo: add switch here and add calls to PcbGeneralLocateAndDisplay(
102  // int aHotKeyCode ) when searching is needed from a hotkey handler
103  }
104  else
105  {
107  }
108 
109  m_Collector->Collect( GetBoard(), scanList, RefPos( true ), guide );
110 
111  // Remove redundancies: when an item is found, we can remove the module from list
112  if( m_Collector->GetCount() > 1 )
113  {
114  for( int ii = 0; ii < m_Collector->GetCount(); ii++ )
115  {
116  item = (*m_Collector)[ii];
117 
118  if( item->Type() != PCB_MODULE_T )
119  continue;
120 
121  m_Collector->Remove( ii );
122  ii--;
123  }
124  }
125 
126  if( m_Collector->GetCount() <= 1 )
127  {
128  item = (*m_Collector)[0];
129  SetCurItem( item );
130  }
131  else // we can't figure out which item user wants, do popup menu so user can choose
132  {
133  wxMenu itemMenu;
134 
135  // Give a title to the selection menu. It also allows one to close the popup menu without any action
136  AddMenuItem( &itemMenu, wxID_NONE, _( "Clarify Selection" ),
137  KiBitmap( info_xpm ) );
138  itemMenu.AppendSeparator();
139 
140  int limit = std::min( MAX_ITEMS_IN_PICKER, m_Collector->GetCount() );
141 
142  for( int ii = 0; ii<limit; ++ii )
143  {
144  item = (*m_Collector)[ii];
145 
146  wxString text = item->GetSelectMenuText( GetUserUnits() );
147  BITMAP_DEF xpm = item->GetMenuImage();
148 
149  AddMenuItem( &itemMenu,
151  text,
152  KiBitmap( xpm ) );
153  }
154 
155  // this menu's handler is void
156  // PCB_BASE_FRAME::ProcessItemSelection()
157  // and it calls SetCurItem() which in turn calls DisplayInfo() on the
158  // item.
159  m_canvas->SetAbortRequest( true ); // changed in false if an item is selected
160  PopupMenu( &itemMenu ); // m_AbortRequest = false if an item is selected
161 
162  m_canvas->MoveCursorToCrossHair();
163  m_canvas->SetIgnoreMouseEvents( false );
164 
165  // The function ProcessItemSelection() has set the current item, return it.
166  item = GetCurItem();
167  }
168 
169  if( item )
170  {
171  SetMsgPanel( item );
172  }
173 
174  return item;
175 }
176 
177 
178 void FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard( wxCommandEvent& event )
179 {
180  Load_Module_From_BOARD( NULL );
181 }
182 
183 
185 {
186  MODULE* module = LoadFootprint( aFPID );
187 
188  if( !module )
189  return;
190 
191  if( !Clear_Pcb( true ) )
192  return;
193 
194  SetCrossHairPosition( wxPoint( 0, 0 ) );
195  AddModuleToBoard( module );
196 
197  if( GetBoard()->m_Modules )
198  {
200 
201  // if either m_Reference or m_Value are gone, reinstall them -
202  // otherwise you cannot see what you are doing on board
204  TEXTE_MODULE* val = &GetBoard()->m_Modules->Value();
205 
206  if( val && ref )
207  {
208  ref->SetType( TEXTE_MODULE::TEXT_is_REFERENCE ); // just in case ...
209 
210  if( ref->GetLength() == 0 )
211  ref->SetText( wxT( "Ref**" ) );
212 
213  val->SetType( TEXTE_MODULE::TEXT_is_VALUE ); // just in case ...
214 
215  if( val->GetLength() == 0 )
216  val->SetText( wxT( "Val**" ) );
217  }
218  }
219 
220  Zoom_Automatique( false );
221 
222  Update3DView();
223 
224  GetScreen()->ClrModify();
225 
226  updateView();
227  m_canvas->Refresh();
228 
229  m_treePane->GetLibTree()->ExpandLibId( aFPID );
230  m_treePane->GetLibTree()->CenterLibId( aFPID );
231  m_treePane->GetLibTree()->Refresh(); // update highlighting
232 }
233 
234 
236 {
237  int id = event.GetId();
238  wxPoint pos;
239 
240  INSTALL_UNBUFFERED_DC( dc, m_canvas );
241 
242  wxGetMousePosition( &pos.x, &pos.y );
243 
244  pos.y += 20;
245 
246  switch( id )
247  {
248  case wxID_CUT:
249  case wxID_COPY:
271  case ID_POPUP_ZOOM_BLOCK:
275  break;
276 
278  default:
279  if( m_canvas->IsMouseCaptured() )
280  {
281  // for all other commands: stop the move in progress
282  m_canvas->CallEndMouseCapture( &dc );
283  }
284 
286  SetNoToolSelected();
287 
288  break;
289  }
290 
291  switch( id )
292  {
293  case ID_EXIT:
294  Close( true );
295  break;
296 
298  {
300 
301  if( !viewer )
302  {
304  viewer->Show( true );
305  viewer->Zoom_Automatique( false );
306  }
307  else
308  {
309  // On Windows, Raise() does not bring the window on screen, when iconized
310  if( viewer->IsIconized() )
311  viewer->Iconize( false );
312 
313  viewer->Raise();
314 
315  // Raising the window does not set the focus on Linux. This should work on
316  // any platform.
317  if( wxWindow::FindFocus() != viewer )
318  viewer->SetFocus();
319  }
320  }
321  break;
322 
324  if( DeleteModuleFromLibrary( getTargetFPID(), true ) )
325  {
326  if( getTargetFPID() == GetLoadedFPID() )
327  Clear_Pcb( false );
328 
329  SyncLibraryTree( true );
330  }
331  break;
332 
334  {
335  LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId();
336  MODULE* module = CreateNewModule( wxEmptyString );
337 
338  if( !module )
339  break;
340 
341  if( !Clear_Pcb( true ) )
342  break;
343 
344  SetCrossHairPosition( wxPoint( 0, 0 ) );
345  AddModuleToBoard( module );
346 
347  // Initialize data relative to nets and netclasses (for a new
348  // module the defaults are used)
349  // This is mandatory to handle and draw pads
351  module->SetPosition( wxPoint( 0, 0 ) );
352 
353  if( GetBoard()->m_Modules )
355 
356  Zoom_Automatique( false );
357  GetScreen()->SetModify();
358 
359  // If selected from the library tree then go ahead and save it there
360  if( !selected.GetLibNickname().empty() )
361  {
362  LIB_ID fpid = module->GetFPID();
363  fpid.SetLibNickname( selected.GetLibNickname() );
364  module->SetFPID( fpid );
365  SaveFootprint( module );
366  GetScreen()->ClrModify();
367  }
368 
369  updateView();
370  m_canvas->Refresh();
371  Update3DView();
372 
373  SyncLibraryTree( false );
374  }
375  break;
376 
378  {
379  LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId();
380 
381  if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
382  {
383  if( !HandleUnsavedChanges( this, _( "The current footprint has been modified. Save changes?" ),
384  [&]()->bool { return SaveFootprint( GetBoard()->m_Modules ); } ) )
385  {
386  break;
387  }
388  }
389 
391  FRAME_PCB_FOOTPRINT_WIZARD, true, this );
392 
393  if( wizard->ShowModal( NULL, this ) )
394  {
395  // Creates the new footprint from python script wizard
396  MODULE* module = wizard->GetBuiltFootprint();
397 
398  if( module == NULL ) // i.e. if create module command aborted
399  break;
400 
401  Clear_Pcb( false );
402 
403  SetCrossHairPosition( wxPoint( 0, 0 ) );
404 
405  // Add the new object to board
406  AddModuleToBoard( module );
407 
408  // Initialize data relative to nets and netclasses (for a new
409  // module the defaults are used)
410  // This is mandatory to handle and draw pads
412  module->SetPosition( wxPoint( 0, 0 ) );
413  module->ClearFlags();
414 
415  Zoom_Automatique( false );
416  GetScreen()->SetModify();
417 
418  // If selected from the library tree then go ahead and save it there
419  if( !selected.GetLibNickname().empty() )
420  {
421  LIB_ID fpid = module->GetFPID();
422  fpid.SetLibNickname( selected.GetLibNickname() );
423  module->SetFPID( fpid );
424  SaveFootprint( module );
425  GetScreen()->ClrModify();
426  }
427 
428  updateView();
429  m_canvas->Refresh();
430  Update3DView();
431 
432  SyncLibraryTree( false );
433  }
434 
435  wizard->Destroy();
436  }
437  break;
438 
439  case ID_MODEDIT_SAVE:
440  if( getTargetFPID() == GetLoadedFPID() )
441  {
442  if( SaveFootprint( GetBoard()->m_Modules ) )
443  {
444  m_toolManager->GetView()->Update( GetBoard()->m_Modules );
445 
446  if( IsGalCanvasActive() && GetGalCanvas() )
447  GetGalCanvas()->ForceRefresh();
448  else
449  GetCanvas()->Refresh();
450 
451  GetScreen()->ClrModify();
452  }
453  }
454 
455  m_treePane->GetLibTree()->Refresh();
456  break;
457 
458  case ID_MODEDIT_SAVE_AS:
459  if( getTargetFPID().GetLibItemName().empty() )
460  {
461  // Save Library As
462  const wxString& libName = getTargetFPID().GetLibNickname();
463 
464  if( SaveLibraryAs( Prj().PcbFootprintLibs()->FindRow( libName )->GetFullURI() ) )
465  SyncLibraryTree( true );
466  }
467  else if( getTargetFPID() == GetLoadedFPID() )
468  {
469  // Save Board Footprint As
470  MODULE* footprint = GetBoard()->m_Modules;
471 
472  if( footprint && SaveFootprintAs( footprint ) )
473  {
474  m_footprintNameWhenLoaded = footprint->GetFPID().GetLibItemName();
475  m_toolManager->GetView()->Update( GetBoard()->m_Modules );
476  GetScreen()->ClrModify();
477 
478  if( IsGalCanvasActive() && GetGalCanvas() )
479  GetGalCanvas()->ForceRefresh();
480  else
481  GetCanvas()->Refresh();
482 
483  SyncLibraryTree( true );
484  }
485  }
486  else
487  {
488  // Save Selected Footprint As
489  MODULE* footprint = LoadFootprint( getTargetFPID() );
490 
491  if( footprint && SaveFootprintAs( footprint ) )
492  SyncLibraryTree( true );
493  }
494 
495  m_treePane->GetLibTree()->Refresh();
496  break;
497 
499  RevertFootprint();
500  break;
501 
502  case ID_MODEDIT_CUT_PART:
504  if( getTargetFPID().IsValid() )
505  {
506  LIB_ID fpID = getTargetFPID();
507  m_copiedModule.reset( LoadFootprint( fpID ) );
508 
509  if( id == ID_MODEDIT_CUT_PART )
510  DeleteModuleFromLibrary( fpID, false );
511 
512  SyncLibraryTree( true );
513  }
514  break;
515 
517  if( m_copiedModule && !getTargetFPID().GetLibNickname().empty() )
518  {
519  wxString newLib = getTargetFPID().GetLibNickname();
520  MODULE* newModule( m_copiedModule.get() );
521  wxString newName = newModule->GetFPID().GetLibItemName();
522 
523  while( Prj().PcbFootprintLibs()->FootprintExists( newLib, newName ) )
524  newName += _( "_copy" );
525 
526  newModule->SetFPID( LIB_ID( newLib, newName ) );
527  saveFootprintInLibrary( newModule, newLib );
528 
529  SyncLibraryTree( true );
530  m_treePane->GetLibTree()->SelectLibId( newModule->GetFPID() );
531  }
532  break;
533 
535  SaveFootprintToBoard( true );
536  break;
537 
539  if( ! Clear_Pcb( true ) )
540  break; // //this command is aborted
541 
542  SetCrossHairPosition( wxPoint( 0, 0 ) );
543  Import_Module();
544 
545  if( GetBoard()->m_Modules )
547 
548  GetScreen()->ClrModify();
549  Zoom_Automatique( false );
550  m_canvas->Refresh();
551  Update3DView();
552 
553  break;
554 
556  if( getTargetFPID() == GetLoadedFPID() )
557  Export_Module( GetBoard()->m_Modules );
558  else
559  Export_Module( LoadFootprint( getTargetFPID() ) );
560  break;
561 
563  {
564  wxFileName fn( CreateNewLibrary() );
565  wxString name = fn.GetName();
566 
567  if( !name.IsEmpty() )
568  {
569  LIB_ID newLib( name, wxEmptyString );
570 
571  SyncLibraryTree( true );
572  m_treePane->GetLibTree()->SelectLibId( newLib );
573  }
574  }
575  break;
576 
578  AddLibrary();
579  break;
580 
582  break;
583 
585  LoadModuleFromLibrary( m_treePane->GetLibTree()->GetSelectedLibId() );
586  break;
587 
589  InstallPadOptionsFrame( NULL );
590  break;
591 
592  case ID_MODEDIT_CHECK:
593  // Currently: not implemented
594  break;
595 
597  if( GetBoard()->m_Modules )
598  {
599  SetCurItem( GetBoard()->m_Modules );
600  editFootprintProperties( (MODULE*) GetScreen()->GetCurItem() );
601 
602  m_canvas->Refresh();
603  }
604  break;
605 
607  break;
608 
610  break;
611 
613  m_canvas->MoveCursorToCrossHair();
614  Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), 900, true );
615  m_canvas->Refresh();
616  break;
617 
619  m_canvas->MoveCursorToCrossHair();
620  Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), -900, true );
621  m_canvas->Refresh();
622  break;
623 
625  editFootprintProperties( (MODULE*) GetScreen()->GetCurItem() );
626  m_canvas->MoveCursorToCrossHair();
627  m_canvas->Refresh();
628  break;
629 
631  m_canvas->MoveCursorToCrossHair();
632  StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
633  break;
634 
636  InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() );
637  m_canvas->MoveCursorToCrossHair();
638  break;
639 
641  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
642  DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
643  SetCurItem( NULL );
644  m_canvas->MoveCursorToCrossHair();
645  break;
646 
648  duplicateItems( false );
649  break;
650 
652  duplicateItems( true );
653  break;
654 
656  moveExact();
657  break;
658 
660  createArray();
661  break;
662 
664  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
665  m_canvas->MoveCursorToCrossHair();
666  Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
667  break;
668 
670  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
671  // Calls the global change dialog:
672  PushPadProperties((D_PAD*) GetScreen()->GetCurItem());
673  m_canvas->MoveCursorToCrossHair();
674  break;
675 
677  m_canvas->MoveCursorToCrossHair();
678  Export_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem() );
679  break;
680 
682  InstallTextOptionsFrame( GetScreen()->GetCurItem(), &dc );
683  break;
684 
686  m_canvas->MoveCursorToCrossHair();
687  StartMoveTexteModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
688  break;
689 
691  RotateTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
692  m_canvas->MoveCursorToCrossHair();
693  break;
694 
696  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
697  DeleteTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ) );
698  SetCurItem( NULL );
699  m_canvas->MoveCursorToCrossHair();
700  break;
701 
703  Start_Move_EdgeMod( static_cast<EDGE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
704  m_canvas->MoveCursorToCrossHair();
705  break;
706 
708  m_canvas->MoveCursorToCrossHair();
709 
710  if( GetScreen()->GetCurItem()->IsNew() )
711  {
712  End_Edge_Module( (EDGE_MODULE*) GetScreen()->GetCurItem() );
713  SetCurItem( NULL );
714  }
715  break;
716 
718  InstallGraphicItemPropertiesDialog( GetScreen()->GetCurItem() );
719  break;
720 
722  m_canvas->MoveCursorToCrossHair();
723  Edit_Edge_Width( NULL );
724  m_canvas->Refresh();
725  break;
726 
728  m_canvas->MoveCursorToCrossHair();
729  Edit_Edge_Layer( NULL );
730  m_canvas->Refresh();
731  break;
732 
734  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
735  m_canvas->MoveCursorToCrossHair();
736  RemoveStruct( GetScreen()->GetCurItem() );
737  SetCurItem( NULL );
738  break;
739 
743  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
744  Transform( (MODULE*) GetScreen()->GetCurItem(), id );
745  m_canvas->Refresh();
746  break;
747 
749  InvokeDialogGrid();
750  break;
751 
753  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
754  m_canvas->SetAutoPanRequest( false );
755  HandleBlockPlace( &dc );
756  break;
757 
759  GetScreen()->m_BlockLocate.SetCommand( BLOCK_DUPLICATE );
760  GetScreen()->m_BlockLocate.SetMessageBlock( this );
761  m_canvas->SetAutoPanRequest( false );
762  HandleBlockPlace( &dc );
763  break;
764 
765  case ID_POPUP_ZOOM_BLOCK:
766  GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
767  GetScreen()->m_BlockLocate.SetMessageBlock( this );
768  HandleBlockEnd( &dc );
769  break;
770 
772  GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
773  GetScreen()->m_BlockLocate.SetMessageBlock( this );
774  HandleBlockEnd( &dc );
775  break;
776 
778  GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
779  GetScreen()->m_BlockLocate.SetMessageBlock( this );
780  HandleBlockEnd( &dc );
781  break;
782 
784  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
785  GetScreen()->m_BlockLocate.SetMessageBlock( this );
786  HandleBlockEnd( &dc );
787  break;
788 
790  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE_EXACT );
791  GetScreen()->m_BlockLocate.SetMessageBlock( this );
792  HandleBlockEnd( &dc );
793  break;
794 
796  if( GetBoard()->m_Modules )
797  {
798  InvokeDXFDialogModuleImport( this, GetBoard()->m_Modules );
799  m_canvas->Refresh();
800  }
801  break;
802 
803  default:
804  DisplayError( this,
805  wxT( "FOOTPRINT_EDIT_FRAME::Process_Special_Functions error" ) );
806  break;
807  }
808 }
809 
810 
812 {
813  LIB_ID oldFPID = aModule->GetFPID();
814 
815  DIALOG_FOOTPRINT_FP_EDITOR dialog( this, aModule );
816  dialog.ShowModal();
817 
818  GetScreen()->GetCurItem()->ClearFlags();
819 
820  updateTitle(); // in case of a name change...
821 }
822 
823 
825 {
826  wxPoint translation;
827  double rotation;
829 
830  DIALOG_MOVE_EXACT dialog( this, translation, rotation, rotationAnchor );
831  int ret = dialog.ShowModal();
832 
833  if( ret == wxID_OK )
834  {
835  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
836 
837  BOARD_ITEM* item = GetScreen()->GetCurItem();
838 
839  item->Move( translation );
840 
841  switch( rotationAnchor )
842  {
844  item->Rotate( item->GetPosition(), rotation );
845  break;
847  item->Rotate( GetScreen()->m_O_Curseur, rotation );
848  break;
849  default:
850  wxFAIL_MSG( "Rotation choice shouldn't have been available in this context." );
851  }
852 
853 
854  item->Rotate( item->GetPosition(), rotation );
855  m_canvas->Refresh();
856  }
857 
858  m_canvas->MoveCursorToCrossHair();
859 }
860 
861 
863 {
864  BOARD_ITEM* item = GetScreen()->GetCurItem();
865 
866  PCB_BASE_EDIT_FRAME::duplicateItem( item, aIncrement );
867 }
868 
869 
870 void FOOTPRINT_EDIT_FRAME::Transform( MODULE* module, int transform )
871 {
872  switch( transform )
873  {
875  RotateMarkedItems( module, wxPoint(0,0), true );
876  break;
877 
879  MirrorMarkedItems( module, wxPoint(0,0), true );
880  break;
881 
883  {
884  wxPoint translation;
885  double rotation;
887 
888  DIALOG_MOVE_EXACT dialog( this, translation, rotation, rotationAnchor );
889 
890  if( dialog.ShowModal() == wxID_OK )
891  {
892  switch( rotationAnchor )
893  {
895  MoveMarkedItemsExactly( module, module->GetPosition() + translation, translation, rotation, true );
896  break;
898  MoveMarkedItemsExactly( module, GetScreen()->m_O_Curseur, translation, rotation, true );
899  break;
900  default:
901  wxFAIL_MSG( "Rotation choice shouldn't have been available in this context." );
902  }
903  }
904 
905  break;
906  }
907 
908  default:
909  DisplayInfoMessage( this, wxT( "Not available" ) );
910  break;
911  }
912 
913  module->CalculateBoundingBox();
914  OnModify();
915 }
916 
917 
918 void FOOTPRINT_EDIT_FRAME::OnVerticalToolbar( wxCommandEvent& aEvent )
919 {
920  int id = aEvent.GetId();
921  int lastToolID = GetToolId();
922 
923  // Stop the current command and deselect the current tool.
924  SetNoToolSelected();
925 
926  switch( id )
927  {
928  case ID_NO_TOOL_SELECTED:
929  break;
930 
931  case ID_ZOOM_SELECTION:
932  // This tool is located on the main toolbar: switch it on or off on click on it
933  if( lastToolID != ID_ZOOM_SELECTION )
934  SetToolID( ID_ZOOM_SELECTION, wxCURSOR_MAGNIFIER, _( "Zoom to selection" ) );
935  else
936  SetNoToolSelected();
937  break;
938 
940  SetToolID( id, wxCURSOR_PENCIL, _( "Add line" ) );
941  break;
942 
943  case ID_MODEDIT_ARC_TOOL:
944  SetToolID( id, wxCURSOR_PENCIL, _( "Add arc" ) );
945  break;
946 
948  SetToolID( id, wxCURSOR_PENCIL, _( "Add circle" ) );
949  break;
950 
952  SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
953  break;
954 
956  SetToolID( id, wxCURSOR_PENCIL, _( "Place anchor" ) );
957  break;
958 
960  SetToolID( id, wxCURSOR_PENCIL, _( "Set grid origin" ) );
961  break;
962 
963  case ID_MODEDIT_PAD_TOOL:
964  if( GetBoard()->m_Modules )
965  {
966  SetToolID( id, wxCURSOR_PENCIL, _( "Add pad" ) );
967  }
968  else
969  {
970  SetToolID( id, wxCURSOR_ARROW, _( "Pad properties" ) );
971  InstallPadOptionsFrame( NULL );
972  SetNoToolSelected();
973  }
974  break;
975 
977  SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
978  break;
979 
981  DisplayError( this, wxT( "Measurement Tool not available in Legacy Toolset" ) );
982  SetNoToolSelected();
983  break;
984 
985  default:
986  wxFAIL_MSG( wxT( "Unknown command id." ) );
987  SetNoToolSelected();
988  }
989 }
990 
991 
993 {
994  if( Item == NULL )
995  return;
996 
997  switch( Item->Type() )
998  {
999  case PCB_PAD_T:
1000  DeletePad( (D_PAD*) Item, false );
1001  break;
1002 
1003  case PCB_MODULE_TEXT_T:
1004  {
1005  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( Item );
1006 
1007  switch( text->GetType() )
1008  {
1010  DisplayError( this, _( "Cannot delete REFERENCE!" ) );
1011  break;
1012 
1014  DisplayError( this, _( "Cannot delete VALUE!" ) );
1015  break;
1016 
1018  DeleteTextModule( text );
1019  }
1020  }
1021  break;
1022 
1023  case PCB_MODULE_EDGE_T:
1024  Delete_Edge_Module( (EDGE_MODULE*) Item );
1025  m_canvas->Refresh();
1026  break;
1027 
1028  case PCB_MODULE_T:
1029  break;
1030 
1031  default:
1032  {
1033  wxString Line;
1034  Line.Printf( wxT( " RemoveStruct: item type %d unknown." ), Item->Type() );
1035  wxMessageBox( Line );
1036  }
1037  break;
1038  }
1039 }
1040 
1042 {
1043  return Settings().Colors().GetItemColor( LAYER_GRID );
1044 }
1045 
1046 
1048 {
1050 
1051  m_Layers->SelectLayer( GetActiveLayer() );
1052  m_Layers->OnLayerSelected();
1053 
1054  if( IsGalCanvasActive() )
1055  {
1056  GetGalCanvas()->SetHighContrastLayer( aLayer );
1057  GetGalCanvas()->Refresh();
1058  }
1059 }
1060 
1061 bool FOOTPRINT_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
1062 {
1063  if( ! Clear_Pcb( true ) )
1064  return false; // //this command is aborted
1065 
1066  SetCrossHairPosition( wxPoint( 0, 0 ) );
1067  Import_Module( aFileSet[0] );
1068 
1069  if( GetBoard()->m_Modules )
1071 
1072  GetScreen()->ClrModify();
1073  Zoom_Automatique( false );
1074  m_canvas->Refresh();
1075 
1076  return true;
1077 }
1078 
1079 
1081 {
1082  const std::string& payload = mail.GetPayload();
1083 
1084  switch( mail.Command() )
1085  {
1086  case MAIL_FP_EDIT:
1087  if( !payload.empty() )
1088  {
1089  wxFileName fpFileName( payload );
1090  wxString libNickname;
1091  wxString msg;
1092 
1093  FP_LIB_TABLE* libTable = Prj().PcbFootprintLibs();
1094  const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( fpFileName.GetPath() );
1095 
1096  if( !libTableRow )
1097  {
1098  msg.Printf( _( "The current configuration does not include the footprint library\n"
1099  "\"%s\".\nUse Manage Footprint Libraries to edit the configuration." ),
1100  fpFileName.GetPath() );
1101  DisplayErrorMessage( this, _( "Library not found in footprint library table." ), msg );
1102  break;
1103  }
1104 
1105  libNickname = libTableRow->GetNickName();
1106 
1107  if( !libTable->HasLibrary( libNickname, true ) )
1108  {
1109  msg.Printf( _( "The library with the nickname \"%s\" is not enabled\n"
1110  "in the current configuration. Use Manage Footprint Libraries to\n"
1111  "edit the configuration." ), libNickname );
1112  DisplayErrorMessage( this, _( "Footprint library not enabled." ), msg );
1113  break;
1114  }
1115 
1116  LIB_ID fpId( libNickname, fpFileName.GetName() );
1117 
1118  if( m_treePane )
1119  {
1120  m_treePane->GetLibTree()->SelectLibId( fpId );
1121  wxCommandEvent event( COMPONENT_SELECTED );
1122  wxPostEvent( m_treePane, event );
1123  }
1124  }
1125 
1126  break;
1127 
1128  default:
1129  ;
1130  }
1131 }
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:729
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:513
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
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:1594
bool InvokeDXFDialogModuleImport(PCB_BASE_FRAME *aCaller, MODULE *aModule)
Function InvokeDXFDialogModuleImport shows the modal DIALOG_DXF_IMPORT for importing a DXF file as fo...
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:305
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:193
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:512
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
const LIB_TABLE_ROW * FindRowByURI(const wxString &aURI)
The common library.
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)
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:248
#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:386
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:184
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:194
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