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