KiCad PCB EDA Suite
edit_tool.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) 2013-2017 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
6  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  * Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #include <limits>
28 #include <class_module.h>
29 #include <class_edge_mod.h>
30 #include <collectors.h>
31 #include <pcb_edit_frame.h>
32 #include <ws_proxy_view_item.h>
33 #include <kiway.h>
34 #include <array_creator.h>
35 #include <pcbnew_settings.h>
36 #include <status_popup.h>
37 #include <tool/tool_manager.h>
38 #include <tools/pcb_actions.h>
39 #include <tools/selection_tool.h>
40 #include <tools/edit_tool.h>
42 #include <tools/tool_event_utils.h>
43 #include <tools/grid_helper.h>
44 #include <tools/pad_tool.h>
45 #include <pad_naming.h>
46 #include <view/view_controls.h>
48 #include <confirm.h>
49 #include <bitmaps.h>
50 #include <cassert>
51 #include <functional>
52 using namespace std::placeholders;
53 #include "kicad_clipboard.h"
54 #include <router/router_tool.h>
57 #include <board_commit.h>
58 #include <zone_filler.h>
59 
60 
61 void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
62 {
63  // Iterate from the back so we don't have to worry about removals.
64  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
65  {
66  BOARD_ITEM* item = aCollector[ i ];
67 
68  if( ( aFlags & EXCLUDE_LOCKED ) && item->IsLocked() )
69  {
70  aCollector.Remove( item );
71  }
72  else if( item->Type() == PCB_MODULE_ZONE_AREA_T )
73  {
74  MODULE* mod = static_cast<MODULE*>( item->GetParent() );
75 
76  // case 1: handle locking
77  if( ( aFlags & EXCLUDE_LOCKED ) && mod && mod->IsLocked() )
78  {
79  aCollector.Remove( item );
80  }
81 
82  // case 2: selection contains both the module and its pads - remove the pads
83  if( !( aFlags & INCLUDE_PADS_AND_MODULES ) && mod && aCollector.HasItem( mod ) )
84  aCollector.Remove( item );
85  }
86  else if( item->Type() == PCB_PAD_T )
87  {
88  MODULE* mod = static_cast<MODULE*>( item->GetParent() );
89 
90  // case 1: handle locking
91  if( ( aFlags & EXCLUDE_LOCKED ) && mod && mod->IsLocked() )
92  {
93  aCollector.Remove( item );
94  }
95  else if( ( aFlags & EXCLUDE_LOCKED_PADS ) && mod && mod->PadsLocked() )
96  {
97  // Pad locking is considerably "softer" than item locking
98  aCollector.Remove( item );
99 
100  if( !mod->IsLocked() && !aCollector.HasItem( mod ) )
101  aCollector.Append( mod );
102  }
103 
104  // case 2: selection contains both the module and its pads - remove the pads
105  if( !( aFlags & INCLUDE_PADS_AND_MODULES ) && mod && aCollector.HasItem( mod ) )
106  aCollector.Remove( item );
107  }
108  else if( ( aFlags & EXCLUDE_TRANSIENTS ) && item->Type() == PCB_MARKER_T )
109  {
110  aCollector.Remove( item );
111  }
112  }
113 }
114 
115 
117  PCB_TOOL_BASE( "pcbnew.InteractiveEdit" ),
118  m_selectionTool( NULL ),
119  m_dragging( false ),
120  m_lockedSelected( false )
121 {
122 }
123 
124 
126 {
127  m_dragging = false;
128 
129  if( aReason != RUN )
130  m_commit.reset( new BOARD_COMMIT( this ) );
131 }
132 
133 
135 {
136 public:
138  ACTION_MENU( true )
139  {
141  SetTitle( _( "Special Tools..." ) );
142 
146  }
147 
148  ACTION_MENU* create() const override
149  {
150  return new SPECIAL_TOOLS_CONTEXT_MENU();
151  }
152 };
153 
154 
156 {
157  // Find the selection tool, so they can cooperate
158  m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
159  wxASSERT_MSG( m_selectionTool, "pcbnew.InteractiveSelection tool is not available" );
160 
161  auto editingModuleCondition =
162  [ this ] ( const SELECTION& aSelection )
163  {
164  return m_editModules;
165  };
166 
167  auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
169 
170  auto noActiveToolCondition =
171  [ this ] ( const SELECTION& aSelection )
172  {
173  return frame()->ToolStackIsEmpty();
174  };
175 
176  // Add context menu entries that are displayed when selection tool is active
178 
187  menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
188 
192 
194 
195  // Add the submenu for create array and special move
196  auto specialToolsSubMenu = std::make_shared<SPECIAL_TOOLS_CONTEXT_MENU>();
197  specialToolsSubMenu->SetTool( this );
198  menu.AddSeparator();
199  m_selectionTool->GetToolMenu().AddSubMenu( specialToolsSubMenu );
200  menu.AddMenu( specialToolsSubMenu.get(), SELECTION_CONDITIONS::NotEmpty );
201 
202  menu.AddSeparator();
205  // Selection tool handles the context menu for some other tools, such as the Picker.
206  // Don't add things like Paste when another tool is active.
207  menu.AddItem( ACTIONS::paste, noActiveToolCondition );
208 
209  // Footprint actions
210  menu.AddSeparator();
211  menu.AddItem( PCB_ACTIONS::editFpInFpEditor, singleModuleCondition );
212  menu.AddItem( PCB_ACTIONS::updateFootprint, singleModuleCondition );
213  menu.AddItem( PCB_ACTIONS::changeFootprint, singleModuleCondition );
214 
215  // Populate the context menu displayed during the edit tool (primarily the measure tool)
216  auto activeToolCondition = [ this ] ( const SELECTION& aSel ) {
217  return !frame()->ToolStackIsEmpty();
218  };
219 
220  auto frame = getEditFrame<PCB_BASE_FRAME>();
221  auto& ctxMenu = m_menu.GetMenu();
222 
223  // "Cancel" goes at the top of the context menu when a tool is active
224  ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
225  ctxMenu.AddSeparator( 1 );
226 
227  if( frame )
229 
230  return true;
231 }
232 
233 
234 int EDIT_TOOL::GetAndPlace( const TOOL_EVENT& aEvent )
235 {
236  SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
237  MODULE* module = getEditFrame<PCB_BASE_FRAME>()->GetFootprintFromBoardByReference();
238 
239  if( module )
240  {
243 
244  selectionTool->GetSelection().SetReferencePoint( module->GetPosition() );
246  }
247 
248  return 0;
249 }
250 
251 
252 bool EDIT_TOOL::invokeInlineRouter( int aDragMode )
253 {
255 
256  if( !theRouter )
257  return false;
258 
259  // make sure we don't accidentally invoke inline routing mode while the router is already active!
260  if( theRouter->IsToolActive() )
261  return false;
262 
263  if( theRouter->CanInlineDrag() )
264  {
266  return true;
267  }
268 
269  return false;
270 }
271 
272 
274 {
275  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
276 
277  return theRouter ? theRouter->Router()->Settings().InlineDragEnabled() : false;
278 }
279 
280 
281 int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
282 {
283  int mode = PNS::DM_ANY;
284 
285  if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
286  mode |= PNS::DM_FREE_ANGLE;
287 
288  invokeInlineRouter( mode );
289 
290  return 0;
291 }
292 
293 int EDIT_TOOL::Move( const TOOL_EVENT& aEvent )
294 {
296  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
297  VECTOR2I originalCursorPos = controls->GetCursorPosition();
298 
299  // Be sure that there is at least one item that we can modify. If nothing was selected before,
300  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
302  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
303  {
305  } );
306 
307  if( m_dragging || selection.Empty() )
308  return 0;
309 
310  LSET item_layers = selection.GetSelectionLayers();
311  bool unselect = selection.IsHover(); //N.B. This must be saved before the re-selection below
312 
313  // Now filter out locked pads. We cannot do this in the first RequestSelection() as we need
314  // the item_layers when a pad is the selection front (ie: will become curr_tiem).
316  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
317  {
319  } );
320 
321  if( selection.Empty() )
322  return 0;
323 
324  std::string tool = aEvent.GetCommandStr().get();
325  editFrame->PushTool( tool );
326  Activate();
327  controls->ShowCursor( true );
328  controls->SetAutoPan( true );
329 
330  std::vector<BOARD_ITEM*> sel_items;
331 
332  for( EDA_ITEM* item : selection )
333  {
334  BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
335  MODULE* module = dynamic_cast<MODULE*>( item );
336 
337  if( boardItem )
338  sel_items.push_back( boardItem );
339 
340  if( module )
341  {
342  for( D_PAD* pad : module->Pads() )
343  sel_items.push_back( pad );
344  }
345  }
346 
347  bool restore_state = false;
348  VECTOR2I totalMovement;
349  GRID_HELPER grid( m_toolMgr, editFrame->GetMagneticItemsSettings() );
350  TOOL_EVENT* evt = const_cast<TOOL_EVENT*>( &aEvent );
351  VECTOR2I prevPos;
352 
353  // Prime the pump
355 
356  // Main loop: keep receiving events
357  do
358  {
359  editFrame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
360  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
361  grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
362  controls->SetSnapping( !evt->Modifier( MD_ALT ) );
363 
364  if( evt->IsAction( &PCB_ACTIONS::move ) || evt->IsMotion() ||
365  evt->IsAction( &PCB_ACTIONS::drag ) || evt->IsDrag( BUT_LEFT ) ||
366  evt->IsAction( &ACTIONS::refreshPreview ) )
367  {
368  if( m_dragging && evt->Category() == TC_MOUSE )
369  {
370  VECTOR2I mousePos( controls->GetMousePosition() );
371 
372  m_cursor = grid.BestSnapAnchor( mousePos, item_layers, sel_items );
373 
375  {
377 
378  // The arrow keys are by definition SINGLE AXIS. Do not allow the other
379  // axis to be snapped to the grid.
380  if( action == ACTIONS::CURSOR_LEFT || action == ACTIONS::CURSOR_RIGHT )
381  m_cursor.y = prevPos.y;
382  else if( action == ACTIONS::CURSOR_UP || action == ACTIONS::CURSOR_DOWN )
383  m_cursor.x = prevPos.x;
384  }
385 
388 
389  VECTOR2I movement( m_cursor - prevPos );
390  prevPos = m_cursor;
391  totalMovement += movement;
392 
393  // Drag items to the current cursor position
394  for( EDA_ITEM* item : sel_items )
395  {
396  // Don't double move footprint pads, fields, etc.
397  if( !item->GetParent() || !item->GetParent()->IsSelected() )
398  static_cast<BOARD_ITEM*>( item )->Move( movement );
399  }
400 
401  frame()->UpdateMsgPanel();
402  }
403  else if( !m_dragging ) // Prepare to start dragging
404  {
405  if ( !evt->IsAction( &PCB_ACTIONS::move ) && isInteractiveDragEnabled() )
406  {
408  break;
409  }
410 
411  // deal with locked items (override lock or abort the operation)
413 
414  if( lockFlags == SELECTION_LOCKED )
415  break;
416 
417  m_dragging = true;
418 
419  // When editing modules, all items have the same parent
420  if( EditingModules() )
421  {
422  m_commit->Modify( selection.Front() );
423  }
424  else
425  {
426  // Save items, so changes can be undone
427  for( EDA_ITEM* item : selection )
428  {
429  // Don't double move footprint pads, fields, etc.
430  if( item->GetParent() && item->GetParent()->IsSelected() )
431  continue;
432 
433  m_commit->Modify( item );
434  }
435  }
436 
437  editFrame->UndoRedoBlock( true );
439 
441  {
442  // start moving with the reference point attached to the cursor
443  grid.SetAuxAxes( false );
444 
445  auto delta = m_cursor - selection.GetReferencePoint();
446 
447  // Drag items to the current cursor position
448  for( EDA_ITEM* item : selection )
449  {
450  // Don't double move footprint pads, fields, etc.
451  if( item->GetParent() && item->GetParent()->IsSelected() )
452  continue;
453 
454  static_cast<BOARD_ITEM*>( item )->Move( delta );
455  }
456 
458  }
459  else
460  {
461  std::vector<BOARD_ITEM*> items;
462 
463  for( EDA_ITEM* item : selection )
464  items.push_back( static_cast<BOARD_ITEM*>( item ) );
465 
466  // Set the current cursor position to the first dragged item origin, so the
467  // movement vector could be computed later
468  m_cursor = grid.BestDragOrigin( originalCursorPos, items );
470  grid.SetAuxAxes( true, m_cursor );
471  }
472 
474 
475  prevPos = m_cursor;
476  controls->SetAutoPan( true );
477  }
478 
481  }
482 
483  else if( evt->IsCancelInteractive() || evt->IsActivate() )
484  {
485  restore_state = true; // Canceling the tool means that items have to be restored
486  break; // Finish
487  }
488 
489  else if( evt->IsAction( &ACTIONS::undo ) )
490  {
491  restore_state = true; // Perform undo locally
492  break; // Finish
493  }
494 
495  // Dispatch TOOL_ACTIONs
496  else if( evt->Category() == TC_COMMAND )
497  {
498  if( evt->IsAction( &ACTIONS::doDelete ) )
499  {
500  break; // finish -- there is no further processing for removed items
501  }
502  else if( evt->IsAction( &ACTIONS::duplicate ) )
503  {
504  break; // finish -- Duplicate tool will start a new Move with the dup'ed items
505  }
506  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
507  {
508  // Reset positions so the Move Exactly is from the start.
509  for( EDA_ITEM* item : selection )
510  {
511  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
512  i->Move( -totalMovement );
513  }
514 
515  break; // finish -- we moved exactly, so we are finished
516  }
517  }
518 
519  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
520  {
521  break; // finish
522  }
523 
524  else
525  {
526  evt->SetPassEvent();
527  }
528 
529  } while( ( evt = Wait() ) ); // Assignment (instead of equality test) is intentional
530 
531  m_lockedSelected = false;
532  controls->ForceCursorPosition( false );
533  controls->ShowCursor( false );
534  controls->SetSnapping( false );
535  controls->SetAutoPan( false );
536 
537  m_dragging = false;
538  editFrame->UndoRedoBlock( false );
539 
540  // Discard reference point when selection is "dropped" onto the board (ie: not dragging anymore)
542 
543  if( unselect )
545 
546  // If canceled, we need to remove the dynamic ratsnest from the screen
547  if( restore_state )
548  {
550  m_commit->Revert();
551  }
552  else
553  {
554  m_commit->Push( _( "Drag" ) );
555  }
556 
557  editFrame->PopTool( tool );
558  return 0;
559 }
560 
562 {
564  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
565  {
567  } );
568 
569  for( EDA_ITEM* item : selection )
570  {
571  if( auto via = dyn_cast<VIA*>( item ) )
572  {
573  m_commit->Modify( item );
574 
575  int new_width;
576  int new_drill;
577 
578  if( via->GetViaType() == VIATYPE::MICROVIA )
579  {
580  auto net = via->GetNet();
581 
582  new_width = net->GetMicroViaSize();
583  new_drill = net->GetMicroViaDrillSize();
584  }
585  else
586  {
587  new_width = board()->GetDesignSettings().GetCurrentViaSize();
588  new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
589  }
590 
591  via->SetDrill( new_drill );
592  via->SetWidth( new_width );
593  }
594  else if ( auto track = dyn_cast<TRACK*>( item ) )
595  {
596  m_commit->Modify( item );
597 
598  int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
599  track->SetWidth( new_width );
600  }
601  }
602 
603  m_commit->Push( _("Edit track width/via size") );
604 
605  if( selection.IsHover() )
606  {
608 
609  // Notify other tools of the changes -- This updates the visual ratsnest
611  }
612 
613  return 0;
614 }
615 
616 
617 int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
618 {
619  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
621  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
622  {
624  } );
625 
626  // Tracks & vias are treated in a special way:
628  {
629  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection, *m_commit );
630  dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
631  }
632  else if( selection.Size() == 1 )
633  {
634  // Display properties dialog
635  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
636 
637  // Do not handle undo buffer, it is done by the properties dialogs
638  editFrame->OnEditItemRequest( item );
639 
640  // Notify other tools of the changes
642  }
643  else if( selection.Size() == 0 && getView()->IsLayerVisible( LAYER_WORKSHEET ) )
644  {
645  KIGFX::WS_PROXY_VIEW_ITEM* worksheet = editFrame->GetCanvas()->GetWorksheet();
646  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
647 
648  if( worksheet && worksheet->HitTestWorksheetItems( getView(), (wxPoint) cursorPos ) )
650  }
651 
652  if( selection.IsHover() )
653  {
655 
656  // Notify other tools of the changes -- This updates the visual ratsnest
658  }
659 
660  return 0;
661 }
662 
663 
664 int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
665 {
666  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
667 
669  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
670  {
672  },
673  nullptr, ! m_dragging );
674 
675  if( selection.Empty() )
676  return 0;
677 
679  auto refPt = selection.GetReferencePoint();
680  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
681 
682  // When editing modules, all items have the same parent
683  if( EditingModules() )
684  m_commit->Modify( selection.Front() );
685 
686  for( auto item : selection )
687  {
688  if( !item->IsNew() && !EditingModules() )
689  m_commit->Modify( item );
690 
691  static_cast<BOARD_ITEM*>( item )->Rotate( refPt, rotateAngle );
692  }
693 
694  if( !m_dragging )
695  m_commit->Push( _( "Rotate" ) );
696 
697  if( selection.IsHover() && !m_dragging )
699 
701 
702  if( m_dragging )
704 
705  return 0;
706 }
707 
708 
712 static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
713 {
714  wxPoint mirrored = aPoint;
715 
716  mirrored.x -= aMirrorPoint.x;
717  mirrored.x = -mirrored.x;
718  mirrored.x += aMirrorPoint.x;
719 
720  return mirrored;
721 }
722 
723 
727 static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
728 {
729  wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
730 
731  if( aPad.GetShape() == PAD_SHAPE_CUSTOM )
732  aPad.MirrorXPrimitives( tmpPt.x );
733 
734  aPad.SetPosition( tmpPt );
735 
736  aPad.SetX0( aPad.GetPosition().x );
737 
738  tmpPt = aPad.GetOffset();
739  tmpPt.x = -tmpPt.x;
740  aPad.SetOffset( tmpPt );
741 
742  auto tmpz = aPad.GetDelta();
743  tmpz.x = -tmpz.x;
744  aPad.SetDelta( tmpz );
745 
746  aPad.SetOrientation( -aPad.GetOrientation() );
747 }
748 
749 
750 int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
751 {
753  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
754  {
756  },
757  nullptr, !m_dragging );
758 
759  if( selection.Empty() )
760  return 0;
761 
763  auto refPoint = selection.GetReferencePoint();
764  wxPoint mirrorPoint( refPoint.x, refPoint.y );
765 
766  // When editing modules, all items have the same parent
767  if( EditingModules() )
768  m_commit->Modify( selection.Front() );
769 
770  for( EDA_ITEM* item : selection )
771  {
772  // only modify items we can mirror
773  switch( item->Type() )
774  {
775  case PCB_MODULE_EDGE_T:
776  case PCB_MODULE_TEXT_T:
778  case PCB_PAD_T:
779  // Only create undo entry for items on the board
780  if( !item->IsNew() && !EditingModules() )
781  m_commit->Modify( item );
782 
783  break;
784  default:
785  continue;
786  }
787 
788  // modify each object as necessary
789  switch( item->Type() )
790  {
791  case PCB_MODULE_EDGE_T:
792  {
793  auto& edge = static_cast<EDGE_MODULE&>( *item );
794  edge.Mirror( mirrorPoint, false );
795  break;
796  }
797 
799  {
800  auto& zone = static_cast<MODULE_ZONE_CONTAINER&>( *item );
801  zone.Mirror( mirrorPoint, false );
802  break;
803  }
804 
805  case PCB_MODULE_TEXT_T:
806  {
807  auto& modText = static_cast<TEXTE_MODULE&>( *item );
808  modText.Mirror( mirrorPoint, false );
809  break;
810  }
811 
812  case PCB_PAD_T:
813  {
814  auto& pad = static_cast<D_PAD&>( *item );
815  mirrorPadX( pad, mirrorPoint );
816  break;
817  }
818 
819  default:
820  // it's likely the commit object is wrong if you get here
821  assert( false );
822  break;
823  }
824  }
825 
826  if( !m_dragging )
827  m_commit->Push( _( "Mirror" ) );
828 
829  if( selection.IsHover() && !m_dragging )
831 
833 
834  if( m_dragging )
836 
837  return 0;
838 }
839 
840 
841 int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
842 {
844  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
845  {
847  },
848  nullptr, !m_dragging );
849 
850  if( selection.Empty() )
851  return 0;
852 
854 
855  // Flip around the anchor for footprints, and the bounding box center for board items
856  VECTOR2I modPoint = EditingModules() ? VECTOR2I( 0, 0 ) : selection.GetCenter();
857 
858  // If only one item selected, flip around the item anchor point, instead
859  // of the bounding box center, to avoid moving the item anchor
860  if( selection.GetSize() == 1 )
861  modPoint = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) )->GetPosition();
862 
863  bool leftRight = frame()->Settings().m_FlipLeftRight;
864 
865  // When editing modules, all items have the same parent
866  if( EditingModules() )
867  m_commit->Modify( selection.Front() );
868 
869  for( EDA_ITEM* item : selection )
870  {
871  if( !item->IsNew() && !EditingModules() )
872  m_commit->Modify( item );
873 
874  static_cast<BOARD_ITEM*>( item )->Flip( modPoint, leftRight );
875  }
876 
877  if( !m_dragging )
878  m_commit->Push( _( "Flip" ) );
879 
880  if( selection.IsHover() && !m_dragging )
882 
884 
885  if( m_dragging )
887 
888  return 0;
889 }
890 
891 
892 int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
893 {
894  ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
895 
896  // Do not delete items while actively routing.
897  if( routerTool && routerTool->Router() && routerTool->Router()->RoutingInProgress() )
898  return 1;
899 
900  std::vector<BOARD_ITEM*> lockedItems;
901  Activate();
902 
903  // get a copy instead of reference (as we're going to clear the selection before removing items)
904  PCBNEW_SELECTION selectionCopy;
907 
908  // If we are in a "Cut" operation, then the copied selection exists already
909  if( isCut )
910  {
911  selectionCopy = m_selectionTool->GetSelection();
912  }
913  else
914  {
915  selectionCopy = m_selectionTool->RequestSelection(
916  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
917  {
919  } );
920  }
921 
922  bool isHover = selectionCopy.IsHover();
923 
924  // in "alternative" mode, deletion is not just a simple list of selected items,
925  // it removes whole tracks, not just segments
926  if( isAlt && isHover
927  && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
928  {
930  }
931 
932  if( selectionCopy.Empty() )
933  return 0;
934 
935  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
936  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
937  // in the copyToClipboard() routine
938  if( !m_lockedSelected && !isCut )
939  {
940  // Second RequestSelection removes locked items but keeps a copy of their pointers
941  selectionCopy = m_selectionTool->RequestSelection(
942  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
943  {
945  },
946  &lockedItems );
947  }
948 
949 
950  // As we are about to remove items, they have to be removed from the selection first
952 
953  for( EDA_ITEM* item : selectionCopy )
954  {
955  if( m_editModules )
956  {
957  m_commit->Remove( item );
958  continue;
959  }
960 
961  switch( item->Type() )
962  {
963  case PCB_MODULE_TEXT_T:
964  {
965  auto text = static_cast<TEXTE_MODULE*>( item );
966  auto parent = static_cast<MODULE*>( item->GetParent() );
967 
968  if( text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
969  {
970  m_commit->Modify( text );
971  getView()->Remove( text );
972  parent->Remove( text );
973  }
974  }
975  break;
976 
977  case PCB_PAD_T:
978  {
979  auto pad = static_cast<D_PAD*>( item );
980  auto parent = static_cast<MODULE*>( item->GetParent() );
981 
982  m_commit->Modify( parent );
983  getView()->Remove( pad );
984  parent->Remove( pad );
985  }
986  break;
987 
989  {
990  auto zone = static_cast<MODULE_ZONE_CONTAINER*>( item );
991  auto parent = static_cast<MODULE*>( item->GetParent() );
992 
993  m_commit->Modify( parent );
994  getView()->Remove( zone );
995  parent->Remove( zone );
996  }
997  break;
998 
999  case PCB_ZONE_AREA_T:
1000  // We process the zones special so that cutouts can be deleted when the delete tool
1001  // is called from inside a cutout when the zone is selected.
1002  {
1003  // Only interact with cutouts when deleting and a single item is selected
1004  if( !isCut && selectionCopy.GetSize() == 1 )
1005  {
1007  auto zone = static_cast<ZONE_CONTAINER*>( item );
1008 
1009  int outlineIdx, holeIdx;
1010 
1011  if( zone->HitTestCutout( curPos, &outlineIdx, &holeIdx ) )
1012  {
1013  // Remove the cutout
1014  m_commit->Modify( zone );
1015  zone->RemoveCutout( outlineIdx, holeIdx );
1016 
1017  std::vector<ZONE_CONTAINER*> toFill;
1018  toFill.emplace_back( zone );
1019 
1020  // Fill the modified zone
1021  ZONE_FILLER filler( board() );
1022  filler.InstallNewProgressReporter( frame(), _( "Fill Zone" ), 4 );
1023  filler.Fill( toFill );
1024 
1025  // Update the display
1026  zone->Hatch();
1027  canvas()->Refresh();
1028 
1029  // Restore the selection on the original zone
1031 
1032  break;
1033  }
1034  }
1035 
1036  // Remove the entire zone otherwise
1037  m_commit->Remove( item );
1038  }
1039  break;
1040 
1041  default:
1042  m_commit->Remove( item );
1043  break;
1044  }
1045  }
1046 
1047  if( isCut )
1048  m_commit->Push( _( "Cut" ) );
1049  else
1050  m_commit->Push( _( "Delete" ) );
1051 
1052  if( !m_lockedSelected && !lockedItems.empty() )
1053  {
1055  STATUS_TEXT_POPUP statusPopup( frame() );
1056 
1057  m_lockedSelected = true;
1058  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &lockedItems );
1059  statusPopup.SetText( _( "Delete again to remove locked items" ) );
1060  statusPopup.PopupFor( 2000 );
1061  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
1062 
1063  Activate();
1064 
1065  while( m_lockedSelected && statusPopup.IsShown() )
1066  {
1067  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
1068  Wait();
1069  }
1070 
1071  // Ensure statusPopup is hidden after use and before deleting it:
1072  statusPopup.Hide();
1073  }
1074 
1075  m_lockedSelected = false;
1076 
1077  return 0;
1078 }
1079 
1080 
1081 int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
1082 {
1084  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1085  {
1086  EditToolSelectionFilter( aCollector,
1088  } );
1089 
1090  if( selection.Empty() )
1091  return 0;
1092 
1093  wxPoint translation;
1094  double rotation;
1095  ROTATION_ANCHOR rotationAnchor = selection.Size() > 1 ? ROTATE_AROUND_SEL_CENTER
1097 
1098  // TODO: Implement a visible bounding border at the edge
1099  auto sel_box = selection.GetBoundingBox();
1100 
1101  DIALOG_MOVE_EXACT dialog( frame(), translation, rotation, rotationAnchor, sel_box );
1102  int ret = dialog.ShowModal();
1103 
1104  if( ret == wxID_OK )
1105  {
1106  VECTOR2I rp = selection.GetCenter();
1107  wxPoint selCenter( rp.x, rp.y );
1108 
1109  // Make sure the rotation is from the right reference point
1110  selCenter += translation;
1111 
1112  // When editing modules, all items have the same parent
1113  if( EditingModules() )
1114  m_commit->Modify( selection.Front() );
1115 
1116  for( EDA_ITEM* selItem : selection )
1117  {
1118  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
1119 
1120  if( !item->IsNew() && !EditingModules() )
1121  m_commit->Modify( item );
1122 
1123  item->Move( translation );
1124 
1125  switch( rotationAnchor )
1126  {
1128  item->Rotate( item->GetPosition(), rotation );
1129  break;
1131  item->Rotate( selCenter, rotation );
1132  break;
1134  item->Rotate( (wxPoint) frame()->GetScreen()->m_LocalOrigin, rotation );
1135  break;
1137  item->Rotate( board()->GetDesignSettings().m_AuxOrigin, rotation );
1138  break;
1139  }
1140 
1141  if( !m_dragging )
1142  getView()->Update( item );
1143  }
1144 
1145  m_commit->Push( _( "Move exact" ) );
1146 
1147  if( selection.IsHover() )
1149 
1151 
1152  if( m_dragging )
1154  }
1155 
1156  return 0;
1157 }
1158 
1159 
1160 int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
1161 {
1162  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
1163 
1164  // Be sure that there is at least one item that we can modify
1166  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1167  {
1169  } );
1170 
1171  if( selection.Empty() )
1172  return 0;
1173 
1174  // we have a selection to work on now, so start the tool process
1175  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1176 
1177  // If the selection was given a hover, we do not keep the selection after completion
1178  bool is_hover = selection.IsHover();
1179 
1180  std::vector<BOARD_ITEM*> new_items;
1181  new_items.reserve( selection.Size() );
1182 
1183  BOARD_ITEM* orig_item = nullptr;
1184  BOARD_ITEM* dupe_item = nullptr;
1185 
1186  // Each selected item is duplicated and pushed to new_items list
1187  // Old selection is cleared, and new items are then selected.
1188  for( EDA_ITEM* item : selection )
1189  {
1190  orig_item = static_cast<BOARD_ITEM*>( item );
1191 
1192  if( m_editModules )
1193  {
1194  MODULE* editModule = editFrame->GetBoard()->GetFirstModule();
1195  dupe_item = editModule->DuplicateItem( orig_item );
1196 
1197  if( increment && item->Type() == PCB_PAD_T
1198  && PAD_NAMING::PadCanHaveName( *static_cast<D_PAD*>( dupe_item ) ) )
1199  {
1200  PAD_TOOL* padTool = m_toolMgr->GetTool<PAD_TOOL>();
1201  wxString padName = padTool->GetLastPadName();
1202  padName = editModule->GetNextPadName( padName );
1203  padTool->SetLastPadName( padName );
1204  static_cast<D_PAD*>( dupe_item )->SetName( padName );
1205  }
1206  }
1207  else if( orig_item->GetParent() && orig_item->GetParent()->Type() == PCB_MODULE_T )
1208  {
1209  MODULE* parent = static_cast<MODULE*>( orig_item->GetParent() );
1210 
1211  m_commit->Modify( parent );
1212  dupe_item = parent->DuplicateItem( orig_item, true /* add to parent */ );
1213  }
1214  else
1215  {
1216  switch( orig_item->Type() )
1217  {
1218  case PCB_MODULE_T:
1219  case PCB_TEXT_T:
1220  case PCB_LINE_T:
1221  case PCB_TRACE_T:
1222  case PCB_VIA_T:
1223  case PCB_ZONE_AREA_T:
1224  case PCB_TARGET_T:
1225  case PCB_DIMENSION_T:
1226  dupe_item = orig_item->Duplicate();
1227  break;
1228 
1229  default:
1230  // Silently drop other items (such as footprint texts) from duplication
1231  break;
1232  }
1233  }
1234 
1235  if( dupe_item )
1236  {
1237  // Clear the selection flag here, otherwise the SELECTION_TOOL
1238  // will not properly select it later on
1239  dupe_item->ClearSelected();
1240 
1241  new_items.push_back( dupe_item );
1242  m_commit->Add( dupe_item );
1243  }
1244  }
1245 
1246  // Clear the old selection first
1248 
1249  // Select the new items
1250  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
1251 
1252  // record the new items as added
1253  if( !selection.Empty() )
1254  {
1255  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
1256  (int) new_items.size() ) );
1257 
1258  // If items were duplicated, pick them up
1259  // this works well for "dropping" copies around and pushes the commit
1261  Move( evt );
1262 
1263  // After moving the new items, we need to refresh the group and view flags
1265 
1266  if( !is_hover )
1267  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
1268  }
1269 
1270  return 0;
1271 }
1272 
1273 
1275 {
1277  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1278  {
1280  } );
1281 
1282  if( selection.Empty() )
1283  return 0;
1284 
1285  // we have a selection to work on now, so start the tool process
1286  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
1287  ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
1288  array_creator.Invoke();
1289 
1290  return 0;
1291 }
1292 
1293 
1295 {
1296  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1297  {
1298  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1299 
1300  if( item->Type() != PCB_PAD_T )
1301  aCollector.Remove( i );
1302  }
1303 }
1304 
1305 
1307 {
1308  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1309  {
1310  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1311 
1312  if( item->Type() != PCB_MODULE_T )
1313  aCollector.Remove( i );
1314  }
1315 }
1316 
1317 
1319 {
1320  if( m_dragging && aSelection.HasReferencePoint() )
1321  return false;
1322 
1323  // When there is only one item selected, the reference point is its position...
1324  if( aSelection.Size() == 1 )
1325  {
1326  auto item = static_cast<BOARD_ITEM*>( aSelection.Front() );
1327  auto pos = item->GetPosition();
1328  aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
1329  }
1330  // ...otherwise modify items with regard to the grid-snapped cursor position
1331  else
1332  {
1334  aSelection.SetReferencePoint( m_cursor );
1335  }
1336 
1337  return true;
1338 }
1339 
1340 
1342 {
1343  std::string tool = "pcbnew.InteractiveEdit.selectReferencePoint";
1344  STATUS_TEXT_POPUP statusPopup( frame() );
1346  OPT<VECTOR2I> pickedPoint;
1347  bool done = false;
1348 
1349  statusPopup.SetText( _( "Select reference point for the copy..." ) );
1350 
1351  picker->SetClickHandler(
1352  [&]( const VECTOR2D& aPoint ) -> bool
1353  {
1354  pickedPoint = aPoint;
1355  statusPopup.SetText( _( "Selection copied." ) );
1356  statusPopup.Expire( 800 );
1357  return false; // we don't need any more points
1358  } );
1359 
1360  picker->SetMotionHandler(
1361  [&] ( const VECTOR2D& aPos )
1362  {
1363  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
1364  } );
1365 
1366  picker->SetCancelHandler(
1367  [&]()
1368  {
1369  statusPopup.SetText( _( "Copy cancelled." ) );
1370  statusPopup.Expire( 800 );
1371  } );
1372 
1373  picker->SetFinalizeHandler(
1374  [&]( const int& aFinalState )
1375  {
1376  done = true;
1377  } );
1378 
1379  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
1380  statusPopup.Popup();
1381 
1382  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
1383 
1384  while( !done )
1385  Wait();
1386 
1387  // Ensure statusPopup is hidden after use and before deleting it:
1388  statusPopup.Hide();
1389 
1390  if( pickedPoint.is_initialized() )
1391  aReferencePoint = pickedPoint.get();
1392 
1393  return pickedPoint.is_initialized();
1394 }
1395 
1396 
1398 {
1399  CLIPBOARD_IO io;
1400 
1401  Activate();
1402 
1404  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1405  {
1407  } );
1408 
1409  if( selection.Empty() )
1410  return 1;
1411 
1412  VECTOR2I refPoint;
1413  bool rv = pickCopyReferencePoint( refPoint );
1414  frame()->SetMsgPanel( board() );
1415 
1416  if( !rv )
1417  return 1;
1418 
1419  selection.SetReferencePoint( refPoint );
1420 
1421  io.SetBoard( board() );
1422  io.SaveSelection( selection );
1423 
1424  return 0;
1425 }
1426 
1427 
1429 {
1430  if( !copyToClipboard( aEvent ) )
1431  {
1432  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
1433  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
1434  // in the copyToClipboard() routine
1435  TOOL_EVENT evt( aEvent.Category(), aEvent.Action(), TOOL_ACTION_SCOPE::AS_GLOBAL );
1437  Remove( evt );
1438  }
1439 
1440  return 0;
1441 }
1442 
1443 
1445 {
1447  Go( &EDIT_TOOL::Move, PCB_ACTIONS::move.MakeEvent() );
1448  Go( &EDIT_TOOL::Move, PCB_ACTIONS::drag.MakeEvent() );
1449  Go( &EDIT_TOOL::Drag, PCB_ACTIONS::drag45Degree.MakeEvent() );
1451  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
1452  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCcw.MakeEvent() );
1453  Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
1454  Go( &EDIT_TOOL::Remove, ACTIONS::doDelete.MakeEvent() );
1455  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::deleteFull.MakeEvent() );
1458  Go( &EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() );
1461  Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
1463 
1464  Go( &EDIT_TOOL::copyToClipboard, ACTIONS::copy.MakeEvent() );
1465  Go( &EDIT_TOOL::cutToClipboard, ACTIONS::cut.MakeEvent() );
1466 }
1467 
1468 
static TOOL_ACTION selectItems
Selects a list of items (specified as the event parameter)
Definition: pcb_actions.h:69
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:62
VECTOR2I GetReferencePoint() const
Definition: selection.h:240
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
void setTransitions() override
Sets up handlers for various events.
Definition: edit_tool.cpp:1444
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddMenu()
VECTOR2I m_cursor
Definition: edit_tool.h:188
void ClearReferencePoint()
Definition: selection.h:250
void AddStandardSubMenus(TOOL_MENU &aMenu)
Function CreateBasicMenu.
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon)
Function Add() Adds a wxWidgets-style entry to the menu.
TOOL_MENU m_menu
functions below are not yet implemented - their interface may change
int Properties(const TOOL_EVENT &aEvent)
Function Properties() Displays properties window for the selected object.
Definition: edit_tool.cpp:617
int Rotate(const TOOL_EVENT &aEvent)
Function Rotate() Rotates currently selected items.
Definition: edit_tool.cpp:664
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:92
static TOOL_ACTION deleteFull
Definition: pcb_actions.h:122
bool IsHover() const
Definition: selection.h:71
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:313
#define INCLUDE_PADS_AND_MODULES
Definition: edit_tool.h:56
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Function GetMousePosition() Returns the current mouse pointer position.
BOARD * board() const
static TOOL_ACTION editFpInFpEditor
Definition: pcb_actions.h:322
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
static TOOL_ACTION pageSettings
Definition: actions.h:59
REMOVE_FLAGS
Remove event modifier flags
Definition: actions.h:190
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
static TOOL_ACTION changeTrackWidth
Updates selected tracks & vias to the current track & via dimensions.
Definition: pcb_actions.h:106
ACTION_MENU.
Definition: action_menu.h:44
This file is part of the common library.
static TOOL_ACTION doDelete
Definition: actions.h:74
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
Definition: selection.h:214
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:190
void ClearSelected()
Definition: base_struct.h:211
void SetCurrentCursor(wxStockCursor aStockCursorID)
Function SetCurrentCursor Set the current cursor shape for this panel.
VIEW_CONTROLS class definition.
TOOL_ACTIONS Action() const
Returns more specific information about the type of an event.
Definition: tool_event.h:250
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Function OnlyTypes Creates a functor that tests if the selected items are only of given types.
SELECTION_TOOL.
int ChangeTrackWidth(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:561
SELECTION_LOCK_FLAGS CheckLock()
Checks if the user has agreed to modify locked items for the given selection.
STATUS_TEXT_POPUP.
Definition: status_popup.h:79
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.h:138
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:133
Tool is invoked after being inactive.
Definition: tool_base.h:81
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
virtual void OnEditItemRequest(BOARD_ITEM *aItem)=0
Function OnEditItemRequest Install the corresponding dialog editor for the given item.
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:102
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:376
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:109
PADS & Pads()
Definition: class_module.h:169
bool PadCanHaveName(const D_PAD &aPad)
Check if a pad should be named.
Definition: pad_naming.cpp:26
PAD_TOOL.
Definition: pad_tool.h:37
TOOL_MENU & GetToolMenu()
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
virtual void SetSnapping(bool aEnabled)
Function SetSnapping() Enables/disables snapping cursor to grid.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:140
static TOOL_ACTION selectConnection
Selects tracks between junctions or expands an existing selection to pads or the entire connection.
Definition: pcb_actions.h:77
static TOOL_ACTION getAndPlace
Find an item and start moving.
Definition: pcb_actions.h:425
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:155
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:551
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:132
TOOL_EVENT_CATEGORY Category() const
Returns the category (eg. mouse/keyboard/action) of an event..
Definition: tool_event.h:247
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:103
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Moves cursor to the requested position expressed in world coordinates.
static TOOL_ACTION changeFootprint
Definition: pcb_actions.h:303
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
static TOOL_ACTION updateFootprint
Definition: pcb_actions.h:301
void UndoRedoBlock(bool aBlock=true)
Function UndoRedoBlock Enables/disable undo and redo operations.
virtual MAGNETIC_SETTINGS * GetMagneticItemsSettings()
TOOL_BASE * FindTool(int aId) const
Function FindTool() Searches for a tool with given ID.
SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:185
static SELECTION_CONDITION Count(int aNumber)
Function Count Creates a functor that tests if the number of selected items is equal to the value giv...
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
void SetBoard(BOARD *aBoard)
static bool NotEmpty(const SELECTION &aSelection)
Function NotEmpty Tests if there are any items selected.
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Function SetFinalizeHandler() Sets a handler for the finalize event.
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:129
static const TOOL_EVENT SelectedItemsModified
Definition: actions.h:206
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
int Mirror(const TOOL_EVENT &aEvent)
Function Mirror Mirrors the current selection.
Definition: edit_tool.cpp:750
void InstallNewProgressReporter(wxWindow *aParent, const wxString &aTitle, int aNumPhases)
Definition: zone_filler.cpp:93
const VC_SETTINGS & GetSettings() const
Returns the current VIEW_CONTROLS settings
bool IsNew() const
Definition: base_struct.h:199
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:67
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:112
int cutToClipboard(const TOOL_EVENT &aEvent)
Function cutToClipboard() Cuts the current selection to the clipboard by formatting it as a fake pcb ...
Definition: edit_tool.cpp:1428
PCBNEW_SELECTION & GetSelection()
Function GetSelection()
virtual const wxPoint GetPosition() const
Definition: base_struct.h:337
static TOOL_ACTION pickerTool
Definition: actions.h:148
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:119
const LSET GetSelectionLayers()
PCB_BASE_EDIT_FRAME * frame() const
bool m_lockedSelected
Definition: edit_tool.h:187
void SetParameter(T aParam)
Function SetParameter() Sets a non-standard parameter assigned to the event.
Definition: tool_event.h:453
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:100
class MODULE, a footprint
Definition: typeinfo.h:89
static TOOL_ACTION copy
Definition: actions.h:70
int Flip(const TOOL_EVENT &aEvent)
Function Flip() Rotates currently selected items.
Definition: edit_tool.cpp:841
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:245
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:118
bool HitTestWorksheetItems(VIEW *aView, const wxPoint &aPosition)
bool isInteractiveDragEnabled() const
Definition: edit_tool.cpp:273
int GetAndPlace(const TOOL_EVENT &aEvent)
Find an item and start moving.
Definition: edit_tool.cpp:234
Generic tool for picking a point.
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:96
LSET is a set of PCB_LAYER_IDs.
const PCBNEW_SELECTION & selection() const
void SetLastPadName(const wxString &aPadName)
Definition: pad_tool.h:74
#define NULL
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
wxString GetLastPadName() const
Definition: pad_tool.h:73
bool m_dragging
Definition: edit_tool.h:186
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
virtual void Move(const wxPoint &aMoveVector)
Function Move move this object.
virtual void PopTool(const std::string &actionName)
int ShowQuasiModal()
SELECTION_LOCK_FLAGS
Definition: selection.h:279
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
Definition: action_menu.cpp:70
const wxPoint & GetOffset() const
Definition: class_pad.h:229
TOOL_EVENT.
Definition: tool_event.h:171
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:364
static TOOL_ACTION cut
Definition: actions.h:69
MODULE * GetFirstModule() const
Gets the first module in the list (used in footprint viewer/editor) or NULL if none.
Definition: class_board.h:330
bool ToolStackIsEmpty()
Definition: tools_holder.h:84
bool HasItem(const EDA_ITEM *aItem) const
Function HasItem tests if aItem has already been collected.
Definition: collector.h:183
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Definition: edit_tool.cpp:155
VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (such a...
virtual void Popup(wxWindow *aFocus=nullptr)
int Drag(const TOOL_EVENT &aEvent)
Function Drag() Invoke the PNS router to drag tracks.
Definition: edit_tool.cpp:281
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
wxString GetNextPadName(const wxString &aLastPadName) const
Function GetNextPadName returns the next available pad name in the module.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle)
Function Rotate Rotate this object.
bool Fill(const std::vector< ZONE_CONTAINER * > &aZones, bool aCheck=false)
virtual void Move(const wxPoint &aWhere)
ACTION_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
Definition: edit_tool.cpp:148
const wxSize & GetDelta() const
Definition: class_pad.h:223
All active tools
Definition: tool_event.h:147
BOARD_ITEM * DuplicateItem(const BOARD_ITEM *aItem, bool aAddToModule=false)
Function DuplicateItem Duplicate a given item within the module, optionally adding it to the board.
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:105
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1540
void Expire(int aMsecs)
Hides the popup after a specified time.
virtual void PopupFor(int aMsecs)
ROTATION_ANCHOR
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:297
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:194
static TOOL_ACTION hideDynamicRatsnest
Definition: pcb_actions.h:418
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
int Move(const TOOL_EVENT &aEvent)
Function Move() Main loop in which events are handled.
Definition: edit_tool.cpp:293
#define EXCLUDE_TRANSIENTS
Definition: edit_tool.h:55
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:121
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:101
static TOOL_ACTION inlineBreakTrack
Breaks track when router is not activated.
Definition: pcb_actions.h:130
static TOOL_ACTION drag
Definition: pcb_actions.h:93
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: edit_tool.cpp:125
bool EditingModules() const
void AddSeparator(int aOrder=ANY_ORDER)
Function AddSeparator()
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:100
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:97
static void PadFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
Function PadFilter() A selection filter which prunes the selection to contain only items of type PCB_...
Definition: edit_tool.cpp:1294
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
int MoveExact(const TOOL_EVENT &aEvent)
Function MoveExact() Invokes a dialog box to allow moving of the item by an exact amount.
Definition: edit_tool.cpp:1081
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:463
int Remove(const TOOL_EVENT &aEvent)
Function Remove() Deletes currently selected items.
Definition: edit_tool.cpp:892
static ROUTER * theRouter
Definition: pns_router.cpp:63
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:100
int GetCurrentViaSize() const
Function GetCurrentViaSize.
void SaveSelection(const PCBNEW_SELECTION &selected)
virtual bool IsLocked() const
Function IsLocked.
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:252
bool HasReferencePoint() const
Definition: selection.h:235
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the menu.
Definition: action_menu.cpp:88
int CreateArray(const TOOL_EVENT &aEvent)
Function CreateArray() Creates an array of the selected items, invoking the array editor dialog to se...
Definition: edit_tool.cpp:1274
KIGFX::WS_PROXY_VIEW_ITEM * GetWorksheet() const
PCBNEW_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, std::vector< BOARD_ITEM * > *aFiltered=nullptr, bool aConfirmLockedItems=false)
Function RequestSelection()
KIGFX::VIEW_CONTROLS * controls() const
Common, abstract interface for edit frames.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
MODULE * module() const
#define _(s)
Definition: 3d_actions.cpp:33
long m_lastKeyboardCursorCommand
ACTIONS::CURSOR_UP, ACTIONS::CURSOR_DOWN, etc.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:313
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
void AddSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Function CreateSubMenu.
Definition: tool_menu.cpp:52
bool m_lastKeyboardCursorPositionValid
Is last cursor motion event coming from keyboard arrow cursor motion action
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
Definition: pcb_actions.h:65
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Function OnlyType Creates a functor that tests if the selected items are only of given type.
PCBNEW_SETTINGS & Settings()
TOOL_EVENT MakeEvent() const
Function MakeEvent() Returns the event associated with the action (i.e.
Definition: tool_action.h:107
int Size() const
Returns the number of selected parts.
Definition: selection.h:127
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
static wxPoint mirrorPointX(const wxPoint &aPoint, const wxPoint &aMirrorPoint)
Definition: edit_tool.cpp:712
void SetMotionHandler(MOTION_HANDLER aHandler)
Function SetMotionHandler() Sets a handler for mouse motion.
static TOOL_ACTION positionRelative
Activation of the position relative tool.
Definition: pcb_actions.h:215
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
boost::optional< T > OPT
Definition: optional.h:7
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:430
bool PadsLocked() const
Definition: class_module.h:333
void Activate()
Function Activate() Runs the tool.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
static TOOL_ACTION undo
Definition: actions.h:67
void SetX0(int x)
Definition: class_pad.h:217
#define EXCLUDE_LOCKED
Function EditToolSelectionFilter.
Definition: edit_tool.h:53
int copyToClipboard(const TOOL_EVENT &aEvent)
Function copyToClipboard() Sends the current selection to the clipboard by formatting it as a fake pc...
Definition: edit_tool.cpp:1397
PAD_SHAPE_T GetShape() const
Definition: class_pad.h:153
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:419
static void FootprintFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
Function FootprintFilter() A selection filter which prunes the selection to contain only items of typ...
Definition: edit_tool.cpp:1306
BOARD * GetBoard() const
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
class ZONE_CONTAINER, managed by a footprint
Definition: typeinfo.h:95
bool RoutingInProgress() const
Definition: pns_router.cpp:117
ROUTER * Router() const
const wxPoint GetPosition() const override
Definition: class_pad.h:161
#define EXCLUDE_LOCKED_PADS
Definition: edit_tool.h:54
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
PCB_DRAW_PANEL_GAL * canvas() const
BOARD_ITEM_CONTAINER * GetParent() const
int GetEventRotationAngle(const PCB_BASE_EDIT_FRAME &aFrame, const TOOL_EVENT &aEvt)
Function getEventRotationAngle()
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:228
bool updateModificationPoint(PCBNEW_SELECTION &aSelection)
Returns the right modification point (e.g.
Definition: edit_tool.cpp:1318
void EditToolSelectionFilter(GENERAL_COLLECTOR &aCollector, int aFlags)
Definition: edit_tool.cpp:61
void SetCancelHandler(CANCEL_HANDLER aHandler)
Function SetCancelHandler() Sets a handler for cancel events (ESC or context-menu Cancel).
void PostEvent(const TOOL_EVENT &aEvent)
Puts an event to the event queue to be processed at the end of event processing cycle.
Definition: tool_manager.h:268
int Duplicate(const TOOL_EVENT &aEvent)
Function Duplicate() Duplicates the current selection and starts a move action.
Definition: edit_tool.cpp:1160
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()
EDA_RECT GetBoundingBox() const
Definition: selection.h:156
const wxPoint GetPosition() const override
Definition: class_module.h:206
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:199
static void mirrorPadX(D_PAD &aPad, const wxPoint &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point.
Definition: edit_tool.cpp:727
void MirrorXPrimitives(int aX)
Mirror the primitives about a coordinate.
Definition: class_pad.cpp:481
static TOOL_ACTION paste
Definition: actions.h:71
PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
static TOOL_ACTION duplicate
Definition: actions.h:73
void SetText(const wxString &aText)
Display a text.
static TOOL_ACTION refreshPreview
Definition: actions.h:101
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:222
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:184
bool pickCopyReferencePoint(VECTOR2I &aReferencePoint)
Definition: edit_tool.cpp:1341
BOARD_ITEM * Duplicate() const
Function Duplicate creates a copy of a BOARD_ITEM.
void DisplayToolMsg(const wxString &msg) override
const BITMAP_OPAQUE options_board_xpm[1]
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
virtual void UpdateMsgPanel()
Redraw the message panel.
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:416
void SetClickHandler(CLICK_HANDLER aHandler)
Function SetClickHandler() Sets a handler for mouse click event.