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-2019 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 <class_zone.h>
32 #include <collectors.h>
33 #include <pcb_edit_frame.h>
34 #include <kiway.h>
35 #include <footprint_edit_frame.h>
36 #include <array_creator.h>
37 #include <pcbnew_id.h>
38 #include <status_popup.h>
39 #include <tool/tool_manager.h>
40 #include <view/view_controls.h>
42 #include <confirm.h>
43 #include <bitmaps.h>
44 #include <cassert>
45 #include <functional>
46 using namespace std::placeholders;
47 #include "pcb_actions.h"
48 #include "selection_tool.h"
49 #include "edit_tool.h"
50 #include "pcbnew_picker_tool.h"
51 #include "grid_helper.h"
52 #include "kicad_clipboard.h"
53 #include <router/router_tool.h>
56 #include <tools/tool_event_utils.h>
58 #include <board_commit.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_PAD_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  else if( ( aFlags & EXCLUDE_LOCKED_PADS ) && mod && mod->PadsLocked() )
82  {
83  // Pad locking is considerably "softer" than item locking
84  aCollector.Remove( item );
85 
86  if( !mod->IsLocked() && !aCollector.HasItem( mod ) )
87  aCollector.Append( mod );
88  }
89 
90  // case 2: selection contains both the module and its pads - remove the pads
91  if( mod && aCollector.HasItem( mod ) )
92  aCollector.Remove( item );
93  }
94  else if( ( aFlags & EXCLUDE_TRANSIENTS ) && item->Type() == PCB_MARKER_T )
95  {
96  aCollector.Remove( item );
97  }
98  }
99 }
100 
101 
103  PCB_TOOL_BASE( "pcbnew.InteractiveEdit" ),
104  m_selectionTool( NULL ),
105  m_dragging( false ),
106  m_lockedSelected( false )
107 {
108 }
109 
110 
112 {
113  m_dragging = false;
114 
115  if( aReason != RUN )
116  m_commit.reset( new BOARD_COMMIT( this ) );
117 }
118 
119 
121 {
122  // Find the selection tool, so they can cooperate
123  m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
124  wxASSERT_MSG( m_selectionTool, "pcbnew.InteractiveSelection tool is not available" );
125 
126  auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
127  return m_editModules;
128  };
129 
130  auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
132 
133  auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) {
134  return frame()->ToolStackIsEmpty();
135  };
136 
137  // Add context menu entries that are displayed when selection tool is active
139 
151 
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  // Mirror only available in modedit
165  menu.AddSeparator();
166  menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
169 
170  // Footprint actions
171  menu.AddSeparator();
172  menu.AddItem( PCB_ACTIONS::editFootprintInFpEditor, singleModuleCondition );
173  menu.AddItem( PCB_ACTIONS::updateFootprint, singleModuleCondition );
174  menu.AddItem( PCB_ACTIONS::changeFootprint, singleModuleCondition );
175 
176  // Populate the context menu displayed during the edit tool (primarily the measure tool)
177  auto activeToolCondition = [ this ] ( const SELECTION& aSel ) {
178  return frame()->ToolStackIsEmpty();
179  };
180 
181  auto frame = getEditFrame<PCB_BASE_FRAME>();
182  auto& ctxMenu = m_menu.GetMenu();
183 
184  // "Cancel" goes at the top of the context menu when a tool is active
185  ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
186  ctxMenu.AddSeparator( 1 );
187 
188  if( frame )
190 
191  return true;
192 }
193 
194 
195 bool EDIT_TOOL::invokeInlineRouter( int aDragMode )
196 {
197  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
198 
199  if( !theRouter )
200  return false;
201 
202  // make sure we don't accidentally invoke inline routing mode while the router is already active!
203  if( theRouter->IsToolActive() )
204  return false;
205 
206  if( theRouter->CanInlineDrag() )
207  {
209  return true;
210  }
211 
212  return false;
213 }
214 
215 
217 {
218  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
219 
220  return theRouter ? theRouter->Router()->Settings().InlineDragEnabled() : false;
221 }
222 
223 
224 int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
225 {
226  int mode = PNS::DM_ANY;
227 
228  if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
229  mode |= PNS::DM_FREE_ANGLE;
230 
231  invokeInlineRouter( mode );
232 
233  return 0;
234 }
235 
236 int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
237 {
239  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
240  VECTOR2I originalCursorPos = controls->GetCursorPosition();
241 
242  // Be sure that there is at least one item that we can modify. If nothing was selected before,
243  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
245  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
246  {
248  } );
249 
250  if( m_dragging || selection.Empty() )
251  return 0;
252 
253  LSET item_layers = static_cast<BOARD_ITEM*>( selection.Front() )->GetLayerSet();
254  bool unselect = selection.IsHover(); //N.B. This must be saved before the re-selection below
255 
256  // Filter out locked pads here
257  // We cannot do this in the selection filter as we need the pad layers
258  // when it is the curr_item.
260  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
261  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS ); } );
262 
263  if( selection.Empty() )
264  return 0;
265 
266  std::string tool = aEvent.GetCommandStr().get();
267  editFrame->PushTool( tool );
268  Activate();
269  controls->ShowCursor( true );
270  controls->SetAutoPan( true );
271 
272  auto curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
273  std::vector<BOARD_ITEM*> sel_items;
274 
275  for( EDA_ITEM* item : selection )
276  {
277  BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
278  MODULE* module = dynamic_cast<MODULE*>( item );
279 
280  if( boardItem )
281  sel_items.push_back( boardItem );
282 
283  if( module )
284  {
285  for( D_PAD* pad : module->Pads() )
286  sel_items.push_back( pad );
287  }
288  }
289 
290  bool restore_state = false;
291  VECTOR2I totalMovement;
292  GRID_HELPER grid( editFrame );
293  TOOL_EVENT* evt = const_cast<TOOL_EVENT*>( &aEvent );
294  VECTOR2I prevPos;
295 
296  // Prime the pump
298 
299  // Main loop: keep receiving events
300  do
301  {
302  editFrame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
303  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
304  grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
305  controls->SetSnapping( !evt->Modifier( MD_ALT ) );
306 
307  if( evt->IsAction( &PCB_ACTIONS::editActivate ) ||
308  evt->IsAction( &PCB_ACTIONS::move ) ||
309  evt->IsMotion() ||
310  evt->IsDrag( BUT_LEFT ) ||
312  {
313  if( m_dragging && evt->Category() == TC_MOUSE )
314  {
315  m_cursor = grid.BestSnapAnchor( controls->GetMousePosition(), item_layers,
316  sel_items );
318  VECTOR2I movement( m_cursor - prevPos );
320 
321  totalMovement += movement;
322  prevPos = m_cursor;
323 
324  // Drag items to the current cursor position
325  for( EDA_ITEM* item : selection )
326  {
327  // Don't double move footprint pads, fields, etc.
328  if( item->GetParent() && item->GetParent()->IsSelected() )
329  continue;
330 
331  static_cast<BOARD_ITEM*>( item )->Move( movement );
332  getView()->Update( item );
333  }
334 
335  frame()->UpdateMsgPanel();
336  }
337  else if( !m_dragging ) // Prepare to start dragging
338  {
340  {
342  break;
343  }
344 
345  // deal with locked items (override lock or abort the operation)
347 
348  if( lockFlags == SELECTION_LOCKED )
349  break;
350 
351  m_dragging = true;
352 
353  // When editing modules, all items have the same parent
354  if( EditingModules() )
355  {
356  m_commit->Modify( selection.Front() );
357  }
358  else
359  {
360  // Save items, so changes can be undone
361  for( auto item : selection )
362  {
363  // Don't double move footprint pads, fields, etc.
364  if( item->GetParent() && item->GetParent()->IsSelected() )
365  continue;
366 
367  m_commit->Modify( item );
368  }
369  }
370 
371  editFrame->UndoRedoBlock( true );
373 
375  {
376  // start moving with the reference point attached to the cursor
377  grid.SetAuxAxes( false );
378 
379  auto delta = m_cursor - selection.GetReferencePoint();
380 
381  // Drag items to the current cursor position
382  for( auto item : selection )
383  {
384  // Don't double move footprint pads, fields, etc.
385  if( item->GetParent() && item->GetParent()->IsSelected() )
386  continue;
387 
388  static_cast<BOARD_ITEM*>( item )->Move( delta );
389  getView()->Update( item );
390  }
391 
393  }
394  else if( selection.Size() == 1 )
395  {
396  // Set the current cursor position to the first dragged item origin, so the
397  // movement vector could be computed later
399  m_cursor = grid.BestDragOrigin( originalCursorPos, curr_item );
400  grid.SetAuxAxes( true, m_cursor );
401  }
402  else
403  {
405  m_cursor = grid.Align( m_cursor );
406  }
407 
409 
410  prevPos = m_cursor;
411  controls->SetAutoPan( true );
412  }
413 
416  }
417 
418  else if( evt->IsCancelInteractive() || evt->IsActivate() )
419  {
420  restore_state = true; // Canceling the tool means that items have to be restored
421  break; // Finish
422  }
423 
424  else if( evt->Action() == TA_UNDO_REDO_PRE )
425  {
426  unselect = true;
427  break;
428  }
429 
430  // Dispatch TOOL_ACTIONs
431  else if( evt->Category() == TC_COMMAND )
432  {
433  if( evt->IsAction( &ACTIONS::doDelete ) )
434  {
435  // exit the loop, as there is no further processing for removed items
436  break;
437  }
438  else if( evt->IsAction( &ACTIONS::duplicate ) )
439  {
440  // On duplicate, stop moving this item
441  // The duplicate tool should then select the new item and start
442  // a new move procedure
443  break;
444  }
445  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
446  {
447  // Can't do this, because the selection will then contain
448  // stale pointers and it will all go horribly wrong...
449  //editFrame->RestoreCopyFromUndoList( dummy );
450  //
451  // So, instead, reset the position manually
452  for( auto item : selection )
453  {
454  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
455  auto delta = VECTOR2I( i->GetPosition() ) - totalMovement;
456  i->SetPosition( wxPoint( delta.x, delta.y ) );
457 
458  // And what about flipping and rotation?
459  // for now, they won't be undone, but maybe that is how
460  // it should be, so you can flip and move exact in the
461  // same action?
462  }
463 
464  // This causes a double event, so we will get the dialogue
465  // correctly, somehow - why does Rotate not?
466  //MoveExact( aEvent );
467  break; // exit the loop - we move exactly, so we have finished moving
468  }
469  }
470 
471  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
472  {
473  break; // Finish
474  }
475 
476  } while( ( evt = Wait() ) ); //Should be assignment not equality test
477 
478  m_lockedSelected = false;
479  controls->ForceCursorPosition( false );
480  controls->ShowCursor( false );
481  controls->SetSnapping( false );
482  controls->SetAutoPan( false );
483 
484  m_dragging = false;
485  editFrame->UndoRedoBlock( false );
486 
487  // Discard reference point when selection is "dropped" onto the board (ie: not dragging anymore)
489 
490  if( unselect )
492 
493  // If canceled, we need to remove the dynamic ratsnest from the screen
494  if( restore_state )
495  {
497  m_commit->Revert();
498  }
499  else
500  {
501  m_commit->Push( _( "Drag" ) );
502  }
503 
504  editFrame->PopTool( tool );
505  return 0;
506 }
507 
509 {
511  {
512  auto item = static_cast<BOARD_ITEM *>( selection[0] );
513 
514  m_commit->Modify( item );
515 
516  if( auto via = dyn_cast<VIA*>( item ) )
517  {
518  int new_width, new_drill;
519 
520  if( via->GetViaType() == VIA_MICROVIA )
521  {
522  auto net = via->GetNet();
523 
524  new_width = net->GetMicroViaSize();
525  new_drill = net->GetMicroViaDrillSize();
526  }
527  else
528  {
529  new_width = board()->GetDesignSettings().GetCurrentViaSize();
530  new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
531  }
532 
533  via->SetDrill( new_drill );
534  via->SetWidth( new_width );
535  }
536  else if ( auto track = dyn_cast<TRACK*>( item ) )
537  {
538  int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
539  track->SetWidth( new_width );
540  }
541 
542  m_commit->Push( _("Edit track width/via size") );
543  return true;
544  }
545 
546  return false;
547 }
548 
549 int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
550 {
551  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
552 
554  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
555  { EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
556 
557  // Tracks & vias are treated in a special way:
559  {
561  {
562  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection, *m_commit );
563  dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
564  }
565  }
566  else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
567  {
568  // Display properties dialog
569  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
570 
571  // Do not handle undo buffer, it is done by the properties dialogs
572  editFrame->OnEditItemRequest( item );
573 
574  // Notify other tools of the changes
576  }
577 
578  if( selection.IsHover() )
579  {
581 
582  // Notify other tools of the changes -- This updates the visual ratsnest
584  }
585 
586  return 0;
587 }
588 
589 
590 int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
591 {
592  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
593 
595  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
596  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); }, nullptr, ! m_dragging );
597 
598  if( selection.Empty() )
599  return 0;
600 
602  auto refPt = selection.GetReferencePoint();
603  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
604 
605  // When editing modules, all items have the same parent
606  if( EditingModules() )
607  m_commit->Modify( selection.Front() );
608 
609  for( auto item : selection )
610  {
611  if( !item->IsNew() && !EditingModules() )
612  m_commit->Modify( item );
613 
614  static_cast<BOARD_ITEM*>( item )->Rotate( refPt, rotateAngle );
615  }
616 
617  if( !m_dragging )
618  m_commit->Push( _( "Rotate" ) );
619 
620  if( selection.IsHover() && !m_dragging )
622 
624 
625  if( m_dragging )
627 
628  return 0;
629 }
630 
631 
635 static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
636 {
637  wxPoint mirrored = aPoint;
638 
639  mirrored.x -= aMirrorPoint.x;
640  mirrored.x = -mirrored.x;
641  mirrored.x += aMirrorPoint.x;
642 
643  return mirrored;
644 }
645 
646 
650 static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
651 {
652  wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
653 
654  if( aPad.GetShape() == PAD_SHAPE_CUSTOM )
655  aPad.MirrorXPrimitives( tmpPt.x );
656 
657  aPad.SetPosition( tmpPt );
658 
659  aPad.SetX0( aPad.GetPosition().x );
660 
661  tmpPt = aPad.GetOffset();
662  tmpPt.x = -tmpPt.x;
663  aPad.SetOffset( tmpPt );
664 
665  auto tmpz = aPad.GetDelta();
666  tmpz.x = -tmpz.x;
667  aPad.SetDelta( tmpz );
668 
669  aPad.SetOrientation( -aPad.GetOrientation() );
670 }
671 
672 
673 int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
674 {
676  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
677  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); }, nullptr, ! m_dragging );
678 
679  if( selection.Empty() )
680  return 0;
681 
683  auto refPoint = selection.GetReferencePoint();
684  wxPoint mirrorPoint( refPoint.x, refPoint.y );
685 
686  // When editing modules, all items have the same parent
687  if( EditingModules() )
688  m_commit->Modify( selection.Front() );
689 
690  for( EDA_ITEM* item : selection )
691  {
692  // only modify items we can mirror
693  switch( item->Type() )
694  {
695  case PCB_MODULE_EDGE_T:
696  case PCB_MODULE_TEXT_T:
697  case PCB_PAD_T:
698  // Only create undo entry for items on the board
699  if( !item->IsNew() && !EditingModules() )
700  m_commit->Modify( item );
701 
702  break;
703  default:
704  continue;
705  }
706 
707  // modify each object as necessary
708  switch( item->Type() )
709  {
710  case PCB_MODULE_EDGE_T:
711  {
712  auto& edge = static_cast<EDGE_MODULE&>( *item );
713  edge.Mirror( mirrorPoint, false );
714  break;
715  }
716 
717  case PCB_MODULE_TEXT_T:
718  {
719  auto& modText = static_cast<TEXTE_MODULE&>( *item );
720  modText.Mirror( mirrorPoint, false );
721  break;
722  }
723 
724  case PCB_PAD_T:
725  {
726  auto& pad = static_cast<D_PAD&>( *item );
727  mirrorPadX( pad, mirrorPoint );
728  break;
729  }
730 
731  default:
732  // it's likely the commit object is wrong if you get here
733  assert( false );
734  break;
735  }
736  }
737 
738  if( !m_dragging )
739  m_commit->Push( _( "Mirror" ) );
740 
741  if( selection.IsHover() && !m_dragging )
743 
745 
746  if( m_dragging )
748 
749  return 0;
750 }
751 
752 
753 int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
754 {
756  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
757  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); }, nullptr, ! m_dragging );
758 
759  if( selection.Empty() )
760  return 0;
761 
763  VECTOR2I modPoint = selection.GetReferencePoint();
764  bool leftRight = frame()->Settings().m_FlipLeftRight;
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  if( !item->IsNew() && !EditingModules() )
773  m_commit->Modify( item );
774 
775  static_cast<BOARD_ITEM*>( item )->Flip( modPoint, leftRight );
776  }
777 
778  if( !m_dragging )
779  m_commit->Push( _( "Flip" ) );
780 
781  if( selection.IsHover() && !m_dragging )
783 
785 
786  if( m_dragging )
788 
789  return 0;
790 }
791 
792 
793 int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
794 {
795  ROUTER_TOOL* routerTool = static_cast<ROUTER_TOOL*>
796  ( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
797 
798  // Do not delete items while actively routing.
799  if( routerTool && routerTool->Router() && routerTool->Router()->RoutingInProgress() )
800  return 1;
801 
802  std::vector<BOARD_ITEM*> lockedItems;
803 
804  // get a copy instead of reference (as we're going to clear the selection before removing items)
805  PCBNEW_SELECTION selectionCopy;
808 
809  // If we are in a "Cut" operation, then the copied selection exists already
810  if( isCut )
811  {
812  selectionCopy = m_selectionTool->GetSelection();
813  }
814  else
815  {
816  selectionCopy = m_selectionTool->RequestSelection(
817  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
819  }
820 
821  bool isHover = selectionCopy.IsHover();
822 
823  // in "alternative" mode, deletion is not just a simple list of selected items,
824  // it removes whole tracks, not just segments
825  if( isAlt && isHover
826  && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
827  {
829  }
830 
831  if( selectionCopy.Empty() )
832  return 0;
833 
834  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
835  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
836  // in the copyToClipboard() routine
837  if( !m_lockedSelected && !isCut )
838  {
839  // Second RequestSelection removes locked items but keeps a copy of their pointers
840  selectionCopy = m_selectionTool->RequestSelection(
841  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
842  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED ); }, &lockedItems );
843  }
844 
845 
846  // As we are about to remove items, they have to be removed from the selection first
848 
849  for( EDA_ITEM* item : selectionCopy )
850  {
851  if( m_editModules )
852  {
853  m_commit->Remove( item );
854  continue;
855  }
856 
857  switch( item->Type() )
858  {
859  case PCB_MODULE_TEXT_T:
860  {
861  auto text = static_cast<TEXTE_MODULE*>( item );
862  auto parent = static_cast<MODULE*>( item->GetParent() );
863 
864  if( text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
865  {
866  m_commit->Modify( text );
867  getView()->Remove( text );
868  parent->Remove( text );
869  }
870  }
871  break;
872 
873  default:
874  m_commit->Remove( item );
875  break;
876  }
877  }
878 
879  if( isCut )
880  m_commit->Push( _( "Cut" ) );
881  else
882  m_commit->Push( _( "Delete" ) );
883 
884  if( !m_lockedSelected && lockedItems.size() > 0 )
885  {
887  STATUS_TEXT_POPUP statusPopup( frame() );
888 
889  m_lockedSelected = true;
890  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &lockedItems );
891  statusPopup.SetText( _( "Delete again to remove locked items" ) );
892  statusPopup.PopupFor( 2000 );
893  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
894 
895  Activate();
896 
897  while( m_lockedSelected && statusPopup.IsShown() )
898  {
899  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
900  Wait();
901  }
902  }
903 
904  m_lockedSelected = false;
905 
906  return 0;
907 }
908 
909 
910 int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
911 {
913  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
915 
916  if( selection.Empty() )
917  return 0;
918 
919  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
920  wxPoint translation;
921  double rotation;
922  ROTATION_ANCHOR rotationAnchor = selection.Size() > 1 ? ROTATE_AROUND_SEL_CENTER
924 
925  // TODO: Implement a visible bounding border at the edge
926  auto sel_box = selection.GetBoundingBox();
927 
928  DIALOG_MOVE_EXACT dialog( editFrame, translation, rotation, rotationAnchor, sel_box );
929  int ret = dialog.ShowModal();
930 
931  if( ret == wxID_OK )
932  {
934  wxPoint selCenter( rp.x, rp.y );
935 
936  // Make sure the rotation is from the right reference point
937  selCenter += translation;
938 
939  // When editing modules, all items have the same parent
940  if( EditingModules() )
941  m_commit->Modify( selection.Front() );
942 
943  for( EDA_ITEM* selItem : selection )
944  {
945  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
946 
947  if( !item->IsNew() && !EditingModules() )
948  m_commit->Modify( item );
949 
950  item->Move( translation );
951 
952  switch( rotationAnchor )
953  {
955  item->Rotate( item->GetPosition(), rotation );
956  break;
958  item->Rotate( selCenter, rotation );
959  break;
961  item->Rotate( (wxPoint) editFrame->GetScreen()->m_LocalOrigin, rotation );
962  break;
964  item->Rotate( editFrame->GetAuxOrigin(), rotation );
965  break;
966  }
967 
968  if( !m_dragging )
969  getView()->Update( item );
970  }
971 
972  m_commit->Push( _( "Move exact" ) );
973 
974  if( selection.IsHover() )
976 
978 
979  if( m_dragging )
981  }
982 
983  return 0;
984 }
985 
986 
987 int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
988 {
989  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
990 
991  // Be sure that there is at least one item that we can modify
993  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
995 
996  if( selection.Empty() )
997  return 0;
998 
999  // we have a selection to work on now, so start the tool process
1000  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1001 
1002  std::vector<BOARD_ITEM*> new_items;
1003  new_items.reserve( selection.Size() );
1004 
1005  BOARD_ITEM* orig_item = nullptr;
1006  BOARD_ITEM* dupe_item = nullptr;
1007 
1008  // Each selected item is duplicated and pushed to new_items list
1009  // Old selection is cleared, and new items are then selected.
1010  for( EDA_ITEM* item : selection )
1011  {
1012  if( !item )
1013  continue;
1014 
1015  orig_item = static_cast<BOARD_ITEM*>( item );
1016 
1017  if( m_editModules )
1018  {
1019  dupe_item = editFrame->GetBoard()->GetFirstModule()->Duplicate( orig_item, increment );
1020  }
1021  else
1022  {
1023 #if 0
1024  // @TODO: see if we allow zone duplication here
1025  // Duplicate zones is especially tricky (overlaping zones must be merged)
1026  // so zones are not duplicated
1027  if( item->Type() != PCB_ZONE_AREA_T )
1028 #endif
1029  dupe_item = editFrame->GetBoard()->Duplicate( orig_item );
1030  }
1031 
1032  if( dupe_item )
1033  {
1034  // Clear the selection flag here, otherwise the SELECTION_TOOL
1035  // will not properly select it later on
1036  dupe_item->ClearSelected();
1037 
1038  new_items.push_back( dupe_item );
1039  m_commit->Add( dupe_item );
1040  }
1041  }
1042 
1043  // Clear the old selection first
1045 
1046  // Select the new items
1047  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
1048 
1049  // record the new items as added
1050  if( !selection.Empty() )
1051  {
1052  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
1053  (int) new_items.size() ) );
1054 
1055  // If items were duplicated, pick them up
1056  // this works well for "dropping" copies around and pushes the commit
1058  Main( evt );
1059  }
1060 
1061  return 0;
1062 }
1063 
1064 
1066 {
1068  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1070 
1071  if( selection.Empty() )
1072  return 0;
1073 
1074  // we have a selection to work on now, so start the tool process
1075  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
1076  ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
1077  array_creator.Invoke();
1078 
1079  return 0;
1080 }
1081 
1082 
1084 {
1085  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1086  {
1087  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1088 
1089  if( item->Type() != PCB_PAD_T )
1090  aCollector.Remove( i );
1091  }
1092 }
1093 
1094 
1096 {
1097  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1098  {
1099  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1100 
1101  if( item->Type() != PCB_MODULE_T )
1102  aCollector.Remove( i );
1103  }
1104 }
1105 
1106 
1108 {
1109  if( EditingModules() && !frame()->GetModel())
1110  return 0;
1111 
1112  auto& view = *getView();
1113  auto& controls = *getViewControls();
1114 
1115  std::string tool = aEvent.GetCommandStr().get();
1116  frame()->PushTool( tool );
1117  Activate();
1118 
1119  EDA_UNITS_T units = frame()->GetUserUnits();
1121  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
1122 
1123  view.Add( &ruler );
1124  view.SetVisible( &ruler, false );
1125 
1126  GRID_HELPER grid( frame() );
1127 
1128  bool originSet = false;
1129 
1130  controls.ShowCursor( true );
1131  controls.SetAutoPan( false );
1132  controls.CaptureCursor( false );
1133 
1134  while( auto evt = Wait() )
1135  {
1136  frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
1137  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1138  grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
1139  controls.SetSnapping( !evt->Modifier( MD_ALT ) );
1140  const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
1141  controls.ForceCursorPosition(true, cursorPos );
1142 
1143  auto clearRuler = [&] () {
1144  view.SetVisible( &ruler, false );
1145  controls.SetAutoPan( false );
1146  controls.CaptureCursor( false );
1147  originSet = false;
1148  };
1149 
1150  if( evt->IsCancelInteractive() )
1151  {
1152  if( originSet )
1153  clearRuler();
1154  else
1155  {
1156  frame()->PopTool( tool );
1157  break;
1158  }
1159  }
1160 
1161  else if( evt->IsActivate() )
1162  {
1163  if( originSet )
1164  clearRuler();
1165 
1166  if( evt->IsMoveTool() )
1167  {
1168  // leave ourselves on the stack so we come back after the move
1169  break;
1170  }
1171  else
1172  {
1173  frame()->PopTool( tool );
1174  break;
1175  }
1176  }
1177 
1178  // click or drag starts
1179  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
1180  {
1181  twoPtMgr.SetOrigin( cursorPos );
1182  twoPtMgr.SetEnd( cursorPos );
1183 
1184  controls.CaptureCursor( true );
1185  controls.SetAutoPan( true );
1186 
1187  originSet = true;
1188  }
1189 
1190  // second click or mouse up after drag ends
1191  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
1192  {
1193  originSet = false;
1194 
1195  controls.SetAutoPan( false );
1196  controls.CaptureCursor( false );
1197  }
1198 
1199  // move or drag when origin set updates rules
1200  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
1201  {
1202  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
1203  twoPtMgr.SetEnd( cursorPos );
1204 
1205  view.SetVisible( &ruler, true );
1206  view.Update( &ruler, KIGFX::GEOMETRY );
1207  }
1208 
1209  else if( evt->IsAction( &ACTIONS::toggleUnits )
1210  || evt->IsAction( &PCB_ACTIONS::updateUnits ) )
1211  {
1212  if( frame()->GetUserUnits() != units )
1213  {
1214  units = frame()->GetUserUnits();
1215  ruler.SwitchUnits();
1216  view.Update( &ruler, KIGFX::GEOMETRY );
1217  }
1218  }
1219 
1220  else if( evt->IsClick( BUT_RIGHT ) )
1221  {
1223  }
1224  }
1225 
1226  view.SetVisible( &ruler, false );
1227  view.Remove( &ruler );
1228  return 0;
1229 }
1230 
1231 
1233 {
1234  if( m_dragging && aSelection.HasReferencePoint() )
1235  return false;
1236 
1237  // When there is only one item selected, the reference point is its position...
1238  if( aSelection.Size() == 1 )
1239  {
1240  auto item = static_cast<BOARD_ITEM*>( aSelection.Front() );
1241  auto pos = item->GetPosition();
1242  aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
1243  }
1244  // ...otherwise modify items with regard to the grid-snapped cursor position
1245  else
1246  {
1248  aSelection.SetReferencePoint( m_cursor );
1249  }
1250 
1251  return true;
1252 }
1253 
1254 
1256 {
1258 
1259  if( selection.Empty() )
1260  return 0;
1261 
1263 
1264  if( !mod )
1265  return 0;
1266 
1267  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1268 
1269  if( mod->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
1270  {
1271  mod->SetTimeStamp( GetNewTimeStamp() );
1272  editFrame->OnModify();
1273  }
1274 
1275  auto editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
1276 
1277  editor->Load_Module_From_BOARD( mod );
1278 
1279  editor->Show( true );
1280  editor->Raise(); // Iconize( false );
1281 
1282  if( selection.IsHover() )
1284 
1285  return 0;
1286 }
1287 
1288 
1290 {
1291  std::string tool = "pcbnew.InteractiveEdit.selectReferencePoint";
1292  STATUS_TEXT_POPUP statusPopup( frame() );
1294  bool retVal = true;
1295 
1296  statusPopup.SetText( _( "Select reference point for the copy..." ) );
1297 
1298  picker->SetClickHandler(
1299  [&]( const VECTOR2D& aPoint ) -> bool
1300  {
1301  aP = aPoint;
1302  statusPopup.SetText( _( "Selection copied." ) );
1303  statusPopup.Expire( 800 );
1304  return false; // we don't need any more points
1305  } );
1306 
1307  picker->SetMotionHandler(
1308  [&] ( const VECTOR2D& aPos )
1309  {
1310  statusPopup.Move( aPos + wxPoint( 20, -50 ) );
1311  } );
1312 
1313  picker->SetCancelHandler(
1314  [&]()
1315  {
1316  statusPopup.SetText( _( "Copy cancelled." ) );
1317  statusPopup.Expire( 800 );
1318  retVal = false;
1319  } );
1320 
1321  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
1322  statusPopup.Popup();
1323 
1324  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
1325 
1326  statusPopup.Hide();
1327  return retVal;
1328 }
1329 
1330 
1332 {
1333  CLIPBOARD_IO io;
1334 
1335  Activate();
1336 
1338  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1340 
1341  if( selection.Empty() )
1342  return 1;
1343 
1344  VECTOR2I refPoint;
1345  bool rv = pickCopyReferencePoint( refPoint );
1346  frame()->SetMsgPanel( board() );
1347 
1348  if( !rv )
1349  return 1;
1350 
1351  selection.SetReferencePoint( refPoint );
1352 
1353  io.SetBoard( board() );
1354  io.SaveSelection( selection );
1355 
1356  return 0;
1357 }
1358 
1359 
1361 {
1362  if( !copyToClipboard( aEvent ) )
1363  {
1364  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
1365  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
1366  // in the copyToClipboard() routine
1367  TOOL_EVENT evt( aEvent.Category(), aEvent.Action(), TOOL_ACTION_SCOPE::AS_GLOBAL );
1369  Remove( evt );
1370  }
1371 
1372  return 0;
1373 }
1374 
1375 
1377 {
1378  Go( &EDIT_TOOL::Main, PCB_ACTIONS::editActivate.MakeEvent() );
1379  Go( &EDIT_TOOL::Main, PCB_ACTIONS::move.MakeEvent() );
1380  Go( &EDIT_TOOL::Drag, PCB_ACTIONS::drag45Degree.MakeEvent() );
1382  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
1383  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCcw.MakeEvent() );
1384  Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
1385  Go( &EDIT_TOOL::Remove, ACTIONS::doDelete.MakeEvent() );
1386  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::deleteFull.MakeEvent() );
1389  Go( &EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() );
1392  Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
1393 
1396 
1397  Go( &EDIT_TOOL::copyToClipboard, ACTIONS::copy.MakeEvent() );
1398  Go( &EDIT_TOOL::cutToClipboard, ACTIONS::cut.MakeEvent() );
1399 }
1400 
1401 
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:238
VECTOR2I BestDragOrigin(const VECTOR2I &aMousePos, BOARD_ITEM *aItem)
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:1376
VECTOR2I m_cursor
Definition: edit_tool.h:174
void ClearReferencePoint()
Definition: selection.h:248
void AddStandardSubMenus(TOOL_MENU &aMenu)
Function CreateBasicMenu.
int Main(const TOOL_EVENT &aEvent)
Function Main() Main loop in which events are handled.
Definition: edit_tool.cpp:236
TOOL_MENU m_menu
functions below are not yet implemented - their interface may change
bool ToolStackIsEmpty()
int Properties(const TOOL_EVENT &aEvent)
Function Properties() Displays properties window for the selected object.
Definition: edit_tool.cpp:549
int Rotate(const TOOL_EVENT &aEvent)
Function Rotate() Rotates currently selected items.
Definition: edit_tool.cpp:590
static TOOL_ACTION move
move an item
Definition: pcb_actions.h:112
static TOOL_ACTION deleteFull
Definition: pcb_actions.h:138
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:69
static TOOL_ACTION editActivate
Activation of the edit tool.
Definition: pcb_actions.h:109
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:313
virtual void PushTool(const std::string &actionName)
The definition of "tool" is different at the user level.
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:183
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
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:73
Class 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:212
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:189
void ClearSelected()
Definition: base_struct.h:230
VIEW_CONTROLS class definition.
TOOL_ACTIONS Action() const
Returns more specific information about the type of an event.
Definition: tool_event.h:247
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:174
SELECTION_LOCK_FLAGS CheckLock()
Checks if the user has agreed to modify locked items for the given selection.
Class 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:136
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:149
Tool is invoked after being inactive.
Definition: tool_base.h:81
static TOOL_ACTION explodePadToShapes
Definition: pcb_actions.h:365
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.
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aIncrementPadNumbers, bool aAddToModule=false)
Function Duplicate Duplicate a given item within the module, without adding to the board.
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:100
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:125
PADS & Pads()
Definition: class_module.h:163
TOOL_MENU & GetToolMenu()
bool IsMotion() const
Definition: tool_event.h:303
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:109
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:224
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:148
TOOL_EVENT_CATEGORY Category() const
Returns the category (eg. mouse/keyboard/action) of an event..
Definition: tool_event.h:244
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:122
static TOOL_ACTION changeFootprint
Definition: pcb_actions.h:310
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
static TOOL_ACTION updateFootprint
Definition: pcb_actions.h:308
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:171
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:587
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 Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:142
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:199
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
int Mirror(const TOOL_EVENT &aEvent)
Function Mirror Mirrors the current selection.
Definition: edit_tool.cpp:673
bool IsNew() const
Definition: base_struct.h:215
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:63
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:128
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:1360
PCBNEW_SELECTION & GetSelection()
Function GetSelection()
static TOOL_ACTION pickerTool
Definition: actions.h:143
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:132
PCB_BASE_EDIT_FRAME * frame() const
int EditFpInFpEditor(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:1255
bool m_lockedSelected
Definition: edit_tool.h:173
void SetParameter(T aParam)
Function SetParameter() Sets a non-standard parameter assigned to the event.
Definition: tool_event.h:445
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:113
static TOOL_ACTION measureTool
Definition: actions.h:142
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:753
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:243
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:134
timestamp_t GetNewTimeStamp()
Definition: common.cpp:217
bool isInteractiveDragEnabled() const
Definition: edit_tool.cpp:216
void SetAuxAxes(bool aEnable, const VECTOR2I &aOrigin=VECTOR2I(0, 0))
Definition: grid_helper.cpp:92
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:293
Generic tool for picking a point.
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:115
Class LSET is a set of PCB_LAYER_IDs.
const PCBNEW_SELECTION & selection() const
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:321
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:172
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.
PCB_GENERAL_SETTINGS & Settings()
int ShowQuasiModal()
SELECTION_LOCK_FLAGS
Definition: selection.h:263
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:427
const wxPoint & GetOffset() const
Definition: class_pad.h:283
Class TOOL_EVENT.
Definition: tool_event.h:168
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:371
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:285
bool HasItem(const EDA_ITEM *aItem) const
Function HasItem tests if aItem has already been collected.
Definition: collector.h:196
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Definition: edit_tool.cpp:120
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
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:224
Class RULER_ITEM.
Definition: ruler_item.h:43
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)
virtual void SetCurrentCursor(int aCursor)
Function SetCurrentCursor Set the current cursor shape for this panel.
const wxSize & GetDelta() const
Definition: class_pad.h:277
All active tools
Definition: tool_event.h:144
bool IsMouseUp(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:298
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:1539
void Expire(int aMsecs)
Hides the popup after a specified time.
bool IsCancelInteractive()
Function IsCancelInteractive()
Definition: tool_event.cpp:186
virtual void PopupFor(int aMsecs)
ROTATION_ANCHOR
#define _(s)
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:203
static TOOL_ACTION hideDynamicRatsnest
Definition: pcb_actions.h:420
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.
#define EXCLUDE_TRANSIENTS
Definition: edit_tool.h:54
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:119
static TOOL_ACTION inlineBreakTrack
Breaks track when router is not activated.
Definition: pcb_actions.h:146
virtual const wxPoint GetPosition() const =0
void SetSnap(bool aSnap)
Definition: grid_helper.h:66
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: edit_tool.cpp:111
static TOOL_ACTION expandSelectedConnection
Expands the current selection to select a connection between two junctions.
Definition: pcb_actions.h:90
bool EditingModules() const
void AddSeparator(int aOrder=ANY_ORDER)
Function AddSeparator()
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:116
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:1083
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:334
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:910
VECTOR2I Align(const VECTOR2I &aPoint) const
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:455
int Remove(const TOOL_EVENT &aEvent)
Function Remove() Deletes currently selected items.
Definition: edit_tool.cpp:793
static ROUTER * theRouter
Definition: pns_router.cpp:59
static TOOL_ACTION createPadFromShapes
Definition: pcb_actions.h:364
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:119
virtual void OnModify()
Function OnModify Virtual Must be called after a change in order to set the "modify" flag of the curr...
int GetCurrentViaSize() const
Function GetCurrentViaSize.
void SaveSelection(const PCBNEW_SELECTION &selected)
bool IsActivate() const
Definition: tool_event.h:318
virtual bool IsLocked() const
Function IsLocked.
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:195
bool HasReferencePoint() const
Definition: selection.h:233
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:97
bool pickCopyReferencePoint(VECTOR2I &aP)
Definition: edit_tool.cpp:1289
void DisplayToolMsg(const wxString &msg)
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:1065
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.
int MeasureTool(const TOOL_EVENT &aEvent)
Launches a tool to measure between points
Definition: edit_tool.cpp:1107
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
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
MODULE * module() const
static TOOL_ACTION editFootprintInFpEditor
Definition: pcb_actions.h:329
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:396
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
bool changeTrackWidthOnClick(const PCBNEW_SELECTION &selection)
Definition: edit_tool.cpp:508
size_t i
Definition: json11.cpp:597
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Function OnlyType Creates a functor that tests if the selected items are only of given type.
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:125
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:150
static wxPoint mirrorPointX(const wxPoint &aPoint, const wxPoint &aMirrorPoint)
Definition: edit_tool.cpp:635
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:224
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
T * FirstOfKind() const
Definition: selection.h:193
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:430
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1485
void Activate()
Function Activate() Runs the tool.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Function Add() Adds a VIEW_ITEM to the view.
Definition: pcb_view.cpp:58
void SetUseGrid(bool aGrid=true)
Definition: grid_helper.h:71
void SetX0(int x)
Definition: class_pad.h:271
#define EXCLUDE_LOCKED
Function EditToolSelectionFilter.
Definition: edit_tool.h:52
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:1331
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:221
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:421
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:1095
BOARD * GetBoard() const
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
bool RoutingInProgress() const
Definition: pns_router.cpp:112
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:225
virtual void PopTool(const std::string &actionName)
#define EXCLUDE_LOCKED_PADS
Definition: edit_tool.h:53
EDGE_MODULE class definition.
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:282
bool updateModificationPoint(PCBNEW_SELECTION &aSelection)
Returns the right modification point (e.g.
Definition: edit_tool.cpp:1232
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:223
int Duplicate(const TOOL_EVENT &aEvent)
Function Duplicate() Duplicates the current selection and starts a move action.
Definition: edit_tool.cpp:987
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()
static TOOL_ACTION toggleUnits
Definition: actions.h:136
EDA_RECT GetBoundingBox() const
Definition: selection.h:154
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:187
static void mirrorPadX(D_PAD &aPad, const wxPoint &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point.
Definition: edit_tool.cpp:650
void MirrorXPrimitives(int aX)
Mirror the primitives about a coordinate.
Definition: class_pad.cpp:504
#define mod(a, n)
Definition: greymap.cpp:24
static TOOL_ACTION paste
Definition: actions.h:71
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
EDA_UNITS_T
Definition: common.h:157
static TOOL_ACTION duplicate
Definition: actions.h:72
void SetText(const wxString &aText)
Display a text.
static TOOL_ACTION refreshPreview
Definition: actions.h:99
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:276
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false)=0
Moves cursor to the requested position expressed in world coordinates.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:182
VECTOR2D m_LocalOrigin
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:114
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:197
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.
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aAddToBoard=false)