KiCad PCB EDA Suite
selection_tool.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013-2017 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 #include <limits>
26 
27 #include <functional>
28 using namespace std::placeholders;
29 
30 #include <class_board.h>
31 #include <class_board_item.h>
32 #include <class_track.h>
33 #include <class_module.h>
34 #include <class_pcb_text.h>
35 #include <class_drawsegment.h>
36 
37 #include <wxPcbStruct.h>
38 #include <collectors.h>
39 #include <confirm.h>
40 #include <dialog_find.h>
41 #include <dialog_block_options.h>
42 
43 #include <class_draw_panel_gal.h>
44 #include <view/view_controls.h>
45 #include <view/view_group.h>
47 #include <painter.h>
48 #include <bitmaps.h>
49 #include <hotkeys.h>
50 
51 #include <tool/tool_event.h>
52 #include <tool/tool_manager.h>
53 #include <ratsnest_data.h>
54 
55 #include "selection_tool.h"
56 #include "pcb_bright_box.h"
57 #include "pcb_actions.h"
58 
59 // Selection tool actions
60 TOOL_ACTION PCB_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection",
61  AS_GLOBAL, 0,
62  "", "", NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
63 
64 TOOL_ACTION PCB_ACTIONS::selectionCursor( "pcbnew.InteractiveSelection.Cursor",
65  AS_GLOBAL, 0,
66  "", "" ); // No description, it is not supposed to be shown anywhere
67 
68 TOOL_ACTION PCB_ACTIONS::selectItem( "pcbnew.InteractiveSelection.SelectItem",
69  AS_GLOBAL, 0,
70  "", "" ); // No description, it is not supposed to be shown anywhere
71 
72 TOOL_ACTION PCB_ACTIONS::unselectItem( "pcbnew.InteractiveSelection.UnselectItem",
73  AS_GLOBAL, 0,
74  "", "" ); // No description, it is not supposed to be shown anywhere
75 
76 TOOL_ACTION PCB_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear",
77  AS_GLOBAL, 0,
78  "", "" ); // No description, it is not supposed to be shown anywhere
79 
80 TOOL_ACTION PCB_ACTIONS::selectConnection( "pcbnew.InteractiveSelection.SelectConnection",
81  AS_GLOBAL, 'U',
82  _( "Trivial Connection" ), _( "Selects a connection between two junctions." ) );
83 
84 TOOL_ACTION PCB_ACTIONS::selectCopper( "pcbnew.InteractiveSelection.SelectCopper",
85  AS_GLOBAL, 'I',
86  _( "Copper Connection" ), _( "Selects whole copper connection." ) );
87 
88 TOOL_ACTION PCB_ACTIONS::selectNet( "pcbnew.InteractiveSelection.SelectNet",
89  AS_GLOBAL, 0,
90  _( "Whole Net" ), _( "Selects all tracks & vias belonging to the same net." ) );
91 
92 TOOL_ACTION PCB_ACTIONS::selectOnSheetFromEeschema( "pcbnew.InteractiveSelection.SelectOnSheet",
93  AS_GLOBAL, 0,
94  _( "Sheet" ), _( "Selects all modules and tracks in the schematic sheet" ) );
95 
96 TOOL_ACTION PCB_ACTIONS::selectSameSheet( "pcbnew.InteractiveSelection.SelectSameSheet",
97  AS_GLOBAL, 0,
98  _( "Items in Same Hierarchical Sheet" ),
99  _( "Selects all modules and tracks in the same schematic sheet" ) );
100 
101 TOOL_ACTION PCB_ACTIONS::find( "pcbnew.InteractiveSelection.Find",
102  AS_GLOBAL, 0, //TOOL_ACTION::LegacyHotKey( HK_FIND_ITEM ), // handled by wxWidgets
103  _( "Find Item" ),_( "Searches the document for an item" ), find_xpm );
104 
105 TOOL_ACTION PCB_ACTIONS::findMove( "pcbnew.InteractiveSelection.FindMove",
107 
108 TOOL_ACTION PCB_ACTIONS::filterSelection( "pcbnew.InteractiveSelection.FilterSelection",
109  AS_GLOBAL, 0,
110  _( "Filter Selection" ), _( "Filter the types of items in the selection" ),
111  nullptr );
112 
113 
114 
116 {
117 public:
119  {
120  SetTitle( _( "Select..." ) );
121 
123 
124  AppendSeparator();
125 
128  Add( PCB_ACTIONS::selectNet );
130  }
131 
132 private:
133 
134  void update() override
135  {
136  using S_C = SELECTION_CONDITIONS;
137 
138  const auto& selection = getToolManager()->GetTool<SELECTION_TOOL>()->GetSelection();
139 
140  bool connItem = ( S_C::OnlyType( PCB_VIA_T ) || S_C::OnlyType( PCB_TRACE_T ) )( selection );
141  bool sheetSelEnabled = ( S_C::OnlyType( PCB_MODULE_T ) )( selection );
142 
143  Enable( getMenuId( PCB_ACTIONS::selectNet ), connItem );
144  Enable( getMenuId( PCB_ACTIONS::selectCopper ), connItem );
145  Enable( getMenuId( PCB_ACTIONS::selectConnection ), connItem );
146  Enable( getMenuId( PCB_ACTIONS::selectSameSheet ), sheetSelEnabled );
147  }
148 
149  CONTEXT_MENU* create() const override
150  {
151  return new SELECT_MENU();
152  }
153 };
154 
155 
160 {
161 public:
163 };
164 
165 
167  PCB_TOOL( "pcbnew.InteractiveSelection" ),
168  m_frame( NULL ), m_additive( false ), m_multiple( false ),
169  m_locked( true ), m_menu( *this ),
170  m_priv( std::make_unique<PRIV>() )
171 {
172 
173 }
174 
175 
177 {
178  getView()->Remove( &m_selection );
179 }
180 
181 
183 {
184  auto selectMenu = std::make_shared<SELECT_MENU>();
185  selectMenu->SetTool( this );
186  m_menu.AddSubMenu( selectMenu );
187 
188  auto& menu = m_menu.GetMenu();
189 
190  menu.AddMenu( selectMenu.get(), false, SELECTION_CONDITIONS::NotEmpty );
191  // only show separator if there is a Select menu to show above it
192  menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 );
193 
194  m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
195 
196  return true;
197 }
198 
199 
201 {
202  m_frame = getEditFrame<PCB_BASE_FRAME>();
203  m_locked = true;
204 
205  if( aReason == TOOL_BASE::MODEL_RELOAD )
206  {
207  // Remove pointers to the selected items from containers
208  // without changing their properties (as they are already deleted
209  // while a new board is loaded)
210  m_selection.Clear();
211  getView()->GetPainter()->GetSettings()->SetHighlight( false );
212  }
213  else
214  // Restore previous properties of selected items and remove them from containers
215  clearSelection();
216 
217  // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
218  getView()->Remove( &m_selection );
219  getView()->Add( &m_selection );
220 }
221 
222 
223 int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
224 {
225  // Main loop: keep receiving events
226  while( OPT_TOOL_EVENT evt = Wait() )
227  {
228  // Should selected items be added to the current selection or
229  // become the new selection (discarding previously selected items)
230  m_additive = evt->Modifier( MD_SHIFT );
231 
232  // single click? Select single object
233  if( evt->IsClick( BUT_LEFT ) )
234  {
235  if( evt->Modifier( MD_CTRL ) && !m_editModules )
236  {
238  }
239  else
240  {
241  if( !m_additive )
242  clearSelection();
243 
244  selectPoint( evt->Position() );
245  }
246  }
247 
248  // right click? if there is any object - show the context menu
249  else if( evt->IsClick( BUT_RIGHT ) )
250  {
251  bool emptySelection = m_selection.Empty();
252 
253  if( emptySelection )
254  selectPoint( evt->Position() );
255 
257  }
258 
259  // double click? Display the properties window
260  else if( evt->IsDblClick( BUT_LEFT ) )
261  {
262  if( m_selection.Empty() )
263  selectPoint( evt->Position() );
264 
266  }
267 
268  // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
269  else if( evt->IsDrag( BUT_LEFT ) )
270  {
271  if( m_additive )
272  {
273  selectMultiple();
274  }
275  else if( m_selection.Empty() )
276  {
277  // There is nothing selected, so try to select something
278  if( !selectCursor() )
279  {
280  // If nothings has been selected or user wants to select more
281  // draw the selection box
282  selectMultiple();
283  }
284  else
285  {
286  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
287  }
288  }
289 
290  else
291  {
292  // Check if dragging has started within any of selected items bounding box
293  if( selectionContains( evt->Position() ) )
294  {
295  // Yes -> run the move tool and wait till it finishes
296  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
297  }
298  else
299  {
300  // No -> clear the selection list
301  clearSelection();
302  }
303  }
304  }
305 
306  else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE )
307  {
308  clearSelection();
309  }
310 
311  else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
312  {
313  m_menu.CloseContextMenu( evt );
314  }
315  }
316 
317  // This tool is supposed to be active forever
318  assert( false );
319 
320  return 0;
321 }
322 
323 
325 {
326  return m_selection;
327 }
328 
329 
331 {
332  if ( m_selection.Empty() )
333  {
335  m_selection.SetIsHover( true );
336  }
337  else
338  {
339  m_selection.SetIsHover( false );
340  }
341 
342  // Be careful with iterators: items can be removed from list
343  // that invalidate iterators.
344  for( unsigned ii = 0; ii < m_selection.GetSize(); ii++ )
345  {
346  EDA_ITEM* item = m_selection[ii];
347 
348  if( ( aFlags & SELECTION_EDITABLE ) && item->Type() == PCB_MARKER_T )
349  {
350  unselect( static_cast<BOARD_ITEM *>( item ) );
351  }
352  }
353 
354  if ( aFlags & SELECTION_SANITIZE_PADS )
356 
357  return m_selection;
358 }
359 
360 
362 {
363  if( aItem->IsSelected() )
364  {
365  unselect( aItem );
366 
367  // Inform other potentially interested tools
369  }
370  else
371  {
372  if( !m_additive )
373  clearSelection();
374 
375  // Prevent selection of invisible or inactive items
376  if( selectable( aItem ) )
377  {
378  select( aItem );
379 
380  // Inform other potentially interested tools
382  }
383  }
384 
386 }
387 
388 
389 bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag )
390 {
391  BOARD_ITEM* item;
393  GENERAL_COLLECTOR collector;
394 
395  collector.Collect( board(),
397  wxPoint( aWhere.x, aWhere.y ), guide );
398 
399  bool anyCollected = collector.GetCount() != 0;
400 
401  // Remove unselectable items
402  for( int i = collector.GetCount() - 1; i >= 0; --i )
403  {
404  if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() ) )
405  collector.Remove( i );
406  }
407 
408  switch( collector.GetCount() )
409  {
410  case 0:
411  if( !m_additive && anyCollected )
412  clearSelection();
413 
414  return false;
415 
416  case 1:
417  toggleSelection( collector[0] );
418 
419  return true;
420 
421  default:
422  // Apply some ugly heuristics to avoid disambiguation menus whenever possible
423  guessSelectionCandidates( collector );
424 
425  // Let's see if there is still disambiguation in selection..
426  if( collector.GetCount() == 1 )
427  {
428  toggleSelection( collector[0] );
429 
430  return true;
431  }
432  else if( collector.GetCount() > 1 )
433  {
434  if( aOnDrag )
436 
437  item = disambiguationMenu( &collector );
438 
439  if( item )
440  {
441  toggleSelection( item );
442 
443  return true;
444  }
445  }
446  break;
447  }
448 
449  return false;
450 }
451 
452 
453 bool SELECTION_TOOL::selectCursor( bool aSelectAlways )
454 {
455  if( aSelectAlways || m_selection.Empty() )
456  {
457  clearSelection();
458  selectPoint( getViewControls()->GetCursorPosition() );
459  }
460 
461  return !m_selection.Empty();
462 }
463 
464 
466 {
467  bool cancelled = false; // Was the tool cancelled while it was running?
468  m_multiple = true; // Multiple selection mode is active
469  KIGFX::VIEW* view = getView();
470  getViewControls()->SetAutoPan( true );
471 
473  view->Add( &area );
474 
475  while( OPT_TOOL_EVENT evt = Wait() )
476  {
477  if( evt->IsCancel() )
478  {
479  cancelled = true;
480  break;
481  }
482 
483  if( evt->IsDrag( BUT_LEFT ) )
484  {
485  if( !m_additive )
486  clearSelection();
487 
488  // Start drawing a selection box
489  area.SetOrigin( evt->DragOrigin() );
490  area.SetEnd( evt->Position() );
491  view->SetVisible( &area, true );
492  view->Update( &area );
493  }
494 
495  if( evt->IsMouseUp( BUT_LEFT ) )
496  {
497  // End drawing the selection box
498  view->SetVisible( &area, false );
499 
500  // Mark items within the selection box as selected
501  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
502  BOX2I selectionBox = area.ViewBBox();
503  view->Query( selectionBox, selectedItems ); // Get the list of selected items
504 
505  std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
506 
507  for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
508  {
509  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
510 
511  // Add only those items that are visible and fully within the selection box
512  if( !item->IsSelected() && selectable( item ) &&
513  selectionBox.Contains( item->ViewBBox() ) )
514  {
515  select( item );
516  }
517  }
518 
519  if( m_selection.Size() == 1 )
520  m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
521  else
522  m_frame->SetCurItem( NULL );
523 
524  // Inform other potentially interested tools
525  if( !m_selection.Empty() )
527 
528  break; // Stop waiting for events
529  }
530  }
531 
532  // Stop drawing the selection box
533  view->Remove( &area );
534  m_multiple = false; // Multiple selection mode is inactive
535  getViewControls()->SetAutoPan( false );
536 
537  return cancelled;
538 }
539 
540 
542 {
548  Go( &SELECTION_TOOL::find, PCB_ACTIONS::find.MakeEvent() );
556 }
557 
558 
560 {
561  if( !m_locked || m_editModules )
562  return SELECTION_UNLOCKED;
563 
564  bool containsLocked = false;
565 
566  // Check if the selection contains locked items
567  for( const auto& item : m_selection )
568  {
569  switch( item->Type() )
570  {
571  case PCB_MODULE_T:
572  if( static_cast<MODULE*>( item )->IsLocked() )
573  containsLocked = true;
574  break;
575 
576  case PCB_MODULE_EDGE_T:
577  case PCB_MODULE_TEXT_T:
578  if( static_cast<MODULE*>( item->GetParent() )->IsLocked() )
579  containsLocked = true;
580  break;
581 
582  default: // suppress warnings
583  break;
584  }
585  }
586 
587  if( containsLocked )
588  {
589  if( IsOK( m_frame, _( "Selection contains locked items. Do you want to continue?" ) ) )
590  {
591  m_locked = false;
593  }
594  else
595  return SELECTION_LOCKED;
596  }
597 
598  m_locked = false;
599 
600  return SELECTION_UNLOCKED;
601 }
602 
603 
605 {
606  bool sanitize = (bool) aEvent.Parameter<intptr_t>();
607 
608  if( m_selection.Empty() ) // Try to find an item that could be modified
609  {
610  selectCursor( true );
611 
612  if( CheckLock() == SELECTION_LOCKED )
613  {
614  clearSelection();
615  return 0;
616  }
617  }
618 
619  if( sanitize )
621 
622  return 0;
623 }
624 
625 
627 {
628  clearSelection();
629 
630  return 0;
631 }
632 
634 {
635  // Check if there is an item to be selected
636  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
637 
638  if( item )
639  {
640  select( item );
641 
642  // Inform other potentially interested tools
644  }
645 
646  return 0;
647 }
648 
649 
651 {
652  // Check if there is an item to be selected
653  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
654 
655  if( item )
656  {
657  unselect( item );
658 
659  // Inform other potentially interested tools
661  }
662 
663  return 0;
664 }
665 
666 
668 {
669  if( !selectCursor() )
670  return 0;
671 
672  // copy the selection, since we're going to iterate and modify
673  auto selection = m_selection.GetItems();
674 
675  for( auto item : selection )
676  {
677  // only TRACK items can be checked for trivial connections
678  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_VIA_T )
679  {
680  TRACK& trackItem = static_cast<TRACK&>( *item );
681  selectAllItemsConnectedToTrack( trackItem );
682  }
683  }
684 
685  // Inform other potentially interested tools
686  if( m_selection.Size() > 0 )
688 
689  return 0;
690 }
691 
692 
694 {
695  if( !selectCursor() )
696  return 0;
697 
698  // copy the selection, since we're going to iterate and modify
699  auto selection = m_selection.GetItems();
700 
701  for( auto i : selection )
702  {
703  auto item = static_cast<BOARD_ITEM*>( i );
704  // only connected items can be traversed in the ratsnest
705  if( item->IsConnected() )
706  {
707  auto& connItem = static_cast<BOARD_CONNECTED_ITEM&>( *item );
708 
709  selectAllItemsConnectedToItem( connItem );
710  }
711  }
712 
713  // Inform other potentially interested tools
714  if( m_selection.Size() > 0 )
716 
717  return 0;
718 }
719 
720 
722 {
723  int segmentCount;
724  TRACK* trackList = board()->MarkTrace( &aSourceTrack, &segmentCount,
725  nullptr, nullptr, true );
726 
727  for( int i = 0; i < segmentCount; ++i )
728  {
729  select( trackList );
730  trackList = trackList->Next();
731  }
732 }
733 
734 
736 {
737  RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
738  std::list<BOARD_CONNECTED_ITEM*> itemsList;
739  ratsnest->GetConnectedItems( &aSourceItem, itemsList, (RN_ITEM_TYPE)( RN_TRACKS | RN_VIAS ) );
740 
741  for( BOARD_CONNECTED_ITEM* i : itemsList )
742  select( i );
743 }
744 
745 
747 {
748  RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
749  std::list<BOARD_CONNECTED_ITEM*> itemsList;
750 
751  ratsnest->GetNetItems( aNetCode, itemsList, (RN_ITEM_TYPE)( RN_TRACKS | RN_VIAS ) );
752 
753  for( BOARD_CONNECTED_ITEM* i : itemsList )
754  select( i );
755 }
756 
757 
759 {
760  if( !selectCursor() )
761  return 0;
762 
763  // copy the selection, since we're going to iterate and modify
764  auto selection = m_selection.GetItems();
765 
766  for( auto i : selection )
767  {
768  auto item = static_cast<BOARD_ITEM*>( i );
769  // only connected items get a net code
770  if( item->IsConnected() )
771  {
772  auto& connItem = static_cast<BOARD_CONNECTED_ITEM&>( *item );
773 
774  selectAllItemsOnNet( connItem.GetNetCode() );
775  }
776  }
777 
778  // Inform other potentially interested tools
779  if( m_selection.Size() > 0 )
781 
782  return 0;
783 }
784 
785 
786 void SELECTION_TOOL::selectAllItemsOnSheet( wxString& aSheetpath )
787 {
788  auto modules = board()->m_Modules.GetFirst();
789  std::list<MODULE*> modList;
790 
791  // store all modules that are on that sheet
792  for( MODULE* mitem = modules; mitem; mitem = mitem->Next() )
793  {
794  if( mitem != NULL && mitem->GetPath().Contains( aSheetpath ) )
795  {
796  modList.push_back( mitem );
797  }
798  }
799 
800  //Generate a list of all pads, and of all nets they belong to.
801  std::list<int> netcodeList;
802  for( MODULE* mmod : modList )
803  {
804  for( D_PAD* pad = mmod->Pads().GetFirst(); pad; pad = pad->Next() )
805  {
806  if( pad->IsConnected() )
807  {
808  netcodeList.push_back( pad->GetNetCode() );
809  }
810  }
811  }
812 
813  // remove all duplicates
814  netcodeList.sort();
815  netcodeList.unique();
816 
817  // now we need to find all modules that are connected to each of these nets
818  // then we need to determine if these modules are in the list of modules
819  // belonging to this sheet ( modList )
820  RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
821  std::list<int> removeCodeList;
822  for( int netCode : netcodeList )
823  {
824  std::list<BOARD_CONNECTED_ITEM*> netPads;
825  ratsnest->GetNetItems( netCode, netPads, (RN_ITEM_TYPE)( RN_PADS ) );
826  for( BOARD_CONNECTED_ITEM* mitem : netPads )
827  {
828  bool found = ( std::find( modList.begin(), modList.end(), mitem->GetParent() ) != modList.end() );
829  if( !found )
830  {
831  // if we cannot find the module of the pad in the modList
832  // then we can assume that that module is not located in the same
833  // schematic, therefore invalidate this netcode.
834  removeCodeList.push_back( netCode );
835  break;
836  }
837  }
838  }
839 
840  // remove all duplicates
841  removeCodeList.sort();
842  removeCodeList.unique();
843 
844  for( int removeCode : removeCodeList )
845  {
846  netcodeList.remove( removeCode );
847  }
848 
849  std::list<BOARD_CONNECTED_ITEM*> localConnectionList;
850  for( int netCode : netcodeList )
851  {
852  ratsnest->GetNetItems( netCode, localConnectionList, (RN_ITEM_TYPE)( RN_TRACKS | RN_VIAS ) );
853  }
854 
855  for( BOARD_ITEM* i : modList )
856  {
857  if( i != NULL )
858  select( i );
859  }
860  for( BOARD_CONNECTED_ITEM* i : localConnectionList )
861  {
862  if( i != NULL )
863  select( i );
864  }
865 }
866 
868 {
869  //Should recalculate the view to zoom in on the selection
870  auto selectionBox = m_selection.ViewBBox();
871  auto canvas = m_frame->GetGalCanvas();
872  auto view = getView();
873 
874  VECTOR2D screenSize = view->ToWorld( canvas->GetClientSize(), false );
875 
876  if( !( selectionBox.GetWidth() == 0 ) || !( selectionBox.GetHeight() == 0 ) )
877  {
878  VECTOR2D vsize = selectionBox.GetSize();
879  double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
880  fabs( vsize.y / screenSize.y ) );
881  view->SetScale( scale );
882  view->SetCenter( selectionBox.Centre() );
883  view->Add( &m_selection );
884  }
885 
887 }
888 
889 
891 {
892  clearSelection();
893  wxString* sheetpath = aEvent.Parameter<wxString*>();
894 
895  selectAllItemsOnSheet( *sheetpath );
896 
898 
899  if( m_selection.Size() > 0 )
901 
902 
903  return 0;
904 }
905 
906 
908 {
909  if( !selectCursor( true ) )
910  return 0;
911 
912  // this function currently only supports modules since they are only
913  // on one sheet.
914  auto item = m_selection.Front();
915 
916  if( !item )
917  return 0;
918 
919  if( item->Type() != PCB_MODULE_T )
920  return 0;
921 
922  auto mod = dynamic_cast<MODULE*>( item );
923 
924  clearSelection();
925 
926  // get the lowest subsheet name for this.
927  wxString sheetPath = mod->GetPath();
928  sheetPath = sheetPath.BeforeLast( '/' );
929  sheetPath = sheetPath.AfterLast( '/' );
930 
931  selectAllItemsOnSheet( sheetPath );
932 
933  // Inform other potentially interested tools
934  if( m_selection.Size() > 0 )
936 
937  return 0;
938 }
939 
940 
942 {
943  clearSelection();
944 
945  if( aItem )
946  {
947  select( aItem );
948  EDA_RECT bbox = aItem->GetBoundingBox();
949  BOX2D viewport( VECTOR2D( bbox.GetOrigin() ), VECTOR2D( bbox.GetSize() ) );
950  getView()->SetViewport( viewport );
951 
952  // Inform other potentially interested tools
954  }
955 
957 }
958 
959 
960 int SELECTION_TOOL::find( const TOOL_EVENT& aEvent )
961 {
962  DIALOG_FIND dlg( m_frame );
963  dlg.EnableWarp( false );
964  dlg.SetCallback( std::bind( &SELECTION_TOOL::findCallback, this, _1 ) );
965  dlg.ShowModal();
966 
967  return 0;
968 }
969 
970 
972 {
974 
975  if( module )
976  {
977  clearSelection();
978  toggleSelection( module );
979 
980  // Place event on module origin first, so the generic anchor snap
981  // doesn't just choose the closest pin for us
982  // Don't warp the view - we want the component to
983  // "teleport" to cursor, not move to the components position
984  getViewControls()->ForceCursorPosition( true, module->GetPosition() );
985 
986  // pick the component up and start moving
987  m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
988  }
989 
990  return 0;
991 }
992 
993 
1002 static bool itemIsIncludedByFilter( const BOARD_ITEM& aItem,
1003  const BOARD& aBoard,
1004  const LSET& aTechnlLayerMask,
1005  const DIALOG_BLOCK_OPTIONS::OPTIONS& aBlockOpts )
1006 {
1007  bool include = true;
1008  const LAYER_ID layer = aItem.GetLayer();
1009 
1010  // can skip without even checking item type
1011  if( !aBlockOpts.includeItemsOnInvisibleLayers
1012  && !aBoard.IsLayerVisible( layer ) )
1013  {
1014  include = false;
1015  }
1016 
1017  // if the item needsto be checked agains the options
1018  if( include )
1019  {
1020  switch( aItem.Type() )
1021  {
1022  case PCB_MODULE_T:
1023  {
1024  const auto& module = static_cast<const MODULE&>( aItem );
1025 
1026  include = aBlockOpts.includeModules;
1027 
1028  if( include && !aBlockOpts.includeLockedModules )
1029  {
1030  include = !module.IsLocked();
1031  }
1032 
1033  break;
1034  }
1035  case PCB_TRACE_T:
1036  {
1037  include = aBlockOpts.includeTracks;
1038  break;
1039  }
1040  case PCB_ZONE_AREA_T:
1041  {
1042  include = aBlockOpts.includeZones;
1043  break;
1044  }
1045  case PCB_LINE_T:
1046  case PCB_TARGET_T:
1047  case PCB_DIMENSION_T:
1048  {
1049  include = aTechnlLayerMask[layer];
1050  break;
1051  }
1052  case PCB_TEXT_T:
1053  {
1054  include = aBlockOpts.includePcbTexts
1055  && aTechnlLayerMask[layer];
1056  break;
1057  }
1058  default:
1059  {
1060  // no filterering, just select it
1061  break;
1062  }
1063  }
1064  }
1065 
1066  return include;
1067 }
1068 
1069 
1075 {
1076  LSET layerMask( Edge_Cuts );
1077 
1078  if( blockOpts.includeItemsOnTechLayers )
1079  layerMask.set();
1080 
1081  if( !blockOpts.includeBoardOutlineLayer )
1082  layerMask.set( Edge_Cuts, false );
1083 
1084  return layerMask;
1085 }
1086 
1087 
1089 {
1090  auto& opts = m_priv->m_filterOpts;
1091  DIALOG_BLOCK_OPTIONS dlg( m_frame, opts, false, _( "Filter selection" ) );
1092 
1093  const int cmd = dlg.ShowModal();
1094 
1095  if( cmd != wxID_OK )
1096  return 0;
1097 
1098  const auto& board = *getModel<BOARD>();
1099  const auto layerMask = getFilteredLayerSet( opts );
1100 
1101  // copy current selection
1102  auto selection = m_selection.GetItems();
1103 
1104  // clear current selection
1105  clearSelection();
1106 
1107  // copy selection items from the saved selection
1108  // according to the dialog options
1109  for( auto i : selection )
1110  {
1111  auto item = static_cast<BOARD_ITEM*>( i );
1112  bool include = itemIsIncludedByFilter( *item, board, layerMask, opts );
1113 
1114  if( include )
1115  {
1116  select( item );
1117  }
1118  }
1119  return 0;
1120 }
1121 
1122 
1124 {
1125  if( m_selection.Empty() )
1126  return;
1127 
1128  for( auto item : m_selection )
1129  unselectVisually( static_cast<BOARD_ITEM*>( item ) );
1130 
1131  m_selection.Clear();
1132 
1133  m_frame->SetCurItem( NULL );
1134  m_locked = true;
1135 
1136  // Inform other potentially interested tools
1138 }
1139 
1140 
1142 {
1143  BOARD_ITEM* current = NULL;
1144  PCB_BRIGHT_BOX brightBox;
1145  CONTEXT_MENU menu;
1146 
1147  getView()->Add( &brightBox );
1148 
1149  int limit = std::min( 10, aCollector->GetCount() );
1150 
1151  for( int i = 0; i < limit; ++i )
1152  {
1153  wxString text;
1154  BOARD_ITEM* item = ( *aCollector )[i];
1155  text = item->GetSelectMenuText();
1156  menu.Add( text, i + 1 );
1157  }
1158 
1159  menu.SetTitle( _( "Clarify selection" ) );
1160  menu.DisplayTitle( true );
1161  SetContextMenu( &menu, CMENU_NOW );
1162 
1163  while( OPT_TOOL_EVENT evt = Wait() )
1164  {
1165  if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
1166  {
1167  if( current )
1168  current->ClearBrightened();
1169 
1170  int id = *evt->GetCommandId();
1171 
1172  // User has pointed an item, so show it in a different way
1173  if( id > 0 && id <= limit )
1174  {
1175  current = ( *aCollector )[id - 1];
1176  current->SetBrightened();
1177  }
1178  else
1179  {
1180  current = NULL;
1181  }
1182  }
1183  else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
1184  {
1185  boost::optional<int> id = evt->GetCommandId();
1186 
1187  // User has selected an item, so this one will be returned
1188  if( id && ( *id > 0 ) )
1189  current = ( *aCollector )[*id - 1];
1190  else
1191  current = NULL;
1192 
1193  break;
1194  }
1195 
1196  // Draw a mark to show which item is available to be selected
1197  if( current && current->IsBrightened() )
1198  {
1199  brightBox.SetItem( current );
1200  getView()->SetVisible( &brightBox, true );
1201 // getView()->Hide( &brightBox, false );
1202  getView()->Update( &brightBox, KIGFX::GEOMETRY );
1204  }
1205  }
1206 
1207  getView()->Remove( &brightBox );
1208 
1209 
1210  return current;
1211 }
1212 
1213 
1215 {
1216  int count = aCollector->GetPrimaryCount(); // try to use preferred layer
1217 
1218  if( 0 == count )
1219  count = aCollector->GetCount();
1220 
1221  for( int i = 0; i < count; ++i )
1222  {
1223  if( ( *aCollector )[i]->Type() != PCB_MODULE_T )
1224  return NULL;
1225  }
1226 
1227  // All are modules, now find smallest MODULE
1228  int minDim = 0x7FFFFFFF;
1229  int minNdx = 0;
1230 
1231  for( int i = 0; i < count; ++i )
1232  {
1233  MODULE* module = (MODULE*) ( *aCollector )[i];
1234 
1235  int lx = module->GetBoundingBox().GetWidth();
1236  int ly = module->GetBoundingBox().GetHeight();
1237 
1238  int lmin = std::min( lx, ly );
1239 
1240  if( lmin < minDim )
1241  {
1242  minDim = lmin;
1243  minNdx = i;
1244  }
1245  }
1246 
1247  return (*aCollector)[minNdx];
1248 }
1249 
1250 
1251 bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
1252 {
1253  // Is high contrast mode enabled?
1254  bool highContrast = getView()->GetPainter()->GetSettings()->GetHighContrast();
1255 
1256  if( highContrast )
1257  {
1258  bool onActive = false; // Is the item on any of active layers?
1259  int layers[KIGFX::VIEW::VIEW_MAX_LAYERS], layers_count;
1260 
1261  // Filter out items that do not belong to active layers
1262  const std::set<unsigned int>& activeLayers = getView()->GetPainter()->
1263  GetSettings()->GetActiveLayers();
1264  aItem->ViewGetLayers( layers, layers_count );
1265 
1266  for( int i = 0; i < layers_count; ++i )
1267  {
1268  if( activeLayers.count( layers[i] ) > 0 ) // Item is on at least one of the active layers
1269  {
1270  onActive = true;
1271  break;
1272  }
1273  }
1274 
1275  if( !onActive ) // We do not want to select items that are in the background
1276  return false;
1277  }
1278 
1279  switch( aItem->Type() )
1280  {
1281  case PCB_VIA_T:
1282  {
1283  // For vias it is enough if only one of layers is visible
1284  LAYER_ID top, bottom;
1285 
1286  static_cast<const VIA*>( aItem )->LayerPair( &top, &bottom );
1287 
1288  return board()->IsLayerVisible( top ) || board()->IsLayerVisible( bottom );
1289  }
1290  break;
1291 
1292  case PCB_MODULE_T:
1293  if( aItem->IsOnLayer( F_Cu ) && board()->IsElementVisible( MOD_FR_VISIBLE ) )
1294  return !m_editModules;
1295 
1296  if( aItem->IsOnLayer( B_Cu ) && board()->IsElementVisible( MOD_BK_VISIBLE ) )
1297  return !m_editModules;
1298 
1299  return false;
1300 
1301  break;
1302 
1303  case PCB_MODULE_TEXT_T:
1304  if( m_multiple && !m_editModules )
1305  return false;
1306 
1307  return view()->IsVisible( aItem ) && board()->IsLayerVisible( aItem->GetLayer() );
1308 
1309  case PCB_MODULE_EDGE_T:
1310  case PCB_PAD_T:
1311  {
1312  // Multiple selection is only allowed in modedit mode
1313  // In pcbnew, you have to select subparts of modules
1314  // one-by-one, rather than with a drag selection.
1315  // This is so you can pick up items under an (unlocked)
1316  // module without also moving the module's sub-parts.
1317  if( m_multiple && !m_editModules )
1318  return false;
1319 
1320  // When editing modules, it's allowed to select them, even when
1321  // locked, since you already have to explicitly activate the
1322  // module editor to get to this stage
1323  if ( !m_editModules )
1324  {
1325  MODULE* mod = static_cast<const D_PAD*>( aItem )->GetParent();
1326  if( mod && mod->IsLocked() )
1327  return false;
1328  }
1329 
1330  break;
1331  }
1332 
1333  // These are not selectable
1334  case NOT_USED:
1335  case TYPE_NOT_INIT:
1336  return false;
1337 
1338  default: // Suppress warnings
1339  break;
1340  }
1341 
1342  // All other items are selected only if the layer on which they exist is visible
1343  return board()->IsLayerVisible( aItem->GetLayer() );
1344 }
1345 
1347 {
1348  if( aItem->IsSelected() )
1349  {
1350  return;
1351  }
1352 
1353  if( aItem->Type() == PCB_PAD_T )
1354  {
1355  MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
1356 
1357  if( m_selection.Contains( module ) )
1358  return;
1359  }
1360 
1361  m_selection.Add( aItem );
1362  selectVisually( aItem );
1363 
1364 
1365  if( m_selection.Size() == 1 )
1366  {
1367  // Set as the current item, so the information about selection is displayed
1368  m_frame->SetCurItem( aItem, true );
1369  }
1370  else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
1371  { // called for every next selected item
1372  // If multiple items are selected, do not show the information about the selected item
1373  m_frame->SetCurItem( NULL, true );
1374  }
1375 }
1376 
1377 
1379 {
1380  if( !aItem->IsSelected() )
1381  return;
1382 
1383  m_selection.Remove( aItem );
1384  unselectVisually( aItem );
1385 
1386  if( m_selection.Empty() )
1387  {
1388  m_frame->SetCurItem( NULL );
1389  m_locked = true;
1390  }
1391 }
1392 
1393 
1395 {
1396  // Hide the original item, so it is shown only on overlay
1397  aItem->SetSelected();
1398  view()->Hide( aItem, true );
1399  view()->Update( aItem, KIGFX::GEOMETRY );
1400 
1401  // Modules are treated in a special way - when they are selected, we have to
1402  // unselect all the parts that make the module, not the module itself
1403 
1404  if( aItem->Type() == PCB_MODULE_T )
1405  {
1406  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1407  {
1408  item->SetSelected();
1409  view()->Hide( item, true );
1410  view()->Update( item, KIGFX::GEOMETRY );
1411  } );
1412  }
1413 
1414  view()->Update( &m_selection );
1415 }
1416 
1417 
1419 {
1420  // Restore original item visibility
1421  aItem->ClearSelected();
1422  view()->Hide( aItem, false );
1423  view()->Update( aItem, KIGFX::ALL );
1424 
1425  // Modules are treated in a special way - when they are selected, we have to
1426  // unselect all the parts that make the module, not the module itself
1427 
1428  if( aItem->Type() == PCB_MODULE_T )
1429  {
1430  static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
1431  {
1432  item->ClearSelected();
1433  view()->Hide( item, false );
1434  view()->Update( item, KIGFX::ALL );
1435  });
1436  }
1437 
1438  view()->Update( &m_selection );
1439 }
1440 
1441 
1442 bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
1443 {
1444  const unsigned GRIP_MARGIN = 20;
1445  VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false );
1446 
1447  // Check if the point is located within any of the currently selected items bounding boxes
1448  for( auto item : m_selection )
1449  {
1450  BOX2I itemBox = item->ViewBBox();
1451  itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
1452 
1453  if( itemBox.Contains( aPoint ) )
1454  return true;
1455  }
1456 
1457  return false;
1458 }
1459 
1460 
1461 static EDA_RECT getRect( const BOARD_ITEM* aItem )
1462 {
1463  if( aItem->Type() == PCB_MODULE_T )
1464  return static_cast<const MODULE*>( aItem )->GetFootprintRect();
1465 
1466  return aItem->GetBoundingBox();
1467 }
1468 
1469 
1470 static double calcArea( const BOARD_ITEM* aItem )
1471 {
1472  if( aItem->Type() == PCB_TRACE_T )
1473  {
1474  const TRACK* t = static_cast<const TRACK*>( aItem );
1475  return ( t->GetWidth() + t->GetLength() ) * t->GetWidth();
1476  }
1477 
1478  return getRect( aItem ).GetArea();
1479 }
1480 
1481 
1482 static double calcMinArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1483 {
1484  double best = std::numeric_limits<double>::max();
1485 
1486  if( !aCollector.GetCount() )
1487  return 0.0;
1488 
1489  for( int i = 0; i < aCollector.GetCount(); i++ )
1490  {
1491  BOARD_ITEM* item = aCollector[i];
1492  if( item->Type() == aType )
1493  best = std::min( best, calcArea( item ) );
1494  }
1495 
1496  return best;
1497 }
1498 
1499 
1500 static double calcMaxArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
1501 {
1502  double best = 0.0;
1503 
1504  for( int i = 0; i < aCollector.GetCount(); i++ )
1505  {
1506  BOARD_ITEM* item = aCollector[i];
1507  if( item->Type() == aType )
1508  best = std::max( best, calcArea( item ) );
1509  }
1510 
1511  return best;
1512 }
1513 
1514 
1515 static inline double calcCommonArea( const BOARD_ITEM* aItem, const BOARD_ITEM* aOther )
1516 {
1517  if( !aItem || !aOther )
1518  return 0;
1519 
1520  return getRect( aItem ).Common( getRect( aOther ) ).GetArea();
1521 }
1522 
1523 
1524 double calcRatio( double a, double b )
1525 {
1526  if( a == 0.0 && b == 0.0 )
1527  return 1.0;
1528 
1529  if( b == 0.0 )
1531 
1532  return a / b;
1533 }
1534 
1535 
1536 // todo: explain the selection heuristics
1538 {
1539  std::set<BOARD_ITEM*> rejected;
1540 
1541  const double footprintAreaRatio = 0.2;
1542  const double modulePadMinCoverRatio = 0.45;
1543  const double padViaAreaRatio = 0.5;
1544  const double trackViaLengthRatio = 2.0;
1545  const double trackTrackLengthRatio = 0.3;
1546  const double textToFeatureMinRatio = 0.2;
1547  const double textToFootprintMinRatio = 0.4;
1548  // If the common area of two compared items is above the following threshold, they cannot
1549  // be rejected (it means they overlap and it might be hard to pick one by selecting
1550  // its unique area).
1551  const double commonAreaRatio = 0.6;
1552 
1553  LAYER_ID actLayer = m_frame->GetActiveLayer();
1554 
1555  LSET silkLayers( 2, B_SilkS, F_SilkS );
1556 
1557  if( silkLayers[actLayer] )
1558  {
1559  std::set<BOARD_ITEM*> preferred;
1560 
1561  for( int i = 0; i < aCollector.GetCount(); ++i )
1562  {
1563  BOARD_ITEM* item = aCollector[i];
1564  KICAD_T type = item->Type();
1565 
1566  if( ( type == PCB_MODULE_TEXT_T || type == PCB_TEXT_T || type == PCB_LINE_T )
1567  && silkLayers[item->GetLayer()] )
1568  {
1569  preferred.insert( item );
1570  }
1571  }
1572 
1573  if( preferred.size() != 0 )
1574  {
1575  aCollector.Empty();
1576 
1577  for( BOARD_ITEM* item : preferred )
1578  aCollector.Append( item );
1579  return;
1580  }
1581  }
1582 
1583  if( aCollector.CountType( PCB_MODULE_TEXT_T ) > 0 )
1584  {
1585  for( int i = 0; i < aCollector.GetCount(); ++i )
1586  {
1587  if( TEXTE_MODULE* txt = dyn_cast<TEXTE_MODULE*>( aCollector[i] ) )
1588  {
1589  double textArea = calcArea( txt );
1590 
1591  for( int j = 0; j < aCollector.GetCount(); ++j )
1592  {
1593  if( i == j )
1594  continue;
1595 
1596  BOARD_ITEM* item = aCollector[j];
1597  double itemArea = calcArea( item );
1598  double areaRatio = calcRatio( textArea, itemArea );
1599  double commonArea = calcCommonArea( txt, item );
1600  double itemCommonRatio = calcRatio( commonArea, itemArea );
1601  double txtCommonRatio = calcRatio( commonArea, textArea );
1602 
1603  if( item->Type() == PCB_MODULE_T && areaRatio < textToFootprintMinRatio &&
1604  itemCommonRatio < commonAreaRatio )
1605  rejected.insert( item );
1606 
1607  switch( item->Type() )
1608  {
1609  case PCB_TRACE_T:
1610  case PCB_PAD_T:
1611  case PCB_LINE_T:
1612  case PCB_VIA_T:
1613  case PCB_MODULE_T:
1614  if( areaRatio > textToFeatureMinRatio && txtCommonRatio < commonAreaRatio )
1615  rejected.insert( txt );
1616  break;
1617  default:
1618  break;
1619  }
1620  }
1621  }
1622  }
1623  }
1624 
1625  if( aCollector.CountType( PCB_MODULE_T ) > 0 )
1626  {
1627  double minArea = calcMinArea( aCollector, PCB_MODULE_T );
1628  double maxArea = calcMaxArea( aCollector, PCB_MODULE_T );
1629 
1630  if( calcRatio( minArea, maxArea ) <= footprintAreaRatio )
1631  {
1632  for( int i = 0; i < aCollector.GetCount(); ++i )
1633  {
1634  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[i] ) )
1635  {
1636  double normalizedArea = calcRatio( calcArea( mod ), maxArea );
1637 
1638  if( normalizedArea > footprintAreaRatio )
1639  rejected.insert( mod );
1640  }
1641  }
1642  }
1643  }
1644 
1645  if( aCollector.CountType( PCB_PAD_T ) > 0 )
1646  {
1647  for( int i = 0; i < aCollector.GetCount(); ++i )
1648  {
1649  if( D_PAD* pad = dyn_cast<D_PAD*>( aCollector[i] ) )
1650  {
1651  double ratio = pad->GetParent()->PadCoverageRatio();
1652 
1653  if( ratio < modulePadMinCoverRatio )
1654  rejected.insert( pad->GetParent() );
1655  }
1656  }
1657  }
1658 
1659  if( aCollector.CountType( PCB_VIA_T ) > 0 )
1660  {
1661  for( int i = 0; i < aCollector.GetCount(); ++i )
1662  {
1663  if( VIA* via = dyn_cast<VIA*>( aCollector[i] ) )
1664  {
1665  double viaArea = calcArea( via );
1666 
1667  for( int j = 0; j < aCollector.GetCount(); ++j )
1668  {
1669  if( i == j )
1670  continue;
1671 
1672  BOARD_ITEM* item = aCollector[j];
1673  double areaRatio = calcRatio( viaArea, calcArea( item ) );
1674 
1675  if( item->Type() == PCB_MODULE_T && areaRatio < modulePadMinCoverRatio )
1676  rejected.insert( item );
1677 
1678  if( item->Type() == PCB_PAD_T && areaRatio < padViaAreaRatio )
1679  rejected.insert( item );
1680 
1681  if( TRACK* track = dyn_cast<TRACK*>( item ) )
1682  {
1683  if( track->GetNetCode() != via->GetNetCode() )
1684  continue;
1685 
1686  double lenRatio = (double) ( track->GetLength() + track->GetWidth() ) /
1687  (double) via->GetWidth();
1688 
1689  if( lenRatio > trackViaLengthRatio )
1690  rejected.insert( track );
1691  }
1692  }
1693  }
1694  }
1695  }
1696 
1697  int nTracks = aCollector.CountType( PCB_TRACE_T );
1698 
1699  if( nTracks > 0 )
1700  {
1701  double maxLength = 0.0;
1702  double minLength = std::numeric_limits<double>::max();
1703  double maxArea = 0.0;
1704  const TRACK* maxTrack = nullptr;
1705 
1706  for( int i = 0; i < aCollector.GetCount(); ++i )
1707  {
1708  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
1709  {
1710  maxLength = std::max( track->GetLength(), maxLength );
1711  maxLength = std::max( (double) track->GetWidth(), maxLength );
1712 
1713  minLength = std::min( std::max( track->GetLength(), (double) track->GetWidth() ), minLength );
1714 
1715  double area = track->GetLength() * track->GetWidth();
1716 
1717  if( area > maxArea )
1718  {
1719  maxArea = area;
1720  maxTrack = track;
1721  }
1722  }
1723  }
1724 
1725  if( maxLength > 0.0 && minLength / maxLength < trackTrackLengthRatio && nTracks > 1 )
1726  {
1727  for( int i = 0; i < aCollector.GetCount(); ++i )
1728  {
1729  if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
1730  {
1731  double ratio = std::max( (double) track->GetWidth(), track->GetLength() ) / maxLength;
1732 
1733  if( ratio > trackTrackLengthRatio )
1734  rejected.insert( track );
1735  }
1736  }
1737  }
1738 
1739  for( int j = 0; j < aCollector.GetCount(); ++j )
1740  {
1741  if( MODULE* mod = dyn_cast<MODULE*>( aCollector[j] ) )
1742  {
1743  double ratio = calcRatio( maxArea, mod->GetFootprintRect().GetArea() );
1744 
1745  if( ratio < modulePadMinCoverRatio && calcCommonArea( maxTrack, mod ) < commonAreaRatio )
1746  rejected.insert( mod );
1747  }
1748  }
1749  }
1750 
1751  if( (unsigned) aCollector.GetCount() > rejected.size() ) // do not remove everything
1752  {
1753  for( BOARD_ITEM* item : rejected )
1754  {
1755  aCollector.Remove( item );
1756  }
1757  }
1758 }
1759 
1760 
1762 {
1763  std::set<BOARD_ITEM*> rejected;
1764  std::set<BOARD_ITEM*> added;
1765 
1766  if( !m_editModules )
1767  {
1768  for( auto i : m_selection )
1769  {
1770  auto item = static_cast<BOARD_ITEM*>( i );
1771  if( item->Type() == PCB_PAD_T )
1772  {
1773  MODULE* mod = static_cast<MODULE*>( item->GetParent() );
1774 
1775  // case 1: module (or its pads) are locked
1776  if( mod && ( mod->PadsLocked() || mod->IsLocked() ) )
1777  {
1778  rejected.insert( item );
1779 
1780  if( !mod->IsLocked() && !mod->IsSelected() )
1781  added.insert( mod );
1782  }
1783 
1784  // case 2: multi-item selection contains both the module and its pads - remove the pads
1785  if( mod && m_selection.Contains( mod ) )
1786  rejected.insert( item );
1787  }
1788  }
1789  }
1790 
1791  if( !rejected.empty() )
1792  {
1793  for( BOARD_ITEM* item : rejected )
1794  unselect( item );
1795 
1796  // Inform other potentially interested tools
1798  }
1799 
1800  if( !added.empty() )
1801  {
1802  for( BOARD_ITEM* item : added )
1803  select( item );
1804 
1805  // Inform other potentially interested tools
1807  }
1808 
1809  return true;
1810 }
1811 
1812 
1813 // TODO(JE) Only works for BOARD_ITEM
1815 {
1816  VECTOR2I centre;
1817 
1818  if( Size() == 1 )
1819  {
1820  centre = static_cast<BOARD_ITEM*>( Front() )->GetCenter();
1821  }
1822  else
1823  {
1824  EDA_RECT bbox = Front()->GetBoundingBox();
1825  auto i = m_items.begin();
1826  ++i;
1827 
1828  for( ; i != m_items.end(); ++i )
1829  {
1830  bbox.Merge( (*i)->GetBoundingBox() );
1831  }
1832 
1833  centre = bbox.Centre();
1834  }
1835 
1836  return centre;
1837 }
1838 
1840 {
1841  EDA_RECT eda_bbox;
1842 
1843  if( Size() == 1 )
1844  {
1845  eda_bbox = Front()->GetBoundingBox();
1846  }
1847  else if( Size() > 1 )
1848  {
1849  eda_bbox = Front()->GetBoundingBox();
1850  auto i = m_items.begin();
1851  ++i;
1852 
1853  for( ; i != m_items.end(); ++i )
1854  {
1855  eda_bbox.Merge( (*i)->GetBoundingBox() );
1856  }
1857  }
1858 
1859  return BOX2I( eda_bbox.GetOrigin(), eda_bbox.GetSize() );
1860 }
1861 
1863 {
1864  std::vector<VIEW_ITEM*> items;
1865 
1866  for( auto item : m_items )
1867  {
1868  items.push_back( item );
1869 
1870  if( item->Type() == PCB_MODULE_T )
1871  {
1872  MODULE* module = static_cast<MODULE*>( item );
1873  module->RunOnChildren( [&] ( BOARD_ITEM* bitem ) { items.push_back( bitem ); } );
1874  }
1875  }
1876 
1877  return items;
1878 }
1879 
1880 
1881 const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
1882 const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
1883 const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
void Empty()
Function Empty sets the list to empty.
show modules on front
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)
Function Hide() Temporarily hides the item in the view (e.g.
Definition: view.cpp:1351
int GetCount() const
Function GetCount returns the number of objects in the list.
int UnselectItem(const TOOL_EVENT &aEvent)
Item unselection event handler.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
int Main(const TOOL_EVENT &aEvent)
Function Main()
BOARD_ITEM_CONTAINER * GetParent() const
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:106
KIGFX::VIEW * view() const
Definition: pcb_tool.h:108
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
BOX2< VECTOR2I > BOX2I
Definition: box2.h:468
void RunOnChildren(std::function< void(BOARD_ITEM *)> aFunction)
Function RunOnChildren.
bool GetHighContrast() const
Function GetHighContrast Returns information about high contrast display mode.
Definition: painter.h:160
static DIALOG_BLOCK_OPTIONS::OPTIONS blockOpts
void SetEnd(VECTOR2I aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
void zoomFitSelection(void)
Zooms the screen to center and fit the current selection.
static EDA_RECT getRect(const BOARD_ITEM *aItem)
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:81
void ForceRefresh()
Function ForceRefresh() Forces a redraw.
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:512
static double calcCommonArea(const BOARD_ITEM *aItem, const BOARD_ITEM *aOther)
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
static const KICAD_T AllBoardItems[]
A scan list for all editable board items, like PcbGeneralLocateAndDisplay()
Definition: collectors.h:241
virtual LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
TEXTE_PCB class definition.
SELECTION & RequestSelection(int aFlags=SELECTION_DEFAULT)
Function RequestSelection()
bool IsBrightened() const
Definition: base_struct.h:224
std::unique_ptr< PRIV > m_priv
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:416
Model changes (required full reload)
Definition: tool_base.h:83
Class RN_DATA.
int selectSameSheet(const TOOL_EVENT &aEvent)
Selects all modules belonging to same hierarchical sheet as the selected footprint.
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:231
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)
Function Collect scans a BOARD_ITEM using this class's Inspector method, which does the collection...
Definition: collectors.cpp:447
Classes BOARD_ITEM and BOARD_CONNECTED_ITEM.
virtual const VIEW_GROUP::ITEMS updateDrawList() const override
void guessSelectionCandidates(GENERAL_COLLECTOR &aCollector) const
Function guessSelectionCandidates() Tries to guess best selection candidates in case multiple items a...
bool selectCursor(bool aSelectAlways=false)
Function selectCursor() Selects an item under the cursor unless there is something already selected o...
Class SELECTION_TOOL.
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:100
Class BOARD to handle a board.
void EnableWarp(bool aEnabled)
Definition: dialog_find.cpp:67
const wxPoint & GetPosition() const override
Definition: class_module.h:143
SELECTION_LOCK_FLAGS CheckLock()
Checks if the user has agreed to modify locked items for the given selection.
static TOOL_ACTION unselectItem
Unselects an item (specified as the event parameter).
Definition: pcb_actions.h:59
Class that computes missing connections on a PCB.
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:139
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:49
the 3d code uses this value
Definition: typeinfo.h:92
static TOOL_ACTION selectNet
Selects all connections belonging to a single net.
Definition: pcb_actions.h:68
EDA_ITEM * Front() const
Definition: selection.h:137
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
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:439
int find(const TOOL_EVENT &aEvent)
Find an item.
MODULE * Next() const
Definition: class_module.h:99
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:114
int findMove(const TOOL_EVENT &aEvent)
Find an item and start moving.
void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:340
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:96
EDA_RECT Common(const EDA_RECT &aRect) const
Function Common returns the area that is common with another rectangle.
void AddSubMenu(std::shared_ptr< CONTEXT_MENU > aSubMenu)
Function CreateSubMenu.
Definition: tool_menu.cpp:55
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
void SetBrightened()
Definition: base_struct.h:229
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
int GetHeight() const
bool IsSelected() const
Definition: base_struct.h:221
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
static TOOL_ACTION selectConnection
Selects a connection between junctions.
Definition: pcb_actions.h:62
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
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
void unselectVisually(BOARD_ITEM *aItem)
Function unselectVisually() Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
static const TOOL_EVENT ClearedEvent
Event sent after selection is cleared.
Layers have changed.
Definition: view_item.h:59
LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int CountType(KICAD_T aType)
Function CountType counts the number of items matching aType.
static double calcArea(const BOARD_ITEM *aItem)
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:247
virtual wxString GetSelectMenuText() const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
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:106
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
bool InvokeTool(TOOL_ID aToolId)
Function InvokeTool() Calls a tool by sending a tool activation event to tool of given ID...
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:107
Pcbnew hotkeys.
void SetIsHover(bool aIsHover)
Definition: selection.h:61
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 to find the smallest (in terms of bounding box area) item fro...
Private implementation of firewalled private data.
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:71
void ClearBrightened()
Definition: base_struct.h:233
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
virtual bool IsOnLayer(LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
void findCallback(BOARD_ITEM *aItem)
Find dialog callback.
const wxPoint & GetOrigin() const
const std::set< EDA_ITEM * > GetItems() const
Definition: selection.h:117
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
bool PadsLocked() const
Definition: class_module.h:259
Struct that will be set with the result of the user choices in the dialog.
class MODULE, a footprint
Definition: typeinfo.h:101
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
const BOX2I ViewBBox() const override
Function ViewBBox() Returns the bounding box for all stored items covering all its layers...
double GetArea() const
Function GetArea returns the area of the rectangle.
void AddStandardSubMenus(EDA_DRAW_FRAME &aFrame)
Function CreateBasicMenu.
Definition: tool_menu.cpp:95
GENERAL_COLLECTORS_GUIDE GetCollectorsGuide()
Function GetCollectorsGuide.
Class LSET is a set of LAYER_IDs.
bool selectable(const BOARD_ITEM *aItem) const
Function selectable() Checks conditions for an item to be selected.
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:563
static double calcMaxArea(GENERAL_COLLECTOR &aCollector, KICAD_T aType)
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589
void selectAllItemsOnSheet(wxString &aSheetpath)
Selects all items with the given sheet timestamp name (the sheet path)
void SetSelected()
Definition: base_struct.h:227
static TOOL_ACTION find
Find an item.
Definition: pcb_actions.h:351
void SetItem(EDA_ITEM *aItem)
Definition: bright_box.cpp:61
int ClearSelection(const TOOL_EVENT &aEvent)
Clear current selection event handler.
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:575
bool selectMultiple()
Function selectMultiple() Handles drawing a selection box that allows to select many items at the sam...
void selectAllItemsOnNet(int aNetCode)
Selects all items with the given net code.
int selectOnSheetFromEeschema(const TOOL_EVENT &aEvent)
Selects all modules belonging to same sheet, from Eeschema, using crossprobing
SELECTION_LOCK_FLAGS
Definition: selection.h:177
Class TOOL_EVENT.
Definition: tool_event.h:162
static const int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:640
void GetNetItems(int aNetCode, std::list< BOARD_CONNECTED_ITEM * > &aOutput, RN_ITEM_TYPE aTypes=RN_ALL) const
Function GetNetItems() Adds all items that belong to a certain net to a list.
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
BOARD_ITEM * disambiguationMenu(GENERAL_COLLECTOR *aItems)
Function disambiguationMenu() Handles the menu that allows to select one of many items in case there ...
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
D_PAD * Next() const
Definition: class_pad.h:106
SELECTION m_selection
Current state of selection.
SELECTION & GetSelection()
Function GetSelection()
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.
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.
RN_ITEM_TYPE
Types of items that are handled by the class
Definition: ratsnest_data.h:53
wxPoint Centre() const
TRACK * MarkTrace(TRACK *aTrace, int *aCount, double *aTraceLength, double *aInPackageLength, bool aReorder)
Function MarkTrace marks a chain of trace segments, connected to aTrace.
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:196
void selectVisually(BOARD_ITEM *aItem)
Function selectVisually() Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
static TOOL_ACTION selectCopper
Selects whole copper connection.
Definition: pcb_actions.h:65
All active tools
Definition: tool_event.h:138
Class PCB_TOOL.
Definition: pcb_tool.h:45
int SelectItem(const TOOL_EVENT &aEvent)
Item selection event handler.
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:112
TOOL_SETTINGS & GetSettings()
Definition: tool_base.cpp:72
void Update(VIEW_ITEM *aItem)
Function Update() For dynamic VIEWs, informs the associated VIEW that the graphical representation of...
Definition: view.cpp:1378
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:223
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:36
bool selectPoint(const VECTOR2I &aWhere, bool aOnDrag=false)
Function selectPoint() Selects an item pointed by the parameter aWhere.
static const TOOL_EVENT SelectedEvent
Event sent after an item is selected.
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:113
bool m_editModules
Definition: pcb_tool.h:112
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:30
virtual unsigned int GetSize() const override
Function GetSize() Returns the number of stored items.
Definition: selection.h:86
std::vector< VIEW_ITEM * > ITEMS
Definition: view_group.h:45
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
bool IsLayerVisible(LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:440
static TOOL_ACTION filterSelection
Filters the items in the current selection (invokes dialog)
Definition: pcb_actions.h:77
void SetCallback(boost::function< void(BOARD_ITEM *)> aCallback)
Definition: dialog_find.h:39
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
Class PCB_BRIGHT_BOX.
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:266
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:373
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:111
const int scale
TRACK * Next() const
Definition: class_track.h:97
void CloseContextMenu(OPT_TOOL_EVENT &evt)
Function CloseContextMenu.
Definition: tool_menu.cpp:82
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:342
void AddMenu(CONTEXT_MENU *aMenu, bool aExpand=false, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddMenu()
int GetPrimaryCount()
Function GetPrimaryCount.
Definition: collectors.h:344
Class to handle a graphic segment.
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:71
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
LAYER_ID
Enum LAYER_ID is the set of PCB layers.
std::set< EDA_ITEM * > m_items
Set of selected items.
Definition: selection.h:168
DLIST< MODULE > m_Modules
Definition: class_board.h:243
int GetWidth() const
Definition: class_track.h:114
static const KICAD_T ModuleItems[]
A scan list for primary module items.
Definition: collectors.h:288
bool IsElementVisible(int aPCB_VISIBLE) const
Function IsElementVisible tests whether a given element category is visible.
Class GENERAL_COLLECTOR is intended for use when the right click button is pressed, or when the plain "arrow" tool is in effect.
Definition: collectors.h:211
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the context menu.
Class TOOL_ACTION.
Definition: tool_action.h:46
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 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.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
int GetWidth() const
bool selectionContains(const VECTOR2I &aPoint) const
Function selectionContains() Checks if the given point is placed within any of selected items' boundi...
double calcRatio(double a, double b)
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
double GetScale() const
Function GetScale()
Definition: view.h:265
double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: class_track.h:170
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Function SetVisible() Sets the item visibility.
Definition: view.cpp:1330
Class SELECTION_AREA.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Function GetGalCanvas returns a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:803
bool m_locked
Can other tools modify locked items.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
void SetTransitions() override
Sets up handlers for various events.
int Size() const
Returns the number of selected parts.
Definition: selection.h:112
MODULE * GetFootprintFromBoardByReference()
Function GetFootprintFromBoardByReference.
Definition: modules.cpp:60
void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:310
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:354
Module description (excepted pads)
void ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
Class VIEW.
Definition: view.h:58
void GetConnectedItems(const BOARD_CONNECTED_ITEM *aItem, std::list< BOARD_CONNECTED_ITEM * > &aOutput, RN_ITEM_TYPE aTypes=RN_ALL) const
Function GetConnectedItems() Adds items that are connected together to a list.
Class GENERAL_COLLECTORS_GUIDE is a general implementation of a COLLECTORS_GUIDE. ...
Definition: collectors.h:378
bool IsVisible(const VIEW_ITEM *aItem) const
Function IsVisible() Returns information if the item is visible (or not).
Definition: view.cpp:1370
bool SanitizeSelection()
Makes sure a group selection does not contain items that would cause conflicts when moving/rotating t...
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
virtual const BOX2I ViewBBox() const override
VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
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:139
const wxSize & GetSize() const
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:111
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:62
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.
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
static bool itemIsIncludedByFilter(const BOARD_ITEM &aItem, const BOARD &aBoard, const LSET &aTechnlLayerMask, const DIALOG_BLOCK_OPTIONS::OPTIONS &aBlockOpts)
Function itemIsIncludedByFilter()
static LSET getFilteredLayerSet(const DIALOG_BLOCK_OPTIONS::OPTIONS &blockOpts)
Gets the technical layers that are part of the given selection opts.
void update() override
Update menu state stub.
DIALOG_BLOCK_OPTIONS::OPTIONS m_filterOpts
#define min(a, b)
Definition: auxiliary.h:85
Color has changed.
Definition: view_item.h:57
static TOOL_ACTION selectSameSheet
Selects all components on the same sheet as the selected footprint.
Definition: pcb_actions.h:74
BOARD * board() const
Definition: pcb_tool.h:110
static double calcMinArea(GENERAL_COLLECTOR &aCollector, KICAD_T aType)
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:76