KiCad PCB EDA Suite
pcb_inspection_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) 2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 #include <tool/tool_manager.h>
26 #include <tools/selection_tool.h>
28 #include <tools/edit_tool.h>
29 #include <painter.h>
31 #include <profile.h>
32 #include "pcb_inspection_tool.h"
33 
34 
36  PCB_TOOL_BASE( "pcbnew.InspectionTool" ),
37  m_frame( nullptr )
38 {
39  m_probingSchToPcb = false;
40  m_lastNetcode = -1;
41 
42  m_slowRatsnest = false;
43 }
44 
45 
47 {
48  m_ratsnestTimer.SetOwner( this );
49  Connect( m_ratsnestTimer.GetId(), wxEVT_TIMER, wxTimerEventHandler( PCB_INSPECTION_TOOL::ratsnestTimer ), NULL, this );
50 
51  return true;
52 }
53 
54 
56 {
57  m_frame = getEditFrame<PCB_EDIT_FRAME>();
58 }
59 
60 
62 {
64  dialog.ShowModal();
65  return 0;
66 }
67 
68 
70 {
71  // Don't get in an infinite loop PCB -> SCH -> PCB -> SCH -> ...
72  if( m_probingSchToPcb )
73  return 0;
74 
76  const PCBNEW_SELECTION& selection = selTool->GetSelection();
77 
78  if( selection.Size() == 1 )
79  m_frame->SendMessageToEESCHEMA( static_cast<BOARD_ITEM*>( selection.Front() ) );
80  else
81  m_frame->SendMessageToEESCHEMA( nullptr );
82 
83  return 0;
84 }
85 
86 
88 {
89  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
90 
91  m_probingSchToPcb = true; // recursion guard
92  {
94 
95  if( item )
96  m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, (void*) item );
97  }
98  m_probingSchToPcb = false;
99 
100  return 0;
101 }
102 
103 
111  bool PCB_INSPECTION_TOOL::highlightNet( const VECTOR2D& aPosition, bool aUseSelection )
112 {
113  BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
115 
116  int net = -1;
117  bool enableHighlight = false;
118 
119  if( aUseSelection )
120  {
121  SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
122 
123  const PCBNEW_SELECTION& selection = selectionTool->GetSelection();
124 
125  for( auto item : selection )
126  {
127  if( BOARD_CONNECTED_ITEM::ClassOf( item ) )
128  {
129  auto ci = static_cast<BOARD_CONNECTED_ITEM*>( item );
130 
131  int item_net = ci->GetNetCode();
132 
133  if( net < 0 )
134  net = item_net;
135  else if( net != item_net ) // more than one net selected: do nothing
136  return false;
137  }
138  }
139 
140  enableHighlight = ( net >= 0 && net != settings->GetHighlightNetCode() );
141  }
142 
143  // If we didn't get a net to highlight from the selection, use the cursor
144  if( net < 0 )
145  {
146  auto guide = m_frame->GetCollectorsGuide();
147  GENERAL_COLLECTOR collector;
148 
149  // Find a connected item for which we are going to highlight a net
150  collector.Collect( board, GENERAL_COLLECTOR::PadsOrTracks, (wxPoint) aPosition, guide );
151 
152  if( collector.GetCount() == 0 )
153  collector.Collect( board, GENERAL_COLLECTOR::Zones, (wxPoint) aPosition, guide );
154 
155  // Clear the previous highlight
156  m_frame->SendMessageToEESCHEMA( nullptr );
157 
158  for( int i = 0; i < collector.GetCount(); i++ )
159  {
160  if( ( collector[i]->GetLayerSet() & LSET::AllCuMask() ).none() )
161  collector.Remove( i );
162 
163  if( collector[i]->Type() == PCB_PAD_T )
164  {
165  m_frame->SendMessageToEESCHEMA( static_cast<BOARD_CONNECTED_ITEM*>( collector[i] ) );
166  break;
167  }
168  }
169 
170  enableHighlight = ( collector.GetCount() > 0 );
171 
172  // Obtain net code for the clicked item
173  if( enableHighlight )
174  net = static_cast<BOARD_CONNECTED_ITEM*>( collector[0] )->GetNetCode();
175  }
176 
177  // Toggle highlight when the same net was picked
178  if( net > 0 && net == settings->GetHighlightNetCode() )
179  enableHighlight = !settings->IsHighlightEnabled();
180 
181  if( enableHighlight != settings->IsHighlightEnabled()
182  || net != settings->GetHighlightNetCode() )
183  {
184  m_lastNetcode = settings->GetHighlightNetCode();
185  settings->SetHighlight( enableHighlight, net );
187  }
188 
189  // Store the highlighted netcode in the current board (for dialogs for instance)
190  if( enableHighlight && net >= 0 )
191  {
192  board->SetHighLightNet( net );
193 
194  NETINFO_ITEM* netinfo = board->FindNet( net );
195 
196  if( netinfo )
197  {
198  MSG_PANEL_ITEMS items;
199  netinfo->GetMsgPanelInfo( m_frame->GetUserUnits(), items );
200  m_frame->SetMsgPanel( items );
202  }
203  }
204  else
205  {
209  }
210 
211  return true;
212 }
213 
214 
216 {
217  int netcode = aEvent.Parameter<intptr_t>();
219 
220  if( netcode > 0 )
221  {
222  m_lastNetcode = settings->GetHighlightNetCode();
223  settings->SetHighlight( true, netcode );
225  }
226  else if( aEvent.IsAction( &PCB_ACTIONS::toggleLastNetHighlight ) )
227  {
228  int temp = settings->GetHighlightNetCode();
229  settings->SetHighlight( true, m_lastNetcode );
231  m_lastNetcode = temp;
232  }
233  else // Highlight the net belonging to the item under the cursor
234  {
235  highlightNet( getViewControls()->GetMousePosition(), false );
236  }
237 
238  return 0;
239 }
240 
241 
243 {
244  BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
246 
248  settings->SetHighlight( false );
252  return 0;
253 }
254 
255 
257 {
258  std::string tool = aEvent.GetCommandStr().get();
260 
261  // Deactivate other tools; particularly important if another PICKER is currently running
262  Activate();
263 
264  // If the keyboard hotkey was triggered and we are already in the highlight tool, behave
265  // the same as a left-click. Otherwise highlight the net of the selected item(s), or if
266  // there is no selection, then behave like a ctrl-left-click.
268  {
269  bool use_selection = m_frame->IsCurrentTool( PCB_ACTIONS::highlightNetTool );
270  highlightNet( getViewControls()->GetMousePosition(), use_selection );
271  }
272 
273  picker->SetClickHandler(
274  [this] ( const VECTOR2D& pt ) -> bool
275  {
276  highlightNet( pt, false );
277  return true;
278  } );
279 
280  picker->SetLayerSet( LSET::AllCuMask() );
281 
282  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
283 
284  return 0;
285 }
286 
287 
289 {
290  std::string tool = aEvent.GetCommandStr().get();
292  BOARD* board = getModel<BOARD>();
293  auto& opt = displayOptions();
294 
295  // Deactivate other tools; particularly important if another PICKER is currently running
296  Activate();
297 
298  picker->SetClickHandler(
299  [this, board, opt]( const VECTOR2D& pt ) -> bool
300  {
301  SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
302 
305  PCBNEW_SELECTION& selection = selectionTool->GetSelection();
306 
307  if( selection.Empty() )
308  {
311  selection = selectionTool->GetSelection();
312  }
313 
314  if( selection.Empty() )
315  {
316  // Clear the previous local ratsnest if we click off all items
317  for( auto mod : board->Modules() )
318  {
319  for( auto pad : mod->Pads() )
320  pad->SetLocalRatsnestVisible( opt.m_ShowGlobalRatsnest );
321  }
322  }
323  else
324  {
325  for( auto item : selection )
326  {
327  if( auto pad = dyn_cast<D_PAD*>(item) )
328  {
329  pad->SetLocalRatsnestVisible( !pad->GetLocalRatsnestVisible() );
330  }
331  else if( auto mod = dyn_cast<MODULE*>(item) )
332  {
333  bool enable = !( *( mod->Pads().begin() ) )->GetLocalRatsnestVisible();
334 
335  for( auto modpad : mod->Pads() )
336  modpad->SetLocalRatsnestVisible( enable );
337  }
338  }
339  }
340 
342 
343  return true;
344  } );
345 
346  picker->SetFinalizeHandler(
347  [board, opt] ( int aCondition )
348  {
349  if( aCondition != PCBNEW_PICKER_TOOL::END_ACTIVATE )
350  {
351  for( auto mod : board->Modules() )
352  {
353  for( auto pad : mod->Pads() )
354  pad->SetLocalRatsnestVisible( opt.m_ShowGlobalRatsnest );
355  }
356  }
357  } );
358 
359  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
360 
361  return 0;
362 }
363 
364 
366 {
367  auto selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
368  auto& selection = selectionTool->GetSelection();
369  auto connectivity = getModel<BOARD>()->GetConnectivity();
370 
371  if( selection.Empty() )
372  {
373  connectivity->ClearDynamicRatsnest();
374  }
375  else if( m_slowRatsnest )
376  {
377  // Compute ratsnest only when user stops dragging for a moment
378  connectivity->HideDynamicRatsnest();
379  m_ratsnestTimer.Start( 20 );
380  }
381  else
382  {
383  // Check how much time doest it take to calculate ratsnest
384  PROF_COUNTER counter;
386  counter.Stop();
387 
388  // If it is too slow, then switch to 'slow ratsnest' mode when
389  // ratsnest is calculated when user stops dragging items for a moment
390  if( counter.msecs() > 25 )
391  {
392  m_slowRatsnest = true;
393  connectivity->HideDynamicRatsnest();
394  }
395  }
396 
397  return 0;
398 }
399 
400 
402 {
403  getModel<BOARD>()->GetConnectivity()->HideDynamicRatsnest();
404  m_slowRatsnest = false;
405  return 0;
406 }
407 
408 
409 void PCB_INSPECTION_TOOL::ratsnestTimer( wxTimerEvent& aEvent )
410 {
411  m_ratsnestTimer.Stop();
414  m_frame->GetCanvas()->Refresh();
415 }
416 
417 
419 {
420  SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
421  SELECTION& selection = selectionTool->GetSelection();
422  std::shared_ptr<CONNECTIVITY_DATA> connectivity = board()->GetConnectivity();
423  std::vector<BOARD_ITEM*> items;
424 
425  for( EDA_ITEM* item : selection )
426  {
427  BOARD_CONNECTED_ITEM* boardItem = static_cast<BOARD_CONNECTED_ITEM*>( item );
428 
429  if( boardItem->Type() == PCB_MODULE_T )
430  {
431  for( auto pad : static_cast<MODULE*>( item )->Pads() )
432  {
433  if( pad->GetLocalRatsnestVisible() || displayOptions().m_ShowModuleRatsnest )
434  items.push_back( pad );
435  }
436  }
437  else if( boardItem->GetLocalRatsnestVisible() || displayOptions().m_ShowModuleRatsnest )
438  {
439  items.push_back( boardItem );
440  }
441  }
442 
443  connectivity->ComputeDynamicRatsnest( items );
444 }
445 
446 
448 {
452 
456 
459 
467 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:73
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
void Stop()
save the time when this function was called, and set the counter stane to stop
Definition: profile.h:82
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
int UpdateSelectionRatsnest(const TOOL_EVENT &aEvent)
Updates ratsnest for selected items.
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:250
static const TOOL_EVENT SelectedEvent
Definition: actions.h:197
void SendCrossProbeNetName(const wxString &aNetName)
Sends a net name to eeschema for highlighting.
BOARD * board() const
int HighlightNet(const TOOL_EVENT &aEvent)
Highlights net belonging to the item under the cursor.
Class RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output ...
Definition: painter.h:56
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:198
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
double msecs(bool aSinceLast=false)
Definition: profile.h:143
static TOOL_ACTION highlightItem
Definition: pcb_actions.h:413
void Collect(BOARD_ITEM *aItem, const KICAD_T aScanList[], const wxPoint &aRefPos, const COLLECTORS_GUIDE &aGuide)
Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:479
static TOOL_ACTION boardStatistics
Definition: pcb_actions.h:417
Class SELECTION_TOOL.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
int HighlightNetTool(const TOOL_EVENT &aEvent)
Launches a tool to pick the item whose net is going to be highlighted.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:109
bool GetLocalRatsnestVisible() const
int CrossProbePcbToSch(const TOOL_EVENT &aEvent)
Notifies eeschema about the selected item.
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
static const KICAD_T PadsOrTracks[]
A scan list for PADs, TRACKs, or VIAs.
Definition: collectors.h:298
bool highlightNet(const VECTOR2D &aPosition, bool aUseSelection)
Look for a BOARD_CONNECTED_ITEM in a given spot and if one is found - it enables highlight for its ne...
static TOOL_ACTION localRatsnestTool
Definition: pcb_actions.h:420
static TOOL_ACTION toggleLastNetHighlight
Definition: pcb_actions.h:410
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:44
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
EDA_ITEM * GetModel() const
Definition: tool_manager.h:263
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Function SetFinalizeHandler() Sets a handler for the finalize event.
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:142
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
void RedrawRatsnest()
Forces refresh of the ratsnest visual representation
int ShowStatisticsDialog(const TOOL_EVENT &aEvent)
Function ShowStatisticDialog()
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:67
PCBNEW_SELECTION & GetSelection()
Function GetSelection()
static TOOL_ACTION pickerTool
Definition: actions.h:145
static TOOL_ACTION highlightNetTool
Definition: pcb_actions.h:411
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:113
class MODULE, a footprint
Definition: typeinfo.h:89
PCB_EDIT_FRAME * m_frame
GENERAL_COLLECTORS_GUIDE GetCollectorsGuide()
Function GetCollectorsGuide.
Generic tool for picking a point.
void ResetNetHighLight()
Function ResetNetHighLight Reset all high light data to the init state.
Definition: class_board.h:367
const PCBNEW_SELECTION & selection() const
MODULES & Modules()
Definition: class_board.h:227
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:585
int HighlightItem(const TOOL_EVENT &aEvent)
Performs the appropriate action in response to an eeschema cross-probe.
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
Class TOOL_EVENT.
Definition: tool_event.h:171
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:301
static const KICAD_T Zones[]
A scan list for zones outlines only.
Definition: collectors.h:277
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:233
Items that may change while the view stays the same (noncached)
Definition: definitions.h:50
static const TOOL_EVENT ClearedEvent
Definition: actions.h:199
static TOOL_ACTION hideDynamicRatsnest
Definition: pcb_actions.h:421
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:36
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
static bool ClassOf(const EDA_ITEM *aItem)
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:119
const PCB_DISPLAY_OPTIONS & displayOptions() const
static TOOL_ACTION clearHighlight
Definition: pcb_actions.h:408
int HideDynamicRatsnest(const TOOL_EVENT &aEvent)
Hides ratsnest for selected items. Called when there are no items selected.
static void PadFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
Function PadFilter() A selection filter which prunes the selection to contain only items of type PCB_...
Definition: edit_tool.cpp:1093
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
void SetHighLightNet(int aNetCode)
Function SetHighLightNet.
Definition: class_board.h:383
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:463
void SendMessageToEESCHEMA(BOARD_ITEM *objectToSync)
Function SendMessageToEESCHEMA sends a message to the schematic editor so that it may move its cursor...
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
void calculateSelectionRatsnest()
Recalculates dynamic ratsnest for the current selection
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:409
static TOOL_ACTION highlightNetSelection
Definition: pcb_actions.h:412
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
void setTransitions() override
Bind handlers to corresponding TOOL_ACTIONs
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:161
void SetLayerSet(LSET aLayerSet)
Function SetLayerSet() Sets the tool's snap layer set.
int LocalRatsnestTool(const TOOL_EVENT &aEvent)
Shows local ratsnest of a component
static TOOL_ACTION listNets
Definition: pcb_actions.h:326
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
Class DIALOG_BOARD_STATISTIC.
size_t i
Definition: json11.cpp:649
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
Definition: pcb_actions.h:76
int Size() const
Returns the number of selected parts.
Definition: selection.h:125
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
int ListNets(const TOOL_EVENT &aEvent)
void Activate()
Function Activate() Runs the tool.
void GetMsgPanelInfo(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo returns the information about the NETINFO_ITEM in aList to display in the me...
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:422
static void FootprintFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector)
Function FootprintFilter() A selection filter which prunes the selection to contain only items of typ...
Definition: edit_tool.cpp:1105
int ClearHighlight(const TOOL_EVENT &aEvent)
Clears all board highlights
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
void UpdateAllLayersColor()
Function UpdateAllLayersColor() Applies the new coloring scheme to all layers.
Definition: view.cpp:798
bool IsCurrentTool(const TOOL_ACTION &aAction) const
#define mod(a, n)
Definition: greymap.cpp:24
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:70
EDA_ITEM * Front() const
Definition: selection.h:182
KICAD_T Type() const
Function Type()
Definition: base_struct.h:210
void SetClickHandler(CLICK_HANDLER aHandler)
Function SetClickHandler() Sets a handler for mouse click event.
void ratsnestTimer(wxTimerEvent &aEvent)
Event handler to recalculate dynamic ratsnest