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_board.h>
29 #include <class_module.h>
30 #include <class_edge_mod.h>
31 #include <collectors.h>
32 #include <pcb_edit_frame.h>
33 #include <kiway.h>
34 #include <footprint_edit_frame.h>
35 #include <array_creator.h>
36 #include <pcbnew_settings.h>
37 #include <status_popup.h>
38 #include <tool/tool_manager.h>
39 #include <tools/pcb_actions.h>
40 #include <tools/selection_tool.h>
41 #include <tools/edit_tool.h>
43 #include <tools/tool_event_utils.h>
44 #include <tools/grid_helper.h>
45 #include <view/view_controls.h>
47 #include <confirm.h>
48 #include <bitmaps.h>
49 #include <cassert>
50 #include <functional>
51 using namespace std::placeholders;
52 #include "kicad_clipboard.h"
53 #include <router/router_tool.h>
57 #include <board_commit.h>
58 
59 
60 void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
61 {
62  // Iterate from the back so we don't have to worry about removals.
63  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
64  {
65  BOARD_ITEM* item = aCollector[ i ];
66 
67  if( ( aFlags & EXCLUDE_LOCKED ) && item->IsLocked() )
68  {
69  aCollector.Remove( item );
70  }
71  else if( item->Type() == PCB_PAD_T )
72  {
73  MODULE* mod = static_cast<MODULE*>( item->GetParent() );
74 
75  // case 1: handle locking
76  if( ( aFlags & EXCLUDE_LOCKED ) && mod && mod->IsLocked() )
77  {
78  aCollector.Remove( item );
79  }
80  else if( ( aFlags & EXCLUDE_LOCKED_PADS ) && mod && mod->PadsLocked() )
81  {
82  // Pad locking is considerably "softer" than item locking
83  aCollector.Remove( item );
84 
85  if( !mod->IsLocked() && !aCollector.HasItem( mod ) )
86  aCollector.Append( mod );
87  }
88 
89  // case 2: selection contains both the module and its pads - remove the pads
90  if( !( aFlags & INCLUDE_PADS_AND_MODULES ) && mod && aCollector.HasItem( mod ) )
91  aCollector.Remove( item );
92  }
93  else if( ( aFlags & EXCLUDE_TRANSIENTS ) && item->Type() == PCB_MARKER_T )
94  {
95  aCollector.Remove( item );
96  }
97  }
98 }
99 
100 
102  PCB_TOOL_BASE( "pcbnew.InteractiveEdit" ),
103  m_selectionTool( NULL ),
104  m_dragging( false ),
105  m_lockedSelected( false )
106 {
107 }
108 
109 
111 {
112  m_dragging = false;
113 
114  if( aReason != RUN )
115  m_commit.reset( new BOARD_COMMIT( this ) );
116 }
117 
118 
120 {
121  // Find the selection tool, so they can cooperate
122  m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
123  wxASSERT_MSG( m_selectionTool, "pcbnew.InteractiveSelection tool is not available" );
124 
125  auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
126  return m_editModules;
127  };
128 
129  auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
131 
132  auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) {
133  return frame()->ToolStackIsEmpty();
134  };
135 
136  // Add context menu entries that are displayed when selection tool is active
138 
150 
155  menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
156 
157  menu.AddSeparator();
160  // Selection tool handles the context menu for some other tools, such as the Picker.
161  // Don't add things like Paste when another tool is active.
162  menu.AddItem( ACTIONS::paste, noActiveToolCondition );
163 
164  // Footprint actions
165  menu.AddSeparator();
166  menu.AddItem( PCB_ACTIONS::editFootprintInFpEditor, singleModuleCondition );
167  menu.AddItem( PCB_ACTIONS::updateFootprint, singleModuleCondition );
168  menu.AddItem( PCB_ACTIONS::changeFootprint, singleModuleCondition );
169 
170  // Populate the context menu displayed during the edit tool (primarily the measure tool)
171  auto activeToolCondition = [ this ] ( const SELECTION& aSel ) {
172  return frame()->ToolStackIsEmpty();
173  };
174 
175  auto frame = getEditFrame<PCB_BASE_FRAME>();
176  auto& ctxMenu = m_menu.GetMenu();
177 
178  // "Cancel" goes at the top of the context menu when a tool is active
179  ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
180  ctxMenu.AddSeparator( 1 );
181 
182  if( frame )
184 
185  return true;
186 }
187 
188 
189 int EDIT_TOOL::GetAndPlace( const TOOL_EVENT& aEvent )
190 {
191  SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
192  MODULE* module = getEditFrame<PCB_BASE_FRAME>()->GetFootprintFromBoardByReference();
193 
194  if( module )
195  {
198 
199  selectionTool->GetSelection().SetReferencePoint( module->GetPosition() );
201  }
202 
203  return 0;
204 }
205 
206 
207 bool EDIT_TOOL::invokeInlineRouter( int aDragMode )
208 {
210 
211  if( !theRouter )
212  return false;
213 
214  // make sure we don't accidentally invoke inline routing mode while the router is already active!
215  if( theRouter->IsToolActive() )
216  return false;
217 
218  if( theRouter->CanInlineDrag() )
219  {
221  return true;
222  }
223 
224  return false;
225 }
226 
227 
229 {
230  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
231 
232  return theRouter ? theRouter->Router()->Settings().InlineDragEnabled() : false;
233 }
234 
235 
236 int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
237 {
238  int mode = PNS::DM_ANY;
239 
240  if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
241  mode |= PNS::DM_FREE_ANGLE;
242 
243  invokeInlineRouter( mode );
244 
245  return 0;
246 }
247 
248 int EDIT_TOOL::Move( const TOOL_EVENT& aEvent )
249 {
251  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
252  VECTOR2I originalCursorPos = controls->GetCursorPosition();
253 
254  // Be sure that there is at least one item that we can modify. If nothing was selected before,
255  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
257  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
258  {
260  } );
261 
262  if( m_dragging || selection.Empty() )
263  return 0;
264 
265  LSET item_layers = selection.GetSelectionLayers();
266  bool unselect = selection.IsHover(); //N.B. This must be saved before the re-selection below
267 
268  // Now filter out locked pads. We cannot do this in the first RequestSelection() as we need
269  // the item_layers when a pad is the selection front (ie: will become curr_tiem).
271  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
272  {
274  } );
275 
276  if( selection.Empty() )
277  return 0;
278 
279  std::string tool = aEvent.GetCommandStr().get();
280  editFrame->PushTool( tool );
281  Activate();
282  controls->ShowCursor( true );
283  controls->SetAutoPan( true );
284 
285  std::vector<BOARD_ITEM*> sel_items;
286 
287  for( EDA_ITEM* item : selection )
288  {
289  BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
290  MODULE* module = dynamic_cast<MODULE*>( item );
291 
292  if( boardItem )
293  sel_items.push_back( boardItem );
294 
295  if( module )
296  {
297  for( D_PAD* pad : module->Pads() )
298  sel_items.push_back( pad );
299  }
300  }
301 
302  bool restore_state = false;
303  VECTOR2I totalMovement;
304  GRID_HELPER grid( editFrame );
305  TOOL_EVENT* evt = const_cast<TOOL_EVENT*>( &aEvent );
306  VECTOR2I prevPos;
307 
308  // Prime the pump
310 
311  // Main loop: keep receiving events
312  do
313  {
314  editFrame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
315  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
316  grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
317  controls->SetSnapping( !evt->Modifier( MD_ALT ) );
318 
319  if( evt->IsAction( &PCB_ACTIONS::move ) || evt->IsMotion() ||
320  evt->IsAction( &PCB_ACTIONS::drag ) || evt->IsDrag( BUT_LEFT ) ||
322  {
323  if( m_dragging && evt->Category() == TC_MOUSE )
324  {
325  VECTOR2I mousePos( controls->GetMousePosition() );
326 
327  m_cursor = grid.BestSnapAnchor( mousePos, item_layers, sel_items );
328 
330  {
332 
333  // The arrow keys are by definition SINGLE AXIS. Do not allow the other
334  // axis to be snapped to the grid.
335  if( action == ACTIONS::CURSOR_LEFT || action == ACTIONS::CURSOR_RIGHT )
336  m_cursor.y = prevPos.y;
337  else if( action == ACTIONS::CURSOR_UP || action == ACTIONS::CURSOR_DOWN )
338  m_cursor.x = prevPos.x;
339  }
340 
343 
344  VECTOR2I movement( m_cursor - prevPos );
345  prevPos = m_cursor;
346  totalMovement += movement;
347 
348  // Drag items to the current cursor position
349  for( EDA_ITEM* item : sel_items )
350  {
351  // Don't double move footprint pads, fields, etc.
352  if( !item->GetParent() || !item->GetParent()->IsSelected() )
353  static_cast<BOARD_ITEM*>( item )->Move( movement );
354  }
355 
356  frame()->UpdateMsgPanel();
357  }
358  else if( !m_dragging ) // Prepare to start dragging
359  {
361  {
363  break;
364  }
365 
366  // deal with locked items (override lock or abort the operation)
368 
369  if( lockFlags == SELECTION_LOCKED )
370  break;
371 
372  m_dragging = true;
373 
374  // When editing modules, all items have the same parent
375  if( EditingModules() )
376  {
377  m_commit->Modify( selection.Front() );
378  }
379  else
380  {
381  // Save items, so changes can be undone
382  for( EDA_ITEM* item : selection )
383  {
384  // Don't double move footprint pads, fields, etc.
385  if( item->GetParent() && item->GetParent()->IsSelected() )
386  continue;
387 
388  m_commit->Modify( item );
389  }
390  }
391 
392  editFrame->UndoRedoBlock( true );
394 
396  {
397  // start moving with the reference point attached to the cursor
398  grid.SetAuxAxes( false );
399 
400  auto delta = m_cursor - selection.GetReferencePoint();
401 
402  // Drag items to the current cursor position
403  for( EDA_ITEM* item : selection )
404  {
405  // Don't double move footprint pads, fields, etc.
406  if( item->GetParent() && item->GetParent()->IsSelected() )
407  continue;
408 
409  static_cast<BOARD_ITEM*>( item )->Move( delta );
410  }
411 
413  }
414  else
415  {
416  std::vector<BOARD_ITEM*> items;
417 
418  for( EDA_ITEM* item : selection )
419  items.push_back( static_cast<BOARD_ITEM*>( item ) );
420 
421  // Set the current cursor position to the first dragged item origin, so the
422  // movement vector could be computed later
423  m_cursor = grid.BestDragOrigin( originalCursorPos, items );
425  grid.SetAuxAxes( true, m_cursor );
426  }
427 
429 
430  prevPos = m_cursor;
431  controls->SetAutoPan( true );
432  }
433 
436  }
437 
438  else if( evt->IsCancelInteractive() || evt->IsActivate() )
439  {
440  restore_state = true; // Canceling the tool means that items have to be restored
441  break; // Finish
442  }
443 
444  else if( evt->IsAction( &ACTIONS::undo ) )
445  {
446  restore_state = true; // Perform undo locally
447  break; // Finish
448  }
449 
450  // Dispatch TOOL_ACTIONs
451  else if( evt->Category() == TC_COMMAND )
452  {
453  if( evt->IsAction( &ACTIONS::doDelete ) )
454  {
455  break; // finish -- there is no further processing for removed items
456  }
457  else if( evt->IsAction( &ACTIONS::duplicate ) )
458  {
459  break; // finish -- Duplicate tool will start a new Move with the dup'ed items
460  }
461  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
462  {
463  // Reset positions so the Move Exactly is from the start.
464  for( EDA_ITEM* item : selection )
465  {
466  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
467  i->Move( -totalMovement );
468  }
469 
470  break; // finish -- we moved exactly, so we are finished
471  }
472  }
473 
474  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
475  {
476  break; // finish
477  }
478 
479  else
480  {
481  evt->SetPassEvent();
482  }
483 
484  } while( ( evt = Wait() ) ); // Assignment (instead of equality test) is intentional
485 
486  m_lockedSelected = false;
487  controls->ForceCursorPosition( false );
488  controls->ShowCursor( false );
489  controls->SetSnapping( false );
490  controls->SetAutoPan( false );
491 
492  m_dragging = false;
493  editFrame->UndoRedoBlock( false );
494 
495  // Discard reference point when selection is "dropped" onto the board (ie: not dragging anymore)
497 
498  if( unselect )
500 
501  // If canceled, we need to remove the dynamic ratsnest from the screen
502  if( restore_state )
503  {
505  m_commit->Revert();
506  }
507  else
508  {
509  m_commit->Push( _( "Drag" ) );
510  }
511 
512  editFrame->PopTool( tool );
513  return 0;
514 }
515 
517 {
519  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
520  {
522  } );
523 
524  for( EDA_ITEM* item : selection )
525  {
526  if( auto via = dyn_cast<VIA*>( item ) )
527  {
528  m_commit->Modify( item );
529 
530  int new_width;
531  int new_drill;
532 
533  if( via->GetViaType() == VIATYPE::MICROVIA )
534  {
535  auto net = via->GetNet();
536 
537  new_width = net->GetMicroViaSize();
538  new_drill = net->GetMicroViaDrillSize();
539  }
540  else
541  {
542  new_width = board()->GetDesignSettings().GetCurrentViaSize();
543  new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
544  }
545 
546  via->SetDrill( new_drill );
547  via->SetWidth( new_width );
548  }
549  else if ( auto track = dyn_cast<TRACK*>( item ) )
550  {
551  m_commit->Modify( item );
552 
553  int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
554  track->SetWidth( new_width );
555  }
556  }
557 
558  m_commit->Push( _("Edit track width/via size") );
559 
560  if( selection.IsHover() )
561  {
563 
564  // Notify other tools of the changes -- This updates the visual ratsnest
566  }
567 
568  return 0;
569 }
570 
571 
572 int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
573 {
574  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
575 
577  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
578  {
580  } );
581 
582  // Tracks & vias are treated in a special way:
584  {
585  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection, *m_commit );
586  dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
587  }
588  else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
589  {
590  // Display properties dialog
591  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
592 
593  // Do not handle undo buffer, it is done by the properties dialogs
594  editFrame->OnEditItemRequest( item );
595 
596  // Notify other tools of the changes
598  }
599 
600  if( selection.IsHover() )
601  {
603 
604  // Notify other tools of the changes -- This updates the visual ratsnest
606  }
607 
608  return 0;
609 }
610 
611 
612 int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
613 {
614  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
615 
617  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
618  {
620  },
621  nullptr, ! m_dragging );
622 
623  if( selection.Empty() )
624  return 0;
625 
627  auto refPt = selection.GetReferencePoint();
628  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
629 
630  // When editing modules, all items have the same parent
631  if( EditingModules() )
632  m_commit->Modify( selection.Front() );
633 
634  for( auto item : selection )
635  {
636  if( !item->IsNew() && !EditingModules() )
637  m_commit->Modify( item );
638 
639  static_cast<BOARD_ITEM*>( item )->Rotate( refPt, rotateAngle );
640  }
641 
642  if( !m_dragging )
643  m_commit->Push( _( "Rotate" ) );
644 
645  if( selection.IsHover() && !m_dragging )
647 
649 
650  if( m_dragging )
652 
653  return 0;
654 }
655 
656 
660 static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
661 {
662  wxPoint mirrored = aPoint;
663 
664  mirrored.x -= aMirrorPoint.x;
665  mirrored.x = -mirrored.x;
666  mirrored.x += aMirrorPoint.x;
667 
668  return mirrored;
669 }
670 
671 
675 static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
676 {
677  wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
678 
679  if( aPad.GetShape() == PAD_SHAPE_CUSTOM )
680  aPad.MirrorXPrimitives( tmpPt.x );
681 
682  aPad.SetPosition( tmpPt );
683 
684  aPad.SetX0( aPad.GetPosition().x );
685 
686  tmpPt = aPad.GetOffset();
687  tmpPt.x = -tmpPt.x;
688  aPad.SetOffset( tmpPt );
689 
690  auto tmpz = aPad.GetDelta();
691  tmpz.x = -tmpz.x;
692  aPad.SetDelta( tmpz );
693 
694  aPad.SetOrientation( -aPad.GetOrientation() );
695 }
696 
697 
698 int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
699 {
701  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
702  {
704  },
705  nullptr, !m_dragging );
706 
707  if( selection.Empty() )
708  return 0;
709 
711  auto refPoint = selection.GetReferencePoint();
712  wxPoint mirrorPoint( refPoint.x, refPoint.y );
713 
714  // When editing modules, all items have the same parent
715  if( EditingModules() )
716  m_commit->Modify( selection.Front() );
717 
718  for( EDA_ITEM* item : selection )
719  {
720  // only modify items we can mirror
721  switch( item->Type() )
722  {
723  case PCB_MODULE_EDGE_T:
724  case PCB_MODULE_TEXT_T:
725  case PCB_PAD_T:
726  // Only create undo entry for items on the board
727  if( !item->IsNew() && !EditingModules() )
728  m_commit->Modify( item );
729 
730  break;
731  default:
732  continue;
733  }
734 
735  // modify each object as necessary
736  switch( item->Type() )
737  {
738  case PCB_MODULE_EDGE_T:
739  {
740  auto& edge = static_cast<EDGE_MODULE&>( *item );
741  edge.Mirror( mirrorPoint, false );
742  break;
743  }
744 
745  case PCB_MODULE_TEXT_T:
746  {
747  auto& modText = static_cast<TEXTE_MODULE&>( *item );
748  modText.Mirror( mirrorPoint, false );
749  break;
750  }
751 
752  case PCB_PAD_T:
753  {
754  auto& pad = static_cast<D_PAD&>( *item );
755  mirrorPadX( pad, mirrorPoint );
756  break;
757  }
758 
759  default:
760  // it's likely the commit object is wrong if you get here
761  assert( false );
762  break;
763  }
764  }
765 
766  if( !m_dragging )
767  m_commit->Push( _( "Mirror" ) );
768 
769  if( selection.IsHover() && !m_dragging )
771 
773 
774  if( m_dragging )
776 
777  return 0;
778 }
779 
780 
781 int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
782 {
784  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
785  {
787  },
788  nullptr, !m_dragging );
789 
790  if( selection.Empty() )
791  return 0;
792 
794 
795  // Flip around the anchor for footprints, and the bounding box center for board items
796  VECTOR2I modPoint = EditingModules() ? VECTOR2I( 0, 0 ) : selection.GetCenter();
797 
798  // If only one item selected, flip around the item anchor point, instead
799  // of the bounding box center, to avoid moving the item anchor
800  if( selection.GetSize() == 1 )
801  modPoint = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) )->GetPosition();
802 
803  bool leftRight = frame()->Settings().m_FlipLeftRight;
804 
805  // When editing modules, all items have the same parent
806  if( EditingModules() )
807  m_commit->Modify( selection.Front() );
808 
809  for( EDA_ITEM* item : selection )
810  {
811  if( !item->IsNew() && !EditingModules() )
812  m_commit->Modify( item );
813 
814  static_cast<BOARD_ITEM*>( item )->Flip( modPoint, leftRight );
815  }
816 
817  if( !m_dragging )
818  m_commit->Push( _( "Flip" ) );
819 
820  if( selection.IsHover() && !m_dragging )
822 
824 
825  if( m_dragging )
827 
828  return 0;
829 }
830 
831 
832 int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
833 {
834  ROUTER_TOOL* routerTool = m_toolMgr->GetTool<ROUTER_TOOL>();
835 
836  // Do not delete items while actively routing.
837  if( routerTool && routerTool->Router() && routerTool->Router()->RoutingInProgress() )
838  return 1;
839 
840  std::vector<BOARD_ITEM*> lockedItems;
841  Activate();
842 
843  // get a copy instead of reference (as we're going to clear the selection before removing items)
844  PCBNEW_SELECTION selectionCopy;
847 
848  // If we are in a "Cut" operation, then the copied selection exists already
849  if( isCut )
850  {
851  selectionCopy = m_selectionTool->GetSelection();
852  }
853  else
854  {
855  selectionCopy = m_selectionTool->RequestSelection(
856  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
857  {
859  } );
860  }
861 
862  bool isHover = selectionCopy.IsHover();
863 
864  // in "alternative" mode, deletion is not just a simple list of selected items,
865  // it removes whole tracks, not just segments
866  if( isAlt && isHover
867  && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
868  {
870  }
871 
872  if( selectionCopy.Empty() )
873  return 0;
874 
875  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
876  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
877  // in the copyToClipboard() routine
878  if( !m_lockedSelected && !isCut )
879  {
880  // Second RequestSelection removes locked items but keeps a copy of their pointers
881  selectionCopy = m_selectionTool->RequestSelection(
882  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
883  {
885  },
886  &lockedItems );
887  }
888 
889 
890  // As we are about to remove items, they have to be removed from the selection first
892 
893  for( EDA_ITEM* item : selectionCopy )
894  {
895  if( m_editModules )
896  {
897  m_commit->Remove( item );
898  continue;
899  }
900 
901  switch( item->Type() )
902  {
903  case PCB_MODULE_TEXT_T:
904  {
905  auto text = static_cast<TEXTE_MODULE*>( item );
906  auto parent = static_cast<MODULE*>( item->GetParent() );
907 
908  if( text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
909  {
910  m_commit->Modify( text );
911  getView()->Remove( text );
912  parent->Remove( text );
913  }
914  }
915  break;
916 
917  case PCB_PAD_T:
918  {
919  auto pad = static_cast<D_PAD*>( item );
920  auto parent = static_cast<MODULE*>( item->GetParent() );
921 
922  m_commit->Modify( parent );
923  getView()->Remove( pad );
924  parent->Remove( pad );
925  }
926  break;
927 
928  default:
929  m_commit->Remove( item );
930  break;
931  }
932  }
933 
934  if( isCut )
935  m_commit->Push( _( "Cut" ) );
936  else
937  m_commit->Push( _( "Delete" ) );
938 
939  if( !m_lockedSelected && !lockedItems.empty() )
940  {
942  STATUS_TEXT_POPUP statusPopup( frame() );
943 
944  m_lockedSelected = true;
945  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &lockedItems );
946  statusPopup.SetText( _( "Delete again to remove locked items" ) );
947  statusPopup.PopupFor( 2000 );
948  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
949 
950  Activate();
951 
952  while( m_lockedSelected && statusPopup.IsShown() )
953  {
954  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
955  Wait();
956  }
957 
958  // Ensure statusPopup is hidden after use and before deleting it:
959  statusPopup.Hide();
960  }
961 
962  m_lockedSelected = false;
963 
964  return 0;
965 }
966 
967 
968 int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
969 {
971  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
972  {
973  EditToolSelectionFilter( aCollector,
975  } );
976 
977  if( selection.Empty() )
978  return 0;
979 
980  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
981  wxPoint translation;
982  double rotation;
983  ROTATION_ANCHOR rotationAnchor = selection.Size() > 1 ? ROTATE_AROUND_SEL_CENTER
985 
986  // TODO: Implement a visible bounding border at the edge
987  auto sel_box = selection.GetBoundingBox();
988 
989  DIALOG_MOVE_EXACT dialog( editFrame, translation, rotation, rotationAnchor, sel_box );
990  int ret = dialog.ShowModal();
991 
992  if( ret == wxID_OK )
993  {
995  wxPoint selCenter( rp.x, rp.y );
996 
997  // Make sure the rotation is from the right reference point
998  selCenter += translation;
999 
1000  // When editing modules, all items have the same parent
1001  if( EditingModules() )
1002  m_commit->Modify( selection.Front() );
1003 
1004  for( EDA_ITEM* selItem : selection )
1005  {
1006  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
1007 
1008  if( !item->IsNew() && !EditingModules() )
1009  m_commit->Modify( item );
1010 
1011  item->Move( translation );
1012 
1013  switch( rotationAnchor )
1014  {
1016  item->Rotate( item->GetPosition(), rotation );
1017  break;
1019  item->Rotate( selCenter, rotation );
1020  break;
1022  item->Rotate( (wxPoint) editFrame->GetScreen()->m_LocalOrigin, rotation );
1023  break;
1025  item->Rotate( editFrame->GetAuxOrigin(), rotation );
1026  break;
1027  }
1028 
1029  if( !m_dragging )
1030  getView()->Update( item );
1031  }
1032 
1033  m_commit->Push( _( "Move exact" ) );
1034 
1035  if( selection.IsHover() )
1037 
1039 
1040  if( m_dragging )
1042  }
1043 
1044  return 0;
1045 }
1046 
1047 
1048 int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
1049 {
1050  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
1051 
1052  // Be sure that there is at least one item that we can modify
1054  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1055  {
1057  } );
1058 
1059  if( selection.Empty() )
1060  return 0;
1061 
1062  // we have a selection to work on now, so start the tool process
1063  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1064 
1065  // If the selection was given a hover, we do not keep the selection after completion
1066  bool is_hover = selection.IsHover();
1067 
1068  std::vector<BOARD_ITEM*> new_items;
1069  new_items.reserve( selection.Size() );
1070 
1071  BOARD_ITEM* orig_item = nullptr;
1072  BOARD_ITEM* dupe_item = nullptr;
1073 
1074  // Each selected item is duplicated and pushed to new_items list
1075  // Old selection is cleared, and new items are then selected.
1076  for( EDA_ITEM* item : selection )
1077  {
1078  orig_item = static_cast<BOARD_ITEM*>( item );
1079 
1080  if( m_editModules )
1081  {
1082  MODULE* editModule = editFrame->GetBoard()->GetFirstModule();
1083  dupe_item = editModule->DuplicateItem( orig_item, increment );
1084  }
1085  else if( orig_item->GetParent() && orig_item->GetParent()->Type() == PCB_MODULE_T )
1086  {
1087  MODULE* parent = static_cast<MODULE*>( orig_item->GetParent() );
1088 
1089  m_commit->Modify( parent );
1090  dupe_item = parent->DuplicateItem( orig_item, false, true /* add to parent */ );
1091  }
1092  else
1093  {
1094  switch( orig_item->Type() )
1095  {
1096  case PCB_MODULE_T:
1097  case PCB_TEXT_T:
1098  case PCB_LINE_T:
1099  case PCB_TRACE_T:
1100  case PCB_VIA_T:
1101  case PCB_ZONE_AREA_T:
1102  case PCB_TARGET_T:
1103  case PCB_DIMENSION_T:
1104  dupe_item = orig_item->Duplicate();
1105  break;
1106 
1107  default:
1108  // Silently drop other items (such as footprint texts) from duplication
1109  break;
1110  }
1111  }
1112 
1113  if( dupe_item )
1114  {
1115  // Clear the selection flag here, otherwise the SELECTION_TOOL
1116  // will not properly select it later on
1117  dupe_item->ClearSelected();
1118 
1119  new_items.push_back( dupe_item );
1120  m_commit->Add( dupe_item );
1121  }
1122  }
1123 
1124  // Clear the old selection first
1126 
1127  // Select the new items
1128  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
1129 
1130  // record the new items as added
1131  if( !selection.Empty() )
1132  {
1133  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
1134  (int) new_items.size() ) );
1135 
1136  // If items were duplicated, pick them up
1137  // this works well for "dropping" copies around and pushes the commit
1139  Move( evt );
1140 
1141  // After moving the new items, we need to refresh the group and view flags
1143 
1144  if( !is_hover )
1145  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
1146  }
1147 
1148  return 0;
1149 }
1150 
1151 
1153 {
1155  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1156  {
1158  } );
1159 
1160  if( selection.Empty() )
1161  return 0;
1162 
1163  // we have a selection to work on now, so start the tool process
1164  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
1165  ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
1166  array_creator.Invoke();
1167 
1168  return 0;
1169 }
1170 
1171 
1173 {
1174  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1175  {
1176  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1177 
1178  if( item->Type() != PCB_PAD_T )
1179  aCollector.Remove( i );
1180  }
1181 }
1182 
1183 
1185 {
1186  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1187  {
1188  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1189 
1190  if( item->Type() != PCB_MODULE_T )
1191  aCollector.Remove( i );
1192  }
1193 }
1194 
1195 
1197 {
1198  if( EditingModules() && !frame()->GetModel())
1199  return 0;
1200 
1201  auto& view = *getView();
1202  auto& controls = *getViewControls();
1203 
1204  std::string tool = aEvent.GetCommandStr().get();
1205  frame()->PushTool( tool );
1206  Activate();
1207 
1208  EDA_UNITS units = frame()->GetUserUnits();
1210  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
1211 
1212  view.Add( &ruler );
1213  view.SetVisible( &ruler, false );
1214 
1215  GRID_HELPER grid( frame() );
1216 
1217  bool originSet = false;
1218 
1219  controls.ShowCursor( true );
1220  controls.SetAutoPan( false );
1221  controls.CaptureCursor( false );
1222 
1223  while( auto evt = Wait() )
1224  {
1225  frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
1226  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1227  grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
1228  controls.SetSnapping( !evt->Modifier( MD_ALT ) );
1229  const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
1230  controls.ForceCursorPosition(true, cursorPos );
1231 
1232  auto clearRuler = [&] () {
1233  view.SetVisible( &ruler, false );
1234  controls.SetAutoPan( false );
1235  controls.CaptureCursor( false );
1236  originSet = false;
1237  };
1238 
1239  if( evt->IsCancelInteractive() )
1240  {
1241  if( originSet )
1242  clearRuler();
1243  else
1244  {
1245  frame()->PopTool( tool );
1246  break;
1247  }
1248  }
1249 
1250  else if( evt->IsActivate() )
1251  {
1252  if( originSet )
1253  clearRuler();
1254 
1255  if( evt->IsMoveTool() )
1256  {
1257  // leave ourselves on the stack so we come back after the move
1258  break;
1259  }
1260  else
1261  {
1262  frame()->PopTool( tool );
1263  break;
1264  }
1265  }
1266 
1267  // click or drag starts
1268  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
1269  {
1270  twoPtMgr.SetOrigin( cursorPos );
1271  twoPtMgr.SetEnd( cursorPos );
1272 
1273  controls.CaptureCursor( true );
1274  controls.SetAutoPan( true );
1275 
1276  originSet = true;
1277  }
1278 
1279  // second click or mouse up after drag ends
1280  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
1281  {
1282  originSet = false;
1283 
1284  controls.SetAutoPan( false );
1285  controls.CaptureCursor( false );
1286  }
1287 
1288  // move or drag when origin set updates rules
1289  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
1290  {
1291  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
1292  twoPtMgr.SetEnd( cursorPos );
1293 
1294  view.SetVisible( &ruler, true );
1295  view.Update( &ruler, KIGFX::GEOMETRY );
1296  }
1297 
1298  else if( evt->IsAction( &ACTIONS::toggleUnits )
1299  || evt->IsAction( &PCB_ACTIONS::updateUnits ) )
1300  {
1301  if( frame()->GetUserUnits() != units )
1302  {
1303  units = frame()->GetUserUnits();
1304  ruler.SwitchUnits();
1305  view.Update( &ruler, KIGFX::GEOMETRY );
1306  }
1307  }
1308 
1309  else if( evt->IsClick( BUT_RIGHT ) )
1310  {
1312  }
1313 
1314  else
1315  evt->SetPassEvent();
1316  }
1317 
1318  view.SetVisible( &ruler, false );
1319  view.Remove( &ruler );
1320  return 0;
1321 }
1322 
1323 
1325 {
1326  if( m_dragging && aSelection.HasReferencePoint() )
1327  return false;
1328 
1329  // When there is only one item selected, the reference point is its position...
1330  if( aSelection.Size() == 1 )
1331  {
1332  auto item = static_cast<BOARD_ITEM*>( aSelection.Front() );
1333  auto pos = item->GetPosition();
1334  aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
1335  }
1336  // ...otherwise modify items with regard to the grid-snapped cursor position
1337  else
1338  {
1340  aSelection.SetReferencePoint( m_cursor );
1341  }
1342 
1343  return true;
1344 }
1345 
1346 
1348 {
1350 
1351  if( selection.Empty() )
1352  return 0;
1353 
1354  MODULE* mod = selection.FirstOfKind<MODULE>();
1355 
1356  if( !mod )
1357  return 0;
1358 
1359  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1360 
1361  auto editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_FOOTPRINT_EDITOR, true );
1362 
1363  editor->Load_Module_From_BOARD( mod );
1364 
1365  editor->Show( true );
1366  editor->Raise(); // Iconize( false );
1367 
1368  if( selection.IsHover() )
1370 
1371  return 0;
1372 }
1373 
1374 
1376 {
1377  std::string tool = "pcbnew.InteractiveEdit.selectReferencePoint";
1378  STATUS_TEXT_POPUP statusPopup( frame() );
1380  OPT<VECTOR2I> pickedPoint;
1381  bool done = false;
1382 
1383  statusPopup.SetText( _( "Select reference point for the copy..." ) );
1384 
1385  picker->SetClickHandler(
1386  [&]( const VECTOR2D& aPoint ) -> bool
1387  {
1388  pickedPoint = aPoint;
1389  statusPopup.SetText( _( "Selection copied." ) );
1390  statusPopup.Expire( 800 );
1391  return false; // we don't need any more points
1392  } );
1393 
1394  picker->SetMotionHandler(
1395  [&] ( const VECTOR2D& aPos )
1396  {
1397  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
1398  } );
1399 
1400  picker->SetCancelHandler(
1401  [&]()
1402  {
1403  statusPopup.SetText( _( "Copy cancelled." ) );
1404  statusPopup.Expire( 800 );
1405  } );
1406 
1407  picker->SetFinalizeHandler(
1408  [&]( const int& aFinalState )
1409  {
1410  done = true;
1411  } );
1412 
1413  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
1414  statusPopup.Popup();
1415 
1416  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
1417 
1418  while( !done )
1419  Wait();
1420 
1421  // Ensure statusPopup is hidden after use and before deleting it:
1422  statusPopup.Hide();
1423 
1424  if( pickedPoint.is_initialized() )
1425  aReferencePoint = pickedPoint.get();
1426 
1427  return pickedPoint.is_initialized();
1428 }
1429 
1430 
1432 {
1433  CLIPBOARD_IO io;
1434 
1435  Activate();
1436 
1438  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1439  {
1441  } );
1442 
1443  if( selection.Empty() )
1444  return 1;
1445 
1446  VECTOR2I refPoint;
1447  bool rv = pickCopyReferencePoint( refPoint );
1448  frame()->SetMsgPanel( board() );
1449 
1450  if( !rv )
1451  return 1;
1452 
1453  selection.SetReferencePoint( refPoint );
1454 
1455  io.SetBoard( board() );
1456  io.SaveSelection( selection );
1457 
1458  return 0;
1459 }
1460 
1461 
1463 {
1464  if( !copyToClipboard( aEvent ) )
1465  {
1466  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
1467  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
1468  // in the copyToClipboard() routine
1469  TOOL_EVENT evt( aEvent.Category(), aEvent.Action(), TOOL_ACTION_SCOPE::AS_GLOBAL );
1471  Remove( evt );
1472  }
1473 
1474  return 0;
1475 }
1476 
1477 
1479 {
1481  Go( &EDIT_TOOL::Move, PCB_ACTIONS::move.MakeEvent() );
1482  Go( &EDIT_TOOL::Move, PCB_ACTIONS::drag.MakeEvent() );
1483  Go( &EDIT_TOOL::Drag, PCB_ACTIONS::drag45Degree.MakeEvent() );
1485  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
1486  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCcw.MakeEvent() );
1487  Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
1488  Go( &EDIT_TOOL::Remove, ACTIONS::doDelete.MakeEvent() );
1489  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::deleteFull.MakeEvent() );
1492  Go( &EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() );
1495  Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
1497 
1500 
1501  Go( &EDIT_TOOL::copyToClipboard, ACTIONS::copy.MakeEvent() );
1502  Go( &EDIT_TOOL::cutToClipboard, ACTIONS::cut.MakeEvent() );
1503 }
1504 
1505 
static TOOL_ACTION selectItems
Selects a list of items (specified as the event parameter)
Definition: pcb_actions.h:80
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:73
VECTOR2I GetReferencePoint() const
Definition: selection.h:239
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
EDA_UNITS
Definition: common.h:184
void setTransitions() override
Sets up handlers for various events.
Definition: edit_tool.cpp:1478
VECTOR2I m_cursor
Definition: edit_tool.h:193
void ClearReferencePoint()
Definition: selection.h:249
void AddStandardSubMenus(TOOL_MENU &aMenu)
Function CreateBasicMenu.
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
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:572
int Rotate(const TOOL_EVENT &aEvent)
Function Rotate() Rotates currently selected items.
Definition: edit_tool.cpp:612
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:103
static TOOL_ACTION deleteFull
Definition: pcb_actions.h:133
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_holder.h:56
bool IsHover() const
Definition: selection.h:70
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
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
REMOVE_FLAGS
Remove event modifier flags
Definition: actions.h:189
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
static TOOL_ACTION changeTrackWidth
Updates selected tracks & vias to the current track & via dimensions.
Definition: pcb_actions.h:117
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags) override
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: pcb_view.cpp:91
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:213
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:195
void ClearSelected()
Definition: base_struct.h:235
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.
bool IsClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:178
SELECTION_TOOL.
int ChangeTrackWidth(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:516
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:137
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:144
Tool is invoked after being inactive.
Definition: tool_base.h:80
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:218
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
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:120
PADS & Pads()
Definition: class_module.h:173
TOOL_MENU & GetToolMenu()
bool IsMotion() const
Definition: tool_event.h:306
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:139
static TOOL_ACTION selectConnection
Selects tracks between junctions or expands an existing selection to pads or the entire connection.
Definition: pcb_actions.h:88
static TOOL_ACTION getAndPlace
Find an item and start moving.
Definition: pcb_actions.h:428
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:240
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:143
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:114
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:307
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
static TOOL_ACTION updateFootprint
Definition: pcb_actions.h:305
VECTOR2I BestSnapAnchor(const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem)
static TOOL_ACTION updateUnits
Definition: pcb_actions.h:407
void UndoRedoBlock(bool aBlock=true)
Function UndoRedoBlock Enables/disable undo and redo operations.
TOOL_BASE * FindTool(int aId) const
Function FindTool() Searches for a tool with given ID.
SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
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
virtual void Remove(VIEW_ITEM *aItem) override
Function Remove() Removes a VIEW_ITEM from the view.
Definition: pcb_view.cpp:74
const wxPoint & GetAuxOrigin() const override
Return the origin of the axis used for plotting and various exports.
static const TOOL_EVENT SelectedItemsModified
Definition: actions.h:205
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:698
const VC_SETTINGS & GetSettings() const
Returns the current VIEW_CONTROLS settings
bool IsNew() const
Definition: base_struct.h:220
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:123
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:1462
PCBNEW_SELECTION & GetSelection()
Function GetSelection()
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
int EditFpInFpEditor(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:1347
bool m_lockedSelected
Definition: edit_tool.h:192
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
static TOOL_ACTION measureTool
Definition: actions.h:147
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:781
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:244
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:129
bool isInteractiveDragEnabled() const
Definition: edit_tool.cpp:228
void SetAuxAxes(bool aEnable, const VECTOR2I &aOrigin=VECTOR2I(0, 0))
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:296
int GetAndPlace(const TOOL_EVENT &aEvent)
Find an item and start moving.
Definition: edit_tool.cpp:189
Generic tool for picking a point.
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:107
VECTOR2I BestDragOrigin(const VECTOR2I &aMousePos, std::vector< BOARD_ITEM * > &aItem)
LSET is a set of PCB_LAYER_IDs.
const PCBNEW_SELECTION & selection() const
#define NULL
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:341
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
bool m_dragging
Definition: edit_tool.h:191
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 CaptureCursor(bool aEnabled)
Function CaptureCursor() Forces the cursor to stay within the drawing panel area.
int ShowQuasiModal()
SELECTION_LOCK_FLAGS
Definition: selection.h:278
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
const wxPoint & GetOffset() const
Definition: class_pad.h:309
TOOL_EVENT.
Definition: tool_event.h:171
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:368
void SetOrigin(const VECTOR2I &aOrigin)
Set the origin of the ruler (the fixed end)
static TOOL_ACTION cut
Definition: actions.h:69
KIGFX::PCB_VIEW * view() const
MODULE * GetFirstModule() const
Gets the first module in the list (used in footprint viewer/editor) or NULL if none.
Definition: class_board.h:283
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:119
void SetPassEvent()
Definition: tool_event.h:256
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:236
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle)
Function Rotate Rotate this object.
virtual void Move(const wxPoint &aWhere)
const wxSize & GetDelta() const
Definition: class_pad.h:303
All active tools
Definition: tool_event.h:147
bool IsMouseUp(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:301
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:104
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.
bool IsCancelInteractive()
Function IsCancelInteractive()
Definition: tool_event.cpp:190
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:301
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:200
static TOOL_ACTION hideDynamicRatsnest
Definition: pcb_actions.h:421
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.
int Move(const TOOL_EVENT &aEvent)
Function Move() Main loop in which events are handled.
Definition: edit_tool.cpp:248
#define EXCLUDE_TRANSIENTS
Definition: edit_tool.h:55
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:120
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:141
virtual const wxPoint GetPosition() const =0
static TOOL_ACTION drag
Definition: pcb_actions.h:104
void SetSnap(bool aSnap)
Definition: grid_helper.h:84
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: edit_tool.cpp:110
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:99
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:108
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:1172
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
int Modifier(int aMask=MD_MODIFIER_MASK) const
Returns information about key modifiers state (Ctrl, Alt, etc.)
Definition: tool_event.h:342
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:968
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:832
static ROUTER * theRouter
Definition: pns_router.cpp:63
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:111
int GetCurrentViaSize() const
Function GetCurrentViaSize.
void SaveSelection(const PCBNEW_SELECTION &selected)
bool IsActivate() const
Definition: tool_event.h:321
virtual bool IsLocked() const
Function IsLocked.
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:207
bool HasReferencePoint() const
Definition: selection.h:234
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
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:1152
PCBNEW_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, std::vector< BOARD_ITEM * > *aFiltered=nullptr, bool aConfirmLockedItems=false)
Function RequestSelection()
KIGFX::VIEW_CONTROLS * controls() const
bool ToolStackIsEmpty()
Common, abstract interface for edit frames.
int MeasureTool(const TOOL_EVENT &aEvent)
Launches a tool to measure between points
Definition: edit_tool.cpp:1196
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
static TOOL_ACTION editFootprintInFpEditor
Definition: pcb_actions.h:326
#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:426
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
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:76
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:126
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:166
static wxPoint mirrorPointX(const wxPoint &aPoint, const wxPoint &aMirrorPoint)
Definition: edit_tool.cpp:660
void SetMotionHandler(MOTION_HANDLER aHandler)
Function SetMotionHandler() Sets a handler for mouse motion.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
static TOOL_ACTION positionRelative
Activation of the position relative tool.
Definition: pcb_actions.h:221
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:78
boost::optional< T > OPT
Definition: optional.h:7
T * FirstOfKind() const
Definition: selection.h:194
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:438
virtual void PopTool(const std::string &actionName)
bool PadsLocked() const
Definition: class_module.h:337
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1486
void Activate()
Function Activate() Runs the tool.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Function Add() Adds a VIEW_ITEM to the view.
Definition: pcb_view.cpp:58
static TOOL_ACTION undo
Definition: actions.h:67
BOARD_ITEM * DuplicateItem(const BOARD_ITEM *aItem, bool aIncrementPadNumbers, bool aAddToModule=false)
Function DuplicateItem Duplicate a given item within the module, without adding to the board.
void SetUseGrid(bool aGrid=true)
Definition: grid_helper.h:94
void SetX0(int x)
Definition: class_pad.h:297
#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:1431
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:237
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:422
Module description (excepted pads)
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:1184
BOARD * GetBoard() const
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
bool RoutingInProgress() const
Definition: pns_router.cpp:117
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms)
Definition: ifsg_api.cpp:471
ROUTER * Router() const
const wxPoint GetPosition() const override
Definition: class_pad.h:241
#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
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:308
bool updateModificationPoint(PCBNEW_SELECTION &aSelection)
Returns the right modification point (e.g.
Definition: edit_tool.cpp:1324
void EditToolSelectionFilter(GENERAL_COLLECTOR &aCollector, int aFlags)
Definition: edit_tool.cpp:60
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:267
int Duplicate(const TOOL_EVENT &aEvent)
Function Duplicate() Duplicates the current selection and starts a move action.
Definition: edit_tool.cpp:1048
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()
static TOOL_ACTION toggleUnits
Definition: actions.h:141
EDA_RECT GetBoundingBox() const
Definition: selection.h:155
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
const wxPoint GetPosition() const override
Definition: class_module.h:210
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:675
void MirrorXPrimitives(int aX)
Mirror the primitives about a coordinate.
Definition: class_pad.cpp:506
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
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
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:302
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:183
bool pickCopyReferencePoint(VECTOR2I &aReferencePoint)
Definition: edit_tool.cpp:1375
VECTOR2D m_LocalOrigin
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:114
BOARD_ITEM * Duplicate() const
Function Duplicate creates a copy of a BOARD_ITEM.
void DisplayToolMsg(const wxString &msg) override
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
Color has changed.
Definition: view_item.h:57
virtual void UpdateMsgPanel()
Redraw the message panel.
void SetClickHandler(CLICK_HANDLER aHandler)
Function SetClickHandler() Sets a handler for mouse click event.