KiCad PCB EDA Suite
board_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-2020 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 #include <bitmaps.h>
25 #include <pcb_group.h>
26 #include <tool/tool_manager.h>
28 #include <tools/pcb_picker_tool.h>
29 #include <tools/edit_tool.h>
30 #include <pcb_painter.h>
32 #include <profile.h>
34 #include <drc/drc_engine.h>
37 #include <kicad_string.h>
38 #include "board_inspection_tool.h"
40 
41 
42 void DIALOG_INSPECTION_REPORTER::OnErrorLinkClicked( wxHtmlLinkEvent& event )
43 {
44  if( event.GetLinkInfo().GetHref() == "boardsetup" )
45  m_frame->ShowBoardSetupDialog( _( "Rules" ) );
46  else if( event.GetLinkInfo().GetHref() == "drc" )
48 }
49 
50 
52  PCB_TOOL_BASE( "pcbnew.InspectionTool" ),
53  m_frame( nullptr )
54 {
55  m_probingSchToPcb = false;
56  m_lastNetcode = -1;
57  m_dynamicData = nullptr;
58 }
59 
60 
62 {
63 public:
65  {
67  SetTitle( _( "Net Tools" ) );
68 
71  // Add( PCB_ACTIONS::highlightNet );
72  }
73 
74 private:
75  ACTION_MENU* create() const override
76  {
77  return new NET_CONTEXT_MENU();
78  }
79 };
80 
81 
83 {
85 
86  auto netSubMenu = std::make_shared<NET_CONTEXT_MENU>();
87  netSubMenu->SetTool( this );
88 
89  static KICAD_T connectedTypes[] = { PCB_TRACE_T, PCB_VIA_T, PCB_ARC_T, PCB_PAD_T,
90  PCB_ZONE_T, EOT };
91 
92  CONDITIONAL_MENU& menu = selectionTool->GetToolMenu().GetMenu();
93 
94  selectionTool->GetToolMenu().AddSubMenu( netSubMenu );
95 
96  menu.AddMenu( netSubMenu.get(), SELECTION_CONDITIONS::OnlyTypes( connectedTypes ), 200 );
98 
99  return true;
100 }
101 
102 
104 {
105  m_frame = getEditFrame<PCB_EDIT_FRAME>();
106 }
107 
108 
110 {
112  dialog.ShowModal();
113  return 0;
114 }
115 
116 
118 {
119  // Null items have no description
120  if( !aItem )
121  return wxString();
122 
123  wxString s = aItem->GetSelectMenuText( m_frame->GetUserUnits() );
124 
125  if( aItem->IsConnected() )
126  {
127  BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem );
128  s += wxS( " " ) + wxString::Format( _( "[netclass %s]" ),
129  cItem->GetNetClass()->GetName() );
130  }
131 
132  return s;
133 };
134 
135 
137 {
139  wxString source;
140  ZONE_CONNECTION connection = aZone->GetPadConnection( aPad, &source );
141 
142  r->Report( "" );
143 
144  r->Report( wxString::Format( _( "Zone connection type: %s." ),
145  connectionEnum.ToString( aZone->GetPadConnection() ) ) );
146 
147  if( source != _( "zone" ) )
148  {
149  r->Report( wxString::Format( _( "Overridden by %s; connection type: %s." ),
150  source,
151  connectionEnum.ToString( connection ) ) );
152  }
153 
154  // Resolve complex connection types into simple types
155  if( connection == ZONE_CONNECTION::THT_THERMAL )
156  {
157  if( aPad->GetAttribute() == PAD_ATTRIB_PTH )
158  {
159  connection = ZONE_CONNECTION::THERMAL;
160  }
161  else
162  {
163  connection = ZONE_CONNECTION::FULL;
164  r->Report( wxString::Format( _( "Pad is not a PTH pad; connection will be: %s." ),
165  connectionEnum.ToString( ZONE_CONNECTION::FULL ) ) );
166  }
167  }
168 
169  r->Report( "" );
170 
171  // Process simple connection types
172  if( connection == ZONE_CONNECTION::THERMAL )
173  {
174  int gap = aZone->GetThermalReliefGap();
175 
176  r->Report( wxString::Format( _( "Zone thermal relief: %s." ),
177  StringFromValue( r->GetUnits(), gap, true ) ) );
178 
179  gap = aZone->GetThermalReliefGap( aPad, &source );
180 
181  if( source != _( "zone" ) )
182  {
183  r->Report( wxString::Format( _( "Overridden by %s; thermal relief: %s." ),
184  source,
185  StringFromValue( r->GetUnits(), gap, true ) ) );
186  }
187  }
188  else if( connection == ZONE_CONNECTION::NONE )
189  {
190  int clearance = aZone->GetLocalClearance();
191 
192  r->Report( wxString::Format( _( "Zone clearance: %s." ),
193  StringFromValue( r->GetUnits(), clearance, true ) ) );
194 
195  if( aZone->GetThermalReliefGap( aPad ) > clearance )
196  {
197  clearance = aZone->GetThermalReliefGap( aPad, &source );
198 
199  if( source != _( "zone" ) )
200  {
201  r->Report( wxString::Format( _( "Overridden by larger thermal relief from %s;"
202  "clearance: %s." ),
203  source,
204  StringFromValue( r->GetUnits(), clearance, true ) ) );
205  }
206  }
207  }
208  else
209  {
210  r->Report( wxString::Format( _( "Clearance: %s." ),
211  StringFromValue( r->GetUnits(), 0, true ) ) );
212  }
213 }
214 
215 
217  BOARD_ITEM* aA, BOARD_ITEM* aB, REPORTER* r )
218 {
219  r->Report( "" );
220 
222 
223  try
224  {
225  drcEngine.InitEngine( m_frame->GetDesignRulesPath() );
226  }
227  catch( PARSE_ERROR& )
228  {
229  r->Report( "" );
230  r->Report( _( "Report incomplete: could not compile custom design rules. " )
231  + "<a href='boardsetup'>" + _( "Show design rules." ) + "</a>" );
232  return;
233  }
234 
235  for( ZONE* zone : m_frame->GetBoard()->Zones() )
236  zone->CacheBoundingBox();
237 
239  {
240  for( ZONE* zone : footprint->Zones() )
241  zone->CacheBoundingBox();
242 
244  }
245 
246  auto constraint = drcEngine.EvalRules( aClearanceType, aA, aB, aLayer, r );
247  int clearance = constraint.m_Value.Min();
248 
249  wxString clearanceStr = StringFromValue( r->GetUnits(), clearance, true );
250 
251  r->Report( "" );
252  r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
253 }
254 
255 
257 {
259  const PCB_SELECTION& selection = selTool->GetSelection();
261 
262  if( selection.Size() != 2 )
263  {
264  m_frame->ShowInfoBarError( _( "Select two items for a clearance resolution report." ) );
265  return 0;
266  }
267 
268  if( m_inspectClearanceDialog == nullptr )
269  {
270  m_inspectClearanceDialog = std::make_unique<DIALOG_INSPECTION_REPORTER>( m_frame );
271  m_inspectClearanceDialog->SetTitle( _( "Clearance Report" ) );
272 
273  m_inspectClearanceDialog->Connect( wxEVT_CLOSE_WINDOW,
275  nullptr, this );
276  }
277 
279  r->SetUnits( m_frame->GetUserUnits() );
280  r->Clear();
281 
282  BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
283  BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection.GetItem( 1 ) );
284 
285  auto hasHole =
286  []( BOARD_ITEM* aItem )
287  {
288  PAD* pad = dynamic_cast<PAD*>( aItem );
289  return pad && pad->GetDrillSizeX() > 0 && pad->GetDrillSizeY() > 0;
290  };
291 
292  wxCHECK( a && b, 0 );
293 
294  if( a->Type() == PCB_GROUP_T )
295  {
296  PCB_GROUP* ag = static_cast<PCB_GROUP*>( a );
297 
298  if( ag->GetItems().empty() )
299  {
300  m_frame->ShowInfoBarError( _( "Cannot generate clearance report on empty group." ) );
301  return 0;
302  }
303 
304  a = *ag->GetItems().begin();
305  }
306 
307  if( b->Type() == PCB_GROUP_T )
308  {
309  PCB_GROUP* bg = static_cast<PCB_GROUP*>( b );
310 
311  if( bg->GetItems().empty() )
312  {
313  m_frame->ShowInfoBarError( _( "Cannot generate clearance report on empty group." ) );
314  return 0;
315  }
316 
317  b = *bg->GetItems().begin();
318  }
319 
320  if( a->Type() == PCB_TRACE_T || a->Type() == PCB_ARC_T )
321  {
322  layer = a->GetLayer();
323  }
324  else if( b->Type() == PCB_TRACE_T || b->Type() == PCB_ARC_T )
325  {
326  layer = b->GetLayer();
327  }
328  else if( a->Type() == PCB_PAD_T && static_cast<PAD*>( a )->GetAttribute() == PAD_ATTRIB_SMD )
329  {
330  PAD* pad = static_cast<PAD*>( a );
331 
332  if( pad->IsOnLayer( F_Cu ) )
333  layer = F_Cu;
334  else
335  layer = B_Cu;
336  }
337  else if( b->Type() == PCB_PAD_T && static_cast<PAD*>( a )->GetAttribute() == PAD_ATTRIB_SMD )
338  {
339  PAD* pad = static_cast<PAD*>( b );
340 
341  if( pad->IsOnLayer( F_Cu ) )
342  layer = F_Cu;
343  else
344  layer = B_Cu;
345  }
346 
347  if( a->Type() != PCB_ZONE_T && b->Type() == PCB_ZONE_T )
348  std::swap( a, b );
349  else if( !a->IsConnected() && b->IsConnected() )
350  std::swap( a, b );
351 
352  if( layer == F_SilkS || layer == B_SilkS )
353  {
354  r->Report( "<h7>" + _( "Silkscreen clearance resolution for:" ) + "</h7>" );
355 
356  r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
357  _( "Layer" ),
358  EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
360  EscapeHTML( getItemDescription( b ) ) ) );
361 
362  reportClearance( SILK_CLEARANCE_CONSTRAINT, layer, a, b, r );
363  }
364  else if( !( a->GetLayerSet() & LSET( 3, layer, Edge_Cuts, Margin ) ).any() )
365  {
366  if( hasHole( a ) )
367  {
368  r->Report( "<h7>" + _( "Hole clearance resolution for:" ) + "</h7>" );
369 
370  r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
371  _( "Layer" ),
372  EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
374  EscapeHTML( getItemDescription( b ) ) ) );
375 
376  reportClearance( HOLE_CLEARANCE_CONSTRAINT, layer, a, b, r );
377  }
378  else
379  {
380  r->Report( wxString::Format( _( "%s not present on layer %s. No clearance defined." ),
381  a->GetSelectMenuText( r->GetUnits() ),
382  m_frame->GetBoard()->GetLayerName( layer ) ) );
383  }
384  }
385  else if( !( b->GetLayerSet() & LSET( 3, layer, Edge_Cuts, Margin ) ).any() )
386  {
387  if( hasHole( b ) )
388  {
389  r->Report( "<h7>" + _( "Hole clearance resolution for:" ) + "</h7>" );
390 
391  r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
392  _( "Layer" ),
393  EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
395  EscapeHTML( getItemDescription( a ) ) ) );
396 
397  reportClearance( HOLE_CLEARANCE_CONSTRAINT, layer, b, a, r );
398  }
399  else
400  {
401  r->Report( wxString::Format( _( "%s not present on layer %s. No clearance defined." ),
402  b->GetSelectMenuText( r->GetUnits() ),
403  m_frame->GetBoard()->GetLayerName( layer ) ) );
404  }
405  }
406  else if( a->GetLayer() == Edge_Cuts || a->GetLayer() == Margin
407  || b->GetLayer() == Edge_Cuts || b->GetLayer() == Margin )
408  {
409  r->Report( "<h7>" + _( "Edge clearance resolution for:" ) + "</h7>" );
410 
411  r->Report( wxString::Format( "<ul><li>%s</li><li>%s</li></ul>",
413  EscapeHTML( getItemDescription( b ) ) ) );
414 
415  reportClearance( EDGE_CLEARANCE_CONSTRAINT, layer, a, b, r );
416  }
417  else
418  {
419  r->Report( "<h7>" + _( "Clearance resolution for:" ) + "</h7>" );
420 
421  r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
422  _( "Layer" ),
423  EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
425  EscapeHTML( getItemDescription( b ) ) ) );
426 
427  BOARD_CONNECTED_ITEM* ac = a && a->IsConnected() ?
428  static_cast<BOARD_CONNECTED_ITEM*>( a ) : nullptr;
429  BOARD_CONNECTED_ITEM* bc = b && b->IsConnected() ?
430  static_cast<BOARD_CONNECTED_ITEM*>( b ) : nullptr;
431 
432  if( ac && bc && ac->GetNetCode() > 0 && ac->GetNetCode() == bc->GetNetCode() )
433  {
434  // Same nets....
435 
436  if( ac->Type() == PCB_ZONE_T && bc->Type() == PCB_PAD_T )
437  {
438  reportZoneConnection( static_cast<ZONE*>( ac ), static_cast<PAD*>( bc ), r );
439  }
440  else
441  {
442  r->Report( "" );
443  r->Report( _( "Items belong to the same net. Clearance is 0." ) );
444  }
445  }
446  else
447  {
448  // Different nets (or one or both unconnected)....
449  reportClearance( CLEARANCE_CONSTRAINT, layer, a, b, r );
450  }
451  }
452 
453  r->Flush();
454 
455  m_inspectClearanceDialog->Raise();
456  m_inspectClearanceDialog->Show( true );
457  return 0;
458 }
459 
460 
462 {
464  const PCB_SELECTION& selection = selTool->GetSelection();
465 
466  if( selection.Size() != 1 )
467  {
468  m_frame->ShowInfoBarError( _( "Select an item for a constraints resolution report." ) );
469  return 0;
470  }
471 
472  if( m_inspectConstraintsDialog == nullptr )
473  {
474  m_inspectConstraintsDialog = std::make_unique<DIALOG_CONSTRAINTS_REPORTER>( m_frame );
475  m_inspectConstraintsDialog->SetTitle( _( "Constraints Report" ) );
476 
477  m_inspectConstraintsDialog->Connect( wxEVT_CLOSE_WINDOW,
479  nullptr, this );
480  }
481 
482  m_inspectConstraintsDialog->DeleteAllPages();
483 
484  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
486  bool courtyardError = false;
487  bool compileError = false;
488 
489  try
490  {
491  drcEngine.InitEngine( m_frame->GetDesignRulesPath() );
492  }
493  catch( PARSE_ERROR& )
494  {
495  compileError = true;
496  }
497 
498  for( ZONE* zone : m_frame->GetBoard()->Zones() )
499  zone->CacheBoundingBox();
500 
502  {
503  for( ZONE* zone : footprint->Zones() )
504  zone->CacheBoundingBox();
505 
507 
508  if( ( footprint->GetFlags() & MALFORMED_COURTYARDS ) != 0 )
509  courtyardError = true;
510  }
511 
512  WX_HTML_REPORT_BOX* r = nullptr;
513 
514  if( item->Type() == PCB_TRACE_T )
515  {
516  r = m_inspectConstraintsDialog->AddPage( _( "Track Width" ) );
517 
518  r->Report( "<h7>" + _( "Track width resolution for:" ) + "</h7>" );
519  r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
520  r->Report( "" );
521 
522  if( compileError )
523  {
524  r->Report( "" );
525  r->Report( _( "Report incomplete: could not compile custom design rules. " )
526  + "<a href='boardsetup'>" + _( "Show design rules." ) + "</a>" );
527  }
528  else
529  {
530  auto constraint = drcEngine.EvalRules( TRACK_WIDTH_CONSTRAINT, item, nullptr,
531  item->GetLayer(), r );
532 
533  wxString min = _( "undefined" );
534  wxString max = _( "undefined" );
535 
536  if( constraint.m_Value.HasMin() )
537  min = StringFromValue( r->GetUnits(), constraint.m_Value.Min(), true );
538 
539  if( constraint.m_Value.HasMax() )
540  max = StringFromValue( r->GetUnits(), constraint.m_Value.Max(), true );
541 
542  r->Report( "" );
543  r->Report( wxString::Format( _( "Width constraints: min %s max %s." ),
544  min,
545  max ) );
546  }
547 
548  r->Flush();
549  }
550 
551  if( item->Type() == PCB_VIA_T )
552  {
553  r = m_inspectConstraintsDialog->AddPage( _( "Via Diameter" ) );
554 
555  r->Report( "<h7>" + _( "Via diameter resolution for:" ) + "</h7>" );
556  r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
557  r->Report( "" );
558 
559  if( compileError )
560  {
561  r->Report( "" );
562  r->Report( _( "Report incomplete: could not compile custom design rules. " )
563  + "<a href='boardsetup'>" + _( "Show design rules." ) + "</a>" );
564  }
565  else
566  {
567  // PADSTACKS TODO: once we have padstacks we'll need to run this per-layer....
568  auto constraint = drcEngine.EvalRules( VIA_DIAMETER_CONSTRAINT, item, nullptr,
569  UNDEFINED_LAYER, r );
570 
571  wxString min = _( "undefined" );
572  wxString max = _( "undefined" );
573 
574  if( constraint.m_Value.HasMin() )
575  min = StringFromValue( r->GetUnits(), constraint.m_Value.Min(), true );
576 
577  if( constraint.m_Value.HasMax() )
578  max = StringFromValue( r->GetUnits(), constraint.m_Value.Max(), true );
579 
580  r->Report( "" );
581  r->Report( wxString::Format( _( "Diameter constraints: min %s max %s." ),
582  min,
583  max ) );
584  }
585 
586  r->Flush();
587 
588  r = m_inspectConstraintsDialog->AddPage( _( "Via Annular Width" ) );
589 
590  r->Report( "<h7>" + _( "Via annular width resolution for:" ) + "</h7>" );
591  r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
592  r->Report( "" );
593 
594  if( compileError )
595  {
596  r->Report( "" );
597  r->Report( _( "Report incomplete: could not compile custom design rules. " )
598  + "<a href='boardsetup'>" + _( "Show design rules." ) + "</a>" );
599  }
600  else
601  {
602  // PADSTACKS TODO: once we have padstacks we'll need to run this per-layer....
603  auto constraint = drcEngine.EvalRules( ANNULAR_WIDTH_CONSTRAINT, item, nullptr,
604  UNDEFINED_LAYER, r );
605 
606  wxString min = _( "undefined" );
607  wxString max = _( "undefined" );
608 
609  if( constraint.m_Value.HasMin() )
610  min = StringFromValue( r->GetUnits(), constraint.m_Value.Min(), true );
611 
612  if( constraint.m_Value.HasMax() )
613  max = StringFromValue( r->GetUnits(), constraint.m_Value.Max(), true );
614 
615  r->Report( "" );
616  r->Report( wxString::Format( _( "Annular width constraints: min %s max %s." ),
617  min,
618  max ) );
619  }
620 
621  r->Flush();
622  }
623 
624  if( ( item->Type() == PCB_PAD_T && static_cast<PAD*>( item )->GetDrillSize().x > 0 )
625  || item->Type() == PCB_VIA_T )
626  {
627  r = m_inspectConstraintsDialog->AddPage( _( "Hole Size" ) );
628 
629  r->Report( "<h7>" + _( "Hole diameter resolution for:" ) + "</h7>" );
630  r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
631  r->Report( "" );
632 
633  if( compileError )
634  {
635  r->Report( "" );
636  r->Report( _( "Report incomplete: could not compile custom design rules. " )
637  + "<a href='boardsetup'>" + _( "Show design rules." ) + "</a>" );
638  }
639  else
640  {
641  // PADSTACKS TODO: once we have padstacks we'll need to run this per-layer....
642  auto constraint = drcEngine.EvalRules( HOLE_SIZE_CONSTRAINT, item, nullptr,
643  UNDEFINED_LAYER, r );
644 
645  wxString min = _( "undefined" );
646 
647  if( constraint.m_Value.HasMin() )
648  min = StringFromValue( r->GetUnits(), constraint.m_Value.Min(), true );
649 
650  r->Report( "" );
651  r->Report( wxString::Format( _( "Hole constraint: min %s." ), min ) );
652  }
653 
654  r->Flush();
655  }
656 
657  r = m_inspectConstraintsDialog->AddPage( _( "Keepouts" ) );
658 
659  r->Report( "<h7>" + _( "Keepout resolution for:" ) + "</h7>" );
660  r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
661  r->Report( "" );
662 
663  if( compileError )
664  {
665  r->Report( "" );
666  r->Report( _( "Report incomplete: could not compile custom design rules. " )
667  + "<a href='boardsetup'>" + _( "Show design rules." ) + "</a>" );
668  }
669  else
670  {
671  if( courtyardError )
672  {
673  r->Report( "" );
674  r->Report( _( "Report may be incomplete: some footprint courtyards are malformed." )
675  + " <a href='drc'>" + _( "Run DRC for a full analysis." ) + "</a>" );
676  }
677 
678  auto constraint = drcEngine.EvalRules( DISALLOW_CONSTRAINT, item, nullptr, item->GetLayer(),
679  r );
680 
681  r->Report( "" );
682 
683  if( constraint.m_DisallowFlags )
684  r->Report( _( "Item <b>disallowed</b> at current location." ) );
685  else
686  r->Report( _( "Item allowed at current location." ) );
687  }
688 
689  r->Flush();
690 
691  m_inspectConstraintsDialog->FinishInitialization();
693  m_inspectConstraintsDialog->Show( true );
694  return 0;
695 }
696 
697 
699 {
700  // Don't get in an infinite loop PCB -> SCH -> PCB -> SCH -> ...
701  if( m_probingSchToPcb )
702  return 0;
703 
705  const PCB_SELECTION& selection = selTool->GetSelection();
706 
707  if( selection.Size() == 1 )
708  m_frame->SendMessageToEESCHEMA( static_cast<BOARD_ITEM*>( selection.Front() ) );
709  else
710  m_frame->SendMessageToEESCHEMA( nullptr );
711 
712  m_frame->Update3DView( false );
713 
714  return 0;
715 }
716 
717 
719 {
720  BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
721 
722  m_probingSchToPcb = true; // recursion guard
723  {
725 
726  if( item )
727  m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, (void*) item );
728  }
729  m_probingSchToPcb = false;
730 
731  bool request3DviewRedraw = true;
732 
733  if( item && item->Type() != PCB_FOOTPRINT_T )
734  request3DviewRedraw = false;
735 
736  if( request3DviewRedraw )
737  m_frame->Update3DView( false );
738 
739  return 0;
740 }
741 
742 
750  bool BOARD_INSPECTION_TOOL::highlightNet( const VECTOR2D& aPosition, bool aUseSelection )
751 {
752  BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
755 
756  int net = -1;
757  bool enableHighlight = false;
758 
759  if( aUseSelection )
760  {
761  const PCB_SELECTION& selection = selectionTool->GetSelection();
762 
763  for( auto item : selection )
764  {
765  if( auto ci = dyn_cast<BOARD_CONNECTED_ITEM*>( item ) )
766  {
767  int item_net = ci->GetNetCode();
768 
769  if( net < 0 )
770  net = item_net;
771  else if( net != item_net ) // more than one net selected: do nothing
772  return false;
773  }
774  }
775 
776  enableHighlight = ( net >= 0 && !settings->GetHighlightNetCodes().count( net ) );
777  }
778 
779  // If we didn't get a net to highlight from the selection, use the cursor
780  if( net < 0 )
781  {
783  GENERAL_COLLECTOR collector;
784 
785  PCB_LAYER_ID activeLayer = static_cast<PCB_LAYER_ID>( view()->GetTopLayer() );
786  guide.SetPreferredLayer( activeLayer );
787 
788  // Find a connected item for which we are going to highlight a net
789  collector.Collect( board, GENERAL_COLLECTOR::PadsOrTracks, (wxPoint) aPosition, guide );
790 
791  if( collector.GetCount() == 0 )
792  collector.Collect( board, GENERAL_COLLECTOR::Zones, (wxPoint) aPosition, guide );
793 
794  // Apply the active selection filter, except we want to allow picking locked items for
795  // highlighting even if the user has disabled them for selection
796  SELECTION_FILTER_OPTIONS& filter = selectionTool->GetFilter();
797 
798  bool saved = filter.lockedItems;
799  filter.lockedItems = true;
800 
801  selectionTool->FilterCollectedItems( collector );
802 
803  filter.lockedItems = saved;
804 
805  // Clear the previous highlight
806  m_frame->SendMessageToEESCHEMA( nullptr );
807 
808  bool highContrast = settings->GetHighContrast();
809  PCB_LAYER_ID contrastLayer = settings->GetPrimaryHighContrastLayer();
810 
811  for( int i = collector.GetCount() - 1; i >= 0; i-- )
812  {
813  LSET itemLayers = collector[i]->GetLayerSet();
814 
815  if( ( itemLayers & LSET::AllCuMask() ).none() ||
816  ( highContrast && !itemLayers.Contains( contrastLayer ) ) )
817  {
818  collector.Remove( i );
819  continue;
820  }
821  }
822 
823  enableHighlight = ( collector.GetCount() > 0 );
824 
825  // Obtain net code for the clicked item
826  if( enableHighlight )
827  {
828  BOARD_CONNECTED_ITEM* targetItem = static_cast<BOARD_CONNECTED_ITEM*>( collector[0] );
829 
830  if( targetItem->Type() == PCB_PAD_T )
831  m_frame->SendMessageToEESCHEMA( targetItem );
832 
833  net = targetItem->GetNetCode();
834  }
835  }
836 
837  auto& netcodes = settings->GetHighlightNetCodes();
838 
839  // Toggle highlight when the same net was picked
840  if( net > 0 && netcodes.count( net ) )
841  enableHighlight = !settings->IsHighlightEnabled();
842 
843  if( enableHighlight != settings->IsHighlightEnabled()
844  || !netcodes.count( net ) )
845  {
846  if( !netcodes.empty() )
847  m_lastNetcode = *netcodes.begin();
848 
849  settings->SetHighlight( enableHighlight, net );
851  }
852 
853  // Store the highlighted netcode in the current board (for dialogs for instance)
854  if( enableHighlight && net >= 0 )
855  {
856  board->SetHighLightNet( net );
857  board->HighLightON();
858 
859  NETINFO_ITEM* netinfo = board->FindNet( net );
860 
861  if( netinfo )
862  {
863  MSG_PANEL_ITEMS items;
864  netinfo->GetMsgPanelInfo( m_frame, items );
865  m_frame->SetMsgPanel( items );
867  }
868  }
869  else
870  {
874  }
875 
876  return true;
877 }
878 
879 
881 {
882  int netcode = aEvent.Parameter<intptr_t>();
884  const std::set<int>& highlighted = settings->GetHighlightNetCodes();
885 
886  if( netcode > 0 )
887  {
888  m_lastNetcode = highlighted.empty() ? -1 : *highlighted.begin();
889  settings->SetHighlight( true, netcode );
891  }
892  else if( aEvent.IsAction( &PCB_ACTIONS::toggleLastNetHighlight ) )
893  {
894  int temp = highlighted.empty() ? -1 : *highlighted.begin();
895  settings->SetHighlight( true, m_lastNetcode );
897  m_lastNetcode = temp;
898  }
899  else // Highlight the net belonging to the item under the cursor
900  {
901  highlightNet( getViewControls()->GetMousePosition(), false );
902  }
903 
904  return 0;
905 }
906 
907 
909 {
910  BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
912 
914  settings->SetHighlight( false );
918  return 0;
919 }
920 
921 
923 {
924  std::string tool = aEvent.GetCommandStr().get();
926 
927  // Deactivate other tools; particularly important if another PICKER is currently running
928  Activate();
929 
930  // If the keyboard hotkey was triggered and we are already in the highlight tool, behave
931  // the same as a left-click. Otherwise highlight the net of the selected item(s), or if
932  // there is no selection, then behave like a ctrl-left-click.
934  {
935  bool use_selection = m_frame->IsCurrentTool( PCB_ACTIONS::highlightNetTool );
936  highlightNet( getViewControls()->GetMousePosition(), use_selection );
937  }
938 
939  picker->SetClickHandler(
940  [this] ( const VECTOR2D& pt ) -> bool
941  {
942  highlightNet( pt, false );
943  return true;
944  } );
945 
946  picker->SetLayerSet( LSET::AllCuMask() );
947  picker->SetSnapping( false );
948 
949  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
950 
951  return 0;
952 }
953 
954 
956 {
957  std::string tool = aEvent.GetCommandStr().get();
959  BOARD* board = getModel<BOARD>();
960  auto& opt = displayOptions();
961 
962  // Deactivate other tools; particularly important if another PICKER is currently running
963  Activate();
964 
965  picker->SetClickHandler(
966  [this, board, opt]( const VECTOR2D& pt ) -> bool
967  {
969 
972  PCB_SELECTION& selection = selectionTool->GetSelection();
973 
974  if( selection.Empty() )
975  {
978  selection = selectionTool->GetSelection();
979  }
980 
981  if( selection.Empty() )
982  {
983  // Clear the previous local ratsnest if we click off all items
984  for( FOOTPRINT* fp : board->Footprints() )
985  {
986  for( PAD* pad : fp->Pads() )
987  pad->SetLocalRatsnestVisible( opt.m_ShowGlobalRatsnest );
988  }
989  }
990  else
991  {
992  for( EDA_ITEM* item : selection )
993  {
994  if( PAD* pad = dyn_cast<PAD*>( item) )
995  {
996  pad->SetLocalRatsnestVisible( !pad->GetLocalRatsnestVisible() );
997  }
998  else if( FOOTPRINT* fp = dyn_cast<FOOTPRINT*>( item) )
999  {
1000  if( !fp->Pads().empty() )
1001  {
1002  bool enable = !fp->Pads()[0]->GetLocalRatsnestVisible();
1003 
1004  for( PAD* childPad : fp->Pads() )
1005  childPad->SetLocalRatsnestVisible( enable );
1006  }
1007  }
1008  }
1009  }
1010 
1012 
1013  return true;
1014  } );
1015 
1016  picker->SetFinalizeHandler(
1017  [board, opt] ( int aCondition )
1018  {
1019  if( aCondition != PCB_PICKER_TOOL::END_ACTIVATE )
1020  {
1021  for( FOOTPRINT* fp : board->Footprints() )
1022  {
1023  for( PAD* pad : fp->Pads() )
1024  pad->SetLocalRatsnestVisible( opt.m_ShowGlobalRatsnest );
1025  }
1026  }
1027  } );
1028 
1029  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
1030 
1031  return 0;
1032 }
1033 
1034 
1036 {
1037  VECTOR2I delta;
1038 
1039  // If we have passed the simple move vector, we can update without recalculation
1040  if( aEvent.Parameter<VECTOR2I*>() )
1041  {
1042  delta = *aEvent.Parameter<VECTOR2I*>();
1043  delete aEvent.Parameter<VECTOR2I*>();
1044  }
1045  else
1046  {
1047  // We can delete the existing map to force a recalculation
1048  delete m_dynamicData;
1049  m_dynamicData = nullptr;
1050  }
1051 
1052  auto selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
1053  auto& selection = selectionTool->GetSelection();
1054  auto connectivity = getModel<BOARD>()->GetConnectivity();
1055 
1056  if( selection.Empty() )
1057  {
1058  connectivity->ClearDynamicRatsnest();
1059  delete m_dynamicData;
1060  m_dynamicData = nullptr;
1061  }
1062  else
1063  {
1064  calculateSelectionRatsnest( delta );
1065  }
1066 
1067  return 0;
1068 }
1069 
1070 
1072 {
1073  getModel<BOARD>()->GetConnectivity()->ClearDynamicRatsnest();
1074  delete m_dynamicData;
1075  m_dynamicData = nullptr;
1076 
1077  return 0;
1078 }
1079 
1080 
1082 {
1084  SELECTION& selection = selectionTool->GetSelection();
1085  std::shared_ptr<CONNECTIVITY_DATA> connectivity = board()->GetConnectivity();
1086  std::vector<BOARD_ITEM*> items;
1087  std::deque<EDA_ITEM*> queued_items( selection.begin(), selection.end() );
1088 
1089  for( std::size_t i = 0; i < queued_items.size(); ++i )
1090  {
1091  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( queued_items[i] );
1092 
1093  if( item->Type() == PCB_FOOTPRINT_T )
1094  {
1095  for( PAD* pad : static_cast<FOOTPRINT*>( item )->Pads() )
1096  {
1097  if( pad->GetLocalRatsnestVisible() || displayOptions().m_ShowModuleRatsnest )
1098  items.push_back( pad );
1099  }
1100  }
1101  else if( item->Type() == PCB_GROUP_T )
1102  {
1103  PCB_GROUP *group = static_cast<PCB_GROUP*>( item );
1104  group->RunOnDescendants( [ &queued_items ]( BOARD_ITEM *aItem )
1105  {
1106  queued_items.push_back( aItem );
1107  } );
1108  }
1109  else if( BOARD_CONNECTED_ITEM* boardItem = dyn_cast<BOARD_CONNECTED_ITEM*>( item ) )
1110  {
1111  if( boardItem->GetLocalRatsnestVisible() || displayOptions().m_ShowModuleRatsnest )
1112  items.push_back( boardItem );
1113  }
1114  }
1115 
1116  if( items.empty() || std::none_of( items.begin(), items.end(),
1117  []( const BOARD_ITEM* aItem )
1118  {
1119  return( aItem->Type() == PCB_TRACE_T
1120  || aItem->Type() == PCB_PAD_T
1121  || aItem->Type() == PCB_ARC_T
1122  || aItem->Type() == PCB_ZONE_T
1123  || aItem->Type() == PCB_FOOTPRINT_T
1124  || aItem->Type() == PCB_VIA_T );
1125  } ) )
1126  {
1127  return;
1128  }
1129 
1130  if( !m_dynamicData )
1131  {
1132  m_dynamicData = new CONNECTIVITY_DATA( items, true );
1133  connectivity->BlockRatsnestItems( items );
1134  }
1135  else
1136  {
1137  m_dynamicData->Move( aDelta );
1138  }
1139 
1140  connectivity->ComputeDynamicRatsnest( items, m_dynamicData );
1141 }
1142 
1143 
1145 {
1146  if( m_listNetsDialog == nullptr )
1147  {
1149  std::make_unique<DIALOG_NET_INSPECTOR>( m_frame, m_listNetsDialogSettings );
1150 
1151  m_listNetsDialog->Connect( wxEVT_CLOSE_WINDOW,
1152  wxCommandEventHandler( BOARD_INSPECTION_TOOL::onListNetsDialogClosed ), nullptr,
1153  this );
1154 
1155  m_listNetsDialog->Connect( wxEVT_BUTTON,
1156  wxCommandEventHandler( BOARD_INSPECTION_TOOL::onListNetsDialogClosed ), nullptr,
1157  this );
1158  }
1159 
1160  m_listNetsDialog->Raise();
1161  m_listNetsDialog->Show( true );
1162  return 0;
1163 }
1164 
1165 
1167 {
1169 
1170  m_listNetsDialog->Disconnect( wxEVT_CLOSE_WINDOW,
1171  wxCommandEventHandler( BOARD_INSPECTION_TOOL::onListNetsDialogClosed ), nullptr, this );
1172 
1173  m_listNetsDialog->Disconnect( wxEVT_BUTTON,
1174  wxCommandEventHandler( BOARD_INSPECTION_TOOL::onListNetsDialogClosed ), nullptr, this );
1175 
1176  m_listNetsDialog->Destroy();
1177  m_listNetsDialog.release();
1178 }
1179 
1180 
1182 {
1183  m_inspectClearanceDialog->Disconnect( wxEVT_CLOSE_WINDOW,
1184  wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectClearanceDialogClosed ), nullptr, this );
1185 
1186  m_inspectClearanceDialog->Destroy();
1187  m_inspectClearanceDialog.release();
1188 }
1189 
1190 
1192 {
1193  m_inspectConstraintsDialog->Disconnect( wxEVT_CLOSE_WINDOW,
1194  wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectConstraintsDialogClosed ), nullptr, this );
1195 
1196  m_inspectConstraintsDialog->Destroy();
1197  m_inspectConstraintsDialog.release();
1198 }
1199 
1200 
1202 {
1203  doHideNet( aEvent.Parameter<intptr_t>(), true );
1204  return 0;
1205 }
1206 
1207 
1209 {
1210  doHideNet( aEvent.Parameter<intptr_t>(), false );
1211  return 0;
1212 }
1213 
1214 
1215 void BOARD_INSPECTION_TOOL::doHideNet( int aNetCode, bool aHide )
1216 {
1217  KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
1219 
1221  SELECTION& selection = selectionTool->GetSelection();
1222 
1223  if( aNetCode <= 0 && !selection.Empty() )
1224  {
1225  for( EDA_ITEM* item : selection )
1226  {
1227  if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
1228  {
1229  if( bci->GetNetCode() > 0 )
1230  doHideNet( bci->GetNetCode(), aHide );
1231  }
1232  }
1233 
1234  return;
1235  }
1236 
1237  if( aHide )
1238  rs->GetHiddenNets().insert( aNetCode );
1239  else
1240  rs->GetHiddenNets().erase( aNetCode );
1241 
1243  m_frame->GetCanvas()->Refresh();
1244 
1245  m_frame->GetAppearancePanel()->OnNetVisibilityChanged( aNetCode, !aHide );
1246 }
1247 
1248 
1250 {
1254 
1258 
1263 
1271 
1274 }
void SetUnits(EDA_UNITS aUnits)
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
void BuildPolyCourtyards(OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Build complex polygons of the courtyard areas from graphic items on the courtyard layers.
Definition: footprint.cpp:1881
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
void reportClearance(DRC_CONSTRAINT_T aClearanceType, PCB_LAYER_ID aLayer, BOARD_ITEM *aA, BOARD_ITEM *aB, REPORTER *r)
int HideDynamicRatsnest(const TOOL_EVENT &aEvent)
Show local ratsnest of a component.
const BITMAP_OPAQUE show_ratsnest_xpm[1]
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
std::set< int > & GetHiddenNets()
Definition: pcb_painter.h:187
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1268
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
Design Rule Checker object that performs all the DRC tests.
Definition: drc_engine.h:80
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon)
Add a wxWidgets-style entry to the menu.
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:289
bool IsCurrentTool(const TOOL_ACTION &aAction) const
static const TOOL_EVENT SelectedEvent
Definition: actions.h:209
wxString getItemDescription(BOARD_ITEM *aItem)
const int GetDrillSizeX() const
Definition: pad.h:244
void SendCrossProbeNetName(const wxString &aNetName)
Send a net name to Eeschema for highlighting.
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:342
ZONES & Zones()
Definition: board.h:302
BOARD * board() const
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:210
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition: board.cpp:2006
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:45
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
A slimmed down version of WX_HTML_REPORT_PANEL.
static TOOL_ACTION hideNet
Definition: pcb_actions.h:451
virtual EDA_UNITS GetUnits() const
Definition: reporter.h:120
static TOOL_ACTION highlightItem
Definition: pcb_actions.h:450
const wxString & GetName() const
Definition: netclass.h:65
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:50
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:567
int LocalRatsnestTool(const TOOL_EVENT &aEvent)
static TOOL_ACTION boardStatistics
Definition: pcb_actions.h:437
int InspectClearance(const TOOL_EVENT &aEvent)
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Create a functor that tests if the selected items are only of given types.
virtual void Update3DView(bool aReloadRequest, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
int ClearHighlight(const TOOL_EVENT &aEvent)
Launch a tool to pick the item whose net is going to be highlighted.
virtual NETCLASS * GetNetClass() const
Return the NETCLASS for this item.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
bool Contains(PCB_LAYER_ID aLayer)
See if the layer set contains a PCB layer.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
ITER end()
Definition: selection.h:63
int CrossProbePcbToSch(const TOOL_EVENT &aEvent)
Highlight net belonging to the item under the cursor.
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:81
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
static ENUM_MAP< T > & Instance()
Definition: property.h:508
TOOL_MENU & GetToolMenu()
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pad.h:559
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:584
class PAD, a pad in a footprint
Definition: typeinfo.h:89
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:100
static const KICAD_T PadsOrTracks[]
A scan list for PADs, TRACKs, or VIAs.
Definition: collectors.h:289
static TOOL_ACTION localRatsnestTool
Definition: pcb_actions.h:455
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
bool IsConnected() const override
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
static TOOL_ACTION toggleLastNetHighlight
Definition: pcb_actions.h:447
std::unordered_set< BOARD_ITEM * > & GetItems()
Definition: pcb_group.h:68
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
EDA_ITEM * GetModel() const
Definition: tool_manager.h:296
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:207
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:70
static TOOL_ACTION inspectConstraints
Definition: pcb_actions.h:441
PAD_ATTR_T GetAttribute() const
Definition: pad.h:363
void SetLayerSet(LSET aLayerSet)
Set the tool's snap layer set.
static TOOL_ACTION pickerTool
Definition: actions.h:158
int GetThermalReliefGap() const
Definition: zone.h:195
virtual PCB_LAYER_ID GetActiveLayer() const
DRC_CONSTRAINT_T
Definition: drc_rule.h:41
static TOOL_ACTION highlightNetTool
Definition: pcb_actions.h:448
PCB specific render settings.
Definition: pcb_painter.h:64
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
PCB_SELECTION & GetSelection()
Return the set of currently selected items.
int InspectConstraints(const TOOL_EVENT &aEvent)
FP_ZONES & Zones()
Definition: footprint.h:170
ITER begin()
Definition: selection.h:62
PCB_LAYER_ID
A quick note on layer IDs:
void SetPreferredLayer(PCB_LAYER_ID aLayer)
Definition: collectors.h:509
GENERAL_COLLECTORS_GUIDE GetCollectorsGuide()
LSET is a set of PCB_LAYER_IDs.
void ResetNetHighLight()
Reset all high light data to the init state.
Definition: board.cpp:1984
pads are covered by copper
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString)
int HighlightNet(const TOOL_EVENT &aEvent)
Clear all board highlights.
const PCB_SELECTION & selection() const
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
std::unique_ptr< DIALOG_CONSTRAINTS_REPORTER > m_inspectConstraintsDialog
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:574
void onInspectClearanceDialogClosed(wxCommandEvent &aEvent)
int GetLocalClearance(wxString *aSource) const override
Function GetLocalClearance returns any local clearances set in the "classic" (ie: pre-rule) system.
Definition: zone.cpp:491
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:443
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
FOOTPRINTS & Footprints()
Definition: board.h:296
void SetIcon(const BITMAP_OPAQUE *aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:71
Generic, UI-independent tool event.
Definition: tool_event.h:173
FOOTPRINT * footprint() const
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:407
KIGFX::PCB_VIEW * view() const
static const KICAD_T Zones[]
A scan list for zones outlines only.
Definition: collectors.h:273
const wxString & GetNetname() const
Definition: netinfo.h:119
Items that may change while the view stays the same (noncached)
Definition: definitions.h:50
int HighlightItem(const TOOL_EVENT &aEvent)
Update ratsnest for selected items.
static const TOOL_EVENT ClearedEvent
Selected item had a property changed (except movement)
Definition: actions.h:211
#define MALFORMED_COURTYARDS
Definition: eda_item.h:125
ZONE handles a list of polygons defining a copper zone.
Definition: zone.h:57
class ZONE, a copper pour area
Definition: typeinfo.h:105
This file contains data structures that are saved in the project file or project local settings file ...
void RunOnDescendants(const std::function< void(BOARD_ITEM *)> &aFunction) const
Invoke a function on all descendants of the group.
Definition: pcb_group.cpp:324
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition: board.cpp:1993
int ShowNet(const TOOL_EVENT &aEvent)
Show the clearance resolution for two selected items.
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:106
static TOOL_ACTION hideDynamicRatsnest
Definition: pcb_actions.h:456
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
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 void PadFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector, PCB_SELECTION_TOOL *sTool)
A selection filter which prunes the selection to contain only items of type PCB_PAD_T.
Definition: edit_tool.cpp:2151
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...
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
Thermal relief only for THT pads.
static TOOL_ACTION inspectClearance
Definition: pcb_actions.h:440
const PCB_DISPLAY_OPTIONS & displayOptions() const
Generic tool for picking an item.
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
std::unique_ptr< DIALOG_NET_INSPECTOR > m_listNetsDialog
static TOOL_ACTION clearHighlight
Definition: pcb_actions.h:445
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:69
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void reportZoneConnection(ZONE *aZone, PAD *aPad, REPORTER *r)
int ListNets(const TOOL_EVENT &aEvent)
Hide the ratsnest for a given net.
void OnNetVisibilityChanged(int aNetCode, bool aVisibility)
Notifies the panel when a net has been hidden or shown via the external tool.
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:471
Use thermal relief for pads.
EDA_UNITS GetUnits() const override
int HighlightNetTool(const TOOL_EVENT &aEvent)
Perform the appropriate action in response to an Eeschema cross-probe.
void SendMessageToEESCHEMA(BOARD_ITEM *objectToSync)
Send a message to the schematic editor so that it may move its cursor to a symbol with the same refer...
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
Handle the data for a net.
Definition: netinfo.h:64
bool lockedItems
Allow selecting locked items.
static TOOL_ACTION showNet
Definition: pcb_actions.h:452
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:118
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:89
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:446
DIALOG_NET_INSPECTOR::SETTINGS m_listNetsDialogSettings
static TOOL_ACTION highlightNetSelection
Definition: pcb_actions.h:449
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:189
const int GetDrillSizeY() const
Definition: pad.h:246
#define _(s)
Definition: 3d_actions.cpp:33
static TOOL_ACTION listNets
Definition: pcb_actions.h:341
bool Init() override
Init() is called once upon a registration of the tool.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
Dialog to show common board info.
virtual wxString GetSelectMenuText(EDA_UNITS aUnits) const
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: eda_item.cpp:123
void AddSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition: tool_menu.cpp:52
void onListNetsDialogClosed(wxCommandEvent &aEvent)
void doHideNet(int aNetCode, bool aHide)
Bind handlers to corresponding TOOL_ACTIONs.
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition: pcb_actions.h:66
Plated through hole pad.
Definition: pad_shapes.h:80
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
The selection tool: currently supports:
static TOOL_ACTION runDRC
Definition: pcb_actions.h:342
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
CONNECTIVITY_DATA * m_dynamicData
Pads are not covered.
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:97
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
int HideNet(const TOOL_EVENT &aEvent)
Show the ratsnest for a given net.
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:225
void Activate()
Run the tool.
int UpdateSelectionRatsnest(const TOOL_EVENT &aEvent)
Hide ratsnest for selected items. Called when there are no items selected.
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: board_item.h:136
SELECTION_FILTER_OPTIONS & GetFilter()
Set up handlers for various events.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
void SetSnapping(bool aSnap)
Definition: picker_tool.h:62
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
APPEARANCE_CONTROLS * GetAppearancePanel()
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:457
static void FootprintFilter(const VECTOR2I &, GENERAL_COLLECTOR &aCollector, PCB_SELECTION_TOOL *sTool)
A selection filter which prunes the selection to contain only items of type #PCB_MODULE_T.
Definition: edit_tool.cpp:2164
BOARD * GetBoard() const
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:381
ZONE_CONNECTION GetPadConnection(PAD *aPad, wxString *aSource=nullptr) const
Definition: zone.cpp:770
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Return the information about the NETINFO_ITEM in aList to display in the message panel.
Definition: pad.h:60
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition: view.cpp:770
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
Definition: string.cpp:346
STATUS_FLAGS GetFlags() const
Definition: eda_item.h:204
void FilterCollectedItems(GENERAL_COLLECTOR &aCollector)
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
std::unique_ptr< DIALOG_INSPECTION_REPORTER > m_inspectClearanceDialog
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
void Move(const VECTOR2I &aDelta)
Moves the connectivity list anchors.
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:60
void calculateSelectionRatsnest(const VECTOR2I &aDelta)
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void onInspectConstraintsDialogClosed(wxCommandEvent &aEvent)
int ShowStatisticsDialog(const TOOL_EVENT &aEvent)
Show dialog with board statistics.
void InitEngine(const wxFileName &aRulePath)
Initializes the DRC engine.
Definition: drc_engine.cpp:598
void OnErrorLinkClicked(wxHtmlLinkEvent &event) override
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:178
EDA_ITEM * Front() const
Definition: selection.h:203
const wxString & ToString(T value) const
Definition: property.h:527
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:162