KiCad PCB EDA Suite
drc_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) 2020 KiCad Developers, see change_log.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 <pcb_edit_frame.h>
25 #include <bitmaps.h>
26 #include <tool/tool_manager.h>
27 #include <tools/pcb_actions.h>
28 #include <tools/pcb_tool_base.h>
29 #include <tools/zone_filler_tool.h>
30 #include <tools/drc_tool.h>
31 #include <kiface_i.h>
32 #include <dialog_drc.h>
33 #include <board_commit.h>
37 
39  PCB_TOOL_BASE( "pcbnew.DRCTool" ),
40  m_editFrame( nullptr ),
41  m_pcb( nullptr ),
42  m_drcDialog( nullptr ),
43  m_drcRunning( false )
44 {
45 }
46 
47 
49 {
50 }
51 
52 
54 {
55  m_editFrame = getEditFrame<PCB_EDIT_FRAME>();
56 
57  if( m_pcb != m_editFrame->GetBoard() )
58  {
59  if( m_drcDialog )
61 
64  }
65 
66  if( aReason == MODEL_RELOAD && m_pcb->GetProject() )
67  {
68  try
69  {
70  m_drcEngine->InitEngine( m_editFrame->GetDesignRulesPath() );
71  }
72  catch( PARSE_ERROR& pe )
73  {
74  // Not sure this is the best place to tell the user their rules are buggy, so
75  // we'll stay quiet for now. Feel free to revisit this decision....
76  }
77  }
78 }
79 
80 
81 void DRC_TOOL::ShowDRCDialog( wxWindow* aParent )
82 {
83  bool show_dlg_modal = true;
84 
85  // the dialog needs a parent frame. if it is not specified, this is the PCB editor frame
86  // specified in DRC_TOOL class.
87  if( !aParent )
88  {
89  // if any parent is specified, the dialog is modal.
90  // if this is the default PCB editor frame, it is not modal
91  show_dlg_modal = false;
92  aParent = m_editFrame;
93  }
94 
95  Activate();
97 
98  if( !m_drcDialog )
99  {
100  m_drcDialog = new DIALOG_DRC( m_editFrame, aParent );
101  updatePointers();
102 
103  if( show_dlg_modal )
104  m_drcDialog->ShowModal();
105  else
106  m_drcDialog->Show( true );
107  }
108  else // The dialog is just not visible (because the user has double clicked on an error item)
109  {
110  updatePointers();
111  m_drcDialog->Show( true );
112  }
113 }
114 
115 
117 {
118  ShowDRCDialog( nullptr );
119  return 0;
120 }
121 
122 
124 {
125  if( m_drcDialog )
126  return m_drcDialog->IsShown();
127 
128  return false;
129 }
130 
131 
133 {
134  if( m_drcDialog )
135  {
136  m_drcDialog->Destroy();
137  m_drcDialog = nullptr;
138  }
139 }
140 
141 
142 void DRC_TOOL::RunTests( PROGRESS_REPORTER* aProgressReporter, bool aTestTracksAgainstZones,
143  bool aRefillZones, bool aReportAllTrackErrors, bool aTestFootprints )
144 {
145  // One at a time, please.
146  // Note that the main GUI entry points to get here are blocked, so this is really an
147  // insurance policy and as such we make no attempts to queue up the DRC run or anything.
148  if( m_drcRunning )
149  return;
150 
152  BOARD_COMMIT commit( m_editFrame );
153  NETLIST netlist;
154  wxWindowDisabler disabler( /* disable everything except: */ m_drcDialog );
155 
156  m_drcRunning = true;
157 
158  if( aRefillZones )
159  {
160  aProgressReporter->AdvancePhase( _( "Refilling all zones..." ) );
161 
162  zoneFiller->FillAllZones( m_drcDialog, aProgressReporter );
163  }
164  else
165  {
166  aProgressReporter->AdvancePhase( _( "Checking zone fills..." ) );
167 
168  zoneFiller->CheckAllZones( m_drcDialog, aProgressReporter );
169  }
170 
171  m_drcEngine->SetWorksheet( m_editFrame->GetCanvas()->GetWorksheet() );
172 
173  if( aTestFootprints && !Kiface().IsSingle() )
174  {
176 
177  if( m_drcDialog )
178  m_drcDialog->Raise();
179 
180  m_drcEngine->SetSchematicNetlist( &netlist );
181  }
182 
183  m_drcEngine->SetProgressReporter( aProgressReporter );
184 
185  m_drcEngine->SetViolationHandler(
186  [&]( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )
187  {
188  if( aItem->GetErrorCode() == DRCE_MISSING_FOOTPRINT
189  || aItem->GetErrorCode() == DRCE_DUPLICATE_FOOTPRINT
190  || aItem->GetErrorCode() == DRCE_EXTRA_FOOTPRINT
191  || aItem->GetErrorCode() == DRCE_NET_CONFLICT )
192  {
193  m_footprints.push_back( aItem );
194  }
195  else if( aItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
196  {
197  m_unconnected.push_back( aItem );
198  }
199  else
200  {
201  MARKER_PCB* marker = new MARKER_PCB( aItem, aPos );
202  commit.Add( marker );
203  }
204  } );
205 
206  m_drcEngine->RunTests( m_editFrame->GetUserUnits(), aTestTracksAgainstZones,
207  aReportAllTrackErrors, aTestFootprints );
208 
209  m_drcEngine->SetProgressReporter( nullptr );
210  m_drcEngine->ClearViolationHandler();
211 
212  if( m_drcDialog )
213  {
215 
216  if( !netlist.IsEmpty() )
218  }
219 
220  commit.Push( _( "DRC" ), false );
221 
222  m_drcRunning = false;
223 
224  // update the m_drcDialog listboxes
225  updatePointers();
226 }
227 
228 
230 {
231  // update my pointers, m_editFrame is the only unchangeable one
233 
235 
236  if( m_drcDialog ) // Use diag list boxes only in DRC_TOOL dialog
237  {
240  &m_unconnected ) );
242  &m_footprints ) );
243  }
244 }
245 
246 
248 {
250 }
251 
252 
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:62
virtual void AdvancePhase()
Uses the next vailable virtual zone of the dialog progress bar.
RATSNEST_DRC_ITEMS_PROVIDER.
wxString GetDesignRulesPath()
Returns the absolute path to the design rules file for the currently-loaded board.
Model changes (required full reload)
Definition: tool_base.h:82
A progress reporter for use in multi-threaded environments.
DRC_TOOL()
Definition: drc_tool.cpp:38
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void ResolveDRCExclusions()
Update markers to match recorded exclusions.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
PCB_EDIT_FRAME * m_editFrame
Definition: drc_tool.h:55
BOARD * m_pcb
Definition: drc_tool.h:56
PROJECT * GetProject() const
Definition: class_board.h:397
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:141
std::shared_ptr< DRC_ENGINE > m_drcEngine
Definition: drc_tool.h:60
bool m_drcRunning
Definition: drc_tool.h:58
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: class_board.h:558
void SetDrcRun()
Definition: dialog_drc.h:51
void ShowDRCDialog(wxWindow *aParent)
Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and create...
Definition: drc_tool.cpp:81
void SetFootprintTestsRun()
Definition: dialog_drc.h:52
void setTransitions() override
Sets up handlers for various events.
Definition: drc_tool.cpp:247
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Definition: drc_tool.cpp:53
void FillAllZones(wxWindow *aCaller, PROGRESS_REPORTER *aReporter=nullptr)
ZONE_FILLER_TOOL.
void CheckAllZones(wxWindow *aCaller, PROGRESS_REPORTER *aReporter=nullptr)
NETLIST stores all of information read from a netlist along with the flags used to update the NETLIST...
Definition: pcb_netlist.h:194
bool IsSingle() const
Function IsSingle is this KIFACE_I running under single_top?
Definition: kiface_i.h:117
BOARD_DRC_ITEMS_PROVIDER is an implementation of the RC_ITEMS_PROVIDER interface which uses a BOARD i...
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
TOOL_EVENT.
Definition: tool_event.h:171
void SetFootprintsProvider(RC_ITEMS_PROVIDER *aProvider)
Definition: dialog_drc.cpp:295
void updatePointers()
Update needed pointers from the one pointer which is known not to change.
Definition: drc_tool.cpp:229
DIALOG_DRC * m_drcDialog
Definition: drc_tool.h:57
bool Show(bool show) override
bool IsDRCDialogShown()
Check to see if the DRC_TOOL dialog is currently shown.
Definition: drc_tool.cpp:123
void SetMarkersProvider(RC_ITEMS_PROVIDER *aProvider)
Definition: dialog_drc.cpp:279
Struct PARSE_ERROR contains a filename or source description, a problem input line,...
Definition: ki_exception.h:123
KIGFX::WS_PROXY_VIEW_ITEM * GetWorksheet() const
std::vector< std::shared_ptr< DRC_ITEM > > m_footprints
Definition: drc_tool.h:63
#define _(s)
Definition: 3d_actions.cpp:33
static TOOL_ACTION runDRC
Definition: pcb_actions.h:338
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
void RunTests(PROGRESS_REPORTER *aProgressReporter, bool aTestTracksAgainstZones, bool aRefillZones, bool aReportAllTrackErrors, bool aTestFootprints)
Run the DRC tests.
Definition: drc_tool.cpp:142
void Activate()
Function Activate() Runs the tool.
bool IsEmpty() const
Function IsEmpty()
Definition: pcb_netlist.h:212
BOARD * GetBoard() const
void DestroyDRCDialog()
Closes and frees the DRC dialog.
Definition: drc_tool.cpp:132
std::vector< std::shared_ptr< DRC_ITEM > > m_unconnected
Definition: drc_tool.h:62
~DRC_TOOL()
Definition: drc_tool.cpp:48
VECTOR_DRC_ITEMS_PROVIDER is an implementation of the interface named DRC_ITEMS_PROVIDER which uses a...
void SetUnconnectedProvider(RC_ITEMS_PROVIDER *aProvider)
Definition: dialog_drc.cpp:287
bool FetchNetlistFromSchematic(NETLIST &aNetlist, FETCH_NETLIST_MODE aMode)
std::shared_ptr< DRC_ENGINE > m_DRCEngine
EDA_UNITS GetUserUnits() const
Return the user units currently in use.