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()->GetEditFlags();
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  evt_type = ID_POPUP_GRID_NEXT;
152  break;
153 
155  evt_type = ID_POPUP_GRID_PREV;
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_PREFERENCES:
225  evt_type = wxID_PREFERENCES;
226  break;
227 
228  case HK_ZOOM_IN:
229  evt_type = ID_KEY_ZOOM_IN;
230  break;
231 
232  case HK_ZOOM_OUT:
233  evt_type = ID_KEY_ZOOM_OUT;
234  break;
235 
236  case HK_ZOOM_REDRAW:
237  evt_type = ID_ZOOM_REDRAW;
238  break;
239 
240  case HK_ZOOM_AUTO:
241  evt_type = ID_ZOOM_PAGE;
242  break;
243 
244  case HK_ZOOM_CENTER:
245  evt_type = ID_POPUP_ZOOM_CENTER;
246  break;
247 
248  case HK_ZOOM_SELECTION:
249  evt_type = ID_ZOOM_SELECTION;
250  break;
251 
252  case HK_ADD_MODULE:
253  evt_type = ID_PCB_MODULE_BUTT;
254  break;
255 
256  case HK_UNDO:
257  case HK_REDO:
258  if( !itemCurrentlyEdited )
259  {
260  wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
261  wxPostEvent( this, event );
262  }
263 
264  break;
265 
266  case HK_RESET_LOCAL_COORD: // Set the relative coord
268  break;
269 
270  case HK_SET_GRID_ORIGIN:
271  PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
274  m_canvas->Refresh();
275  break;
276 
278  PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
280  wxPoint( 0, 0 ) );
281  m_canvas->Refresh();
282  break;
283 
284  case HK_SWITCH_UNITS:
285  evt_type = (GetUserUnits() == INCHES) ?
287  break;
288 
290  displ_opts->m_DisplayPcbTrackFill = !displ_opts->m_DisplayPcbTrackFill;
291  m_canvas->Refresh();
292  break;
293 
294  case HK_DELETE:
295  OnHotkeyDeleteItem( aDC );
296  break;
297 
298  case HK_BACK_SPACE:
299  if( IsCopperLayer( GetActiveLayer() ) )
300  {
301  if( !itemCurrentlyEdited )
302  {
303  // no track is currently being edited - select a segment and remove it.
304  // @todo: possibly? pass the HK command code to PcbGeneralLocateAndDisplay()
305  // so it can restrict its search to specific item types.
307 
308  // don't let backspace delete modules!!
309  if( item && item->IsTrack() )
310  {
311  Delete_Segment( aDC, (TRACK*) item );
312  SetCurItem( NULL );
313  }
314 
315  OnModify();
316  }
317  else if( GetCurItem()->IsTrack() )
318  {
319  // then an element is being edited - remove the last segment.
320  // simple lines for debugger:
321  TRACK* track = (TRACK*) GetCurItem();
322  track = Delete_Segment( aDC, track );
323  SetCurItem( track );
324  OnModify();
325  }
326  }
327 
328  break;
329 
331  if( !itemCurrentlyEdited )
333 
334  break;
335 
336  case HK_FIND_ITEM:
337  if( !itemCurrentlyEdited )
338  evt_type = ID_FIND_ITEMS;
339 
340  break;
341 
342  case HK_OPEN:
343  if( !itemCurrentlyEdited )
344  evt_type = ID_LOAD_FILE ;
345 
346  break;
347 
348  case HK_SAVE:
349  if( !itemCurrentlyEdited )
350  evt_type = ID_SAVE_BOARD;
351 
352  break;
353 
354  case HK_ADD_MICROVIA: // Place a micro via if a track is in progress
355  if( GetToolId() != ID_TRACK_BUTT )
356  return true;
357 
358  if( !itemCurrentlyEdited ) // no track in progress: nothing to do
359  break;
360 
361  if( GetCurItem()->Type() != PCB_TRACE_T ) // Should not occur
362  return true;
363 
364  if( !GetCurItem()->IsNew() )
365  return true;
366 
367  // place micro via and switch layer
368  if( IsMicroViaAcceptable() )
369  evt_type = ID_POPUP_PCB_PLACE_MICROVIA;
370 
371  break;
372 
374  case HK_ADD_THROUGH_VIA: // Switch to alternate layer and Place a via if a track is in progress
375  if( GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed &&
376  hk_id == HK_ADD_BLIND_BURIED_VIA )
378  else
380 
381  if( !itemCurrentlyEdited ) // no track in progress: switch layer only
382  {
383  Other_Layer_Route( NULL, aDC );
384  if( displ_opts->m_ContrastModeDisplay )
385  m_canvas->Refresh();
386  break;
387  }
388 
389  if( GetToolId() != ID_TRACK_BUTT )
390  return true;
391 
392  if( GetCurItem()->Type() != PCB_TRACE_T )
393  return true;
394 
395  if( !GetCurItem()->IsNew() )
396  return true;
397 
398  evt_type = hk_id == HK_ADD_BLIND_BURIED_VIA ?
400  break;
401 
404  if( GetCurItem() == NULL || !GetCurItem()->IsNew() ||
405  GetCurItem()->Type() != PCB_TRACE_T )
406  break;
407 
408  evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ?
411  break;
412 
414  /* change the position of initial segment when creating new tracks
415  * switch from _/ to -\ .
416  */
418  break;
419 
422  break;
423 
424  case HK_PLACE_ITEM:
425  OnHotkeyPlaceItem( aDC );
426  break;
427 
428  case HK_ADD_NEW_TRACK: // Start new track, if possible
429  OnHotkeyBeginRoute( aDC );
430  break;
431 
432  case HK_EDIT_ITEM: // Edit board item
434  break;
435 
436  case HK_EDIT_MODULE_WITH_MODEDIT: // Edit module with module editor
438  break;
439 
440  case HK_LOCK_UNLOCK_FOOTPRINT: // toggle module "MODULE_is_LOCKED" status:
441  // get any module, locked or not locked and toggle its locked status
442  if( !itemCurrentlyEdited )
443  {
444  wxPoint pos = RefPos( true );
445  module = GetBoard()->GetFootprint( pos, screen->m_Active_Layer, true );
446  }
447  else if( GetCurItem()->Type() == PCB_MODULE_T )
448  {
449  module = (MODULE*) GetCurItem();
450  }
451 
452  if( module )
453  {
454  SetCurItem( module );
455  module->SetLocked( !module->IsLocked() );
456  OnModify();
457  SetMsgPanel( module );
458  }
459  break;
460 
461  case HK_DRAG_ITEM: // Start drag module or track segment
463  break;
464 
465  case HK_MOVE_ITEM: // Start move item
467  break;
468 
469  case HK_COPY_ITEM:
470  evt_type = OnHotkeyCopyItem();
471  break;
472 
473  case HK_ROTATE_ITEM: // Rotation
475  break;
476 
477  case HK_FLIP_ITEM:
479  break;
480 
481  case HK_MOVE_ITEM_EXACT:
482  case HK_DUPLICATE:
484  case HK_CREATE_ARRAY:
486  break;
487 
488  case HK_SWITCH_HIGHCONTRAST_MODE: // switch to high contrast mode and refresh the canvas
489  displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay;
490  m_canvas->Refresh();
491  break;
492 
493  case HK_CANVAS_CAIRO:
494  evt_type = ID_MENU_CANVAS_CAIRO;
495  break;
496 
497  case HK_CANVAS_OPENGL:
498  evt_type = ID_MENU_CANVAS_OPENGL;
499  break;
500 
501  case HK_CANVAS_LEGACY:
502  evt_type = ID_MENU_CANVAS_LEGACY;
503  break;
504 
506  evt_type = ID_POPUP_PCB_FILL_ALL_ZONES;
507  break;
508 
511  break;
512  }
513 
514  if( evt_type != 0 )
515  {
516  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
517  evt.SetEventObject( this );
518  evt.SetId( evt_type );
519  GetEventHandler()->ProcessEvent( evt );
520  }
521 
522  return true;
523 }
524 
525 
527 {
528  BOARD_ITEM* item = GetCurItem();
529  bool ItemFree = ( !item || item->GetEditFlags() == 0 );
530 
531  switch( GetToolId() )
532  {
533  case ID_TRACK_BUTT:
534  if( !IsCopperLayer ( GetActiveLayer() ) )
535  return false;
536 
537  if( ItemFree )
538  {
540 
541  if( item && !item->IsTrack() )
542  return false;
543 
544  Delete_Track( aDC, (TRACK*) item );
545  }
546  else if( item->IsTrack( ) )
547  {
548  // simple lines for debugger:
549  TRACK* track = (TRACK*) item;
550  track = Delete_Segment( aDC, track );
551  SetCurItem( track );
552  OnModify();
553  return true;
554  }
555  break;
556 
557  case ID_PCB_MODULE_BUTT:
558  if( ItemFree )
559  {
560  wxPoint pos = RefPos( false );
561  MODULE* module = GetBoard()->GetFootprint( pos, UNDEFINED_LAYER, false );
562 
563  if( module == NULL || module->IsLocked() )
564  return false;
565 
566  RemoveStruct( module, aDC );
567  }
568  else
569  return false;
570  break;
571 
572  default:
573  if( ItemFree )
574  {
576 
577  // Shouldn't there be a check for locked tracks and vias here?
578  if( item == NULL || (item->Type() == PCB_MODULE_T && (MODULE*)item->IsLocked()) )
579  return false;
580 
581  RemoveStruct( item, aDC );
582  }
583  else
584  return false;
585  }
586 
587  OnModify();
588  SetCurItem( NULL );
589  return true;
590 }
591 
592 
593 bool PCB_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
594 {
595  BOARD_ITEM* item = GetCurItem();
596  bool itemCurrentlyEdited = item && item->GetEditFlags();
597 
598  if( itemCurrentlyEdited )
599  return false;
600 
602 
603  if( item == NULL )
604  return false;
605 
606  SetCurItem( item );
607 
608  int evt_type = 0; //Used to post a wxCommandEvent on demand
609 
610  switch( item->Type() )
611  {
612  case PCB_TRACE_T:
613  case PCB_VIA_T:
614  if( aIdCommand == HK_EDIT_ITEM )
615  {
616  // Be sure the corresponding netclass is selected before edit:
617  SetCurrentNetClass( ( (BOARD_CONNECTED_ITEM*)item )->GetNetClassName() );
618  evt_type = ID_POPUP_PCB_EDIT_TRACKSEG;
619  }
620 
621  break;
622 
623  case PCB_TEXT_T:
624  if( aIdCommand == HK_EDIT_ITEM )
625  evt_type = ID_POPUP_PCB_EDIT_TEXTEPCB;
626 
627  break;
628 
629  case PCB_MODULE_T:
630  if( aIdCommand == HK_EDIT_ITEM )
632  else if( aIdCommand == HK_EDIT_MODULE_WITH_MODEDIT )
634 
635  break;
636 
637  case PCB_PAD_T:
638  // Until dec 2012 a EDIT_MODULE event is posted here to prevent pads
639  // from being edited by hotkeys.
640  // Process_Special_Functions takes care of finding the parent.
641  // After dec 2012 a EDIT_PAD event is posted, because there is no
642  // reason to not allow pad edit by hotkey
643  // (pad coordinates are no more modified by rounding, in nanometer version
644  // when using inches or mm in dialog)
645  if( aIdCommand == HK_EDIT_ITEM )
646  evt_type = ID_POPUP_PCB_EDIT_PAD;
647 
648  break;
649 
650  case PCB_TARGET_T:
651  if( aIdCommand == HK_EDIT_ITEM )
652  evt_type = ID_POPUP_PCB_EDIT_PCB_TARGET;
653 
654  break;
655 
656  case PCB_DIMENSION_T:
657  if( aIdCommand == HK_EDIT_ITEM )
658  evt_type = ID_POPUP_PCB_EDIT_DIMENSION;
659 
660  break;
661 
662  case PCB_MODULE_TEXT_T:
663  if( aIdCommand == HK_EDIT_ITEM )
664  evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE;
665 
666  break;
667 
668  case PCB_LINE_T:
669  if( aIdCommand == HK_EDIT_ITEM )
670  evt_type = ID_POPUP_PCB_EDIT_DRAWING;
671 
672  break;
673 
674  case PCB_ZONE_AREA_T:
675  if( aIdCommand == HK_EDIT_ITEM )
677 
678  break;
679 
680  default:
681  break;
682  }
683 
684  if( evt_type != 0 )
685  {
686  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
687  evt.SetEventObject( this );
688  evt.SetId( evt_type );
689  GetEventHandler()->ProcessEvent( evt );
690  return true;
691  }
692 
693  return false;
694 }
695 
696 
698 {
699  BOARD_ITEM* item = GetCurItem();
700  bool itemCurrentlyEdited = item && item->GetEditFlags();
701 
702  if( itemCurrentlyEdited )
703  return 0;
704 
706 
707  if( item == NULL )
708  return 0;
709 
710  SetCurItem( item );
711 
712  int eventId = 0;
713 
714  switch( item->Type() )
715  {
716  case PCB_TEXT_T:
717  eventId = ID_POPUP_PCB_COPY_TEXTEPCB;
718  break;
719  default:
720  eventId = 0;
721  break;
722  }
723 
724  return eventId;
725 }
726 
727 
728 bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
729 {
730  BOARD_ITEM* item = GetCurItem();
731  bool itemCurrentlyEdited = item && item->GetEditFlags();
732 
733  if( itemCurrentlyEdited )
734  return false;
735 
737 
738  if( item == NULL )
739  return false;
740 
741  SetCurItem( item );
742 
743  int evt_type = 0; // Used to post a wxCommandEvent on demand
744 
745  switch( item->Type() )
746  {
747  case PCB_TRACE_T:
748  case PCB_VIA_T:
749  if( aIdCommand == HK_MOVE_ITEM )
750  evt_type = ID_POPUP_PCB_MOVE_TRACK_NODE;
751 
752  if( aIdCommand == HK_DRAG_ITEM )
754 
755  if( aIdCommand == HK_DRAG_TRACK_KEEP_SLOPE )
757 
758  break;
759 
760  case PCB_MODULE_T:
761  {
762  if( aIdCommand == HK_MOVE_ITEM )
764 
765  if( aIdCommand == HK_DRAG_ITEM )
767  }
768  break;
769 
770  case PCB_PAD_T:
771  // Post MODULE_REQUEST events here to prevent pads
772  // from being moved or dragged by hotkeys.
773  // Process_Special_Functions takes care of finding
774  // the parent.
775  if( aIdCommand == HK_MOVE_ITEM )
777 
778  if( aIdCommand == HK_DRAG_ITEM )
780 
781  break;
782 
783  case PCB_TEXT_T:
784  if( aIdCommand == HK_MOVE_ITEM )
786 
787  break;
788 
789  case PCB_TARGET_T:
790  if( aIdCommand == HK_MOVE_ITEM )
792 
793  break;
794 
795  case PCB_ZONE_AREA_T:
796  if( aIdCommand == HK_MOVE_ITEM )
798 
799  if( aIdCommand == HK_DRAG_ITEM )
801 
802  break;
803 
804  case PCB_MODULE_TEXT_T:
805  if( aIdCommand == HK_MOVE_ITEM )
807 
808  break;
809 
810  case PCB_LINE_T:
811  if( aIdCommand == HK_MOVE_ITEM )
813 
814  break;
815 
816  case PCB_DIMENSION_T:
817  if( aIdCommand == HK_MOVE_ITEM )
819  break;
820 
821  default:
822  break;
823  }
824 
825  if( evt_type != 0 )
826  {
827  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
828  evt.SetEventObject( this );
829  evt.SetId( evt_type );
830  GetEventHandler()->ProcessEvent( evt );
831  return true;
832  }
833 
834  return false;
835 }
836 
837 
839 {
840  BOARD_ITEM* item = GetCurItem();
841  bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED;
842  bool itemCurrentlyEdited = item && item->GetEditFlags();
843 
844  m_canvas->SetAutoPanRequest( false );
845 
846  if( itemCurrentlyEdited )
847  {
849  m_canvas->CrossHairOff( aDC );
850 
851  switch( item->Type() )
852  {
853  case PCB_TRACE_T:
854  case PCB_VIA_T:
855  if( item->IsDragging() )
856  PlaceDraggedOrMovedTrackSegment( static_cast<TRACK*>( item ), aDC );
857 
858  break;
859 
860  case PCB_TEXT_T:
861  Place_Texte_Pcb( static_cast<TEXTE_PCB*>( item ), aDC );
862  break;
863 
864  case PCB_MODULE_TEXT_T:
865  PlaceTexteModule( static_cast<TEXTE_MODULE*>( item ), aDC );
866  break;
867 
868  case PCB_PAD_T:
869  PlacePad( static_cast<D_PAD*>( item ), aDC );
870  break;
871 
872  case PCB_MODULE_T:
873  PlaceModule( static_cast<MODULE*>( item ), aDC );
874  break;
875 
876  case PCB_TARGET_T:
877  PlaceTarget( static_cast<PCB_TARGET*>( item ), aDC );
878  break;
879 
880  case PCB_LINE_T:
881  if( no_tool ) // when no tools: existing item moving.
882  Place_DrawItem( static_cast<DRAWSEGMENT*>( item ), aDC );
883 
884  break;
885 
886  default:
887  break;
888  }
889 
890  m_canvas->SetIgnoreMouseEvents( false );
891  m_canvas->CrossHairOn( aDC );
892 
893  return true;
894  }
895 
896  return false;
897 }
898 
899 
901 {
902  if( !IsCopperLayer( GetActiveLayer() ) )
903  return NULL;
904 
905  bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetEditFlags();
906 
907  // Ensure the track tool is active
908  if( GetToolId() != ID_TRACK_BUTT && !itemCurrentlyEdited )
909  {
910  wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
911  cmd.SetEventObject( this );
912  cmd.SetId( ID_TRACK_BUTT );
913  GetEventHandler()->ProcessEvent( cmd );
914  }
915 
916  if( GetToolId() != ID_TRACK_BUTT )
917  return NULL;
918 
919  TRACK* track = NULL;
920 
921  if( !itemCurrentlyEdited ) // no track in progress:
922  {
923  track = Begin_Route( NULL, aDC );
924  SetCurItem( track );
925 
926  if( track )
927  m_canvas->SetAutoPanRequest( true );
928  }
929  else if( GetCurItem()->IsNew() )
930  {
931  track = Begin_Route( (TRACK*) GetCurItem(), aDC );
932 
933  // SetCurItem() must not write to the msg panel
934  // because a track info is displayed while moving the mouse cursor
935  if( track ) // A new segment was created
936  SetCurItem( track, false );
937 
938  m_canvas->SetAutoPanRequest( true );
939  }
940 
941  return track;
942 }
943 
944 
945 bool PCB_EDIT_FRAME::OnHotkeyFlipItem( int aIdCommand )
946 {
947  BOARD_ITEM* item = GetCurItem();
948  bool itemCurrentlyEdited = item && item->GetEditFlags();
949  int evt_type = 0; // Used to post a wxCommandEvent on demand
950 
951  wxASSERT( aIdCommand == HK_FLIP_ITEM );
952 
953  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
954  {
955  evt_type = ID_POPUP_FLIP_BLOCK;
956  }
957  else
958  {
959  if( !itemCurrentlyEdited )
961 
962  if( item == NULL )
963  return false;
964 
965  SetCurItem( item );
966 
967  switch( item->Type() )
968  {
969  case PCB_MODULE_T:
971  break;
972 
973  case PCB_TEXT_T:
974  evt_type = ID_POPUP_PCB_FLIP_TEXTEPCB;
975  break;
976 
977  default:
978  break;
979  }
980  }
981 
982  if( evt_type != 0 )
983  {
984  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
985  evt.SetEventObject( this );
986  evt.SetId( evt_type );
987  GetEventHandler()->ProcessEvent( evt );
988  return true;
989  }
990  else
991  {
992  return false;
993  }
994 }
995 
996 
998 {
999  BOARD_ITEM* item = GetCurItem();
1000  bool itemCurrentlyEdited = item && item->GetEditFlags();
1001  int evt_type = 0; // Used to post a wxCommandEvent on demand
1002 
1003  wxASSERT( aIdCommand == HK_ROTATE_ITEM );
1004 
1005  // Allows block rotate operation on hot key.
1006  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
1007  {
1008  evt_type = ID_POPUP_ROTATE_BLOCK;
1009  }
1010  else
1011  {
1012  if( !itemCurrentlyEdited )
1013  item = PcbGeneralLocateAndDisplay();
1014 
1015  if( item == NULL )
1016  return false;
1017 
1018  SetCurItem( item );
1019 
1020  switch( item->Type() )
1021  {
1022  case PCB_MODULE_T:
1024  break;
1025 
1026  case PCB_TEXT_T:
1027  evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB;
1028  break;
1029 
1030  case PCB_MODULE_TEXT_T:
1031  evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE;
1032  break;
1033 
1034  default:
1035  break;
1036  }
1037  }
1038 
1039  if( evt_type != 0 )
1040  {
1041  wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
1042  evt.SetEventObject( this );
1043  evt.SetId( evt_type );
1044  GetEventHandler()->ProcessEvent( evt );
1045  return true;
1046  }
1047 
1048  return false;
1049 }
1050 
1051 
1053 {
1054  BOARD_ITEM* item = GetCurItem();
1055  bool itemCurrentlyEdited = item && item->GetEditFlags();
1056 
1057  if( itemCurrentlyEdited )
1058  return false;
1059 
1060  item = PcbGeneralLocateAndDisplay();
1061 
1062  if( item == NULL )
1063  return false;
1064 
1065  SetCurItem( item );
1066 
1067  int evt_type = 0; // Used to post a wxCommandEvent on demand
1068 
1069  bool canDuplicate = true;
1070 
1071  switch( item->Type() )
1072  {
1073  // Only handle items we know we can handle
1074  case PCB_PAD_T:
1075  canDuplicate = false;
1076  // no break
1077  case PCB_MODULE_T:
1078  case PCB_LINE_T:
1079  case PCB_TEXT_T:
1080  case PCB_TRACE_T:
1081  case PCB_ZONE_AREA_T:
1082  case PCB_TARGET_T:
1083  case PCB_DIMENSION_T:
1084  switch( aIdCommand )
1085  {
1086  case HK_CREATE_ARRAY:
1087  if( canDuplicate )
1088  evt_type = ID_POPUP_PCB_CREATE_ARRAY;
1089  break;
1090 
1092  if( canDuplicate )
1094  break;
1095 
1096  case HK_DUPLICATE:
1097  if( canDuplicate )
1098  evt_type = ID_POPUP_PCB_DUPLICATE_ITEM;
1099  break;
1100 
1101  case HK_MOVE_ITEM_EXACT:
1102  evt_type = ID_POPUP_PCB_MOVE_EXACT;
1103  break;
1104 
1105  default:
1106  // We don't handle other commands here
1107  break;
1108  }
1109  break;
1110 
1111  default:
1112  evt_type = 0;
1113  break;
1114  }
1115 
1116  return PostCommandMenuEvent( evt_type );
1117 }
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:931
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:100
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:534
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
virtual void SetAutoPanRequest(bool aEnable)=0
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:1242
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:225
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...
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 .
STATUS_FLAGS GetEditFlags() const
Definition: base_struct.h:263
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:289
Definition: common.h:158
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)
Post a menu event to the frame, which can be used to trigger actions bound to menu items.
virtual EDA_DRAW_PANEL * GetCanvas() const
Definition: draw_frame.h:399
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:98
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:99
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
void PlaceTexteModule(TEXTE_MODULE *Text, wxDC *DC)
Definition: edtxtmod.cpp:218
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:128
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:157
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:141
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
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:1311
int GetState(int type) const
Definition: base_struct.h:243
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:524
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:204