KiCad PCB EDA Suite
hotkeys_board_editor.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) 2009 Jean-Pierre Charras, jp.charras@wanadoo.fr
5  * Copyright (C) 1992-2016 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 <pcb_edit_frame.h>
31 #include <class_drawpanel.h>
32 #include <confirm.h>
33 
34 #include <class_board.h>
35 #include <class_module.h>
36 #include <class_track.h>
37 #include <class_pcb_text.h>
38 #include <class_pcb_target.h>
39 #include <class_drawsegment.h>
40 #include <origin_viewitem.h>
41 
42 #include <pcbnew.h>
43 #include <pcbnew_id.h>
44 #include <hotkeys.h>
45 #include <class_zone.h>
46 #include <tool/tool_manager.h>
47 #include <tools/pcbnew_control.h>
48 
49 /* How to add a new hotkey:
50  * see hotkeys.cpp
51  */
52 
53 
55 {
57 
58  if( HK_Descr == NULL )
59  HK_Descr = GetDescriptorFromCommand( aCommand, board_edit_Hotkey_List );
60 
61  return HK_Descr;
62 }
63 
64 
65 bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition,
66  EDA_ITEM* aItem )
67 {
68  if( aHotkeyCode == 0 )
69  return false;
70 
71  bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
72  MODULE* module = NULL;
73  int evt_type = 0; //Used to post a wxCommandEvent on demand
74  PCB_SCREEN* screen = GetScreen();
75  auto displ_opts = (PCB_DISPLAY_OPTIONS*)GetDisplayOptions();
76 
77  /* Convert lower to upper case
78  * (the usual toupper function has problem with non ascii codes like function keys
79  */
80  if( (aHotkeyCode >= 'a') && (aHotkeyCode <= 'z') )
81  aHotkeyCode += 'A' - 'a';
82 
83  EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, common_Hotkey_List );
84 
85  if( HK_Descr == NULL )
86  HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, board_edit_Hotkey_List );
87 
88  if( HK_Descr == NULL )
89  return false;
90 
91  int hk_id = HK_Descr->m_Idcommand;
92 
93  // Create a wxCommandEvent that will be posted in some hot keys functions
94  wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
95  cmd.SetEventObject( this );
96 
97  LAYER_NUM ll;
98 
99  switch( hk_id )
100  {
101  default:
102  case HK_NOT_FOUND:
103  return false;
104 
105  case HK_LEFT_CLICK:
106  OnLeftClick( aDC, aPosition );
107  break;
108 
109  case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
110  OnLeftClick( aDC, aPosition );
111  OnLeftDClick( aDC, aPosition );
112  break;
113 
115  if( GetCanvas()->IsMouseCaptured() )
116  GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
117 
118  if( GetDesignSettings().GetTrackWidthIndex() < GetDesignSettings().m_TrackWidthList.size() - 1 )
119  GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() + 1 );
120  else
122 
123  if( GetCanvas()->IsMouseCaptured() )
124  GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
125 
126  break;
127 
129  if( GetCanvas()->IsMouseCaptured() )
130  GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
131 
132  if( GetDesignSettings().GetTrackWidthIndex() <= 0 )
133  GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().m_TrackWidthList.size() -1 );
134  else
135  GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() - 1 );
136 
137  if( GetCanvas()->IsMouseCaptured() )
138  GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
139 
140  break;
141 
143  SetFastGrid1();
144  break;
145 
147  SetFastGrid2();
148  break;
149 
151  SetNextGrid();
152  break;
153 
155  SetPrevGrid();
156  break;
157 
159  ll = GetActiveLayer();
160 
161  if( !IsCopperLayer( ll ) )
162  break;
163 
164  if( ll == F_Cu )
165  ll = B_Cu;
166  else if( ll == B_Cu )
167  ll = ToLAYER_ID( GetBoard()->GetCopperLayerCount() - 2 );
168  else
169  ll = ll - 1;
170 
171  SwitchLayer( aDC, ToLAYER_ID( ll ) );
172  break;
173 
175  ll = GetActiveLayer();
176 
177  if( !IsCopperLayer( ll ) )
178  break;
179 
180  if( ll == B_Cu )
181  ll = F_Cu;
182  else if( ++ll >= GetBoard()->GetCopperLayerCount() - 1 )
183  ll = B_Cu;
184 
185  SwitchLayer( aDC, ToLAYER_ID( ll ) );
186  break;
187 
189  SwitchLayer( aDC, F_Cu );
190  break;
191 
193  SwitchLayer( aDC, B_Cu );
194  break;
195 
197  SwitchLayer( aDC, In1_Cu );
198  break;
199 
201  SwitchLayer( aDC, In2_Cu );
202  break;
203 
205  SwitchLayer( aDC, In3_Cu );
206  break;
207 
209  SwitchLayer( aDC, In4_Cu );
210  break;
211 
213  SwitchLayer( aDC, In5_Cu );
214  break;
215 
217  SwitchLayer( aDC, In6_Cu );
218  break;
219 
220  case HK_HELP: // Display Current hotkey list
222  break;
223 
224  case HK_ZOOM_IN:
225  evt_type = ID_KEY_ZOOM_IN;
226  break;
227 
228  case HK_ZOOM_OUT:
229  evt_type = ID_KEY_ZOOM_OUT;
230  break;
231 
232  case HK_ZOOM_REDRAW:
233  evt_type = ID_ZOOM_REDRAW;
234  break;
235 
236  case HK_ZOOM_AUTO:
237  evt_type = ID_ZOOM_PAGE;
238  break;
239 
240  case HK_ZOOM_CENTER:
241  evt_type = ID_POPUP_ZOOM_CENTER;
242  break;
243 
244  case HK_ZOOM_SELECTION:
245  evt_type = ID_ZOOM_SELECTION;
246  break;
247 
248  case HK_ADD_MODULE:
249  evt_type = ID_PCB_MODULE_BUTT;
250  break;
251 
252  case HK_UNDO:
253  case HK_REDO:
254  if( !itemCurrentlyEdited )
255  {
256  wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
257  wxPostEvent( this, event );
258  }
259 
260  break;
261 
262  case HK_RESET_LOCAL_COORD: // Set the relative coord
264  break;
265 
266  case HK_SET_GRID_ORIGIN:
267  PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
270  m_canvas->Refresh();
271  break;
272 
274  PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
276  wxPoint( 0, 0 ) );
277  m_canvas->Refresh();
278  break;
279 
280  case HK_SWITCH_UNITS:
281  evt_type = (g_UserUnit == INCHES) ?
283  break;
284 
286  displ_opts->m_DisplayPcbTrackFill = !displ_opts->m_DisplayPcbTrackFill;
287  m_canvas->Refresh();
288  break;
289 
290  case HK_DELETE:
291  OnHotkeyDeleteItem( aDC );
292  break;
293 
294  case HK_BACK_SPACE:
295  if( IsCopperLayer( GetActiveLayer() ) )
296  {
297  if( !itemCurrentlyEdited )
298  {
299  // no track is currently being edited - select a segment and remove it.
300  // @todo: possibly? pass the HK command code to PcbGeneralLocateAndDisplay()
301  // so it can restrict its search to specific item types.
303 
304  // don't let backspace delete modules!!
305  if( item && item->IsTrack() )
306  {
307  Delete_Segment( aDC, (TRACK*) item );
308  SetCurItem( NULL );
309  }
310 
311  OnModify();
312  }
313  else if( GetCurItem()->IsTrack() )
314  {
315  // then an element is being edited - remove the last segment.
316  // simple lines for debugger:
317  TRACK* track = (TRACK*) GetCurItem();
318  track = Delete_Segment( aDC, track );
319  SetCurItem( track );
320  OnModify();
321  }
322  }
323 
324  break;
325 
327  if( !itemCurrentlyEdited )
329 
330  break;
331 
332  case HK_FIND_ITEM:
333  if( !itemCurrentlyEdited )
334  evt_type = ID_FIND_ITEMS;
335 
336  break;
337 
338  case HK_OPEN:
339  if( !itemCurrentlyEdited )
340  evt_type = ID_LOAD_FILE ;
341 
342  break;
343 
344  case HK_SAVE:
345  if( !itemCurrentlyEdited )
346  evt_type = ID_SAVE_BOARD;
347 
348  break;
349 
350  case HK_ADD_MICROVIA: // Place a micro via if a track is in progress
351  if( GetToolId() != ID_TRACK_BUTT )
352  return true;
353 
354  if( !itemCurrentlyEdited ) // no track in progress: nothing to do
355  break;
356 
357  if( GetCurItem()->Type() != PCB_TRACE_T ) // Should not occur
358  return true;
359 
360  if( !GetCurItem()->IsNew() )
361  return true;
362 
363  // place micro via and switch layer
364  if( IsMicroViaAcceptable() )
365  evt_type = ID_POPUP_PCB_PLACE_MICROVIA;
366 
367  break;
368 
370  case HK_ADD_THROUGH_VIA: // Switch to alternate layer and Place a via if a track is in progress
371  if( GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed &&
372  hk_id == HK_ADD_BLIND_BURIED_VIA )
374  else
376 
377  if( !itemCurrentlyEdited ) // no track in progress: switch layer only
378  {
379  Other_Layer_Route( NULL, aDC );
380  if( displ_opts->m_ContrastModeDisplay )
381  m_canvas->Refresh();
382  break;
383  }
384 
385  if( GetToolId() != ID_TRACK_BUTT )
386  return true;
387 
388  if( GetCurItem()->Type() != PCB_TRACE_T )
389  return true;
390 
391  if( !GetCurItem()->IsNew() )
392  return true;
393 
394  evt_type = hk_id == HK_ADD_BLIND_BURIED_VIA ?
396  break;
397 
400  if( GetCurItem() == NULL || !GetCurItem()->IsNew() ||
401  GetCurItem()->Type() != PCB_TRACE_T )
402  break;
403 
404  evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ?
407  break;
408 
410  /* change the position of initial segment when creating new tracks
411  * switch from _/ to -\ .
412  */
414  break;
415 
418  break;
419 
420  case HK_PLACE_ITEM:
421  OnHotkeyPlaceItem( aDC );
422  break;
423 
424  case HK_ADD_NEW_TRACK: // Start new track, if possible
425  OnHotkeyBeginRoute( aDC );
426  break;
427 
428  case HK_EDIT_ITEM: // Edit board item
430  break;
431 
432  case HK_EDIT_MODULE_WITH_MODEDIT: // Edit module with module editor
434  break;
435 
436  // Footprint edition:
437  case HK_LOCK_UNLOCK_FOOTPRINT: // toggle module "MODULE_is_LOCKED" status:
438  // get any module, locked or not locked and toggle its locked status
439  if( !itemCurrentlyEdited )
440  {
441  wxPoint pos = RefPos( true );
442  module = GetBoard()->GetFootprint( pos, screen->m_Active_Layer, true );
443  }
444  else if( GetCurItem()->Type() == PCB_MODULE_T )
445  {
446  module = (MODULE*) GetCurItem();
447  }
448 
449  if( module )
450  {
451  SetCurItem( module );
452  module->SetLocked( !module->IsLocked() );
453  OnModify();
454  SetMsgPanel( module );
455  }
456  break;
457 
458  case HK_DRAG_ITEM: // Start drag module or track segment
460  break;
461 
462  case HK_MOVE_ITEM: // Start move item
464  break;
465 
466  case HK_COPY_ITEM:
467  evt_type = OnHotkeyCopyItem();
468  break;
469 
470  case HK_ROTATE_ITEM: // Rotation
472  break;
473 
474  case HK_FLIP_ITEM:
476  break;
477 
478  case HK_MOVE_ITEM_EXACT:
479  case HK_DUPLICATE_ITEM:
481  case HK_CREATE_ARRAY:
483  break;
484 
485  case HK_SWITCH_HIGHCONTRAST_MODE: // switch to high contrast mode and refresh the canvas
486  displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay;
487  m_canvas->Refresh();
488  break;
489 
490  case HK_CANVAS_CAIRO:
491  evt_type = ID_MENU_CANVAS_CAIRO;
492  break;
493 
494  case HK_CANVAS_OPENGL:
495  evt_type = ID_MENU_CANVAS_OPENGL;
496  break;
497 
498  case HK_CANVAS_LEGACY:
499  evt_type = ID_MENU_CANVAS_LEGACY;
500  break;
501 
503  evt_type = ID_POPUP_PCB_FILL_ALL_ZONES;
504  break;
505 
508  break;
509  }
510 
511  if( evt_type != 0 )
512  {
513  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
514  evt.SetEventObject( this );
515  evt.SetId( evt_type );
516  GetEventHandler()->ProcessEvent( evt );
517  }
518 
519  return true;
520 }
521 
522 
524 {
525  BOARD_ITEM* item = GetCurItem();
526  bool ItemFree = (item == NULL) || (item->GetFlags() == 0);
527 
528  switch( GetToolId() )
529  {
530  case ID_TRACK_BUTT:
531  if( !IsCopperLayer ( GetActiveLayer() ) )
532  return false;
533 
534  if( ItemFree )
535  {
537 
538  if( item && !item->IsTrack() )
539  return false;
540 
541  Delete_Track( aDC, (TRACK*) item );
542  }
543  else if( item->IsTrack( ) )
544  {
545  // simple lines for debugger:
546  TRACK* track = (TRACK*) item;
547  track = Delete_Segment( aDC, track );
548  SetCurItem( track );
549  OnModify();
550  return true;
551  }
552  break;
553 
554  case ID_PCB_MODULE_BUTT:
555  if( ItemFree )
556  {
557  wxPoint pos = RefPos( false );
558  MODULE* module = GetBoard()->GetFootprint( pos, UNDEFINED_LAYER, false );
559 
560  if( module == NULL || module->IsLocked() )
561  return false;
562 
563  RemoveStruct( module, aDC );
564  }
565  else
566  return false;
567  break;
568 
569  default:
570  if( ItemFree )
571  {
573 
574  // Shouldn't there be a check for locked tracks and vias here?
575  if( item == NULL || (item->Type() == PCB_MODULE_T && (MODULE*)item->IsLocked()) )
576  return false;
577 
578  RemoveStruct( item, aDC );
579  }
580  else
581  return false;
582  }
583 
584  OnModify();
585  SetCurItem( NULL );
586  return true;
587 }
588 
589 
590 bool PCB_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
591 {
592  BOARD_ITEM* item = GetCurItem();
593  bool itemCurrentlyEdited = item && item->GetFlags();
594 
595  if( itemCurrentlyEdited )
596  return false;
597 
599 
600  if( item == NULL )
601  return false;
602 
603  SetCurItem( item );
604 
605  int evt_type = 0; //Used to post a wxCommandEvent on demand
606 
607  switch( item->Type() )
608  {
609  case PCB_TRACE_T:
610  case PCB_VIA_T:
611  if( aIdCommand == HK_EDIT_ITEM )
612  {
613  // Be sure the corresponding netclass is selected before edit:
614  SetCurrentNetClass( ( (BOARD_CONNECTED_ITEM*)item )->GetNetClassName() );
615  evt_type = ID_POPUP_PCB_EDIT_TRACKSEG;
616  }
617 
618  break;
619 
620  case PCB_TEXT_T:
621  if( aIdCommand == HK_EDIT_ITEM )
622  evt_type = ID_POPUP_PCB_EDIT_TEXTEPCB;
623 
624  break;
625 
626  case PCB_MODULE_T:
627  if( aIdCommand == HK_EDIT_ITEM )
629  else if( aIdCommand == HK_EDIT_MODULE_WITH_MODEDIT )
631 
632  break;
633 
634  case PCB_PAD_T:
635  // Until dec 2012 a EDIT_MODULE event is posted here to prevent pads
636  // from being edited by hotkeys.
637  // Process_Special_Functions takes care of finding the parent.
638  // After dec 2012 a EDIT_PAD event is posted, because there is no
639  // reason to not allow pad edit by hotkey
640  // (pad coordinates are no more modified by rounding, in nanometer version
641  // when using inches or mm in dialog)
642  if( aIdCommand == HK_EDIT_ITEM )
643  evt_type = ID_POPUP_PCB_EDIT_PAD;
644 
645  break;
646 
647  case PCB_TARGET_T:
648  if( aIdCommand == HK_EDIT_ITEM )
649  evt_type = ID_POPUP_PCB_EDIT_PCB_TARGET;
650 
651  break;
652 
653  case PCB_DIMENSION_T:
654  if( aIdCommand == HK_EDIT_ITEM )
655  evt_type = ID_POPUP_PCB_EDIT_DIMENSION;
656 
657  break;
658 
659  case PCB_MODULE_TEXT_T:
660  if( aIdCommand == HK_EDIT_ITEM )
661  evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE;
662 
663  break;
664 
665  case PCB_LINE_T:
666  if( aIdCommand == HK_EDIT_ITEM )
667  evt_type = ID_POPUP_PCB_EDIT_DRAWING;
668 
669  break;
670 
671  case PCB_ZONE_AREA_T:
672  if( aIdCommand == HK_EDIT_ITEM )
674 
675  break;
676 
677  default:
678  break;
679  }
680 
681  if( evt_type != 0 )
682  {
683  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
684  evt.SetEventObject( this );
685  evt.SetId( evt_type );
686  GetEventHandler()->ProcessEvent( evt );
687  return true;
688  }
689 
690  return false;
691 }
692 
693 
695 {
696  BOARD_ITEM* item = GetCurItem();
697  bool itemCurrentlyEdited = item && item->GetFlags();
698 
699  if( itemCurrentlyEdited )
700  return 0;
701 
703 
704  if( item == NULL )
705  return 0;
706 
707  SetCurItem( item );
708 
709  int eventId = 0;
710 
711  switch( item->Type() )
712  {
713  case PCB_TEXT_T:
714  eventId = ID_POPUP_PCB_COPY_TEXTEPCB;
715  break;
716  default:
717  eventId = 0;
718  break;
719  }
720 
721  return eventId;
722 }
723 
724 
725 bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
726 {
727  BOARD_ITEM* item = GetCurItem();
728  bool itemCurrentlyEdited = item && item->GetFlags();
729 
730  if( itemCurrentlyEdited )
731  return false;
732 
734 
735  if( item == NULL )
736  return false;
737 
738  SetCurItem( item );
739 
740  int evt_type = 0; // Used to post a wxCommandEvent on demand
741 
742  switch( item->Type() )
743  {
744  case PCB_TRACE_T:
745  case PCB_VIA_T:
746  if( aIdCommand == HK_MOVE_ITEM )
747  evt_type = ID_POPUP_PCB_MOVE_TRACK_NODE;
748 
749  if( aIdCommand == HK_DRAG_ITEM )
751 
752  if( aIdCommand == HK_DRAG_TRACK_KEEP_SLOPE )
754 
755  break;
756 
757  case PCB_MODULE_T:
758  {
759  if( aIdCommand == HK_MOVE_ITEM )
761 
762  if( aIdCommand == HK_DRAG_ITEM )
764  }
765  break;
766 
767  case PCB_PAD_T:
768  // Post MODULE_REQUEST events here to prevent pads
769  // from being moved or dragged by hotkeys.
770  // Process_Special_Functions takes care of finding
771  // the parent.
772  if( aIdCommand == HK_MOVE_ITEM )
774 
775  if( aIdCommand == HK_DRAG_ITEM )
777 
778  break;
779 
780  case PCB_TEXT_T:
781  if( aIdCommand == HK_MOVE_ITEM )
783 
784  break;
785 
786  case PCB_TARGET_T:
787  if( aIdCommand == HK_MOVE_ITEM )
789 
790  break;
791 
792  case PCB_ZONE_AREA_T:
793  if( aIdCommand == HK_MOVE_ITEM )
795 
796  if( aIdCommand == HK_DRAG_ITEM )
798 
799  break;
800 
801  case PCB_MODULE_TEXT_T:
802  if( aIdCommand == HK_MOVE_ITEM )
804 
805  break;
806 
807  case PCB_LINE_T:
808  if( aIdCommand == HK_MOVE_ITEM )
810 
811  break;
812 
813  case PCB_DIMENSION_T:
814  if( aIdCommand == HK_MOVE_ITEM )
816  break;
817 
818  default:
819  break;
820  }
821 
822  if( evt_type != 0 )
823  {
824  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
825  evt.SetEventObject( this );
826  evt.SetId( evt_type );
827  GetEventHandler()->ProcessEvent( evt );
828  return true;
829  }
830 
831  return false;
832 }
833 
834 
836 {
837  BOARD_ITEM* item = GetCurItem();
838  bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED;
839  bool itemCurrentlyEdited = item && item->GetFlags();
840 
841  m_canvas->SetAutoPanRequest( false );
842 
843  if( itemCurrentlyEdited )
844  {
846  m_canvas->CrossHairOff( aDC );
847 
848  switch( item->Type() )
849  {
850  case PCB_TRACE_T:
851  case PCB_VIA_T:
852  if( item->IsDragging() )
853  PlaceDraggedOrMovedTrackSegment( static_cast<TRACK*>( item ), aDC );
854 
855  break;
856 
857  case PCB_TEXT_T:
858  Place_Texte_Pcb( static_cast<TEXTE_PCB*>( item ), aDC );
859  break;
860 
861  case PCB_MODULE_TEXT_T:
862  PlaceTexteModule( static_cast<TEXTE_MODULE*>( item ), aDC );
863  break;
864 
865  case PCB_PAD_T:
866  PlacePad( static_cast<D_PAD*>( item ), aDC );
867  break;
868 
869  case PCB_MODULE_T:
870  PlaceModule( static_cast<MODULE*>( item ), aDC );
871  break;
872 
873  case PCB_TARGET_T:
874  PlaceTarget( static_cast<PCB_TARGET*>( item ), aDC );
875  break;
876 
877  case PCB_LINE_T:
878  if( no_tool ) // when no tools: existing item moving.
879  Place_DrawItem( static_cast<DRAWSEGMENT*>( item ), aDC );
880 
881  break;
882 
883  default:
884  break;
885  }
886 
887  m_canvas->SetIgnoreMouseEvents( false );
888  m_canvas->CrossHairOn( aDC );
889 
890  return true;
891  }
892 
893  return false;
894 }
895 
896 
898 {
899  if( !IsCopperLayer( GetActiveLayer() ) )
900  return NULL;
901 
902  bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
903 
904  // Ensure the track tool is active
905  if( GetToolId() != ID_TRACK_BUTT && !itemCurrentlyEdited )
906  {
907  wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
908  cmd.SetEventObject( this );
909  cmd.SetId( ID_TRACK_BUTT );
910  GetEventHandler()->ProcessEvent( cmd );
911  }
912 
913  if( GetToolId() != ID_TRACK_BUTT )
914  return NULL;
915 
916  TRACK* track = NULL;
917 
918  if( !itemCurrentlyEdited ) // no track in progress:
919  {
920  track = Begin_Route( NULL, aDC );
921  SetCurItem( track );
922 
923  if( track )
924  m_canvas->SetAutoPanRequest( true );
925  }
926  else if( GetCurItem()->IsNew() )
927  {
928  track = Begin_Route( (TRACK*) GetCurItem(), aDC );
929 
930  // SetCurItem() must not write to the msg panel
931  // because a track info is displayed while moving the mouse cursor
932  if( track ) // A new segment was created
933  SetCurItem( track, false );
934 
935  m_canvas->SetAutoPanRequest( true );
936  }
937 
938  return track;
939 }
940 
941 
942 bool PCB_EDIT_FRAME::OnHotkeyFlipItem( int aIdCommand )
943 {
944  BOARD_ITEM* item = GetCurItem();
945  bool itemCurrentlyEdited = item && item->GetFlags();
946  int evt_type = 0; // Used to post a wxCommandEvent on demand
947 
948  wxASSERT( aIdCommand == HK_FLIP_ITEM );
949 
950  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
951  {
952  evt_type = ID_POPUP_FLIP_BLOCK;
953  }
954  else
955  {
956  if( !itemCurrentlyEdited )
958 
959  if( item == NULL )
960  return false;
961 
962  SetCurItem( item );
963 
964  switch( item->Type() )
965  {
966  case PCB_MODULE_T:
968  break;
969 
970  case PCB_TEXT_T:
971  evt_type = ID_POPUP_PCB_FLIP_TEXTEPCB;
972  break;
973 
974  default:
975  break;
976  }
977  }
978 
979  if( evt_type != 0 )
980  {
981  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
982  evt.SetEventObject( this );
983  evt.SetId( evt_type );
984  GetEventHandler()->ProcessEvent( evt );
985  return true;
986  }
987  else
988  {
989  return false;
990  }
991 }
992 
993 
995 {
996  BOARD_ITEM* item = GetCurItem();
997  bool itemCurrentlyEdited = item && item->GetFlags();
998  int evt_type = 0; // Used to post a wxCommandEvent on demand
999 
1000  wxASSERT( aIdCommand == HK_ROTATE_ITEM );
1001 
1002  // Allows block rotate operation on hot key.
1003  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
1004  {
1005  evt_type = ID_POPUP_ROTATE_BLOCK;
1006  }
1007  else
1008  {
1009  if( !itemCurrentlyEdited )
1010  item = PcbGeneralLocateAndDisplay();
1011 
1012  if( item == NULL )
1013  return false;
1014 
1015  SetCurItem( item );
1016 
1017  switch( item->Type() )
1018  {
1019  case PCB_MODULE_T:
1021  break;
1022 
1023  case PCB_TEXT_T:
1024  evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB;
1025  break;
1026 
1027  case PCB_MODULE_TEXT_T:
1028  evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE;
1029  break;
1030 
1031  default:
1032  break;
1033  }
1034  }
1035 
1036  if( evt_type != 0 )
1037  {
1038  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
1039  evt.SetEventObject( this );
1040  evt.SetId( evt_type );
1041  GetEventHandler()->ProcessEvent( evt );
1042  return true;
1043  }
1044 
1045  return false;
1046 }
1047 
1048 
1050 {
1051  BOARD_ITEM* item = GetCurItem();
1052  bool itemCurrentlyEdited = item && item->GetFlags();
1053 
1054  if( itemCurrentlyEdited )
1055  return false;
1056 
1057  item = PcbGeneralLocateAndDisplay();
1058 
1059  if( item == NULL )
1060  return false;
1061 
1062  SetCurItem( item );
1063 
1064  int evt_type = 0; // Used to post a wxCommandEvent on demand
1065 
1066  bool canDuplicate = true;
1067 
1068  switch( item->Type() )
1069  {
1070  // Only handle items we know we can handle
1071  case PCB_PAD_T:
1072  canDuplicate = false;
1073  // no break
1074  case PCB_MODULE_T:
1075  case PCB_LINE_T:
1076  case PCB_TEXT_T:
1077  case PCB_TRACE_T:
1078  case PCB_ZONE_AREA_T:
1079  case PCB_TARGET_T:
1080  case PCB_DIMENSION_T:
1081  switch( aIdCommand )
1082  {
1083  case HK_CREATE_ARRAY:
1084  if( canDuplicate )
1085  evt_type = ID_POPUP_PCB_CREATE_ARRAY;
1086  break;
1087 
1089  if( canDuplicate )
1091  break;
1092 
1093  case HK_DUPLICATE_ITEM:
1094  if( canDuplicate )
1095  evt_type = ID_POPUP_PCB_DUPLICATE_ITEM;
1096  break;
1097 
1098  case HK_MOVE_ITEM_EXACT:
1099  evt_type = ID_POPUP_PCB_MOVE_EXACT;
1100  break;
1101 
1102  default:
1103  // We don't handle other commands here
1104  break;
1105  }
1106  break;
1107 
1108  default:
1109  evt_type = 0;
1110  break;
1111  }
1112 
1113  return PostCommandMenuEvent( evt_type );
1114 }
void Place_DrawItem(DRAWSEGMENT *drawitem, wxDC *DC)
Definition: editedge.cpp:74
KICAD_T Type() const
Function Type()
Definition: base_struct.h:227
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
bool Other_Layer_Route(TRACK *track, wxDC *DC)
Function Other_Layer_Route operates in one of two ways.
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:284
void SetTrackWidthIndex(unsigned aIndex)
Function SetTrackWidthIndex sets the current track width list index to aIndex.
VIATYPE_T m_CurrentViaType
via type (VIA_BLIND_BURIED, VIA_THROUGH VIA_MICROVIA)
TRACK * Delete_Segment(wxDC *DC, TRACK *Track)
Function Delete_Segment removes a track segment.
Definition: deltrack.cpp:45
TEXTE_PCB class definition.
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it bu a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:339
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...
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:342
bool OnHotkeyPlaceItem(wxDC *aDC)
Function OnHotkeyPlaceItem Place the item (footprint, track, text .
Class BOARD to handle a board.
void SetFastGrid2()
Function SetFastGrid2()
const wxPoint & GetGridOrigin() const override
Function GetGridOrigin returns the absolute coordinates of the origin of the snap grid...
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:102
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
BOARD * GetBoard() const
Classes to handle copper zones.
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
void SetNextGrid() override
Virtual function SetNextGrid() changes the grid size settings to the next one available.
TRACK * Begin_Route(TRACK *aTrack, wxDC *aDC)
Function Begin_Route Starts a new track and/or establish of a new track point.
Definition: editrack.cpp:98
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
int GetState(int type) const
Definition: base_struct.h:266
PCB_LAYER_ID m_Active_Layer
Definition: pcb_screen.h:44
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
void RemoveStruct(BOARD_ITEM *Item, wxDC *DC)
Definition: edit.cpp:1294
wxPoint m_O_Curseur
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:185
void PlacePad(D_PAD *Pad, wxDC *DC)
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void * GetDisplayOptions() override
Function GetDisplayOptions returns the display options current in use Display options are relative to...
Pcbnew hotkeys.
EDA_DRAW_FRAME::OnSelectGrid ID_TB_OPTIONS_SELECT_UNIT_INCH
Definition: draw_frame.cpp:122
void PlaceTarget(PCB_TARGET *aTarget, wxDC *DC)
void PlaceModule(MODULE *aModule, wxDC *aDC, bool aDoNotRecreateRatsnest=false)
Function PlaceModule places aModule at the current cursor position and updates module coordinates wit...
EDA_HOTKEY * GetDescriptorFromHotkey(int aKey, EDA_HOTKEY **aList)
Function GetDescriptorFromHotkey Return a EDA_HOTKEY * pointer from a key code for OnHotKey() functio...
void SetFastGrid1()
Function SetFastGrid1()
void Place_Texte_Pcb(TEXTE_PCB *TextePcb, wxDC *DC)
class MODULE, a footprint
Definition: typeinfo.h:89
void DisplayHotkeyList(EDA_BASE_FRAME *aFrame, struct EDA_HOTKEY_CONFIG *aDescList)
Function DisplayHotkeyList Displays the current hotkey list.
Class PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings...
bool OnHotkeyDuplicateOrArrayItem(int aIdCommand)
Function OnHotkeyDuplicateOrArrayItem Duplicate an item (optionally incrementing if necessary and pos...
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:790
bool OnHotkeyMoveItem(int aIdCommand)
Function OnHotkeyMoveItem Moves or drag the item (footprint, track, text .
void OnLeftDClick(wxDC *DC, const wxPoint &MousePos) override
Definition: common.h:145
EDA_HOTKEY * common_Hotkey_List[]
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
TRACK * OnHotkeyBeginRoute(wxDC *aDC)
Function OnHotkeyBeginRoute If the current active layer is a copper layer, and if no item currently e...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
struct EDA_HOTKEY_CONFIG g_Board_Editor_Hotkeys_Descr[]
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
bool OnHotkeyFlipItem(int aIdCommand)
Function OnHotkeyFlipItem Flip the item (text or footprint) found under the mouse cursor...
bool PostCommandMenuEvent(int evt_type)
Function PostCommandMenuEvent.
void SetAutoPanRequest(bool aEnable)
bool OnHotKey(wxDC *aDC, int aHotkeyCode, const wxPoint &aPosition, EDA_ITEM *aItem=NULL) override
Function OnHotKey.
bool PlaceDraggedOrMovedTrackSegment(TRACK *Track, wxDC *DC)
EDA_HOTKEY * board_edit_Hotkey_List[]
void CrossHairOff(wxDC *DC)
Definition: draw_panel.cpp:266
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
bool OnHotkeyDeleteItem(wxDC *aDC)
Function OnHotkeyDeleteItem Delete the item found under the mouse cursor Depending on the current act...
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:256
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:101
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
void PlaceTexteModule(TEXTE_MODULE *Text, wxDC *DC)
Definition: edtxtmod.cpp:227
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
bool OnHotkeyRotateItem(int aIdCommand)
Function OnHotkeyRotateItem Rotate the item (text or footprint) found under the mouse cursor...
wxPoint RefPos(bool useMouse) const
Function RefPos Return the reference position, coming from either the mouse position or the cursor po...
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:93
EDA_HOTKEY * GetHotKeyDescription(int aCommand) const override
>
void Delete_Track(wxDC *DC, TRACK *Track)
Definition: deltrack.cpp:140
bool OnHotkeyEditItem(int aIdCommand)
void CrossHairOn(wxDC *DC)
Definition: draw_panel.cpp:273
class EDA_HOTKEY is a class to handle hot key commands.
Definition: hotkeys_basic.h:57
void SetLocked(bool isLocked) override
Function SetLocked sets the MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition: class_module.h:266
Class to handle a graphic segment.
virtual bool IsLocked() const
Function IsLocked.
int GetToolId() const
Definition: draw_frame.h:476
void SetIgnoreMouseEvents(bool aIgnore)
static bool SetGridOrigin(KIGFX::VIEW *aView, PCB_BASE_FRAME *aFrame, BOARD_ITEM *originViewItem, const VECTOR2D &aPoint)
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:180
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
Definition: base_struct.h:155
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Function GetGalCanvas returns a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:882
PCB_TARGET class definition.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
bool IsMicroViaAcceptable(void)
Function IsMicroViaAcceptable return true if a microvia can be placed on the board.
Module description (excepted pads)
BOARD_ITEM * PcbGeneralLocateAndDisplay(int aHotKeyCode=0)
Function PcbGeneralLocateAndDisplay searches for an item under the mouse cursor.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
MODULE * GetFootprint(const wxPoint &aPosition, PCB_LAYER_ID aActiveLayer, bool aVisibleOnly, bool aIgnoreLocked=false)
Function GetFootprint get a footprint by its bounding rectangle at aPosition on aLayer.
int OnHotkeyCopyItem()
Function OnHotkeyCopyItem returns the copy event id for copyable items.
BOARD_ITEM * GetCurItem()
bool IsTrack() const
Function IsTrack tests to see if this object is a track or via (or microvia).
void SwitchLayer(wxDC *DC, PCB_LAYER_ID layer) override
Definition: edit.cpp:1371
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:796
void OnLeftClick(wxDC *DC, const wxPoint &MousePos) override
int m_IdMenuEvent
Definition: hotkeys_basic.h:66
EDA_HOTKEY * GetDescriptorFromCommand(int aCommand, EDA_HOTKEY **aList)
Function GetDescriptorFromCommand Returns a EDA_HOTKEY* pointer from a hot key identifier.
bool IsDragging() const
Definition: base_struct.h:248
void SetPrevGrid() override
Virtual function SetPrevGrid() changes the grid size settings to the previous one available...