KiCad PCB EDA Suite
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  ACTION_MENU* create() const override
179  {
180  return new SELECT_MENU();
181  }
182 };
183 
184 
189 {
190 public:
192 };
193 
194 
196  PCB_TOOL_BASE( "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 
210 {
211  getView()->Remove( &m_selection );
212 }
213 
214 
216 {
217  auto frame = getEditFrame<PCB_BASE_FRAME>();
218 
221  {
223  return true;
224  }
225 
226  auto selectMenu = std::make_shared<SELECT_MENU>();
227  selectMenu->SetTool( this );
228  m_menu.AddSubMenu( selectMenu );
229 
230  auto& menu = m_menu.GetMenu();
231 
232  menu.AddMenu( selectMenu.get(), SELECTION_CONDITIONS::NotEmpty );
233  menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 );
234 
235  if( frame )
237 
238  return true;
239 }
240 
241 
243 {
244  m_frame = getEditFrame<PCB_BASE_FRAME>();
245  m_locked = true;
246 
247  if( aReason == TOOL_BASE::MODEL_RELOAD )
248  {
249  // Remove pointers to the selected items from containers
250  // without changing their properties (as they are already deleted
251  // while a new board is loaded)
252  m_selection.Clear();
253  getView()->GetPainter()->GetSettings()->SetHighlight( false );
254  }
255  else
256  {
257  // Restore previous properties of selected items and remove them from containers
258  clearSelection();
259  }
260 
261  // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
262  view()->Remove( &m_selection );
263  view()->Add( &m_selection );
264 }
265 
266 
267 int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
268 {
269  // Main loop: keep receiving events
270  while( OPT_TOOL_EVENT evt = Wait() )
271  {
272  // Should selected items be added to the current selection or
273  // become the new selection (discarding previously selected items)
274  m_additive = evt->Modifier( MD_SHIFT );
275 
276  // Should selected items be REMOVED from the current selection?
277  // This will be ignored if the SHIFT modifier is pressed
278  m_subtractive = !m_additive && evt->Modifier( MD_CTRL );
279 
280  // Is the user requesting that the selection list include all possible
281  // items without removing less likely selection candidates
282  m_skip_heuristics = !!evt->Modifier( MD_ALT );
283 
284  // Single click? Select single object
285  if( evt->IsClick( BUT_LEFT ) )
286  {
287  if( evt->Modifier( MD_CTRL ) && !m_editModules )
288  {
290  }
291  else
292  {
293  // If no modifier keys are pressed, clear the selection
294  if( !m_additive )
295  clearSelection();
296 
297  selectPoint( evt->Position() );
298  }
299  }
300 
301  // right click? if there is any object - show the context menu
302  else if( evt->IsClick( BUT_RIGHT ) )
303  {
304  bool selectionCancelled = false;
305 
306  if( m_selection.Empty() )
307  {
308  selectPoint( evt->Position(), false, &selectionCancelled );
309  m_selection.SetIsHover( true );
310  }
311 
312  if( !selectionCancelled )
314  }
315 
316  // double click? Display the properties window
317  else if( evt->IsDblClick( BUT_LEFT ) )
318  {
319  if( m_selection.Empty() )
320  selectPoint( evt->Position() );
321 
323  }
324 
325  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
326  else if( evt->IsDrag( BUT_LEFT ) )
327  {
328  if( m_additive || m_subtractive )
329  {
330  selectMultiple();
331  }
332  else if( m_selection.Empty() )
333  {
334  // There is nothing selected, so try to select something
335  if( getEditFrame<PCB_BASE_FRAME>()->Settings().m_dragSelects || !selectCursor() )
336  {
337  // If nothings has been selected, user wants to select more or selection
338  // box is preferred to dragging - draw selection box
339  selectMultiple();
340  }
341  else
342  {
343  m_selection.SetIsHover( true );
344  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
345  }
346  }
347 
348  else
349  {
350  // Check if dragging has started within any of selected items bounding box
351  if( selectionContains( evt->Position() ) )
352  {
353  // Yes -> run the move tool and wait till it finishes
354  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
355  }
356  else
357  {
358  // No -> clear the selection list
359  clearSelection();
360  }
361  }
362  }
363 
364  else if( evt->Action() == TA_UNDO_REDO_PRE )
365  {
366  clearSelection();
367  }
368 
369  else if( evt->IsCancel() )
370  {
371  clearSelection();
373  }
374 
375  else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
376  {
377  m_menu.CloseContextMenu( evt );
378  }
379  }
380 
381  // This tool is supposed to be active forever
382  assert( false );
383 
384  return 0;
385 }
386 
387 
389 {
390  return m_selection;
391 }
392 
393 
395  std::vector<BOARD_ITEM*>* aFiltered, bool aConfirmLockedItems )
396 {
397  bool selectionEmpty = m_selection.Empty();
398  m_selection.SetIsHover( selectionEmpty );
399 
400  if( selectionEmpty )
401  {
402  m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, aClientFilter );
404  }
405 
406  if ( aConfirmLockedItems && CheckLock() == SELECTION_LOCKED )
407  {
408  clearSelection();
409  }
410 
411  if( aClientFilter )
412  {
413  GENERAL_COLLECTOR collector;
414 
415  for( auto item : m_selection )
416  collector.Append( item );
417 
418  aClientFilter( VECTOR2I(), collector );
419 
420  /*
421  * The first step is to find the items that may have been added by the client filter
422  * This can happen if the locked pads select the module instead
423  */
424  std::vector<EDA_ITEM*> new_items;
425  std::set_difference( collector.begin(), collector.end(), m_selection.begin(), m_selection.end(),
426  std::back_inserter( new_items ) );
427 
431  std::vector<EDA_ITEM*> diff;
432  std::set_difference( m_selection.begin(), m_selection.end(), collector.begin(), collector.end(),
433  std::back_inserter( diff ) );
434 
435  if( aFiltered )
436  {
437  for( auto item : diff )
438  aFiltered->push_back( static_cast<BOARD_ITEM*>( item ) );
439  }
440 
445  for( auto item : diff )
446  unhighlight( static_cast<BOARD_ITEM*>( item ), SELECTED, m_selection );
447 
448  for( auto item : new_items )
449  highlight( static_cast<BOARD_ITEM*>( item ), SELECTED, m_selection );
450 
452  }
453 
454  return m_selection;
455 }
456 
457 
458 void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem, bool aForce )
459 {
460  if( aItem->IsSelected() )
461  {
462  unselect( aItem );
463 
464  // Inform other potentially interested tools
466  }
467  else
468  {
469  if( !m_additive )
470  clearSelection();
471 
472  // Prevent selection of invisible or inactive items
473  if( aForce || selectable( aItem ) )
474  {
475  select( aItem );
476 
477  // Inform other potentially interested tools
479  }
480  }
481 
482  if( m_frame )
484 }
485 
487 {
488  GENERAL_COLLECTORS_GUIDE guide( board()->GetVisibleLayers(),
489  (PCB_LAYER_ID) view()->GetTopLayer(), view() );
490 
491  // account for the globals
492  guide.SetIgnoreMTextsMarkedNoShow( ! board()->IsElementVisible( LAYER_MOD_TEXT_INVISIBLE ) );
493  guide.SetIgnoreMTextsOnBack( ! board()->IsElementVisible( LAYER_MOD_TEXT_BK ) );
494  guide.SetIgnoreMTextsOnFront( ! board()->IsElementVisible( LAYER_MOD_TEXT_FR ) );
495  guide.SetIgnoreModulesOnBack( ! board()->IsElementVisible( LAYER_MOD_BK ) );
496  guide.SetIgnoreModulesOnFront( ! board()->IsElementVisible( LAYER_MOD_FR ) );
497  guide.SetIgnorePadsOnBack( ! board()->IsElementVisible( LAYER_PAD_BK ) );
498  guide.SetIgnorePadsOnFront( ! board()->IsElementVisible( LAYER_PAD_FR ) );
499  guide.SetIgnoreThroughHolePads( ! board()->IsElementVisible( LAYER_PADS_TH ) );
500  guide.SetIgnoreModulesVals( ! board()->IsElementVisible( LAYER_MOD_VALUES ) );
501  guide.SetIgnoreModulesRefs( ! board()->IsElementVisible( LAYER_MOD_REFERENCES ) );
502  guide.SetIgnoreThroughVias( ! board()->IsElementVisible( LAYER_VIA_THROUGH ) );
503  guide.SetIgnoreBlindBuriedVias( ! board()->IsElementVisible( LAYER_VIA_BBLIND ) );
504  guide.SetIgnoreMicroVias( ! board()->IsElementVisible( LAYER_VIA_MICROVIA ) );
505  guide.SetIgnoreTracks( ! board()->IsElementVisible( LAYER_TRACKS ) );
506 
507  return guide;
508 }
509 
510 
511 bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
512  bool* aSelectionCancelledFlag,
513  CLIENT_SELECTION_FILTER aClientFilter )
514 {
515  auto guide = getCollectorsGuide();
516  GENERAL_COLLECTOR collector;
517  auto displayOpts = (PCB_DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
518 
519  guide.SetIgnoreZoneFills( displayOpts->m_DisplayZonesMode != 0 );
520 
521  collector.Collect( board(),
523  wxPoint( aWhere.x, aWhere.y ), guide );
524 
525  bool anyCollected = collector.GetCount() != 0;
526 
527  // Remove unselectable items
528  for( int i = collector.GetCount() - 1; i >= 0; --i )
529  {
530  if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() ) )
531  collector.Remove( i );
532  }
533 
535 
536  // Allow the client to do tool- or action-specific filtering to see if we
537  // can get down to a single item
538  if( aClientFilter )
539  aClientFilter( aWhere, collector );
540 
541  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
542  if( collector.GetCount() > 1 && !m_skip_heuristics )
543  {
544  guessSelectionCandidates( collector, aWhere );
545  }
546 
547  // If still more than one item we're going to have to ask the user.
548  if( collector.GetCount() > 1 )
549  {
550  if( aOnDrag )
551  {
553  }
554 
555  if( !doSelectionMenu( &collector, _( "Clarify Selection" ) ) )
556  {
557  if( aSelectionCancelledFlag )
558  *aSelectionCancelledFlag = true;
559 
560  return false;
561  }
562  }
563 
564  if( collector.GetCount() == 1 )
565  {
566  BOARD_ITEM* item = collector[ 0 ];
567 
568  toggleSelection( item );
569  return true;
570  }
571 
572  if( !m_additive && anyCollected )
573  clearSelection();
574 
575  return false;
576 }
577 
578 
579 bool SELECTION_TOOL::selectCursor( bool aForceSelect, CLIENT_SELECTION_FILTER aClientFilter )
580 {
581  if( aForceSelect || m_selection.Empty() )
582  {
583  clearSelection();
584  selectPoint( getViewControls()->GetCursorPosition( false ), false, NULL, aClientFilter );
585  }
586 
587  return !m_selection.Empty();
588 }
589 
590 
592 {
593  bool cancelled = false; // Was the tool cancelled while it was running?
594  m_multiple = true; // Multiple selection mode is active
595  KIGFX::VIEW* view = getView();
596 
598  view->Add( &area );
599 
600  while( OPT_TOOL_EVENT evt = Wait() )
601  {
603  {
604  cancelled = true;
605  break;
606  }
607 
608  if( evt->IsDrag( BUT_LEFT ) )
609  {
610  // Start drawing a selection box
611  area.SetOrigin( evt->DragOrigin() );
612  area.SetEnd( evt->Position() );
613  area.SetAdditive( m_additive );
615 
616  view->SetVisible( &area, true );
617  view->Update( &area );
618  getViewControls()->SetAutoPan( true );
619  }
620 
621  if( evt->IsMouseUp( BUT_LEFT ) )
622  {
623  getViewControls()->SetAutoPan( false );
624 
625  // End drawing the selection box
626  view->SetVisible( &area, false );
627 
628  // Mark items within the selection box as selected
629  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
630 
631  // Filter the view items based on the selection box
632  BOX2I selectionBox = area.ViewBBox();
633  view->Query( selectionBox, selectedItems ); // Get the list of selected items
634 
635  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
636 
637  int width = area.GetEnd().x - area.GetOrigin().x;
638  int height = area.GetEnd().y - area.GetOrigin().y;
639 
640  /* Selection mode depends on direction of drag-selection:
641  * Left > Right : Select objects that are fully enclosed by selection
642  * Right > Left : Select objects that are crossed by selection
643  */
644  bool windowSelection = width >= 0 ? true : false;
645 
646  if( view->IsMirroredX() )
647  windowSelection = !windowSelection;
648 
649  // Construct an EDA_RECT to determine BOARD_ITEM selection
650  EDA_RECT selectionRect( wxPoint( area.GetOrigin().x, area.GetOrigin().y ),
651  wxSize( width, height ) );
652 
653  selectionRect.Normalize();
654 
655  for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
656  {
657  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
658 
659  if( !item || !selectable( item ) )
660  continue;
661 
662  if( item->HitTest( selectionRect, windowSelection ) )
663  {
664  if( m_subtractive )
665  unselect( item );
666  else
667  select( item );
668  }
669  }
670 
671  if( m_frame )
672  {
673  if( m_selection.Size() == 1 )
674  m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
675  else
676  m_frame->SetCurItem( NULL );
677  }
678 
679  // Inform other potentially interested tools
680  if( !m_selection.Empty() )
682 
683  break; // Stop waiting for events
684  }
685  }
686 
687  getViewControls()->SetAutoPan( false );
688 
689  // Stop drawing the selection box
690  view->Remove( &area );
691  m_multiple = false; // Multiple selection mode is inactive
692 
693  if( !cancelled )
695 
696  return cancelled;
697 }
698 
699 
701 {
702  if( !m_locked || m_editModules )
703  return SELECTION_UNLOCKED;
704 
705  bool containsLocked = false;
706 
707  // Check if the selection contains locked items
708  for( const auto& item : m_selection )
709  {
710  switch( item->Type() )
711  {
712  case PCB_MODULE_T:
713  if( static_cast<MODULE*>( item )->IsLocked() )
714  containsLocked = true;
715  break;
716 
717  case PCB_MODULE_EDGE_T:
718  case PCB_MODULE_TEXT_T:
719  if( static_cast<MODULE*>( item->GetParent() )->IsLocked() )
720  containsLocked = true;
721  break;
722 
723  default: // suppress warnings
724  break;
725  }
726  }
727 
728  if( containsLocked )
729  {
730  if( IsOK( m_frame, _( "Selection contains locked items. Do you want to continue?" ) ) )
731  {
732  m_locked = false;
734  }
735  else
736  return SELECTION_LOCKED;
737  }
738 
739  return SELECTION_UNLOCKED;
740 }
741 
742 
744 {
746 
747  selectCursor( false, aClientFilter );
748 
749  return 0;
750 }
751 
752 
754 {
755  clearSelection();
756 
757  return 0;
758 }
759 
760 
762 {
763  std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
764 
765  if( items )
766  {
767  // Perform individual selection of each item before processing the event.
768  for( auto item : *items )
769  select( item );
770 
772  }
773 
774  return 0;
775 }
776 
777 
779 {
780  // Check if there is an item to be selected
781  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
782 
783  if( item )
784  {
785  select( item );
786 
787  // Inform other potentially interested tools
789  }
790 
791  return 0;
792 }
793 
794 
796 {
797  std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
798 
799  if( items )
800  {
801  // Perform individual unselection of each item before processing the event
802  for( auto item : *items )
803  unselect( item );
804 
806  }
807 
808  return 0;
809 }
810 
811 
813 {
814  // Check if there is an item to be selected
815  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
816 
817  if( item )
818  {
819  unselect( item );
820 
821  // Inform other potentially interested tools
823  }
824 
825  return 0;
826 }
827 
828 
829 void connectedTrackFilter( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
830 {
831  /* Narrow the collection down to a single TRACK item for a trivial
832  * connection, or multiple TRACK items for non-trivial connections.
833  */
834  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
835  {
836  if( !dynamic_cast<TRACK*>( aCollector[i] ) )
837  aCollector.Remove( i );
838  }
839 
840  ROUTER_TOOL::NeighboringSegmentFilter( aPt, aCollector );
841 }
842 
843 
845 {
848 
850  return 0;
851 
852  return expandConnection( aEvent );
853 }
854 
855 
857 {
858  // copy the selection, since we're going to iterate and modify
859  auto selection = m_selection.GetItems();
860 
861  // We use the BUSY flag to mark connections
862  for( auto item : selection )
863  item->SetState( BUSY, false );
864 
865  for( auto item : selection )
866  {
867  TRACK* trackItem = dynamic_cast<TRACK*>( item );
868 
869  // Track items marked BUSY have already been visited
870  // therefore their connections have already been marked
871  if( trackItem && !trackItem->GetState( BUSY ) )
872  selectAllItemsConnectedToTrack( *trackItem );
873  }
874 
875  // Inform other potentially interested tools
876  if( m_selection.Size() > 0 )
878 
879  return 0;
880 }
881 
882 
883 void connectedItemFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
884 {
885  /* Narrow the collection down to a single BOARD_CONNECTED_ITEM for each
886  * represented net. All other items types are removed.
887  */
888  std::set<int> representedNets;
889 
890  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
891  {
892  BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[i] );
893  if( !item )
894  aCollector.Remove( i );
895  else if ( representedNets.count( item->GetNetCode() ) )
896  aCollector.Remove( i );
897  else
898  representedNets.insert( item->GetNetCode() );
899  }
900 }
901 
902 
904 {
905  bool haveCopper = false;
906 
907  for( auto item : m_selection.GetItems() )
908  {
909  if( dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
910  haveCopper = true;;
911  }
912 
913  if( !haveCopper )
915 
916  // copy the selection, since we're going to iterate and modify
917  auto selection = m_selection.GetItems();
918 
919  for( auto item : selection )
920  {
921  BOARD_CONNECTED_ITEM* connItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( item );
922 
923  if( connItem )
924  selectAllItemsConnectedToItem( *connItem );
925  }
926 
927  // Inform other potentially interested tools
928  if( m_selection.Size() > 0 )
930 
931  return 0;
932 }
933 
934 
936 {
937  int segmentCount;
938  TRACK* trackList = board()->MarkTrace( board()->m_Track, &aSourceTrack, &segmentCount,
939  nullptr, nullptr, true );
940 
941  for( int i = 0; i < segmentCount; ++i )
942  {
943  select( trackList );
944  trackList = trackList->Next();
945  }
946 }
947 
948 
950 {
951  constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_PAD_T, EOT };
952  auto connectivity = board()->GetConnectivity();
953 
954  for( auto item : connectivity->GetConnectedItems( &aSourceItem, types ) )
955  {
956  // We want to select items connected through pads but not pads
957  // otherwise, the common use case of "Select Copper"->Delete will
958  // remove footprints in addition to traces and vias
959  if( item->Type() != PCB_PAD_T )
960  select( item );
961  }
962 }
963 
964 
966 {
967  constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, EOT };
968  auto connectivity = board()->GetConnectivity();
969 
970  for( auto item : connectivity->GetNetItems( aNetCode, types ) )
971  select( item );
972 }
973 
974 
976 {
977  if( !selectCursor() )
978  return 0;
979 
980  // copy the selection, since we're going to iterate and modify
981  auto selection = m_selection.GetItems();
982 
983  for( auto i : selection )
984  {
985  auto item = static_cast<BOARD_ITEM*>( i );
986 
987  // only connected items get a net code
988  if( item->IsConnected() )
989  {
990  auto& connItem = static_cast<BOARD_CONNECTED_ITEM&>( *item );
991 
992  selectAllItemsOnNet( connItem.GetNetCode() );
993  }
994  }
995 
996  // Inform other potentially interested tools
997  if( m_selection.Size() > 0 )
999 
1000  return 0;
1001 }
1002 
1003 
1004 void SELECTION_TOOL::selectAllItemsOnSheet( wxString& aSheetpath )
1005 {
1006  auto modules = board()->m_Modules.GetFirst();
1007  std::list<MODULE*> modList;
1008 
1009  // store all modules that are on that sheet
1010  for( MODULE* mitem = modules; mitem; mitem = mitem->Next() )
1011  {
1012  if( mitem != NULL && mitem->GetPath().Contains( aSheetpath ) )
1013  {
1014  modList.push_back( mitem );
1015  }
1016  }
1017 
1018  //Generate a list of all pads, and of all nets they belong to.
1019  std::list<int> netcodeList;
1020  std::list<BOARD_CONNECTED_ITEM*> padList;
1021  for( MODULE* mmod : modList )
1022  {
1023  for( auto pad : mmod->Pads() )
1024  {
1025  if( pad->IsConnected() )
1026  {
1027  netcodeList.push_back( pad->GetNetCode() );
1028  padList.push_back( pad );
1029  }
1030  }
1031  }
1032  // remove all duplicates
1033  netcodeList.sort();
1034  netcodeList.unique();
1035 
1036  // auto select trivial connections segments which are launched from the pads
1037  std::list<TRACK*> launchTracks;
1038 
1039  for( auto pad : padList )
1040  {
1041  launchTracks = board()->GetTracksByPosition( pad->GetPosition() );
1042 
1043  for( auto track : launchTracks )
1044  {
1046  }
1047  }
1048 
1049  // now we need to find all modules that are connected to each of these nets
1050  // then we need to determine if these modules are in the list of modules
1051  // belonging to this sheet ( modList )
1052  std::list<int> removeCodeList;
1053  constexpr KICAD_T padType[] = { PCB_PAD_T, EOT };
1054 
1055  for( int netCode : netcodeList )
1056  {
1057  for( BOARD_CONNECTED_ITEM* mitem : board()->GetConnectivity()->GetNetItems( netCode, padType ) )
1058  {
1059  if( mitem->Type() == PCB_PAD_T)
1060  {
1061  bool found = ( std::find( modList.begin(), modList.end(),
1062  mitem->GetParent() ) != modList.end() );
1063 
1064  if( !found )
1065  {
1066  // if we cannot find the module of the pad in the modList
1067  // then we can assume that that module is not located in the same
1068  // schematic, therefore invalidate this netcode.
1069  removeCodeList.push_back( netCode );
1070  break;
1071  }
1072  }
1073  }
1074  }
1075 
1076  // remove all duplicates
1077  removeCodeList.sort();
1078  removeCodeList.unique();
1079 
1080  for( int removeCode : removeCodeList )
1081  {
1082  netcodeList.remove( removeCode );
1083  }
1084 
1085  std::list<BOARD_CONNECTED_ITEM*> localConnectionList;
1086  constexpr KICAD_T trackViaType[] = { PCB_TRACE_T, PCB_VIA_T, EOT };
1087 
1088  for( int netCode : netcodeList )
1089  {
1090  for( BOARD_CONNECTED_ITEM* item : board()->GetConnectivity()->GetNetItems( netCode, trackViaType ) )
1091  {
1092  localConnectionList.push_back( item );
1093  }
1094  }
1095 
1096  for( BOARD_ITEM* i : modList )
1097  {
1098  if( i != NULL )
1099  select( i );
1100  }
1101 
1102  for( BOARD_CONNECTED_ITEM* i : localConnectionList )
1103  {
1104  if( i != NULL )
1105  select( i );
1106  }
1107 }
1108 
1109 
1111 {
1112  //Should recalculate the view to zoom in on the selection
1113  auto selectionBox = m_selection.ViewBBox();
1114  auto canvas = m_frame->GetGalCanvas();
1115  auto view = getView();
1116 
1117  VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
1118 
1119  if( !( selectionBox.GetWidth() == 0 ) || !( selectionBox.GetHeight() == 0 ) )
1120  {
1121  VECTOR2D vsize = selectionBox.GetSize();
1122  double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
1123  fabs( vsize.y / screenSize.y ) );
1124  view->SetScale( scale );
1125  view->SetCenter( selectionBox.Centre() );
1126  view->Add( &m_selection );
1127  }
1128 
1130 }
1131 
1132 
1134 {
1135  clearSelection();
1136  wxString* sheetpath = aEvent.Parameter<wxString*>();
1137 
1138  selectAllItemsOnSheet( *sheetpath );
1139 
1140  zoomFitSelection();
1141 
1142  if( m_selection.Size() > 0 )
1144 
1145  return 0;
1146 }
1147 
1148 
1150 {
1151  if( !selectCursor( true ) )
1152  return 0;
1153 
1154  // this function currently only supports modules since they are only
1155  // on one sheet.
1156  auto item = m_selection.Front();
1157 
1158  if( !item )
1159  return 0;
1160 
1161  if( item->Type() != PCB_MODULE_T )
1162  return 0;
1163 
1164  auto mod = dynamic_cast<MODULE*>( item );
1165 
1166  clearSelection();
1167 
1168  // get the lowest subsheet name for this.
1169  wxString sheetPath = mod->GetPath();
1170  sheetPath = sheetPath.BeforeLast( '/' );
1171  sheetPath = sheetPath.AfterLast( '/' );
1172 
1173  selectAllItemsOnSheet( sheetPath );
1174 
1175  // Inform other potentially interested tools
1176  if( m_selection.Size() > 0 )
1178 
1179  return 0;
1180 }
1181 
1182 
1184 {
1185  clearSelection();
1186 
1187  if( aItem )
1188  {
1189  select( aItem );
1190  getView()->SetCenter( aItem->GetPosition() );
1191 
1192  // Inform other potentially interested tools
1194  }
1195 
1197 }
1198 
1199 
1200 int SELECTION_TOOL::find( const TOOL_EVENT& aEvent )
1201 {
1202  DIALOG_FIND dlg( m_frame );
1203  dlg.SetCallback( std::bind( &SELECTION_TOOL::findCallback, this, _1 ) );
1204  dlg.ShowModal();
1205 
1206  return 0;
1207 }
1208 
1209 
1211 {
1213 
1214  if( module )
1215  {
1216  KIGFX::VIEW_CONTROLS* viewCtrls = getViewControls();
1217  clearSelection();
1218  toggleSelection( module, true );
1219 
1220  auto cursorPosition = viewCtrls->GetCursorPosition( false );
1221 
1222  // Set a reference point so InteractiveEdit will move it to the
1223  // cursor before waiting for mouse move events
1225 
1226  // Place event on module origin first, so the generic anchor snap
1227  // doesn't just choose the closest pin for us
1228  viewCtrls->ForceCursorPosition( true, module->GetPosition() );
1229 
1230  // pick the component up and start moving
1231  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
1232 
1233  // restore the previous cursor position
1234  viewCtrls->SetCursorPosition( cursorPosition, false );
1235  }
1236 
1237  return 0;
1238 }
1239 
1240 
1249 static bool itemIsIncludedByFilter( const BOARD_ITEM& aItem,
1250  const BOARD& aBoard,
1251  const DIALOG_BLOCK_OPTIONS::OPTIONS& aBlockOpts )
1252 {
1253  bool include = true;
1254  const PCB_LAYER_ID layer = aItem.GetLayer();
1255 
1256  // can skip without even checking item type
1257  // fixme: selecting items on invisible layers does not work in GAL
1258  if( !aBlockOpts.includeItemsOnInvisibleLayers
1259  && !aBoard.IsLayerVisible( layer ) )
1260  {
1261  include = false;
1262  }
1263 
1264  // if the item needs to be checked against the options
1265  if( include )
1266  {
1267  switch( aItem.Type() )
1268  {
1269  case PCB_MODULE_T:
1270  {
1271  const auto& module = static_cast<const MODULE&>( aItem );
1272 
1273  include = aBlockOpts.includeModules;
1274 
1275  if( include && !aBlockOpts.includeLockedModules )
1276  {
1277  include = !module.IsLocked();
1278  }
1279 
1280  break;
1281  }
1282  case PCB_TRACE_T:
1283  {
1284  include = aBlockOpts.includeTracks;
1285  break;
1286  }
1287  case PCB_VIA_T:
1288  {
1289  include = aBlockOpts.includeVias;
1290  break;
1291  }
1292  case PCB_ZONE_AREA_T:
1293  {
1294  include = aBlockOpts.includeZones;
1295  break;
1296  }
1297  case PCB_LINE_T:
1298  case PCB_TARGET_T:
1299  case PCB_DIMENSION_T:
1300  {
1301  if( layer == Edge_Cuts )
1302  include = aBlockOpts.includeBoardOutlineLayer;
1303  else
1304  include = aBlockOpts.includeItemsOnTechLayers;
1305  break;
1306  }
1307  case PCB_TEXT_T:
1308  {
1309  include = aBlockOpts.includePcbTexts;
1310  break;
1311  }
1312  default:
1313  {
1314  // no filtering, just select it
1315  break;
1316  }
1317  }
1318  }
1319 
1320  return include;
1321 }
1322 
1323 
1325 {
1326  auto& opts = m_priv->m_filterOpts;
1327  DIALOG_BLOCK_OPTIONS dlg( m_frame, opts, false, _( "Filter selection" ) );
1328 
1329  const int cmd = dlg.ShowModal();
1330 
1331  if( cmd != wxID_OK )
1332  return 0;
1333 
1334  const auto& board = *getModel<BOARD>();
1335 
1336  // copy current selection
1337  auto selection = m_selection.GetItems();
1338 
1339  // clear current selection
1340  clearSelection();
1341 
1342  // copy selection items from the saved selection
1343  // according to the dialog options
1344  for( auto i : selection )
1345  {
1346  auto item = static_cast<BOARD_ITEM*>( i );
1347  bool include = itemIsIncludedByFilter( *item, board, opts );
1348 
1349  if( include )
1350  {
1351  select( item );
1352  }
1353  }
1354  return 0;
1355 }
1356 
1357 
1359 {
1360  if( m_selection.Empty() )
1361  return;
1362 
1363  while( m_selection.GetSize() )
1364  unhighlight( static_cast<BOARD_ITEM*>( m_selection.Front() ), SELECTED, m_selection );
1365 
1366  view()->Update( &m_selection );
1367 
1368  m_selection.SetIsHover( false );
1370 
1371  if( m_frame )
1372  m_frame->SetCurItem( NULL );
1373 
1374  m_locked = true;
1375 
1376  // Inform other potentially interested tools
1379 }
1380 
1381 
1383 {
1384  m_selection.Clear();
1385 
1386  INSPECTOR_FUNC inspector = [&] ( EDA_ITEM* item, void* testData )
1387  {
1388  if( item->IsSelected() )
1389  {
1390  EDA_ITEM* parent = item->GetParent();
1391 
1392  // Flags on module children might be set only because the parent is selected.
1393  if( parent && parent->Type() == PCB_MODULE_T && parent->IsSelected() )
1394  return SEARCH_CONTINUE;
1395 
1397  }
1398 
1399  return SEARCH_CONTINUE;
1400  };
1401 
1402  board()->Visit( inspector, nullptr, m_editModules ? GENERAL_COLLECTOR::ModuleItems
1404 }
1405 
1406 
1408 {
1409  GENERAL_COLLECTOR* collector = aEvent.Parameter<GENERAL_COLLECTOR*>();
1410 
1411  doSelectionMenu( collector, wxEmptyString );
1412 
1413  return 0;
1414 }
1415 
1416 
1417 bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxString& aTitle )
1418 {
1419  BOARD_ITEM* current = nullptr;
1420  SELECTION highlightGroup;
1421  ACTION_MENU menu;
1422 
1423  highlightGroup.SetLayer( LAYER_SELECT_OVERLAY );
1424  getView()->Add( &highlightGroup );
1425 
1426  int limit = std::min( 9, aCollector->GetCount() );
1427 
1428  for( int i = 0; i < limit; ++i )
1429  {
1430  wxString text;
1431  BOARD_ITEM* item = ( *aCollector )[i];
1432  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
1433 
1434  wxString menuText = wxString::Format("&%d. %s", i + 1, text );
1435  menu.Add( menuText, i + 1, item->GetMenuImage() );
1436  }
1437 
1438  if( aTitle.Length() )
1439  menu.SetTitle( aTitle );
1440 
1441  menu.SetIcon( info_xpm );
1442  menu.DisplayTitle( true );
1443  SetContextMenu( &menu, CMENU_NOW );
1444 
1445  while( OPT_TOOL_EVENT evt = Wait() )
1446  {
1447  if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
1448  {
1449  if( current )
1450  unhighlight( current, BRIGHTENED, highlightGroup );
1451 
1452  int id = *evt->GetCommandId();
1453 
1454  // User has pointed an item, so show it in a different way
1455  if( id > 0 && id <= limit )
1456  {
1457  current = ( *aCollector )[id - 1];
1458  highlight( current, BRIGHTENED, highlightGroup );
1459  }
1460  else
1461  {
1462  current = NULL;
1463  }
1464  }
1465  else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
1466  {
1467  if( current )
1468  unhighlight( current, BRIGHTENED, highlightGroup );
1469 
1470  OPT<int> id = evt->GetCommandId();
1471 
1472  // User has selected an item, so this one will be returned
1473  if( id && ( *id > 0 ) )
1474  current = ( *aCollector )[*id - 1];
1475  else
1476  current = NULL;
1477 
1478  break;
1479  }
1480  }
1481  getView()->Remove( &highlightGroup );
1482 
1483  if( current )
1484  {
1485  aCollector->Empty();
1486  aCollector->Append( current );
1487  return true;
1488  }
1489 
1490  return false;
1491 }
1492 
1493 
1495 {
1496  int count = aCollector->GetPrimaryCount(); // try to use preferred layer
1497 
1498  if( 0 == count )
1499  count = aCollector->GetCount();
1500 
1501  for( int i = 0; i < count; ++i )
1502  {
1503  if( ( *aCollector )[i]->Type() != PCB_MODULE_T )
1504  return NULL;
1505  }
1506 
1507  // All are modules, now find smallest MODULE
1508  int minDim = 0x7FFFFFFF;
1509  int minNdx = 0;
1510 
1511  for( int i = 0; i < count; ++i )
1512  {
1513  MODULE* module = (MODULE*) ( *aCollector )[i];
1514 
1515  int lx = module->GetFootprintRect().GetWidth();
1516  int ly = module->GetFootprintRect().GetHeight();
1517 
1518  int lmin = std::min( lx, ly );
1519 
1520  if( lmin < minDim )
1521  {
1522  minDim = lmin;
1523  minNdx = i;
1524  }
1525  }
1526 
1527  return (*aCollector)[minNdx];
1528 }
1529 
1530 
1531 bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem, bool checkVisibilityOnly ) const
1532 {
1533  // Is high contrast mode enabled?
1534  bool highContrast = getView()->GetPainter()->GetSettings()->GetHighContrast();
1535 
1536  int layers[KIGFX::VIEW::VIEW_MAX_LAYERS], layers_count;
1537 
1538  // Filter out items that do not belong to active layers
1539  std::set<unsigned int> activeLayers = getView()->GetPainter()->GetSettings()->GetActiveLayers();
1540 
1541  // The markers layer is considered to be always active
1542  activeLayers.insert( (unsigned int) LAYER_DRC );
1543 
1544  aItem->ViewGetLayers( layers, layers_count );
1545 
1546  if( highContrast )
1547  {
1548  bool onActive = false; // Is the item on any of active layers?
1549 
1550  for( int i = 0; i < layers_count; ++i )
1551  {
1552  if( activeLayers.count( layers[i] ) > 0 ) // Item is on at least one of the active layers
1553  {
1554  onActive = true;
1555  break;
1556  }
1557  }
1558 
1559  if( !onActive ) // We do not want to select items that are in the background
1560  {
1561  return false;
1562  }
1563  }
1564 
1565  switch( aItem->Type() )
1566  {
1567  case PCB_ZONE_AREA_T:
1568  // Keepout zones can exist on multiple layers!
1569  {
1570  auto* zone = static_cast<const ZONE_CONTAINER*>( aItem );
1571 
1572  if( zone->GetIsKeepout() )
1573  {
1574  auto zoneLayers = zone->GetLayerSet().Seq();
1575 
1576  for( unsigned int i = 0; i < zoneLayers.size(); i++ )
1577  {
1578  if( board()->IsLayerVisible( zoneLayers[i] ) )
1579  {
1580  return true;
1581  }
1582  }
1583 
1584  // No active layers selected!
1585  return false;
1586  }
1587  }
1588  break;
1589 
1590  case PCB_TRACE_T:
1591  {
1592  if( !board()->IsElementVisible( LAYER_TRACKS ) )
1593  return false;
1594  }
1595  break;
1596 
1597  case PCB_VIA_T:
1598  {
1599  const VIA* via = static_cast<const VIA*>( aItem );
1600 
1601  // Check if appropriate element layer is visible
1602  switch( via->GetViaType() )
1603  {
1604  case VIA_THROUGH:
1606  return false;
1607  break;
1608 
1609  case VIA_BLIND_BURIED:
1611  return false;
1612  break;
1613 
1614  case VIA_MICROVIA:
1616  return false;
1617  break;
1618 
1619  default:
1620  wxFAIL;
1621  return false;
1622  }
1623 
1624  // For vias it is enough if only one of its layers is visible
1625  return ( board()->GetVisibleLayers() & via->GetLayerSet() ).any();
1626  }
1627 
1628  case PCB_MODULE_T:
1629  {
1630  // In modedit, we do not want to select the module itself.
1631  if( m_editModules )
1632  return false;
1633 
1634  // Allow selection of footprints if some part of the footprint is visible.
1635 
1636  MODULE* module = const_cast<MODULE*>( static_cast<const MODULE*>( aItem ) );
1637 
1638  for( auto item : module->GraphicalItems() )
1639  {
1640  if( selectable( item, true ) )
1641  return true;
1642  }
1643 
1644  for( auto pad : module->Pads() )
1645  {
1646  if( selectable( pad, true ) )
1647  return true;
1648  }
1649 
1650  return false;
1651  }
1652 
1653  case PCB_MODULE_TEXT_T:
1654  // Multiple selection is only allowed in modedit mode. In pcbnew, you have to select
1655  // module subparts one by one, rather than with a drag selection. This is so you can
1656  // pick up items under an (unlocked) module without also moving the module's sub-parts.
1657  if( !m_editModules && !checkVisibilityOnly )
1658  {
1659  if( m_multiple )
1660  return false;
1661  }
1662 
1663  if( !m_editModules && !view()->IsVisible( aItem ) )
1664  return false;
1665 
1666  break;
1667 
1668  case PCB_MODULE_EDGE_T:
1669  case PCB_PAD_T:
1670  {
1671  // Multiple selection is only allowed in modedit mode. In pcbnew, you have to select
1672  // module subparts one by one, rather than with a drag selection. This is so you can
1673  // pick up items under an (unlocked) module without also moving the module's sub-parts.
1674  if( !m_editModules && !checkVisibilityOnly )
1675  {
1676  if( m_multiple )
1677  return false;
1678  }
1679 
1680  if( aItem->Type() == PCB_PAD_T )
1681  {
1682  auto pad = static_cast<const D_PAD*>( aItem );
1683 
1684  // In pcbnew, locked modules prevent individual pad selection.
1685  // In modedit, we don't enforce this as the module is assumed to be edited by design.
1686  if( !m_editModules && !checkVisibilityOnly )
1687  {
1688  if( pad->GetParent() && pad->GetParent()->IsLocked() )
1689  return false;
1690  }
1691 
1692  // Check render mode (from the Items tab) first
1693  switch( pad->GetAttribute() )
1694  {
1695  case PAD_ATTRIB_STANDARD:
1697  if( !board()->IsElementVisible( LAYER_PADS_TH ) )
1698  return false;
1699  break;
1700 
1701  case PAD_ATTRIB_CONN:
1702  case PAD_ATTRIB_SMD:
1703  if( pad->IsOnLayer( F_Cu ) && !board()->IsElementVisible( LAYER_PAD_FR ) )
1704  return false;
1705  else if( pad->IsOnLayer( B_Cu ) && !board()->IsElementVisible( LAYER_PAD_BK ) )
1706  return false;
1707  break;
1708  }
1709 
1710  // Otherwise, pads are selectable if any draw layer is visible
1711 
1712  // Shortcut: check copper layer visibility
1713  if( board()->IsLayerVisible( F_Cu ) && pad->IsOnLayer( F_Cu ) )
1714  return true;
1715 
1716  if( board()->IsLayerVisible( B_Cu ) && pad->IsOnLayer( B_Cu ) )
1717  return true;
1718 
1719  // Now check the non-copper layers
1720 
1721  bool draw_layer_visible = false;
1722 
1723  int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
1724  pad->ViewGetLayers( pad_layers, pad_layers_count );
1725 
1726  for( int i = 0; i < pad_layers_count; ++i )
1727  {
1728  // NOTE: Only checking the regular layers (not GAL meta-layers)
1729  if( ( ( pad_layers[i] < PCB_LAYER_ID_COUNT ) &&
1730  board()->IsLayerVisible( static_cast<PCB_LAYER_ID>( pad_layers[i] ) ) ) )
1731  {
1732  draw_layer_visible = true;
1733  }
1734  }
1735 
1736  return draw_layer_visible;
1737  }
1738 
1739  break;
1740  }
1741 
1742 
1743  case PCB_MARKER_T: // Always selectable
1744  return true;
1745 
1746  // These are not selectable
1747  case NOT_USED:
1748  case TYPE_NOT_INIT:
1749  return false;
1750 
1751  default: // Suppress warnings
1752  break;
1753  }
1754 
1755  // All other items are selected only if the layer on which they exist is visible
1756  return board()->IsLayerVisible( aItem->GetLayer() );
1757 }
1758 
1759 
1761 {
1762  if( aItem->IsSelected() )
1763  {
1764  return;
1765  }
1766 
1767  if( aItem->Type() == PCB_PAD_T )
1768  {
1769  MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
1770 
1771  if( m_selection.Contains( module ) )
1772  return;
1773  }
1774 
1775  highlight( aItem, SELECTED, m_selection );
1776  view()->Update( &m_selection );
1777 
1778  if( m_frame )
1779  {
1780  if( m_selection.Size() == 1 )
1781  {
1782  // Set as the current item, so the information about selection is displayed
1783  m_frame->SetCurItem( aItem, true );
1784  }
1785  else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
1786  { // called for every next selected item
1787  // If multiple items are selected, do not show the information about the selected item
1788  m_frame->SetCurItem( NULL, true );
1789  }
1790  }
1791 }
1792 
1793 
1795 {
1796  unhighlight( aItem, SELECTED, m_selection );
1797  view()->Update( &m_selection );
1798 
1799  if( m_frame && m_frame->GetCurItem() == aItem )
1800  m_frame->SetCurItem( NULL );
1801 
1802  if( m_selection.Empty() )
1803  m_locked = true;
1804 }
1805 
1806 
1807 void SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGroup )
1808 {
1809  if( aMode == SELECTED )
1810  aItem->SetSelected();
1811  else if( aMode == BRIGHTENED )
1812  aItem->SetBrightened();
1813 
1814  // Hide the original item, so it is shown only on overlay
1815  view()->Hide( aItem, true );
1816 
1817  aGroup.Add( aItem );
1818 
1819  // Modules are treated in a special way - when they are highlighted, we have to
1820  // highlight all the parts that make the module, not the module itself
1821  if( aItem->Type() == PCB_MODULE_T )
1822  {
1823  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1824  {
1825  if( aMode == SELECTED )
1826  item->SetSelected();
1827  else if( aMode == BRIGHTENED )
1828  {
1829  item->SetBrightened();
1830  aGroup.Add( item );
1831  }
1832  view()->Hide( item, true );
1833  });
1834  }
1835 
1836  // Many selections are very temporal and updating the display each time just
1837  // creates noise.
1838  if( aMode == BRIGHTENED )
1840 }
1841 
1842 
1843 void SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGroup )
1844 {
1845  if( aMode == SELECTED )
1846  aItem->ClearSelected();
1847  else if( aMode == BRIGHTENED )
1848  aItem->ClearBrightened();
1849 
1850  aGroup.Remove( aItem );
1851 
1852  // Restore original item visibility
1853  view()->Hide( aItem, false );
1854  view()->Update( aItem );
1855 
1856  // Modules are treated in a special way - when they are highlighted, we have to
1857  // highlight all the parts that make the module, not the module itself
1858  if( aItem->Type() == PCB_MODULE_T )
1859  {
1860  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1861  {
1862  if( aMode == SELECTED )
1863  item->ClearSelected();
1864  else if( aMode == BRIGHTENED )
1865  item->ClearBrightened();
1866 
1867  // N.B. if we clear the selection flag for sub-elements, we need to also
1868  // remove the element from the selection group (if it exists)
1869  aGroup.Remove( item );
1870  view()->Hide( item, false );
1871  view()->Update( item );
1872  });
1873  }
1874 
1875  // Many selections are very temporal and updating the display each time just
1876  // creates noise.
1877  if( aMode == BRIGHTENED )
1879 }
1880 
1881 
1882 bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
1883 {
1884  const unsigned GRIP_MARGIN = 20;
1885  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
1886 
1887  // Check if the point is located within any of the currently selected items bounding boxes
1888  for( auto item : m_selection )
1889  {
1890  BOX2I itemBox = item->ViewBBox();
1891  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
1892 
1893  if( itemBox.Contains( aPoint ) )
1894  return true;
1895  }
1896 
1897  return false;
1898 }
1899 
1900 
1901 static EDA_RECT getRect( const BOARD_ITEM* aItem )
1902 {
1903  if( aItem->Type() == PCB_MODULE_T )
1904  return static_cast<const MODULE*>( aItem )->GetFootprintRect();
1905 
1906  return aItem->GetBoundingBox();
1907 }
1908 
1909 
1910 static double calcArea( const BOARD_ITEM* aItem )
1911 {
1912  if( aItem->Type() == PCB_TRACE_T )
1913  {
1914  const TRACK* t = static_cast<const TRACK*>( aItem );
1915  return ( t->GetWidth() + t->GetLength() ) * t->GetWidth();
1916  }
1917 
1918  return getRect( aItem ).GetArea();
1919 }
1920 
1921 
1922 /*static double calcMinArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1923 {
1924  double best = std::numeric_limits<double>::max();
1925 
1926  if( !aCollector.GetCount() )
1927  return 0.0;
1928 
1929  for( int i = 0; i < aCollector.GetCount(); i++ )
1930  {
1931  BOARD_ITEM* item = aCollector[i];
1932  if( item->Type() == aType )
1933  best = std::min( best, calcArea( item ) );
1934  }
1935 
1936  return best;
1937 }*/
1938 
1939 
1940 static double calcMaxArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1941 {
1942  double best = 0.0;
1943 
1944  for( int i = 0; i < aCollector.GetCount(); i++ )
1945  {
1946  BOARD_ITEM* item = aCollector[i];
1947  if( item->Type() == aType )
1948  best = std::max( best, calcArea( item ) );
1949  }
1950 
1951  return best;
1952 }
1953 
1954 
1955 static inline double calcCommonArea( const BOARD_ITEM* aItem, const BOARD_ITEM* aOther )
1956 {
1957  if( !aItem || !aOther )
1958  return 0;
1959 
1960  return getRect( aItem ).Common( getRect( aOther ) ).GetArea();
1961 }
1962 
1963 
1964 double calcRatio( double a, double b )
1965 {
1966  if( a == 0.0 && b == 0.0 )
1967  return 1.0;
1968 
1969  if( b == 0.0 )
1971 
1972  return a / b;
1973 }
1974 
1975 
1976 // The general idea here is that if the user clicks directly on a small item inside a larger
1977 // one, then they want the small item. The quintessential case of this is clicking on a pad
1978 // within a footprint, but we also apply it for text within a footprint, footprints within
1979 // larger footprints, and vias within either larger pads or longer tracks.
1980 //
1981 // These "guesses" presume there is area within the larger item to click in to select it. If
1982 // an item is mostly covered by smaller items within it, then the guesses are inappropriate as
1983 // there might not be any area left to click to select the larger item. In this case we must
1984 // leave the items in the collector and bring up a Selection Clarification menu.
1985 //
1986 // We currently check for pads and text mostly covering a footprint, but we don’t check for
1987 // smaller footprints mostly covering a larger footprint.
1988 //
1990  const VECTOR2I& aWhere ) const
1991 {
1992  std::set<BOARD_ITEM*> preferred;
1993  std::set<BOARD_ITEM*> rejected;
1994  std::set<BOARD_ITEM*> forced;
1995  wxPoint where( aWhere.x, aWhere.y );
1996 
1997  // footprints which are below this percentage of the largest footprint will be considered
1998  // for selection; all others will not
1999  constexpr double footprintToFootprintMinRatio = 0.20;
2000  // pads which are below this percentage of their parent's area will exclude their parent
2001  constexpr double padToFootprintMinRatio = 0.45;
2002  // footprints containing items with items-to-footprint area ratio higher than this will be
2003  // forced to stay on the list
2004  constexpr double footprintMaxCoverRatio = 0.80;
2005  constexpr double viaToPadMinRatio = 0.50;
2006  constexpr double trackViaLengthRatio = 2.0;
2007  constexpr double trackTrackLengthRatio = 0.3;
2008  constexpr double textToFeatureMinRatio = 0.2;
2009  constexpr double textToFootprintMinRatio = 0.4;
2010  // If the common area of two compared items is above the following threshold, they cannot
2011  // be rejected (it means they overlap and it might be hard to pick one by selecting
2012  // its unique area).
2013  constexpr double commonAreaRatio = 0.6;
2014 
2015  PCB_LAYER_ID activeLayer = (PCB_LAYER_ID) view()->GetTopLayer();
2016  LSET silkLayers( 2, B_SilkS, F_SilkS );
2017 
2018  if( silkLayers[activeLayer] )
2019  {
2020  for( int i = 0; i < aCollector.GetCount(); ++i )
2021  {
2022  BOARD_ITEM* item = aCollector[i];
2023  KICAD_T type = item->Type();
2024 
2025  if( ( type == PCB_MODULE_TEXT_T || type == PCB_TEXT_T || type == PCB_LINE_T )
2026  && silkLayers[item->GetLayer()] )
2027  {
2028  preferred.insert( item );
2029  }
2030  }
2031 
2032  if( preferred.size() > 0 )
2033  {
2034  aCollector.Empty();
2035 
2036  for( BOARD_ITEM* item : preferred )
2037  aCollector.Append( item );
2038  return;
2039  }
2040  }
2041 
2042  int numZones = aCollector.CountType( PCB_ZONE_AREA_T );
2043 
2044  // Zone edges are very specific; zone fills much less so.
2045  if( numZones > 0 )
2046  {
2047  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2048  {
2049  if( aCollector[i]->Type() == PCB_ZONE_AREA_T )
2050  {
2051  auto zone = static_cast<ZONE_CONTAINER*>( aCollector[i] );
2052 
2053  if( zone->HitTestForEdge( where, 5 * aCollector.GetGuide()->OnePixelInIU() ) )
2054  preferred.insert( zone );
2055  else
2056  rejected.insert( zone );
2057  }
2058  }
2059 
2060  if( preferred.size() > 0 )
2061  {
2062  aCollector.Empty();
2063 
2064  for( BOARD_ITEM* item : preferred )
2065  aCollector.Append( item );
2066  return;
2067  }
2068  }
2069 
2070  if( aCollector.CountType( PCB_MODULE_TEXT_T ) > 0 )
2071  {
2072  for( int i = 0; i < aCollector.GetCount(); ++i )
2073  {
2074  if( TEXTE_MODULE* txt = dyn_cast<TEXTE_MODULE*>( aCollector[i] ) )
2075  {
2076  double textArea = calcArea( txt );
2077 
2078  for( int j = 0; j < aCollector.GetCount(); ++j )
2079  {
2080  if( i == j )
2081  continue;
2082 
2083  BOARD_ITEM* item = aCollector[j];
2084  double itemArea = calcArea( item );
2085  double areaRatio = calcRatio( textArea, itemArea );
2086  double commonArea = calcCommonArea( txt, item );
2087  double itemCommonRatio = calcRatio( commonArea, itemArea );
2088  double txtCommonRatio = calcRatio( commonArea, textArea );
2089 
2090  if( item->Type() == PCB_MODULE_T )
2091  {
2092  // when text area is small compared to an overlapping footprint,
2093  // then it's a clear sign the text is the selection target
2094  if( areaRatio < textToFootprintMinRatio && itemCommonRatio < commonAreaRatio )
2095  rejected.insert( item );
2096  }
2097 
2098  switch( item->Type() )
2099  {
2100  case PCB_TRACE_T:
2101  case PCB_PAD_T:
2102  case PCB_LINE_T:
2103  case PCB_VIA_T:
2104  case PCB_MODULE_T:
2105  if( areaRatio > textToFeatureMinRatio && txtCommonRatio < commonAreaRatio )
2106  rejected.insert( txt );
2107  break;
2108  default:
2109  break;
2110  }
2111  }
2112  }
2113  }
2114  }
2115 
2116  if( aCollector.CountType( PCB_PAD_T ) > 0 )
2117  {
2118  for( int i = 0; i < aCollector.GetCount(); ++i )
2119  {
2120  if( D_PAD* pad = dyn_cast<D_PAD*>( aCollector[i] ) )
2121  {
2122  MODULE* parent = pad->GetParent();
2123  double ratio = calcRatio( calcArea( pad ), calcArea( parent ) );
2124 
2125  // when pad area is small compared to the parent footprint,
2126  // then it is a clear sign the pad is the selection target
2127  if( ratio < padToFootprintMinRatio )
2128  rejected.insert( pad->GetParent() );
2129  }
2130  }
2131  }
2132 
2133  int moduleCount = aCollector.CountType( PCB_MODULE_T );
2134 
2135  if( moduleCount > 0 )
2136  {
2137  double maxArea = calcMaxArea( aCollector, PCB_MODULE_T );
2138  BOX2D viewportD = getView()->GetViewport();
2139  BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
2140  double maxCoverRatio = footprintMaxCoverRatio;
2141 
2142  // MODULE::CoverageRatio() doesn't take zone handles & borders into account so just
2143  // use a more aggressive cutoff point if zones are involved.
2144  if( aCollector.CountType( PCB_ZONE_AREA_T ) )
2145  maxCoverRatio /= 2;
2146 
2147  for( int i = 0; i < aCollector.GetCount(); ++i )
2148  {
2149  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[i] ) )
2150  {
2151  // filter out components larger than the viewport
2152  if( mod->ViewBBox().Contains( viewport ) )
2153  rejected.insert( mod );
2154  // footprints completely covered with other features have no other
2155  // means of selection, so must be kept
2156  else if( mod->CoverageRatio( aCollector ) > maxCoverRatio )
2157  rejected.erase( mod );
2158  // if a footprint is much smaller than the largest overlapping
2159  // footprint then it should be considered for selection
2160  else if( calcRatio( calcArea( mod ), maxArea ) <= footprintToFootprintMinRatio )
2161  continue;
2162  // if there are multiple footprints for selection at this point, prefer
2163  // one that is on the active layer
2164  else if( moduleCount > 1 && mod->GetLayer() == activeLayer )
2165  preferred.insert( mod );
2166  // reject ALL OTHER footprints if there's still something else left
2167  // to select
2168  else if( (int)( rejected.size() + 1 ) < aCollector.GetCount() )
2169  rejected.insert( mod );
2170  }
2171  }
2172  }
2173 
2174  if( aCollector.CountType( PCB_VIA_T ) > 0 )
2175  {
2176  for( int i = 0; i < aCollector.GetCount(); ++i )
2177  {
2178  if( VIA* via = dyn_cast<VIA*>( aCollector[i] ) )
2179  {
2180  double viaArea = calcArea( via );
2181 
2182  for( int j = 0; j < aCollector.GetCount(); ++j )
2183  {
2184  if( i == j )
2185  continue;
2186 
2187  BOARD_ITEM* item = aCollector[j];
2188  double areaRatio = calcRatio( viaArea, calcArea( item ) );
2189 
2190  if( item->Type() == PCB_MODULE_T && areaRatio < padToFootprintMinRatio )
2191  rejected.insert( item );
2192 
2193  if( item->Type() == PCB_PAD_T && areaRatio < viaToPadMinRatio )
2194  rejected.insert( item );
2195 
2196  if( TRACK* track = dyn_cast<TRACK*>( item ) )
2197  {
2198  if( track->GetNetCode() != via->GetNetCode() )
2199  continue;
2200 
2201  double lenRatio = (double) ( track->GetLength() + track->GetWidth() ) /
2202  (double) via->GetWidth();
2203 
2204  if( lenRatio > trackViaLengthRatio )
2205  rejected.insert( track );
2206  }
2207  }
2208  }
2209  }
2210  }
2211 
2212  int nTracks = aCollector.CountType( PCB_TRACE_T );
2213 
2214  if( nTracks > 0 )
2215  {
2216  double maxLength = 0.0;
2217  double minLength = std::numeric_limits<double>::max();
2218  double maxArea = 0.0;
2219  const TRACK* maxTrack = nullptr;
2220 
2221  for( int i = 0; i < aCollector.GetCount(); ++i )
2222  {
2223  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
2224  {
2225  maxLength = std::max( track->GetLength(), maxLength );
2226  maxLength = std::max( (double) track->GetWidth(), maxLength );
2227 
2228  minLength = std::min( std::max( track->GetLength(), (double) track->GetWidth() ), minLength );
2229 
2230  double area = track->GetLength() * track->GetWidth();
2231 
2232  if( area > maxArea )
2233  {
2234  maxArea = area;
2235  maxTrack = track;
2236  }
2237  }
2238  }
2239 
2240  if( maxLength > 0.0 && minLength / maxLength < trackTrackLengthRatio && nTracks > 1 )
2241  {
2242  for( int i = 0; i < aCollector.GetCount(); ++i )
2243  {
2244  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
2245  {
2246  double ratio = std::max( (double) track->GetWidth(), track->GetLength() ) / maxLength;
2247 
2248  if( ratio > trackTrackLengthRatio )
2249  rejected.insert( track );
2250  }
2251  }
2252  }
2253 
2254  for( int j = 0; j < aCollector.GetCount(); ++j )
2255  {
2256  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[j] ) )
2257  {
2258  double ratio = calcRatio( maxArea, mod->GetFootprintRect().GetArea() );
2259 
2260  if( ratio < padToFootprintMinRatio && calcCommonArea( maxTrack, mod ) < commonAreaRatio )
2261  rejected.insert( mod );
2262  }
2263  }
2264  }
2265 
2266  if( (unsigned) aCollector.GetCount() > rejected.size() ) // do not remove everything
2267  {
2268  for( BOARD_ITEM* item : rejected )
2269  {
2270  aCollector.Remove( item );
2271  }
2272  }
2273 }
2274 
2275 
2277 {
2278  getView()->Update( &m_selection );
2279 
2280  return 0;
2281 }
2282 
2283 
2285 {
2286  ACTION_MENU* actionMenu = aEvent.Parameter<ACTION_MENU*>();
2287  CONDITIONAL_MENU* conditionalMenu = dynamic_cast<CONDITIONAL_MENU*>( actionMenu );
2288 
2289  if( conditionalMenu )
2290  conditionalMenu->Evaluate( m_selection );
2291 
2292  if( actionMenu )
2293  actionMenu->UpdateAll();
2294 
2295  return 0;
2296 }
2297 
2298 
2300 {
2302 
2306 
2312 
2313  Go( &SELECTION_TOOL::find, PCB_ACTIONS::find.MakeEvent() );
2315 
2324 }
2325 
2326 
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 AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddMenu()
void ClearReferencePoint()
Definition: selection.h:213
int UnselectItem(const TOOL_EVENT &aEvent)
Item unselection event handler.
int Main(const TOOL_EVENT &aEvent)
Function Main()
int UpdateMenu(const TOOL_EVENT &aEvent)
Pass the selection to a conditional menu for updating.
void SetIgnoreTracks(bool ignore)
Definition: collectors.h:608
void AddStandardSubMenus(EDA_DRAW_FRAME *aFrame)
Function CreateBasicMenu.
Definition: tool_menu.cpp:83
void connectedTrackFilter(const VECTOR2I &aPt, GENERAL_COLLECTOR &aCollector)
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:132
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.
static EDA_RECT getRect(const BOARD_ITEM *aItem)
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:93
void ForceRefresh()
Function ForceRefresh() Forces a redraw.
int GetNetCode() const
Function GetNetCode.
static double calcCommonArea(const BOARD_ITEM *aItem, const BOARD_ITEM *aOther)
std::function< SEARCH_RESULT(EDA_ITEM *aItem, void *aTestData) > INSPECTOR_FUNC
Typedef INSPECTOR is used to inspect and possibly collect the (search) results of iterating over a li...
Definition: base_struct.h:77
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
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...
BOARD * board() const
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:133
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
Class ACTION_MENU.
Definition: action_menu.h:43
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:185
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
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.
virtual double OnePixelInIU() const =0
void SetIgnoreModulesVals(bool ignore)
Definition: collectors.h:590
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Function OnlyTypes Creates a functor that tests if the selected items are only of given types.
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:931
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
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
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
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
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:165
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:134
void UpdateAll()
Function UpdateAll() Runs update handlers for the menu and its submenus.
void highlight(BOARD_ITEM *aItem, int aHighlightMode, SELECTION &aGroup)
Function highlight() Highlights the item visually.
const COLLECTORS_GUIDE * GetGuide()
Definition: collectors.h:347
void SetContextMenu(ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
void(* CLIENT_SELECTION_FILTER)(const VECTOR2I &, GENERAL_COLLECTOR &)
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...
static double calcArea(const BOARD_ITEM *aItem)
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
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
static const TOOL_EVENT SelectedItemsModified
Definition: actions.h:136
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
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
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
show modules on front
virtual bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: base_struct.h:333
void findCallback(BOARD_ITEM *aItem)
Find dialog callback.
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) override
Function Visit may be re-implemented for each derived class in order to handle all the types given by...
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
int expandConnection(const TOOL_EVENT &aEvent)
Expands the current selection to select a connection between two junctions
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:208
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:
Class LSET is a set of PCB_LAYER_IDs.
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:601
static double calcMaxArea(GENERAL_COLLECTOR &aCollector, KICAD_T aType)
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:327
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:323
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
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:289
void connectedItemFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
SELECTION_LOCK_FLAGS
Definition: selection.h:232
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:378
virtual int GetTopLayer() const
Definition: view.cpp:850
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
Definition: action_menu.cpp:82
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:167
bool Contains(EDA_ITEM *aItem) const
Definition: selection.h:111
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:292
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:130
KIGFX::PCB_VIEW * view() const
void unhighlight(BOARD_ITEM *aItem, int aHighlightMode, SELECTION &aGroup)
Function unhighlight() Unhighlights the item visually.
SELECTION m_selection
SELECTION & GetSelection()
Function GetSelection()
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:137
VIATYPE_T GetViaType() const
Definition: class_track.h:437
void toggleSelection(BOARD_ITEM *aItem, bool aForce=false)
Function toggleSelection() Changes selection status of a given item.
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
EDA_ITEM * GetParent() const
Definition: base_struct.h:214
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
void clearSelection()
Function clearSelection() Clears the current selection.
PCB_BASE_FRAME * m_frame
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.
TOOL_MENU m_menu
static const TOOL_EVENT ClearedEvent
Event sent after selection is cleared.
Definition: actions.h:134
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
static TOOL_ACTION updateMenu
Definition: actions.h:49
int selectSheetContents(const TOOL_EVENT &aEvent)
Selects all modules belonging to same sheet, from Eeschema, using crossprobing
bool IsCancelInteractive(const TOOL_EVENT &aEvt)
Function IsCancelInteractive()
Definition: tool_event.cpp:177
All active tools
Definition: tool_event.h:143
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.
static bool itemIsIncludedByFilter(const BOARD_ITEM &aItem, const BOARD &aBoard, const DIALOG_BLOCK_OPTIONS::OPTIONS &aBlockOpts)
Function itemIsIncludedByFilter()
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
PCB_EDIT_FRAME * frame() const
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:119
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:99
virtual const wxPoint GetPosition() const =0
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:311
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:98
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 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:453
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:97
const int scale
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the menu.
Definition: action_menu.cpp:96
smd pads, front layer
int GetWidth() const
Definition: class_track.h:127
void CloseContextMenu(OPT_TOOL_EVENT &evt)
Function CloseContextMenu.
Definition: tool_menu.cpp:75
TRACK * Next() const
Definition: class_track.h:110
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:312
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
MODULE * module() const
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
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 AddSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Function CreateSubMenu.
Definition: tool_menu.cpp:52
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:125
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 RebuildSelection()
Rebuilds the selection from the EDA_ITEMs' selection flags.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:157
double calcRatio(double a, double b)
void guessSelectionCandidates(GENERAL_COLLECTOR &aCollector, const VECTOR2I &aWhere) const
Function guessSelectionCandidates() Tries to guess best selection candidates in case multiple items a...
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
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon=NULL)
Function Add() Adds an entry to the menu.
int SelectItems(const TOOL_EVENT &aEvent)
Multiple item selection event handler
ACTION_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
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
static TOOL_ACTION findMove
Find an item and start moving.
Definition: pcb_actions.h:330
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
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
PCB_DRAW_PANEL_GAL * canvas() const
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
const SELECTION & selection() const
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:294
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
const wxPoint GetPosition() const override
Definition: class_module.h:183
#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:155
DIALOG_BLOCK_OPTIONS::OPTIONS m_filterOpts
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:486
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
void DisplayTitle(bool aDisplay=true)
Function DisplayTitle() Decides whether a title for a pop up menu should be displayed.
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:85