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
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.
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)
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame.
TRACK * Delete_Segment(wxDC *DC, TRACK *Track)
Function Delete_Segment removes a track segment.
Definition: deltrack.cpp:45
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()
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:935
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
bool IsTrack() const
Function IsTrack tests to see if this object is a track or via (or microvia).
Classes to handle copper zones.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
virtual void SetAutoPanRequest(bool aEnable)=0
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 ...
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:1261
wxPoint m_O_Curseur
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:185
bool IsDragging() const
Definition: base_struct.h:222
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)
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
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:291
Definition: common.h:161
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...
struct EDA_HOTKEY_CONFIG g_Board_Editor_Hotkeys_Descr[]
virtual void CrossHairOff(wxDC *DC=nullptr)
bool OnHotkeyFlipItem(int aIdCommand)
Function OnHotkeyFlipItem Flip the item (text or footprint) found under the mouse cursor.
bool PostCommandMenuEvent(int evt_type)
Function PostCommandMenuEvent.
virtual EDA_DRAW_PANEL * GetCanvas() const
Definition: draw_frame.h:395
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:267
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:215
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.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:126
EDA_HOTKEY * GetHotKeyDescription(int aCommand) const override
void Delete_Track(wxDC *DC, TRACK *Track)
Definition: deltrack.cpp:146
bool OnHotkeyEditItem(int aIdCommand)
virtual bool IsLocked() const
Function IsLocked.
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:277
Class to handle a graphic segment.
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
wxPoint RefPos(bool useMouse) const
Return the reference position, coming from either the mouse position or the cursor position.
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
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 * GetBoard() const
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
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:258
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()
void SwitchLayer(wxDC *DC, PCB_LAYER_ID layer) override
Definition: edit.cpp:1334
int GetState(int type) const
Definition: base_struct.h:240
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:813
void OnLeftClick(wxDC *DC, const wxPoint &MousePos) override
int m_IdMenuEvent
Definition: hotkeys_basic.h:68
int GetToolId() const
Definition: draw_frame.h:526
EDA_HOTKEY * GetDescriptorFromCommand(int aCommand, EDA_HOTKEY **aList)
Function GetDescriptorFromCommand Returns a EDA_HOTKEY* pointer from a hot key identifier.
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Return the current cross hair position in logical (drawing) coordinates.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
void SetPrevGrid() override
Virtual function SetPrevGrid() changes the grid size settings to the previous one available.