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