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 KiCad Developers, see CHANGELOG.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 
29 #include <class_board.h>
30 #include <class_module.h>
31 #include <class_edge_mod.h>
32 #include <class_zone.h>
33 #include <collectors.h>
34 #include <pcb_edit_frame.h>
35 #include <kiway.h>
36 #include <class_draw_panel_gal.h>
37 #include <footprint_edit_frame.h>
38 #include <array_creator.h>
39 #include <pcbnew_id.h>
40 #include <status_popup.h>
41 #include <tool/tool_manager.h>
42 #include <view/view_controls.h>
43 #include <view/view.h>
46 #include <confirm.h>
47 #include <bitmaps.h>
48 #include <hotkeys.h>
49 
50 #include <cassert>
51 #include <functional>
52 using namespace std::placeholders;
53 
54 #include "pcb_actions.h"
55 #include "selection_tool.h"
56 #include "edit_tool.h"
57 #include "picker_tool.h"
58 #include "grid_helper.h"
59 #include "kicad_clipboard.h"
60 #include "pcbnew_control.h"
61 
62 #include <router/router_tool.h>
63 
67 
68 #include <tools/tool_event_utils.h>
69 
71 
72 #include <board_commit.h>
73 
74 
75 // Edit tool actions
76 TOOL_ACTION PCB_ACTIONS::editFootprintInFpEditor( "pcbnew.InteractiveEdit.editFootprintInFpEditor",
78  _( "Open in Footprint Editor" ),
79  _( "Opens the selected footprint in the Footprint Editor" ),
80  module_editor_xpm );
81 
82 TOOL_ACTION PCB_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
83  AS_GLOBAL, 0,
84  _( "Edit Activate" ), "", move_xpm, AF_ACTIVATE );
85 
86 TOOL_ACTION PCB_ACTIONS::move( "pcbnew.InteractiveEdit.move",
88  _( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE );
89 
90 TOOL_ACTION PCB_ACTIONS::duplicate( "pcbnew.InteractiveEdit.duplicate",
92  _( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_xpm );
93 
94 TOOL_ACTION PCB_ACTIONS::duplicateIncrement( "pcbnew.InteractiveEdit.duplicateIncrementPads",
96  _( "Duplicate" ), _( "Duplicates the selected item(s), incrementing pad numbers" ) );
97 
98 TOOL_ACTION PCB_ACTIONS::moveExact( "pcbnew.InteractiveEdit.moveExact",
100  _( "Move Exactly..." ), _( "Moves the selected item(s) by an exact amount" ),
101  move_exactly_xpm );
102 
103 TOOL_ACTION PCB_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray",
105  _( "Create Array..." ), _( "Create array" ), array_xpm, AF_ACTIVATE );
106 
107 TOOL_ACTION PCB_ACTIONS::rotateCw( "pcbnew.InteractiveEdit.rotateCw",
109  _( "Rotate Clockwise" ), _( "Rotates selected item(s) clockwise" ),
110  rotate_cw_xpm, AF_NONE, (void*) -1 );
111 
112 TOOL_ACTION PCB_ACTIONS::rotateCcw( "pcbnew.InteractiveEdit.rotateCcw",
114  _( "Rotate Counterclockwise" ), _( "Rotates selected item(s) counterclockwise" ),
115  rotate_ccw_xpm, AF_NONE, (void*) 1 );
116 
117 TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
119  _( "Flip" ), _( "Flips selected item(s)" ), swap_layer_xpm );
120 
121 TOOL_ACTION PCB_ACTIONS::mirror( "pcbnew.InteractiveEdit.mirror",
122  AS_GLOBAL, 0,
123  _( "Mirror" ), _( "Mirrors selected item" ), mirror_h_xpm );
124 
125 TOOL_ACTION PCB_ACTIONS::remove( "pcbnew.InteractiveEdit.remove",
127  _( "Delete" ), _( "Deletes selected item(s)" ), delete_xpm,
128  AF_NONE, (void*) REMOVE_FLAGS::NORMAL );
129 
130 TOOL_ACTION PCB_ACTIONS::removeAlt( "pcbnew.InteractiveEdit.removeAlt",
132  _( "Delete Full Track" ), _( "Deletes selected item(s) and copper connections" ),
133  delete_xpm, AF_NONE, (void*) REMOVE_FLAGS::ALT );
134 
135 TOOL_ACTION PCB_ACTIONS::updateFootprints( "pcbnew.InteractiveEdit.updateFootprints",
136  AS_GLOBAL, 0,
137  _( "Update Footprint..." ), _( "Update the footprint from the library" ),
138  reload_xpm );
139 
140 TOOL_ACTION PCB_ACTIONS::exchangeFootprints( "pcbnew.InteractiveEdit.ExchangeFootprints",
141  AS_GLOBAL, 0,
142  _( "Change Footprint..." ), _( "Assign a different footprint from the library" ),
143  exchange_xpm );
144 
145 TOOL_ACTION PCB_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
147  _( "Properties..." ), _( "Displays item properties dialog" ), config_xpm );
148 
149 TOOL_ACTION PCB_ACTIONS::selectionModified( "pcbnew.InteractiveEdit.ModifiedSelection",
150  AS_GLOBAL, 0,
151  "", "", nullptr, AF_NOTIFY );
152 
153 TOOL_ACTION PCB_ACTIONS::measureTool( "pcbnew.InteractiveEdit.measureTool",
155  _( "Measuring Tool" ), _( "Interactively measure distance between points" ),
156  nullptr, AF_ACTIVATE );
157 
158 TOOL_ACTION PCB_ACTIONS::copyToClipboard( "pcbnew.InteractiveEdit.CopyToClipboard",
159  AS_GLOBAL, 0, // do not define a hotkey and let TranslateLegacyId() handle the event
160  _( "Copy" ), _( "Copy selected content to clipboard" ),
161  copy_xpm );
162 
163 TOOL_ACTION PCB_ACTIONS::cutToClipboard( "pcbnew.InteractiveEdit.CutToClipboard",
164  AS_GLOBAL, 0, // do not define a hotkey and let TranslateLegacyId() handle the event
165  _( "Cut" ), _( "Cut selected content to clipboard" ),
166  cut_xpm );
167 
168 TOOL_ACTION PCB_ACTIONS::updateUnits( "pcbnew.InteractiveEdit.updateUnits",
169  AS_GLOBAL, 0,
170  "", "" );
171 
172 
173 void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
174 {
175  // Iterate from the back so we don't have to worry about removals.
176  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
177  {
178  BOARD_ITEM* item = aCollector[ i ];
179 
180  if( ( aFlags & EXCLUDE_LOCKED ) && item->IsLocked() )
181  {
182  aCollector.Remove( item );
183  }
184  else if( item->Type() == PCB_PAD_T )
185  {
186  MODULE* mod = static_cast<MODULE*>( item->GetParent() );
187 
188  // case 1: handle locking
189  if( ( aFlags & EXCLUDE_LOCKED ) && mod && mod->IsLocked() )
190  {
191  aCollector.Remove( item );
192  }
193  else if( ( aFlags & EXCLUDE_LOCKED_PADS ) && mod && mod->PadsLocked() )
194  {
195  // Pad locking is considerably "softer" than item locking
196  aCollector.Remove( item );
197 
198  if( !mod->IsLocked() && !aCollector.HasItem( mod ) )
199  aCollector.Append( mod );
200  }
201 
202  // case 2: selection contains both the module and its pads - remove the pads
203  if( mod && aCollector.HasItem( mod ) )
204  aCollector.Remove( item );
205  }
206  else if( ( aFlags & EXCLUDE_TRANSIENTS ) && item->Type() == PCB_MARKER_T )
207  {
208  aCollector.Remove( item );
209  }
210  }
211 }
212 
213 
215  PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
216  m_dragging( false ), m_lockedSelected( false )
217 {
218 }
219 
220 
222 {
223  m_dragging = false;
224 
225  if( aReason != RUN )
226  m_commit.reset( new BOARD_COMMIT( this ) );
227 }
228 
229 
231 {
232  // Find the selection tool, so they can cooperate
233  m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
234 
235  if( !m_selectionTool )
236  {
237  DisplayError( NULL, _( "pcbnew.InteractiveSelection tool is not available" ) );
238  return false;
239  }
240 
241  auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
242  return m_editModules;
243  };
244 
245  auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
247 
248  auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) {
249  return ( frame()->GetToolId() == ID_NO_TOOL_SELECTED );
250  };
251 
252  // Add context menu entries that are displayed when selection tool is active
254 
266 
267 
272 
273 
277  // Selection tool handles the context menu for some other tools, such as the Picker.
278  // Don't add things like Paste when another tool is active.
279  menu.AddItem( PCB_ACTIONS::pasteFromClipboard, noActiveToolCondition );
280 
281  // Mirror only available in modedit
282  menu.AddSeparator( editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
283  menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
286 
287  // Footprint actions
288  menu.AddSeparator( singleModuleCondition );
289  menu.AddItem( PCB_ACTIONS::editFootprintInFpEditor, singleModuleCondition );
290  menu.AddItem( PCB_ACTIONS::updateFootprints, singleModuleCondition );
291  menu.AddItem( PCB_ACTIONS::exchangeFootprints, singleModuleCondition );
292 
293  return true;
294 }
295 
296 
297 bool EDIT_TOOL::invokeInlineRouter( int aDragMode )
298 {
299  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
300 
301  if( !theRouter )
302  return false;
303 
304  // make sure we don't accidentally invoke inline routing mode while the router is already active!
305  if( theRouter->IsToolActive() )
306  return false;
307 
308  if( theRouter->CanInlineDrag() )
309  {
311  return true;
312  }
313 
314  return false;
315 }
316 
317 
319 {
320  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
321 
322  return theRouter ? theRouter->Router()->Settings().InlineDragEnabled() : false;
323 }
324 
325 
326 int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
327 {
328  int mode = PNS::DM_ANY;
329 
330  if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
331  mode |= PNS::DM_FREE_ANGLE;
332 
333  invokeInlineRouter( mode );
334 
335  return 0;
336 }
337 
338 int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
339 {
341  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
342  VECTOR2I originalCursorPos = controls->GetCursorPosition();
343 
344  // Be sure that there is at least one item that we can modify. If nothing was selected before,
345  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
347  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
348  { EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
349 
350  if( m_dragging || selection.Empty() )
351  return 0;
352 
353  LSET item_layers = static_cast<BOARD_ITEM*>( selection.Front() )->GetLayerSet();
354  bool unselect = selection.IsHover(); //N.B. This must be saved before the re-selection below
355 
356  // Filter out locked pads here
357  // We cannot do this in the selection filter as we need the pad layers
358  // when it is the curr_item.
360  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
361  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS ); } );
362 
363  if( selection.Empty() )
364  return 0;
365 
366  Activate();
367  controls->ShowCursor( true );
368  controls->SetAutoPan( true );
369 
370  auto curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
371  std::vector<BOARD_ITEM*> sel_items;
372 
373  for( auto it : selection )
374  {
375  if( auto item = dynamic_cast<BOARD_ITEM*>( it ) )
376  {
377  sel_items.push_back( item );
378 
379  if( auto mod = dyn_cast<MODULE*>( item ) )
380  {
381  for( auto pad : mod->Pads() )
382  sel_items.push_back( pad );
383  }
384  }
385  }
386 
387  bool restore_state = false;
388  VECTOR2I totalMovement;
389  GRID_HELPER grid( editFrame );
390  OPT_TOOL_EVENT evt = aEvent;
391  VECTOR2I prevPos;
392 
393  // Main loop: keep receiving events
394  do
395  {
396  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
397  grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
398  controls->SetSnapping( !evt->Modifier( MD_ALT ) );
399 
400  if( evt->IsAction( &PCB_ACTIONS::editActivate ) ||
401  evt->IsAction( &PCB_ACTIONS::move ) ||
402  evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
403  {
404  if( m_dragging && evt->Category() == TC_MOUSE )
405  {
407  item_layers, sel_items );
409  VECTOR2I movement( m_cursor - prevPos );
411 
412  totalMovement += movement;
413  prevPos = m_cursor;
414 
415  // Drag items to the current cursor position
416  for( auto item : selection )
417  {
418  // Don't double move footprint pads, fields, etc.
419  if( item->GetParent() && item->GetParent()->IsSelected() )
420  continue;
421 
422  static_cast<BOARD_ITEM*>( item )->Move( movement );
423  }
424 
425  frame()->UpdateMsgPanel();
426  }
427  else if( !m_dragging ) // Prepare to start dragging
428  {
429  bool invokedRouter = false;
430 
431  if ( !evt->IsAction( &PCB_ACTIONS::move ) && isInteractiveDragEnabled() )
432  invokedRouter = invokeInlineRouter( PNS::DM_ANY );
433 
434  if( !invokedRouter )
435  {
436  // deal with locked items (override lock or abort the operation)
438 
439  if( lockFlags == SELECTION_LOCKED )
440  break;
441 
442  // When editing modules, all items have the same parent
443  if( EditingModules() )
444  {
445  m_commit->Modify( selection.Front() );
446  }
447  else
448  {
449  // Save items, so changes can be undone
450  for( auto item : selection )
451  {
452  // Don't double move footprint pads, fields, etc.
453  if( item->GetParent() && item->GetParent()->IsSelected() )
454  continue;
455 
456  m_commit->Modify( item );
457  }
458  }
459 
460  editFrame->UndoRedoBlock( true );
462 
464  {
465  // start moving with the reference point attached to the cursor
466  grid.SetAuxAxes( false );
467 
469 
470  // Drag items to the current cursor position
471  for( auto item : selection )
472  {
473  // Don't double move footprint pads, fields, etc.
474  if( item->GetParent() && item->GetParent()->IsSelected() )
475  continue;
476 
477  static_cast<BOARD_ITEM*>( item )->Move( delta );
478  }
479 
481  }
482  else if( selection.Size() == 1 )
483  {
484  // Set the current cursor position to the first dragged item origin, so the
485  // movement vector could be computed later
487  m_cursor = grid.BestDragOrigin( originalCursorPos, curr_item );
488  grid.SetAuxAxes( true, m_cursor );
489  }
490  else
491  {
493  m_cursor = grid.Align( m_cursor );
494  }
495 
497 
498  prevPos = m_cursor;
499  controls->SetAutoPan( true );
500  m_dragging = true;
501  }
502  }
503 
506 
507  }
508 
509  else if( evt->IsCancel() || evt->IsActivate() )
510  {
511  restore_state = true; // Canceling the tool means that items have to be restored
512  break; // Finish
513  }
514 
515  else if( evt->Action() == TA_UNDO_REDO_PRE )
516  {
517  unselect = true;
518  break;
519  }
520 
521  // Dispatch TOOL_ACTIONs
522  else if( evt->Category() == TC_COMMAND )
523  {
524  if( evt->IsAction( &PCB_ACTIONS::remove ) )
525  {
526  // exit the loop, as there is no further processing for removed items
527  break;
528  }
529  else if( evt->IsAction( &PCB_ACTIONS::duplicate ) )
530  {
531  // On duplicate, stop moving this item
532  // The duplicate tool should then select the new item and start
533  // a new move procedure
534  break;
535  }
536  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
537  {
538  // Can't do this, because the selection will then contain
539  // stale pointers and it will all go horribly wrong...
540  //editFrame->RestoreCopyFromUndoList( dummy );
541  //
542  // So, instead, reset the position manually
543  for( auto item : selection )
544  {
545  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
546  auto delta = VECTOR2I( i->GetPosition() ) - totalMovement;
547  i->SetPosition( wxPoint( delta.x, delta.y ) );
548 
549  // And what about flipping and rotation?
550  // for now, they won't be undone, but maybe that is how
551  // it should be, so you can flip and move exact in the
552  // same action?
553  }
554 
555  // This causes a double event, so we will get the dialogue
556  // correctly, somehow - why does Rotate not?
557  //MoveExact( aEvent );
558  break; // exit the loop - we move exactly, so we have finished moving
559  }
560  }
561 
562  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
563  {
564  break; // Finish
565  }
566 
567  } while( ( evt = Wait() ) ); //Should be assignment not equality test
568 
569  m_lockedSelected = false;
570  controls->ForceCursorPosition( false );
571  controls->ShowCursor( false );
572  controls->SetSnapping( false );
573  controls->SetAutoPan( false );
574 
575  m_dragging = false;
576  editFrame->UndoRedoBlock( false );
577 
578  // Discard reference point when selection is "dropped" onto the board (ie: not dragging anymore)
580 
581  if( unselect || restore_state )
583 
584  if( restore_state )
585  m_commit->Revert();
586  else
587  m_commit->Push( _( "Drag" ) );
588 
589  return 0;
590 }
591 
593 {
595  {
596  auto item = static_cast<BOARD_ITEM *>( selection[0] );
597 
598  m_commit->Modify( item );
599 
600  if( auto via = dyn_cast<VIA*>( item ) )
601  {
602  int new_width, new_drill;
603 
604  if( via->GetViaType() == VIA_MICROVIA )
605  {
606  auto net = via->GetNet();
607 
608  new_width = net->GetMicroViaSize();
609  new_drill = net->GetMicroViaDrillSize();
610  }
611  else
612  {
613  new_width = board()->GetDesignSettings().GetCurrentViaSize();
614  new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
615  }
616 
617  via->SetDrill( new_drill );
618  via->SetWidth( new_width );
619  }
620  else if ( auto track = dyn_cast<TRACK*>( item ) )
621  {
622  int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
623  track->SetWidth( new_width );
624  }
625 
626  m_commit->Push( _("Edit track width/via size") );
627  return true;
628  }
629 
630  return false;
631 }
632 
633 int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
634 {
635  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
636 
638  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
639  { EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
640 
641  // Tracks & vias are treated in a special way:
643  {
645  {
646  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection, *m_commit );
647  dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
648  }
649  }
650  else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
651  {
652  // Display properties dialog
653  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
654 
655  // Do not handle undo buffer, it is done by the properties dialogs @todo LEGACY
656  // Display properties dialog provided by the legacy canvas frame
657  editFrame->OnEditItemRequest( NULL, item );
658 
659  // Notify other tools of the changes
661  }
662 
663  if( selection.IsHover() )
664  {
666 
667  // Notify other tools of the changes -- This updates the visual ratsnest
669  }
670 
671  return 0;
672 }
673 
674 
675 int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
676 {
677  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
678 
680  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
681  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); }, nullptr, ! m_dragging );
682 
683  if( selection.Empty() )
684  return 0;
685 
687  auto refPt = selection.GetReferencePoint();
688  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
689 
690  // When editing modules, all items have the same parent
691  if( EditingModules() )
692  {
693  m_commit->Modify( selection.Front() );
694  }
695 
696  for( auto item : selection )
697  {
698  if( !item->IsNew() && !EditingModules() )
699  m_commit->Modify( item );
700 
701  static_cast<BOARD_ITEM*>( item )->Rotate( refPt, rotateAngle );
702  }
703 
704  if( !m_dragging )
705  m_commit->Push( _( "Rotate" ) );
706 
707  if( selection.IsHover() && !m_dragging )
709 
711 
712  if( m_dragging )
714 
715  return 0;
716 }
717 
718 
722 static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
723 {
724  wxPoint mirrored = aPoint;
725 
726  mirrored.x -= aMirrorPoint.x;
727  mirrored.x = -mirrored.x;
728  mirrored.x += aMirrorPoint.x;
729 
730  return mirrored;
731 }
732 
733 
737 static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
738 {
739  wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
740 
741  if( aPad.GetShape() == PAD_SHAPE_CUSTOM )
742  aPad.MirrorXPrimitives( tmpPt.x );
743 
744  aPad.SetPosition( tmpPt );
745 
746  aPad.SetX0( aPad.GetPosition().x );
747 
748  tmpPt = aPad.GetOffset();
749  tmpPt.x = -tmpPt.x;
750  aPad.SetOffset( tmpPt );
751 
752  auto tmpz = aPad.GetDelta();
753  tmpz.x = -tmpz.x;
754  aPad.SetDelta( tmpz );
755 
756  aPad.SetOrientation( -aPad.GetOrientation() );
757 }
758 
759 
760 int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
761 {
763  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
764  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); }, nullptr, ! m_dragging );
765 
766  if( selection.Empty() )
767  return 0;
768 
770  auto refPoint = selection.GetReferencePoint();
771  wxPoint mirrorPoint( refPoint.x, refPoint.y );
772 
773  // When editing modules, all items have the same parent
774  if( EditingModules() )
775  {
776  m_commit->Modify( selection.Front() );
777  }
778 
779  for( auto item : selection )
780  {
781  // only modify items we can mirror
782  switch( item->Type() )
783  {
784  case PCB_MODULE_EDGE_T:
785  case PCB_MODULE_TEXT_T:
786  case PCB_PAD_T:
787  // Only create undo entry for items on the board
788  if( !item->IsNew() && !EditingModules() )
789  m_commit->Modify( item );
790 
791  break;
792  default:
793  continue;
794  }
795 
796  // modify each object as necessary
797  switch( item->Type() )
798  {
799  case PCB_MODULE_EDGE_T:
800  {
801  auto& edge = static_cast<EDGE_MODULE&>( *item );
802  edge.Mirror( mirrorPoint, false );
803  break;
804  }
805 
806  case PCB_MODULE_TEXT_T:
807  {
808  auto& modText = static_cast<TEXTE_MODULE&>( *item );
809  modText.Mirror( mirrorPoint, false );
810  break;
811  }
812 
813  case PCB_PAD_T:
814  {
815  auto& pad = static_cast<D_PAD&>( *item );
816  mirrorPadX( pad, mirrorPoint );
817  break;
818  }
819 
820  default:
821  // it's likely the commit object is wrong if you get here
822  assert( false );
823  break;
824  }
825  }
826 
827  if( !m_dragging )
828  m_commit->Push( _( "Mirror" ) );
829 
830  if( selection.IsHover() && !m_dragging )
832 
834 
835  if( m_dragging )
837 
838  return 0;
839 }
840 
841 
842 int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
843 {
845  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
846  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); }, nullptr, ! m_dragging );
847 
848  if( selection.Empty() )
849  return 0;
850 
852  auto modPoint = selection.GetReferencePoint();
853 
854  // When editing modules, all items have the same parent
855  if( EditingModules() )
856  {
857  m_commit->Modify( selection.Front() );
858  }
859 
860  for( auto item : selection )
861  {
862  if( !item->IsNew() && !EditingModules() )
863  m_commit->Modify( item );
864 
865  static_cast<BOARD_ITEM*>( item )->Flip( modPoint );
866  }
867 
868  if( !m_dragging )
869  m_commit->Push( _( "Flip" ) );
870 
871  if( selection.IsHover() && !m_dragging )
873 
875 
876  if( m_dragging )
878 
879  return 0;
880 }
881 
882 
883 int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
884 {
885  ROUTER_TOOL* routerTool = static_cast<ROUTER_TOOL*>
886  ( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
887 
888  // Do not delete items while actively routing.
889  if( routerTool && routerTool->Router() && routerTool->Router()->RoutingInProgress() )
890  return 1;
891 
892  std::vector<BOARD_ITEM*> lockedItems;
893 
894  // get a copy instead of reference (as we're going to clear the selection before removing items)
895  SELECTION selectionCopy;
896  bool isCut = aEvent.Parameter<intptr_t>() == static_cast<intptr_t>( PCB_ACTIONS::REMOVE_FLAGS::CUT );
897  bool isAlt = aEvent.Parameter<intptr_t>() == static_cast<intptr_t>( PCB_ACTIONS::REMOVE_FLAGS::ALT );
898 
899  // If we are in a "Cut" operation, then the copied selection exists already
900  if( isCut )
901  selectionCopy = m_selectionTool->GetSelection();
902  else
903  selectionCopy = m_selectionTool->RequestSelection(
904  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
906 
907  bool isHover = selectionCopy.IsHover();
908 
909  // in "alternative" mode, deletion is not just a simple list of selected items,
910  // it removes whole tracks, not just segments
911  if( isAlt && isHover
912  && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
913  {
915  }
916 
917  if( selectionCopy.Empty() )
918  return 0;
919 
920  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
921  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
922  // in the copyToClipboard() routine
923  if( !m_lockedSelected && !isCut )
924  {
925  // Second RequestSelection removes locked items but keeps a copy of their pointers
926  selectionCopy = m_selectionTool->RequestSelection(
927  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
928  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED ); }, &lockedItems );
929  }
930 
931 
932  // As we are about to remove items, they have to be removed from the selection first
934 
935  for( auto item : selectionCopy )
936  {
937  if( m_editModules )
938  {
939  m_commit->Remove( item );
940  continue;
941  }
942 
943  switch( item->Type() )
944  {
945  case PCB_MODULE_TEXT_T:
946  {
947  auto text = static_cast<TEXTE_MODULE*>( item );
948  auto parent = static_cast<MODULE*>( item->GetParent() );
949 
950  if( text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
951  {
952  m_commit->Modify( text );
953  getView()->Remove( text );
954  parent->Remove( text );
955  }
956  }
957  break;
958 
959  default:
960  m_commit->Remove( item );
961  break;
962  }
963  }
964 
965  if( isCut )
966  m_commit->Push( _( "Cut" ) );
967  else
968  m_commit->Push( _( "Delete" ) );
969 
970  if( !m_lockedSelected && lockedItems.size() > 0 )
971  {
973  STATUS_TEXT_POPUP statusPopup( frame() );
974 
975  m_lockedSelected = true;
976  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &lockedItems );
977  statusPopup.SetText( _( "Delete again to remove locked items" ) );
978  statusPopup.Expire( 2000 );
979  statusPopup.Popup();
980  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
981 
982  Activate();
983 
984  while( m_lockedSelected && statusPopup.IsShown() )
985  {
986  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
987  Wait();
988  }
989  }
990 
991  m_lockedSelected = false;
992 
993  return 0;
994 }
995 
996 
997 int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
998 {
1000  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1002 
1003  if( selection.Empty() )
1004  return 0;
1005 
1006  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
1007  wxPoint translation;
1008  double rotation;
1009  ROTATION_ANCHOR rotationAnchor = selection.Size() > 1 ? ROTATE_AROUND_SEL_CENTER
1011 
1012  DIALOG_MOVE_EXACT dialog( editFrame, translation, rotation, rotationAnchor );
1013  int ret = dialog.ShowModal();
1014 
1015  if( ret == wxID_OK )
1016  {
1017  VECTOR2I rp = selection.GetCenter();
1018  wxPoint selCenter( rp.x, rp.y );
1019 
1020  // Make sure the rotation is from the right reference point
1021  selCenter += translation;
1022 
1023  // When editing modules, all items have the same parent
1024  if( EditingModules() )
1025  {
1026  m_commit->Modify( selection.Front() );
1027  }
1028 
1029  for( auto selItem : selection )
1030  {
1031  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
1032 
1033  if( !item->IsNew() && !EditingModules() )
1034  m_commit->Modify( item );
1035 
1036  item->Move( translation );
1037 
1038  switch( rotationAnchor )
1039  {
1041  item->Rotate( item->GetPosition(), rotation );
1042  break;
1044  item->Rotate( selCenter, rotation );
1045  break;
1047  item->Rotate( editFrame->GetScreen()->m_O_Curseur, rotation );
1048  break;
1050  item->Rotate( editFrame->GetAuxOrigin(), rotation );
1051  break;
1052  }
1053 
1054  if( !m_dragging )
1055  getView()->Update( item );
1056  }
1057 
1058  m_commit->Push( _( "Move exact" ) );
1059 
1060  if( selection.IsHover() )
1062 
1064 
1065  if( m_dragging )
1067  }
1068 
1069  return 0;
1070 }
1071 
1072 
1073 int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
1074 {
1075  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
1076 
1077  // Be sure that there is at least one item that we can modify
1079  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1081 
1082  if( selection.Empty() )
1083  return 0;
1084 
1085  // we have a selection to work on now, so start the tool process
1086  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1087 
1088  std::vector<BOARD_ITEM*> new_items;
1089  new_items.reserve( selection.Size() );
1090 
1091  BOARD_ITEM* orig_item = nullptr;
1092  BOARD_ITEM* dupe_item = nullptr;
1093 
1094  // Each selected item is duplicated and pushed to new_items list
1095  // Old selection is cleared, and new items are then selected.
1096  for( auto item : selection )
1097  {
1098  if( !item )
1099  continue;
1100 
1101  orig_item = static_cast<BOARD_ITEM*>( item );
1102 
1103  if( m_editModules )
1104  {
1105  dupe_item = editFrame->GetBoard()->m_Modules->Duplicate( orig_item, increment );
1106  }
1107  else
1108  {
1109 #if 0
1110  // @TODO: see if we allow zone duplication here
1111  // Duplicate zones is especially tricky (overlaping zones must be merged)
1112  // so zones are not duplicated
1113  if( item->Type() != PCB_ZONE_AREA_T )
1114 #endif
1115  dupe_item = editFrame->GetBoard()->Duplicate( orig_item );
1116  }
1117 
1118  if( dupe_item )
1119  {
1120  // Clear the selection flag here, otherwise the SELECTION_TOOL
1121  // will not properly select it later on
1122  dupe_item->ClearSelected();
1123 
1124  new_items.push_back( dupe_item );
1125  m_commit->Add( dupe_item );
1126  }
1127  }
1128 
1129  // Clear the old selection first
1131 
1132  // Select the new items
1133  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
1134 
1135  // record the new items as added
1136  if( !selection.Empty() )
1137  {
1138  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
1139  (int) new_items.size() ) );
1140 
1141 
1142  // If items were duplicated, pick them up
1143  // this works well for "dropping" copies around and pushes the commit
1145  Main( evt );
1146  }
1147 
1148  return 0;
1149 }
1150 
1151 
1153 {
1154 public:
1155 
1156  GAL_ARRAY_CREATOR( PCB_BASE_FRAME& editFrame, bool editModules,
1157  const SELECTION& selection ):
1158  ARRAY_CREATOR( editFrame ),
1159  m_editModules( editModules ),
1160  m_selection( selection )
1161  {}
1162 
1163 private:
1164 
1165  int getNumberOfItemsToArray() const override
1166  {
1167  // only handle single items
1168  return m_selection.Size();
1169  }
1170 
1171  BOARD_ITEM* getNthItemToArray( int n ) const override
1172  {
1173  return static_cast<BOARD_ITEM*>( m_selection[n] );
1174  }
1175 
1176  BOARD* getBoard() const override
1177  {
1178  return m_parent.GetBoard();
1179  }
1180 
1181  MODULE* getModule() const override
1182  {
1183  // Remember this is valid and used only in the module editor.
1184  // in board editor, the parent of items is usually the board.
1185  return m_editModules ? m_parent.GetBoard()->m_Modules.GetFirst() : NULL;
1186  }
1187 
1188  wxPoint getRotationCentre() const override
1189  {
1190  const VECTOR2I rp = m_selection.GetCenter();
1191  return wxPoint( rp.x, rp.y );
1192  }
1193 
1194  void prePushAction( BOARD_ITEM* aItem ) override
1195  {
1196  // Because aItem is/can be created from a selected item, and inherits from
1197  // it this state, reset the selected stated of aItem:
1198  aItem->ClearSelected();
1199 
1200  if( aItem->Type() == PCB_MODULE_T )
1201  {
1202  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1203  {
1204  item->ClearSelected();
1205  }
1206  );
1207  }
1208  }
1209 
1210  void postPushAction( BOARD_ITEM* new_item ) override
1211  {
1212  }
1213 
1214  void finalise() override
1215  {
1216  }
1217 
1220 };
1221 
1222 
1224 {
1226  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1228 
1229  if( selection.Empty() )
1230  return 0;
1231 
1232  // we have a selection to work on now, so start the tool process
1233  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
1234  GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
1235  array_creator.Invoke();
1236 
1237  return 0;
1238 }
1239 
1240 
1242 {
1243  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1244  {
1245  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1246 
1247  if( item->Type() != PCB_PAD_T )
1248  aCollector.Remove( i );
1249  }
1250 }
1251 
1252 
1254 {
1255  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1256  {
1257  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1258 
1259  if( item->Type() != PCB_MODULE_T )
1260  aCollector.Remove( i );
1261  }
1262 }
1263 
1264 
1266 {
1268 
1269  bool updateMode = aEvent.IsAction( &PCB_ACTIONS::updateFootprints );
1270 
1271  MODULE* mod = (selection.Empty() ? nullptr : selection.FirstOfKind<MODULE> () );
1272 
1273  frame()->SetCurItem( mod );
1274 
1275  // Footprint exchange could remove modules, so they have to be
1276  // removed from the selection first
1278 
1279  // invoke the exchange dialog process
1280  {
1281  DIALOG_EXCHANGE_FOOTPRINTS dialog( frame(), mod, updateMode, mod != nullptr );
1282  dialog.ShowQuasiModal();
1283  }
1284 
1285  return 0;
1286 }
1287 
1288 
1290 {
1291  if( EditingModules() && !frame()->GetModel())
1292  return 0;
1293 
1294  auto& view = *getView();
1295  auto& controls = *getViewControls();
1297 
1298  Activate();
1299  frame()->SetToolID( toolID, wxCURSOR_PENCIL, _( "Measure distance" ) );
1300 
1301  EDA_UNITS_T units = frame()->GetUserUnits();
1303  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
1304 
1305  view.Add( &ruler );
1306  view.SetVisible( &ruler, false );
1307 
1308  GRID_HELPER grid( frame() );
1309 
1310  bool originSet = false;
1311 
1312  controls.ShowCursor( true );
1313  controls.SetAutoPan( false );
1314  controls.CaptureCursor( false );
1315 
1316  while( auto evt = Wait() )
1317  {
1318  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1319  grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
1320  controls.SetSnapping( !evt->Modifier( MD_ALT ) );
1321  const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
1322  controls.ForceCursorPosition(true, cursorPos );
1323 
1325  {
1326  break;
1327  }
1328 
1329  // click or drag starts
1330  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
1331  {
1332  twoPtMgr.SetOrigin( cursorPos );
1333  twoPtMgr.SetEnd( cursorPos );
1334 
1335  controls.CaptureCursor( true );
1336  controls.SetAutoPan( true );
1337 
1338  originSet = true;
1339  }
1340 
1341  // second click or mouse up after drag ends
1342  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
1343  {
1344  originSet = false;
1345 
1346  controls.SetAutoPan( false );
1347  controls.CaptureCursor( false );
1348  }
1349 
1350  // move or drag when origin set updates rules
1351  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
1352  {
1353  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
1354  twoPtMgr.SetEnd( cursorPos );
1355 
1356  view.SetVisible( &ruler, true );
1357  view.Update( &ruler, KIGFX::GEOMETRY );
1358  }
1359 
1360  else if( evt->IsAction( &PCB_ACTIONS::switchUnits )
1361  || evt->IsAction( &PCB_ACTIONS::updateUnits ) )
1362  {
1363  if( frame()->GetUserUnits() != units )
1364  {
1365  units = frame()->GetUserUnits();
1366  ruler.SwitchUnits();
1367  view.Update( &ruler, KIGFX::GEOMETRY );
1368  }
1369  }
1370 
1371  else if( evt->IsClick( BUT_RIGHT ) )
1372  {
1374  }
1375  }
1376 
1377  view.SetVisible( &ruler, false );
1378  view.Remove( &ruler );
1379 
1380  frame()->SetNoToolSelected();
1381 
1382  return 0;
1383 }
1384 
1385 
1387 {
1388  Go( &EDIT_TOOL::Main, PCB_ACTIONS::editActivate.MakeEvent() );
1389  Go( &EDIT_TOOL::Main, PCB_ACTIONS::move.MakeEvent() );
1390  Go( &EDIT_TOOL::Drag, PCB_ACTIONS::drag45Degree.MakeEvent() );
1392  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
1393  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCcw.MakeEvent() );
1394  Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
1395  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::remove.MakeEvent() );
1396  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::removeAlt.MakeEvent() );
1402  Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
1403 
1410 }
1411 
1412 
1414 {
1415  if( m_dragging && aSelection.HasReferencePoint() )
1416  return false;
1417 
1418  // When there is only one item selected, the reference point is its position...
1419  if( aSelection.Size() == 1 )
1420  {
1421  auto item = static_cast<BOARD_ITEM*>( aSelection.Front() );
1422  auto pos = item->GetPosition();
1423  aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
1424  }
1425  // ...otherwise modify items with regard to the grid-snapped cursor position
1426  else
1427  {
1429  aSelection.SetReferencePoint( m_cursor );
1430  }
1431 
1432  return true;
1433 }
1434 
1435 
1437 {
1439 
1440  if( selection.Empty() )
1441  return 0;
1442 
1444 
1445  if( !mod )
1446  return 0;
1447 
1448  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1449 
1450  editFrame->SetCurItem( mod );
1451 
1452  if( editFrame->GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
1453  {
1454  editFrame->GetCurItem()->SetTimeStamp( GetNewTimeStamp() );
1455  editFrame->OnModify();
1456  }
1457 
1459 
1460  editor->Load_Module_From_BOARD( (MODULE*) editFrame->GetCurItem() );
1461  editFrame->SetCurItem( NULL ); // the current module could be deleted by
1462 
1463  editor->Show( true );
1464  editor->Raise(); // Iconize( false );
1465 
1466  if( selection.IsHover() )
1468 
1469  return 0;
1470 }
1471 
1472 
1474 {
1475  STATUS_TEXT_POPUP statusPopup( frame() );
1476  PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
1477  bool picking = true;
1478  bool retVal = true;
1479 
1480  statusPopup.SetText( _( "Select reference point for the copy..." ) );
1481  picker->Activate();
1482  picker->SetClickHandler( [&]( const VECTOR2D& aPoint ) -> bool
1483  {
1484  aP = aPoint;
1485  statusPopup.SetText( _( "Selection copied." ) );
1486  statusPopup.Expire( 800 );
1487  picking = false;
1488  return false; // we don't need any more points
1489  } );
1490  picker->SetCancelHandler( [&]()
1491  {
1492  statusPopup.SetText( _( "Copy cancelled." ) );
1493  statusPopup.Expire( 800 );
1494  picking = false;
1495  retVal = false;
1496  } );
1497 
1498  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
1499  statusPopup.Popup();
1500 
1501  while( picking )
1502  {
1503  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
1504  Wait();
1505  }
1506 
1507  statusPopup.Hide();
1508  return retVal;
1509 }
1510 
1511 
1512 int EDIT_TOOL::doCopyToClipboard( bool withAnchor )
1513 {
1514  CLIPBOARD_IO io;
1515 
1516  Activate();
1517 
1519  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
1521 
1522  if( selection.Empty() )
1523  return 1;
1524 
1525  if( withAnchor )
1526  {
1527  VECTOR2I refPoint;
1528  bool rv = pickCopyReferencePoint( refPoint );
1529  frame()->SetMsgPanel( board() );
1530 
1531  if( !rv )
1532  return 1;
1533 
1534  selection.SetReferencePoint( refPoint );
1535  }
1536 
1537  io.SetBoard( board() );
1538  io.SaveSelection( selection );
1539 
1540  return 0;
1541 }
1542 
1543 
1545 {
1546  return doCopyToClipboard( true );
1547 }
1548 
1549 
1551 {
1552  return doCopyToClipboard( true );
1553 }
1554 
1555 
1557 {
1558  if( !copyToClipboard( aEvent ) )
1559  {
1560  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items that
1561  // were copied to the clipboard, no more, no fewer. Filtering for locked item, if any will be done
1562  // in the copyToClipboard() routine
1563  TOOL_EVENT evt( aEvent.Category(), aEvent.Action(), TOOL_ACTION_SCOPE::AS_GLOBAL );
1565  Remove( evt );
1566  }
1567 
1568  return 0;
1569 }
static TOOL_ACTION selectItems
Selects a list of items (specified as the event parameter)
Definition: pcb_actions.h:59
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
VECTOR2I GetReferencePoint() const
Definition: selection.h:200
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:1386
VECTOR2I m_cursor
Last cursor position (needed for getModificationPoint() to avoid changes of edit reference point).
Definition: edit_tool.h:209
void ClearReferencePoint()
Definition: selection.h:210
int Main(const TOOL_EVENT &aEvent)
Function Main()
Definition: edit_tool.cpp:338
int Properties(const TOOL_EVENT &aEvent)
Function Edit()
Definition: edit_tool.cpp:633
int Rotate(const TOOL_EVENT &aEvent)
Function Rotate()
Definition: edit_tool.cpp:675
static TOOL_ACTION move
move an item
Definition: pcb_actions.h:96
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:138
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:67
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg) override
Set the tool command ID to aId and sets the cursor to aCursor.
bool IsHover() const
Definition: selection.h:69
int ExchangeFootprints(const TOOL_EVENT &aEvent)
Function ExchangeFootprints()
Definition: edit_tool.cpp:1265
static TOOL_ACTION editActivate
Activation of the edit tool.
Definition: pcb_actions.h:93
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:318
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Function GetMousePosition() Returns the current mouse pointer position.
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, std::vector< BOARD_ITEM * > *aFiltered=NULL, bool aConfirmLockedItems=false)
Function RequestSelection()
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
TOOL_MENU m_menu
Menu model displayed by the tool.
Definition: pcb_tool.h:148
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.
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:182
void SetClickHandler(CLICK_HANDLER aHandler)
Function SetClickHandler() Sets a handler for mouse click event.
Definition: picker_tool.h:95
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:223
void ClearSelected()
Definition: base_struct.h:234
int doCopyToClipboard(bool withAnchor)
Definition: edit_tool.cpp:1512
void AddSeparator(const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddSeparator()
VIEW_CONTROLS class definition.
TOOL_ACTIONS Action() const
Returns more specific information about the type of an event.
Definition: tool_event.h:240
virtual void OnEditItemRequest(wxDC *aDC, BOARD_ITEM *aItem)=0
Function OnEditItemRequest Install the corresponding dialog editor for the given item.
Class BOARD to handle a board.
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
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:49
bool updateModificationPoint(SELECTION &aSelection)
Returns the right modification point (e.g.
Definition: edit_tool.cpp:1413
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:142
const SELECTION & selection() const
Definition: pcb_tool.cpp:251
Tool is invoked after being inactive.
Definition: tool_base.h:82
KIGFX::PCB_VIEW * view() const
Definition: pcb_tool.h:137
static TOOL_ACTION explodePadToShapes
Definition: pcb_actions.h:317
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
PCB_BASE_FRAME & m_parent
Definition: array_creator.h:61
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:111
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
Action activates a tool
Definition: tool_event.h:152
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:125
static int LegacyHotKey(int aHotKey)
Creates a hot key code that refers to a legacy hot key setting, instead of a particular key.
Definition: tool_action.h:174
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
static TOOL_ACTION removeAlt
Definition: pcb_actions.h:133
Classes to handle copper zones.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:141
TOOL_EVENT_CATEGORY Category() const
Returns the category (eg. mouse/keyboard/action) of an event..
Definition: tool_event.h:234
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:108
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
VECTOR2I BestSnapAnchor(const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem)
static TOOL_ACTION updateUnits
Definition: pcb_actions.h:373
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
Selection tool used for obtaining selected items
Definition: edit_tool.h:199
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...
void SaveSelection(const SELECTION &selected)
static TOOL_ACTION pasteFromClipboard
Paste from clipboard.
Definition: pcb_actions.h:329
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
static TOOL_ACTION switchUnits
Definition: pcb_actions.h:372
void SetBoard(BOARD *aBoard)
Definition of class FOOTPRINT_EDIT_FRAME.
static bool NotEmpty(const SELECTION &aSelection)
Function NotEmpty Tests if there are any items selected.
wxPoint m_O_Curseur
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:185
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
static const int delta[8][2]
Definition: solve.cpp:112
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:143
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.
MODULE * getModule() const override
Definition: edit_tool.cpp:1181
static TOOL_ACTION selectionModified
Modified selection notification.
Definition: pcb_actions.h:114
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
int Mirror(const TOOL_EVENT &aEvent)
Function Mirror.
Definition: edit_tool.cpp:760
Pcbnew hotkeys.
BOARD_ITEM * getNthItemToArray(int n) const override
Definition: edit_tool.cpp:1171
bool IsNew() const
Definition: base_struct.h:219
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:54
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:117
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:1556
Generic tool for picking a point.
Definition: picker_tool.h:34
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:133
void finalise() override
Definition: edit_tool.cpp:1214
bool m_lockedSelected
Flag determining whether we are prompting for locked removal
Definition: edit_tool.h:205
void SetParameter(T aParam)
Function SetParameter() Sets a non-standard parameter assigned to the event.
Definition: tool_event.h:399
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
static TOOL_ACTION duplicate
Activation of the duplication tool.
Definition: pcb_actions.h:120
class MODULE, a footprint
Definition: typeinfo.h:89
int Flip(const TOOL_EVENT &aEvent)
Function Flip()
Definition: edit_tool.cpp:842
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:205
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:123
timestamp_t GetNewTimeStamp()
Definition: common.cpp:216
bool isInteractiveDragEnabled() const
Definition: edit_tool.cpp:318
static TOOL_ACTION rotateCw
Rotation of selected objects clockwise.
Definition: pcb_actions.h:99
Class LSET is a set of PCB_LAYER_IDs.
int getNumberOfItemsToArray() const override
Definition: edit_tool.cpp:1165
wxPoint getRotationCentre() const override
Definition: edit_tool.cpp:1188
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:300
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
bool m_dragging
Flag determining if anything is being dragged right now
Definition: edit_tool.h:202
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()
BOARD * board() const
Definition: pcb_tool.h:140
int ShowQuasiModal()
static SELECTION_CONDITION OnlyTypes(const std::vector< KICAD_T > &aTypes)
Function OnlyTypes Creates a functor that tests if the selected items are only of given types.
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:291
SELECTION_LOCK_FLAGS
Definition: selection.h:229
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
const wxPoint & GetOffset() const
Definition: class_pad.h:278
Class TOOL_EVENT.
Definition: tool_event.h:168
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:323
void SetOrigin(const VECTOR2I &aOrigin)
Set the origin of the ruler (the fixed end)
GAL_ARRAY_CREATOR(PCB_BASE_FRAME &editFrame, bool editModules, const SELECTION &selection)
Definition: edit_tool.cpp:1156
timestamp_t GetTimeStamp() const
Definition: base_struct.h:207
SELECTION & GetSelection()
Function GetSelection()
bool HasItem(const EDA_ITEM *aItem) const
Function HasItem tests if aItem has already been collected.
Definition: collector.h:197
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Definition: edit_tool.cpp:230
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
bool Load_Module_From_BOARD(MODULE *Module)
Load in Modedit a footprint from the main board.
virtual void Popup(wxWindow *aFocus=nullptr)
int Drag(const TOOL_EVENT &aEvent)
Function Drag()
Definition: edit_tool.cpp:326
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.
static TOOL_ACTION exchangeFootprints
Exchange footprints of modules.
Definition: pcb_actions.h:129
virtual void Move(const wxPoint &aWhere)
const wxSize & GetDelta() const
Definition: class_pad.h:272
bool IsCancelInteractive(const TOOL_EVENT &aEvt)
Function IsCancelInteractive()
All active tools
Definition: tool_event.h:144
static TOOL_ACTION cutToClipboard
Paste from clipboard.
Definition: pcb_actions.h:332
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty.
Definition: dlist.h:163
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
BOARD * getBoard() const override
Definition: edit_tool.cpp:1176
void Expire(int aMsecs)
Hides the popup after a specified time.
const SELECTION & m_selection
Definition: edit_tool.cpp:1219
ROTATION_ANCHOR
static TOOL_ACTION copyToClipboard
Copy selected items to clipboard.
Definition: pcb_actions.h:326
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:223
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
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:48
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
static TOOL_ACTION inlineBreakTrack
Breaks track when router is not activated.
Definition: pcb_actions.h:139
void SetCancelHandler(CANCEL_HANDLER aHandler)
Function SetCancelHandler() Sets a handler for cancel events (ESC or context-menu Cancel).
Definition: picker_tool.h:105
virtual const wxPoint GetPosition() const =0
bool m_editModules
Definition: pcb_tool.h:150
void SetSnap(bool aSnap)
Definition: grid_helper.h:72
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: edit_tool.cpp:221
static TOOL_ACTION expandSelectedConnection
Expands the current selection to select a connection between two junctions.
Definition: pcb_actions.h:74
static TOOL_ACTION updateFootprints
Update footprints to reflect any changes in the library.
Definition: pcb_actions.h:126
static TOOL_ACTION rotateCcw
Rotation of selected objects counter-clockwise.
Definition: pcb_actions.h:102
static void PadFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
Function PadFilter()
Definition: edit_tool.cpp:1241
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
int MoveExact(const TOOL_EVENT &aEvent)
Function MoveExact()
Definition: edit_tool.cpp:997
ID_MODEDIT_MEASUREMENT_TOOL
VECTOR2I Align(const VECTOR2I &aPoint) const
int Remove(const TOOL_EVENT &aEvent)
Function Remove()
Definition: edit_tool.cpp:883
static ROUTER * theRouter
Definition: pns_router.cpp:59
static TOOL_ACTION createPadFromShapes
Definition: pcb_actions.h:316
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:105
virtual void SetNoToolSelected()
Select the ID_NO_TOOL_SELECTED id tool (Idle tool)
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.
virtual bool IsLocked() const
Function IsLocked.
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:297
bool HasReferencePoint() const
Definition: selection.h:195
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
bool pickCopyReferencePoint(VECTOR2I &aP)
Definition: edit_tool.cpp:1473
void DisplayToolMsg(const wxString &msg)
int CreateArray(const TOOL_EVENT &aEvent)
Function CreateArray()
Definition: edit_tool.cpp:1223
bool changeTrackWidthOnClick(const SELECTION &selection)
Definition: edit_tool.cpp:592
Common, abstract interface for edit frames.
int MeasureTool(const TOOL_EVENT &aEvent)
Launches a tool to measure between points
Definition: edit_tool.cpp:1289
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
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:171
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddItem()
static TOOL_ACTION editFootprintInFpEditor
Definition: pcb_actions.h:396
DLIST< MODULE > m_Modules
Definition: class_board.h:249
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:389
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:245
Class TOOL_ACTION.
Definition: tool_action.h:46
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 HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
int Size() const
Returns the number of selected parts.
Definition: selection.h:122
void SetAuxAxes(bool aEnable, const VECTOR2I &aOrigin=VECTOR2I(0, 0), bool aEnableDiagonal=false)
static wxPoint mirrorPointX(const wxPoint &aPoint, const wxPoint &aMirrorPoint)
Definition: edit_tool.cpp:722
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:139
static TOOL_ACTION positionRelative
Activation of the position relative tool.
Definition: pcb_actions.h:259
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
int editFootprintInFpEditor(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:1436
T * FirstOfKind() const
Definition: selection.h:163
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:429
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1485
void Activate()
Function Activate() Runs the tool.
bool EditingModules() const
Definition: pcb_tool.h:102
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:77
void SetX0(int x)
Definition: class_pad.h:266
#define EXCLUDE_LOCKED
Function EditToolSelectionFilter.
Definition: edit_tool.h:46
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:1544
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:388
int copyToClipboardWithAnchor(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:1550
Module description (excepted pads)
static void FootprintFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
Function FootprintFilter()
Definition: edit_tool.cpp:1253
BOARD * GetBoard() const
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
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
static TOOL_ACTION remove
Deleting a BOARD_ITEM.
Definition: pcb_actions.h:132
void UpdateMsgPanel() override
ROUTER * Router() const
const wxPoint GetPosition() const override
Definition: class_pad.h:220
#define EXCLUDE_LOCKED_PADS
Definition: edit_tool.h:47
EDGE_MODULE class definition.
void postPushAction(BOARD_ITEM *new_item) override
Definition: edit_tool.cpp:1210
BOARD_ITEM_CONTAINER * GetParent() const
int GetEventRotationAngle(const PCB_BASE_EDIT_FRAME &aFrame, const TOOL_EVENT &aEvt)
Function getEventRotationAngle()
BOARD_ITEM * GetCurItem()
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:277
void EditToolSelectionFilter(GENERAL_COLLECTOR &aCollector, int aFlags)
Definition: edit_tool.cpp:173
int Duplicate(const TOOL_EVENT &aEvent)
Function Duplicate()
Definition: edit_tool.cpp:1073
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:243
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:62
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:737
void MirrorXPrimitives(int aX)
Mirror the primitives about a coordinate.
Definition: class_pad.cpp:496
#define mod(a, n)
Definition: greymap.cpp:24
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
static TOOL_ACTION measureTool
Definition: pcb_actions.h:370
EDA_UNITS_T
Definition: common.h:160
void SetText(const wxString &aText)
Display a text.
int GetToolId() const
Definition: draw_frame.h:526
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:271
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:152
void prePushAction(BOARD_ITEM *aItem) override
Definition: edit_tool.cpp:1194
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:495
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:206
Color has changed.
Definition: view_item.h:57
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aAddToBoard=false)