KiCad PCB EDA Suite
pcbnew/tools/selection_tool.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013-2017 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  * Copyright (C) 2018 KiCad Developers, see AUTHORS.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 #include <limits>
27 
28 #include <functional>
29 using namespace std::placeholders;
30 
31 #include <class_board.h>
32 #include <class_board_item.h>
33 #include <class_track.h>
34 #include <class_module.h>
35 #include <class_pcb_text.h>
36 #include <class_drawsegment.h>
37 #include <class_zone.h>
38 
39 #include <pcb_edit_frame.h>
40 #include <collectors.h>
41 #include <confirm.h>
42 #include <dialog_find.h>
43 #include <dialog_block_options.h>
44 
45 #include <class_draw_panel_gal.h>
46 #include <view/view_controls.h>
47 #include <view/view_group.h>
49 #include <painter.h>
50 #include <bitmaps.h>
51 #include <hotkeys.h>
52 
53 #include <tool/tool_event.h>
54 #include <tool/tool_manager.h>
55 #include <router/router_tool.h>
57 #include <footprint_viewer_frame.h>
58 #include "tool_event_utils.h"
59 
60 #include "selection_tool.h"
61 #include "pcb_bright_box.h"
62 #include "pcb_actions.h"
63 
64 #include "kicad_plugin.h"
65 
66 // Selection tool actions
67 TOOL_ACTION PCB_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection",
68  AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE ); // No description, not shown anywhere
69 
70 TOOL_ACTION PCB_ACTIONS::selectionCursor( "pcbnew.InteractiveSelection.Cursor",
71  AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
72 
73 TOOL_ACTION PCB_ACTIONS::selectItem( "pcbnew.InteractiveSelection.SelectItem",
74  AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
75 
76 TOOL_ACTION PCB_ACTIONS::selectItems( "pcbnew.InteractiveSelection.SelectItems",
77  AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
78 
79 TOOL_ACTION PCB_ACTIONS::unselectItem( "pcbnew.InteractiveSelection.UnselectItem",
80  AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
81 
82 TOOL_ACTION PCB_ACTIONS::unselectItems( "pcbnew.InteractiveSelection.UnselectItems",
83  AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
84 
85 TOOL_ACTION PCB_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear",
86  AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
87 
88 TOOL_ACTION PCB_ACTIONS::selectionMenu( "pcbnew.InteractiveSelection.SelectionMenu",
89  AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
90 
91 TOOL_ACTION PCB_ACTIONS::selectConnection( "pcbnew.InteractiveSelection.SelectConnection",
93  _( "Single Track" ),
94  _( "Selects all track segments & vias between two junctions." ),
95  add_tracks_xpm );
96 
97 TOOL_ACTION PCB_ACTIONS::selectCopper( "pcbnew.InteractiveSelection.SelectCopper",
99  _( "Connected Tracks" ),
100  _( "Selects all connected tracks & vias." ),
101  net_highlight_xpm );
102 
103 TOOL_ACTION PCB_ACTIONS::expandSelectedConnection( "pcbnew.InteractiveSelection.ExpandConnection",
104  AS_GLOBAL, 0,
105  _( "Expand Selected Connection" ),
106  _( "Expands the current selection to select a connection between two junctions." ) );
107 
108 TOOL_ACTION PCB_ACTIONS::selectNet( "pcbnew.InteractiveSelection.SelectNet",
109  AS_GLOBAL, 0,
110  _( "All Tracks in Net" ),
111  _( "Selects all tracks & vias belonging to the same net." ),
112  mode_track_xpm );
113 
114 TOOL_ACTION PCB_ACTIONS::selectOnSheetFromEeschema( "pcbnew.InteractiveSelection.SelectOnSheet",
115  AS_GLOBAL, 0,
116  _( "Sheet" ),
117  _( "Selects all modules and tracks in the schematic sheet" ),
118  select_same_sheet_xpm );
119 
120 TOOL_ACTION PCB_ACTIONS::selectSameSheet( "pcbnew.InteractiveSelection.SelectSameSheet",
121  AS_GLOBAL, 0,
122  _( "Items in Same Hierarchical Sheet" ),
123  _( "Selects all modules and tracks in the same schematic sheet" ),
124  select_same_sheet_xpm );
125 
126 TOOL_ACTION PCB_ACTIONS::find( "pcbnew.InteractiveSelection.Find",
127  AS_GLOBAL, 0, //TOOL_ACTION::LegacyHotKey( HK_FIND_ITEM ), // handled by wxWidgets
128  _( "Find Item..." ),
129  _( "Searches the document for an item" ),
130  find_xpm );
131 
132 TOOL_ACTION PCB_ACTIONS::findMove( "pcbnew.InteractiveSelection.FindMove",
134  _( "Get and Move Footprint" ),
135  _( "Selects a footprint by reference and places it under the cursor for moving"),
136  move_xpm );
137 
138 TOOL_ACTION PCB_ACTIONS::filterSelection( "pcbnew.InteractiveSelection.FilterSelection",
139  AS_GLOBAL, 0,
140  _( "Filter Selection..." ), _( "Filter the types of items in the selection" ),
141  options_generic_xpm );
142 
144 {
145 public:
147  {
148  SetTitle( _( "Select" ) );
149  SetIcon( options_generic_xpm );
150 
152 
153  AppendSeparator();
154 
157  Add( PCB_ACTIONS::selectNet );
159  }
160 
161 private:
162 
163  void update() override
164  {
165  using S_C = SELECTION_CONDITIONS;
166 
167  const auto& selection = getToolManager()->GetTool<SELECTION_TOOL>()->GetSelection();
168 
169  bool connItem = S_C::OnlyTypes( GENERAL_COLLECTOR::Tracks )( selection );
170  bool sheetSelEnabled = ( S_C::OnlyType( PCB_MODULE_T ) )( selection );
171 
172  Enable( getMenuId( PCB_ACTIONS::selectNet ), connItem );
173  Enable( getMenuId( PCB_ACTIONS::selectCopper ), connItem );
174  Enable( getMenuId( PCB_ACTIONS::selectConnection ), connItem );
175  Enable( getMenuId( PCB_ACTIONS::selectSameSheet ), sheetSelEnabled );
176  }
177 
178  CONTEXT_MENU* create() const override
179  {
180  return new SELECT_MENU();
181  }
182 };
183 
184 
189 {
190 public:
192 };
193 
194 
196  PCB_TOOL( "pcbnew.InteractiveSelection" ),
197  m_frame( NULL ),
198  m_additive( false ),
199  m_subtractive( false ),
200  m_multiple( false ),
201  m_skip_heuristics( false ),
202  m_locked( true ),
203  m_menu( *this ),
204  m_priv( std::make_unique<PRIV>() )
205 {
206 
207 }
208 
209 
211 {
212  getView()->Remove( &m_selection );
213 }
214 
215 
217 {
218  auto frame = getEditFrame<PCB_BASE_FRAME>();
219 
222  {
224  return true;
225  }
226 
227  auto selectMenu = std::make_shared<SELECT_MENU>();
228  selectMenu->SetTool( this );
229  m_menu.AddSubMenu( selectMenu );
230 
231  auto& menu = m_menu.GetMenu();
232 
233  menu.AddMenu( selectMenu.get(), false, SELECTION_CONDITIONS::NotEmpty );
234  menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 );
235 
236  if( frame )
237  {
239  }
240 
241  return true;
242 }
243 
244 
246 {
247  m_frame = getEditFrame<PCB_BASE_FRAME>();
248  m_locked = true;
249 
250  if( aReason == TOOL_BASE::MODEL_RELOAD )
251  {
252  // Remove pointers to the selected items from containers
253  // without changing their properties (as they are already deleted
254  // while a new board is loaded)
255  m_selection.Clear();
256  getView()->GetPainter()->GetSettings()->SetHighlight( false );
257  }
258  else
259  // Restore previous properties of selected items and remove them from containers
260  clearSelection();
261 
262  // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
263  view()->Remove( &m_selection );
264  view()->Add( &m_selection );
265 }
266 
267 
268 int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
269 {
270  // Main loop: keep receiving events
271  while( OPT_TOOL_EVENT evt = Wait() )
272  {
273  // Should selected items be added to the current selection or
274  // become the new selection (discarding previously selected items)
275  m_additive = evt->Modifier( MD_SHIFT );
276 
277  // Should selected items be REMOVED from the current selection?
278  // This will be ignored if the SHIFT modifier is pressed
279  m_subtractive = !m_additive && evt->Modifier( MD_CTRL );
280 
281  // Is the user requesting that the selection list include all possible
282  // items without removing less likely selection candidates
283  m_skip_heuristics = !!evt->Modifier( MD_ALT );
284 
285  // Single click? Select single object
286  if( evt->IsClick( BUT_LEFT ) )
287  {
288  if( evt->Modifier( MD_CTRL ) && !m_editModules )
289  {
291  }
292  else
293  {
294  // If no modifier keys are pressed, clear the selection
295  if( !m_additive )
296  clearSelection();
297 
298  selectPoint( evt->Position() );
299  }
300  }
301 
302  // right click? if there is any object - show the context menu
303  else if( evt->IsClick( BUT_RIGHT ) )
304  {
305  bool selectionCancelled = false;
306 
307  if( m_selection.Empty() )
308  {
309  selectPoint( evt->Position(), false, &selectionCancelled );
310  m_selection.SetIsHover( true );
311  }
312 
313  if( !selectionCancelled )
315  }
316 
317  // double click? Display the properties window
318  else if( evt->IsDblClick( BUT_LEFT ) )
319  {
320  if( m_selection.Empty() )
321  selectPoint( evt->Position() );
322 
324  }
325 
326  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
327  else if( evt->IsDrag( BUT_LEFT ) )
328  {
329  if( m_additive || m_subtractive )
330  {
331  selectMultiple();
332  }
333  else if( m_selection.Empty() )
334  {
335  // There is nothing selected, so try to select something
336  if( getEditFrame<PCB_BASE_FRAME>()->Settings().m_dragSelects || !selectCursor() )
337  {
338  // If nothings has been selected, user wants to select more or selection
339  // box is preferred to dragging - draw selection box
340  selectMultiple();
341  }
342  else
343  {
344  m_selection.SetIsHover( true );
345  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
346  }
347  }
348 
349  else
350  {
351  // Check if dragging has started within any of selected items bounding box
352  if( selectionContains( evt->Position() ) )
353  {
354  // Yes -> run the move tool and wait till it finishes
355  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
356  }
357  else
358  {
359  // No -> clear the selection list
360  clearSelection();
361  }
362  }
363  }
364 
365  else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE )
366  {
367  clearSelection();
368 
369  if( evt->IsCancel() && !m_editModules )
371  }
372 
373  else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
374  {
375  m_menu.CloseContextMenu( evt );
376  }
377  }
378 
379  // This tool is supposed to be active forever
380  assert( false );
381 
382  return 0;
383 }
384 
385 
387 {
388  return m_selection;
389 }
390 
391 
392 static EDA_RECT getRect( const BOARD_ITEM* aItem )
393 {
394  if( aItem->Type() == PCB_MODULE_T )
395  return static_cast<const MODULE*>( aItem )->GetFootprintRect();
396 
397  return aItem->GetBoundingBox();
398 }
399 
400 
402  std::vector<BOARD_ITEM*>* aFiltered, bool aConfirmLockedItems )
403 {
404  bool selectionEmpty = m_selection.Empty();
405  m_selection.SetIsHover( selectionEmpty );
406 
407  if( selectionEmpty )
408  {
409  m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, aClientFilter );
411  }
412 
413  if ( aConfirmLockedItems && CheckLock() == SELECTION_LOCKED )
414  {
415  clearSelection();
416  }
417 
418  if( aClientFilter )
419  {
420  GENERAL_COLLECTOR collector;
421 
422  for( auto item : m_selection )
423  collector.Append( item );
424 
425  aClientFilter( VECTOR2I(), collector );
426 
427  /*
428  * The first step is to find the items that may have been added by the client filter
429  * This can happen if the locked pads select the module instead
430  */
431  std::vector<EDA_ITEM*> new_items;
432  std::set_difference( collector.begin(), collector.end(), m_selection.begin(), m_selection.end(),
433  std::back_inserter( new_items ) );
434 
438  std::vector<EDA_ITEM*> diff;
439  std::set_difference( m_selection.begin(), m_selection.end(), collector.begin(), collector.end(),
440  std::back_inserter( diff ) );
441 
442  if( aFiltered )
443  {
444  for( auto item : diff )
445  aFiltered->push_back( static_cast<BOARD_ITEM*>( item ) );
446  }
447 
452  for( auto item : diff )
453  unhighlight( static_cast<BOARD_ITEM*>( item ), SELECTED, m_selection );
454 
455  for( auto item : new_items )
456  highlight( static_cast<BOARD_ITEM*>( item ), SELECTED, m_selection );
457 
459  }
460 
461  return m_selection;
462 }
463 
464 
465 void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem, bool aForce )
466 {
467  if( aItem->IsSelected() )
468  {
469  unselect( aItem );
470 
471  // Inform other potentially interested tools
473  }
474  else
475  {
476  if( !m_additive )
477  clearSelection();
478 
479  // Prevent selection of invisible or inactive items
480  if( aForce || selectable( aItem ) )
481  {
482  select( aItem );
483 
484  // Inform other potentially interested tools
486  }
487  }
488 
489  if( m_frame )
491 }
492 
494 {
495  GENERAL_COLLECTORS_GUIDE guide( board()->GetVisibleLayers(),
496  (PCB_LAYER_ID) view()->GetTopLayer(), view() );
497 
498  // account for the globals
499  guide.SetIgnoreMTextsMarkedNoShow( ! board()->IsElementVisible( LAYER_MOD_TEXT_INVISIBLE ) );
500  guide.SetIgnoreMTextsOnBack( ! board()->IsElementVisible( LAYER_MOD_TEXT_BK ) );
501  guide.SetIgnoreMTextsOnFront( ! board()->IsElementVisible( LAYER_MOD_TEXT_FR ) );
502  guide.SetIgnoreModulesOnBack( ! board()->IsElementVisible( LAYER_MOD_BK ) );
503  guide.SetIgnoreModulesOnFront( ! board()->IsElementVisible( LAYER_MOD_FR ) );
504  guide.SetIgnorePadsOnBack( ! board()->IsElementVisible( LAYER_PAD_BK ) );
505  guide.SetIgnorePadsOnFront( ! board()->IsElementVisible( LAYER_PAD_FR ) );
506  guide.SetIgnoreThroughHolePads( ! board()->IsElementVisible( LAYER_PADS_TH ) );
507  guide.SetIgnoreModulesVals( ! board()->IsElementVisible( LAYER_MOD_VALUES ) );
508  guide.SetIgnoreModulesRefs( ! board()->IsElementVisible( LAYER_MOD_REFERENCES ) );
509  guide.SetIgnoreThroughVias( ! board()->IsElementVisible( LAYER_VIA_THROUGH ) );
510  guide.SetIgnoreBlindBuriedVias( ! board()->IsElementVisible( LAYER_VIA_BBLIND ) );
511  guide.SetIgnoreMicroVias( ! board()->IsElementVisible( LAYER_VIA_MICROVIA ) );
512  guide.SetIgnoreTracks( ! board()->IsElementVisible( LAYER_TRACKS ) );
513 
514  return guide;
515 }
516 
517 
518 bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
519  bool* aSelectionCancelledFlag,
520  CLIENT_SELECTION_FILTER aClientFilter )
521 {
522  auto guide = getCollectorsGuide();
523  GENERAL_COLLECTOR collector;
524  auto displayOpts = (PCB_DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
525 
526  guide.SetIgnoreZoneFills( displayOpts->m_DisplayZonesMode != 0 );
527 
528  collector.Collect( board(),
530  wxPoint( aWhere.x, aWhere.y ), guide );
531 
532  bool anyCollected = collector.GetCount() != 0;
533 
534  // Remove unselectable items
535  for( int i = collector.GetCount() - 1; i >= 0; --i )
536  {
537  if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() ) )
538  collector.Remove( i );
539  }
540 
542 
543  // Allow the client to do tool- or action-specific filtering to see if we
544  // can get down to a single item
545  if( aClientFilter )
546  aClientFilter( aWhere, collector );
547 
548  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
549  if( collector.GetCount() > 1 && !m_skip_heuristics )
550  {
551  guessSelectionCandidates( collector, aWhere );
552  }
553 
554  // If still more than one item we're going to have to ask the user.
555  if( collector.GetCount() > 1 )
556  {
557  if( aOnDrag )
558  {
560  }
561 
562  if( !doSelectionMenu( &collector, _( "Clarify Selection" ) ) )
563  {
564  if( aSelectionCancelledFlag )
565  *aSelectionCancelledFlag = true;
566 
567  return false;
568  }
569  }
570 
571  if( collector.GetCount() == 1 )
572  {
573  BOARD_ITEM* item = collector[ 0 ];
574 
575  toggleSelection( item );
576  return true;
577  }
578 
579  if( !m_additive && anyCollected )
580  clearSelection();
581 
582  return false;
583 }
584 
585 
586 bool SELECTION_TOOL::selectCursor( bool aForceSelect, CLIENT_SELECTION_FILTER aClientFilter )
587 {
588  if( aForceSelect || m_selection.Empty() )
589  {
590  clearSelection();
591  selectPoint( getViewControls()->GetCursorPosition( false ), false, NULL, aClientFilter );
592  }
593 
594  return !m_selection.Empty();
595 }
596 
597 
599 {
600  bool cancelled = false; // Was the tool cancelled while it was running?
601  m_multiple = true; // Multiple selection mode is active
602  KIGFX::VIEW* view = getView();
603 
605  view->Add( &area );
606 
607  while( OPT_TOOL_EVENT evt = Wait() )
608  {
610  {
611  cancelled = true;
612  break;
613  }
614 
615  if( evt->IsDrag( BUT_LEFT ) )
616  {
617  // Start drawing a selection box
618  area.SetOrigin( evt->DragOrigin() );
619  area.SetEnd( evt->Position() );
620  area.SetAdditive( m_additive );
622 
623  view->SetVisible( &area, true );
624  view->Update( &area );
625  getViewControls()->SetAutoPan( true );
626  }
627 
628  if( evt->IsMouseUp( BUT_LEFT ) )
629  {
630  getViewControls()->SetAutoPan( false );
631 
632  // End drawing the selection box
633  view->SetVisible( &area, false );
634 
635  // Mark items within the selection box as selected
636  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
637 
638  // Filter the view items based on the selection box
639  BOX2I selectionBox = area.ViewBBox();
640  view->Query( selectionBox, selectedItems ); // Get the list of selected items
641 
642  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
643 
644  int width = area.GetEnd().x - area.GetOrigin().x;
645  int height = area.GetEnd().y - area.GetOrigin().y;
646 
647  /* Selection mode depends on direction of drag-selection:
648  * Left > Right : Select objects that are fully enclosed by selection
649  * Right > Left : Select objects that are crossed by selection
650  */
651  bool windowSelection = width >= 0 ? true : false;
652 
653  if( view->IsMirroredX() )
654  windowSelection = !windowSelection;
655 
656  // Construct an EDA_RECT to determine BOARD_ITEM selection
657  EDA_RECT selectionRect( wxPoint( area.GetOrigin().x, area.GetOrigin().y ),
658  wxSize( width, height ) );
659 
660  selectionRect.Normalize();
661 
662  for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
663  {
664  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
665 
666  if( !item || !selectable( item ) )
667  continue;
668 
669  if( windowSelection )
670  {
671  BOX2I bbox = getRect( item );
672 
673  if( selectionBox.Contains( bbox ) )
674  {
675  if( m_subtractive )
676  unselect( item );
677  else
678  select( item );
679  }
680  }
681  else
682  {
683  if( item->HitTest( selectionRect, false ) )
684  {
685  if( m_subtractive )
686  unselect( item );
687  else
688  select( item );
689  }
690  }
691  }
692 
693  if( m_frame )
694  {
695  if( m_selection.Size() == 1 )
696  m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
697  else
698  m_frame->SetCurItem( NULL );
699  }
700 
701  // Inform other potentially interested tools
702  if( !m_selection.Empty() )
704 
705  break; // Stop waiting for events
706  }
707  }
708 
709  getViewControls()->SetAutoPan( false );
710 
711  // Stop drawing the selection box
712  view->Remove( &area );
713  m_multiple = false; // Multiple selection mode is inactive
714 
715  if( !cancelled )
717 
718  return cancelled;
719 }
720 
721 
723 {
732  Go( &SELECTION_TOOL::find, PCB_ACTIONS::find.MakeEvent() );
742 }
743 
744 
746 {
747  if( !m_locked || m_editModules )
748  return SELECTION_UNLOCKED;
749 
750  bool containsLocked = false;
751 
752  // Check if the selection contains locked items
753  for( const auto& item : m_selection )
754  {
755  switch( item->Type() )
756  {
757  case PCB_MODULE_T:
758  if( static_cast<MODULE*>( item )->IsLocked() )
759  containsLocked = true;
760  break;
761 
762  case PCB_MODULE_EDGE_T:
763  case PCB_MODULE_TEXT_T:
764  if( static_cast<MODULE*>( item->GetParent() )->IsLocked() )
765  containsLocked = true;
766  break;
767 
768  default: // suppress warnings
769  break;
770  }
771  }
772 
773  if( containsLocked )
774  {
775  if( IsOK( m_frame, _( "Selection contains locked items. Do you want to continue?" ) ) )
776  {
777  m_locked = false;
779  }
780  else
781  return SELECTION_LOCKED;
782  }
783 
784  return SELECTION_UNLOCKED;
785 }
786 
787 
789 {
791 
792  selectCursor( false, aClientFilter );
793 
794  return 0;
795 }
796 
797 
799 {
800  clearSelection();
801 
802  return 0;
803 }
804 
805 
807 {
808  std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
809 
810  if( items )
811  {
812  // Perform individual selection of each item before processing the event.
813  for( auto item : *items )
814  select( item );
815 
817  }
818 
819  return 0;
820 }
821 
822 
824 {
825  // Check if there is an item to be selected
826  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
827 
828  if( item )
829  {
830  select( item );
831 
832  // Inform other potentially interested tools
834  }
835 
836  return 0;
837 }
838 
839 
841 {
842  std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
843 
844  if( items )
845  {
846  // Perform individual unselection of each item before processing the event
847  for( auto item : *items )
848  unselect( item );
849 
851  }
852 
853  return 0;
854 }
855 
856 
858 {
859  // Check if there is an item to be selected
860  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
861 
862  if( item )
863  {
864  unselect( item );
865 
866  // Inform other potentially interested tools
868  }
869 
870  return 0;
871 }
872 
873 
874 void connectedTrackFilter( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
875 {
876  /* Narrow the collection down to a single TRACK item for a trivial
877  * connection, or multiple TRACK items for non-trivial connections.
878  */
879  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
880  {
881  if( !dynamic_cast<TRACK*>( aCollector[i] ) )
882  aCollector.Remove( i );
883  }
884 
885  ROUTER_TOOL::NeighboringSegmentFilter( aPt, aCollector );
886 }
887 
888 
890 {
893 
895  return 0;
896 
897  return expandSelectedConnection( aEvent );
898 }
899 
900 
902 {
903  // copy the selection, since we're going to iterate and modify
904  auto selection = m_selection.GetItems();
905 
906  // We use the BUSY flag to mark connections
907  for( auto item : selection )
908  item->SetState( BUSY, false );
909 
910  for( auto item : selection )
911  {
912  TRACK* trackItem = dynamic_cast<TRACK*>( item );
913 
914  // Track items marked BUSY have already been visited
915  // therefore their connections have already been marked
916  if( trackItem && !trackItem->GetState( BUSY ) )
917  selectAllItemsConnectedToTrack( *trackItem );
918  }
919 
920  // Inform other potentially interested tools
921  if( m_selection.Size() > 0 )
923 
924  return 0;
925 }
926 
927 
928 void connectedItemFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
929 {
930  /* Narrow the collection down to a single BOARD_CONNECTED_ITEM for each
931  * represented net. All other items types are removed.
932  */
933  std::set<int> representedNets;
934 
935  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
936  {
937  BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[i] );
938  if( !item )
939  aCollector.Remove( i );
940  else if ( representedNets.count( item->GetNetCode() ) )
941  aCollector.Remove( i );
942  else
943  representedNets.insert( item->GetNetCode() );
944  }
945 }
946 
947 
949 {
950  bool haveCopper = false;
951 
952  for( auto item : m_selection.GetItems() )
953  {
954  if( dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
955  haveCopper = true;;
956  }
957 
958  if( !haveCopper )
960 
961  // copy the selection, since we're going to iterate and modify
962  auto selection = m_selection.GetItems();
963 
964  for( auto item : selection )
965  {
966  BOARD_CONNECTED_ITEM* connItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( item );
967 
968  if( connItem )
969  selectAllItemsConnectedToItem( *connItem );
970  }
971 
972  // Inform other potentially interested tools
973  if( m_selection.Size() > 0 )
975 
976  return 0;
977 }
978 
979 
981 {
982  int segmentCount;
983  TRACK* trackList = board()->MarkTrace( board()->m_Track, &aSourceTrack, &segmentCount,
984  nullptr, nullptr, true );
985 
986  for( int i = 0; i < segmentCount; ++i )
987  {
988  select( trackList );
989  trackList = trackList->Next();
990  }
991 }
992 
993 
995 {
996  constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_PAD_T, EOT };
997  auto connectivity = board()->GetConnectivity();
998 
999  for( auto item : connectivity->GetConnectedItems( &aSourceItem, types ) )
1000  {
1001  // We want to select items connected through pads but not pads
1002  // otherwise, the common use case of "Select Copper"->Delete will
1003  // remove footprints in addition to traces and vias
1004  if( item->Type() != PCB_PAD_T )
1005  select( item );
1006  }
1007 }
1008 
1009 
1011 {
1012  constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, EOT };
1013  auto connectivity = board()->GetConnectivity();
1014 
1015  for( auto item : connectivity->GetNetItems( aNetCode, types ) )
1016  select( item );
1017 }
1018 
1019 
1021 {
1022  if( !selectCursor() )
1023  return 0;
1024 
1025  // copy the selection, since we're going to iterate and modify
1026  auto selection = m_selection.GetItems();
1027 
1028  for( auto i : selection )
1029  {
1030  auto item = static_cast<BOARD_ITEM*>( i );
1031 
1032  // only connected items get a net code
1033  if( item->IsConnected() )
1034  {
1035  auto& connItem = static_cast<BOARD_CONNECTED_ITEM&>( *item );
1036 
1037  selectAllItemsOnNet( connItem.GetNetCode() );
1038  }
1039  }
1040 
1041  // Inform other potentially interested tools
1042  if( m_selection.Size() > 0 )
1044 
1045  return 0;
1046 }
1047 
1048 
1049 void SELECTION_TOOL::selectAllItemsOnSheet( wxString& aSheetpath )
1050 {
1051  auto modules = board()->m_Modules.GetFirst();
1052  std::list<MODULE*> modList;
1053 
1054  // store all modules that are on that sheet
1055  for( MODULE* mitem = modules; mitem; mitem = mitem->Next() )
1056  {
1057  if( mitem != NULL && mitem->GetPath().Contains( aSheetpath ) )
1058  {
1059  modList.push_back( mitem );
1060  }
1061  }
1062 
1063  //Generate a list of all pads, and of all nets they belong to.
1064  std::list<int> netcodeList;
1065  std::list<BOARD_CONNECTED_ITEM*> padList;
1066  for( MODULE* mmod : modList )
1067  {
1068  for( auto pad : mmod->Pads() )
1069  {
1070  if( pad->IsConnected() )
1071  {
1072  netcodeList.push_back( pad->GetNetCode() );
1073  padList.push_back( pad );
1074  }
1075  }
1076  }
1077  // remove all duplicates
1078  netcodeList.sort();
1079  netcodeList.unique();
1080 
1081  // auto select trivial connections segments which are launched from the pads
1082  std::list<TRACK*> launchTracks;
1083 
1084  for( auto pad : padList )
1085  {
1086  launchTracks = board()->GetTracksByPosition( pad->GetPosition() );
1087 
1088  for( auto track : launchTracks )
1089  {
1091  }
1092  }
1093 
1094  // now we need to find all modules that are connected to each of these nets
1095  // then we need to determine if these modules are in the list of modules
1096  // belonging to this sheet ( modList )
1097  std::list<int> removeCodeList;
1098  constexpr KICAD_T padType[] = { PCB_PAD_T, EOT };
1099 
1100  for( int netCode : netcodeList )
1101  {
1102  for( BOARD_CONNECTED_ITEM* mitem : board()->GetConnectivity()->GetNetItems( netCode, padType ) )
1103  {
1104  if( mitem->Type() == PCB_PAD_T)
1105  {
1106  bool found = ( std::find( modList.begin(), modList.end(),
1107  mitem->GetParent() ) != modList.end() );
1108 
1109  if( !found )
1110  {
1111  // if we cannot find the module of the pad in the modList
1112  // then we can assume that that module is not located in the same
1113  // schematic, therefore invalidate this netcode.
1114  removeCodeList.push_back( netCode );
1115  break;
1116  }
1117  }
1118  }
1119  }
1120 
1121  // remove all duplicates
1122  removeCodeList.sort();
1123  removeCodeList.unique();
1124 
1125  for( int removeCode : removeCodeList )
1126  {
1127  netcodeList.remove( removeCode );
1128  }
1129 
1130  std::list<BOARD_CONNECTED_ITEM*> localConnectionList;
1131  constexpr KICAD_T trackViaType[] = { PCB_TRACE_T, PCB_VIA_T, EOT };
1132 
1133  for( int netCode : netcodeList )
1134  {
1135  for( BOARD_CONNECTED_ITEM* item : board()->GetConnectivity()->GetNetItems( netCode, trackViaType ) )
1136  {
1137  localConnectionList.push_back( item );
1138  }
1139  }
1140 
1141  for( BOARD_ITEM* i : modList )
1142  {
1143  if( i != NULL )
1144  select( i );
1145  }
1146 
1147  for( BOARD_CONNECTED_ITEM* i : localConnectionList )
1148  {
1149  if( i != NULL )
1150  select( i );
1151  }
1152 }
1153 
1154 
1156 {
1157  //Should recalculate the view to zoom in on the selection
1158  auto selectionBox = m_selection.ViewBBox();
1159  auto canvas = m_frame->GetGalCanvas();
1160  auto view = getView();
1161 
1162  VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
1163 
1164  if( !( selectionBox.GetWidth() == 0 ) || !( selectionBox.GetHeight() == 0 ) )
1165  {
1166  VECTOR2D vsize = selectionBox.GetSize();
1167  double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
1168  fabs( vsize.y / screenSize.y ) );
1169  view->SetScale( scale );
1170  view->SetCenter( selectionBox.Centre() );
1171  view->Add( &m_selection );
1172  }
1173 
1175 }
1176 
1177 
1179 {
1180  clearSelection();
1181  wxString* sheetpath = aEvent.Parameter<wxString*>();
1182 
1183  selectAllItemsOnSheet( *sheetpath );
1184 
1185  zoomFitSelection();
1186 
1187  if( m_selection.Size() > 0 )
1189 
1190  return 0;
1191 }
1192 
1193 
1195 {
1196  if( !selectCursor( true ) )
1197  return 0;
1198 
1199  // this function currently only supports modules since they are only
1200  // on one sheet.
1201  auto item = m_selection.Front();
1202 
1203  if( !item )
1204  return 0;
1205 
1206  if( item->Type() != PCB_MODULE_T )
1207  return 0;
1208 
1209  auto mod = dynamic_cast<MODULE*>( item );
1210 
1211  clearSelection();
1212 
1213  // get the lowest subsheet name for this.
1214  wxString sheetPath = mod->GetPath();
1215  sheetPath = sheetPath.BeforeLast( '/' );
1216  sheetPath = sheetPath.AfterLast( '/' );
1217 
1218  selectAllItemsOnSheet( sheetPath );
1219 
1220  // Inform other potentially interested tools
1221  if( m_selection.Size() > 0 )
1223 
1224  return 0;
1225 }
1226 
1227 
1229 {
1230  clearSelection();
1231 
1232  if( aItem )
1233  {
1234  select( aItem );
1235  getView()->SetCenter( aItem->GetPosition() );
1236 
1237  // Inform other potentially interested tools
1239  }
1240 
1242 }
1243 
1244 
1245 int SELECTION_TOOL::find( const TOOL_EVENT& aEvent )
1246 {
1247  DIALOG_FIND dlg( m_frame );
1248  dlg.SetCallback( std::bind( &SELECTION_TOOL::findCallback, this, _1 ) );
1249  dlg.ShowModal();
1250 
1251  return 0;
1252 }
1253 
1254 
1256 {
1258 
1259  if( module )
1260  {
1261  KIGFX::VIEW_CONTROLS* viewCtrls = getViewControls();
1262  clearSelection();
1263  toggleSelection( module, true );
1264 
1265  auto cursorPosition = viewCtrls->GetCursorPosition( false );
1266 
1267  // Set a reference point so InteractiveEdit will move it to the
1268  // cursor before waiting for mouse move events
1270 
1271  // Place event on module origin first, so the generic anchor snap
1272  // doesn't just choose the closest pin for us
1273  viewCtrls->ForceCursorPosition( true, module->GetPosition() );
1274 
1275  // pick the component up and start moving
1276  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
1277 
1278  // restore the previous cursor position
1279  viewCtrls->SetCursorPosition( cursorPosition, false );
1280  }
1281 
1282  return 0;
1283 }
1284 
1285 
1294 static bool itemIsIncludedByFilter( const BOARD_ITEM& aItem,
1295  const BOARD& aBoard,
1296  const DIALOG_BLOCK_OPTIONS::OPTIONS& aBlockOpts )
1297 {
1298  bool include = true;
1299  const PCB_LAYER_ID layer = aItem.GetLayer();
1300 
1301  // can skip without even checking item type
1302  // fixme: selecting items on invisible layers does not work in GAL
1303  if( !aBlockOpts.includeItemsOnInvisibleLayers
1304  && !aBoard.IsLayerVisible( layer ) )
1305  {
1306  include = false;
1307  }
1308 
1309  // if the item needs to be checked against the options
1310  if( include )
1311  {
1312  switch( aItem.Type() )
1313  {
1314  case PCB_MODULE_T:
1315  {
1316  const auto& module = static_cast<const MODULE&>( aItem );
1317 
1318  include = aBlockOpts.includeModules;
1319 
1320  if( include && !aBlockOpts.includeLockedModules )
1321  {
1322  include = !module.IsLocked();
1323  }
1324 
1325  break;
1326  }
1327  case PCB_TRACE_T:
1328  {
1329  include = aBlockOpts.includeTracks;
1330  break;
1331  }
1332  case PCB_VIA_T:
1333  {
1334  include = aBlockOpts.includeVias;
1335  break;
1336  }
1337  case PCB_ZONE_AREA_T:
1338  {
1339  include = aBlockOpts.includeZones;
1340  break;
1341  }
1342  case PCB_LINE_T:
1343  case PCB_TARGET_T:
1344  case PCB_DIMENSION_T:
1345  {
1346  if( layer == Edge_Cuts )
1347  include = aBlockOpts.includeBoardOutlineLayer;
1348  else
1349  include = aBlockOpts.includeItemsOnTechLayers;
1350  break;
1351  }
1352  case PCB_TEXT_T:
1353  {
1354  include = aBlockOpts.includePcbTexts;
1355  break;
1356  }
1357  default:
1358  {
1359  // no filtering, just select it
1360  break;
1361  }
1362  }
1363  }
1364 
1365  return include;
1366 }
1367 
1368 
1370 {
1371  auto& opts = m_priv->m_filterOpts;
1372  DIALOG_BLOCK_OPTIONS dlg( m_frame, opts, false, _( "Filter selection" ) );
1373 
1374  const int cmd = dlg.ShowModal();
1375 
1376  if( cmd != wxID_OK )
1377  return 0;
1378 
1379  const auto& board = *getModel<BOARD>();
1380 
1381  // copy current selection
1382  auto selection = m_selection.GetItems();
1383 
1384  // clear current selection
1385  clearSelection();
1386 
1387  // copy selection items from the saved selection
1388  // according to the dialog options
1389  for( auto i : selection )
1390  {
1391  auto item = static_cast<BOARD_ITEM*>( i );
1392  bool include = itemIsIncludedByFilter( *item, board, opts );
1393 
1394  if( include )
1395  {
1396  select( item );
1397  }
1398  }
1399  return 0;
1400 }
1401 
1402 
1404 {
1405  if( m_selection.Empty() )
1406  return;
1407 
1408  while( m_selection.GetSize() )
1409  unhighlight( static_cast<BOARD_ITEM*>( m_selection.Front() ), SELECTED, m_selection );
1410 
1411  view()->Update( &m_selection );
1412 
1413  m_selection.SetIsHover( false );
1415 
1416  if( m_frame )
1417  m_frame->SetCurItem( NULL );
1418 
1419  m_locked = true;
1420 
1421  // Inform other potentially interested tools
1424 }
1425 
1426 
1428 {
1429  GENERAL_COLLECTOR* collector = aEvent.Parameter<GENERAL_COLLECTOR*>();
1430 
1431  doSelectionMenu( collector, wxEmptyString );
1432 
1433  return 0;
1434 }
1435 
1436 
1437 bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxString& aTitle )
1438 {
1439  BOARD_ITEM* current = nullptr;
1440  SELECTION highlightGroup;
1441  CONTEXT_MENU menu;
1442 
1443  highlightGroup.SetLayer( LAYER_SELECT_OVERLAY );
1444  getView()->Add( &highlightGroup );
1445 
1446  int limit = std::min( 9, aCollector->GetCount() );
1447 
1448  for( int i = 0; i < limit; ++i )
1449  {
1450  wxString text;
1451  BOARD_ITEM* item = ( *aCollector )[i];
1452  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
1453 
1454  wxString menuText = wxString::Format("&%d. %s", i + 1, text );
1455  menu.Add( menuText, i + 1, item->GetMenuImage() );
1456  }
1457 
1458  if( aTitle.Length() )
1459  menu.SetTitle( aTitle );
1460 
1461  menu.SetIcon( info_xpm );
1462  menu.DisplayTitle( true );
1463  SetContextMenu( &menu, CMENU_NOW );
1464 
1465  while( OPT_TOOL_EVENT evt = Wait() )
1466  {
1467  if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
1468  {
1469  if( current )
1470  unhighlight( current, BRIGHTENED, highlightGroup );
1471 
1472  int id = *evt->GetCommandId();
1473 
1474  // User has pointed an item, so show it in a different way
1475  if( id > 0 && id <= limit )
1476  {
1477  current = ( *aCollector )[id - 1];
1478  highlight( current, BRIGHTENED, highlightGroup );
1479  }
1480  else
1481  {
1482  current = NULL;
1483  }
1484  }
1485  else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
1486  {
1487  if( current )
1488  unhighlight( current, BRIGHTENED, highlightGroup );
1489 
1490  OPT<int> id = evt->GetCommandId();
1491 
1492  // User has selected an item, so this one will be returned
1493  if( id && ( *id > 0 ) )
1494  current = ( *aCollector )[*id - 1];
1495  else
1496  current = NULL;
1497 
1498  break;
1499  }
1500  }
1501  getView()->Remove( &highlightGroup );
1502 
1503  if( current )
1504  {
1505  aCollector->Empty();
1506  aCollector->Append( current );
1507  return true;
1508  }
1509 
1510  return false;
1511 }
1512 
1513 
1515 {
1516  int count = aCollector->GetPrimaryCount(); // try to use preferred layer
1517 
1518  if( 0 == count )
1519  count = aCollector->GetCount();
1520 
1521  for( int i = 0; i < count; ++i )
1522  {
1523  if( ( *aCollector )[i]->Type() != PCB_MODULE_T )
1524  return NULL;
1525  }
1526 
1527  // All are modules, now find smallest MODULE
1528  int minDim = 0x7FFFFFFF;
1529  int minNdx = 0;
1530 
1531  for( int i = 0; i < count; ++i )
1532  {
1533  MODULE* module = (MODULE*) ( *aCollector )[i];
1534 
1535  int lx = module->GetFootprintRect().GetWidth();
1536  int ly = module->GetFootprintRect().GetHeight();
1537 
1538  int lmin = std::min( lx, ly );
1539 
1540  if( lmin < minDim )
1541  {
1542  minDim = lmin;
1543  minNdx = i;
1544  }
1545  }
1546 
1547  return (*aCollector)[minNdx];
1548 }
1549 
1550 
1551 bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem, bool checkVisibilityOnly ) const
1552 {
1553  // Is high contrast mode enabled?
1554  bool highContrast = getView()->GetPainter()->GetSettings()->GetHighContrast();
1555 
1556  int layers[KIGFX::VIEW::VIEW_MAX_LAYERS], layers_count;
1557 
1558  // Filter out items that do not belong to active layers
1559  std::set<unsigned int> activeLayers = getView()->GetPainter()->GetSettings()->GetActiveLayers();
1560 
1561  // The markers layer is considered to be always active
1562  activeLayers.insert( (unsigned int) LAYER_DRC );
1563 
1564  aItem->ViewGetLayers( layers, layers_count );
1565 
1566  if( highContrast )
1567  {
1568  bool onActive = false; // Is the item on any of active layers?
1569 
1570  for( int i = 0; i < layers_count; ++i )
1571  {
1572  if( activeLayers.count( layers[i] ) > 0 ) // Item is on at least one of the active layers
1573  {
1574  onActive = true;
1575  break;
1576  }
1577  }
1578 
1579  if( !onActive ) // We do not want to select items that are in the background
1580  {
1581  return false;
1582  }
1583  }
1584 
1585  switch( aItem->Type() )
1586  {
1587  case PCB_ZONE_AREA_T:
1588  // Keepout zones can exist on multiple layers!
1589  {
1590  auto* zone = static_cast<const ZONE_CONTAINER*>( aItem );
1591 
1592  if( zone->GetIsKeepout() )
1593  {
1594  auto zoneLayers = zone->GetLayerSet().Seq();
1595 
1596  for( unsigned int i = 0; i < zoneLayers.size(); i++ )
1597  {
1598  if( board()->IsLayerVisible( zoneLayers[i] ) )
1599  {
1600  return true;
1601  }
1602  }
1603 
1604  // No active layers selected!
1605  return false;
1606  }
1607  }
1608  break;
1609 
1610  case PCB_TRACE_T:
1611  {
1612  if( !board()->IsElementVisible( LAYER_TRACKS ) )
1613  return false;
1614  }
1615  break;
1616 
1617  case PCB_VIA_T:
1618  {
1619  const VIA* via = static_cast<const VIA*>( aItem );
1620 
1621  // Check if appropriate element layer is visible
1622  switch( via->GetViaType() )
1623  {
1624  case VIA_THROUGH:
1626  return false;
1627  break;
1628 
1629  case VIA_BLIND_BURIED:
1631  return false;
1632  break;
1633 
1634  case VIA_MICROVIA:
1636  return false;
1637  break;
1638 
1639  default:
1640  wxFAIL;
1641  return false;
1642  }
1643 
1644  // For vias it is enough if only one of its layers is visible
1645  return ( board()->GetVisibleLayers() & via->GetLayerSet() ).any();
1646  }
1647 
1648  case PCB_MODULE_T:
1649  {
1650  // In modedit, we do not want to select the module itself.
1651  if( m_editModules )
1652  return false;
1653 
1654  // Allow selection of footprints if some part of the footprint is visible.
1655 
1656  MODULE* module = const_cast<MODULE*>( static_cast<const MODULE*>( aItem ) );
1657 
1658  for( auto item : module->GraphicalItems() )
1659  {
1660  if( selectable( item, true ) )
1661  return true;
1662  }
1663 
1664  for( auto pad : module->Pads() )
1665  {
1666  if( selectable( pad, true ) )
1667  return true;
1668  }
1669 
1670  return false;
1671  }
1672 
1673  case PCB_MODULE_TEXT_T:
1674  // Multiple selection is only allowed in modedit mode. In pcbnew, you have to select
1675  // module subparts one by one, rather than with a drag selection. This is so you can
1676  // pick up items under an (unlocked) module without also moving the module's sub-parts.
1677  if( !m_editModules && !checkVisibilityOnly )
1678  {
1679  if( m_multiple )
1680  return false;
1681  }
1682 
1683  if( !m_editModules && !view()->IsVisible( aItem ) )
1684  return false;
1685 
1686  break;
1687 
1688  case PCB_MODULE_EDGE_T:
1689  case PCB_PAD_T:
1690  {
1691  // Multiple selection is only allowed in modedit mode. In pcbnew, you have to select
1692  // module subparts one by one, rather than with a drag selection. This is so you can
1693  // pick up items under an (unlocked) module without also moving the module's sub-parts.
1694  if( !m_editModules && !checkVisibilityOnly )
1695  {
1696  if( m_multiple )
1697  return false;
1698  }
1699 
1700  if( aItem->Type() == PCB_PAD_T )
1701  {
1702  auto pad = static_cast<const D_PAD*>( aItem );
1703 
1704  // In pcbnew, locked modules prevent individual pad selection.
1705  // In modedit, we don't enforce this as the module is assumed to be edited by design.
1706  if( !m_editModules && !checkVisibilityOnly )
1707  {
1708  if( pad->GetParent() && pad->GetParent()->IsLocked() )
1709  return false;
1710  }
1711 
1712  // Check render mode (from the Items tab) first
1713  switch( pad->GetAttribute() )
1714  {
1715  case PAD_ATTRIB_STANDARD:
1717  if( !board()->IsElementVisible( LAYER_PADS_TH ) )
1718  return false;
1719  break;
1720 
1721  case PAD_ATTRIB_CONN:
1722  case PAD_ATTRIB_SMD:
1723  if( pad->IsOnLayer( F_Cu ) && !board()->IsElementVisible( LAYER_PAD_FR ) )
1724  return false;
1725  else if( pad->IsOnLayer( B_Cu ) && !board()->IsElementVisible( LAYER_PAD_BK ) )
1726  return false;
1727  break;
1728  }
1729 
1730  // Otherwise, pads are selectable if any draw layer is visible
1731 
1732  // Shortcut: check copper layer visibility
1733  if( board()->IsLayerVisible( F_Cu ) && pad->IsOnLayer( F_Cu ) )
1734  return true;
1735 
1736  if( board()->IsLayerVisible( B_Cu ) && pad->IsOnLayer( B_Cu ) )
1737  return true;
1738 
1739  // Now check the non-copper layers
1740 
1741  bool draw_layer_visible = false;
1742 
1743  int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
1744  pad->ViewGetLayers( pad_layers, pad_layers_count );
1745 
1746  for( int i = 0; i < pad_layers_count; ++i )
1747  {
1748  // NOTE: Only checking the regular layers (not GAL meta-layers)
1749  if( ( ( pad_layers[i] < PCB_LAYER_ID_COUNT ) &&
1750  board()->IsLayerVisible( static_cast<PCB_LAYER_ID>( pad_layers[i] ) ) ) )
1751  {
1752  draw_layer_visible = true;
1753  }
1754  }
1755 
1756  return draw_layer_visible;
1757  }
1758 
1759  break;
1760  }
1761 
1762 
1763  case PCB_MARKER_T: // Always selectable
1764  return true;
1765 
1766  // These are not selectable
1767  case NOT_USED:
1768  case TYPE_NOT_INIT:
1769  return false;
1770 
1771  default: // Suppress warnings
1772  break;
1773  }
1774 
1775  // All other items are selected only if the layer on which they exist is visible
1776  return board()->IsLayerVisible( aItem->GetLayer() );
1777 }
1778 
1779 
1781 {
1782  if( aItem->IsSelected() )
1783  {
1784  return;
1785  }
1786 
1787  if( aItem->Type() == PCB_PAD_T )
1788  {
1789  MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
1790 
1791  if( m_selection.Contains( module ) )
1792  return;
1793  }
1794 
1795  highlight( aItem, SELECTED, m_selection );
1796  view()->Update( &m_selection );
1797 
1798  if( m_frame )
1799  {
1800  if( m_selection.Size() == 1 )
1801  {
1802  // Set as the current item, so the information about selection is displayed
1803  m_frame->SetCurItem( aItem, true );
1804  }
1805  else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
1806  { // called for every next selected item
1807  // If multiple items are selected, do not show the information about the selected item
1808  m_frame->SetCurItem( NULL, true );
1809  }
1810  }
1811 }
1812 
1813 
1815 {
1816  unhighlight( aItem, SELECTED, m_selection );
1817  view()->Update( &m_selection );
1818 
1819  if( m_frame && m_frame->GetCurItem() == aItem )
1820  m_frame->SetCurItem( NULL );
1821 
1822  if( m_selection.Empty() )
1823  m_locked = true;
1824 }
1825 
1826 
1827 void SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGroup )
1828 {
1829  if( aMode == SELECTED )
1830  aItem->SetSelected();
1831  else if( aMode == BRIGHTENED )
1832  aItem->SetBrightened();
1833 
1834  // Hide the original item, so it is shown only on overlay
1835  view()->Hide( aItem, true );
1836 
1837  aGroup.Add( aItem );
1838 
1839  // Modules are treated in a special way - when they are highlighted, we have to
1840  // highlight all the parts that make the module, not the module itself
1841  if( aItem->Type() == PCB_MODULE_T )
1842  {
1843  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1844  {
1845  if( aMode == SELECTED )
1846  item->SetSelected();
1847  else if( aMode == BRIGHTENED )
1848  {
1849  item->SetBrightened();
1850  aGroup.Add( item );
1851  }
1852  view()->Hide( item, true );
1853  });
1854  }
1855 
1856  // Many selections are very temporal and updating the display each time just
1857  // creates noise.
1858  if( aMode == BRIGHTENED )
1860 }
1861 
1862 
1863 void SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGroup )
1864 {
1865  if( aMode == SELECTED )
1866  aItem->ClearSelected();
1867  else if( aMode == BRIGHTENED )
1868  aItem->ClearBrightened();
1869 
1870  aGroup.Remove( aItem );
1871 
1872  // Restore original item visibility
1873  view()->Hide( aItem, false );
1874  view()->Update( aItem );
1875 
1876  // Modules are treated in a special way - when they are highlighted, we have to
1877  // highlight all the parts that make the module, not the module itself
1878  if( aItem->Type() == PCB_MODULE_T )
1879  {
1880  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1881  {
1882  if( aMode == SELECTED )
1883  item->ClearSelected();
1884  else if( aMode == BRIGHTENED )
1885  item->ClearBrightened();
1886 
1887  // N.B. if we clear the selection flag for sub-elements, we need to also
1888  // remove the element from the selection group (if it exists)
1889  aGroup.Remove( item );
1890  view()->Hide( item, false );
1891  view()->Update( item );
1892  });
1893  }
1894 
1895  // Many selections are very temporal and updating the display each time just
1896  // creates noise.
1897  if( aMode == BRIGHTENED )
1899 }
1900 
1901 
1902 bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
1903 {
1904  const unsigned GRIP_MARGIN = 20;
1905  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
1906 
1907  // Check if the point is located within any of the currently selected items bounding boxes
1908  for( auto item : m_selection )
1909  {
1910  BOX2I itemBox = item->ViewBBox();
1911  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
1912 
1913  if( itemBox.Contains( aPoint ) )
1914  return true;
1915  }
1916 
1917  return false;
1918 }
1919 
1920 
1921 static double calcArea( const BOARD_ITEM* aItem )
1922 {
1923  if( aItem->Type() == PCB_TRACE_T )
1924  {
1925  const TRACK* t = static_cast<const TRACK*>( aItem );
1926  return ( t->GetWidth() + t->GetLength() ) * t->GetWidth();
1927  }
1928 
1929  return getRect( aItem ).GetArea();
1930 }
1931 
1932 
1933 /*static double calcMinArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1934 {
1935  double best = std::numeric_limits<double>::max();
1936 
1937  if( !aCollector.GetCount() )
1938  return 0.0;
1939 
1940  for( int i = 0; i < aCollector.GetCount(); i++ )
1941  {
1942  BOARD_ITEM* item = aCollector[i];
1943  if( item->Type() == aType )
1944  best = std::min( best, calcArea( item ) );
1945  }
1946 
1947  return best;
1948 }*/
1949 
1950 
1951 static double calcMaxArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1952 {
1953  double best = 0.0;
1954 
1955  for( int i = 0; i < aCollector.GetCount(); i++ )
1956  {
1957  BOARD_ITEM* item = aCollector[i];
1958  if( item->Type() == aType )
1959  best = std::max( best, calcArea( item ) );
1960  }
1961 
1962  return best;
1963 }
1964 
1965 
1966 static inline double calcCommonArea( const BOARD_ITEM* aItem, const BOARD_ITEM* aOther )
1967 {
1968  if( !aItem || !aOther )
1969  return 0;
1970 
1971  return getRect( aItem ).Common( getRect( aOther ) ).GetArea();
1972 }
1973 
1974 
1975 double calcRatio( double a, double b )
1976 {
1977  if( a == 0.0 && b == 0.0 )
1978  return 1.0;
1979 
1980  if( b == 0.0 )
1982 
1983  return a / b;
1984 }
1985 
1986 
1987 // The general idea here is that if the user clicks directly on a small item inside a larger
1988 // one, then they want the small item. The quintessential case of this is clicking on a pad
1989 // within a footprint, but we also apply it for text within a footprint, footprints within
1990 // larger footprints, and vias within either larger pads or longer tracks.
1991 //
1992 // These "guesses" presume there is area within the larger item to click in to select it. If
1993 // an item is mostly covered by smaller items within it, then the guesses are inappropriate as
1994 // there might not be any area left to click to select the larger item. In this case we must
1995 // leave the items in the collector and bring up a Selection Clarification menu.
1996 //
1997 // We currently check for pads and text mostly covering a footprint, but we don’t check for
1998 // smaller footprints mostly covering a larger footprint.
1999 //
2001  const VECTOR2I& aWhere ) const
2002 {
2003  std::set<BOARD_ITEM*> preferred;
2004  std::set<BOARD_ITEM*> rejected;
2005  std::set<BOARD_ITEM*> forced;
2006  wxPoint where( aWhere.x, aWhere.y );
2007 
2008  // footprints which are below this percentage of the largest footprint will be considered
2009  // for selection; all others will not
2010  constexpr double footprintToFootprintMinRatio = 0.20;
2011  // pads which are below this percentage of their parent's area will exclude their parent
2012  constexpr double padToFootprintMinRatio = 0.45;
2013  // footprints containing items with items-to-footprint area ratio higher than this will be
2014  // forced to stay on the list
2015  constexpr double footprintMaxCoverRatio = 0.80;
2016  constexpr double viaToPadMinRatio = 0.50;
2017  constexpr double trackViaLengthRatio = 2.0;
2018  constexpr double trackTrackLengthRatio = 0.3;
2019  constexpr double textToFeatureMinRatio = 0.2;
2020  constexpr double textToFootprintMinRatio = 0.4;
2021  // If the common area of two compared items is above the following threshold, they cannot
2022  // be rejected (it means they overlap and it might be hard to pick one by selecting
2023  // its unique area).
2024  constexpr double commonAreaRatio = 0.6;
2025 
2026  PCB_LAYER_ID activeLayer = (PCB_LAYER_ID) view()->GetTopLayer();
2027  LSET silkLayers( 2, B_SilkS, F_SilkS );
2028 
2029  if( silkLayers[activeLayer] )
2030  {
2031  for( int i = 0; i < aCollector.GetCount(); ++i )
2032  {
2033  BOARD_ITEM* item = aCollector[i];
2034  KICAD_T type = item->Type();
2035 
2036  if( ( type == PCB_MODULE_TEXT_T || type == PCB_TEXT_T || type == PCB_LINE_T )
2037  && silkLayers[item->GetLayer()] )
2038  {
2039  preferred.insert( item );
2040  }
2041  }
2042 
2043  if( preferred.size() > 0 )
2044  {
2045  aCollector.Empty();
2046 
2047  for( BOARD_ITEM* item : preferred )
2048  aCollector.Append( item );
2049  return;
2050  }
2051  }
2052 
2053  int numZones = aCollector.CountType( PCB_ZONE_AREA_T );
2054 
2055  // Zone edges are very specific; zone fills much less so.
2056  if( numZones > 0 )
2057  {
2058  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2059  {
2060  if( aCollector[i]->Type() == PCB_ZONE_AREA_T )
2061  {
2062  auto zone = static_cast<ZONE_CONTAINER*>( aCollector[i] );
2063 
2064  if( zone->HitTestForEdge( where, 5 * aCollector.GetGuide()->OnePixelInIU() ) )
2065  preferred.insert( zone );
2066  else
2067  rejected.insert( zone );
2068  }
2069  }
2070 
2071  if( preferred.size() > 0 )
2072  {
2073  aCollector.Empty();
2074 
2075  for( BOARD_ITEM* item : preferred )
2076  aCollector.Append( item );
2077  return;
2078  }
2079  }
2080 
2081  if( aCollector.CountType( PCB_MODULE_TEXT_T ) > 0 )
2082  {
2083  for( int i = 0; i < aCollector.GetCount(); ++i )
2084  {
2085  if( TEXTE_MODULE* txt = dyn_cast<TEXTE_MODULE*>( aCollector[i] ) )
2086  {
2087  double textArea = calcArea( txt );
2088 
2089  for( int j = 0; j < aCollector.GetCount(); ++j )
2090  {
2091  if( i == j )
2092  continue;
2093 
2094  BOARD_ITEM* item = aCollector[j];
2095  double itemArea = calcArea( item );
2096  double areaRatio = calcRatio( textArea, itemArea );
2097  double commonArea = calcCommonArea( txt, item );
2098  double itemCommonRatio = calcRatio( commonArea, itemArea );
2099  double txtCommonRatio = calcRatio( commonArea, textArea );
2100 
2101  if( item->Type() == PCB_MODULE_T )
2102  {
2103  // when text area is small compared to an overlapping footprint,
2104  // then it's a clear sign the text is the selection target
2105  if( areaRatio < textToFootprintMinRatio && itemCommonRatio < commonAreaRatio )
2106  rejected.insert( item );
2107  }
2108 
2109  switch( item->Type() )
2110  {
2111  case PCB_TRACE_T:
2112  case PCB_PAD_T:
2113  case PCB_LINE_T:
2114  case PCB_VIA_T:
2115  case PCB_MODULE_T:
2116  if( areaRatio > textToFeatureMinRatio && txtCommonRatio < commonAreaRatio )
2117  rejected.insert( txt );
2118  break;
2119  default:
2120  break;
2121  }
2122  }
2123  }
2124  }
2125  }
2126 
2127  if( aCollector.CountType( PCB_PAD_T ) > 0 )
2128  {
2129  for( int i = 0; i < aCollector.GetCount(); ++i )
2130  {
2131  if( D_PAD* pad = dyn_cast<D_PAD*>( aCollector[i] ) )
2132  {
2133  MODULE* parent = pad->GetParent();
2134  double ratio = calcRatio( calcArea( pad ), calcArea( parent ) );
2135 
2136  // when pad area is small compared to the parent footprint,
2137  // then it is a clear sign the pad is the selection target
2138  if( ratio < padToFootprintMinRatio )
2139  rejected.insert( pad->GetParent() );
2140  }
2141  }
2142  }
2143 
2144  int moduleCount = aCollector.CountType( PCB_MODULE_T );
2145 
2146  if( moduleCount > 0 )
2147  {
2148  double maxArea = calcMaxArea( aCollector, PCB_MODULE_T );
2149  BOX2D viewportD = getView()->GetViewport();
2150  BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
2151  double maxCoverRatio = footprintMaxCoverRatio;
2152 
2153  // MODULE::CoverageRatio() doesn't take zone handles & borders into account so just
2154  // use a more aggressive cutoff point if zones are involved.
2155  if( aCollector.CountType( PCB_ZONE_AREA_T ) )
2156  maxCoverRatio /= 2;
2157 
2158  for( int i = 0; i < aCollector.GetCount(); ++i )
2159  {
2160  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[i] ) )
2161  {
2162  // filter out components larger than the viewport
2163  if( mod->ViewBBox().Contains( viewport ) )
2164  rejected.insert( mod );
2165  // footprints completely covered with other features have no other
2166  // means of selection, so must be kept
2167  else if( mod->CoverageRatio( aCollector ) > maxCoverRatio )
2168  rejected.erase( mod );
2169  // if a footprint is much smaller than the largest overlapping
2170  // footprint then it should be considered for selection
2171  else if( calcRatio( calcArea( mod ), maxArea ) <= footprintToFootprintMinRatio )
2172  continue;
2173  // reject ALL OTHER footprints if there's still something else left
2174  // to select
2175  else if( (int)( rejected.size() + 1 ) < aCollector.GetCount() )
2176  rejected.insert( mod );
2177  }
2178  }
2179  }
2180 
2181  if( aCollector.CountType( PCB_VIA_T ) > 0 )
2182  {
2183  for( int i = 0; i < aCollector.GetCount(); ++i )
2184  {
2185  if( VIA* via = dyn_cast<VIA*>( aCollector[i] ) )
2186  {
2187  double viaArea = calcArea( via );
2188 
2189  for( int j = 0; j < aCollector.GetCount(); ++j )
2190  {
2191  if( i == j )
2192  continue;
2193 
2194  BOARD_ITEM* item = aCollector[j];
2195  double areaRatio = calcRatio( viaArea, calcArea( item ) );
2196 
2197  if( item->Type() == PCB_MODULE_T && areaRatio < padToFootprintMinRatio )
2198  rejected.insert( item );
2199 
2200  if( item->Type() == PCB_PAD_T && areaRatio < viaToPadMinRatio )
2201  rejected.insert( item );
2202 
2203  if( TRACK* track = dyn_cast<TRACK*>( item ) )
2204  {
2205  if( track->GetNetCode() != via->GetNetCode() )
2206  continue;
2207 
2208  double lenRatio = (double) ( track->GetLength() + track->GetWidth() ) /
2209  (double) via->GetWidth();
2210 
2211  if( lenRatio > trackViaLengthRatio )
2212  rejected.insert( track );
2213  }
2214  }
2215  }
2216  }
2217  }
2218 
2219  int nTracks = aCollector.CountType( PCB_TRACE_T );
2220 
2221  if( nTracks > 0 )
2222  {
2223  double maxLength = 0.0;
2224  double minLength = std::numeric_limits<double>::max();
2225  double maxArea = 0.0;
2226  const TRACK* maxTrack = nullptr;
2227 
2228  for( int i = 0; i < aCollector.GetCount(); ++i )
2229  {
2230  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
2231  {
2232  maxLength = std::max( track->GetLength(), maxLength );
2233  maxLength = std::max( (double) track->GetWidth(), maxLength );
2234 
2235  minLength = std::min( std::max( track->GetLength(), (double) track->GetWidth() ), minLength );
2236 
2237  double area = track->GetLength() * track->GetWidth();
2238 
2239  if( area > maxArea )
2240  {
2241  maxArea = area;
2242  maxTrack = track;
2243  }
2244  }
2245  }
2246 
2247  if( maxLength > 0.0 && minLength / maxLength < trackTrackLengthRatio && nTracks > 1 )
2248  {
2249  for( int i = 0; i < aCollector.GetCount(); ++i )
2250  {
2251  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
2252  {
2253  double ratio = std::max( (double) track->GetWidth(), track->GetLength() ) / maxLength;
2254 
2255  if( ratio > trackTrackLengthRatio )
2256  rejected.insert( track );
2257  }
2258  }
2259  }
2260 
2261  for( int j = 0; j < aCollector.GetCount(); ++j )
2262  {
2263  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[j] ) )
2264  {
2265  double ratio = calcRatio( maxArea, mod->GetFootprintRect().GetArea() );
2266 
2267  if( ratio < padToFootprintMinRatio && calcCommonArea( maxTrack, mod ) < commonAreaRatio )
2268  rejected.insert( mod );
2269  }
2270  }
2271  }
2272 
2273  if( (unsigned) aCollector.GetCount() > rejected.size() ) // do not remove everything
2274  {
2275  for( BOARD_ITEM* item : rejected )
2276  {
2277  aCollector.Remove( item );
2278  }
2279  }
2280 }
2281 
2282 
2284 {
2285  getView()->Update( &m_selection );
2286 
2287  return 0;
2288 }
2289 
2290 
static TOOL_ACTION selectItems
Selects a list of items (specified as the event parameter)
Definition: pcb_actions.h:60
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:123
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition: pcb_actions.h:47
void Hide(VIEW_ITEM *aItem, bool aHide=true)
Temporarily hides the item in the view (e.g.
Definition: view.cpp:1506
void ClearReferencePoint()
Definition: selection.h:210
int UnselectItem(const TOOL_EVENT &aEvent)
Item unselection event handler.
int Main(const TOOL_EVENT &aEvent)
Function Main()
void SetIgnoreTracks(bool ignore)
Definition: collectors.h:608
static double calcMaxArea(GENERAL_COLLECTOR &aCollector, KICAD_T aType)
to draw blind/buried vias
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
static const TOOL_EVENT SelectedEvent
Event sent after an item is selected.
Definition: actions.h:120
BOX2D GetViewport() const
Function GetViewport() Returns the current viewport visible area rectangle.
Definition: view.cpp:538
void SetEnd(VECTOR2I aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:90
void ForceRefresh()
Function ForceRefresh() Forces a redraw.
int GetNetCode() const
Function GetNetCode.
static const KICAD_T AllBoardItems[]
A scan list for all editable board items, like PcbGeneralLocateAndDisplay()
Definition: collectors.h:267
void SetIgnoreBlindBuriedVias(bool ignore)
Definition: collectors.h:602
void connectedItemFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
TEXTE_PCB class definition.
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:313
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, std::vector< BOARD_ITEM * > *aFiltered=NULL, bool aConfirmLockedItems=false)
Function RequestSelection()
std::unique_ptr< PRIV > m_priv
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
bool IsSelected() const
Definition: base_struct.h:227
Model changes (required full reload)
Definition: tool_base.h:83
multilayer pads, usually with holes
static const TOOL_EVENT UnselectedEvent
Event sent after an item is unselected.
Definition: actions.h:121
int selectSameSheet(const TOOL_EVENT &aEvent)
Selects all modules belonging to same hierarchical sheet as the selected footprint.
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags) override
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: pcb_view.cpp:91
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,...
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
Definition: selection.h:182
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:475
void SetOrigin(VECTOR2I aOrigin)
Set the origin of the rectange (the fixed corner)
void ClearSelected()
Definition: base_struct.h:237
Class CONTEXT_MENU.
Definition: context_menu.h:44
VIEW_CONTROLS class definition.
void Collect(BOARD_ITEM *aItem, const KICAD_T aScanList[], const wxPoint &aRefPos, const COLLECTORS_GUIDE &aGuide)
Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:473
Classes BOARD_ITEM and BOARD_CONNECTED_ITEM.
void connectedTrackFilter(const VECTOR2I &aPt, GENERAL_COLLECTOR &aCollector)
virtual double OnePixelInIU() const =0
void SetIgnoreModulesVals(bool ignore)
Definition: collectors.h:590
void SetIgnoreMicroVias(bool ignore)
Definition: collectors.h:605
Class SELECTION_TOOL.
void SetIgnoreModulesOnBack(bool ignore)
Definition: collectors.h:560
Class BOARD to handle a board.
SELECTION_LOCK_FLAGS CheckLock()
Checks if the user has agreed to modify locked items for the given selection.
static TOOL_ACTION unselectItem
Definition: pcb_actions.h:57
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:912
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:49
the 3d code uses this value
Definition: typeinfo.h:80
static TOOL_ACTION selectNet
Selects all connections belonging to a single net.
Definition: pcb_actions.h:76
const SELECTION & selection() const
Definition: pcb_tool.cpp:251
KIGFX::PCB_VIEW * view() const
Definition: pcb_tool.h:137
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:216
ITER end()
Definition: selection.h:60
static TOOL_ACTION unselectItems
Definition: pcb_actions.h:61
const GENERAL_COLLECTORS_GUIDE getCollectorsGuide() const
int find(const TOOL_EVENT &aEvent)
Find an item.
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:62
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:100
static bool itemIsIncludedByFilter(const BOARD_ITEM &aItem, const BOARD &aBoard, const DIALOG_BLOCK_OPTIONS::OPTIONS &aBlockOpts)
Function itemIsIncludedByFilter()
int findMove(const TOOL_EVENT &aEvent)
Find an item and start moving.
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:376
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:105
void AddSubMenu(std::shared_ptr< CONTEXT_MENU > aSubMenu)
Function CreateSubMenu.
Definition: tool_menu.cpp:55
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on.
ITER begin()
Definition: collector.h:92
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
int GetWidth() const
Definition: eda_rect.h:117
int UnselectItems(const TOOL_EVENT &aEvent)
Multiple item unselection event handler
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:168
void SetBrightened()
Definition: base_struct.h:235
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
void SetIgnoreModulesRefs(bool ignore)
Definition: collectors.h:596
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
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 selectionMenu
Runs a selection menu to select from a list of items.
Definition: pcb_actions.h:64
static TOOL_ACTION selectConnection
Selects a connection between junctions.
Definition: pcb_actions.h:67
Class that groups generic conditions for selected items.
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
show modules values (when texts are visibles)
Classes to handle copper zones.
Template specialization to enable wxStrings for certain containers (e.g. unordered_map)
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text.
ITER end()
Definition: collector.h:93
EDA_RECT Common(const EDA_RECT &aRect) const
Function Common returns the area that is common with another rectangle.
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
#define BUSY
Pcbnew: flag indicating that the structure has.
Definition: base_struct.h:135
void highlight(BOARD_ITEM *aItem, int aHighlightMode, SELECTION &aGroup)
Function highlight() Highlights the item visually.
const COLLECTORS_GUIDE * GetGuide()
Definition: collectors.h:347
PCB_DRAW_PANEL_GAL * canvas() const
Definition: pcb_tool.cpp:246
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
int CountType(KICAD_T aType)
Function CountType counts the number of items matching aType.
Definition: collector.h:265
bool selectionContains(const VECTOR2I &aPoint) const
Function selectionContains() Checks if the given point is placed within any of selected items' boundi...
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:250
static bool NotEmpty(const SELECTION &aSelection)
Function NotEmpty Tests if there are any items selected.
int selectConnection(const TOOL_EVENT &aEvent)
Selects a trivial connection (between two junctions) of items in selection
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void select(BOARD_ITEM *aItem)
Function select() Takes necessary action mark an item as selected.
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:143
bool InvokeTool(TOOL_ID aToolId)
Function InvokeTool() Calls a tool by sending a tool activation event to tool of given ID.
virtual void Remove(VIEW_ITEM *aItem) override
Function Remove() Removes a VIEW_ITEM from the view.
Definition: pcb_view.cpp:74
search types array terminator (End Of Types)
Definition: typeinfo.h:82
static double calcCommonArea(const BOARD_ITEM *aItem, const BOARD_ITEM *aOther)
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
static TOOL_ACTION selectionModified
Modified selection notification.
Definition: pcb_actions.h:108
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:712
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void * GetDisplayOptions() override
Function GetDisplayOptions returns the display options current in use Display options are relative to...
Pcbnew hotkeys.
double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: class_track.h:186
void SetIsHover(bool aIsHover)
Definition: selection.h:64
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon=NULL)
Function Add() Adds an entry to the menu.
BOARD_ITEM * pickSmallestComponent(GENERAL_COLLECTOR *aCollector)
Function pickSmallestComponent() Allows one to find the smallest (in terms of bounding box area) item...
Private implementation of firewalled private data.
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:74
void ClearBrightened()
Definition: base_struct.h:239
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:133
void(* CLIENT_SELECTION_FILTER)(const VECTOR2I &, GENERAL_COLLECTOR &)
show modules on front
void findCallback(BOARD_ITEM *aItem)
Find dialog callback.
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
int selectCopper(const TOOL_EVENT &aEvent)
Selects items with a continuous copper connection to items in selection
int filterSelection(const TOOL_EVENT &aEvent)
Invoke filter dialog and modify current selection
#define SELECTED
Definition: base_struct.h:121
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > GraphicalItems()
Definition: class_module.h:173
Struct that will be set with the result of the user choices in the dialog.
ITER begin()
Definition: selection.h:59
class MODULE, a footprint
Definition: typeinfo.h:89
bool selectPoint(const VECTOR2I &aWhere, bool aOnDrag=false, bool *aSelectionCancelledFlag=NULL, CLIENT_SELECTION_FILTER aClientFilter=NULL)
Function selectPoint() Selects an item pointed by the parameter aWhere.
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:205
std::list< TRACK * > GetTracksByPosition(const wxPoint &aPosition, PCB_LAYER_ID aLayer=PCB_LAYER_ID(-1)) const
Function GetTracksByPosition finds the list of tracks that starts or ends at aPosition on aLayer.
bool selectCursor(bool aForceSelect=false, CLIENT_SELECTION_FILTER aClientFilter=NULL)
Function selectCursor() Selects an item under the cursor unless there is something already selected o...
const BOX2I ViewBBox() const override
Function ViewBBox() Returns the bounding box for all stored items covering all its layers.
Class PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
PCB_LAYER_ID
A quick note on layer IDs:
void AddStandardSubMenus(EDA_DRAW_FRAME &aFrame)
Function CreateBasicMenu.
Definition: tool_menu.cpp:95
Class LSET is a set of PCB_LAYER_IDs.
int expandSelectedConnection(const TOOL_EVENT &aEvent)
Expands the current selection to select a connection between two junctions
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:601
void selectAllItemsOnSheet(wxString &aSheetpath)
Selects all items with the given sheet timestamp name (the sheet path)
void SetSelected()
Definition: base_struct.h:233
static TOOL_ACTION find
Find an item.
Definition: pcb_actions.h:337
void SetIgnoreMTextsOnBack(bool ignore)
Definition: collectors.h:548
int updateSelection(const TOOL_EVENT &aEvent)
Event handler to update the selection VIEW_ITEM.
static TOOL_ACTION hideLocalRatsnest
Definition: pcb_actions.h:333
void SetIgnorePadsOnFront(bool ignore)
Definition: collectors.h:578
int ClearSelection(const TOOL_EVENT &aEvent)
Clear current selection event handler.
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:596
bool selectMultiple()
Function selectMultiple() Handles drawing a selection box that allows one to select many items at the...
void selectAllItemsOnNet(int aNetCode)
Selects all items with the given net code.
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
bool IsVisible(const VIEW_ITEM *aItem) const
Returns information if the item is visible (or not).
Definition: view.cpp:1525
void SetIgnoreMTextsOnFront(bool ignore)
Definition: collectors.h:554
BOARD * board() const
Definition: pcb_tool.h:140
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.
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:291
int selectOnSheetFromEeschema(const TOOL_EVENT &aEvent)
Selects all modules belonging to same sheet, from Eeschema, using crossprobing
SELECTION_LOCK_FLAGS
Definition: selection.h:229
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
virtual int GetTopLayer() const
Definition: view.cpp:850
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:149
to draw usual through hole vias
Class TOOL_EVENT.
Definition: tool_event.h:168
bool Contains(EDA_ITEM *aItem) const
Definition: selection.h:108
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:293
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:127
void unhighlight(BOARD_ITEM *aItem, int aHighlightMode, SELECTION &aGroup)
Function unhighlight() Unhighlights the item visually.
SELECTION & GetSelection()
Function GetSelection()
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:138
VIATYPE_T GetViaType() const
Definition: class_track.h:439
void toggleSelection(BOARD_ITEM *aItem, bool aForce=false)
Function toggleSelection() Changes selection status of a given item.
void SetContextMenu(CONTEXT_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
void clearSelection()
Function clearSelection() Clears the current selection.
Items that may change while the view stays the same (noncached)
Definition: definitions.h:50
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
static const TOOL_EVENT ClearedEvent
Event sent after selection is cleared.
Definition: actions.h:122
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
int SelectionMenu(const TOOL_EVENT &aEvent)
Function SelectionMenu() Shows a popup menu to trim the COLLECTOR passed as aEvent's parameter down t...
double GetArea() const
Function GetArea returns the area of the rectangle.
static TOOL_ACTION selectCopper
Selects whole copper connection.
Definition: pcb_actions.h:73
bool IsCancelInteractive(const TOOL_EVENT &aEvt)
Function IsCancelInteractive()
All active tools
Definition: tool_event.h:144
void SetIgnoreMTextsMarkedNoShow(bool ignore)
Definition: collectors.h:542
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
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1539
int SelectItem(const TOOL_EVENT &aEvent)
Item selection event handler.
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:63
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:98
virtual void SetLayer(int aLayer)
Function SetLayer() Sets layer used to draw the group.
Definition: view_group.h:115
int GetHeight() const
Definition: eda_rect.h:118
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
int selectNet(const TOOL_EVENT &aEvent)
Selects all copper connections belonging to the same net(s) as the items in the selection.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:99
virtual const wxPoint GetPosition() const =0
bool m_editModules
Definition: pcb_tool.h:150
bool IsMirroredX() const
Function IsMirroredX() Returns true if view is flipped across the X axis.
Definition: view.h:230
static TOOL_ACTION expandSelectedConnection
Expands the current selection to select a connection between two junctions.
Definition: pcb_actions.h:70
static TOOL_ACTION clearHighlight
Definition: pcb_actions.h:321
const Vec & GetPosition() const
Definition: box2.h:192
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Function IsElementVisible tests whether a given element category is visible.
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:95
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
static TOOL_ACTION filterSelection
Filters the items in the current selection (invokes dialog)
Definition: pcb_actions.h:85
void Normalize()
Function Normalize ensures that the height ant width are positive.
void SetCallback(boost::function< void(BOARD_ITEM *)> aCallback)
Definition: dialog_find.h:39
bool GetHighContrast() const
Function GetHighContrast Returns information about high contrast display mode.
Definition: painter.h:161
virtual bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item.
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:300
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:454
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:97
const int scale
smd pads, front layer
int GetWidth() const
Definition: class_track.h:127
void CloseContextMenu(OPT_TOOL_EVENT &evt)
Function CloseContextMenu.
Definition: tool_menu.cpp:82
TRACK * Next() const
Definition: class_track.h:110
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:322
void AddMenu(CONTEXT_MENU *aMenu, bool aExpand=false, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddMenu()
bool IsType(FRAME_T aType) const
Class to handle a graphic segment.
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
void selectAllItemsConnectedToTrack(TRACK &aSourceTrack)
Selects all items connected by copper tracks to the given TRACK.
static TOOL_ACTION selectOnSheetFromEeschema
Selects all components on sheet from Eeschema crossprobing.
Definition: pcb_actions.h:79
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
double calcRatio(double a, double b)
DLIST< MODULE > m_Modules
Definition: class_board.h:248
bool selectable(const BOARD_ITEM *aItem, bool checkVisibilityOnly=false) const
Function selectable() Checks conditions for an item to be selected.
void SetSubtractive(bool aSubtractive)
static const KICAD_T ModuleItems[]
A scan list for primary module items.
Definition: collectors.h:308
void SetIgnoreModulesOnFront(bool ignore)
Definition: collectors.h:566
static EDA_RECT getRect(const BOARD_ITEM *aItem)
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
void SetIgnoreThroughVias(bool ignore)
Definition: collectors.h:599
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the context menu.
Class TOOL_ACTION.
Definition: tool_action.h:46
size_t i
Definition: json11.cpp:597
void unselect(BOARD_ITEM *aItem)
Function unselect() Takes necessary action mark an item as unselected.
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
Definition: pcb_actions.h:56
static void NeighboringSegmentFilter(const VECTOR2I &aPt, GENERAL_COLLECTOR &aCollector)
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Function OnlyType Creates a functor that tests if the selected items are only of given type.
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
int Size() const
Returns the number of selected parts.
Definition: selection.h:122
virtual wxString GetSelectMenuText(EDA_UNITS_T aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
currently selected items overlay
void guessSelectionCandidates(GENERAL_COLLECTOR &aCollector, const VECTOR2I &aWhere) const
Function guessSelectionCandidates() Tries to guess best selection candidates in case multiple items a...
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:139
static double calcArea(const BOARD_ITEM *aItem)
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
boost::optional< T > OPT
Definition: optional.h:7
MODULE * Next() const
Definition: class_module.h:122
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1485
int SelectItems(const TOOL_EVENT &aEvent)
Multiple item selection event handler
void zoomFitSelection()
Zooms the screen to center and fit the current selection.
Class SELECTION_AREA.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Function Add() Adds a VIEW_ITEM to the view.
Definition: pcb_view.cpp:58
MODULE * GetFootprintFromBoardByReference()
Function GetFootprintFromBoardByReference.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:346
const Vec & GetSize() const
Definition: box2.h:187
void DisplayTitle(bool aDisplay=true)
Function DisplayTitle() Decides whether a title for a pop up menu should be displayed.
static TOOL_ACTION findMove
Find an item and start moving.
Definition: pcb_actions.h:340
virtual int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Function Query() Finds all visible items that touch or are within the rectangle aRect.
Definition: view.cpp:452
Module description (excepted pads)
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
Class VIEW.
Definition: view.h:61
bool doSelectionMenu(GENERAL_COLLECTOR *aItems, const wxString &aTitle)
Allows the selection of a single item from a list via pop-up menu.
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:386
MODULE * module() const
Definition: pcb_tool.h:141
TRACK * MarkTrace(TRACK *aTrackList, TRACK *aTrace, int *aCount, double *aTraceLength, double *aInPackageLength, bool aReorder)
Function MarkTrace marks a chain of trace segments, connected to aTrace.
double GetScale() const
Function GetScale()
Definition: view.h:268
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
void SetAdditive(bool aAdditive)
BOARD_ITEM_CONTAINER * GetParent() const
BOARD_ITEM * GetCurItem()
virtual BITMAP_DEF GetMenuImage() const
Function GetMenuImage returns a pointer to an image to be used in menus.
void SetHighlight(bool aEnabled, int aNetcode=-1)
Function SetHighlight Turns on/off highlighting - it may be done for the active layer or the specifie...
Definition: painter.h:140
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetState(int type) const
Definition: base_struct.h:243
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:293
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:62
const wxPoint GetPosition() const override
Definition: class_module.h:183
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
#define mod(a, n)
Definition: greymap.cpp:24
void selectAllItemsConnectedToItem(BOARD_CONNECTED_ITEM &aSourceItem)
Selects all items connected (by copper) to the given item.
void setTransitions() override
Sets up handlers for various events.
int CursorSelection(const TOOL_EVENT &aEvent)
Select a single item under cursor event handler.
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:50
void SetIgnoreThroughHolePads(bool ignore)
Definition: collectors.h:584
show modules references (when texts are visibles)
void update() override
Update menu state stub.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false)=0
Moves cursor to the requested position expressed in world coordinates.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:152
DIALOG_BLOCK_OPTIONS::OPTIONS m_filterOpts
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:495
KICAD_T Type() const
Function Type()
Definition: base_struct.h:204
#define min(a, b)
Definition: auxiliary.h:85
const std::set< unsigned int > GetActiveLayers()
Function GetActiveLayers() Returns the set of currently active layers.
Definition: painter.h:89
static TOOL_ACTION selectSameSheet
Selects all components on the same sheet as the selected footprint.
Definition: pcb_actions.h:82
void SetIgnorePadsOnBack(bool ignore)
Definition: collectors.h:572
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:82