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-2015 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
6  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  * Copyright (C) 2017 KiCad Developers, see CHANGELOG.TXT for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #include <limits>
28 
29 #include <class_board.h>
30 #include <class_module.h>
31 #include <class_edge_mod.h>
32 #include <class_zone.h>
33 #include <collectors.h>
34 #include <wxPcbStruct.h>
35 #include <kiway.h>
36 #include <class_draw_panel_gal.h>
37 #include <module_editor_frame.h>
38 #include <array_creator.h>
39 #include <pcbnew_id.h>
40 
41 #include <tool/tool_manager.h>
42 #include <view/view_controls.h>
43 #include <view/view.h>
45 #include <connectivity.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 "grid_helper.h"
58 
59 #include <router/router_tool.h>
60 
64 
65 #include <tools/tool_event_utils.h>
66 
68 
69 #include <board_commit.h>
70 
71 // Edit tool actions
72 TOOL_ACTION PCB_ACTIONS::editFootprintInFpEditor( "pcbnew.InteractiveEdit.editFootprintInFpEditor",
74  _( "Open in Footprint Editor" ),
75  _( "Opens the selected footprint in the Footprint Editor" ),
76  module_editor_xpm );
77 
78 TOOL_ACTION PCB_ACTIONS::copyPadToSettings( "pcbnew.InteractiveEdit.copyPadToSettings",
79  AS_GLOBAL, 0,
80  _( "Copy Pad Settings to Current Settings" ),
81  _( "Copies the properties of selected pad to the current template pad settings." ) );
82 
83 TOOL_ACTION PCB_ACTIONS::copySettingsToPads( "pcbnew.InteractiveEdit.copySettingsToPads",
84  AS_GLOBAL, 0,
85  _( "Copy Current Settings to Pads" ),
86  _( "Copies the current template pad settings to the selected pad(s)." ) );
87 
88 TOOL_ACTION PCB_ACTIONS::globalEditPads( "pcbnew.InteractiveEdit.globalPadEdit",
89  AS_GLOBAL, 0,
90  _( "Global Pad Edition" ),
91  _( "Changes pad properties globally." ), push_pad_settings_xpm );
92 
93 TOOL_ACTION PCB_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
94  AS_GLOBAL, 0,
95  _( "Edit Activate" ), "", move_xpm, AF_ACTIVATE );
96 
97 TOOL_ACTION PCB_ACTIONS::move( "pcbnew.InteractiveEdit.move",
99  _( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE );
100 
101 TOOL_ACTION PCB_ACTIONS::duplicate( "pcbnew.InteractiveEdit.duplicate",
103  _( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_xpm );
104 
105 TOOL_ACTION PCB_ACTIONS::duplicateIncrement( "pcbnew.InteractiveEdit.duplicateIncrementPads",
107  _( "Duplicate" ), _( "Duplicates the selected item(s), incrementing pad numbers" ) );
108 
109 TOOL_ACTION PCB_ACTIONS::moveExact( "pcbnew.InteractiveEdit.moveExact",
111  _( "Move Exactly" ), _( "Moves the selected item(s) by an exact amount" ),
112  move_exactly_xpm );
113 
114 TOOL_ACTION PCB_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray",
116  _( "Create Array" ), _( "Create array" ), array_xpm, AF_ACTIVATE );
117 
118 TOOL_ACTION PCB_ACTIONS::rotateCw( "pcbnew.InteractiveEdit.rotateCw",
119  AS_GLOBAL, MD_SHIFT + 'R',
120  _( "Rotate Clockwise" ), _( "Rotates selected item(s) clockwise" ),
121  rotate_cw_xpm, AF_NONE, (void*) -1 );
122 
123 TOOL_ACTION PCB_ACTIONS::rotateCcw( "pcbnew.InteractiveEdit.rotateCcw",
125  _( "Rotate Counterclockwise" ), _( "Rotates selected item(s) counterclockwise" ),
126  rotate_ccw_xpm, AF_NONE, (void*) 1 );
127 
128 TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
130  _( "Flip" ), _( "Flips selected item(s)" ), swap_layer_xpm );
131 
132 TOOL_ACTION PCB_ACTIONS::mirror( "pcbnew.InteractiveEdit.mirror",
133  AS_GLOBAL, 0,
134  _( "Mirror" ), _( "Mirrors selected item" ), mirror_h_xpm );
135 
136 TOOL_ACTION PCB_ACTIONS::remove( "pcbnew.InteractiveEdit.remove",
138  _( "Delete" ), _( "Deletes selected item(s)" ), delete_xpm,
139  AF_NONE, (void*) REMOVE_FLAGS::NORMAL );
140 
141 TOOL_ACTION PCB_ACTIONS::removeAlt( "pcbnew.InteractiveEdit.removeAlt",
143  _( "Delete (Alternative)" ), _( "Deletes selected item(s)" ), delete_xpm,
144  AF_NONE, (void*) REMOVE_FLAGS::ALT );
145 
146 TOOL_ACTION PCB_ACTIONS::exchangeFootprints( "pcbnew.InteractiveEdit.ExchangeFootprints",
147  AS_GLOBAL, 0,
148  _( "Exchange Footprint" ), _( "Change the footprint used for modules" ),
149  exchange_xpm );
150 
151 TOOL_ACTION PCB_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
153  _( "Properties" ), _( "Displays item properties dialog" ), config_xpm );
154 
155 TOOL_ACTION PCB_ACTIONS::selectionModified( "pcbnew.InteractiveEdit.ModifiedSelection",
156  AS_GLOBAL, 0,
157  "", "", nullptr, AF_NOTIFY );
158 
159 TOOL_ACTION PCB_ACTIONS::measureTool( "pcbnew.InteractiveEdit.measureTool",
160  AS_GLOBAL, MD_CTRL + MD_SHIFT + 'M',
161  _( "Measuring tool" ), _( "Interactively measure distance between points" ),
162  nullptr, AF_ACTIVATE );
163 
164 static wxPoint getAnchorPoint( const SELECTION &selection, const MOVE_PARAMETERS &params )
165 {
166  wxPoint anchorPoint;
167 
168  if( params.origin == RELATIVE_TO_CURRENT_POSITION )
169  {
170  return wxPoint( 0, 0 );
171  }
172 
173  // set default anchor
174  VECTOR2I rp = selection.GetCenter();
175  anchorPoint = wxPoint( rp.x, rp.y );
176 
177  // If the anchor is not ANCHOR_FROM_LIBRARY then the user applied an override.
178  // Also run through this block if only one item is slected because it may be a module,
179  // in which case we want something different than the center of the selection
180  if( ( params.anchor != ANCHOR_FROM_LIBRARY ) || ( selection.GetSize() == 1 ) )
181  {
182  BOARD_ITEM* topLeftItem = static_cast<BOARD_ITEM*>( selection.GetTopLeftModule() );
183 
184  // no module found if the GetTopLeftModule() returns null
185  if( topLeftItem != nullptr )
186  {
187  if( topLeftItem->Type() == PCB_MODULE_T )
188  {
189  // Cast to module to allow access to the pads
190  MODULE* mod = static_cast<MODULE*>( topLeftItem );
191 
192  switch( params.anchor )
193  {
194  case ANCHOR_FROM_LIBRARY:
195  anchorPoint = mod->GetPosition();
196  break;
197 
198  case ANCHOR_TOP_LEFT_PAD:
199  topLeftItem = mod->GetTopLeftPad();
200  break;
201 
203  anchorPoint = mod->GetFootprintRect().GetCenter();
204  break;
205  }
206  }
207 
208  if( topLeftItem->Type() == PCB_PAD_T )
209  {
210  if( static_cast<D_PAD*>( topLeftItem )->GetAttribute() == PAD_ATTRIB_SMD )
211  {
212  // Use the top left corner of SMD pads as an anchor instead of the center
213  anchorPoint = topLeftItem->GetBoundingBox().GetPosition();
214  }
215  else
216  {
217  anchorPoint = topLeftItem->GetPosition();
218  }
219  }
220  }
221  else // no module found in the selection
222  {
223  // in a selection of non-modules
224  if( params.anchor == ANCHOR_TOP_LEFT_PAD )
225  {
226  // approach the top left pad override for non-modules by using the position of
227  // the topleft item as an anchor
228  topLeftItem = static_cast<BOARD_ITEM*>( selection.GetTopLeftItem() );
229  anchorPoint = topLeftItem->GetPosition();
230  }
231  }
232  }
233 
234  return anchorPoint;
235 }
236 
237 
238 
239 
241  PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
242  m_dragging( false )
243 {
244 }
245 
246 
248 {
249  m_dragging = false;
250 
251  if( aReason != RUN )
252  m_commit.reset( new BOARD_COMMIT( this ) );
253 }
254 
255 
257 {
258  // Find the selection tool, so they can cooperate
259  m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
260 
261  if( !m_selectionTool )
262  {
263  DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
264  return false;
265  }
266 
267  auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
268  return m_editModules;
269  };
270 
271  auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
273 
274  // Add context menu entries that are displayed when selection tool is active
276 
286 
291 
292  // Mirror only available in modedit
293  menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
294 
295  // Footprint actions
297  singleModuleCondition );
299  singleModuleCondition );
300 
301  m_offset.x = 0;
302  m_offset.y = 0;
303 
304  return true;
305 }
306 
307 
308 bool EDIT_TOOL::invokeInlineRouter( int aDragMode )
309 {
310  TRACK* track = uniqueSelected<TRACK>();
311  VIA* via = uniqueSelected<VIA>();
312 
313 
314 
315  if( track || via )
316  {
317  auto theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
318  assert( theRouter );
319 
320  if( !theRouter->Router()->Settings().InlineDragEnabled() )
321  return false;
322 
324  return true;
325  }
326 
327  return false;
328 }
329 
330 int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
331 {
332  int mode = PNS::DM_ANY;
333 
334  if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
335  mode |= PNS::DM_FREE_ANGLE;
336 
337  invokeInlineRouter( mode );
338 
339  return 0;
340 }
341 
342 int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
343 {
345  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
346 
347  VECTOR2I originalCursorPos = controls->GetCursorPosition();
348 
349  // Be sure that there is at least one item that we can modify. If nothing was selected before,
350  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
351  auto& selection = m_selectionTool->RequestSelection( SELECTION_DEFAULT );
352 
353  if( selection.Empty() )
354  return 0;
355 
356  bool unselect = selection.IsHover();
357 
358  Activate();
359 
360  m_dragging = false; // Are selected items being dragged?
361  bool restore = false; // Should items' state be restored when finishing the tool?
362  bool lockOverride = false;
363 
364  controls->ShowCursor( true );
365  controls->SetSnapping( true );
366  controls->SetAutoPan( true );
367 
368  // cumulative translation
369  wxPoint totalMovement( 0, 0 );
370 
371  GRID_HELPER grid( editFrame );
372  OPT_TOOL_EVENT evt = aEvent;
373 
374  // Main loop: keep receiving events
375  do
376  {
377  bool matchingAction = evt->IsAction( &PCB_ACTIONS::editActivate )
378  || evt->IsAction( &PCB_ACTIONS::move );
379 
380  if( matchingAction
381  || evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
382  {
383  if( selection.Empty() )
384  break;
385 
386  auto curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
387 
388  if( m_dragging && evt->Category() == TC_MOUSE )
389  {
390  m_cursor = grid.BestSnapAnchor( evt->Position(), curr_item );
391  controls->ForceCursorPosition( true, m_cursor );
392 
393  wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) - curr_item->GetPosition();
394  totalMovement += movement;
395 
396  // Drag items to the current cursor position
397  for( auto item : selection )
398  static_cast<BOARD_ITEM*>( item )->Move( movement + m_offset );
399  }
400  else if( !m_dragging ) // Prepare to start dragging
401  {
402  bool invokedRouter = false;
403 
404  if ( !evt->IsAction( &PCB_ACTIONS::move ) )
405  invokedRouter = invokeInlineRouter( PNS::DM_ANY );
406 
407  if( !invokedRouter )
408  {
409  // deal with locked items (override lock or abort the operation)
411 
412  if( lockFlags == SELECTION_LOCKED )
413  break;
414  else if( lockFlags == SELECTION_LOCK_OVERRIDE )
415  lockOverride = true;
416 
417  // Save items, so changes can be undone
418  for( auto item : selection )
419  m_commit->Modify( item );
420 
421  m_cursor = controls->GetCursorPosition();
422 
423  if( selection.Size() == 1 )
424  {
425  // Set the current cursor position to the first dragged item origin, so the
426  // movement vector could be computed later
427  m_cursor = grid.BestDragOrigin( originalCursorPos, curr_item );
428  grid.SetAuxAxes( true, m_cursor );
429  }
430  else
431  {
432  m_cursor = grid.Align( m_cursor );
433  }
434 
435  controls->ForceCursorPosition( true, m_cursor );
436  controls->WarpCursor( m_cursor, true );
437 
438  VECTOR2I o = VECTOR2I( curr_item->GetPosition() );
439  m_offset.x = o.x - m_cursor.x;
440  m_offset.y = o.y - m_cursor.y;
441 
442  controls->SetAutoPan( true );
443  m_dragging = true;
444  }
445  }
446 
448  }
449 
450  else if( evt->IsCancel() || evt->IsActivate() )
451  {
452  restore = true; // Cancelling the tool means that items have to be restored
453  break; // Finish
454  }
455 
456  else if( evt->Action() == TA_UNDO_REDO_PRE )
457  {
458  unselect = true;
459  break;
460  }
461 
462  // Dispatch TOOL_ACTIONs
463  else if( evt->Category() == TC_COMMAND )
464  {
465  wxPoint modPoint = getModificationPoint( selection );
466 
467  if( evt->IsAction( &PCB_ACTIONS::remove ) )
468  {
469  // exit the loop, as there is no further processing for removed items
470  break;
471  }
472  else if( evt->IsAction( &PCB_ACTIONS::duplicate ) )
473  {
474  // On duplicate, stop moving this item
475  // The duplicate tool should then select the new item and start
476  // a new move procedure
477  break;
478  }
479  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
480  {
481  // Can't do this, because the selection will then contain
482  // stale pointers and it will all go horribly wrong...
483  //editFrame->RestoreCopyFromUndoList( dummy );
484  //
485  // So, instead, reset the position manually
486  for( auto item : selection )
487  {
488  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
489  i->SetPosition( i->GetPosition() - totalMovement );
490 
491  // And what about flipping and rotation?
492  // for now, they won't be undone, but maybe that is how
493  // it should be, so you can flip and move exact in the
494  // same action?
495  }
496 
497  // This causes a double event, so we will get the dialogue
498  // correctly, somehow - why does Rotate not?
499  //MoveExact( aEvent );
500  break; // exit the loop - we move exactly, so we have finished moving
501  }
502 
503  // TODO check if the following can be removed
504  if( m_dragging && !selection.Empty() )
505  {
506  // Update dragging offset (distance between cursor and the first dragged item)
507  m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
508  }
509  }
510 
511  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
512  {
513  if( !lockOverride )
514  break; // Finish
515 
516  lockOverride = false;
517  }
518  } while( ( evt = Wait() ) ); //Should be assignment not equality test
519 
520  controls->ForceCursorPosition( false );
521  controls->ShowCursor( false );
522  controls->SetSnapping( false );
523  controls->SetAutoPan( false );
524 
525  m_dragging = false;
526  m_offset.x = 0;
527  m_offset.y = 0;
528 
529  if( unselect || restore )
531 
532  if( restore )
533  m_commit->Revert();
534  else
535  m_commit->Push( _( "Drag" ) );
536 
537  return 0;
538 }
539 
541 {
542  if ( selection.Size() == 1 && frame()->Settings().m_editActionChangesTrackWidth )
543  {
544  auto item = static_cast<BOARD_ITEM *>( selection[0] );
545 
546  m_commit->Modify( item );
547 
548  if( auto via = dyn_cast<VIA*>( item ) )
549  {
550  int new_width, new_drill;
551 
552  if( via->GetViaType() == VIA_MICROVIA )
553  {
554  auto net = via->GetNet();
555 
556  new_width = net->GetMicroViaSize();
557  new_drill = net->GetMicroViaDrillSize();
558  }
559  else
560  {
561  new_width = board()->GetDesignSettings().GetCurrentViaSize();
562  new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
563  }
564 
565  via->SetDrill( new_drill );
566  via->SetWidth( new_width );
567  }
568  else if ( auto track = dyn_cast<TRACK*>( item ) )
569  {
570  int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
571  track->SetWidth( new_width );
572  }
573 
574  m_commit->Push( _("Edit track width/via size") );
575  return true;
576  }
577 
578  return false;
579 }
580 
581 int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
582 {
583  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
584 
586 
587  if( selection.Empty() )
588  return 0;
589 
590  // Tracks & vias are treated in a special way:
592  {
593  if ( !changeTrackWidthOnClick( selection ) )
594  {
595  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection );
596 
597  if( dlg.ShowModal() )
598  {
599  dlg.Apply( *m_commit );
600  m_commit->Push( _( "Edit track/via properties" ) );
601  }
602  }
603  }
604  else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
605  {
606  // Display properties dialog
607  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
608 
609  // Some of properties dialogs alter pointers, so we should deselect them
611 
612  // Store flags, so they can be restored later
613  STATUS_FLAGS flags = item->GetFlags();
614  item->ClearFlags();
615 
616  // Do not handle undo buffer, it is done by the properties dialogs @todo LEGACY
617  // Display properties dialog provided by the legacy canvas frame
618  editFrame->OnEditItemRequest( NULL, item );
619 
621  item->SetFlags( flags );
622  }
623 
624  if( selection.IsHover() )
626 
627  return 0;
628 }
629 
630 
631 int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
632 {
633  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
634 
635  const auto& selection = m_selectionTool->RequestSelection();
636 
637  if( selection.Empty() )
638  return 0;
639 
641  return 0;
642 
643  wxPoint modPoint = getModificationPoint( selection );
644  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
645 
646  for( auto item : selection )
647  {
648  m_commit->Modify( item );
649  static_cast<BOARD_ITEM*>( item )->Rotate( modPoint, rotateAngle );
650  }
651 
652  // Update the dragging point offset
653  m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
654 
655  if( !m_dragging )
656  m_commit->Push( _( "Rotate" ) );
657 
658  if( selection.IsHover() && !m_dragging )
660 
662 
663  return 0;
664 }
665 
666 
670 static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
671 {
672  wxPoint mirrored = aPoint;
673 
674  mirrored.x -= aMirrorPoint.x;
675  mirrored.x = -mirrored.x;
676  mirrored.x += aMirrorPoint.x;
677 
678  return mirrored;
679 }
680 
681 
685 static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
686 {
687  wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
688 
689  aPad.SetPosition( tmpPt );
690 
691  aPad.SetX0( aPad.GetPosition().x );
692 
693  tmpPt = aPad.GetOffset();
694  tmpPt.x = -tmpPt.x;
695  aPad.SetOffset( tmpPt );
696 
697  auto tmpz = aPad.GetDelta();
698  tmpz.x = -tmpz.x;
699  aPad.SetDelta( tmpz );
700 
701  aPad.SetOrientation( -aPad.GetOrientation() );
702 }
703 
704 
705 int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
706 {
707  const auto& selection = m_selectionTool->RequestSelection();
708 
710  return 0;
711 
712  if( selection.Empty() )
713  return 0;
714 
715  wxPoint mirrorPoint = getModificationPoint( selection );
716 
717  for( auto item : selection )
718  {
719  // only modify items we can mirror
720  switch( item->Type() )
721  {
722  case PCB_MODULE_EDGE_T:
723  case PCB_MODULE_TEXT_T:
724  case PCB_PAD_T:
725  m_commit->Modify( item );
726  break;
727  default:
728  continue;
729  }
730 
731  // modify each object as necessary
732  switch( item->Type() )
733  {
734  case PCB_MODULE_EDGE_T:
735  {
736  auto& edge = static_cast<EDGE_MODULE&>( *item );
737  edge.Mirror( mirrorPoint, false );
738  break;
739  }
740 
741  case PCB_MODULE_TEXT_T:
742  {
743  auto& modText = static_cast<TEXTE_MODULE&>( *item );
744  modText.Mirror( mirrorPoint, false );
745  break;
746  }
747 
748  case PCB_PAD_T:
749  {
750  auto& pad = static_cast<D_PAD&>( *item );
751  mirrorPadX( pad, mirrorPoint );
752  break;
753  }
754 
755  default:
756  // it's likely the commit object is wrong if you get here
757  assert( false );
758  break;
759  }
760  }
761 
762  if( !m_dragging )
763  m_commit->Push( _( "Mirror" ) );
764 
765  if( selection.IsHover() && !m_dragging )
767 
769 
770  return 0;
771 }
772 
773 
774 int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
775 {
776  const auto& selection = m_selectionTool->RequestSelection();
777 
779  return 0;
780 
781  if( selection.Empty() )
782  return 0;
783 
784  wxPoint modPoint = getModificationPoint( selection );
785 
786  for( auto item : selection )
787  {
788  m_commit->Modify( item );
789  static_cast<BOARD_ITEM*>( item )->Flip( modPoint );
790  }
791 
792  // Update the dragging point offset
793  m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
794 
795  if( !m_dragging )
796  m_commit->Push( _( "Flip" ) );
797 
798  if( selection.IsHover() && !m_dragging )
800 
802 
803  return 0;
804 }
805 
806 
807 int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
808 {
809  // get a copy instead of reference (as we're going to clear the selectio before removing items)
811 
813  return 0;
814 
815  if( selection.Empty() )
816  return 0;
817 
818  // is this "alternative" remove?
819  const bool isAlt = aEvent.Parameter<intptr_t>() ==
821 
822  // in "alternative" mode, deletion is not just a simple list
823  // of selected items, it is:
824  // - whole tracks, not just segments
825  if( isAlt && selection.IsHover() )
826  {
829  }
830 
831  // As we are about to remove items, they have to be removed from the selection first
833 
834  for( auto item : selection )
835  {
836  m_commit->Remove( item );
837  }
838 
839  m_commit->Push( _( "Delete" ) );
840 
841  return 0;
842 }
843 
844 
845 int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
846 {
847  const auto& selection = m_selectionTool->RequestSelection();
848 
850  return 0;
851 
852  if( selection.Empty() )
853  return 0;
854 
855  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
856 
857  MOVE_PARAMETERS params;
859 
860  DIALOG_MOVE_EXACT dialog( editFrame, params );
861  int ret = dialog.ShowModal();
862 
863  if( ret == wxID_OK )
864  {
865  VECTOR2I rp = selection.GetCenter();
866  wxPoint rotPoint( rp.x, rp.y );
867 
868  wxPoint anchorPoint = getAnchorPoint( selection, params );
869 
870  wxPoint finalMoveVector = params.translation - anchorPoint;
871 
872  // Make sure the rotation is from the right reference point
873  rotPoint += finalMoveVector;
874 
875  for( auto item : selection )
876  {
877  m_commit->Modify( item );
878  static_cast<BOARD_ITEM*>( item )->Move( finalMoveVector );
879  static_cast<BOARD_ITEM*>( item )->Rotate( rotPoint, params.rotation );
880 
881  if( !m_dragging )
882  getView()->Update( item );
883  }
884 
885  m_commit->Push( _( "Move exact" ) );
886 
887  if( selection.IsHover() )
889 
891  }
892 
893  return 0;
894 }
895 
896 
897 int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
898 {
899  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
900 
901  // Be sure that there is at least one item that we can modify
903 
904  if( selection.Empty() )
905  return 0;
906 
907  // we have a selection to work on now, so start the tool process
908  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
909 
910  std::vector<BOARD_ITEM*> new_items;
911  new_items.reserve( selection.Size() );
912 
913  BOARD_ITEM* orig_item = nullptr;
914  BOARD_ITEM* dupe_item = nullptr;
915 
916  // Each selected item is duplicated and pushed to new_items list
917  // Old selection is cleared, and new items are then selected.
918  for( auto item : selection )
919  {
920  if( !item )
921  continue;
922 
923  orig_item = static_cast<BOARD_ITEM*>( item );
924 
925  if( m_editModules )
926  {
927  dupe_item = editFrame->GetBoard()->m_Modules->Duplicate( orig_item, increment );
928  }
929  else
930  {
931 #if 0
932  // @TODO: see if we allow zone duplication here
933  // Duplicate zones is especially tricky (overlaping zones must be merged)
934  // so zones are not duplicated
935  if( item->Type() != PCB_ZONE_AREA_T )
936 #endif
937  dupe_item = editFrame->GetBoard()->Duplicate( orig_item );
938  }
939 
940  if( dupe_item )
941  {
942  // Clear the selection flag here, otherwise the SELECTION_TOOL
943  // will not properly select it later on
944  dupe_item->ClearSelected();
945 
946  new_items.push_back( dupe_item );
947  m_commit->Add( dupe_item );
948  }
949  }
950 
951  // Clear the old selection first
953 
954  // Select the new items
955  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
956 
957  // record the new items as added
958  if( !selection.Empty() )
959  {
960  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
961  (int) new_items.size() ) );
962 
963  // If items were duplicated, pick them up
964  // this works well for "dropping" copies around and pushes the commit
966  Main( evt );
967  }
968 
969  return 0;
970 }
971 
972 
974 {
975 public:
976 
977  GAL_ARRAY_CREATOR( PCB_BASE_FRAME& editFrame, bool editModules,
978  const SELECTION& selection ):
979  ARRAY_CREATOR( editFrame ),
980  m_editModules( editModules ),
981  m_selection( selection )
982  {}
983 
984 private:
985 
986  int getNumberOfItemsToArray() const override
987  {
988  // only handle single items
989  return m_selection.Size();
990  }
991 
992  BOARD_ITEM* getNthItemToArray( int n ) const override
993  {
994  return static_cast<BOARD_ITEM*>( m_selection[n] );
995  }
996 
997  BOARD* getBoard() const override
998  {
999  return m_parent.GetBoard();
1000  }
1001 
1002  MODULE* getModule() const override
1003  {
1004  // Remember this is valid and used only in the module editor.
1005  // in board editor, the parent of items is usually the board.
1006  return m_editModules ? m_parent.GetBoard()->m_Modules.GetFirst() : NULL;
1007  }
1008 
1009  wxPoint getRotationCentre() const override
1010  {
1011  const VECTOR2I rp = m_selection.GetCenter();
1012  return wxPoint( rp.x, rp.y );
1013  }
1014 
1015  void prePushAction( BOARD_ITEM* aItem ) override
1016  {
1017  // Because aItem is/can be created from a selected item, and inherits from
1018  // it this state, reset the selected stated of aItem:
1019  aItem->ClearSelected();
1020 
1021  if( aItem->Type() == PCB_MODULE_T )
1022  {
1023  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1024  {
1025  item->ClearSelected();
1026  }
1027  );
1028  }
1029  }
1030 
1031  void postPushAction( BOARD_ITEM* new_item ) override
1032  {
1033  }
1034 
1035  void finalise() override
1036  {
1037  }
1038 
1041 };
1042 
1043 
1045 {
1046  const auto& selection = m_selectionTool->RequestSelection();
1047 
1048  if( selection.Empty() )
1049  return 0;
1050 
1051  // we have a selection to work on now, so start the tool process
1052  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
1053  GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
1054  array_creator.Invoke();
1055 
1056  return 0;
1057 }
1058 
1059 
1061 {
1062  const auto& selection = m_selectionTool->RequestSelection();
1063 
1064  if( selection.Empty() )
1065  return 0;
1066 
1067  MODULE* mod = selection.FirstOfKind<MODULE> ();
1068 
1069  if( !mod )
1070  return 0;
1071 
1072  frame()->SetCurItem( mod );
1073 
1074  // Footprint exchange could remove modules, so they have to be
1075  // removed from the selection first
1077 
1078  // invoke the exchange dialog process
1079  {
1080  DIALOG_EXCHANGE_MODULE dialog( frame(), mod );
1081  dialog.ShowQuasiModal();
1082  }
1083 
1084  // The current item can be deleted by exchange module, and the
1085  // selection is emptied, so remove current item from frame info area
1086  frame()->SetCurItem( nullptr );
1087 
1088  return 0;
1089 }
1090 
1091 
1093 {
1094  auto& view = *getView();
1095  auto& controls = *getViewControls();
1096 
1097  Activate();
1100  wxCURSOR_PENCIL, _( "Measure distance" ) );
1101 
1103 
1104  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr );
1105 
1106  view.Add( &ruler );
1107  view.SetVisible( &ruler, false );
1108 
1109  bool originSet = false;
1110 
1111  controls.ShowCursor( true );
1112  controls.SetSnapping( true );
1113 
1114  while( auto evt = Wait() )
1115  {
1116  const VECTOR2I cursorPos = controls.GetCursorPosition();
1117 
1118  if( evt->IsCancel() || evt->IsActivate() )
1119  {
1120  break;
1121  }
1122 
1123  // click or drag starts
1124  else if( !originSet &&
1125  ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
1126  {
1127  if( !evt->IsDrag( BUT_LEFT ) )
1128  {
1129  twoPtMgr.SetOrigin( cursorPos );
1130  twoPtMgr.SetEnd( cursorPos );
1131  }
1132 
1133  controls.CaptureCursor( true );
1134  controls.SetAutoPan( true );
1135 
1136  originSet = true;
1137  }
1138 
1139  else if( !originSet && evt->IsMotion() )
1140  {
1141  // make sure the origin is set before a drag starts
1142  // otherwise you can miss a step
1143  twoPtMgr.SetOrigin( cursorPos );
1144  twoPtMgr.SetEnd( cursorPos );
1145  }
1146 
1147  // second click or mouse up after drag ends
1148  else if( originSet &&
1149  ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
1150  {
1151  originSet = false;
1152 
1153  controls.SetAutoPan( false );
1154  controls.CaptureCursor( false );
1155 
1156  view.SetVisible( &ruler, false );
1157  }
1158 
1159  // move or drag when origin set updates rules
1160  else if( originSet &&
1161  ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
1162  {
1163  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
1164  twoPtMgr.SetEnd( cursorPos );
1165 
1166  view.SetVisible( &ruler, true );
1167  view.Update( &ruler, KIGFX::GEOMETRY );
1168  }
1169 
1170  else if( evt->IsClick( BUT_RIGHT ) )
1171  {
1172  GetManager()->PassEvent();
1173  }
1174  }
1175 
1176  view.SetVisible( &ruler, false );
1177  view.Remove( &ruler );
1178 
1179  frame()->SetNoToolSelected();
1180 
1181  return 0;
1182 }
1183 
1184 
1186 {
1187  Go( &EDIT_TOOL::Main, PCB_ACTIONS::editActivate.MakeEvent() );
1188  Go( &EDIT_TOOL::Main, PCB_ACTIONS::move.MakeEvent() );
1189  Go( &EDIT_TOOL::Drag, PCB_ACTIONS::drag45Degree.MakeEvent() );
1191  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
1192  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCcw.MakeEvent() );
1193  Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
1194  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::remove.MakeEvent() );
1195  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::removeAlt.MakeEvent() );
1201  Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
1205 }
1206 
1207 
1209 {
1210  if( aSelection.Size() == 1 )
1211  {
1212  return static_cast<BOARD_ITEM*>( aSelection.Front() )->GetPosition() - m_offset;
1213  }
1214  else
1215  {
1216  // If EDIT_TOOL is not currently active then it means that the cursor position is not
1217  // updated, so we have to fetch the latest value
1218  if( m_toolMgr->GetCurrentToolId() != m_toolId )
1220 
1221  return wxPoint( m_cursor.x, m_cursor.y );
1222  }
1223 }
1224 
1225 
1227 {
1228  const auto& selection = m_selectionTool->RequestSelection();
1229 
1230  if( selection.Empty() )
1231  return 0;
1232 
1233  MODULE* mod = selection.FirstOfKind<MODULE>();
1234 
1235  if( !mod )
1236  return 0;
1237 
1238  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1239 
1240  editFrame->SetCurItem( mod );
1241 
1242  if( editFrame->GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
1243  {
1244  editFrame->GetCurItem()->SetTimeStamp( GetNewTimeStamp() );
1245  editFrame->OnModify();
1246  }
1247 
1249 
1250  editor->Load_Module_From_BOARD( (MODULE*) editFrame->GetCurItem() );
1251  editFrame->SetCurItem( NULL ); // the current module could be deleted by
1252 
1253  editor->Show( true );
1254  editor->Raise(); // Iconize( false );
1255 
1256  if( selection.IsHover() )
1258 
1259  return 0;
1260 }
1261 
1262 
1263 template<class T>
1265 {
1266  auto& selection = m_selectionTool->RequestSelection( SELECTION_DEFAULT );
1267 
1268  if( selection.Size() != 1 )
1269  return nullptr;
1270 
1271  auto item = selection[0];
1272  return dyn_cast<T*>( item );
1273 }
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)
wxPoint getModificationPoint(const SELECTION &aSelection)
Returns the right modification point (e.g.
Definition: edit_tool.cpp:1208
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:1185
VECTOR2I m_cursor
Last cursor position (needed for getModificationPoint() to avoid changes of edit reference point)...
Definition: edit_tool.h:154
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
int Main(const TOOL_EVENT &aEvent)
Function Main()
Definition: edit_tool.cpp:342
KIGFX::VIEW * view() const
Definition: pcb_tool.h:123
Definition of class FOOTPRINT_EDIT_FRAME.
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:255
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:164
int Properties(const TOOL_EVENT &aEvent)
Function Edit()
Definition: edit_tool.cpp:581
int Rotate(const TOOL_EVENT &aEvent)
Function Rotate()
Definition: edit_tool.cpp:631
TOOL_BASE * FindTool(int aId) const
Function FindTool() Searches for a tool with given ID.
static TOOL_ACTION move
move an item
Definition: pcb_actions.h:90
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
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:1060
static TOOL_ACTION editActivate
Activation of the edit tool.
Definition: pcb_actions.h:87
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:294
int GetCurrentToolId() const
Returns id of the tool that is on the top of the active tools stack (was invoked the most recently)...
Definition: tool_manager.h:268
SELECTION & RequestSelection(int aFlags=SELECTION_DEFAULT)
Function RequestSelection()
static TOOL_ACTION globalEditPads
Definition: pcb_actions.h:382
virtual void SetPosition(const wxPoint &aPos)=0
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:213
T
enum T contains all this lexer's tokens.
void ClearSelected()
Definition: base_struct.h:231
VECTOR2I Align(const VECTOR2I &aPoint) const
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.
const wxPoint & GetPosition() const override
Definition: class_module.h:155
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
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:128
Tool is invoked after being inactive.
Definition: tool_base.h:82
TOOL_MENU & GetToolMenu()
EDA_ITEM * Front() const
Definition: selection.h:144
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:213
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aIncrementPadNumbers, bool aAddToModule=false)
Function Duplicate Duplicate a given item within the module, without adding to the board...
PCB_BASE_FRAME & m_parent
Definition: array_creator.h:61
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:59
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:114
void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:341
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:105
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
time_t GetNewTimeStamp()
Definition: common.cpp:166
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
Action activates a tool
Definition: tool_event.h:146
TOOL_ID m_toolId
Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
Definition: tool_base.h:208
MOVE_EXACT_ORIGIN origin
virtual const wxPoint & GetPosition() const =0
virtual void SetSnapping(bool aEnabled)
Function SetSnapping() Enables/disables snapping cursor to grid.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
static TOOL_ACTION selectConnection
Selects a connection between junctions.
Definition: pcb_actions.h:68
static int LegacyHotKey(int aHotKey)
Creates a hot key code that refers to a legacy hot key setting, instead of a particular key...
Definition: tool_action.h:174
BOARD * GetBoard() const
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:169
static TOOL_ACTION removeAlt
Definition: pcb_actions.h:124
Classes to handle copper zones.
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:54
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:127
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:102
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
VECTOR2I BestSnapAnchor(const VECTOR2I &aOrigin, BOARD_ITEM *aDraggedItem)
SELECTION_TOOL * m_selectionTool
Selection tool used for obtaining selected items
Definition: edit_tool.h:144
wxPoint m_offset
Offset from the dragged item's center (anchor)
Definition: edit_tool.h:150
static SELECTION_CONDITION Count(int aNumber)
Function Count Creates a functor that tests if the number of selected items is equal to the value giv...
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
int GetCurrentViaSize() const
Function GetCurrentViaSize.
static bool NotEmpty(const SELECTION &aSelection)
Function NotEmpty Tests if there are any items selected.
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:73
static TOOL_ACTION copyPadToSettings
Definition: pcb_actions.h:380
MODULE * getModule() const override
Definition: edit_tool.cpp:1002
static TOOL_ACTION selectionModified
Modified selection notification.
Definition: pcb_actions.h:108
void SetTimeStamp(time_t aNewTimeStamp)
Definition: base_struct.h:203
int Mirror(const TOOL_EVENT &aEvent)
Function Mirror.
Definition: edit_tool.cpp:705
Pcbnew hotkeys.
BOARD_ITEM * getNthItemToArray(int n) const override
Definition: edit_tool.cpp:992
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:111
void finalise() override
Definition: edit_tool.cpp:1035
static TOOL_ACTION copySettingsToPads
Definition: pcb_actions.h:381
void PassEvent()
Allows a tool to pass the already handled event to the next tool on the stack.
Definition: tool_manager.h:342
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:124
static TOOL_ACTION duplicate
Activation of the duplication tool.
Definition: pcb_actions.h:114
void Mirror(const wxPoint aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
class MODULE, a footprint
Definition: typeinfo.h:101
int Flip(const TOOL_EVENT &aEvent)
Function Flip()
Definition: edit_tool.cpp:774
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:117
virtual void WarpCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false) const =0
Function WarpCursor() If enabled (.
static TOOL_ACTION rotateCw
Rotation of selected objects clockwise.
Definition: pcb_actions.h:93
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, KIWAY_PLAYER *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:302
int getNumberOfItemsToArray() const override
Definition: edit_tool.cpp:986
wxPoint getRotationCentre() const override
Definition: edit_tool.cpp:1009
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:253
bool m_dragging
Flag determining if anything is being dragged right now
Definition: edit_tool.h:147
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...
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
SELECTION_LOCK_FLAGS
Definition: selection.h:184
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
T * uniqueSelected()
Function uniqueSelected()
Definition: edit_tool.cpp:1264
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:125
Class TOOL_EVENT.
Definition: tool_event.h:162
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:295
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:977
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty...
Definition: dlist.h:163
EDA_ITEM * GetTopLeftItem(bool onlyModules=false) const
unsigned STATUS_FLAGS
Definition: base_struct.h:144
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:256
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
Definition: view_controls.h:94
bool Load_Module_From_BOARD(MODULE *Module)
Function Load_Module_From_BOARD load in Modedit a footprint from the main board.
Definition: loadcmp.cpp:75
int Drag(const TOOL_EVENT &aEvent)
Function Drag()
Definition: edit_tool.cpp:330
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.
static TOOL_ACTION exchangeFootprints
Exchange footprints of modules.
Definition: pcb_actions.h:120
All active tools
Definition: tool_event.h:138
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:1389
BOARD * getBoard() const override
Definition: edit_tool.cpp:997
const SELECTION & m_selection
Definition: edit_tool.cpp:1040
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:206
D_PAD * GetTopLeftPad()
const wxPoint & GetPosition() const
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:36
time_t GetTimeStamp() const
Definition: base_struct.h:204
bool m_editModules
Definition: pcb_tool.h:128
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: edit_tool.cpp:247
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:30
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:86
static TOOL_ACTION rotateCcw
Rotation of selected objects counter-clockwise.
Definition: pcb_actions.h:96
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
int MoveExact(const TOOL_EVENT &aEvent)
Function MoveExact()
Definition: edit_tool.cpp:845
int Remove(const TOOL_EVENT &aEvent)
Function Remove()
Definition: edit_tool.cpp:807
static ROUTER * theRouter
Definition: pns_router.cpp:59
bool EditingModules() const
Definition: pcb_tool.h:91
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:99
virtual void SetNoToolSelected()
Select the ID_NO_TOOL_SELECTED id tool (Idle tool)
Definition: draw_frame.cpp:560
virtual void OnModify()
Function OnModify Virtual Must be called after a change in order to set the "modify" flag of the curr...
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:373
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:308
TOOL_EVENT MakeEvent() const
Function HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
void DisplayToolMsg(const wxString &msg)
Definition: draw_frame.cpp:497
int CreateArray(const TOOL_EVENT &aEvent)
Function CreateArray()
Definition: edit_tool.cpp:1044
bool changeTrackWidthOnClick(const SELECTION &selection)
Definition: edit_tool.cpp:540
Common, abstract interface for edit frames.
int MeasureTool(const TOOL_EVENT &aEvent)
Launches a tool to measure between points
Definition: edit_tool.cpp:1092
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
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:379
DLIST< MODULE > m_Modules
Definition: class_board.h:245
Class TOOL_ACTION.
Definition: tool_action.h:46
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:214
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:185
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:670
static TOOL_ACTION positionRelative
Activation of the position relative tool.
Definition: pcb_actions.h:236
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:1226
bool IsHover() const
Definition: selection.h:66
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:357
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:254
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1335
void Activate()
Function Activate() Runs the tool.
int Size() const
Returns the number of selected parts.
Definition: selection.h:112
void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:311
void SetX0(int x)
Definition: class_pad.h:179
Module description (excepted pads)
static TOOL_ACTION remove
Deleting a BOARD_ITEM.
Definition: pcb_actions.h:123
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
EDGE_MODULE class definition.
void postPushAction(BOARD_ITEM *new_item) override
Definition: edit_tool.cpp:1031
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:190
VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
EDA_ITEM * GetTopLeftModule() const
int Duplicate(const TOOL_EVENT &aEvent)
Function Duplicate()
Definition: edit_tool.cpp:897
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:71
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:685
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:360
const wxPoint & GetOffset() const
Definition: class_pad.h:191
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:184
PCB_EDIT_FRAME::OnResetModuleTextSizes PCB_EDIT_FRAME::OnSelectOptionToolbar PCB_EDIT_FRAME::OnSelectOptionToolbar PCB_EDIT_FRAME::OnSelectOptionToolbar PCB_EDIT_FRAME::OnSelectOptionToolbar ID_PCB_MEASUREMENT_TOOL
Definition: pcbframe.cpp:262
bool Apply(COMMIT &aCommit)
Applies values from the dialog to the selected items.
void prePushAction(BOARD_ITEM *aItem) override
Definition: edit_tool.cpp:1015
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
Color has changed.
Definition: view_item.h:57
BOARD * board() const
Definition: pcb_tool.h:126
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aAddToBoard=false)
const wxPoint GetCenter() const