KiCad PCB EDA Suite
modedit.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 <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 <wxPcbStruct.h>
40 #include <kicad_device_context.h>
41 #include <macros.h>
42 #include <invoke_pcb_dialog.h>
43 #include <class_pcb_layer_widget.h>
44 #include <board_commit.h>
45 
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 <module_editor_frame.h>
55 #include <modview_frame.h>
56 #include <collectors.h>
57 #include <tool/tool_manager.h>
58 #include <tools/pcb_actions.h>
59 
61 #include <dialog_move_exact.h>
62 #include <dialog_create_array.h>
64 #include <menus_helpers.h>
65 #include <footprint_wizard_frame.h>
66 #include <pcbnew_config.h>
67 
68 #include <functional>
69 using namespace std::placeholders;
70 
71 
72 // Functions defined in block_module_editor, but used here
73 // These 3 functions are used in modedit to rotate, mirror or move the
74 // whole footprint so they are called with force_all = true
75 void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
76 void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
77 void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
78  const wxPoint& translation, double rotation,
79  bool force_all = false );
80 
81 
83 {
84  BOARD_ITEM* item = GetCurItem();
85 
86  if( GetBoard()->m_Modules == NULL )
87  return NULL;
88 
89  GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
90 
91  // Assign to scanList the proper item types desired based on tool type
92  // or hotkey that is in play.
93 
94  const KICAD_T* scanList = NULL;
95 
96  if( aHotKeyCode )
97  {
98  // @todo: add switch here and add calls to PcbGeneralLocateAndDisplay(
99  // int aHotKeyCode ) when searching is needed from a hotkey handler
100  }
101  else
102  {
104  }
105 
106  m_Collector->Collect( GetBoard(), scanList, RefPos( true ), guide );
107 
108  // Remove redundancies: when an item is found, we can remove the module from list
109  if( m_Collector->GetCount() > 1 )
110  {
111  for( int ii = 0; ii < m_Collector->GetCount(); ii++ )
112  {
113  item = (*m_Collector)[ii];
114 
115  if( item->Type() != PCB_MODULE_T )
116  continue;
117 
118  m_Collector->Remove( ii );
119  ii--;
120  }
121  }
122 
123  if( m_Collector->GetCount() <= 1 )
124  {
125  item = (*m_Collector)[0];
126  SetCurItem( item );
127  }
128  else // we can't figure out which item user wants, do popup menu so user can choose
129  {
130  wxMenu itemMenu;
131 
132  // Give a title to the selection menu. It also allow to close the popup menu without any action
133  AddMenuItem( &itemMenu, wxID_NONE, _( "Clarify Selection" ),
134  KiBitmap( info_xpm ) );
135  itemMenu.AppendSeparator();
136 
137  int limit = std::min( MAX_ITEMS_IN_PICKER, m_Collector->GetCount() );
138 
139  for( int ii = 0; ii<limit; ++ii )
140  {
141  item = (*m_Collector)[ii];
142 
143  wxString text = item->GetSelectMenuText();
144  BITMAP_DEF xpm = item->GetMenuImage();
145 
146  AddMenuItem( &itemMenu,
148  text,
149  KiBitmap( xpm ) );
150  }
151 
152  // this menu's handler is void
153  // PCB_BASE_FRAME::ProcessItemSelection()
154  // and it calls SetCurItem() which in turn calls DisplayInfo() on the
155  // item.
156  m_canvas->SetAbortRequest( true ); // changed in false if an item is selected
157  PopupMenu( &itemMenu ); // m_AbortRequest = false if an item is selected
158 
159  m_canvas->MoveCursorToCrossHair();
160  m_canvas->SetIgnoreMouseEvents( false );
161 
162  // The function ProcessItemSelection() has set the current item, return it.
163  item = GetCurItem();
164  }
165 
166  if( item )
167  {
168  SetMsgPanel( item );
169  }
170 
171  return item;
172 }
173 
174 
175 void FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard( wxCommandEvent& event )
176 {
177  if( GetScreen()->IsModify() )
178  {
179  if( !IsOK( this,
180  _( "Current footprint changes will be lost and this operation cannot be undone. Continue?" ) ) )
181  return;
182  }
183 
184  if( ! Load_Module_From_BOARD( NULL ) )
185  return;
186 
187  GetScreen()->ClearUndoRedoList();
188  GetScreen()->ClrModify();
189 
190  EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
191 
192  if( draw3DFrame )
193  draw3DFrame->NewDisplay( true );
194 }
195 
196 
198 {
199  int id = event.GetId();
200  wxPoint pos;
201 
202  INSTALL_UNBUFFERED_DC( dc, m_canvas );
203 
204  wxGetMousePosition( &pos.x, &pos.y );
205 
206  pos.y += 20;
207 
208  switch( id )
209  {
210  case wxID_CUT:
211  case wxID_COPY:
234  case ID_POPUP_ZOOM_BLOCK:
237  case ID_POPUP_COPY_BLOCK:
238  break;
239 
241  default:
242  if( m_canvas->IsMouseCaptured() )
243  {
244  // for all other commands: stop the move in progress
245  m_canvas->CallEndMouseCapture( &dc );
246  }
247 
249  SetNoToolSelected();
250 
251  break;
252  }
253 
254  switch( id )
255  {
256  case ID_EXIT:
257  Close( true );
258  break;
259 
261  {
262  wxString library = SelectLibrary( GetCurrentLib() );
263 
264  if( library.size() )
265  {
267  updateTitle();
268  }
269  }
270  break;
271 
273  {
275 
276  if( !viewer )
277  {
279  viewer->Show( true );
280  viewer->Zoom_Automatique( false );
281  }
282  else
283  {
284  // On Windows, Raise() does not bring the window on screen, when iconized
285  if( viewer->IsIconized() )
286  viewer->Iconize( false );
287 
288  viewer->Raise();
289 
290  // Raising the window does not set the focus on Linux. This should work on
291  // any platform.
292  if( wxWindow::FindFocus() != viewer )
293  viewer->SetFocus();
294  }
295  }
296  break;
297 
299  DeleteModuleFromCurrentLibrary();
300  break;
301 
303  {
304  if( !Clear_Pcb( true ) )
305  break;
306 
307  SetCrossHairPosition( wxPoint( 0, 0 ) );
308 
309  MODULE* module = CreateNewModule( wxEmptyString );
310 
311  if( module ) // i.e. if create module command not aborted
312  {
313  // Initialize data relative to nets and netclasses (for a new
314  // module the defaults are used)
315  // This is mandatory to handle and draw pads
317  module->SetPosition( wxPoint( 0, 0 ) );
318 
319  if( GetBoard()->m_Modules )
321 
322  Zoom_Automatique( false );
323  }
324 
325  updateView();
326  m_canvas->Refresh();
327 
328  GetScreen()->ClrModify();
329  }
330  break;
331 
333  {
334  if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
335  {
336  if( !IsOK( this,
337  _( "Current Footprint will be lost and this operation cannot be undone. Continue ?" ) ) )
338  break;
339  }
340 
342  FRAME_PCB_FOOTPRINT_WIZARD_MODAL, true, this );
343 
344  if( wizard->ShowModal( NULL, this ) )
345  {
346  // Creates the new footprint from python script wizard
347  MODULE* module = wizard->GetBuiltFootprint();
348 
349  if( module == NULL ) // i.e. if create module command aborted
350  break;
351 
352  Clear_Pcb( false );
353 
354  SetCrossHairPosition( wxPoint( 0, 0 ) );
355 
356  // Add the new object to board
357  GetBoard()->Add( module, ADD_APPEND );
358 
359  // Initialize data relative to nets and netclasses (for a new
360  // module the defaults are used)
361  // This is mandatory to handle and draw pads
363  module->SetPosition( wxPoint( 0, 0 ) );
364  module->ClearFlags();
365 
366  Zoom_Automatique( false );
367  updateView();
368  m_canvas->Refresh();
369 
370  EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
371 
372  if( draw3DFrame )
373  draw3DFrame->NewDisplay( true );
374 
375  GetScreen()->ClrModify();
376  }
377 
378  wizard->Destroy();
379  }
380  break;
381 
383  if( GetBoard()->m_Modules && GetCurrentLib().size() )
384  {
385  SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules, true, true );
386  GetScreen()->ClrModify();
387  }
388  break;
389 
392  {
393  // update module in the current board,
394  // not just add it to the board with total disregard for the netlist...
395  PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
396 
397  if( pcbframe == NULL ) // happens when the board editor is not active (or closed)
398  {
399  wxMessageBox( _("No board currently edited" ) );
400  break;
401  }
402 
403  BOARD* mainpcb = pcbframe->GetBoard();
404  MODULE* source_module = NULL;
405  MODULE* module_in_edit = GetBoard()->m_Modules;
406 
407  // Search the old module (source) if exists
408  // Because this source could be deleted when editing the main board...
409  if( module_in_edit->GetLink() ) // this is not a new module ...
410  {
411  source_module = mainpcb->m_Modules;
412 
413  for( ; source_module != NULL; source_module = source_module->Next() )
414  {
415  if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
416  break;
417  }
418  }
419 
420  if( ( source_module == NULL )
421  && ( id == ID_MODEDIT_UPDATE_MODULE_IN_BOARD ) ) // source not found
422  {
423  wxString msg;
424  msg.Printf( _( "Unable to find the footprint source on the main board" ) );
425  msg << _( "\nCannot update the footprint" );
426  DisplayError( this, msg );
427  break;
428  }
429 
430  if( ( source_module != NULL )
431  && ( id == ID_MODEDIT_INSERT_MODULE_IN_BOARD ) ) // source not found
432  {
433  wxString msg;
434  msg.Printf( _( "A footprint source was found on the main board" ) );
435  msg << _( "\nCannot insert this footprint" );
436  DisplayError( this, msg );
437  break;
438  }
439 
440  m_toolManager->RunAction( PCB_ACTIONS::selectionClear, true );
442  BOARD_COMMIT commit( pcbframe );
443 
444  // Create the "new" module
445  MODULE* newmodule = new MODULE( *module_in_edit );
446  newmodule->SetParent( mainpcb );
447  newmodule->SetLink( 0 );
448 
449  if( source_module ) // this is an update command
450  {
451  // In the main board,
452  // the new module replace the old module (pos, orient, ref, value
453  // and connexions are kept)
454  // and the source_module (old module) is deleted
455  pcbframe->Exchange_Module( source_module, newmodule, commit );
456  newmodule->SetTimeStamp( module_in_edit->GetLink() );
457  commit.Push( wxT( "Update module" ) );
458  }
459  else // This is an insert command
460  {
461  wxPoint cursor_pos = pcbframe->GetCrossHairPosition();
462 
463  commit.Add( newmodule );
464  pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
465  pcbframe->PlaceModule( newmodule, NULL );
466  newmodule->SetPosition( wxPoint( 0, 0 ) );
467  pcbframe->SetCrossHairPosition( cursor_pos );
468  newmodule->SetTimeStamp( GetNewTimeStamp() );
469  commit.Push( wxT( "Insert module" ) );
470  }
471 
472  newmodule->ClearFlags();
473  GetScreen()->ClrModify();
474  pcbframe->SetCurItem( NULL );
475  // @todo LEGACY should be unnecessary
476  mainpcb->m_Status_Pcb = 0;
477  }
478  break;
479 
481  if( ! Clear_Pcb( true ) )
482  break; // //this command is aborted
483 
484  SetCrossHairPosition( wxPoint( 0, 0 ) );
485  Import_Module();
486 
487  if( GetBoard()->m_Modules )
489 
490  GetScreen()->ClrModify();
491  Zoom_Automatique( false );
492  m_canvas->Refresh();
493  {
494  EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
495 
496  if( draw3DFrame )
497  draw3DFrame->NewDisplay( true );
498  }
499 
500  break;
501 
503  if( GetBoard()->m_Modules )
504  Export_Module( GetBoard()->m_Modules );
505  break;
506 
508  if( GetBoard()->m_Modules )
509  {
510  // CreateModuleLibrary() only creates a new library, does not save footprint
511  wxString libPath = CreateNewLibrary();
512  if( libPath.size() )
513  SaveCurrentModule( &libPath );
514  }
515  break;
516 
518  break;
519 
521  wxLogDebug( wxT( "Loading module from library " ) + getLibPath() );
522 
523  if( ! Clear_Pcb( true ) )
524  break;
525 
526  SetCrossHairPosition( wxPoint( 0, 0 ) );
527 
528  LoadModuleFromLibrary( GetCurrentLib(), Prj().PcbFootprintLibs(), true );
529 
530  if( GetBoard() && GetBoard()->m_Modules )
531  {
533 
534  // if either m_Reference or m_Value are gone, reinstall them -
535  // otherwise you cannot see what you are doing on board
537  TEXTE_MODULE* val = &GetBoard()->m_Modules->Value();
538 
539  if( val && ref )
540  {
541  ref->SetType( TEXTE_MODULE::TEXT_is_REFERENCE ); // just in case ...
542 
543  if( ref->GetLength() == 0 )
544  ref->SetText( wxT( "Ref**" ) );
545 
546  val->SetType( TEXTE_MODULE::TEXT_is_VALUE ); // just in case ...
547 
548  if( val->GetLength() == 0 )
549  val->SetText( wxT( "Val**" ) );
550  }
551  }
552 
553  Zoom_Automatique( false );
554 
555  {
556  EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
557 
558  if( draw3DFrame )
559  draw3DFrame->NewDisplay( true );
560  }
561 
562  GetScreen()->ClrModify();
563 
564  updateView();
565  m_canvas->Refresh();
566 
567  break;
568 
570  InstallPadOptionsFrame( NULL );
571  break;
572 
573  case ID_MODEDIT_CHECK:
574  // Currently: not implemented
575  break;
576 
578  if( GetBoard()->m_Modules )
579  {
580  SetCurItem( GetBoard()->m_Modules );
581 
582  DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
583 
584  dialog.ShowModal();
585  GetScreen()->GetCurItem()->ClearFlags();
586 
587  m_canvas->Refresh();
588  }
589  break;
590 
592  break;
593 
595  break;
596 
598  m_canvas->MoveCursorToCrossHair();
599  Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), 900, true );
600  m_canvas->Refresh();
601  break;
602 
604  m_canvas->MoveCursorToCrossHair();
605  Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), -900, true );
606  m_canvas->Refresh();
607  break;
608 
610  {
611  DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
612  dialog.ShowModal();
613  GetScreen()->GetCurItem()->ClearFlags();
614  m_canvas->MoveCursorToCrossHair();
615  m_canvas->Refresh();
616  }
617  break;
618 
620  m_canvas->MoveCursorToCrossHair();
621  StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
622  break;
623 
625  InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() );
626  m_canvas->MoveCursorToCrossHair();
627  break;
628 
630  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
631  DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
632  SetCurItem( NULL );
633  m_canvas->MoveCursorToCrossHair();
634  break;
635 
637  duplicateItems( false );
638  break;
639 
641  duplicateItems( true );
642  break;
643 
645  moveExact();
646  break;
647 
649  createArray();
650  break;
651 
653  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
654  m_canvas->MoveCursorToCrossHair();
655  Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
656  break;
657 
659  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
660  // Calls the global change dialog:
661  DlgGlobalChange_PadSettings( (D_PAD*) GetScreen()->GetCurItem() );
662  m_canvas->MoveCursorToCrossHair();
663  break;
664 
666  m_canvas->MoveCursorToCrossHair();
667  Export_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem() );
668  break;
669 
671  InstallTextModOptionsFrame( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
672  m_canvas->MoveCursorToCrossHair();
673  break;
674 
676  m_canvas->MoveCursorToCrossHair();
677  StartMoveTexteModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
678  break;
679 
681  RotateTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
682  m_canvas->MoveCursorToCrossHair();
683  break;
684 
686  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
687  DeleteTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ) );
688  SetCurItem( NULL );
689  m_canvas->MoveCursorToCrossHair();
690  break;
691 
693  Start_Move_EdgeMod( static_cast<EDGE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
694  m_canvas->MoveCursorToCrossHair();
695  break;
696 
698  m_canvas->MoveCursorToCrossHair();
699 
700  if( GetScreen()->GetCurItem()->IsNew() )
701  {
702  End_Edge_Module( (EDGE_MODULE*) GetScreen()->GetCurItem() );
703  SetCurItem( NULL );
704  }
705  break;
706 
708  {
709  EDGE_MODULE* edge = NULL;
710 
711  if( GetScreen()->GetCurItem()
712  && ( GetScreen()->GetCurItem()->Type() == PCB_MODULE_EDGE_T ) )
713  {
714  edge = (EDGE_MODULE*) GetScreen()->GetCurItem();
715  }
716 
717  Enter_Edge_Width( edge );
718  m_canvas->MoveCursorToCrossHair();
719 
720  if( edge )
721  m_canvas->Refresh();
722  }
723  break;
724 
726  m_canvas->MoveCursorToCrossHair();
727  InstallFootprintBodyItemPropertiesDlg( (EDGE_MODULE*) GetScreen()->GetCurItem() );
728  m_canvas->Refresh();
729  break;
730 
732  m_canvas->MoveCursorToCrossHair();
733  Edit_Edge_Width( NULL );
734  m_canvas->Refresh();
735  break;
736 
738  m_canvas->MoveCursorToCrossHair();
739  Edit_Edge_Layer( NULL );
740  m_canvas->Refresh();
741  break;
742 
744  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
745  m_canvas->MoveCursorToCrossHair();
746  RemoveStruct( GetScreen()->GetCurItem() );
747  SetCurItem( NULL );
748  break;
749 
753  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
754  Transform( (MODULE*) GetScreen()->GetCurItem(), id );
755  m_canvas->Refresh();
756  break;
757 
759  InstallOptionsFrame( pos );
760  break;
761 
762  case ID_PCB_PAD_SETUP:
763  {
764  BOARD_ITEM* item = GetCurItem();
765 
766  if( item )
767  {
768  if( item->Type() != PCB_PAD_T )
769  item = NULL;
770  }
771 
772  InstallPadOptionsFrame( (D_PAD*) item );
773  }
774  break;
775 
777  InvokeDialogGrid();
778  break;
779 
781  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
782  m_canvas->SetAutoPanRequest( false );
783  HandleBlockPlace( &dc );
784  break;
785 
786  case ID_POPUP_COPY_BLOCK:
787  GetScreen()->m_BlockLocate.SetCommand( BLOCK_COPY );
788  GetScreen()->m_BlockLocate.SetMessageBlock( this );
789  m_canvas->SetAutoPanRequest( false );
790  HandleBlockPlace( &dc );
791  break;
792 
793  case ID_POPUP_ZOOM_BLOCK:
794  GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
795  GetScreen()->m_BlockLocate.SetMessageBlock( this );
796  HandleBlockEnd( &dc );
797  break;
798 
800  GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
801  GetScreen()->m_BlockLocate.SetMessageBlock( this );
802  HandleBlockEnd( &dc );
803  break;
804 
806  GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
807  GetScreen()->m_BlockLocate.SetMessageBlock( this );
808  HandleBlockEnd( &dc );
809  break;
810 
812  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
813  GetScreen()->m_BlockLocate.SetMessageBlock( this );
814  HandleBlockEnd( &dc );
815  break;
816 
818  GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE_EXACT );
819  GetScreen()->m_BlockLocate.SetMessageBlock( this );
820  HandleBlockEnd( &dc );
821  break;
822 
824  if( GetBoard()->m_Modules )
825  {
826  InvokeDXFDialogModuleImport( this, GetBoard()->m_Modules );
827  m_canvas->Refresh();
828  }
829  break;
830 
831  default:
832  DisplayError( this,
833  wxT( "FOOTPRINT_EDIT_FRAME::Process_Special_Functions error" ) );
834  break;
835  }
836 }
837 
838 
840 {
841  MOVE_PARAMETERS params;
842  params.allowOverride = false;
843  params.editingFootprint = true;
844 
845  DIALOG_MOVE_EXACT dialog( this, params );
846  int ret = dialog.ShowModal();
847 
848  if( ret == wxID_OK )
849  {
850  SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
851 
852  BOARD_ITEM* item = GetScreen()->GetCurItem();
853 
854  wxPoint anchorPoint = item->GetPosition();
855  wxPoint origin;
856 
857  switch( params.origin )
858  {
860  origin = GetScreen()->m_O_Curseur;
861  break;
862 
864  origin = GetGridOrigin();
865  break;
866 
868  origin = GetAuxOrigin();
869  break;
870 
872  origin = wxPoint( 0, 0 );
873  break;
874 
876  // relative movement means that only the translation values should be used:
877  // -> set origin and anchor to zero
878  origin = wxPoint( 0, 0 );
879  anchorPoint = wxPoint( 0, 0 );
880  break;
881  }
882 
883  wxPoint finalMoveVector = params.translation + origin - anchorPoint;
884 
885  item->Move( finalMoveVector );
886  item->Rotate( item->GetPosition(), params.rotation );
887  m_canvas->Refresh();
888  }
889 
890  m_canvas->MoveCursorToCrossHair();
891 }
892 
893 
895 {
896  BOARD_ITEM* item = GetScreen()->GetCurItem();
897 
898  PCB_BASE_EDIT_FRAME::duplicateItem( item, aIncrement );
899 }
900 
901 
902 void FOOTPRINT_EDIT_FRAME::Transform( MODULE* module, int transform )
903 {
904  switch( transform )
905  {
907  RotateMarkedItems( module, wxPoint(0,0), true );
908  break;
909 
911  MirrorMarkedItems( module, wxPoint(0,0), true );
912  break;
913 
915  {
916  MOVE_PARAMETERS params;
917 
918  DIALOG_MOVE_EXACT dialog( this, params );
919  int ret = dialog.ShowModal();
920 
921  if( ret == wxID_OK )
922  {
923  MoveMarkedItemsExactly( module, wxPoint( 0, 0 ),
924  params.translation, params.rotation, true );
925  }
926 
927  break;
928  }
929 
930  default:
931  DisplayInfoMessage( this, wxT( "Not available" ) );
932  break;
933  }
934 
935  module->CalculateBoundingBox();
936  OnModify();
937 }
938 
939 
940 void FOOTPRINT_EDIT_FRAME::OnVerticalToolbar( wxCommandEvent& aEvent )
941 {
942  int id = aEvent.GetId();
943  int lastToolID = GetToolId();
944 
945  // Stop the current command and deselect the current tool.
946  SetNoToolSelected();
947 
948  switch( id )
949  {
950  case ID_NO_TOOL_SELECTED:
951  break;
952 
953  case ID_ZOOM_SELECTION:
954  // This tool is located on the main toolbar: switch it on or off on click on it
955  if( lastToolID != ID_ZOOM_SELECTION )
956  SetToolID( ID_ZOOM_SELECTION, wxCURSOR_MAGNIFIER, _( "Zoom to selection" ) );
957  else
958  SetNoToolSelected();
959  break;
960 
962  SetToolID( id, wxCURSOR_PENCIL, _( "Add line" ) );
963  break;
964 
965  case ID_MODEDIT_ARC_TOOL:
966  SetToolID( id, wxCURSOR_PENCIL, _( "Add arc" ) );
967  break;
968 
970  SetToolID( id, wxCURSOR_PENCIL, _( "Add circle" ) );
971  break;
972 
974  SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
975  break;
976 
978  SetToolID( id, wxCURSOR_PENCIL, _( "Place anchor" ) );
979  break;
980 
982  SetToolID( id, wxCURSOR_PENCIL, _( "Set grid origin" ) );
983  break;
984 
985  case ID_MODEDIT_PAD_TOOL:
986  if( GetBoard()->m_Modules )
987  {
988  SetToolID( id, wxCURSOR_PENCIL, _( "Add pad" ) );
989  }
990  else
991  {
992  SetToolID( id, wxCURSOR_ARROW, _( "Pad settings" ) );
993  InstallPadOptionsFrame( NULL );
994  SetNoToolSelected();
995  }
996  break;
997 
999  SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
1000  break;
1001 
1003  DisplayError( this, wxT( "Unsupported tool in legacy canvas" ) );
1004  SetNoToolSelected();
1005  break;
1006 
1007  default:
1008  wxFAIL_MSG( wxT( "Unknown command id." ) );
1009  SetNoToolSelected();
1010  }
1011 }
1012 
1013 
1015 {
1017 }
1018 
1019 
1021 {
1023 
1024  m_Layers->SelectLayer( GetActiveLayer() );
1025  m_Layers->OnLayerSelected();
1026 
1027  if( IsGalCanvasActive() )
1028  {
1029  GetGalCanvas()->SetHighContrastLayer( aLayer );
1030  GetGalCanvas()->Refresh();
1031  }
1032 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
BOARD_ITEM * ModeditLocateAndDisplay(int aHotKeyCode=0)
Definition: modedit.cpp:82
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
int GetLength() const
void BuildListOfNets()
Definition: class_board.h:736
Class FOOTPRINT_WIZARD_FRAME.
Definition of class FOOTPRINT_EDIT_FRAME.
TEXTE_MODULE & Reference()
Definition: class_module.h:463
PNG memory record (file in memory).
Definition: bitmap_types.h:38
This file is part of the common library TODO brief description.
void SetActiveLayer(PCB_LAYER_ID aLayer) override
>
Definition: modedit.cpp:1020
void OnVerticalToolbar(wxCommandEvent &aEvent)
Definition: modedit.cpp:940
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...
void Exchange_Module(MODULE *aOldModule, MODULE *aNewModule, BOARD_COMMIT &aCommit)
Function Exchange_Module Replaces OldModule by NewModule, using OldModule settings: position...
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
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:55
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
PROJECT & Prj()
Definition: kicad.cpp:293
Class BOARD to handle a board.
Class that computes missing connections on a PCB.
Component library viewer main window.
Definition: modview_frame.h:44
MODULE * Next() const
Definition: class_module.h:100
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
time_t GetNewTimeStamp()
Definition: common.cpp:166
MOVE_EXACT_ORIGIN origin
virtual const wxPoint & GetPosition() const =0
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
BOARD * GetBoard() const
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
void duplicateItem(BOARD_ITEM *aItem, bool aIncrement)
Function duplicateItem Duplicate the specified item This function is shared between pcbnew and modedi...
Definition: edit.cpp:1641
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
Function duplicateItems Duplicate the item under the cursor.
Definition: modedit.cpp:894
void MoveMarkedItemsExactly(MODULE *module, const wxPoint &centre, const wxPoint &translation, double rotation, bool force_all=false)
virtual wxString GetSelectMenuText() const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true) override
Executes the changes.
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 ...
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
void SetTimeStamp(time_t aNewTimeStamp)
Definition: base_struct.h:203
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:282
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
void PlaceModule(MODULE *aModule, wxDC *aDC, bool aDoNotRecreateRatsnest=false)
Function PlaceModule places aModule at the current cursor position and updates module coordinates wit...
Definition: modules.cpp:352
Definition: id.h:109
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:36
void Zoom_Automatique(bool aWarpPointer)
Function Zoom_Automatique redraws the screen with best zoom level and the best centering that shows a...
Definition: zoom.cpp:77
class MODULE, a footprint
Definition: typeinfo.h:101
PCB_LAYER_ID
A quick note on layer IDs:
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, KIWAY_PLAYER *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:302
a helper to handle the real device context used in KiCad
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:213
virtual void Move(const wxPoint &aMoveVector)
Function Move move this object.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:462
time_t GetLink() const
Definition: class_module.h:527
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
The common library.
Configuration parameters for Pcbnew.
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.
virtual COLOR4D GetGridColor() const override
Function GetGridColor() , virtual.
Definition: modedit.cpp:1014
void moveExact()
Function moveExact Move the selected item exactly, popping up a dialog to allow the user the enter th...
Definition: modedit.cpp:839
COLORS_DESIGN_SETTINGS g_ColorsSettings
Definition: pcbnew.cpp:68
void SetType(TEXT_TYPE aType)
time_t GetTimeStamp() const
Definition: base_struct.h:204
VTBL_ENTRY void SetRString(RSTRING_T aStringId, const wxString &aString)
Function SetRString stores a "retained string", which is any session and project specific string iden...
Definition: project.cpp:162
BOARD * GetBoard()
void Process_Special_Functions(wxCommandEvent &event)
Definition: modedit.cpp:197
void DisplayInfoMessage(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:89
TOOL_MANAGER * GetToolManager() const
Function GetToolManager returns the tool manager instance, if any.
Definition: draw_frame.h:824
see class PGM_BASE
void LoadModuleFromBoard(wxCommandEvent &event)
Function LoadModuleFromBoard called from the main toolbar to load a footprint from board mainly to ed...
Definition: modedit.cpp:175
Declaration of the eda_3d_viewer class.
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
DLIST< MODULE > m_Modules
Definition: class_board.h:245
#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...
void SetLink(time_t aLink)
Definition: class_module.h:528
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:254
Class EDA_3D_VIEWER Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard...
Definition: eda_3d_viewer.h:50
#define MAX_ITEMS_IN_PICKER
Command IDs for the printed circuit board editor.
Definition: pcbnew_id.h:14
Module description (excepted pads)
Class GENERAL_COLLECTORS_GUIDE is a general implementation of a COLLECTORS_GUIDE. ...
Definition: collectors.h:378
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Function SetCrossHairPosition sets the screen cross hair position to aPosition in logical (drawing) u...
EDGE_MODULE class definition.
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:69
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:111
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...
virtual BITMAP_DEF GetMenuImage() const
Function GetMenuImage returns a pointer to an image to be used in menus.
void Transform(MODULE *module, int transform)
Function Transform performs a geometric transform on the current footprint.
Definition: modedit.cpp:902
#define min(a, b)
Definition: auxiliary.h:85
KIWAY Kiway
virtual void SetText(const wxString &aText)
Definition: eda_text.h:141
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:237
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39