KiCad PCB EDA Suite
Loading...
Searching...
No Matches
headless_pcb_context.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 * @author Jon Evans <[email protected]>
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
22#include <board.h>
23#include <board_loader.h>
25#include <drc/drc_engine.h>
26#include <footprint.h>
30#include <pcbnew_settings.h>
31#include <pgm_base.h>
32#include <project.h>
33#include <reporter.h>
35#include <spread_footprints.h>
36#include <tool/tool_manager.h>
37#include <tools/drc_tool.h>
38#include <wx/debug.h>
39
40
41HEADLESS_PCB_CONTEXT::HEADLESS_PCB_CONTEXT( std::unique_ptr<BOARD> aBoard, PROJECT* aProject,
42 APP_SETTINGS_BASE* aSettings,
43 KIWAY* aKiway ) :
44 m_board( std::move( aBoard ) ),
45 m_project( aProject ),
46 m_kiway( aKiway ),
47 m_toolManager( std::make_unique<TOOL_MANAGER>() )
48{
49 wxCHECK( m_board, /* void */ );
50 wxCHECK( m_project, /* void */ );
51
52 m_board->SetProject( m_project );
53 m_toolManager->SetEnvironment( m_board.get(), nullptr, nullptr, aSettings, nullptr );
54}
55
56
58{
59 // Sever the board↔project linkage before destruction. The PROJECT holds a raw pointer
60 // (m_BoardSettings) to the board's design settings. If the board is destroyed while the
61 // project still exists, that pointer becomes dangling.
62 if( m_board )
63 m_board->ClearProject();
64}
65
66
68{
69 return m_board.get();
70}
71
72
74{
75 // Shouldn't be able to construct this without a project
76 wxASSERT( m_project );
77 return *m_project;
78}
79
80
85
86
88{
89 if( !m_board )
90 return wxEmptyString;
91
92 return m_board->GetFileName();
93}
94
95
97{
98 if( !m_board )
99 return false;
100
101 wxString fileName = m_board->GetFileName();
102
103 if( fileName.IsEmpty() )
104 return false;
105
106 bool success = BOARD_LOADER::SaveBoard( fileName, *m_board );
107
108 if( success )
109 {
110 m_contentModified = false;
111
112 wxFileName pro = fileName;
113 pro.SetExt( FILEEXT::ProjectFileExtension );
114 pro.MakeAbsolute();
115
116 Pgm().GetSettingsManager().SaveProjectAs( pro.GetFullPath(), m_board->GetProject() );
117 }
118
119 return success;
120}
121
122
123bool HEADLESS_PCB_CONTEXT::SavePcbCopy( const wxString& aFileName, bool aCreateProject, bool aHeadless )
124{
125 if( !m_board || aFileName.IsEmpty() )
126 return false;
127
128 wxString outPath = aFileName;
129
130 bool success = BOARD_LOADER::SaveBoard( outPath, *m_board );
131
132 if( success && aCreateProject )
133 {
134 wxFileName pro = aFileName;
135 pro.SetExt( FILEEXT::ProjectFileExtension );
136 pro.MakeAbsolute();
137
138 Pgm().GetSettingsManager().SaveProjectAs( pro.GetFullPath(), m_board->GetProject() );
139 }
140
141 return success;
142}
143
144
145bool HEADLESS_PCB_CONTEXT::ReadNetlistFromFile( const wxString& aFilename, NETLIST& aNetlist, REPORTER& aReporter )
146{
147 wxString msg;
148
149 try
150 {
151 std::unique_ptr<NETLIST_READER> netlistReader(
152 NETLIST_READER::GetNetlistReader( &aNetlist, aFilename, wxEmptyString ) );
153
154 if( !netlistReader.get() )
155 {
156 msg.Printf( _( "Cannot open netlist file '%s'." ), aFilename );
157 aReporter.Report( msg, RPT_SEVERITY_ERROR );
158 return false;
159 }
160
161 netlistReader->LoadNetlist();
162 LoadNetlistFootprints( GetBoard(), aNetlist, aReporter );
163 }
164 catch( const IO_ERROR& ioe )
165 {
166 msg.Printf( _( "Error loading netlist.\n%s" ), ioe.What().GetData() );
167 aReporter.Report( msg, RPT_SEVERITY_ERROR );
168 return false;
169 }
170
171 return true;
172}
173
174
175std::unique_ptr<BOARD_NETLIST_UPDATER> HEADLESS_PCB_CONTEXT::MakeNetlistUpdater()
176{
177 return std::make_unique<BOARD_NETLIST_UPDATER>( GetToolManager(), GetBoard() );
178}
179
180
182{
183 BOARD* board = GetBoard();
184
185 // Re-sync nets and netclasses
186 board->SynchronizeNetsAndNetClasses( false );
187
188 // Recompute component classes
191
192 // Resync DRC rules to account for new aggregate netclass / component class rules
193 if( DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>() )
194 {
195 if( drcTool->GetDRCEngine() )
196 {
197 try
198 {
199 drcTool->GetDRCEngine()->InitEngine( board->GetDesignRulesPath() );
200 }
201 catch( PARSE_ERROR& )
202 {
203 }
204 }
205 }
206
207 std::vector<FOOTPRINT*> newFootprints = aUpdater.GetAddedFootprints();
208 SpreadFootprints( &newFootprints, { 0, 0 }, true );
209
210 board->CompileRatsnest();
211}
212
213
215{
216 wxCHECK( m_board && m_project, false );
217
218 wxString fileName = m_board->GetFileName();
219
220 if( fileName.IsEmpty() || !wxFileExists( fileName ) )
221 return false;
222
224
225 if( pluginType == PCB_IO_MGR::FILE_TYPE_NONE )
226 return false;
227
228 std::unique_ptr<BOARD> reloaded;
229
230 try
231 {
232 reloaded = BOARD_LOADER::Load( fileName, pluginType, m_project );
233 }
234 catch( ... )
235 {
236 return false;
237 }
238
239 if( !reloaded )
240 return false;
241
242 m_board = std::move( reloaded );
243 m_board->SetProject( m_project );
244 m_toolManager->SetEnvironment( m_board.get(), nullptr, nullptr, GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ),
245 nullptr );
246 m_contentModified = false;
247
248 return true;
249}
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
static bool SaveBoard(wxString &aFileName, BOARD &aBoard, PCB_IO_MGR::PCB_FILE_T aFormat)
static std::unique_ptr< BOARD > Load(const wxString &aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, PROJECT *aProject, const OPTIONS &aOptions)
Update the BOARD with a new netlist.
std::vector< FOOTPRINT * > GetAddedFootprints() const
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
void CompileRatsnest()
Rebuild the entire board ratsnest.
Definition board.cpp:4039
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3402
wxString GetDesignRulesPath() const
Return the absolute path to the design rules file for this board.
Definition board.cpp:435
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1668
void InvalidateComponentClasses()
Invalidates any caches component classes and recomputes caches if required.
void RebuildRequiredCaches(FOOTPRINT *aFootprint=nullptr) const
Rebuilds any caches that may be required by custom assignment rules.
BOARD * GetBoard() const override
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject, bool aHeadless) override
void OnNetlistChanged(BOARD_NETLIST_UPDATER &aUpdater) override
Post-import board sync (nets, classes, DRC, ratsnest, new footprint placement).
PROJECT & Prj() const override
TOOL_MANAGER * GetToolManager() const override
std::unique_ptr< TOOL_MANAGER > m_toolManager
HEADLESS_PCB_CONTEXT(std::unique_ptr< BOARD > aBoard, PROJECT *aProject, APP_SETTINGS_BASE *aSettings, KIWAY *aKiway=nullptr)
std::unique_ptr< BOARD > m_board
std::unique_ptr< BOARD_NETLIST_UPDATER > MakeNetlistUpdater() override
Create a netlist updater bound to this context's board.
bool ReadNetlistFromFile(const wxString &aFilename, NETLIST &aNetlist, REPORTER &aReporter) override
Read a netlist file and preload component footprints.
wxString GetCurrentFileName() const override
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:340
static NETLIST_READER * GetNetlistReader(NETLIST *aNetlist, const wxString &aNetlistFileName, const wxString &aCompFootprintFileName=wxEmptyString)
Attempt to determine the net list file type of aNetlistFileName and return the appropriate NETLIST_RE...
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:52
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:123
Container for project specific data.
Definition project.h:63
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:102
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Set the currently loaded project path and saves it (pointers remain valid).
Master controller class:
#define _(s)
static const std::string ProjectFileExtension
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
STL namespace.
void LoadNetlistFootprints(BOARD *aBoard, NETLIST &aNetlist, REPORTER &aReporter)
Load the footprints for each #SCH_COMPONENT in aNetlist from the list of libraries.
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
@ RPT_SEVERITY_ERROR
T * GetAppSettings(const char *aFilename)
void SpreadFootprints(std::vector< FOOTPRINT * > *aFootprints, const VECTOR2I &aTargetBoxPosition, bool aGroupBySheet, int aComponentGap, int aGroupGap)
Footprints (after loaded by reading a netlist for instance) are moved to be in a small free area (out...
A filename or source description, a problem input line, a line number, a byte offset,...