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 = (GetUserUnits() == 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  case HK_LOCK_UNLOCK_FOOTPRINT: // toggle module "MODULE_is_LOCKED" status:
437  // get any module, locked or not locked and toggle its locked status
438  if( !itemCurrentlyEdited )
439  {
440  wxPoint pos = RefPos( true );
441  module = GetBoard()->GetFootprint( pos, screen->m_Active_Layer, true );
442  }
443  else if( GetCurItem()->Type() == PCB_MODULE_T )
444  {
445  module = (MODULE*) GetCurItem();
446  }
447 
448  if( module )
449  {
450  SetCurItem( module );
451  module->SetLocked( !module->IsLocked() );
452  OnModify();
453  SetMsgPanel( module );
454  }
455  break;
456 
457  case HK_DRAG_ITEM: // Start drag module or track segment
459  break;
460 
461  case HK_MOVE_ITEM: // Start move item
463  break;
464 
465  case HK_COPY_ITEM:
466  evt_type = OnHotkeyCopyItem();
467  break;
468 
469  case HK_ROTATE_ITEM: // Rotation
471  break;
472 
473  case HK_FLIP_ITEM:
475  break;
476 
477  case HK_MOVE_ITEM_EXACT:
478  case HK_DUPLICATE_ITEM:
480  case HK_CREATE_ARRAY:
482  break;
483 
484  case HK_SWITCH_HIGHCONTRAST_MODE: // switch to high contrast mode and refresh the canvas
485  displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay;
486  m_canvas->Refresh();
487  break;
488 
489  case HK_CANVAS_CAIRO:
490  evt_type = ID_MENU_CANVAS_CAIRO;
491  break;
492 
493  case HK_CANVAS_OPENGL:
494  evt_type = ID_MENU_CANVAS_OPENGL;
495  break;
496 
497  case HK_CANVAS_LEGACY:
498  evt_type = ID_MENU_CANVAS_LEGACY;
499  break;
500 
502  evt_type = ID_POPUP_PCB_FILL_ALL_ZONES;
503  break;
504 
507  break;
508  }
509 
510  if( evt_type != 0 )
511  {
512  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
513  evt.SetEventObject( this );
514  evt.SetId( evt_type );
515  GetEventHandler()->ProcessEvent( evt );
516  }
517 
518  return true;
519 }
520 
521 
523 {
524  BOARD_ITEM* item = GetCurItem();
525  bool ItemFree = (item == NULL) || (item->GetFlags() == 0);
526 
527  switch( GetToolId() )
528  {
529  case ID_TRACK_BUTT:
530  if( !IsCopperLayer ( GetActiveLayer() ) )
531  return false;
532 
533  if( ItemFree )
534  {
536 
537  if( item && !item->IsTrack() )
538  return false;
539 
540  Delete_Track( aDC, (TRACK*) item );
541  }
542  else if( item->IsTrack( ) )
543  {
544  // simple lines for debugger:
545  TRACK* track = (TRACK*) item;
546  track = Delete_Segment( aDC, track );
547  SetCurItem( track );
548  OnModify();
549  return true;
550  }
551  break;
552 
553  case ID_PCB_MODULE_BUTT:
554  if( ItemFree )
555  {
556  wxPoint pos = RefPos( false );
557  MODULE* module = GetBoard()->GetFootprint( pos, UNDEFINED_LAYER, false );
558 
559  if( module == NULL || module->IsLocked() )
560  return false;
561 
562  RemoveStruct( module, aDC );
563  }
564  else
565  return false;
566  break;
567 
568  default:
569  if( ItemFree )
570  {
572 
573  // Shouldn't there be a check for locked tracks and vias here?
574  if( item == NULL || (item->Type() == PCB_MODULE_T && (MODULE*)item->IsLocked()) )
575  return false;
576 
577  RemoveStruct( item, aDC );
578  }
579  else
580  return false;
581  }
582 
583  OnModify();
584  SetCurItem( NULL );
585  return true;
586 }
587 
588 
589 bool PCB_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
590 {
591  BOARD_ITEM* item = GetCurItem();
592  bool itemCurrentlyEdited = item && item->GetFlags();
593 
594  if( itemCurrentlyEdited )
595  return false;
596 
598 
599  if( item == NULL )
600  return false;
601 
602  SetCurItem( item );
603 
604  int evt_type = 0; //Used to post a wxCommandEvent on demand
605 
606  switch( item->Type() )
607  {
608  case PCB_TRACE_T:
609  case PCB_VIA_T:
610  if( aIdCommand == HK_EDIT_ITEM )
611  {
612  // Be sure the corresponding netclass is selected before edit:
613  SetCurrentNetClass( ( (BOARD_CONNECTED_ITEM*)item )->GetNetClassName() );
614  evt_type = ID_POPUP_PCB_EDIT_TRACKSEG;
615  }
616 
617  break;
618 
619  case PCB_TEXT_T:
620  if( aIdCommand == HK_EDIT_ITEM )
621  evt_type = ID_POPUP_PCB_EDIT_TEXTEPCB;
622 
623  break;
624 
625  case PCB_MODULE_T:
626  if( aIdCommand == HK_EDIT_ITEM )
628  else if( aIdCommand == HK_EDIT_MODULE_WITH_MODEDIT )
630 
631  break;
632 
633  case PCB_PAD_T:
634  // Until dec 2012 a EDIT_MODULE event is posted here to prevent pads
635  // from being edited by hotkeys.
636  // Process_Special_Functions takes care of finding the parent.
637  // After dec 2012 a EDIT_PAD event is posted, because there is no
638  // reason to not allow pad edit by hotkey
639  // (pad coordinates are no more modified by rounding, in nanometer version
640  // when using inches or mm in dialog)
641  if( aIdCommand == HK_EDIT_ITEM )
642  evt_type = ID_POPUP_PCB_EDIT_PAD;
643 
644  break;
645 
646  case PCB_TARGET_T:
647  if( aIdCommand == HK_EDIT_ITEM )
648  evt_type = ID_POPUP_PCB_EDIT_PCB_TARGET;
649 
650  break;
651 
652  case PCB_DIMENSION_T:
653  if( aIdCommand == HK_EDIT_ITEM )
654  evt_type = ID_POPUP_PCB_EDIT_DIMENSION;
655 
656  break;
657 
658  case PCB_MODULE_TEXT_T:
659  if( aIdCommand == HK_EDIT_ITEM )
660  evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE;
661 
662  break;
663 
664  case PCB_LINE_T:
665  if( aIdCommand == HK_EDIT_ITEM )
666  evt_type = ID_POPUP_PCB_EDIT_DRAWING;
667 
668  break;
669 
670  case PCB_ZONE_AREA_T:
671  if( aIdCommand == HK_EDIT_ITEM )
673 
674  break;
675 
676  default:
677  break;
678  }
679 
680  if( evt_type != 0 )
681  {
682  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
683  evt.SetEventObject( this );
684  evt.SetId( evt_type );
685  GetEventHandler()->ProcessEvent( evt );
686  return true;
687  }
688 
689  return false;
690 }
691 
692 
694 {
695  BOARD_ITEM* item = GetCurItem();
696  bool itemCurrentlyEdited = item && item->GetFlags();
697 
698  if( itemCurrentlyEdited )
699  return 0;
700 
702 
703  if( item == NULL )
704  return 0;
705 
706  SetCurItem( item );
707 
708  int eventId = 0;
709 
710  switch( item->Type() )
711  {
712  case PCB_TEXT_T:
713  eventId = ID_POPUP_PCB_COPY_TEXTEPCB;
714  break;
715  default:
716  eventId = 0;
717  break;
718  }
719 
720  return eventId;
721 }
722 
723 
724 bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
725 {
726  BOARD_ITEM* item = GetCurItem();
727  bool itemCurrentlyEdited = item && item->GetFlags();
728 
729  if( itemCurrentlyEdited )
730  return false;
731 
733 
734  if( item == NULL )
735  return false;
736 
737  SetCurItem( item );
738 
739  int evt_type = 0; // Used to post a wxCommandEvent on demand
740 
741  switch( item->Type() )
742  {
743  case PCB_TRACE_T:
744  case PCB_VIA_T:
745  if( aIdCommand == HK_MOVE_ITEM )
746  evt_type = ID_POPUP_PCB_MOVE_TRACK_NODE;
747 
748  if( aIdCommand == HK_DRAG_ITEM )
750 
751  if( aIdCommand == HK_DRAG_TRACK_KEEP_SLOPE )
753 
754  break;
755 
756  case PCB_MODULE_T:
757  {
758  if( aIdCommand == HK_MOVE_ITEM )
760 
761  if( aIdCommand == HK_DRAG_ITEM )
763  }
764  break;
765 
766  case PCB_PAD_T:
767  // Post MODULE_REQUEST events here to prevent pads
768  // from being moved or dragged by hotkeys.
769  // Process_Special_Functions takes care of finding
770  // the parent.
771  if( aIdCommand == HK_MOVE_ITEM )
773 
774  if( aIdCommand == HK_DRAG_ITEM )
776 
777  break;
778 
779  case PCB_TEXT_T:
780  if( aIdCommand == HK_MOVE_ITEM )
782 
783  break;
784 
785  case PCB_TARGET_T:
786  if( aIdCommand == HK_MOVE_ITEM )
788 
789  break;
790 
791  case PCB_ZONE_AREA_T:
792  if( aIdCommand == HK_MOVE_ITEM )
794 
795  if( aIdCommand == HK_DRAG_ITEM )
797 
798  break;
799 
800  case PCB_MODULE_TEXT_T:
801  if( aIdCommand == HK_MOVE_ITEM )
803 
804  break;
805 
806  case PCB_LINE_T:
807  if( aIdCommand == HK_MOVE_ITEM )
809 
810  break;
811 
812  case PCB_DIMENSION_T:
813  if( aIdCommand == HK_MOVE_ITEM )
815  break;
816 
817  default:
818  break;
819  }
820 
821  if( evt_type != 0 )
822  {
823  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
824  evt.SetEventObject( this );
825  evt.SetId( evt_type );
826  GetEventHandler()->ProcessEvent( evt );
827  return true;
828  }
829 
830  return false;
831 }
832 
833 
835 {
836  BOARD_ITEM* item = GetCurItem();
837  bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED;
838  bool itemCurrentlyEdited = item && item->GetFlags();
839 
840  m_canvas->SetAutoPanRequest( false );
841 
842  if( itemCurrentlyEdited )
843  {
845  m_canvas->CrossHairOff( aDC );
846 
847  switch( item->Type() )
848  {
849  case PCB_TRACE_T:
850  case PCB_VIA_T:
851  if( item->IsDragging() )
852  PlaceDraggedOrMovedTrackSegment( static_cast<TRACK*>( item ), aDC );
853 
854  break;
855 
856  case PCB_TEXT_T:
857  Place_Texte_Pcb( static_cast<TEXTE_PCB*>( item ), aDC );
858  break;
859 
860  case PCB_MODULE_TEXT_T:
861  PlaceTexteModule( static_cast<TEXTE_MODULE*>( item ), aDC );
862  break;
863 
864  case PCB_PAD_T:
865  PlacePad( static_cast<D_PAD*>( item ), aDC );
866  break;
867 
868  case PCB_MODULE_T:
869  PlaceModule( static_cast<MODULE*>( item ), aDC );
870  break;
871 
872  case PCB_TARGET_T:
873  PlaceTarget( static_cast<PCB_TARGET*>( item ), aDC );
874  break;
875 
876  case PCB_LINE_T:
877  if( no_tool ) // when no tools: existing item moving.
878  Place_DrawItem( static_cast<DRAWSEGMENT*>( item ), aDC );
879 
880  break;
881 
882  default:
883  break;
884  }
885 
886  m_canvas->SetIgnoreMouseEvents( false );
887  m_canvas->CrossHairOn( aDC );
888 
889  return true;
890  }
891 
892  return false;
893 }
894 
895 
897 {
898  if( !IsCopperLayer( GetActiveLayer() ) )
899  return NULL;
900 
901  bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
902 
903  // Ensure the track tool is active
904  if( GetToolId() != ID_TRACK_BUTT && !itemCurrentlyEdited )
905  {
906  wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
907  cmd.SetEventObject( this );
908  cmd.SetId( ID_TRACK_BUTT );
909  GetEventHandler()->ProcessEvent( cmd );
910  }
911 
912  if( GetToolId() != ID_TRACK_BUTT )
913  return NULL;
914 
915  TRACK* track = NULL;
916 
917  if( !itemCurrentlyEdited ) // no track in progress:
918  {
919  track = Begin_Route( NULL, aDC );
920  SetCurItem( track );
921 
922  if( track )
923  m_canvas->SetAutoPanRequest( true );
924  }
925  else if( GetCurItem()->IsNew() )
926  {
927  track = Begin_Route( (TRACK*) GetCurItem(), aDC );
928 
929  // SetCurItem() must not write to the msg panel
930  // because a track info is displayed while moving the mouse cursor
931  if( track ) // A new segment was created
932  SetCurItem( track, false );
933 
934  m_canvas->SetAutoPanRequest( true );
935  }
936 
937  return track;
938 }
939 
940 
941 bool PCB_EDIT_FRAME::OnHotkeyFlipItem( int aIdCommand )
942 {
943  BOARD_ITEM* item = GetCurItem();
944  bool itemCurrentlyEdited = item && item->GetFlags();
945  int evt_type = 0; // Used to post a wxCommandEvent on demand
946 
947  wxASSERT( aIdCommand == HK_FLIP_ITEM );
948 
949  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
950  {
951  evt_type = ID_POPUP_FLIP_BLOCK;
952  }
953  else
954  {
955  if( !itemCurrentlyEdited )
957 
958  if( item == NULL )
959  return false;
960 
961  SetCurItem( item );
962 
963  switch( item->Type() )
964  {
965  case PCB_MODULE_T:
967  break;
968 
969  case PCB_TEXT_T:
970  evt_type = ID_POPUP_PCB_FLIP_TEXTEPCB;
971  break;
972 
973  default:
974  break;
975  }
976  }
977 
978  if( evt_type != 0 )
979  {
980  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
981  evt.SetEventObject( this );
982  evt.SetId( evt_type );
983  GetEventHandler()->ProcessEvent( evt );
984  return true;
985  }
986  else
987  {
988  return false;
989  }
990 }
991 
992 
994 {
995  BOARD_ITEM* item = GetCurItem();
996  bool itemCurrentlyEdited = item && item->GetFlags();
997  int evt_type = 0; // Used to post a wxCommandEvent on demand
998 
999  wxASSERT( aIdCommand == HK_ROTATE_ITEM );
1000 
1001  // Allows block rotate operation on hot key.
1002  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
1003  {
1004  evt_type = ID_POPUP_ROTATE_BLOCK;
1005  }
1006  else
1007  {
1008  if( !itemCurrentlyEdited )
1009  item = PcbGeneralLocateAndDisplay();
1010 
1011  if( item == NULL )
1012  return false;
1013 
1014  SetCurItem( item );
1015 
1016  switch( item->Type() )
1017  {
1018  case PCB_MODULE_T:
1020  break;
1021 
1022  case PCB_TEXT_T:
1023  evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB;
1024  break;
1025 
1026  case PCB_MODULE_TEXT_T:
1027  evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE;
1028  break;
1029 
1030  default:
1031  break;
1032  }
1033  }
1034 
1035  if( evt_type != 0 )
1036  {
1037  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
1038  evt.SetEventObject( this );
1039  evt.SetId( evt_type );
1040  GetEventHandler()->ProcessEvent( evt );
1041  return true;
1042  }
1043 
1044  return false;
1045 }
1046 
1047 
1049 {
1050  BOARD_ITEM* item = GetCurItem();
1051  bool itemCurrentlyEdited = item && item->GetFlags();
1052 
1053  if( itemCurrentlyEdited )
1054  return false;
1055 
1056  item = PcbGeneralLocateAndDisplay();
1057 
1058  if( item == NULL )
1059  return false;
1060 
1061  SetCurItem( item );
1062 
1063  int evt_type = 0; // Used to post a wxCommandEvent on demand
1064 
1065  bool canDuplicate = true;
1066 
1067  switch( item->Type() )
1068  {
1069  // Only handle items we know we can handle
1070  case PCB_PAD_T:
1071  canDuplicate = false;
1072  // no break
1073  case PCB_MODULE_T:
1074  case PCB_LINE_T:
1075  case PCB_TEXT_T:
1076  case PCB_TRACE_T:
1077  case PCB_ZONE_AREA_T:
1078  case PCB_TARGET_T:
1079  case PCB_DIMENSION_T:
1080  switch( aIdCommand )
1081  {
1082  case HK_CREATE_ARRAY:
1083  if( canDuplicate )
1084  evt_type = ID_POPUP_PCB_CREATE_ARRAY;
1085  break;
1086 
1088  if( canDuplicate )
1090  break;
1091 
1092  case HK_DUPLICATE_ITEM:
1093  if( canDuplicate )
1094  evt_type = ID_POPUP_PCB_DUPLICATE_ITEM;
1095  break;
1096 
1097  case HK_MOVE_ITEM_EXACT:
1098  evt_type = ID_POPUP_PCB_MOVE_EXACT;
1099  break;
1100 
1101  default:
1102  // We don't handle other commands here
1103  break;
1104  }
1105  break;
1106 
1107  default:
1108  evt_type = 0;
1109  break;
1110  }
1111 
1112  return PostCommandMenuEvent( evt_type );
1113 }
void Place_DrawItem(DRAWSEGMENT *drawitem, wxDC *DC)
Definition: editedge.cpp:74
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
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:258
void SetTrackWidthIndex(unsigned aIndex)
Function SetTrackWidthIndex sets the current track width list index to aIndex.
VIATYPE_T m_CurrentViaType
(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
virtual EDA_DRAW_PANEL * GetCanvas() const
Definition: draw_frame.h:388
TEXTE_PCB class definition.
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...
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
Return 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:240
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:1268
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.
void PlaceTarget(PCB_TARGET *aTarget, wxDC *DC)
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...
EDA_DRAW_FRAME::OnSelectGrid ID_TB_OPTIONS_SELECT_UNIT_INCH
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
bool OnHotkeyMoveItem(int aIdCommand)
Function OnHotkeyMoveItem Moves or drag the item (footprint, track, text .
void PlaceModule(MODULE *aModule, wxDC *aDC, bool aRecreateRatsnest=true)
Function PlaceModule places aModule at the current cursor position and updates module coordinates wit...
virtual void CrossHairOn(wxDC *DC=nullptr)
void OnLeftDClick(wxDC *DC, const wxPoint &MousePos) override
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:284
Definition: common.h:160
EDA_HOTKEY * common_Hotkey_List[]
virtual 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:538
struct EDA_HOTKEY_CONFIG g_Board_Editor_Hotkeys_Descr[]
virtual void CrossHairOff(wxDC *DC=nullptr)
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[]
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:268
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:213
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
Return the reference position, coming from either the mouse position or the cursor position...
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:123
EDA_HOTKEY * GetHotKeyDescription(int aCommand) const override
>
void Delete_Track(wxDC *DC, TRACK *Track)
Definition: deltrack.cpp:146
bool OnHotkeyEditItem(int aIdCommand)
class EDA_HOTKEY is a class to handle hot key commands.
Definition: hotkeys_basic.h:59
void SetLocked(bool isLocked) override
Function SetLocked sets the MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition: class_module.h:278
Class to handle a graphic segment.
virtual bool IsLocked() const
Function IsLocked.
int GetToolId() const
Definition: draw_frame.h:519
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:154
PCB_SCREEN * GetScreen() const override
Return 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.
bool IsMicroViaAcceptable()
Function IsMicroViaAcceptable return true if a microvia can be placed on the board.
#define UR_TRANSIENT
indicates the item is owned by the undo/redo stack
Definition: base_struct.h:142
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:908
PCB_TARGET class definition.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Module description (excepted pads)
BOARD_ITEM * PcbGeneralLocateAndDisplay(int aHotKeyCode=0)
Function PcbGeneralLocateAndDisplay searches for an item under the mouse cursor.
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL)
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:1345
wxPoint GetCrossHairPosition(bool aInvertY=false) const
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:810
void OnLeftClick(wxDC *DC, const wxPoint &MousePos) override
int m_IdMenuEvent
Definition: hotkeys_basic.h:68
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:222
void SetPrevGrid() override
Virtual function SetPrevGrid() changes the grid size settings to the previous one available...