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 <wxPcbStruct.h>
35 #include <kiway.h>
36 #include <class_draw_panel_gal.h>
37 #include <module_editor_frame.h>
38 #include <array_creator.h>
39 #include <pcbnew_id.h>
40 
41 #include <tool/tool_manager.h>
42 #include <view/view_controls.h>
43 #include <view/view.h>
45 #include <connectivity_data.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 // Edit tool actions
75 TOOL_ACTION PCB_ACTIONS::editFootprintInFpEditor( "pcbnew.InteractiveEdit.editFootprintInFpEditor",
77  _( "Open in Footprint Editor" ),
78  _( "Opens the selected footprint in the Footprint Editor" ),
79  module_editor_xpm );
80 
81 TOOL_ACTION PCB_ACTIONS::copyPadToSettings( "pcbnew.InteractiveEdit.copyPadToSettings",
82  AS_GLOBAL, 0,
83  _( "Copy Pad Settings to Current Settings" ),
84  _( "Copies the properties of selected pad to the current template pad settings." ) );
85 
86 TOOL_ACTION PCB_ACTIONS::copySettingsToPads( "pcbnew.InteractiveEdit.copySettingsToPads",
87  AS_GLOBAL, 0,
88  _( "Copy Current Settings to Pads" ),
89  _( "Copies the current template pad settings to the selected pad(s)." ) );
90 
91 TOOL_ACTION PCB_ACTIONS::globalEditPads( "pcbnew.InteractiveEdit.globalPadEdit",
92  AS_GLOBAL, 0,
93  _( "Global Pad Edition" ),
94  _( "Changes pad properties globally." ), push_pad_settings_xpm );
95 
96 TOOL_ACTION PCB_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
97  AS_GLOBAL, 0,
98  _( "Edit Activate" ), "", move_xpm, AF_ACTIVATE );
99 
100 TOOL_ACTION PCB_ACTIONS::move( "pcbnew.InteractiveEdit.move",
102  _( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE );
103 
104 TOOL_ACTION PCB_ACTIONS::duplicate( "pcbnew.InteractiveEdit.duplicate",
106  _( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_xpm );
107 
108 TOOL_ACTION PCB_ACTIONS::duplicateIncrement( "pcbnew.InteractiveEdit.duplicateIncrementPads",
110  _( "Duplicate" ), _( "Duplicates the selected item(s), incrementing pad numbers" ) );
111 
112 TOOL_ACTION PCB_ACTIONS::moveExact( "pcbnew.InteractiveEdit.moveExact",
114  _( "Move Exactly" ), _( "Moves the selected item(s) by an exact amount" ),
115  move_exactly_xpm );
116 
117 TOOL_ACTION PCB_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray",
119  _( "Create Array" ), _( "Create array" ), array_xpm, AF_ACTIVATE );
120 
121 TOOL_ACTION PCB_ACTIONS::rotateCw( "pcbnew.InteractiveEdit.rotateCw",
122  AS_GLOBAL, MD_SHIFT + 'R',
123  _( "Rotate Clockwise" ), _( "Rotates selected item(s) clockwise" ),
124  rotate_cw_xpm, AF_NONE, (void*) -1 );
125 
126 TOOL_ACTION PCB_ACTIONS::rotateCcw( "pcbnew.InteractiveEdit.rotateCcw",
128  _( "Rotate Counterclockwise" ), _( "Rotates selected item(s) counterclockwise" ),
129  rotate_ccw_xpm, AF_NONE, (void*) 1 );
130 
131 TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
133  _( "Flip" ), _( "Flips selected item(s)" ), swap_layer_xpm );
134 
135 TOOL_ACTION PCB_ACTIONS::mirror( "pcbnew.InteractiveEdit.mirror",
136  AS_GLOBAL, 0,
137  _( "Mirror" ), _( "Mirrors selected item" ), mirror_h_xpm );
138 
139 TOOL_ACTION PCB_ACTIONS::remove( "pcbnew.InteractiveEdit.remove",
141  _( "Delete" ), _( "Deletes selected item(s)" ), delete_xpm,
142  AF_NONE, (void*) REMOVE_FLAGS::NORMAL );
143 
144 TOOL_ACTION PCB_ACTIONS::removeAlt( "pcbnew.InteractiveEdit.removeAlt",
146  _( "Delete (Alternative)" ), _( "Deletes selected item(s)" ), delete_xpm,
147  AF_NONE, (void*) REMOVE_FLAGS::ALT );
148 
149 TOOL_ACTION PCB_ACTIONS::exchangeFootprints( "pcbnew.InteractiveEdit.ExchangeFootprints",
150  AS_GLOBAL, 0,
151  _( "Exchange Footprint" ), _( "Change the footprint used for modules" ),
152  exchange_xpm );
153 
154 TOOL_ACTION PCB_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
156  _( "Properties" ), _( "Displays item properties dialog" ), config_xpm );
157 
158 TOOL_ACTION PCB_ACTIONS::selectionModified( "pcbnew.InteractiveEdit.ModifiedSelection",
159  AS_GLOBAL, 0,
160  "", "", nullptr, AF_NOTIFY );
161 
162 TOOL_ACTION PCB_ACTIONS::measureTool( "pcbnew.InteractiveEdit.measureTool",
163  AS_GLOBAL, MD_CTRL + MD_SHIFT + 'M',
164  _( "Measuring tool" ), _( "Interactively measure distance between points" ),
165  nullptr, AF_ACTIVATE );
166 
167 TOOL_ACTION PCB_ACTIONS::copyToClipboard( "pcbnew.InteractiveEdit.CopyToClipboard",
168  AS_GLOBAL, MD_CTRL + int( 'C' ),
169  _( "Copy" ), _( "Copy selected content to clipboard" ),
170  copy_xpm );
171 
172 TOOL_ACTION PCB_ACTIONS::cutToClipboard( "pcbnew.InteractiveEdit.CutToClipboard",
173  AS_GLOBAL, MD_CTRL + int( 'X' ),
174  _( "Cut" ), _( "Cut selected content to clipboard" ),
175  cut_xpm );
176 
177 static wxPoint getAnchorPoint( const SELECTION &selection, const MOVE_PARAMETERS &params )
178 {
179  wxPoint anchorPoint;
180 
181  if( params.origin == RELATIVE_TO_CURRENT_POSITION )
182  {
183  return wxPoint( 0, 0 );
184  }
185 
186  // set default anchor
187  VECTOR2I rp = selection.GetCenter();
188  anchorPoint = wxPoint( rp.x, rp.y );
189 
190  // If the anchor is not ANCHOR_FROM_LIBRARY then the user applied an override.
191  // Also run through this block if only one item is slected because it may be a module,
192  // in which case we want something different than the center of the selection
193  if( ( params.anchor != ANCHOR_FROM_LIBRARY ) || ( selection.GetSize() == 1 ) )
194  {
195  BOARD_ITEM* topLeftItem = static_cast<BOARD_ITEM*>( selection.GetTopLeftModule() );
196 
197  // no module found if the GetTopLeftModule() returns null
198  if( topLeftItem != nullptr )
199  {
200  if( topLeftItem->Type() == PCB_MODULE_T )
201  {
202  // Cast to module to allow access to the pads
203  MODULE* mod = static_cast<MODULE*>( topLeftItem );
204 
205  switch( params.anchor )
206  {
207  case ANCHOR_FROM_LIBRARY:
208  anchorPoint = mod->GetPosition();
209  break;
210 
211  case ANCHOR_TOP_LEFT_PAD:
212  topLeftItem = mod->GetTopLeftPad();
213  break;
214 
216  anchorPoint = mod->GetFootprintRect().GetCenter();
217  break;
218  }
219  }
220 
221  if( topLeftItem->Type() == PCB_PAD_T )
222  {
223  if( static_cast<D_PAD*>( topLeftItem )->GetAttribute() == PAD_ATTRIB_SMD )
224  {
225  // Use the top left corner of SMD pads as an anchor instead of the center
226  anchorPoint = topLeftItem->GetBoundingBox().GetPosition();
227  }
228  else
229  {
230  anchorPoint = topLeftItem->GetPosition();
231  }
232  }
233  }
234  else // no module found in the selection
235  {
236  // in a selection of non-modules
237  if( params.anchor == ANCHOR_TOP_LEFT_PAD )
238  {
239  // approach the top left pad override for non-modules by using the position of
240  // the topleft item as an anchor
241  topLeftItem = static_cast<BOARD_ITEM*>( selection.GetTopLeftItem() );
242  anchorPoint = topLeftItem->GetPosition();
243  }
244  }
245  }
246 
247  return anchorPoint;
248 }
249 
250 
252  PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
253  m_dragging( false )
254 {
255 }
256 
257 
259 {
260  m_dragging = false;
261 
262  if( aReason != RUN )
263  m_commit.reset( new BOARD_COMMIT( this ) );
264 }
265 
266 
268 {
269  // Find the selection tool, so they can cooperate
270  m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
271 
272  if( !m_selectionTool )
273  {
274  DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
275  return false;
276  }
277 
278  auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
279  return m_editModules;
280  };
281 
282  auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
284 
285  // Add context menu entries that are displayed when selection tool is active
287 
297 
298 
303 
304 
308  menu.AddSeparator();
309 
310  // Mirror only available in modedit
311  menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
314 
315  // Footprint actions
317  singleModuleCondition );
319  singleModuleCondition );
320 
321  return true;
322 }
323 
324 
325 bool EDIT_TOOL::invokeInlineRouter( int aDragMode )
326 {
327  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
328 
329  if( !theRouter )
330  return false;
331 
332  // make sure we don't accidentally invoke inline routing mode while the router is already active!
333  if( theRouter->IsToolActive() )
334  return false;
335 
336  if( theRouter->CanInlineDrag() )
337  {
339  return true;
340  }
341 
342  return false;
343 }
344 
345 
347 {
348  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
349 
350  return theRouter ? theRouter->Router()->Settings().InlineDragEnabled() : false;
351 }
352 
353 
354 int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
355 {
356  int mode = PNS::DM_ANY;
357 
358  if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
359  mode |= PNS::DM_FREE_ANGLE;
360 
361  invokeInlineRouter( mode );
362 
363  return 0;
364 }
365 
366 int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
367 {
369  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
370 
371  VECTOR2I originalCursorPos = controls->GetCursorPosition();
372 
373  // Be sure that there is at least one item that we can modify. If nothing was selected before,
374  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
376 
377  if( selection.Empty() )
378  return 0;
379 
380  bool unselect = selection.IsHover();
381 
382  if( m_dragging )
383  return 0;
384 
385  Activate();
386 
387  m_dragging = false; // Are selected items being dragged?
388  bool restore = false; // Should items' state be restored when finishing the tool?
389 
390  controls->ShowCursor( true );
391  controls->SetSnapping( true );
392  controls->SetAutoPan( true );
393 
394  // cumulative translation
395  VECTOR2I totalMovement;
396  GRID_HELPER grid( editFrame );
397  OPT_TOOL_EVENT evt = aEvent;
398  VECTOR2I prevPos;
399 
400  // Main loop: keep receiving events
401  do
402  {
403  bool matchingAction = evt->IsAction( &PCB_ACTIONS::editActivate )
404  || evt->IsAction( &PCB_ACTIONS::move );
405 
406  if( matchingAction
407  || evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
408  {
409  if( selection.Empty() )
410  break;
411 
412  auto curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
413 
414  if( m_dragging && evt->Category() == TC_MOUSE )
415  {
416  m_cursor = grid.BestSnapAnchor( evt->Position(), curr_item );
417  controls->ForceCursorPosition( true, m_cursor );
418 
419  VECTOR2I movement( m_cursor - prevPos );
421 
422  totalMovement += movement;
423  prevPos = m_cursor;
424 
425  // Drag items to the current cursor position
426  for( auto item : selection )
427  {
428  static_cast<BOARD_ITEM*>( item )->Move( movement );
429  }
430  }
431  else if( !m_dragging ) // Prepare to start dragging
432  {
433  bool invokedRouter = false;
434 
435  if ( !evt->IsAction( &PCB_ACTIONS::move ) && isInteractiveDragEnabled() )
436  invokedRouter = invokeInlineRouter( PNS::DM_ANY );
437 
438  if( !invokedRouter )
439  {
440  // deal with locked items (override lock or abort the operation)
442 
443  if( lockFlags == SELECTION_LOCKED )
444  break;
445 
446  // Save items, so changes can be undone
447  for( auto item : selection )
448  m_commit->Modify( item );
449 
450  m_cursor = controls->GetCursorPosition();
451 
452  if ( selection.HasReferencePoint() )
453  {
454  // start moving with the reference point attached to the cursor
455  grid.SetAuxAxes( false );
456 
457  auto delta = m_cursor - selection.GetReferencePoint();
458 
459  // Drag items to the current cursor position
460  for( auto item : selection )
461  static_cast<BOARD_ITEM*>( item )->Move( delta );
462 
463  selection.SetReferencePoint( m_cursor );
464  }
465  else if( selection.Size() == 1 )
466  {
467  // Set the current cursor position to the first dragged item origin, so the
468  // movement vector could be computed later
469  updateModificationPoint( selection );
470  m_cursor = grid.BestDragOrigin( originalCursorPos, curr_item );
471  grid.SetAuxAxes( true, m_cursor );
472  }
473  else
474  {
475  updateModificationPoint( selection );
476  m_cursor = grid.Align( m_cursor );
477  }
478 
479  controls->SetCursorPosition( m_cursor, false );
480 
481  prevPos = m_cursor;
482  controls->SetAutoPan( true );
483  m_dragging = true;
484  }
485  }
486 
488  }
489 
490  else if( evt->IsCancel() || evt->IsActivate() )
491  {
492  restore = true; // Cancelling the tool means that items have to be restored
493  break; // Finish
494  }
495 
496  else if( evt->Action() == TA_UNDO_REDO_PRE )
497  {
498  unselect = true;
499  break;
500  }
501 
502  // Dispatch TOOL_ACTIONs
503  else if( evt->Category() == TC_COMMAND )
504  {
505  if( evt->IsAction( &PCB_ACTIONS::remove ) )
506  {
507  // exit the loop, as there is no further processing for removed items
508  break;
509  }
510  else if( evt->IsAction( &PCB_ACTIONS::duplicate ) )
511  {
512  // On duplicate, stop moving this item
513  // The duplicate tool should then select the new item and start
514  // a new move procedure
515  break;
516  }
517  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
518  {
519  // Can't do this, because the selection will then contain
520  // stale pointers and it will all go horribly wrong...
521  //editFrame->RestoreCopyFromUndoList( dummy );
522  //
523  // So, instead, reset the position manually
524  for( auto item : selection )
525  {
526  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
527  auto delta = VECTOR2I( i->GetPosition() ) - totalMovement;
528  i->SetPosition( wxPoint( delta.x, delta.y ) );
529 
530  // And what about flipping and rotation?
531  // for now, they won't be undone, but maybe that is how
532  // it should be, so you can flip and move exact in the
533  // same action?
534  }
535 
536  // This causes a double event, so we will get the dialogue
537  // correctly, somehow - why does Rotate not?
538  //MoveExact( aEvent );
539  break; // exit the loop - we move exactly, so we have finished moving
540  }
541  }
542 
543  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
544  {
545  break; // Finish
546  }
547  } while( ( evt = Wait() ) ); //Should be assignment not equality test
548 
549  controls->ForceCursorPosition( false );
550  controls->ShowCursor( false );
551  controls->SetSnapping( false );
552  controls->SetAutoPan( false );
553 
554  m_dragging = false;
555  // Discard reference point when selection is "dropped" onto the board (ie: not dragging anymore)
557 
558  if( unselect || restore )
560 
561  if( restore )
562  m_commit->Revert();
563  else
564  m_commit->Push( _( "Drag" ) );
565 
566  return 0;
567 }
568 
570 {
571  if ( selection.Size() == 1 && frame()->Settings().m_editActionChangesTrackWidth )
572  {
573  auto item = static_cast<BOARD_ITEM *>( selection[0] );
574 
575  m_commit->Modify( item );
576 
577  if( auto via = dyn_cast<VIA*>( item ) )
578  {
579  int new_width, new_drill;
580 
581  if( via->GetViaType() == VIA_MICROVIA )
582  {
583  auto net = via->GetNet();
584 
585  new_width = net->GetMicroViaSize();
586  new_drill = net->GetMicroViaDrillSize();
587  }
588  else
589  {
590  new_width = board()->GetDesignSettings().GetCurrentViaSize();
591  new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
592  }
593 
594  via->SetDrill( new_drill );
595  via->SetWidth( new_width );
596  }
597  else if ( auto track = dyn_cast<TRACK*>( item ) )
598  {
599  int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
600  track->SetWidth( new_width );
601  }
602 
603  m_commit->Push( _("Edit track width/via size") );
604  return true;
605  }
606 
607  return false;
608 }
609 
610 int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
611 {
612  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
613 
616 
617  if( selection.Empty() )
618  return 0;
619 
620  // Tracks & vias are treated in a special way:
622  {
623  if ( !changeTrackWidthOnClick( selection ) )
624  {
625  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection );
626 
627  if( dlg.ShowModal() )
628  {
629  dlg.Apply( *m_commit );
630  m_commit->Push( _( "Edit track/via properties" ) );
631  }
632  }
633  }
634  else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
635  {
636  // Display properties dialog
637  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
638 
639  // Some of properties dialogs alter pointers, so we should deselect them
641 
642  // Store flags, so they can be restored later
643  STATUS_FLAGS flags = item->GetFlags();
644  item->ClearFlags();
645 
646  // Do not handle undo buffer, it is done by the properties dialogs @todo LEGACY
647  // Display properties dialog provided by the legacy canvas frame
648  editFrame->OnEditItemRequest( NULL, item );
649 
651  item->SetFlags( flags );
652  }
653 
654  if( selection.IsHover() )
656 
657  return 0;
658 }
659 
660 
661 int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
662 {
663  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
664 
666 
667  if( selection.Empty() )
668  return 0;
669 
671  return 0;
672 
673  updateModificationPoint( selection );
674  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
675 
676  for( auto item : selection )
677  {
678  m_commit->Modify( item );
679  static_cast<BOARD_ITEM*>( item )->Rotate( selection.GetReferencePoint(), rotateAngle );
680  }
681 
682  if( !m_dragging )
683  m_commit->Push( _( "Rotate" ) );
684 
685  if( selection.IsHover() && !m_dragging )
687 
689 
690  return 0;
691 }
692 
693 
697 static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
698 {
699  wxPoint mirrored = aPoint;
700 
701  mirrored.x -= aMirrorPoint.x;
702  mirrored.x = -mirrored.x;
703  mirrored.x += aMirrorPoint.x;
704 
705  return mirrored;
706 }
707 
708 
712 static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
713 {
714  wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
715 
716  aPad.SetPosition( tmpPt );
717 
718  aPad.SetX0( aPad.GetPosition().x );
719 
720  tmpPt = aPad.GetOffset();
721  tmpPt.x = -tmpPt.x;
722  aPad.SetOffset( tmpPt );
723 
724  auto tmpz = aPad.GetDelta();
725  tmpz.x = -tmpz.x;
726  aPad.SetDelta( tmpz );
727 
728  aPad.SetOrientation( -aPad.GetOrientation() );
729 }
730 
731 
732 int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
733 {
735 
737  return 0;
738 
739  if( selection.Empty() )
740  return 0;
741 
743  auto refPoint = selection.GetReferencePoint();
744  wxPoint mirrorPoint( refPoint.x, refPoint.y );
745 
746  for( auto item : selection )
747  {
748  // only modify items we can mirror
749  switch( item->Type() )
750  {
751  case PCB_MODULE_EDGE_T:
752  case PCB_MODULE_TEXT_T:
753  case PCB_PAD_T:
754  m_commit->Modify( item );
755  break;
756  default:
757  continue;
758  }
759 
760  // modify each object as necessary
761  switch( item->Type() )
762  {
763  case PCB_MODULE_EDGE_T:
764  {
765  auto& edge = static_cast<EDGE_MODULE&>( *item );
766  edge.Mirror( mirrorPoint, false );
767  break;
768  }
769 
770  case PCB_MODULE_TEXT_T:
771  {
772  auto& modText = static_cast<TEXTE_MODULE&>( *item );
773  modText.Mirror( mirrorPoint, false );
774  break;
775  }
776 
777  case PCB_PAD_T:
778  {
779  auto& pad = static_cast<D_PAD&>( *item );
780  mirrorPadX( pad, mirrorPoint );
781  break;
782  }
783 
784  default:
785  // it's likely the commit object is wrong if you get here
786  assert( false );
787  break;
788  }
789  }
790 
791  if( !m_dragging )
792  m_commit->Push( _( "Mirror" ) );
793 
794  if( selection.IsHover() && !m_dragging )
796 
798 
799  return 0;
800 }
801 
802 
803 int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
804 {
806 
808  return 0;
809 
810  if( selection.Empty() )
811  return 0;
812 
814  auto modPoint = selection.GetReferencePoint();
815 
816  for( auto item : selection )
817  {
818  m_commit->Modify( item );
819  static_cast<BOARD_ITEM*>( item )->Flip( modPoint );
820  }
821 
822  if( !m_dragging )
823  m_commit->Push( _( "Flip" ) );
824 
825  if( selection.IsHover() && !m_dragging )
827 
829 
830  return 0;
831 }
832 
833 
834 int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
835 {
836  // get a copy instead of reference (as we're going to clear the selectio before removing items)
838 
840  return 0;
841 
842  if( selection.Empty() )
843  return 0;
844 
845  // is this "alternative" remove?
846  const bool isAlt = aEvent.Parameter<intptr_t>() ==
848 
849  // in "alternative" mode, deletion is not just a simple list
850  // of selected items, it is:
851  // - whole tracks, not just segments
852  if( isAlt && selection.IsHover() )
853  {
856  }
857 
858  // As we are about to remove items, they have to be removed from the selection first
860 
861  for( auto item : selection )
862  {
863  m_commit->Remove( item );
864  }
865 
866  m_commit->Push( _( "Delete" ) );
867 
868  return 0;
869 }
870 
871 
872 int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
873 {
874  const auto& selection = m_selectionTool->RequestSelection();
875 
877  return 0;
878 
879  if( selection.Empty() )
880  return 0;
881 
882  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
883 
884  MOVE_PARAMETERS params;
886 
887  DIALOG_MOVE_EXACT dialog( editFrame, params );
888  int ret = dialog.ShowModal();
889 
890  if( ret == wxID_OK )
891  {
893  wxPoint rotPoint( rp.x, rp.y );
894 
895  wxPoint anchorPoint = getAnchorPoint( selection, params );
896 
897  wxPoint finalMoveVector = params.translation - anchorPoint;
898 
899  // Make sure the rotation is from the right reference point
900  rotPoint += finalMoveVector;
901 
902  for( auto item : selection )
903  {
904  m_commit->Modify( item );
905  static_cast<BOARD_ITEM*>( item )->Move( finalMoveVector );
906  static_cast<BOARD_ITEM*>( item )->Rotate( rotPoint, params.rotation );
907 
908  if( !m_dragging )
909  getView()->Update( item );
910  }
911 
912  m_commit->Push( _( "Move exact" ) );
913 
914  if( selection.IsHover() )
916 
918  }
919 
920  return 0;
921 }
922 
923 
924 int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
925 {
926  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
927 
928  // Be sure that there is at least one item that we can modify
930 
931  if( selection.Empty() )
932  return 0;
933 
934  // we have a selection to work on now, so start the tool process
935  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
936 
937  std::vector<BOARD_ITEM*> new_items;
938  new_items.reserve( selection.Size() );
939 
940  BOARD_ITEM* orig_item = nullptr;
941  BOARD_ITEM* dupe_item = nullptr;
942 
943  // Each selected item is duplicated and pushed to new_items list
944  // Old selection is cleared, and new items are then selected.
945  for( auto item : selection )
946  {
947  if( !item )
948  continue;
949 
950  orig_item = static_cast<BOARD_ITEM*>( item );
951 
952  if( m_editModules )
953  {
954  dupe_item = editFrame->GetBoard()->m_Modules->Duplicate( orig_item, increment );
955  }
956  else
957  {
958 #if 0
959  // @TODO: see if we allow zone duplication here
960  // Duplicate zones is especially tricky (overlaping zones must be merged)
961  // so zones are not duplicated
962  if( item->Type() != PCB_ZONE_AREA_T )
963 #endif
964  dupe_item = editFrame->GetBoard()->Duplicate( orig_item );
965  }
966 
967  if( dupe_item )
968  {
969  // Clear the selection flag here, otherwise the SELECTION_TOOL
970  // will not properly select it later on
971  dupe_item->ClearSelected();
972 
973  new_items.push_back( dupe_item );
974  m_commit->Add( dupe_item );
975  }
976  }
977 
978  // Clear the old selection first
980 
981  // Select the new items
982  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
983 
984  // record the new items as added
985  if( !selection.Empty() )
986  {
987  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
988  (int) new_items.size() ) );
989 
990  // If items were duplicated, pick them up
991  // this works well for "dropping" copies around and pushes the commit
993  Main( evt );
994  }
995 
996  return 0;
997 }
998 
999 
1001 {
1002 public:
1003 
1004  GAL_ARRAY_CREATOR( PCB_BASE_FRAME& editFrame, bool editModules,
1005  const SELECTION& selection ):
1006  ARRAY_CREATOR( editFrame ),
1007  m_editModules( editModules ),
1008  m_selection( selection )
1009  {}
1010 
1011 private:
1012 
1013  int getNumberOfItemsToArray() const override
1014  {
1015  // only handle single items
1016  return m_selection.Size();
1017  }
1018 
1019  BOARD_ITEM* getNthItemToArray( int n ) const override
1020  {
1021  return static_cast<BOARD_ITEM*>( m_selection[n] );
1022  }
1023 
1024  BOARD* getBoard() const override
1025  {
1026  return m_parent.GetBoard();
1027  }
1028 
1029  MODULE* getModule() const override
1030  {
1031  // Remember this is valid and used only in the module editor.
1032  // in board editor, the parent of items is usually the board.
1033  return m_editModules ? m_parent.GetBoard()->m_Modules.GetFirst() : NULL;
1034  }
1035 
1036  wxPoint getRotationCentre() const override
1037  {
1038  const VECTOR2I rp = m_selection.GetCenter();
1039  return wxPoint( rp.x, rp.y );
1040  }
1041 
1042  void prePushAction( BOARD_ITEM* aItem ) override
1043  {
1044  // Because aItem is/can be created from a selected item, and inherits from
1045  // it this state, reset the selected stated of aItem:
1046  aItem->ClearSelected();
1047 
1048  if( aItem->Type() == PCB_MODULE_T )
1049  {
1050  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1051  {
1052  item->ClearSelected();
1053  }
1054  );
1055  }
1056  }
1057 
1058  void postPushAction( BOARD_ITEM* new_item ) override
1059  {
1060  }
1061 
1062  void finalise() override
1063  {
1064  }
1065 
1068 };
1069 
1070 
1072 {
1073  const auto& selection = m_selectionTool->RequestSelection();
1074 
1075  if( selection.Empty() )
1076  return 0;
1077 
1078  // we have a selection to work on now, so start the tool process
1079  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
1080  GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
1081  array_creator.Invoke();
1082 
1083  return 0;
1084 }
1085 
1086 
1088 {
1089  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
1090  {
1091  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
1092 
1093  if( item->Type() != PCB_MODULE_T )
1094  aCollector.Remove( i );
1095  }
1096 }
1097 
1098 
1100 {
1102 
1103  if( selection.Empty() )
1104  return 0;
1105 
1107 
1108  if( !mod )
1109  return 0;
1110 
1111  frame()->SetCurItem( mod );
1112 
1113  // Footprint exchange could remove modules, so they have to be
1114  // removed from the selection first
1116 
1117  // invoke the exchange dialog process
1118  {
1119  DIALOG_EXCHANGE_MODULE dialog( frame(), mod );
1120  dialog.ShowQuasiModal();
1121  }
1122 
1123  // The current item can be deleted by exchange module, and the
1124  // selection is emptied, so remove current item from frame info area
1125  frame()->SetCurItem( nullptr );
1126 
1127  return 0;
1128 }
1129 
1130 
1132 {
1133  auto& view = *getView();
1134  auto& controls = *getViewControls();
1135 
1136  Activate();
1139  wxCURSOR_PENCIL, _( "Measure distance" ) );
1140 
1142 
1143  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr );
1144 
1145  view.Add( &ruler );
1146  view.SetVisible( &ruler, false );
1147 
1148  bool originSet = false;
1149 
1150  controls.ShowCursor( true );
1151  controls.SetSnapping( true );
1152 
1153  while( auto evt = Wait() )
1154  {
1155  const VECTOR2I cursorPos = controls.GetCursorPosition();
1156 
1157  if( evt->IsCancel() || evt->IsActivate() )
1158  {
1159  break;
1160  }
1161 
1162  // click or drag starts
1163  else if( !originSet &&
1164  ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
1165  {
1166  if( !evt->IsDrag( BUT_LEFT ) )
1167  {
1168  twoPtMgr.SetOrigin( cursorPos );
1169  twoPtMgr.SetEnd( cursorPos );
1170  }
1171 
1172  controls.CaptureCursor( true );
1173  controls.SetAutoPan( true );
1174 
1175  originSet = true;
1176  }
1177 
1178  else if( !originSet && evt->IsMotion() )
1179  {
1180  // make sure the origin is set before a drag starts
1181  // otherwise you can miss a step
1182  twoPtMgr.SetOrigin( cursorPos );
1183  twoPtMgr.SetEnd( cursorPos );
1184  }
1185 
1186  // second click or mouse up after drag ends
1187  else if( originSet &&
1188  ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
1189  {
1190  originSet = false;
1191 
1192  controls.SetAutoPan( false );
1193  controls.CaptureCursor( false );
1194 
1195  view.SetVisible( &ruler, false );
1196  }
1197 
1198  // move or drag when origin set updates rules
1199  else if( originSet &&
1200  ( 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->IsClick( BUT_RIGHT ) )
1210  {
1211  GetManager()->PassEvent();
1212  }
1213  }
1214 
1215  view.SetVisible( &ruler, false );
1216  view.Remove( &ruler );
1217 
1218  frame()->SetNoToolSelected();
1219 
1220  return 0;
1221 }
1222 
1223 
1225 {
1226  Go( &EDIT_TOOL::Main, PCB_ACTIONS::editActivate.MakeEvent() );
1227  Go( &EDIT_TOOL::Main, PCB_ACTIONS::move.MakeEvent() );
1228  Go( &EDIT_TOOL::Drag, PCB_ACTIONS::drag45Degree.MakeEvent() );
1230  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
1231  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCcw.MakeEvent() );
1232  Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
1233  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::remove.MakeEvent() );
1234  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::removeAlt.MakeEvent() );
1240  Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
1241 
1247 }
1248 
1249 
1251 {
1252  if( aSelection.HasReferencePoint() )
1253  return false;
1254 
1255  if( aSelection.Size() == 1 )
1256  {
1257  auto item = static_cast<BOARD_ITEM*>( aSelection.Front() );
1258  auto pos = item->GetPosition();
1259  aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
1260  }
1261  else
1262  {
1263  // If EDIT_TOOL is not currently active then it means that the cursor position is not
1264  // updated, so we have to fetch the latest value
1265  if( m_toolMgr->GetCurrentToolId() != m_toolId )
1267 
1268  aSelection.SetReferencePoint( m_cursor );
1269  }
1270 
1271  return true;
1272 }
1273 
1274 
1276 {
1278 
1279  if( selection.Empty() )
1280  return 0;
1281 
1283 
1284  if( !mod )
1285  return 0;
1286 
1287  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1288 
1289  editFrame->SetCurItem( mod );
1290 
1291  if( editFrame->GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
1292  {
1293  editFrame->GetCurItem()->SetTimeStamp( GetNewTimeStamp() );
1294  editFrame->OnModify();
1295  }
1296 
1298 
1299  editor->Load_Module_From_BOARD( (MODULE*) editFrame->GetCurItem() );
1300  editFrame->SetCurItem( NULL ); // the current module could be deleted by
1301 
1302  editor->Show( true );
1303  editor->Raise(); // Iconize( false );
1304 
1305  if( selection.IsHover() )
1307 
1308  return 0;
1309 }
1310 
1311 
1313 {
1314  PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
1315  assert( picker );
1316 
1317  picker->Activate();
1318 
1319  while ( picker->IsPicking() )
1320  Wait();
1321 
1322  if( !picker->GetPoint() )
1323  return false;
1324 
1325  aP = *picker->GetPoint();
1326  return true;
1327 }
1328 
1329 
1331 {
1332  CLIPBOARD_IO io;
1333  VECTOR2I refPoint;
1334 
1335  Activate();
1336 
1337  auto item1 = MSG_PANEL_ITEM( "", _( "Select reference point for the block being copied..." ),
1338  COLOR4D::BLACK );
1339 
1340  std::vector<MSG_PANEL_ITEM> msgItems = { item1 };
1341 
1343 
1344  if( selection.Empty() )
1345  return 0;
1346 
1347  frame()->SetMsgPanel( msgItems );
1348  bool rv = pickCopyReferencePoint( refPoint );
1349  frame()->SetMsgPanel( board() );
1350 
1351  if( !rv )
1352  return 0;
1353 
1354  selection.SetReferencePoint( refPoint );
1355  io.SetBoard( board() );
1356  io.SaveSelection( selection );
1357 
1358  return 0;
1359 }
1360 
1361 
1363 {
1364  copyToClipboard( aEvent );
1365  Remove( aEvent );
1366  return 0;
1367 }
1368 
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 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:1224
int GetCount() const
Function GetCount returns the number of objects in the list.
VECTOR2I m_cursor
Last cursor position (needed for getModificationPoint() to avoid changes of edit reference point)...
Definition: edit_tool.h:180
void ClearReferencePoint()
Definition: selection.h:188
KICAD_T Type() const
Function Type()
Definition: base_struct.h:225
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:106
int Main(const TOOL_EVENT &aEvent)
Function Main()
Definition: edit_tool.cpp:366
Definition of class FOOTPRINT_EDIT_FRAME.
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:282
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
static wxPoint getAnchorPoint(const SELECTION &selection, const MOVE_PARAMETERS &params)
Definition: edit_tool.cpp:177
int Properties(const TOOL_EVENT &aEvent)
Function Edit()
Definition: edit_tool.cpp:610
int Rotate(const TOOL_EVENT &aEvent)
Function Rotate()
Definition: edit_tool.cpp:661
TOOL_BASE * FindTool(int aId) const
Function FindTool() Searches for a tool with given ID.
static TOOL_ACTION move
move an item
Definition: pcb_actions.h:90
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
VECTOR2I GetReferencePoint() const
Definition: selection.h:178
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
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg) override
Function SetToolID sets the tool command ID to aId and sets the cursor to aCursor.
int ExchangeFootprints(const TOOL_EVENT &aEvent)
Function ExchangeFootprints()
Definition: edit_tool.cpp:1099
static TOOL_ACTION editActivate
Activation of the edit tool.
Definition: pcb_actions.h:87
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:300
int GetCurrentToolId() const
Returns id of the tool that is on the top of the active tools stack (was invoked the most recently)...
Definition: tool_manager.h:277
static TOOL_ACTION globalEditPads
Definition: pcb_actions.h:390
virtual void SetPosition(const wxPoint &aPos)=0
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:81
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...
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:209
void ClearSelected()
Definition: base_struct.h:258
VECTOR2I Align(const VECTOR2I &aPoint) const
void AddSeparator(const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddSeparator()
VIEW_CONTROLS class definition.
Class SELECTION_TOOL.
Class TWO_POINT_GEOMETRY_MANAGER.
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.
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:1250
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:128
Tool is invoked after being inactive.
Definition: tool_base.h:82
static TOOL_ACTION explodePadToShapes
Definition: pcb_actions.h:295
EDA_ITEM * Front() const
Definition: selection.h:144
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
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...
PCB_BASE_FRAME & m_parent
Definition: array_creator.h:61
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:61
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:102
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:105
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:146
TOOL_ID m_toolId
Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
Definition: tool_base.h:210
MOVE_EXACT_ORIGIN origin
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 TOOL_ACTION selectConnection
Selects a connection between junctions.
Definition: pcb_actions.h:68
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
BOARD * GetBoard() const
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
static TOOL_ACTION removeAlt
Definition: pcb_actions.h:124
Classes to handle copper zones.
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 drag45Degree
Definition: pcb_actions.h:127
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:102
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
VECTOR2I BestSnapAnchor(const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem)
SELECTION_TOOL * m_selectionTool
Selection tool used for obtaining selected items
Definition: edit_tool.h:173
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:307
VECTOR2< int > VECTOR2I
Definition: vector2d.h:589
void SetBoard(BOARD *aBoard)
int GetCurrentViaSize() const
Function GetCurrentViaSize.
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);.
static const int delta[8][2]
Definition: solve.cpp:112
virtual void Remove(VIEW_ITEM *aItem) override
Function Remove() Removes a VIEW_ITEM from the view.
Definition: pcb_view.cpp:64
static TOOL_ACTION copyPadToSettings
Definition: pcb_actions.h:388
MODULE * getModule() const override
Definition: edit_tool.cpp:1029
static TOOL_ACTION selectionModified
Modified selection notification.
Definition: pcb_actions.h:108
int Mirror(const TOOL_EVENT &aEvent)
Function Mirror.
Definition: edit_tool.cpp:732
Pcbnew hotkeys.
BOARD_ITEM * getNthItemToArray(int n) const override
Definition: edit_tool.cpp:1019
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:111
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:1362
Generic tool for picking a point.
Definition: picker_tool.h:34
void finalise() override
Definition: edit_tool.cpp:1062
static TOOL_ACTION copySettingsToPads
Definition: pcb_actions.h:389
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Moves cursor to the requested position expressed in world coordinates.
void PassEvent()
Allows a tool to pass the already handled event to the next tool on the stack.
Definition: tool_manager.h:351
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:133
static TOOL_ACTION duplicate
Activation of the duplication tool.
Definition: pcb_actions.h:114
void Mirror(const wxPoint aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
class MODULE, a footprint
Definition: typeinfo.h:89
int Flip(const TOOL_EVENT &aEvent)
Function Flip()
Definition: edit_tool.cpp:803
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:183
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:117
timestamp_t GetNewTimeStamp()
Definition: common.cpp:166
static TOOL_ACTION rotateCw
Rotation of selected objects clockwise.
Definition: pcb_actions.h:93
int getNumberOfItemsToArray() const override
Definition: edit_tool.cpp:1013
wxPoint getRotationCentre() const override
Definition: edit_tool.cpp:1036
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:280
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)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:793
bool m_dragging
Flag determining if anything is being dragged right now
Definition: edit_tool.h:176
virtual void CaptureCursor(bool aEnabled)
Function CaptureCursor() Forces the cursor to stay within the drawing panel area. ...
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
PCB_GENERAL_SETTINGS & Settings()
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...
SELECTION_LOCK_FLAGS
Definition: selection.h:207
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:134
Class TOOL_EVENT.
Definition: tool_event.h:162
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:301
SELECTION & RequestSelection(int aFlags=SELECTION_DEFAULT, CLIENT_SELECTION_FILTER aClientFilter=NULL)
Function RequestSelection()
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:1004
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
EDA_ITEM * GetTopLeftItem(bool onlyModules=false) const
Definition: selection.cpp:90
unsigned STATUS_FLAGS
Definition: base_struct.h:158
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Definition: edit_tool.cpp:267
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
bool Load_Module_From_BOARD(MODULE *Module)
Function Load_Module_From_BOARD load in Modedit a footprint from the main board.
Definition: loadcmp.cpp:75
int Drag(const TOOL_EVENT &aEvent)
Function Drag()
Definition: edit_tool.cpp:354
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.
const SELECTION & selection() const
Definition: pcb_tool.cpp:218
bool isInteractiveDragEnabled() const
Definition: edit_tool.cpp:346
static TOOL_ACTION exchangeFootprints
Exchange footprints of modules.
Definition: pcb_actions.h:120
All active tools
Definition: tool_event.h:138
static TOOL_ACTION cutToClipboard
Paste from clipboard.
Definition: pcb_actions.h:310
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:1385
BOARD * getBoard() const override
Definition: edit_tool.cpp:1024
const SELECTION & m_selection
Definition: edit_tool.cpp:1067
static TOOL_ACTION copyToClipboard
Copy selected items to clipboard.
Definition: pcb_actions.h:304
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:209
const wxPoint GetPosition() const
D_PAD * GetTopLeftPad()
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg...
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
virtual const wxPoint GetPosition() const =0
bool IsPicking() const
Function IsPicking() Returns information whether the tool is still active.
Definition: picker_tool.h:87
bool m_editModules
Definition: pcb_tool.h:142
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: edit_tool.cpp:258
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
T * FirstOfKind() const
Definition: selection.h:158
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:86
static TOOL_ACTION rotateCcw
Rotation of selected objects counter-clockwise.
Definition: pcb_actions.h:96
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
int MoveExact(const TOOL_EVENT &aEvent)
Function MoveExact()
Definition: edit_tool.cpp:872
int Remove(const TOOL_EVENT &aEvent)
Function Remove()
Definition: edit_tool.cpp:834
static ROUTER * theRouter
Definition: pns_router.cpp:59
static TOOL_ACTION createPadFromShapes
Definition: pcb_actions.h:294
bool EditingModules() const
Definition: pcb_tool.h:97
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:99
virtual void SetNoToolSelected()
Select the ID_NO_TOOL_SELECTED id tool (Idle tool)
Definition: draw_frame.cpp:577
virtual void OnModify()
Function OnModify Virtual Must be called after a change in order to set the "modify" flag of the curr...
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:373
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:325
TOOL_EVENT MakeEvent() const
Function HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
bool pickCopyReferencePoint(VECTOR2I &aP)
Definition: edit_tool.cpp:1312
void DisplayToolMsg(const wxString &msg)
Definition: draw_frame.cpp:514
int CreateArray(const TOOL_EVENT &aEvent)
Function CreateArray()
Definition: edit_tool.cpp:1071
bool changeTrackWidthOnClick(const SELECTION &selection)
Definition: edit_tool.cpp:569
Common, abstract interface for edit frames.
int MeasureTool(const TOOL_EVENT &aEvent)
Launches a tool to measure between points
Definition: edit_tool.cpp:1131
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:169
KIGFX::PCB_VIEW * view() const
Definition: pcb_tool.h:132
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:387
DLIST< MODULE > m_Modules
Definition: class_board.h:245
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:227
Class TOOL_ACTION.
Definition: tool_action.h:46
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:375
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Function OnlyType Creates a functor that tests if the selected items are only of given type...
const wxSize & GetDelta() const
Definition: class_pad.h:272
OPT< VECTOR2D > GetPoint() const
Function GetPoint() Returns picked point.
Definition: picker_tool.h:77
void SetAuxAxes(bool aEnable, const VECTOR2I &aOrigin=VECTOR2I(0, 0), bool aEnableDiagonal=false)
Definition: grid_helper.cpp:99
static wxPoint mirrorPointX(const wxPoint &aPoint, const wxPoint &aMirrorPoint)
Definition: edit_tool.cpp:697
static TOOL_ACTION positionRelative
Activation of the position relative tool.
Definition: pcb_actions.h:239
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
void Mirror(const wxPoint &aCentre, bool aMirrorAroundXAxis)
Mirror text position in footprint edition the text itself is not mirrored, and the layer not modified...
int editFootprintInFpEditor(const TOOL_EVENT &aEvent)
Definition: edit_tool.cpp:1275
bool IsHover() const
Definition: selection.h:66
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:401
TOOL_MANAGER * GetManager() const
Function GetManager() Returns the instance of TOOL_MANAGER that takes care of the tool...
Definition: tool_base.h:144
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:281
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1331
void Activate()
Function Activate() Runs the tool.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Function Add() Adds a VIEW_ITEM to the view.
Definition: pcb_view.cpp:48
int Size() const
Returns the number of selected parts.
Definition: selection.h:112
void SetX0(int x)
Definition: class_pad.h:266
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:1330
Module description (excepted pads)
Definition: colors.h:45
static void FootprintFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
Function FootprintFilter()
Definition: edit_tool.cpp:1087
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
bool HasReferencePoint() const
Definition: selection.h:173
static TOOL_ACTION remove
Deleting a BOARD_ITEM.
Definition: pcb_actions.h:123
const wxPoint GetPosition() const override
Definition: class_pad.h:220
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
EDGE_MODULE class definition.
void postPushAction(BOARD_ITEM *new_item) override
Definition: edit_tool.cpp:1058
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
VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:67
EDA_ITEM * GetTopLeftModule() const
Definition: selection.cpp:126
int Duplicate(const TOOL_EVENT &aEvent)
Function Duplicate()
Definition: edit_tool.cpp:924
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:74
const wxPoint GetPosition() const override
Definition: class_module.h:175
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:712
MOVE_EXACT_ANCHOR anchor
#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:368
const wxPoint & GetOffset() const
Definition: class_pad.h:278
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:271
timestamp_t GetTimeStamp() const
Definition: base_struct.h:231
PCB_EDIT_FRAME::OnResetModuleTextSizes PCB_EDIT_FRAME::OnSelectOptionToolbar PCB_EDIT_FRAME::OnSelectOptionToolbar PCB_EDIT_FRAME::OnSelectOptionToolbar PCB_EDIT_FRAME::OnSelectOptionToolbar ID_PCB_MEASUREMENT_TOOL
Definition: pcbframe.cpp:259
bool Apply(COMMIT &aCommit)
Applies values from the dialog to the selected items.
void prePushAction(BOARD_ITEM *aItem) override
Definition: edit_tool.cpp:1042
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:460
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:230
Color has changed.
Definition: view_item.h:57
BOARD * board() const
Definition: pcb_tool.h:135
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aAddToBoard=false)
const wxPoint GetCenter() const