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