KiCad PCB EDA Suite
Loading...
Searching...
No Matches
project.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) 2014-2022 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 <wx/log.h>
25#include <wx/stdpaths.h> // required on Mac
27
28#include <pgm_base.h>
29#include <confirm.h>
30#include <core/arraydim.h>
31#include <core/kicad_algo.h>
32#include <fp_lib_table.h>
33#include <string_utils.h>
34#include <kiface_ids.h>
35#include <kiway.h>
36#include <macros.h>
37#include <project.h>
39#include <trace_helpers.h>
43
45 m_readOnly( false ),
46 m_textVarsTicker( 0 ),
47 m_netclassesTicker( 0 ),
48 m_projectFile( nullptr ),
49 m_localSettings( nullptr )
50{
51 memset( m_elems, 0, sizeof( m_elems ) );
52}
53
54
56{
57 // careful here, this should work, but the virtual destructor may not
58 // be in the same link image as PROJECT.
59 for( unsigned i = 0; i < arrayDim( m_elems ); ++i )
60 {
61 SetElem( ELEM_T( i ), nullptr );
62 }
63}
64
65
67{
68 ElemsClear();
69}
70
71
72bool PROJECT::TextVarResolver( wxString* aToken ) const
73{
74 if( GetTextVars().count( *aToken ) > 0 )
75 {
76 *aToken = GetTextVars().at( *aToken );
77 return true;
78 }
79
80 return false;
81}
82
83
84std::map<wxString, wxString>& PROJECT::GetTextVars() const
85{
87}
88
89
90void PROJECT::ApplyTextVars( const std::map<wxString, wxString>& aVarsMap )
91{
92 if( aVarsMap.size() == 0 )
93 return;
94
95 std::map<wxString, wxString>& existingVarsMap = GetTextVars();
96
97 for( const auto& var : aVarsMap )
98 {
99 // create or update the existing vars
100 existingVarsMap[var.first] = var.second;
101 }
102}
103
104
105void PROJECT::setProjectFullName( const wxString& aFullPathAndName )
106{
107 // Compare paths, rather than inodes, to be less surprising to the user.
108 // Create a temporary wxFileName to normalize the path
109 wxFileName candidate_path( aFullPathAndName );
110
111 // Edge transitions only. This is what clears the project
112 // data using the Clear() function.
113 if( m_project_name.GetFullPath() != candidate_path.GetFullPath() )
114 {
115 Clear(); // clear the data when the project changes.
116
117 wxLogTrace( tracePathsAndFiles, "%s: old:'%s' new:'%s'", __func__,
118 TO_UTF8( GetProjectFullName() ), TO_UTF8( aFullPathAndName ) );
119
120 m_project_name = aFullPathAndName;
121
122 wxASSERT( m_project_name.IsAbsolute() );
123
124 wxASSERT( m_project_name.GetExt() == FILEEXT::ProjectFileExtension );
125 }
126}
127
128
129const wxString PROJECT::GetProjectFullName() const
130{
131 return m_project_name.GetFullPath();
132}
133
134
135const wxString PROJECT::GetProjectPath() const
136{
137 return m_project_name.GetPathWithSep();
138}
139
140
141const wxString PROJECT::GetProjectDirectory() const
142{
143 return m_project_name.GetPath();
144}
145
146
147const wxString PROJECT::GetProjectName() const
148{
149 return m_project_name.GetName();
150}
151
152
154{
155 return m_project_name.GetName().IsEmpty();
156}
157
158
159const wxString PROJECT::SymbolLibTableName() const
160{
161 return libTableName( wxS( "sym-lib-table" ) );
162}
163
164
165const wxString PROJECT::FootprintLibTblName() const
166{
167 return libTableName( wxS( "fp-lib-table" ) );
168}
169
170
171void PROJECT::PinLibrary( const wxString& aLibrary, bool isSymbolLibrary )
172{
173 COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
174 std::vector<wxString>* pinnedLibs = isSymbolLibrary ? &m_projectFile->m_PinnedSymbolLibs
176
177 if( !alg::contains( *pinnedLibs, aLibrary ) )
178 pinnedLibs->push_back( aLibrary );
179
180 Pgm().GetSettingsManager().SaveProject();
181
182 pinnedLibs = isSymbolLibrary ? &cfg->m_Session.pinned_symbol_libs
184
185 if( !alg::contains( *pinnedLibs, aLibrary ) )
186 pinnedLibs->push_back( aLibrary );
187
188 cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
189}
190
191
192void PROJECT::UnpinLibrary( const wxString& aLibrary, bool isSymbolLibrary )
193{
194 COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
195 std::vector<wxString>* pinnedLibs = isSymbolLibrary ? &m_projectFile->m_PinnedSymbolLibs
197
198 alg::delete_matching( *pinnedLibs, aLibrary );
199 Pgm().GetSettingsManager().SaveProject();
200
201 pinnedLibs = isSymbolLibrary ? &cfg->m_Session.pinned_symbol_libs
203
204 alg::delete_matching( *pinnedLibs, aLibrary );
205 cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
206}
207
208
209const wxString PROJECT::libTableName( const wxString& aLibTableName ) const
210{
211 wxFileName fn = GetProjectFullName();
212 wxString path = fn.GetPath();
213
214 // if there's no path to the project name, or the name as a whole is bogus or its not
215 // write-able then use a template file.
216 if( !fn.GetDirCount() || !fn.IsOk() || !wxFileName::IsDirWritable( path ) )
217 {
218 // return a template filename now.
219
220 // this next line is likely a problem now, since it relies on an
221 // application title which is no longer constant or known. This next line needs
222 // to be re-thought out.
223
224#ifdef __WXMAC__
225 fn.AssignDir( KIPLATFORM::ENV::GetUserConfigPath() );
226#else
227 // don't pollute home folder, temp folder seems to be more appropriate
228 fn.AssignDir( wxStandardPaths::Get().GetTempDir() );
229#endif
230
231#if defined( __WINDOWS__ )
232 fn.AppendDir( wxT( "kicad" ) );
233#endif
234
235 /*
236 * The library table name used when no project file is passed to the appropriate
237 * code. This is used temporarily to store the project specific library table
238 * until the project file being edited is saved. It is then moved to the correct
239 * file in the folder where the project file is saved.
240 */
241 fn.SetName( wxS( "prj-" ) + aLibTableName );
242 }
243 else // normal path.
244 {
245 fn.SetName( aLibTableName );
246 }
247
248 fn.ClearExt();
249
250 return fn.GetFullPath();
251}
252
253
254const wxString PROJECT::GetSheetName( const KIID& aSheetID )
255{
256 if( m_sheetNames.empty() )
257 {
258 for( const std::pair<KIID, wxString>& pair : GetProjectFile().GetSheets() )
259 m_sheetNames[pair.first] = pair.second;
260 }
261
262 if( m_sheetNames.count( aSheetID ) )
263 return m_sheetNames.at( aSheetID );
264 else
265 return aSheetID.AsString();
266}
267
268
269void PROJECT::SetRString( RSTRING_T aIndex, const wxString& aString )
270{
271 unsigned ndx = unsigned( aIndex );
272
273 if( ndx < arrayDim( m_rstrings ) )
274 m_rstrings[ndx] = aString;
275 else
276 wxASSERT( 0 ); // bad index
277}
278
279
280const wxString& PROJECT::GetRString( RSTRING_T aIndex )
281{
282 unsigned ndx = unsigned( aIndex );
283
284 if( ndx < arrayDim( m_rstrings ) )
285 {
286 return m_rstrings[ndx];
287 }
288 else
289 {
290 static wxString no_cookie_for_you;
291
292 wxASSERT( 0 ); // bad index
293
294 return no_cookie_for_you;
295 }
296}
297
298
300{
301 // This is virtual, so implement it out of line
302 if( unsigned( aIndex ) < arrayDim( m_elems ) )
303 return m_elems[aIndex];
304
305 return nullptr;
306}
307
308
309void PROJECT::SetElem( ELEM_T aIndex, _ELEM* aElem )
310{
311 // This is virtual, so implement it out of line
312 if( unsigned( aIndex ) < arrayDim( m_elems ) )
313 {
314 delete m_elems[aIndex];
315 m_elems[aIndex] = aElem;
316 }
317}
318
319
320const wxString PROJECT::AbsolutePath( const wxString& aFileName ) const
321{
322 wxFileName fn = aFileName;
323
324 // Paths which start with an unresolved variable reference are more likely to be
325 // absolute than relative.
326 if( aFileName.StartsWith( wxT( "${" ) ) )
327 return aFileName;
328
329 if( !fn.IsAbsolute() )
330 {
331 wxString pro_dir = wxPathOnly( GetProjectFullName() );
332 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS, pro_dir );
333 }
334
335 return fn.GetFullPath();
336}
337
338
340{
341 // This is a lazy loading function, it loads the project specific table when
342 // that table is asked for, not before.
343
345
346 if( tbl )
347 {
348 wxASSERT( tbl->Type() == FP_LIB_TABLE_T );
349 }
350 else
351 {
352 try
353 {
354 // Build a new project specific FP_LIB_TABLE with the global table as a fallback.
355 // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
356 // stack this way, all using the same global fallback table.
357 KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_PCB );
358
360 tbl->Load( FootprintLibTblName() );
361
362 SetElem( ELEM_FPTBL, tbl );
363 }
364 catch( const IO_ERROR& ioe )
365 {
366 DisplayErrorMessage( nullptr, _( "Error loading project footprint library table." ),
367 ioe.What() );
368 }
369 catch( ... )
370 {
371 DisplayErrorMessage( nullptr, _( "Error loading project footprint library table." ) );
372 }
373 }
374
375 return tbl;
376}
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
KICAD_T Type() override
Definition: fp_lib_table.h:101
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
Calls Store() and then writes the contents of the JSON document to a file.
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:257
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:202
@ FACE_PCB
pcbnew DSO
Definition: kiway.h:287
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
A PROJECT can hold stuff it knows nothing about, in the form of _ELEM derivatives.
Definition: project.h:73
std::map< wxString, wxString > m_TextVars
Definition: project_file.h:125
std::vector< wxString > m_PinnedFootprintLibs
The list of pinned footprint libraries.
Definition: project_file.h:123
std::vector< wxString > m_PinnedSymbolLibs
Below are project-level settings that have not been moved to a dedicated file.
Definition: project_file.h:120
PROJECT_FILE * m_projectFile
Backing store for project data – owned by SETTINGS_MANAGER.
Definition: project.h:329
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:129
void UnpinLibrary(const wxString &aLibrary, bool isSymbolLibrary)
Definition: project.cpp:192
RSTRING_T
Retain a number of project specific wxStrings, enumerated here:
Definition: project.h:180
std::map< KIID, wxString > m_sheetNames
Definition: project.h:334
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:135
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:147
virtual const wxString SymbolLibTableName() const
Return the path and file name of this projects symbol library table.
Definition: project.cpp:159
virtual ~PROJECT()
Definition: project.cpp:66
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:339
virtual void ApplyTextVars(const std::map< wxString, wxString > &aVarsMap)
Applies the given var map, it will create or update existing vars.
Definition: project.cpp:90
virtual void ElemsClear()
Delete all the _ELEMs and set their pointers to NULL.
Definition: project.cpp:55
void PinLibrary(const wxString &aLibrary, bool isSymbolLibrary)
Definition: project.cpp:171
virtual bool TextVarResolver(wxString *aToken) const
Definition: project.cpp:72
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
virtual const wxString GetSheetName(const KIID &aSheetID)
Return the name of the sheet identified by the given UUID.
Definition: project.cpp:254
wxString m_rstrings[RSTRING_COUNT]
Definition: project.h:337
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition: project.cpp:165
virtual _ELEM * GetElem(ELEM_T aIndex)
Get and set the elements for this project.
Definition: project.cpp:299
_ELEM * m_elems[ELEM_COUNT]
Definition: project.h:340
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:309
virtual void SetRString(RSTRING_T aStringId, const wxString &aString)
Store a "retained string", which is any session and project specific string identified in enum RSTRIN...
Definition: project.cpp:269
wxFileName m_project_name
<fullpath>/<basename>.pro
Definition: project.h:321
void Clear()
Clear the _ELEMs and RSTRINGs.
Definition: project.h:256
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition: project.cpp:320
const wxString libTableName(const wxString &aLibTableName) const
Return the full path and file name of the project specific library table aLibTableName.
Definition: project.cpp:209
virtual void setProjectFullName(const wxString &aFullPathAndName)
Set the full directory, basename, and extension of the project.
Definition: project.cpp:105
virtual const wxString GetProjectDirectory() const
Return the full path of the project DIRECTORY.
Definition: project.cpp:141
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:84
PROJECT()
Definition: project.cpp:44
virtual const wxString & GetRString(RSTRING_T aStringId)
Return a "retained string", which is any session and project specific string identified in enum RSTRI...
Definition: project.cpp:280
ELEM_T
The set of #_ELEMs that a PROJECT can hold.
Definition: project.h:222
@ ELEM_FPTBL
Definition: project.h:223
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:153
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:305
This file is part of the common library.
#define _(s)
static const std::string ProjectFileExtension
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
@ KIFACE_NEW_FOOTPRINT_TABLE
Return a new FP_LIB_TABLE with the global table installed as a fallback.
Definition: kiface_ids.h:46
This file contains miscellaneous commonly used macros and functions.
wxString GetUserConfigPath()
Retrieves the operating system specific path for a user's configuration store.
void delete_matching(_Container &__c, _Value __value)
Covers for the horrifically named std::remove and std::remove_if (neither of which remove anything).
Definition: kicad_algo.h:165
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
SETTINGS_MANAGER * GetSettingsManager()
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:391
std::vector< wxString > pinned_fp_libs
std::vector< wxString > pinned_symbol_libs
void * IfaceOrAddress(int aDataId) override
Return a pointer to the requested object.
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:151
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
wxLogTrace helper definitions.
@ FP_LIB_TABLE_T
Definition: typeinfo.h:239
Definition of file extensions used in Kicad.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39