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  std::vector<BOARD_ITEM*>* aFiltered, bool aConfirmLockedItems )
400 {
401  bool selectionEmpty = m_selection.Empty();
402  m_selection.SetIsHover( selectionEmpty );
403 
404  if( selectionEmpty )
405  {
406  m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, aClientFilter );
408  }
409 
410  if ( aConfirmLockedItems && CheckLock() == SELECTION_LOCKED )
411  {
412  clearSelection();
413  }
414 
415  if( aClientFilter )
416  {
417  GENERAL_COLLECTOR collector;
418 
419  for( auto item : m_selection )
420  collector.Append( item );
421 
422  aClientFilter( VECTOR2I(), collector );
423 
424  /*
425  * The first step is to find the items that may have been added by the client filter
426  * This can happen if the locked pads select the module instead
427  */
428  std::vector<EDA_ITEM*> new_items;
429  std::set_difference( collector.begin(), collector.end(), m_selection.begin(), m_selection.end(),
430  std::back_inserter( new_items ) );
431 
435  std::vector<EDA_ITEM*> diff;
436  std::set_difference( m_selection.begin(), m_selection.end(), collector.begin(), collector.end(),
437  std::back_inserter( diff ) );
438 
439  if( aFiltered )
440  {
441  for( auto item : diff )
442  aFiltered->push_back( static_cast<BOARD_ITEM*>( item ) );
443  }
444 
449  for( auto item : diff )
450  unhighlight( static_cast<BOARD_ITEM*>( item ), SELECTED, m_selection );
451 
452  for( auto item : new_items )
453  highlight( static_cast<BOARD_ITEM*>( item ), SELECTED, m_selection );
454 
456  }
457 
458  return m_selection;
459 }
460 
461 
462 void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem, bool aForce )
463 {
464  if( aItem->IsSelected() )
465  {
466  unselect( aItem );
467 
468  // Inform other potentially interested tools
470  }
471  else
472  {
473  if( !m_additive )
474  clearSelection();
475 
476  // Prevent selection of invisible or inactive items
477  if( aForce || selectable( aItem ) )
478  {
479  select( aItem );
480 
481  // Inform other potentially interested tools
483  }
484  }
485 
486  if( m_frame )
488 }
489 
491 {
492  GENERAL_COLLECTORS_GUIDE guide( board()->GetVisibleLayers(),
493  (PCB_LAYER_ID) view()->GetTopLayer(), view() );
494 
495  // account for the globals
496  guide.SetIgnoreMTextsMarkedNoShow( ! board()->IsElementVisible( LAYER_MOD_TEXT_INVISIBLE ) );
497  guide.SetIgnoreMTextsOnBack( ! board()->IsElementVisible( LAYER_MOD_TEXT_BK ) );
498  guide.SetIgnoreMTextsOnFront( ! board()->IsElementVisible( LAYER_MOD_TEXT_FR ) );
499  guide.SetIgnoreModulesOnBack( ! board()->IsElementVisible( LAYER_MOD_BK ) );
500  guide.SetIgnoreModulesOnFront( ! board()->IsElementVisible( LAYER_MOD_FR ) );
501  guide.SetIgnorePadsOnBack( ! board()->IsElementVisible( LAYER_PAD_BK ) );
502  guide.SetIgnorePadsOnFront( ! board()->IsElementVisible( LAYER_PAD_FR ) );
503  guide.SetIgnoreThroughHolePads( ! board()->IsElementVisible( LAYER_PADS_TH ) );
504  guide.SetIgnoreModulesVals( ! board()->IsElementVisible( LAYER_MOD_VALUES ) );
505  guide.SetIgnoreModulesRefs( ! board()->IsElementVisible( LAYER_MOD_REFERENCES ) );
506  guide.SetIgnoreThroughVias( ! board()->IsElementVisible( LAYER_VIA_THROUGH ) );
507  guide.SetIgnoreBlindBuriedVias( ! board()->IsElementVisible( LAYER_VIA_BBLIND ) );
508  guide.SetIgnoreMicroVias( ! board()->IsElementVisible( LAYER_VIA_MICROVIA ) );
509  guide.SetIgnoreTracks( ! board()->IsElementVisible( LAYER_TRACKS ) );
510 
511  return guide;
512 }
513 
514 
515 bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
516  bool* aSelectionCancelledFlag,
517  CLIENT_SELECTION_FILTER aClientFilter )
518 {
519  auto guide = getCollectorsGuide();
520  GENERAL_COLLECTOR collector;
521  auto displayOpts = (PCB_DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
522 
523  guide.SetIgnoreZoneFills( displayOpts->m_DisplayZonesMode != 0 );
524 
525  collector.Collect( board(),
527  wxPoint( aWhere.x, aWhere.y ), guide );
528 
529  bool anyCollected = collector.GetCount() != 0;
530 
531  // Remove unselectable items
532  for( int i = collector.GetCount() - 1; i >= 0; --i )
533  {
534  if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() ) )
535  collector.Remove( i );
536  }
537 
539 
540  // Allow the client to do tool- or action-specific filtering to see if we
541  // can get down to a single item
542  if( aClientFilter )
543  aClientFilter( aWhere, collector );
544 
545  if( collector.GetCount() == 0 )
546  {
547  if( !m_additive && anyCollected )
548  {
549  clearSelection();
550  }
551  return false;
552  }
553 
554  if( collector.GetCount() == 1 )
555  {
556  toggleSelection( collector[0] );
557  return true;
558  }
559 
560  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
561  if( !m_skip_heuristics )
562  {
563  guessSelectionCandidates( collector, aWhere );
564 
565  if( collector.GetCount() == 1 )
566  {
567  toggleSelection( collector[0] );
568  return true;
569  }
570  }
571 
572  // Still more than one item. We're going to have to ask the user.
573  if( aOnDrag )
574  {
576  }
577 
578  BOARD_ITEM* item = doSelectionMenu( &collector, _( "Clarify Selection" ) );
579 
580  if( item )
581  {
582  toggleSelection( item );
583  return true;
584  }
585  else
586  {
587  if( aSelectionCancelledFlag )
588  *aSelectionCancelledFlag = true;
589 
590  return false;
591  }
592 
593  return false;
594 }
595 
596 
597 bool SELECTION_TOOL::selectCursor( bool aSelectAlways, CLIENT_SELECTION_FILTER aClientFilter )
598 {
599  if( aSelectAlways || m_selection.Empty() )
600  {
601  clearSelection();
602  selectPoint( getViewControls()->GetCursorPosition( false ), false, NULL, aClientFilter );
603  }
604 
605  return !m_selection.Empty();
606 }
607 
608 
610 {
611  bool cancelled = false; // Was the tool cancelled while it was running?
612  m_multiple = true; // Multiple selection mode is active
613  KIGFX::VIEW* view = getView();
614 
616  view->Add( &area );
617 
618  while( OPT_TOOL_EVENT evt = Wait() )
619  {
621  {
622  cancelled = true;
623  break;
624  }
625 
626  if( evt->IsDrag( BUT_LEFT ) )
627  {
628  // Start drawing a selection box
629  area.SetOrigin( evt->DragOrigin() );
630  area.SetEnd( evt->Position() );
631  area.SetAdditive( m_additive );
633 
634  view->SetVisible( &area, true );
635  view->Update( &area );
636  getViewControls()->SetAutoPan( true );
637  }
638 
639  if( evt->IsMouseUp( BUT_LEFT ) )
640  {
641  getViewControls()->SetAutoPan( false );
642 
643  // End drawing the selection box
644  view->SetVisible( &area, false );
645 
646  // Mark items within the selection box as selected
647  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
648 
649  // Filter the view items based on the selection box
650  BOX2I selectionBox = area.ViewBBox();
651  view->Query( selectionBox, selectedItems ); // Get the list of selected items
652 
653  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
654 
655  int width = area.GetEnd().x - area.GetOrigin().x;
656  int height = area.GetEnd().y - area.GetOrigin().y;
657 
658  /* Selection mode depends on direction of drag-selection:
659  * Left > Right : Select objects that are fully enclosed by selection
660  * Right > Left : Select objects that are crossed by selection
661  */
662  bool windowSelection = width >= 0 ? true : false;
663 
664  if( view->IsMirroredX() )
665  windowSelection = !windowSelection;
666 
667  // Construct an EDA_RECT to determine BOARD_ITEM selection
668  EDA_RECT selectionRect( wxPoint( area.GetOrigin().x, area.GetOrigin().y ),
669  wxSize( width, height ) );
670 
671  selectionRect.Normalize();
672 
673  for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
674  {
675  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
676 
677  if( !item || !selectable( item ) )
678  continue;
679 
680  if( windowSelection )
681  {
682  BOX2I bbox = getRect( item );
683 
684  if( selectionBox.Contains( bbox ) )
685  {
686  if( m_subtractive )
687  unselect( item );
688  else
689  select( item );
690  }
691  }
692  else
693  {
694  if( item->HitTest( selectionRect, false ) )
695  {
696  if( m_subtractive )
697  unselect( item );
698  else
699  select( item );
700  }
701  }
702  }
703 
704  if( m_frame )
705  {
706  if( m_selection.Size() == 1 )
707  m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
708  else
709  m_frame->SetCurItem( NULL );
710  }
711 
712  // Inform other potentially interested tools
713  if( !m_selection.Empty() )
715 
716  break; // Stop waiting for events
717  }
718  }
719 
720  getViewControls()->SetAutoPan( false );
721 
722  // Stop drawing the selection box
723  view->Remove( &area );
724  m_multiple = false; // Multiple selection mode is inactive
725 
726  if( !cancelled )
728 
729  return cancelled;
730 }
731 
732 
734 {
743  Go( &SELECTION_TOOL::find, PCB_ACTIONS::find.MakeEvent() );
753 }
754 
755 
757 {
758  if( !m_locked || m_editModules )
759  return SELECTION_UNLOCKED;
760 
761  bool containsLocked = false;
762 
763  // Check if the selection contains locked items
764  for( const auto& item : m_selection )
765  {
766  switch( item->Type() )
767  {
768  case PCB_MODULE_T:
769  if( static_cast<MODULE*>( item )->IsLocked() )
770  containsLocked = true;
771  break;
772 
773  case PCB_MODULE_EDGE_T:
774  case PCB_MODULE_TEXT_T:
775  if( static_cast<MODULE*>( item->GetParent() )->IsLocked() )
776  containsLocked = true;
777  break;
778 
779  default: // suppress warnings
780  break;
781  }
782  }
783 
784  if( containsLocked )
785  {
786  if( IsOK( m_frame, _( "Selection contains locked items. Do you want to continue?" ) ) )
787  {
788  m_locked = false;
790  }
791  else
792  return SELECTION_LOCKED;
793  }
794 
795  return SELECTION_UNLOCKED;
796 }
797 
798 
800 {
802 
803  selectCursor( false, aClientFilter );
804 
805  return 0;
806 }
807 
808 
810 {
811  clearSelection();
812 
813  return 0;
814 }
815 
816 
818 {
819  std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
820 
821  if( items )
822  {
823  // Perform individual selection of each item
824  // before processing the event.
825  for( auto item : *items )
826  {
827  select( item );
828  }
829 
831  }
832 
833  return 0;
834 }
835 
836 
838 {
839  // Check if there is an item to be selected
840  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
841 
842  if( item )
843  {
844  select( item );
845 
846  // Inform other potentially interested tools
848  }
849 
850  return 0;
851 }
852 
853 
855 {
856  std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
857 
858  if( items )
859  {
860  // Perform individual unselection of each item
861  // before processing the event
862  for( auto item : *items )
863  {
864  unselect( item );
865  }
866 
868  }
869 
870  return 0;
871 }
872 
873 
875 {
876  // Check if there is an item to be selected
877  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
878 
879  if( item )
880  {
881  unselect( item );
882 
883  // Inform other potentially interested tools
885  }
886 
887  return 0;
888 }
889 
890 
891 void connectedTrackFilter( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
892 {
893  /* Narrow the collection down to a single TRACK item for a trivial
894  * connection, or multiple TRACK items for non-trivial connections.
895  */
896  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
897  {
898  if( !dynamic_cast<TRACK*>( aCollector[i] ) )
899  aCollector.Remove( i );
900  }
901 
902  ROUTER_TOOL::NeighboringSegmentFilter( aPt, aCollector );
903 }
904 
905 
907 {
910 
912  return 0;
913 
914  return expandSelectedConnection( aEvent );
915 }
916 
917 
919 {
920  // copy the selection, since we're going to iterate and modify
921  auto selection = m_selection.GetItems();
922 
923  // We use the BUSY flag to mark connections
924  for( auto item : selection )
925  item->SetState( BUSY, false );
926 
927  for( auto item : selection )
928  {
929  TRACK* trackItem = dynamic_cast<TRACK*>( item );
930 
931  // Track items marked BUSY have already been visited
932  // therefore their connections have already been marked
933  if( trackItem && !trackItem->GetState( BUSY ) )
934  selectAllItemsConnectedToTrack( *trackItem );
935  }
936 
937  // Inform other potentially interested tools
938  if( m_selection.Size() > 0 )
940 
941  return 0;
942 }
943 
944 
945 void connectedItemFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
946 {
947  /* Narrow the collection down to a single BOARD_CONNECTED_ITEM for each
948  * represented net. All other items types are removed.
949  */
950  std::set<int> representedNets;
951 
952  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
953  {
954  BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[i] );
955  if( !item )
956  aCollector.Remove( i );
957  else if ( representedNets.count( item->GetNetCode() ) )
958  aCollector.Remove( i );
959  else
960  representedNets.insert( item->GetNetCode() );
961  }
962 }
963 
964 
966 {
967  bool haveCopper = false;
968 
969  for( auto item : m_selection.GetItems() )
970  {
971  if( dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
972  haveCopper = true;;
973  }
974 
975  if( !haveCopper )
977 
978  // copy the selection, since we're going to iterate and modify
979  auto selection = m_selection.GetItems();
980 
981  for( auto item : selection )
982  {
983  BOARD_CONNECTED_ITEM* connItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( item );
984 
985  if( connItem )
986  selectAllItemsConnectedToItem( *connItem );
987  }
988 
989  // Inform other potentially interested tools
990  if( m_selection.Size() > 0 )
992 
993  return 0;
994 }
995 
996 
998 {
999  int segmentCount;
1000  TRACK* trackList = board()->MarkTrace( board()->m_Track, &aSourceTrack, &segmentCount,
1001  nullptr, nullptr, true );
1002 
1003  for( int i = 0; i < segmentCount; ++i )
1004  {
1005  select( trackList );
1006  trackList = trackList->Next();
1007  }
1008 }
1009 
1010 
1012 {
1013  constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_PAD_T, EOT };
1014  auto connectivity = board()->GetConnectivity();
1015 
1016  for( auto item : connectivity->GetConnectedItems( &aSourceItem, types ) )
1017  {
1018  // We want to select items connected through pads but not pads
1019  // otherwise, the common use case of "Select Copper"->Delete will
1020  // remove footprints in addition to traces and vias
1021  if( item->Type() != PCB_PAD_T )
1022  select( item );
1023  }
1024 }
1025 
1026 
1028 {
1029  constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, EOT };
1030  auto connectivity = board()->GetConnectivity();
1031 
1032  for( auto item : connectivity->GetNetItems( aNetCode, types ) )
1033  select( item );
1034 }
1035 
1036 
1038 {
1039  if( !selectCursor() )
1040  return 0;
1041 
1042  // copy the selection, since we're going to iterate and modify
1043  auto selection = m_selection.GetItems();
1044 
1045  for( auto i : selection )
1046  {
1047  auto item = static_cast<BOARD_ITEM*>( i );
1048 
1049  // only connected items get a net code
1050  if( item->IsConnected() )
1051  {
1052  auto& connItem = static_cast<BOARD_CONNECTED_ITEM&>( *item );
1053 
1054  selectAllItemsOnNet( connItem.GetNetCode() );
1055  }
1056  }
1057 
1058  // Inform other potentially interested tools
1059  if( m_selection.Size() > 0 )
1061 
1062  return 0;
1063 }
1064 
1065 
1066 void SELECTION_TOOL::selectAllItemsOnSheet( wxString& aSheetpath )
1067 {
1068  auto modules = board()->m_Modules.GetFirst();
1069  std::list<MODULE*> modList;
1070 
1071  // store all modules that are on that sheet
1072  for( MODULE* mitem = modules; mitem; mitem = mitem->Next() )
1073  {
1074  if( mitem != NULL && mitem->GetPath().Contains( aSheetpath ) )
1075  {
1076  modList.push_back( mitem );
1077  }
1078  }
1079 
1080  //Generate a list of all pads, and of all nets they belong to.
1081  std::list<int> netcodeList;
1082  std::list<BOARD_CONNECTED_ITEM*> padList;
1083  for( MODULE* mmod : modList )
1084  {
1085  for( auto pad : mmod->Pads() )
1086  {
1087  if( pad->IsConnected() )
1088  {
1089  netcodeList.push_back( pad->GetNetCode() );
1090  padList.push_back( pad );
1091  }
1092  }
1093  }
1094  // remove all duplicates
1095  netcodeList.sort();
1096  netcodeList.unique();
1097 
1098  // auto select trivial connections segments which are launched from the pads
1099  std::list<TRACK*> launchTracks;
1100 
1101  for( auto pad : padList )
1102  {
1103  launchTracks = board()->GetTracksByPosition( pad->GetPosition() );
1104 
1105  for( auto track : launchTracks )
1106  {
1108  }
1109  }
1110 
1111  // now we need to find all modules that are connected to each of these nets
1112  // then we need to determine if these modules are in the list of modules
1113  // belonging to this sheet ( modList )
1114  std::list<int> removeCodeList;
1115  constexpr KICAD_T padType[] = { PCB_PAD_T, EOT };
1116 
1117  for( int netCode : netcodeList )
1118  {
1119  for( BOARD_CONNECTED_ITEM* mitem : board()->GetConnectivity()->GetNetItems( netCode, padType ) )
1120  {
1121  if( mitem->Type() == PCB_PAD_T)
1122  {
1123  bool found = ( std::find( modList.begin(), modList.end(),
1124  mitem->GetParent() ) != modList.end() );
1125 
1126  if( !found )
1127  {
1128  // if we cannot find the module of the pad in the modList
1129  // then we can assume that that module is not located in the same
1130  // schematic, therefore invalidate this netcode.
1131  removeCodeList.push_back( netCode );
1132  break;
1133  }
1134  }
1135  }
1136  }
1137 
1138  // remove all duplicates
1139  removeCodeList.sort();
1140  removeCodeList.unique();
1141 
1142  for( int removeCode : removeCodeList )
1143  {
1144  netcodeList.remove( removeCode );
1145  }
1146 
1147  std::list<BOARD_CONNECTED_ITEM*> localConnectionList;
1148  constexpr KICAD_T trackViaType[] = { PCB_TRACE_T, PCB_VIA_T, EOT };
1149 
1150  for( int netCode : netcodeList )
1151  {
1152  for( BOARD_CONNECTED_ITEM* item : board()->GetConnectivity()->GetNetItems( netCode, trackViaType ) )
1153  {
1154  localConnectionList.push_back( item );
1155  }
1156  }
1157 
1158  for( BOARD_ITEM* i : modList )
1159  {
1160  if( i != NULL )
1161  select( i );
1162  }
1163 
1164  for( BOARD_CONNECTED_ITEM* i : localConnectionList )
1165  {
1166  if( i != NULL )
1167  select( i );
1168  }
1169 }
1170 
1171 
1173 {
1174  //Should recalculate the view to zoom in on the selection
1175  auto selectionBox = m_selection.ViewBBox();
1176  auto canvas = m_frame->GetGalCanvas();
1177  auto view = getView();
1178 
1179  VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
1180 
1181  if( !( selectionBox.GetWidth() == 0 ) || !( selectionBox.GetHeight() == 0 ) )
1182  {
1183  VECTOR2D vsize = selectionBox.GetSize();
1184  double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
1185  fabs( vsize.y / screenSize.y ) );
1186  view->SetScale( scale );
1187  view->SetCenter( selectionBox.Centre() );
1188  view->Add( &m_selection );
1189  }
1190 
1192 }
1193 
1194 
1196 {
1197  clearSelection();
1198  wxString* sheetpath = aEvent.Parameter<wxString*>();
1199 
1200  selectAllItemsOnSheet( *sheetpath );
1201 
1202  zoomFitSelection();
1203 
1204  if( m_selection.Size() > 0 )
1206 
1207  return 0;
1208 }
1209 
1210 
1212 {
1213  if( !selectCursor( true ) )
1214  return 0;
1215 
1216  // this function currently only supports modules since they are only
1217  // on one sheet.
1218  auto item = m_selection.Front();
1219 
1220  if( !item )
1221  return 0;
1222 
1223  if( item->Type() != PCB_MODULE_T )
1224  return 0;
1225 
1226  auto mod = dynamic_cast<MODULE*>( item );
1227 
1228  clearSelection();
1229 
1230  // get the lowest subsheet name for this.
1231  wxString sheetPath = mod->GetPath();
1232  sheetPath = sheetPath.BeforeLast( '/' );
1233  sheetPath = sheetPath.AfterLast( '/' );
1234 
1235  selectAllItemsOnSheet( sheetPath );
1236 
1237  // Inform other potentially interested tools
1238  if( m_selection.Size() > 0 )
1240 
1241  return 0;
1242 }
1243 
1244 
1246 {
1247  clearSelection();
1248 
1249  if( aItem )
1250  {
1251  select( aItem );
1252  getView()->SetCenter( aItem->GetPosition() );
1253 
1254  // Inform other potentially interested tools
1256  }
1257 
1259 }
1260 
1261 
1262 int SELECTION_TOOL::find( const TOOL_EVENT& aEvent )
1263 {
1264  DIALOG_FIND dlg( m_frame );
1265  dlg.SetCallback( std::bind( &SELECTION_TOOL::findCallback, this, _1 ) );
1266  dlg.ShowModal();
1267 
1268  return 0;
1269 }
1270 
1271 
1273 {
1275 
1276  if( module )
1277  {
1278  KIGFX::VIEW_CONTROLS* viewCtrls = getViewControls();
1279  clearSelection();
1280  toggleSelection( module, true );
1281 
1282  auto cursorPosition = viewCtrls->GetCursorPosition( false );
1283 
1284  // Set a reference point so InteractiveEdit will move it to the
1285  // cursor before waiting for mouse move events
1287 
1288  // Place event on module origin first, so the generic anchor snap
1289  // doesn't just choose the closest pin for us
1290  viewCtrls->ForceCursorPosition( true, module->GetPosition() );
1291 
1292  // pick the component up and start moving
1293  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
1294 
1295  // restore the previous cursor position
1296  viewCtrls->SetCursorPosition( cursorPosition, false );
1297  }
1298 
1299  return 0;
1300 }
1301 
1302 
1311 static bool itemIsIncludedByFilter( const BOARD_ITEM& aItem,
1312  const BOARD& aBoard,
1313  const DIALOG_BLOCK_OPTIONS::OPTIONS& aBlockOpts )
1314 {
1315  bool include = true;
1316  const PCB_LAYER_ID layer = aItem.GetLayer();
1317 
1318  // can skip without even checking item type
1319  // fixme: selecting items on invisible layers does not work in GAL
1320  if( !aBlockOpts.includeItemsOnInvisibleLayers
1321  && !aBoard.IsLayerVisible( layer ) )
1322  {
1323  include = false;
1324  }
1325 
1326  // if the item needs to be checked against the options
1327  if( include )
1328  {
1329  switch( aItem.Type() )
1330  {
1331  case PCB_MODULE_T:
1332  {
1333  const auto& module = static_cast<const MODULE&>( aItem );
1334 
1335  include = aBlockOpts.includeModules;
1336 
1337  if( include && !aBlockOpts.includeLockedModules )
1338  {
1339  include = !module.IsLocked();
1340  }
1341 
1342  break;
1343  }
1344  case PCB_TRACE_T:
1345  {
1346  include = aBlockOpts.includeTracks;
1347  break;
1348  }
1349  case PCB_VIA_T:
1350  {
1351  include = aBlockOpts.includeVias;
1352  break;
1353  }
1354  case PCB_ZONE_AREA_T:
1355  {
1356  include = aBlockOpts.includeZones;
1357  break;
1358  }
1359  case PCB_LINE_T:
1360  case PCB_TARGET_T:
1361  case PCB_DIMENSION_T:
1362  {
1363  if( layer == Edge_Cuts )
1364  include = aBlockOpts.includeBoardOutlineLayer;
1365  else
1366  include = aBlockOpts.includeItemsOnTechLayers;
1367  break;
1368  }
1369  case PCB_TEXT_T:
1370  {
1371  include = aBlockOpts.includePcbTexts;
1372  break;
1373  }
1374  default:
1375  {
1376  // no filtering, just select it
1377  break;
1378  }
1379  }
1380  }
1381 
1382  return include;
1383 }
1384 
1385 
1387 {
1388  auto& opts = m_priv->m_filterOpts;
1389  DIALOG_BLOCK_OPTIONS dlg( m_frame, opts, false, _( "Filter selection" ) );
1390 
1391  const int cmd = dlg.ShowModal();
1392 
1393  if( cmd != wxID_OK )
1394  return 0;
1395 
1396  const auto& board = *getModel<BOARD>();
1397 
1398  // copy current selection
1399  auto selection = m_selection.GetItems();
1400 
1401  // clear current selection
1402  clearSelection();
1403 
1404  // copy selection items from the saved selection
1405  // according to the dialog options
1406  for( auto i : selection )
1407  {
1408  auto item = static_cast<BOARD_ITEM*>( i );
1409  bool include = itemIsIncludedByFilter( *item, board, opts );
1410 
1411  if( include )
1412  {
1413  select( item );
1414  }
1415  }
1416  return 0;
1417 }
1418 
1419 
1421 {
1422  if( m_selection.Empty() )
1423  return;
1424 
1425  while( m_selection.GetSize() )
1426  unhighlight( static_cast<BOARD_ITEM*>( m_selection.Front() ), SELECTED, m_selection );
1427 
1428  view()->Update( &m_selection );
1429 
1430  m_selection.SetIsHover( false );
1432 
1433  if( m_frame )
1434  {
1435  m_frame->SetCurItem( NULL );
1436  }
1437 
1438  m_locked = true;
1439 
1440  // Inform other potentially interested tools
1443 }
1444 
1445 
1447 {
1448  GENERAL_COLLECTOR* collector = aEvent.Parameter<GENERAL_COLLECTOR*>();
1449  doSelectionMenu( collector, wxEmptyString );
1450 
1451  return 0;
1452 }
1453 
1454 
1456  const wxString& aTitle )
1457 {
1458  BOARD_ITEM* current = NULL;
1459  SELECTION highlightGroup;
1460  CONTEXT_MENU menu;
1461 
1462  highlightGroup.SetLayer( LAYER_SELECT_OVERLAY );
1463  getView()->Add( &highlightGroup );
1464 
1465  int limit = std::min( 9, aCollector->GetCount() );
1466 
1467  for( int i = 0; i < limit; ++i )
1468  {
1469  wxString text;
1470  BOARD_ITEM* item = ( *aCollector )[i];
1471  text = item->GetSelectMenuText( m_frame->GetUserUnits() );
1472 
1473  wxString menuText = wxString::Format("&%d. %s", i + 1, text );
1474  menu.Add( menuText, i + 1, item->GetMenuImage() );
1475  }
1476 
1477  if( aTitle.Length() )
1478  menu.SetTitle( aTitle );
1479  menu.SetIcon( info_xpm );
1480  menu.DisplayTitle( true );
1481  SetContextMenu( &menu, CMENU_NOW );
1482 
1483  while( OPT_TOOL_EVENT evt = Wait() )
1484  {
1485  if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
1486  {
1487  if( current )
1488  unhighlight( current, BRIGHTENED, highlightGroup );
1489 
1490  int id = *evt->GetCommandId();
1491 
1492  // User has pointed an item, so show it in a different way
1493  if( id > 0 && id <= limit )
1494  {
1495  current = ( *aCollector )[id - 1];
1496  highlight( current, BRIGHTENED, highlightGroup );
1497  }
1498  else
1499  {
1500  current = NULL;
1501  }
1502  }
1503  else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
1504  {
1505  if( current )
1506  unhighlight( current, BRIGHTENED, highlightGroup );
1507 
1508  OPT<int> id = evt->GetCommandId();
1509 
1510  // User has selected an item, so this one will be returned
1511  if( id && ( *id > 0 ) )
1512  current = ( *aCollector )[*id - 1];
1513  else
1514  current = NULL;
1515 
1516  break;
1517  }
1518  }
1519  getView()->Remove( &highlightGroup );
1520 
1521  return current;
1522 }
1523 
1524 
1526 {
1527  int count = aCollector->GetPrimaryCount(); // try to use preferred layer
1528 
1529  if( 0 == count )
1530  count = aCollector->GetCount();
1531 
1532  for( int i = 0; i < count; ++i )
1533  {
1534  if( ( *aCollector )[i]->Type() != PCB_MODULE_T )
1535  return NULL;
1536  }
1537 
1538  // All are modules, now find smallest MODULE
1539  int minDim = 0x7FFFFFFF;
1540  int minNdx = 0;
1541 
1542  for( int i = 0; i < count; ++i )
1543  {
1544  MODULE* module = (MODULE*) ( *aCollector )[i];
1545 
1546  int lx = module->GetFootprintRect().GetWidth();
1547  int ly = module->GetFootprintRect().GetHeight();
1548 
1549  int lmin = std::min( lx, ly );
1550 
1551  if( lmin < minDim )
1552  {
1553  minDim = lmin;
1554  minNdx = i;
1555  }
1556  }
1557 
1558  return (*aCollector)[minNdx];
1559 }
1560 
1561 
1562 bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem, bool checkVisibilityOnly ) const
1563 {
1564  // Is high contrast mode enabled?
1565  bool highContrast = getView()->GetPainter()->GetSettings()->GetHighContrast();
1566 
1567  int layers[KIGFX::VIEW::VIEW_MAX_LAYERS], layers_count;
1568 
1569  // Filter out items that do not belong to active layers
1570  std::set<unsigned int> activeLayers = getView()->GetPainter()->GetSettings()->GetActiveLayers();
1571 
1572  // The markers layer is considered to be always active
1573  activeLayers.insert( (unsigned int) LAYER_DRC );
1574 
1575  aItem->ViewGetLayers( layers, layers_count );
1576 
1577  if( highContrast )
1578  {
1579  bool onActive = false; // Is the item on any of active layers?
1580 
1581  for( int i = 0; i < layers_count; ++i )
1582  {
1583  if( activeLayers.count( layers[i] ) > 0 ) // Item is on at least one of the active layers
1584  {
1585  onActive = true;
1586  break;
1587  }
1588  }
1589 
1590  if( !onActive ) // We do not want to select items that are in the background
1591  {
1592  return false;
1593  }
1594  }
1595 
1596  switch( aItem->Type() )
1597  {
1598  case PCB_ZONE_AREA_T:
1599  // Keepout zones can exist on multiple layers!
1600  {
1601  auto* zone = static_cast<const ZONE_CONTAINER*>( aItem );
1602 
1603  if( zone->GetIsKeepout() )
1604  {
1605  auto zoneLayers = zone->GetLayerSet().Seq();
1606 
1607  for( unsigned int i = 0; i < zoneLayers.size(); i++ )
1608  {
1609  if( board()->IsLayerVisible( zoneLayers[i] ) )
1610  {
1611  return true;
1612  }
1613  }
1614 
1615  // No active layers selected!
1616  return false;
1617  }
1618  }
1619  break;
1620 
1621  case PCB_TRACE_T:
1622  {
1623  if( !board()->IsElementVisible( LAYER_TRACKS ) )
1624  return false;
1625  }
1626  break;
1627 
1628  case PCB_VIA_T:
1629  {
1630  const VIA* via = static_cast<const VIA*>( aItem );
1631 
1632  // Check if appropriate element layer is visible
1633  switch( via->GetViaType() )
1634  {
1635  case VIA_THROUGH:
1637  return false;
1638  break;
1639 
1640  case VIA_BLIND_BURIED:
1642  return false;
1643  break;
1644 
1645  case VIA_MICROVIA:
1647  return false;
1648  break;
1649 
1650  default:
1651  wxFAIL;
1652  return false;
1653  }
1654 
1655  // For vias it is enough if only one of its layers is visible
1656  return ( board()->GetVisibleLayers() & via->GetLayerSet() ).any();
1657  }
1658 
1659  case PCB_MODULE_T:
1660  {
1661  // In modedit, we do not want to select the module itself.
1662  if( m_editModules )
1663  return false;
1664 
1665  // Allow selection of footprints if some part of the footprint is visible.
1666 
1667  MODULE* module = const_cast<MODULE*>( static_cast<const MODULE*>( aItem ) );
1668 
1669  for( auto item : module->GraphicalItems() )
1670  {
1671  if( selectable( item, true ) )
1672  return true;
1673  }
1674 
1675  for( auto pad : module->Pads() )
1676  {
1677  if( selectable( pad, true ) )
1678  return true;
1679  }
1680 
1681  return false;
1682  }
1683 
1684  case PCB_MODULE_TEXT_T:
1685  // Multiple selection is only allowed in modedit mode. In pcbnew, you have to select
1686  // module subparts one by one, rather than with a drag selection. This is so you can
1687  // pick up items under an (unlocked) module without also moving the module's sub-parts.
1688  if( !m_editModules && !checkVisibilityOnly )
1689  {
1690  if( m_multiple )
1691  return false;
1692  }
1693 
1694  if( !m_editModules && !view()->IsVisible( aItem ) )
1695  return false;
1696 
1697  break;
1698 
1699  case PCB_MODULE_EDGE_T:
1700  case PCB_PAD_T:
1701  {
1702  // Multiple selection is only allowed in modedit mode. In pcbnew, you have to select
1703  // module subparts one by one, rather than with a drag selection. This is so you can
1704  // pick up items under an (unlocked) module without also moving the module's sub-parts.
1705  if( !m_editModules && !checkVisibilityOnly )
1706  {
1707  if( m_multiple )
1708  return false;
1709  }
1710 
1711  if( aItem->Type() == PCB_PAD_T )
1712  {
1713  auto pad = static_cast<const D_PAD*>( aItem );
1714 
1715  // In pcbnew, locked modules prevent individual pad selection.
1716  // In modedit, we don't enforce this as the module is assumed to be edited by design.
1717  if( !m_editModules && !checkVisibilityOnly )
1718  {
1719  if( pad->GetParent() && pad->GetParent()->IsLocked() )
1720  return false;
1721  }
1722 
1723  // Check render mode (from the Items tab) first
1724  switch( pad->GetAttribute() )
1725  {
1726  case PAD_ATTRIB_STANDARD:
1728  if( !board()->IsElementVisible( LAYER_PADS_TH ) )
1729  return false;
1730  break;
1731 
1732  case PAD_ATTRIB_CONN:
1733  case PAD_ATTRIB_SMD:
1734  if( pad->IsOnLayer( F_Cu ) && !board()->IsElementVisible( LAYER_PAD_FR ) )
1735  return false;
1736  else if( pad->IsOnLayer( B_Cu ) && !board()->IsElementVisible( LAYER_PAD_BK ) )
1737  return false;
1738  break;
1739  }
1740 
1741  // Otherwise, pads are selectable if any draw layer is visible
1742 
1743  // Shortcut: check copper layer visibility
1744  if( board()->IsLayerVisible( F_Cu ) && pad->IsOnLayer( F_Cu ) )
1745  return true;
1746 
1747  if( board()->IsLayerVisible( B_Cu ) && pad->IsOnLayer( B_Cu ) )
1748  return true;
1749 
1750  // Now check the non-copper layers
1751 
1752  bool draw_layer_visible = false;
1753 
1754  int pad_layers[KIGFX::VIEW::VIEW_MAX_LAYERS], pad_layers_count;
1755  pad->ViewGetLayers( pad_layers, pad_layers_count );
1756 
1757  for( int i = 0; i < pad_layers_count; ++i )
1758  {
1759  // NOTE: Only checking the regular layers (not GAL meta-layers)
1760  if( ( ( pad_layers[i] < PCB_LAYER_ID_COUNT ) &&
1761  board()->IsLayerVisible( static_cast<PCB_LAYER_ID>( pad_layers[i] ) ) ) )
1762  {
1763  draw_layer_visible = true;
1764  }
1765  }
1766 
1767  return draw_layer_visible;
1768  }
1769 
1770  break;
1771  }
1772 
1773 
1774  case PCB_MARKER_T: // Always selectable
1775  return true;
1776 
1777  // These are not selectable
1778  case NOT_USED:
1779  case TYPE_NOT_INIT:
1780  return false;
1781 
1782  default: // Suppress warnings
1783  break;
1784  }
1785 
1786  // All other items are selected only if the layer on which they exist is visible
1787  return board()->IsLayerVisible( aItem->GetLayer() );
1788 }
1789 
1790 
1792 {
1793  if( aItem->IsSelected() )
1794  {
1795  return;
1796  }
1797 
1798  if( aItem->Type() == PCB_PAD_T )
1799  {
1800  MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
1801 
1802  if( m_selection.Contains( module ) )
1803  return;
1804  }
1805 
1806  highlight( aItem, SELECTED, m_selection );
1807  view()->Update( &m_selection );
1808 
1809  if( m_frame )
1810  {
1811  if( m_selection.Size() == 1 )
1812  {
1813  // Set as the current item, so the information about selection is displayed
1814  m_frame->SetCurItem( aItem, true );
1815  }
1816  else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
1817  { // called for every next selected item
1818  // If multiple items are selected, do not show the information about the selected item
1819  m_frame->SetCurItem( NULL, true );
1820  }
1821  }
1822 }
1823 
1824 
1826 {
1827  unhighlight( aItem, SELECTED, m_selection );
1828  view()->Update( &m_selection );
1829 
1830  if( m_frame && m_frame->GetCurItem() == aItem )
1831  m_frame->SetCurItem( NULL );
1832 
1833  if( m_selection.Empty() )
1834  m_locked = true;
1835 }
1836 
1837 
1838 void SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGroup )
1839 {
1840  if( aMode == SELECTED )
1841  aItem->SetSelected();
1842  else if( aMode == BRIGHTENED )
1843  aItem->SetBrightened();
1844 
1845  // Hide the original item, so it is shown only on overlay
1846  view()->Hide( aItem, true );
1847 
1848  aGroup.Add( aItem );
1849 
1850  // Modules are treated in a special way - when they are selected, we have to
1851  // unselect all the parts that make the module, not the module itself
1852  if( aItem->Type() == PCB_MODULE_T )
1853  {
1854  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1855  {
1856  if( aMode == SELECTED )
1857  item->SetSelected();
1858  else if( aMode == BRIGHTENED )
1859  {
1860  item->SetBrightened();
1861  aGroup.Add( item );
1862  }
1863  view()->Hide( item, true );
1864  });
1865  }
1866 
1867  // Many selections are very temporal and updating the display each time just
1868  // creates noise.
1869  if( aMode == BRIGHTENED )
1871 }
1872 
1873 
1874 void SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGroup )
1875 {
1876  if( aMode == SELECTED )
1877  aItem->ClearSelected();
1878  else if( aMode == BRIGHTENED )
1879  aItem->ClearBrightened();
1880 
1881  aGroup.Remove( aItem );
1882 
1883  // Restore original item visibility
1884  view()->Hide( aItem, false );
1885  view()->Update( aItem );
1886 
1887  // Modules are treated in a special way - when they are selected, we have to
1888  // unselect all the parts that make the module, not the module itself
1889  if( aItem->Type() == PCB_MODULE_T )
1890  {
1891  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1892  {
1893  if( aMode == SELECTED )
1894  item->ClearSelected();
1895  else if( aMode == BRIGHTENED )
1896  item->ClearBrightened();
1897 
1898  // N.B. if we clear the selection flag for sub-elements, we need to also
1899  // remove the element from the selection group (if it exists)
1900  aGroup.Remove( item );
1901  view()->Hide( item, false );
1902  view()->Update( item );
1903  });
1904  }
1905 
1906  // Many selections are very temporal and updating the display each time just
1907  // creates noise.
1908  if( aMode == BRIGHTENED )
1910 }
1911 
1912 
1913 bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
1914 {
1915  const unsigned GRIP_MARGIN = 20;
1916  VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
1917 
1918  // Check if the point is located within any of the currently selected items bounding boxes
1919  for( auto item : m_selection )
1920  {
1921  BOX2I itemBox = item->ViewBBox();
1922  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
1923 
1924  if( itemBox.Contains( aPoint ) )
1925  return true;
1926  }
1927 
1928  return false;
1929 }
1930 
1931 
1932 static double calcArea( const BOARD_ITEM* aItem )
1933 {
1934  if( aItem->Type() == PCB_TRACE_T )
1935  {
1936  const TRACK* t = static_cast<const TRACK*>( aItem );
1937  return ( t->GetWidth() + t->GetLength() ) * t->GetWidth();
1938  }
1939 
1940  return getRect( aItem ).GetArea();
1941 }
1942 
1943 
1944 /*static double calcMinArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1945 {
1946  double best = std::numeric_limits<double>::max();
1947 
1948  if( !aCollector.GetCount() )
1949  return 0.0;
1950 
1951  for( int i = 0; i < aCollector.GetCount(); i++ )
1952  {
1953  BOARD_ITEM* item = aCollector[i];
1954  if( item->Type() == aType )
1955  best = std::min( best, calcArea( item ) );
1956  }
1957 
1958  return best;
1959 }*/
1960 
1961 
1962 static double calcMaxArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1963 {
1964  double best = 0.0;
1965 
1966  for( int i = 0; i < aCollector.GetCount(); i++ )
1967  {
1968  BOARD_ITEM* item = aCollector[i];
1969  if( item->Type() == aType )
1970  best = std::max( best, calcArea( item ) );
1971  }
1972 
1973  return best;
1974 }
1975 
1976 
1977 static inline double calcCommonArea( const BOARD_ITEM* aItem, const BOARD_ITEM* aOther )
1978 {
1979  if( !aItem || !aOther )
1980  return 0;
1981 
1982  return getRect( aItem ).Common( getRect( aOther ) ).GetArea();
1983 }
1984 
1985 
1986 double calcRatio( double a, double b )
1987 {
1988  if( a == 0.0 && b == 0.0 )
1989  return 1.0;
1990 
1991  if( b == 0.0 )
1993 
1994  return a / b;
1995 }
1996 
1997 
1998 // The general idea here is that if the user clicks directly on a small item inside a larger
1999 // one, then they want the small item. The quintessential case of this is clicking on a pad
2000 // within a footprint, but we also apply it for text within a footprint, footprints within
2001 // larger footprints, and vias within either larger pads or longer tracks.
2002 //
2003 // These "guesses" presume there is area within the larger item to click in to select it. If
2004 // an item is mostly covered by smaller items within it, then the guesses are inappropriate as
2005 // there might not be any area left to click to select the larger item. In this case we must
2006 // leave the items in the collector and bring up a Selection Clarification menu.
2007 //
2008 // We currently check for pads and text mostly covering a footprint, but we don’t check for
2009 // smaller footprints mostly covering a larger footprint.
2010 //
2012  const VECTOR2I& aWhere ) const
2013 {
2014  std::set<BOARD_ITEM*> preferred;
2015  std::set<BOARD_ITEM*> rejected;
2016  std::set<BOARD_ITEM*> forced;
2017  wxPoint where( aWhere.x, aWhere.y );
2018 
2019  // footprints which are below this percentage of the largest footprint will be considered
2020  // for selection; all others will not
2021  constexpr double footprintToFootprintMinRatio = 0.20;
2022  // pads which are below this percentage of their parent's area will exclude their parent
2023  constexpr double padToFootprintMinRatio = 0.45;
2024  // footprints containing items with items-to-footprint area ratio higher than this will be
2025  // forced to stay on the list
2026  constexpr double footprintMaxCoverRatio = 0.80;
2027  constexpr double viaToPadMinRatio = 0.50;
2028  constexpr double trackViaLengthRatio = 2.0;
2029  constexpr double trackTrackLengthRatio = 0.3;
2030  constexpr double textToFeatureMinRatio = 0.2;
2031  constexpr double textToFootprintMinRatio = 0.4;
2032  // If the common area of two compared items is above the following threshold, they cannot
2033  // be rejected (it means they overlap and it might be hard to pick one by selecting
2034  // its unique area).
2035  constexpr double commonAreaRatio = 0.6;
2036 
2037  PCB_LAYER_ID activeLayer = (PCB_LAYER_ID) view()->GetTopLayer();
2038  LSET silkLayers( 2, B_SilkS, F_SilkS );
2039 
2040  if( silkLayers[activeLayer] )
2041  {
2042  for( int i = 0; i < aCollector.GetCount(); ++i )
2043  {
2044  BOARD_ITEM* item = aCollector[i];
2045  KICAD_T type = item->Type();
2046 
2047  if( ( type == PCB_MODULE_TEXT_T || type == PCB_TEXT_T || type == PCB_LINE_T )
2048  && silkLayers[item->GetLayer()] )
2049  {
2050  preferred.insert( item );
2051  }
2052  }
2053 
2054  if( preferred.size() > 0 )
2055  {
2056  aCollector.Empty();
2057 
2058  for( BOARD_ITEM* item : preferred )
2059  aCollector.Append( item );
2060  return;
2061  }
2062  }
2063 
2064  int numZones = aCollector.CountType( PCB_ZONE_AREA_T );
2065 
2066  // Zone edges are very specific; zone fills much less so.
2067  if( numZones > 0 )
2068  {
2069  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2070  {
2071  if( aCollector[i]->Type() == PCB_ZONE_AREA_T )
2072  {
2073  auto zone = static_cast<ZONE_CONTAINER*>( aCollector[i] );
2074 
2075  if( zone->HitTestForEdge( where, 5 * aCollector.GetGuide()->OnePixelInIU() ) )
2076  preferred.insert( zone );
2077  else
2078  rejected.insert( zone );
2079  }
2080  }
2081 
2082  if( preferred.size() > 0 )
2083  {
2084  aCollector.Empty();
2085 
2086  for( BOARD_ITEM* item : preferred )
2087  aCollector.Append( item );
2088  return;
2089  }
2090  }
2091 
2092  if( aCollector.CountType( PCB_MODULE_TEXT_T ) > 0 )
2093  {
2094  for( int i = 0; i < aCollector.GetCount(); ++i )
2095  {
2096  if( TEXTE_MODULE* txt = dyn_cast<TEXTE_MODULE*>( aCollector[i] ) )
2097  {
2098  double textArea = calcArea( txt );
2099 
2100  for( int j = 0; j < aCollector.GetCount(); ++j )
2101  {
2102  if( i == j )
2103  continue;
2104 
2105  BOARD_ITEM* item = aCollector[j];
2106  double itemArea = calcArea( item );
2107  double areaRatio = calcRatio( textArea, itemArea );
2108  double commonArea = calcCommonArea( txt, item );
2109  double itemCommonRatio = calcRatio( commonArea, itemArea );
2110  double txtCommonRatio = calcRatio( commonArea, textArea );
2111 
2112  if( item->Type() == PCB_MODULE_T )
2113  {
2114  // when text area is small compared to an overlapping footprint,
2115  // then it's a clear sign the text is the selection target
2116  if( areaRatio < textToFootprintMinRatio && itemCommonRatio < commonAreaRatio )
2117  rejected.insert( item );
2118  }
2119 
2120  switch( item->Type() )
2121  {
2122  case PCB_TRACE_T:
2123  case PCB_PAD_T:
2124  case PCB_LINE_T:
2125  case PCB_VIA_T:
2126  case PCB_MODULE_T:
2127  if( areaRatio > textToFeatureMinRatio && txtCommonRatio < commonAreaRatio )
2128  rejected.insert( txt );
2129  break;
2130  default:
2131  break;
2132  }
2133  }
2134  }
2135  }
2136  }
2137 
2138  if( aCollector.CountType( PCB_PAD_T ) > 0 )
2139  {
2140  for( int i = 0; i < aCollector.GetCount(); ++i )
2141  {
2142  if( D_PAD* pad = dyn_cast<D_PAD*>( aCollector[i] ) )
2143  {
2144  MODULE* parent = pad->GetParent();
2145  double ratio = calcRatio( calcArea( pad ), calcArea( parent ) );
2146 
2147  // when pad area is small compared to the parent footprint,
2148  // then it is a clear sign the pad is the selection target
2149  if( ratio < padToFootprintMinRatio )
2150  rejected.insert( pad->GetParent() );
2151  }
2152  }
2153  }
2154 
2155  int moduleCount = aCollector.CountType( PCB_MODULE_T );
2156 
2157  if( moduleCount > 0 )
2158  {
2159  double maxArea = calcMaxArea( aCollector, PCB_MODULE_T );
2160  BOX2D viewportD = getView()->GetViewport();
2161  BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
2162  double maxCoverRatio = footprintMaxCoverRatio;
2163 
2164  // MODULE::CoverageRatio() doesn't take zone handles & borders into account so just
2165  // use a more aggressive cutoff point if zones are involved.
2166  if( aCollector.CountType( PCB_ZONE_AREA_T ) )
2167  maxCoverRatio /= 2;
2168 
2169  for( int i = 0; i < aCollector.GetCount(); ++i )
2170  {
2171  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[i] ) )
2172  {
2173  // filter out components larger than the viewport
2174  if( mod->ViewBBox().Contains( viewport ) )
2175  rejected.insert( mod );
2176  // footprints completely covered with other features have no other
2177  // means of selection, so must be kept
2178  else if( mod->CoverageRatio( aCollector ) > maxCoverRatio )
2179  rejected.erase( mod );
2180  // if a footprint is much smaller than the largest overlapping
2181  // footprint then it should be considered for selection
2182  else if( calcRatio( calcArea( mod ), maxArea ) <= footprintToFootprintMinRatio )
2183  continue;
2184  // reject ALL OTHER footprints if there's still something else left
2185  // to select
2186  else if( (int)( rejected.size() + 1 ) < aCollector.GetCount() )
2187  rejected.insert( mod );
2188  }
2189  }
2190  }
2191 
2192  if( aCollector.CountType( PCB_VIA_T ) > 0 )
2193  {
2194  for( int i = 0; i < aCollector.GetCount(); ++i )
2195  {
2196  if( VIA* via = dyn_cast<VIA*>( aCollector[i] ) )
2197  {
2198  double viaArea = calcArea( via );
2199 
2200  for( int j = 0; j < aCollector.GetCount(); ++j )
2201  {
2202  if( i == j )
2203  continue;
2204 
2205  BOARD_ITEM* item = aCollector[j];
2206  double areaRatio = calcRatio( viaArea, calcArea( item ) );
2207 
2208  if( item->Type() == PCB_MODULE_T && areaRatio < padToFootprintMinRatio )
2209  rejected.insert( item );
2210 
2211  if( item->Type() == PCB_PAD_T && areaRatio < viaToPadMinRatio )
2212  rejected.insert( item );
2213 
2214  if( TRACK* track = dyn_cast<TRACK*>( item ) )
2215  {
2216  if( track->GetNetCode() != via->GetNetCode() )
2217  continue;
2218 
2219  double lenRatio = (double) ( track->GetLength() + track->GetWidth() ) /
2220  (double) via->GetWidth();
2221 
2222  if( lenRatio > trackViaLengthRatio )
2223  rejected.insert( track );
2224  }
2225  }
2226  }
2227  }
2228  }
2229 
2230  int nTracks = aCollector.CountType( PCB_TRACE_T );
2231 
2232  if( nTracks > 0 )
2233  {
2234  double maxLength = 0.0;
2235  double minLength = std::numeric_limits<double>::max();
2236  double maxArea = 0.0;
2237  const TRACK* maxTrack = nullptr;
2238 
2239  for( int i = 0; i < aCollector.GetCount(); ++i )
2240  {
2241  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
2242  {
2243  maxLength = std::max( track->GetLength(), maxLength );
2244  maxLength = std::max( (double) track->GetWidth(), maxLength );
2245 
2246  minLength = std::min( std::max( track->GetLength(), (double) track->GetWidth() ), minLength );
2247 
2248  double area = track->GetLength() * track->GetWidth();
2249 
2250  if( area > maxArea )
2251  {
2252  maxArea = area;
2253  maxTrack = track;
2254  }
2255  }
2256  }
2257 
2258  if( maxLength > 0.0 && minLength / maxLength < trackTrackLengthRatio && nTracks > 1 )
2259  {
2260  for( int i = 0; i < aCollector.GetCount(); ++i )
2261  {
2262  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
2263  {
2264  double ratio = std::max( (double) track->GetWidth(), track->GetLength() ) / maxLength;
2265 
2266  if( ratio > trackTrackLengthRatio )
2267  rejected.insert( track );
2268  }
2269  }
2270  }
2271 
2272  for( int j = 0; j < aCollector.GetCount(); ++j )
2273  {
2274  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[j] ) )
2275  {
2276  double ratio = calcRatio( maxArea, mod->GetFootprintRect().GetArea() );
2277 
2278  if( ratio < padToFootprintMinRatio && calcCommonArea( maxTrack, mod ) < commonAreaRatio )
2279  rejected.insert( mod );
2280  }
2281  }
2282  }
2283 
2284  if( (unsigned) aCollector.GetCount() > rejected.size() ) // do not remove everything
2285  {
2286  for( BOARD_ITEM* item : rejected )
2287  {
2288  aCollector.Remove( item );
2289  }
2290  }
2291 }
2292 
2293 
2295 {
2296  getView()->Update( &m_selection );
2297 
2298  return 0;
2299 }
2300 
2301 
2302 const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
2303 const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
2304 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:1506
void ClearReferencePoint()
Definition: selection.h:210
int UnselectItem(const TOOL_EVENT &aEvent)
Item unselection event handler.
int Main(const TOOL_EVENT &aEvent)
Function Main()
void SetIgnoreTracks(bool ignore)
Definition: collectors.h:613
static double calcMaxArea(GENERAL_COLLECTOR &aCollector, KICAD_T aType)
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:59
to draw blind/buried vias
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
BOX2D GetViewport() const
Function GetViewport() Returns the current viewport visible area rectangle.
Definition: view.cpp:538
void SetEnd(VECTOR2I aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:90
void ForceRefresh()
Function ForceRefresh() Forces a redraw.
int GetNetCode() const
Function GetNetCode.
static const KICAD_T AllBoardItems[]
A scan list for all editable board items, like PcbGeneralLocateAndDisplay()
Definition: collectors.h:272
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
bool IsSelected() const
Definition: base_struct.h:224
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 HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
Definition: selection.h:182
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates...
Definition: view.cpp:475
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
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.
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
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:934
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
const SELECTION & selection() const
Definition: pcb_tool.cpp:245
KIGFX::PCB_VIEW * view() const
Definition: pcb_tool.h:137
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
ITER end()
Definition: selection.h:60
static TOOL_ACTION unselectItems
Unselects a list of items (specified as the event parameter)
Definition: pcb_actions.h:65
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: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:376
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:111
void AddSubMenu(std::shared_ptr< CONTEXT_MENU > aSubMenu)
Function CreateSubMenu.
Definition: tool_menu.cpp:55
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
ITER begin()
Definition: collector.h:92
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
int GetWidth() const
Definition: eda_rect.h:117
int UnselectItems(const TOOL_EVENT &aEvent)
Multiple item unselection event handler
show modules on back
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:168
void SetBrightened()
Definition: base_struct.h:232
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:601
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: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.
Template specialization to enable wxStrings for certain containers (e.g. unordered_map) ...
Definition: bitmap.cpp:55
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
ITER end()
Definition: collector.h:93
EDA_RECT Common(const EDA_RECT &aRect) const
Function Common returns the area that is common with another rectangle.
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
#define BUSY
Pcbnew: flag indicating that the structure has.
Definition: base_struct.h:135
void highlight(BOARD_ITEM *aItem, int aHighlightMode, SELECTION &aGroup)
Function selectVisually() Highlights the item visually.
static const TOOL_EVENT ClearedEvent
Event sent after selection is cleared.
const COLLECTORS_GUIDE * GetGuide()
Definition: collectors.h:352
PCB_DRAW_PANEL_GAL * canvas() const
Definition: pcb_tool.cpp:240
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&#39; boundi...
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:367
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
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
static TOOL_ACTION selectionModified
Modified selection notification.
Definition: pcb_actions.h:114
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:179
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 &)
show modules on front
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 GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
int selectCopper(const TOOL_EVENT &aEvent)
Selects items with a continuous copper connection to items in selection
int filterSelection(const TOOL_EVENT &aEvent)
Invoke filter dialog and modify current selection
#define SELECTED
Definition: base_struct.h:121
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > GraphicalItems()
Definition: class_module.h:173
Struct that will be set with the result of the user choices in the dialog.
ITER begin()
Definition: selection.h:59
class MODULE, a footprint
Definition: typeinfo.h:89
bool selectPoint(const VECTOR2I &aWhere, bool aOnDrag=false, bool *aSelectionCancelledFlag=NULL, CLIENT_SELECTION_FILTER aClientFilter=NULL)
Function selectPoint() Selects an item pointed by the parameter aWhere.
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:205
std::list< TRACK * > GetTracksByPosition(const wxPoint &aPosition, PCB_LAYER_ID aLayer=PCB_LAYER_ID(-1)) const
Function GetTracksByPosition finds the list of tracks that starts or ends at aPosition on aLayer...
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:
void AddStandardSubMenus(EDA_DRAW_FRAME &aFrame)
Function CreateBasicMenu.
Definition: tool_menu.cpp:95
Class LSET is a set of PCB_LAYER_IDs.
int expandSelectedConnection(const TOOL_EVENT &aEvent)
Expands the current selection to select a connection between two junctions
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:601
void selectAllItemsOnSheet(wxString &aSheetpath)
Selects all items with the given sheet timestamp name (the sheet path)
void SetSelected()
Definition: base_struct.h:230
static TOOL_ACTION find
Find an item.
Definition: pcb_actions.h:391
void SetIgnoreMTextsOnBack(bool ignore)
Definition: collectors.h:553
int updateSelection(const TOOL_EVENT &aEvent)
Event handler to update the selection VIEW_ITEM.
static TOOL_ACTION hideLocalRatsnest
Definition: pcb_actions.h:387
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).
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:559
BOARD * board() const
Definition: pcb_tool.h:140
static SELECTION_CONDITION OnlyTypes(const std::vector< KICAD_T > &aTypes)
Function OnlyTypes Creates a functor that tests if the selected items are only of given types...
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:290
int selectOnSheetFromEeschema(const TOOL_EVENT &aEvent)
Selects all modules belonging to same sheet, from Eeschema, using crossprobing
SELECTION_LOCK_FLAGS
Definition: selection.h:229
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
virtual int GetTopLayer() const
Definition: view.cpp:850
bool selectCursor(bool aSelectAlways=false, CLIENT_SELECTION_FILTER aClientFilter=NULL)
Function selectCursor() Selects an item under the cursor unless there is something already selected o...
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:149
to draw usual through hole vias
Class TOOL_EVENT.
Definition: tool_event.h:168
bool Contains(EDA_ITEM *aItem) const
Definition: selection.h:108
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:297
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:127
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
VIATYPE_T GetViaType() const
Definition: class_track.h:461
void toggleSelection(BOARD_ITEM *aItem, bool aForce=false)
Function toggleSelection() Changes selection status of a given item.
void SetContextMenu(CONTEXT_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
void clearSelection()
Function clearSelection() Clears the current selection.
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
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.
int SelectionMenu(const TOOL_EVENT &aEvent)
Function SelectionMenu() Allows the selection of a single item from a list of items via a popup menu...
double GetArea() const
Function GetArea returns the area of the rectangle.
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
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty...
Definition: dlist.h:163
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1539
int SelectItem(const TOOL_EVENT &aEvent)
Item selection event handler.
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:62
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
virtual void SetLayer(int aLayer)
Function SetLayer() Sets layer used to draw the group.
Definition: view_group.h:115
int GetHeight() const
Definition: eda_rect.h:118
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg...
int selectNet(const TOOL_EVENT &aEvent)
Selects all copper connections belonging to the same net(s) as the items in the selection.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
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
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:74
static TOOL_ACTION clearHighlight
Definition: pcb_actions.h:375
const Vec & GetPosition() const
Definition: box2.h:192
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Function IsElementVisible tests whether a given element category is visible.
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:95
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
static TOOL_ACTION filterSelection
Filters the items in the current selection (invokes dialog)
Definition: pcb_actions.h: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.
bool GetHighContrast() const
Function GetHighContrast Returns information about high contrast display mode.
Definition: painter.h:161
virtual bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:300
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:458
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
const int scale
smd pads, front layer
int GetWidth() const
Definition: class_track.h:120
void CloseContextMenu(OPT_TOOL_EVENT &evt)
Function CloseContextMenu.
Definition: tool_menu.cpp:82
TRACK * Next() const
Definition: class_track.h:103
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:376
void AddMenu(CONTEXT_MENU *aMenu, bool aExpand=false, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddMenu()
bool IsType(FRAME_T aType) const
Class to handle a graphic segment.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void selectAllItemsConnectedToTrack(TRACK &aSourceTrack)
Selects all items connected by copper tracks to the given TRACK.
static TOOL_ACTION selectOnSheetFromEeschema
Selects all components on sheet from Eeschema crossprobing.
Definition: pcb_actions.h:83
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:171
double calcRatio(double a, double b)
DLIST< MODULE > m_Modules
Definition: class_board.h:249
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:313
SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, std::vector< BOARD_ITEM *> *aFiltered=NULL, bool aConfirmLockedItems=false)
Function RequestSelection()
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
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
int Size() const
Returns the number of selected parts.
Definition: selection.h:122
virtual wxString GetSelectMenuText(EDA_UNITS_T aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
currently selected items overlay
void guessSelectionCandidates(GENERAL_COLLECTOR &aCollector, const VECTOR2I &aWhere) const
Function guessSelectionCandidates() Tries to guess best selection candidates in case multiple items a...
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:139
static double calcArea(const BOARD_ITEM *aItem)
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
boost::optional< T > OPT
Definition: optional.h:7
MODULE * Next() const
Definition: class_module.h:122
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1485
int SelectItems(const TOOL_EVENT &aEvent)
Multiple item selection event handler
void zoomFitSelection()
Zooms the screen to center and fit the current selection.
Class SELECTION_AREA.
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
MODULE * GetFootprintFromBoardByReference()
Function GetFootprintFromBoardByReference.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:346
const Vec & GetSize() const
Definition: box2.h:187
void DisplayTitle(bool aDisplay=true)
Function DisplayTitle() Decides whether a title for a pop up menu should be displayed.
static TOOL_ACTION findMove
Find an item and start moving.
Definition: pcb_actions.h:394
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
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:391
MODULE * module() const
Definition: pcb_tool.h:141
TRACK * MarkTrace(TRACK *aTrackList, TRACK *aTrace, int *aCount, double *aTraceLength, double *aInPackageLength, bool aReorder)
Function MarkTrace marks a chain of trace segments, connected to aTrace.
double GetScale() const
Function GetScale()
Definition: view.h:268
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
void SetAdditive(bool aAdditive)
BOARD_ITEM_CONTAINER * GetParent() const
BOARD_ITEM * GetCurItem()
virtual BITMAP_DEF GetMenuImage() const
Function GetMenuImage returns a pointer to an image to be used in menus.
void SetHighlight(bool aEnabled, int aNetcode=-1)
Function SetHighlight Turns on/off highlighting - it may be done for the active layer or the specifie...
Definition: painter.h:140
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetState(int type) const
Definition: base_struct.h:240
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:183
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes. ...
#define mod(a, n)
Definition: greymap.cpp:24
void selectAllItemsConnectedToItem(BOARD_CONNECTED_ITEM &aSourceItem)
Selects all items connected (by copper) to the given item.
void setTransitions() override
Sets up handlers for various events.
int CursorSelection(const TOOL_EVENT &aEvent)
Select a single item under cursor event handler.
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:50
void SetIgnoreThroughHolePads(bool ignore)
Definition: collectors.h:589
show modules references (when texts are visibles)
void update() override
Update menu state stub.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false)=0
Moves cursor to the requested position expressed in world coordinates.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:152
DIALOG_BLOCK_OPTIONS::OPTIONS m_filterOpts
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:495
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
#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
void SetIgnorePadsOnBack(bool ignore)
Definition: collectors.h:577
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:82