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