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 <ratsnest_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 "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",
95  _( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE );
96 
97 TOOL_ACTION PCB_ACTIONS::duplicate( "pcbnew.InteractiveEdit.duplicate",
99  _( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_module_xpm );
100 
101 TOOL_ACTION PCB_ACTIONS::duplicateIncrement( "pcbnew.InteractiveEdit.duplicateIncrementPads",
103  _( "Duplicate" ), _( "Duplicates the selected item(s), incrementing pad numbers" ) );
104 
105 TOOL_ACTION PCB_ACTIONS::moveExact( "pcbnew.InteractiveEdit.moveExact",
107  _( "Move Exactly..." ), _( "Moves the selected item(s) by an exact amount" ),
108  move_module_xpm );
109 
110 TOOL_ACTION PCB_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray",
112  _( "Create Array" ), _( "Create array" ), array_module_xpm, AF_ACTIVATE );
113 
114 TOOL_ACTION PCB_ACTIONS::rotateCw( "pcbnew.InteractiveEdit.rotateCw",
115  AS_GLOBAL, MD_SHIFT + 'R',
116  _( "Rotate Clockwise" ), _( "Rotates selected item(s) clockwise" ),
117  rotate_cw_xpm, AF_NONE, (void*) -1 );
118 
119 TOOL_ACTION PCB_ACTIONS::rotateCcw( "pcbnew.InteractiveEdit.rotateCcw",
121  _( "Rotate Counter-clockwise" ), _( "Rotates selected item(s) counter-clockwise" ),
122  rotate_ccw_xpm, AF_NONE, (void*) 1 );
123 
124 TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
126  _( "Flip" ), _( "Flips selected item(s)" ), swap_layer_xpm );
127 
128 TOOL_ACTION PCB_ACTIONS::mirror( "pcbnew.InteractiveEdit.mirror",
129  AS_GLOBAL, 0,
130  _( "Mirror" ), _( "Mirrors selected item" ), mirror_h_xpm );
131 
132 TOOL_ACTION PCB_ACTIONS::remove( "pcbnew.InteractiveEdit.remove",
134  _( "Remove" ), _( "Deletes selected item(s)" ), delete_xpm,
135  AF_NONE, (void*) REMOVE_FLAGS::NORMAL );
136 
137 TOOL_ACTION PCB_ACTIONS::removeAlt( "pcbnew.InteractiveEdit.removeAlt",
139  _( "Remove (Alternative)" ), _( "Deletes selected item(s)" ), delete_xpm,
140  AF_NONE, (void*) REMOVE_FLAGS::ALT );
141 
142 TOOL_ACTION PCB_ACTIONS::exchangeFootprints( "pcbnew.InteractiveEdit.ExchangeFootprints",
143  AS_GLOBAL, 0,
144  _( "Exchange Footprint(s)" ), _( "Change the footprint used for modules" ),
145  import_module_xpm );
146 
147 TOOL_ACTION PCB_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
149  _( "Properties..." ), _( "Displays item properties dialog" ), editor_xpm );
150 
151 TOOL_ACTION PCB_ACTIONS::selectionModified( "pcbnew.InteractiveEdit.ModifiedSelection",
152  AS_GLOBAL, 0,
153  "", "", nullptr, AF_NOTIFY );
154 
155 TOOL_ACTION PCB_ACTIONS::measureTool( "pcbnew.InteractiveEdit.measureTool",
156  AS_GLOBAL, MD_CTRL + MD_SHIFT + 'M',
157  _( "Measure tool" ), _( "Interactively measure distance between points" ),
158  nullptr, AF_ACTIVATE );
159 
160 
162  PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
163  m_dragging( false )
164 {
165 }
166 
167 
169 {
170  m_dragging = false;
171 
172  if( aReason != RUN )
173  m_commit.reset( new BOARD_COMMIT( this ) );
174 }
175 
176 
178 {
179  // Find the selection tool, so they can cooperate
180  m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
181 
182  if( !m_selectionTool )
183  {
184  DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
185  return false;
186  }
187 
188  auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
189  return m_editModules;
190  };
191 
192  auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
194 
195  // Add context menu entries that are displayed when selection tool is active
207 
208  // Mirror only available in modedit
209  menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
210 
211  // Footprint actions
213  singleModuleCondition );
215  singleModuleCondition );
216 
217  m_offset.x = 0;
218  m_offset.y = 0;
219 
220  return true;
221 }
222 
223 
225 
226 
227 {
228  TRACK* track = uniqueSelected<TRACK>();
229  VIA* via = uniqueSelected<VIA>();
230 
231  if( track || via )
232  {
233  ROUTER_TOOL* theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
234  assert( theRouter );
235 
236  if( !theRouter->PNSSettings().InlineDragEnabled() )
237  return false;
238 
240  return true;
241  }
242 
243  return false;
244 }
245 
246 
247 int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
248 {
250  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
251 
252  VECTOR2I originalCursorPos = controls->GetCursorPosition();
253 
254  // Be sure that there is at least one item that we can modify. If nothing was selected before,
255  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
257 
258  if( selection.Empty() )
259  return 0;
260 
261  bool unselect = selection.IsHover();
262 
263  Activate();
264 
265  m_dragging = false; // Are selected items being dragged?
266  bool restore = false; // Should items' state be restored when finishing the tool?
267  bool lockOverride = false;
268 
269  controls->ShowCursor( true );
270  controls->SetSnapping( true );
271  controls->SetAutoPan( true );
272 
273  // cumulative translation
274  wxPoint totalMovement( 0, 0 );
275 
276  GRID_HELPER grid( editFrame );
277  OPT_TOOL_EVENT evt = aEvent;
278 
279  // Main loop: keep receiving events
280  do
281  {
282  if( evt->IsAction( &PCB_ACTIONS::editActivate )
283  || evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
284  {
285  if( selection.Empty() )
286  break;
287 
288  BOARD_ITEM* curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
289 
290  if( m_dragging && evt->Category() == TC_MOUSE )
291  {
292  m_cursor = grid.BestSnapAnchor( evt->Position(), curr_item );
293  controls->ForceCursorPosition( true, m_cursor );
294 
295  wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) - curr_item->GetPosition();
296  totalMovement += movement;
297 
298  // Drag items to the current cursor position
299  for( auto item : selection )
300  static_cast<BOARD_ITEM*>( item )->Move( movement + m_offset );
301  }
302  else if( !m_dragging ) // Prepare to start dragging
303  {
304  if( !invokeInlineRouter() )
305  {
307 
308  if( selection.Empty() )
309  break;
310 
311  // deal with locked items (override lock or abort the operation)
313 
314  if( lockFlags == SELECTION_LOCKED )
315  break;
316  else if( lockFlags == SELECTION_LOCK_OVERRIDE )
317  lockOverride = true;
318 
319  // Save items, so changes can be undone
320  for( auto item : selection )
321  m_commit->Modify( item );
322 
323  m_cursor = controls->GetCursorPosition();
324 
325  if( selection.Size() == 1 )
326  {
327  // Set the current cursor position to the first dragged item origin, so the
328  // movement vector could be computed later
329  m_cursor = grid.BestDragOrigin( originalCursorPos, curr_item );
330  grid.SetAuxAxes( true, m_cursor );
331  }
332  else
333  {
334  m_cursor = grid.Align( m_cursor );
335  }
336 
337  controls->ForceCursorPosition( true, m_cursor );
338  controls->WarpCursor( m_cursor, true );
339 
340  VECTOR2I o = VECTOR2I( curr_item->GetPosition() );
341  m_offset.x = o.x - m_cursor.x;
342  m_offset.y = o.y - m_cursor.y;
343 
344  controls->SetAutoPan( true );
345  m_dragging = true;
346  }
347  }
348 
350  }
351 
352  else if( evt->IsCancel() || evt->IsActivate() )
353  {
354  restore = true; // Cancelling the tool means that items have to be restored
355  break; // Finish
356  }
357 
358  else if( evt->Action() == TA_UNDO_REDO_PRE )
359  {
360  unselect = true;
361  break;
362  }
363 
364  // Dispatch TOOL_ACTIONs
365  else if( evt->Category() == TC_COMMAND )
366  {
367  wxPoint modPoint = getModificationPoint( selection );
368 
369  if( evt->IsAction( &PCB_ACTIONS::remove ) )
370  {
371  // exit the loop, as there is no further processing for removed items
372  break;
373  }
374  else if( evt->IsAction( &PCB_ACTIONS::duplicate ) )
375  {
376  // On duplicate, stop moving this item
377  // The duplicate tool should then select the new item and start
378  // a new move procedure
379  break;
380  }
381  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
382  {
383  // Can't do this, because the selection will then contain
384  // stale pointers and it will all go horribly wrong...
385  //editFrame->RestoreCopyFromUndoList( dummy );
386  //
387  // So, instead, reset the position manually
388  for( auto item : selection )
389  {
390  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
391  i->SetPosition( i->GetPosition() - totalMovement );
392 
393  // And what about flipping and rotation?
394  // for now, they won't be undone, but maybe that is how
395  // it should be, so you can flip and move exact in the
396  // same action?
397  }
398 
399  // This causes a double event, so we will get the dialogue
400  // correctly, somehow - why does Rotate not?
401  //MoveExact( aEvent );
402  break; // exit the loop - we move exactly, so we have finished moving
403  }
404 
405  if( m_dragging )
406  {
407  // Update dragging offset (distance between cursor and the first dragged item)
408  m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
409  getView()->Update( &selection );
410  }
411  }
412 
413  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
414  {
415  if( !lockOverride )
416  break; // Finish
417 
418  lockOverride = false;
419  }
420  } while( ( evt = Wait() ) ); //Should be assignment not equality test
421 
422  controls->ForceCursorPosition( false );
423  controls->ShowCursor( false );
424  controls->SetSnapping( false );
425  controls->SetAutoPan( false );
426 
427  m_dragging = false;
428  m_offset.x = 0;
429  m_offset.y = 0;
430 
431  if( unselect || restore )
433 
434  if( restore )
435  m_commit->Revert();
436  else
437  m_commit->Push( _( "Drag" ) );
438 
439  return 0;
440 }
441 
442 
443 int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
444 {
445  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
446 
448 
449  if( selection.Empty() )
450  return 0;
451 
452  // Tracks & vias are treated in a special way:
454  {
455  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection );
456 
457  if( dlg.ShowModal() )
458  {
459  dlg.Apply( *m_commit );
460  m_commit->Push( _( "Edit track/via properties" ) );
461  }
462  }
463  else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
464  {
465  // Display properties dialog
466  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
467 
468  // Some of properties dialogs alter pointers, so we should deselect them
470 
471  // Store flags, so they can be restored later
472  STATUS_FLAGS flags = item->GetFlags();
473  item->ClearFlags();
474 
475  // Do not handle undo buffer, it is done by the properties dialogs @todo LEGACY
476  // Display properties dialog provided by the legacy canvas frame
477  editFrame->OnEditItemRequest( NULL, item );
478 
480  item->SetFlags( flags );
481  }
482 
483  if( selection.IsHover() )
485 
486  return 0;
487 }
488 
489 
490 int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
491 {
492  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
493 
494  const auto& selection = m_selectionTool->RequestSelection();
495 
496  if( selection.Empty() )
497  return 0;
498 
500  return 0;
501 
502  wxPoint modPoint = getModificationPoint( selection );
503  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
504 
505  for( auto item : selection )
506  {
507  m_commit->Modify( item );
508  static_cast<BOARD_ITEM*>( item )->Rotate( modPoint, rotateAngle );
509  }
510 
511  // Update the dragging point offset
512  m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
513 
514  if( !m_dragging )
515  m_commit->Push( _( "Rotate" ) );
516 
517  if( selection.IsHover() )
519 
521 
522  return 0;
523 }
524 
528 static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
529 {
530  wxPoint mirrored = aPoint;
531 
532  mirrored.x -= aMirrorPoint.x;
533  mirrored.x = -mirrored.x;
534  mirrored.x += aMirrorPoint.x;
535 
536  return mirrored;
537 }
538 
539 
543 static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
544 {
545  wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
546 
547  aPad.SetPosition( tmpPt );
548 
549  aPad.SetX0( aPad.GetPosition().x );
550 
551  tmpPt = aPad.GetOffset();
552  tmpPt.x = -tmpPt.x;
553  aPad.SetOffset( tmpPt );
554 
555  auto tmpz = aPad.GetDelta();
556  tmpz.x = -tmpz.x;
557  aPad.SetDelta( tmpz );
558 
559  aPad.SetOrientation( -aPad.GetOrientation() );
560 }
561 
562 
563 int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
564 {
565  const auto& selection = m_selectionTool->RequestSelection();
566 
568  return 0;
569 
570  if( selection.Empty() )
571  return 0;
572 
573  wxPoint mirrorPoint = getModificationPoint( selection );
574 
575  for( auto item : selection )
576  {
577  // only modify items we can mirror
578  switch( item->Type() )
579  {
580  case PCB_MODULE_EDGE_T:
581  case PCB_MODULE_TEXT_T:
582  case PCB_PAD_T:
583  m_commit->Modify( item );
584  break;
585  default:
586  continue;
587  }
588 
589  // modify each object as necessary
590  switch( item->Type() )
591  {
592  case PCB_MODULE_EDGE_T:
593  {
594  auto& edge = static_cast<EDGE_MODULE&>( *item );
595  edge.Mirror( mirrorPoint, false );
596  break;
597  }
598 
599  case PCB_MODULE_TEXT_T:
600  {
601  auto& modText = static_cast<TEXTE_MODULE&>( *item );
602  modText.Mirror( mirrorPoint, false );
603  break;
604  }
605 
606  case PCB_PAD_T:
607  {
608  auto& pad = static_cast<D_PAD&>( *item );
609  mirrorPadX( pad, mirrorPoint );
610  break;
611  }
612 
613  default:
614  // it's likely the commit object is wrong if you get here
615  assert( false );
616  break;
617  }
618  }
619 
620  if( !m_dragging )
621  m_commit->Push( _( "Mirror" ) );
622 
623  if( selection.IsHover() )
625 
627 
628  return 0;
629 }
630 
631 
632 int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
633 {
634  const auto& selection = m_selectionTool->RequestSelection();
635 
637  return 0;
638 
639  if( selection.Empty() )
640  return 0;
641 
642  wxPoint modPoint = getModificationPoint( selection );
643 
644  for( auto item : selection )
645  {
646  m_commit->Modify( item );
647  static_cast<BOARD_ITEM*>( item )->Flip( modPoint );
648  }
649 
650  // Update the dragging point offset
651  m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
652 
653  if( !m_dragging )
654  m_commit->Push( _( "Flip" ) );
655 
656  if( selection.IsHover() )
658 
660 
661  return 0;
662 }
663 
664 
665 int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
666 {
667  // get a copy instead of reference (as we're going to clear the selectio before removing items)
669 
671  return 0;
672 
673  if( selection.Empty() )
674  return 0;
675 
676  // is this "alternative" remove?
677  const bool isAlt = aEvent.Parameter<intptr_t>() ==
679 
680  // in "alternative" mode, deletion is not just a simple list
681  // of selected items, it is:
682  // - whole tracks, not just segments
683  if( isAlt && selection.IsHover() )
684  {
687  }
688 
689  // As we are about to remove items, they have to be removed from the selection first
691 
692  for( auto item : selection )
693  {
694  m_commit->Remove( item );
695  }
696 
697  m_commit->Push( _( "Delete" ) );
698 
699  return 0;
700 }
701 
702 
703 int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
704 {
705  const auto& selection = m_selectionTool->RequestSelection();
706 
708  return 0;
709 
710  if( selection.Empty() )
711  return 0;
712 
713  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
714 
715  MOVE_PARAMETERS params;
717 
718  DIALOG_MOVE_EXACT dialog( editFrame, params );
719  int ret = dialog.ShowModal();
720 
721  if( ret == wxID_OK )
722  {
723  VECTOR2I rp = selection.GetCenter();
724  wxPoint rotPoint( rp.x, rp.y );
725 
726  // Begin at the center of the selection determined above
727  wxPoint anchorPoint = rotPoint;
728 
729  // If the anchor is not ANCHOR_FROM_LIBRARY then the user applied an override.
730  // Also run through this block if only one item is slected because it may be a module,
731  // in which case we want something different than the center of the selection
732  if( ( params.anchor != ANCHOR_FROM_LIBRARY ) || ( selection.GetSize() == 1 ) )
733  {
734  BOARD_ITEM* topLeftItem = static_cast<BOARD_ITEM*>( selection.GetTopLeftModule() );
735 
736  // no module found if the GetTopLeftModule() returns null, retry for
737  if( topLeftItem == nullptr )
738  {
739  topLeftItem = static_cast<BOARD_ITEM*>( selection.GetTopLeftItem() );
740  anchorPoint = topLeftItem->GetPosition();
741  }
742 
743  if( topLeftItem->Type() == PCB_MODULE_T )
744  {
745  // Cast to module to allow access to the pads
746  MODULE* mod = static_cast<MODULE*>( topLeftItem );
747 
748  switch( params.anchor )
749  {
750  case ANCHOR_FROM_LIBRARY:
751  anchorPoint = mod->GetPosition();
752  break;
753  case ANCHOR_TOP_LEFT_PAD:
754  topLeftItem = mod->GetTopLeftPad();
755  break;
757  anchorPoint = mod->GetFootprintRect().GetCenter();
758  break;
759  }
760  }
761 
762  if( topLeftItem->Type() == PCB_PAD_T )
763  {
764  if( static_cast<D_PAD*>( topLeftItem )->GetAttribute() == PAD_ATTRIB_SMD )
765  {
766  // Use the top left corner of SMD pads as an anchor instead of the center
767  anchorPoint = topLeftItem->GetBoundingBox().GetPosition();
768  }
769  else
770  {
771  anchorPoint = topLeftItem->GetPosition();
772  }
773  }
774  }
775 
776  wxPoint origin;
777 
778  switch( params.origin )
779  {
781  origin = editFrame->GetScreen()->m_O_Curseur;
782  break;
783 
785  origin = editFrame->GetGridOrigin();
786  break;
787 
789  origin = editFrame->GetAuxOrigin();
790  break;
791 
793  origin = wxPoint( 0, 0 );
794  break;
795 
797  // relative movement means that only the translation values should be used:
798  // -> set origin and anchor to zero
799  origin = wxPoint( 0, 0 );
800  anchorPoint = wxPoint( 0, 0 );
801  break;
802  }
803 
804  wxPoint finalMoveVector = params.translation + origin - anchorPoint;
805 
806  // Make sure the rotation is from the right reference point
807  rotPoint += finalMoveVector;
808 
809  for( auto item : selection )
810  {
811  m_commit->Modify( item );
812  static_cast<BOARD_ITEM*>( item )->Move( finalMoveVector );
813  static_cast<BOARD_ITEM*>( item )->Rotate( rotPoint, params.rotation );
814 
815  if( !m_dragging )
816  getView()->Update( item );
817  }
818 
819  m_commit->Push( _( "Move exact" ) );
820 
821  if( selection.IsHover() )
823 
825  }
826 
827  return 0;
828 }
829 
830 
831 int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
832 {
833  // Note: original items are no more modified.
834 
835  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
836 
837  // Be sure that there is at least one item that we can modify
839 
840  if( selection.Empty() )
841  return 0;
842 
843  // we have a selection to work on now, so start the tool process
844  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
845 
846  std::vector<BOARD_ITEM*> old_items;
847 
848  for( auto item : selection )
849  {
850  if( item )
851  old_items.push_back( static_cast<BOARD_ITEM*>( item ) );
852  }
853 
854  for( unsigned i = 0; i < old_items.size(); ++i )
855  {
856  BOARD_ITEM* item = old_items[i];
857 
858  // Unselect the item, so we won't pick it up again
859  // Do this first, so a single-item duplicate will correctly call
860  // SetCurItem and show the item properties
862 
863  BOARD_ITEM* new_item = NULL;
864 
865  if( m_editModules )
866  {
867  new_item = editFrame->GetBoard()->m_Modules->Duplicate( item, increment );
868  }
869  else
870  {
871 #if 0
872  // @TODO: see if we allow zone duplication here
873  // Duplicate zones is especially tricky (overlaping zones must be merged)
874  // so zones are not duplicated
875  if( item->Type() != PCB_ZONE_AREA_T )
876 #endif
877  new_item = editFrame->GetBoard()->Duplicate( item );
878  }
879 
880  if( new_item )
881  {
882  m_commit->Add( new_item );
883 
884  // Select the new item, so we can pick it up
885  m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, new_item );
886  }
887  }
888 
889  // record the new items as added
890  if( !selection.Empty() )
891  {
892  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
893  (int) old_items.size() ) );
894 
895  // If items were duplicated, pick them up
896  // this works well for "dropping" copies around and pushes the commit
898  Main( evt );
899  }
900 
901  return 0;
902 }
903 
904 
906 {
907 public:
908 
909  GAL_ARRAY_CREATOR( PCB_BASE_FRAME& editFrame, bool editModules,
910  const SELECTION& selection ):
911  ARRAY_CREATOR( editFrame ),
912  m_editModules( editModules ),
913  m_selection( selection )
914  {}
915 
916 private:
917 
918  int getNumberOfItemsToArray() const override
919  {
920  // only handle single items
921  return m_selection.Size();
922  }
923 
924  BOARD_ITEM* getNthItemToArray( int n ) const override
925  {
926  return static_cast<BOARD_ITEM*>( m_selection[n] );
927  }
928 
929  BOARD* getBoard() const override
930  {
931  return m_parent.GetBoard();
932  }
933 
934  MODULE* getModule() const override
935  {
936  // Remember this is valid and used only in the module editor.
937  // in board editor, the parent of items is usually the board.
938  return m_editModules ? m_parent.GetBoard()->m_Modules.GetFirst() : NULL;
939  }
940 
941  wxPoint getRotationCentre() const override
942  {
943  const VECTOR2I rp = m_selection.GetCenter();
944  return wxPoint( rp.x, rp.y );
945  }
946 
947  void prePushAction( BOARD_ITEM* aItem ) override
948  {
949  // Because aItem is/can be created from a selected item, and inherits from
950  // it this state, reset the selected stated of aItem:
951  aItem->ClearSelected();
952 
953  if( aItem->Type() == PCB_MODULE_T )
954  {
955  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
956  {
957  item->ClearSelected();
958  }
959  );
960  }
961  }
962 
963  void postPushAction( BOARD_ITEM* new_item ) override
964  {
965  }
966 
967  void finalise() override
968  {
969  }
970 
973 };
974 
975 
976 int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
977 {
978  const auto& selection = m_selectionTool->RequestSelection();
979 
980  if( selection.Empty() )
981  return 0;
982 
983  // we have a selection to work on now, so start the tool process
984  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
985  GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
986  array_creator.Invoke();
987 
988  return 0;
989 }
990 
991 
993 {
994  const auto& selection = m_selectionTool->RequestSelection();
995 
996  if( selection.Empty() )
997  return 0;
998 
999  MODULE* mod = selection.FirstOfKind<MODULE> ();
1000 
1001  if( !mod )
1002  return 0;
1003 
1004  frame()->SetCurItem( mod );
1005 
1006  // Footprint exchange could remove modules, so they have to be
1007  // removed from the selection first
1009 
1010  // invoke the exchange dialog process
1011  {
1012  DIALOG_EXCHANGE_MODULE dialog( frame(), mod );
1013  dialog.ShowQuasiModal();
1014  }
1015 
1016  // The current item can be deleted by exchange module, and the
1017  // selection is emptied, so remove current item from frame info area
1018  frame()->SetCurItem( nullptr );
1019 
1020  return 0;
1021 }
1022 
1023 
1025 {
1026  auto& view = *getView();
1027  auto& controls = *getViewControls();
1028 
1029  Activate();
1032  wxCURSOR_PENCIL, _( "Measure distance between two points" ) );
1033 
1035 
1036  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr );
1037 
1038  view.Add( &ruler );
1039  view.SetVisible( &ruler, false );
1040 
1041  bool originSet = false;
1042 
1043  controls.ShowCursor( true );
1044  controls.SetSnapping( true );
1045 
1046  while( auto evt = Wait() )
1047  {
1048  const VECTOR2I cursorPos = controls.GetCursorPosition();
1049 
1050  if( evt->IsCancel() || evt->IsActivate() )
1051  {
1052  break;
1053  }
1054 
1055  // click or drag starts
1056  else if( !originSet &&
1057  ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
1058  {
1059  if( !evt->IsDrag( BUT_LEFT ) )
1060  {
1061  twoPtMgr.SetOrigin( cursorPos );
1062  twoPtMgr.SetEnd( cursorPos );
1063  }
1064 
1065  controls.CaptureCursor( true );
1066  controls.SetAutoPan( true );
1067 
1068  originSet = true;
1069  }
1070 
1071  else if( !originSet && evt->IsMotion() )
1072  {
1073  // make sure the origin is set before a drag starts
1074  // otherwise you can miss a step
1075  twoPtMgr.SetOrigin( cursorPos );
1076  twoPtMgr.SetEnd( cursorPos );
1077  }
1078 
1079  // second click or mouse up after drag ends
1080  else if( originSet &&
1081  ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
1082  {
1083  originSet = false;
1084 
1085  controls.SetAutoPan( false );
1086  controls.CaptureCursor( false );
1087 
1088  view.SetVisible( &ruler, false );
1089  }
1090 
1091  // move or drag when origin set updates rules
1092  else if( originSet &&
1093  ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
1094  {
1095  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
1096  twoPtMgr.SetEnd( cursorPos );
1097 
1098  view.SetVisible( &ruler, true );
1099  view.Update( &ruler, KIGFX::GEOMETRY );
1100  }
1101 
1102  else if( evt->IsClick( BUT_RIGHT ) )
1103  {
1104  GetManager()->PassEvent();
1105  }
1106  }
1107 
1108  view.SetVisible( &ruler, false );
1109  view.Remove( &ruler );
1110 
1111  frame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
1112 
1113  return 0;
1114 }
1115 
1116 
1118 {
1119  Go( &EDIT_TOOL::Main, PCB_ACTIONS::editActivate.MakeEvent() );
1120  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
1121  Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCcw.MakeEvent() );
1122  Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
1123  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::remove.MakeEvent() );
1124  Go( &EDIT_TOOL::Remove, PCB_ACTIONS::removeAlt.MakeEvent() );
1130  Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
1134 }
1135 
1136 
1138 {
1139  if( aSelection.Size() == 1 )
1140  {
1141  return static_cast<BOARD_ITEM*>( aSelection.Front() )->GetPosition() - m_offset;
1142  }
1143  else
1144  {
1145  // If EDIT_TOOL is not currently active then it means that the cursor position is not
1146  // updated, so we have to fetch the latest value
1147  if( m_toolMgr->GetCurrentToolId() != m_toolId )
1149 
1150  return wxPoint( m_cursor.x, m_cursor.y );
1151  }
1152 }
1153 
1155 {
1156  const auto& selection = m_selectionTool->RequestSelection();
1157 
1158  if( selection.Empty() )
1159  return 0;
1160 
1161  MODULE* mod = selection.FirstOfKind<MODULE>();
1162 
1163  if( !mod )
1164  return 0;
1165 
1166  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1167 
1168  editFrame->SetCurItem( mod );
1169 
1170  if( editFrame->GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
1171  {
1172  editFrame->GetCurItem()->SetTimeStamp( GetNewTimeStamp() );
1173  editFrame->OnModify();
1174  }
1175 
1177 
1178  editor->Load_Module_From_BOARD( (MODULE*) editFrame->GetCurItem() );
1179  editFrame->SetCurItem( NULL ); // the current module could be deleted by
1180 
1181  editor->Show( true );
1182  editor->Raise(); // Iconize( false );
1183 
1184  if( selection.IsHover() )
1186 
1187  return 0;
1188 }
1189 
1190 template<class T>
1192 {
1193  const auto selection = m_selectionTool->GetSelection();
1194 
1195  if( selection.Size() != 1 )
1196  return nullptr;
1197 
1198  auto item = selection[0];
1199  return dyn_cast<T*>( item );
1200 }
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:1137
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
VECTOR2I m_cursor
Last cursor position (needed for getModificationPoint() to avoid changes of edit reference point)...
Definition: edit_tool.h:145
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
int Main(const TOOL_EVENT &aEvent)
Function Main()
Definition: edit_tool.cpp:247
KIGFX::VIEW * view() const
Definition: pcb_tool.h:108
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...
int Properties(const TOOL_EVENT &aEvent)
Function Edit()
Definition: edit_tool.cpp:443
int Rotate(const TOOL_EVENT &aEvent)
Function Rotate()
Definition: edit_tool.cpp:490
TOOL_BASE * FindTool(int aId) const
Function FindTool() Searches for a tool with given ID.
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:992
static TOOL_ACTION editActivate
Activation of the edit tool.
Definition: pcb_actions.h:81
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:359
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
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:201
T
enum T contains all this lexer's tokens.
void ClearSelected()
Definition: base_struct.h:231
VECTOR2I Align(const VECTOR2I &aPoint) const
Definition: grid_helper.cpp:95
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:144
SELECTION_LOCK_FLAGS CheckLock()
Checks if the user has agreed to modify locked items for the given selection.
static TOOL_ACTION unselectItem
Unselects an item (specified as the event parameter).
Definition: pcb_actions.h:59
Class that computes missing connections on a PCB.
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:49
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:220
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
const wxPoint & GetGridOrigin() const override
Function GetGridOrigin returns the absolute coordinates of the origin of the snap grid...
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:96
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:215
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:62
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:115
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 mirror
Mirroring of selected items.
Definition: pcb_actions.h:93
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:135
wxPoint m_offset
Offset from the dragged item's center (anchor)
Definition: edit_tool.h:141
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
static bool NotEmpty(const SELECTION &aSelection)
Function NotEmpty Tests if there are any items selected.
wxPoint m_O_Curseur
Relative Screen cursor coordinate (on grid) in user units.
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
const wxPoint & GetAuxOrigin() const override
Function GetAuxOrigin returns the origin of the axis used for plotting and various exports...
static TOOL_ACTION copyPadToSettings
Definition: pcb_actions.h:357
MODULE * getModule() const override
Definition: edit_tool.cpp:934
static TOOL_ACTION selectionModified
Modified selection notification.
Definition: pcb_actions.h:99
void SetTimeStamp(time_t aNewTimeStamp)
Definition: base_struct.h:203
int Mirror(const TOOL_EVENT &aEvent)
Function Mirror.
Definition: edit_tool.cpp:563
Pcbnew hotkeys.
BOARD_ITEM * getNthItemToArray(int n) const override
Definition: edit_tool.cpp:924
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:102
const ROUTING_SETTINGS & PNSSettings() const
Definition: pns_tool_base.h:54
void finalise() override
Definition: edit_tool.cpp:967
static TOOL_ACTION copySettingsToPads
Definition: pcb_actions.h:358
void PassEvent()
Allows a tool to pass the already handled event to the next tool on the stack.
Definition: tool_manager.h:336
static TOOL_ACTION duplicate
Activation of the duplication tool.
Definition: pcb_actions.h:105
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:632
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:108
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:84
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:918
wxPoint getRotationCentre() const override
Definition: edit_tool.cpp:941
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:253
virtual VECTOR2D GetCursorPosition() const =0
Function GetCursorPosition() Returns the current cursor position in world coordinates.
bool m_dragging
Flag determining if anything is being dragged right now
Definition: edit_tool.h:138
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
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
T * uniqueSelected()
Function uniqueSelected()
Definition: edit_tool.cpp:1191
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:109
Class TOOL_EVENT.
Definition: tool_event.h:162
static TOOL_ACTION createArray
Tool for creating an array of objects.
Definition: pcb_actions.h:273
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:909
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
SELECTION & GetSelection()
Function GetSelection()
unsigned STATUS_FLAGS
Definition: base_struct.h:144
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Definition: edit_tool.cpp:177
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
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:111
All active tools
Definition: tool_event.h:138
Class PCB_TOOL.
Definition: pcb_tool.h:45
BOARD * getBoard() const override
Definition: edit_tool.cpp:929
const SELECTION & m_selection
Definition: edit_tool.cpp:972
void Update(VIEW_ITEM *aItem)
Function Update() For dynamic VIEWs, informs the associated VIEW that the graphical representation of...
Definition: view.cpp:1379
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:189
bool invokeInlineRouter()
Definition: edit_tool.cpp:224
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:112
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: edit_tool.cpp:168
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:30
static TOOL_ACTION rotateCcw
Rotation of selected objects counter-clockwise.
Definition: pcb_actions.h:87
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
int MoveExact(const TOOL_EVENT &aEvent)
Function MoveExact()
Definition: edit_tool.cpp:703
int Remove(const TOOL_EVENT &aEvent)
Function Remove()
Definition: edit_tool.cpp:665
static ROUTER * theRouter
Definition: pns_router.cpp:66
bool EditingModules() const
Definition: pcb_tool.h:78
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:90
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
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:976
Common, abstract interface for edit frames.
int MeasureTool(const TOOL_EVENT &aEvent)
Launches a tool to measure between points
Definition: edit_tool.cpp:1024
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:166
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:356
DLIST< MODULE > m_Modules
Definition: class_board.h:243
Class TOOL_ACTION.
Definition: tool_action.h:46
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
Definition: pcb_actions.h:56
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:84
static wxPoint mirrorPointX(const wxPoint &aPoint, const wxPoint &aMirrorPoint)
Definition: edit_tool.cpp:528
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
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:1154
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)
Function SetVisible() Sets the item visibility.
Definition: view.cpp:1331
void Activate()
Function Activate() Runs the tool.
void SetTransitions() override
Sets up handlers for various events.
Definition: edit_tool.cpp:1117
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:114
EDGE_MODULE class definition.
void postPushAction(BOARD_ITEM *new_item) override
Definition: edit_tool.cpp:963
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.
int Duplicate(const TOOL_EVENT &aEvent)
Function Duplicate()
Definition: edit_tool.cpp:831
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:69
static void mirrorPadX(D_PAD &aPad, const wxPoint &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point.
Definition: edit_tool.cpp:543
#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:338
const wxPoint & GetOffset() const
Definition: class_pad.h:191
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:184
bool Apply(COMMIT &aCommit)
Applies values from the dialog to the selected items.
void prePushAction(BOARD_ITEM *aItem) override
Definition: edit_tool.cpp:947
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_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aAddToBoard=false)
const wxPoint GetCenter() const