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 The 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/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 <lockfile.h>
37#include <macros.h>
38#include <project.h>
40#include <trace_helpers.h>
44#include <title_block.h>
45
46
48 m_readOnly( false ),
49 m_textVarsTicker( 0 ),
50 m_netclassesTicker( 0 ),
51 m_projectFile( nullptr ),
52 m_localSettings( nullptr )
53{
54 m_elems.fill( nullptr );
55}
56
57
59{
60 // careful here, this should work, but the virtual destructor may not
61 // be in the same link image as PROJECT.
62 for( unsigned i = 0; i < m_elems.size(); ++i )
63 {
64 SetElem( static_cast<PROJECT::ELEM>( i ), nullptr );
65 }
66}
67
68
70{
71 elemsClear();
72}
73
74
75bool PROJECT::TextVarResolver( wxString* aToken ) const
76{
77 if( aToken->IsSameAs( wxT( "PROJECTNAME" ) ) )
78 {
79 *aToken = GetProjectName();
80 return true;
81 }
82 else if( aToken->IsSameAs( wxT( "CURRENT_DATE" ) ) )
83 {
85 return true;
86 }
87 else if( GetTextVars().count( *aToken ) > 0 )
88 {
89 *aToken = GetTextVars().at( *aToken );
90 return true;
91 }
92
93 return false;
94}
95
96
97std::map<wxString, wxString>& PROJECT::GetTextVars() const
98{
100}
101
102
103void PROJECT::ApplyTextVars( const std::map<wxString, wxString>& aVarsMap )
104{
105 if( aVarsMap.size() == 0 )
106 return;
107
108 std::map<wxString, wxString>& existingVarsMap = GetTextVars();
109
110 for( const auto& var : aVarsMap )
111 {
112 // create or update the existing vars
113 existingVarsMap[var.first] = var.second;
114 }
115}
116
117
118void PROJECT::setProjectFullName( const wxString& aFullPathAndName )
119{
120 // Compare paths, rather than inodes, to be less surprising to the user.
121 // Create a temporary wxFileName to normalize the path
122 wxFileName candidate_path( aFullPathAndName );
123
124 // Edge transitions only. This is what clears the project
125 // data using the Clear() function.
126 if( m_project_name.GetFullPath() != candidate_path.GetFullPath() )
127 {
128 Clear(); // clear the data when the project changes.
129
130 wxLogTrace( tracePathsAndFiles, "%s: old:'%s' new:'%s'", __func__,
131 TO_UTF8( GetProjectFullName() ), TO_UTF8( aFullPathAndName ) );
132
133 m_project_name = aFullPathAndName;
134
135 wxASSERT( m_project_name.IsAbsolute() );
136
137 wxASSERT( m_project_name.GetExt() == FILEEXT::ProjectFileExtension );
138 }
139}
140
141
142const wxString PROJECT::GetProjectFullName() const
143{
144 return m_project_name.GetFullPath();
145}
146
147
148const wxString PROJECT::GetProjectPath() const
149{
150 return m_project_name.GetPathWithSep();
151}
152
153
154const wxString PROJECT::GetProjectDirectory() const
155{
156 return m_project_name.GetPath();
157}
158
159
160const wxString PROJECT::GetProjectName() const
161{
162 return m_project_name.GetName();
163}
164
165
167{
168 return m_project_name.GetName().IsEmpty();
169}
170
171
172const wxString PROJECT::SymbolLibTableName() const
173{
175}
176
177
178const wxString PROJECT::FootprintLibTblName() const
179{
181}
182
183
184const wxString PROJECT::DesignBlockLibTblName() const
185{
187}
188
189
190void PROJECT::PinLibrary( const wxString& aLibrary, enum LIB_TYPE_T aLibType )
191{
193 std::vector<wxString>* pinnedLibsCfg = nullptr;
194 std::vector<wxString>* pinnedLibsFile = nullptr;
195
196 switch( aLibType )
197 {
199 pinnedLibsFile = &m_projectFile->m_PinnedSymbolLibs;
200 pinnedLibsCfg = &cfg->m_Session.pinned_symbol_libs;
201 break;
203 pinnedLibsFile = &m_projectFile->m_PinnedFootprintLibs;
204 pinnedLibsCfg = &cfg->m_Session.pinned_fp_libs;
205 break;
207 pinnedLibsFile = &m_projectFile->m_PinnedDesignBlockLibs;
208 pinnedLibsCfg = &cfg->m_Session.pinned_design_block_libs;
209 break;
210 default:
211 wxFAIL_MSG( "Cannot pin library: invalid library type" );
212 return;
213 }
214
215 if( !alg::contains( *pinnedLibsFile, aLibrary ) )
216 pinnedLibsFile->push_back( aLibrary );
217
219
220 if( !alg::contains( *pinnedLibsCfg, aLibrary ) )
221 pinnedLibsCfg->push_back( aLibrary );
222
223 cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
224}
225
226
227void PROJECT::UnpinLibrary( const wxString& aLibrary, enum LIB_TYPE_T aLibType )
228{
230 std::vector<wxString>* pinnedLibsCfg = nullptr;
231 std::vector<wxString>* pinnedLibsFile = nullptr;
232
233 switch( aLibType )
234 {
236 pinnedLibsFile = &m_projectFile->m_PinnedSymbolLibs;
237 pinnedLibsCfg = &cfg->m_Session.pinned_symbol_libs;
238 break;
240 pinnedLibsFile = &m_projectFile->m_PinnedFootprintLibs;
241 pinnedLibsCfg = &cfg->m_Session.pinned_fp_libs;
242 break;
244 pinnedLibsFile = &m_projectFile->m_PinnedDesignBlockLibs;
245 pinnedLibsCfg = &cfg->m_Session.pinned_design_block_libs;
246 break;
247 default:
248 wxFAIL_MSG( "Cannot unpin library: invalid library type" );
249 return;
250 }
251
252 alg::delete_matching( *pinnedLibsFile, aLibrary );
254
255 alg::delete_matching( *pinnedLibsCfg, aLibrary );
256 cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
257}
258
259
260const wxString PROJECT::libTableName( const wxString& aLibTableName ) const
261{
262 wxFileName fn = GetProjectFullName();
263 wxString path = fn.GetPath();
264
265 // if there's no path to the project name, or the name as a whole is bogus or its not
266 // write-able then use a template file.
267 if( !fn.GetDirCount() || !fn.IsOk() || !wxFileName::IsDirWritable( path ) )
268 {
269 // return a template filename now.
270
271 // this next line is likely a problem now, since it relies on an
272 // application title which is no longer constant or known. This next line needs
273 // to be re-thought out.
274
275#ifdef __WXMAC__
276 fn.AssignDir( KIPLATFORM::ENV::GetUserConfigPath() );
277#else
278 // don't pollute home folder, temp folder seems to be more appropriate
279 fn.AssignDir( wxStandardPaths::Get().GetTempDir() );
280#endif
281
282#if defined( __WINDOWS__ )
283 fn.AppendDir( wxT( "kicad" ) );
284#endif
285
286 /*
287 * The library table name used when no project file is passed to the appropriate
288 * code. This is used temporarily to store the project specific library table
289 * until the project file being edited is saved. It is then moved to the correct
290 * file in the folder where the project file is saved.
291 */
292 fn.SetName( wxS( "prj-" ) + aLibTableName );
293 }
294 else // normal path.
295 {
296 fn.SetName( aLibTableName );
297 }
298
299 fn.ClearExt();
300
301 return fn.GetFullPath();
302}
303
304
305const wxString PROJECT::GetSheetName( const KIID& aSheetID )
306{
307 if( m_sheetNames.empty() )
308 {
309 for( const std::pair<KIID, wxString>& pair : GetProjectFile().GetSheets() )
310 m_sheetNames[pair.first] = pair.second;
311 }
312
313 if( m_sheetNames.count( aSheetID ) )
314 return m_sheetNames.at( aSheetID );
315 else
316 return aSheetID.AsString();
317}
318
319
320void PROJECT::SetRString( RSTRING_T aIndex, const wxString& aString )
321{
322 unsigned ndx = unsigned( aIndex );
323
324 if( ndx < m_rstrings.size() )
325 m_rstrings[ndx] = aString;
326 else
327 wxASSERT( 0 ); // bad index
328}
329
330
331const wxString& PROJECT::GetRString( RSTRING_T aIndex )
332{
333 unsigned ndx = unsigned( aIndex );
334
335 if( ndx < m_rstrings.size() )
336 {
337 return m_rstrings[ndx];
338 }
339 else
340 {
341 static wxString no_cookie_for_you;
342
343 wxASSERT( 0 ); // bad index
344
345 return no_cookie_for_you;
346 }
347}
348
349
351{
352 // This is virtual, so implement it out of line
353
354 if( static_cast<unsigned>( aIndex ) < m_elems.size() )
355 return m_elems[static_cast<unsigned>( aIndex )];
356
357 return nullptr;
358}
359
360
362{
363 // This is virtual, so implement it out of line
364 if( static_cast<unsigned>( aIndex ) < m_elems.size() )
365 {
366 delete m_elems[static_cast<unsigned>(aIndex)];
367 m_elems[static_cast<unsigned>( aIndex )] = aElem;
368 }
369}
370
371
372const wxString PROJECT::AbsolutePath( const wxString& aFileName ) const
373{
374 wxFileName fn = aFileName;
375
376 // Paths which start with an unresolved variable reference are more likely to be
377 // absolute than relative.
378 if( aFileName.StartsWith( wxT( "${" ) ) )
379 return aFileName;
380
381 if( !fn.IsAbsolute() )
382 {
383 wxString pro_dir = wxPathOnly( GetProjectFullName() );
384 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS, pro_dir );
385 }
386
387 return fn.GetFullPath();
388}
389
390
392{
393 // This is a lazy loading function, it loads the project specific table when
394 // that table is asked for, not before.
395
397
398 if( tbl )
399 {
400 wxASSERT( tbl->ProjectElementType() == PROJECT::ELEM::FPTBL );
401 }
402 else
403 {
404 try
405 {
406 // Build a new project specific FP_LIB_TABLE with the global table as a fallback.
407 // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
408 // stack this way, all using the same global fallback table.
409 KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_PCB );
410
412 tbl->Load( FootprintLibTblName() );
413
415 }
416 catch( const IO_ERROR& ioe )
417 {
418 DisplayErrorMessage( nullptr, _( "Error loading project footprint library table." ),
419 ioe.What() );
420 }
421 catch( ... )
422 {
423 DisplayErrorMessage( nullptr, _( "Error loading project footprint library table." ) );
424 }
425 }
426
427 return tbl;
428}
429
430
432{
433 // This is a lazy loading function, it loads the project specific table when
434 // that table is asked for, not before.
435
437
438 if( tbl )
439 {
441 }
442 else
443 {
444 try
445 {
447 tbl->Load( DesignBlockLibTblName() );
448
450 }
451 catch( const IO_ERROR& ioe )
452 {
453 DisplayErrorMessage( nullptr, _( "Error loading project design block library table." ),
454 ioe.What() );
455 }
456 catch( ... )
457 {
458 DisplayErrorMessage( nullptr,
459 _( "Error loading project design block library table." ) );
460 }
461 }
462
463 return tbl;
464}
465
466
468{
469 m_project_lock.reset( aLockFile );
470}
471
472
474{
475 return m_project_lock.get();
476}
PROJECT::ELEM ProjectElementType() override
static DESIGN_BLOCK_LIB_TABLE & GetGlobalLibTable()
PROJECT::ELEM ProjectElementType() override
Definition: fp_lib_table.h:103
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:246
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:285
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:198
@ FACE_PCB
pcbnew DSO
Definition: kiway.h:293
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:556
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:125
A PROJECT can hold stuff it knows nothing about, in the form of _ELEM derivatives.
Definition: project.h:97
std::map< wxString, wxString > m_TextVars
Definition: project_file.h:147
std::vector< wxString > m_PinnedDesignBlockLibs
The list of pinned design block libraries.
Definition: project_file.h:145
std::vector< wxString > m_PinnedFootprintLibs
The list of pinned footprint libraries.
Definition: project_file.h:142
std::vector< wxString > m_PinnedSymbolLibs
Below are project-level settings that have not been moved to a dedicated file.
Definition: project_file.h:139
PROJECT_FILE * m_projectFile
Backing store for project data – owned by SETTINGS_MANAGER.
Definition: project.h:362
void SetProjectLock(LOCKFILE *aLockFile)
Definition: project.cpp:467
LOCKFILE * GetProjectLock() const
Definition: project.cpp:473
LIB_TYPE_T
Definition: project.h:193
@ SYMBOL_LIB
Definition: project.h:194
@ DESIGN_BLOCK_LIB
Definition: project.h:196
@ FOOTPRINT_LIB
Definition: project.h:195
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:142
virtual void SetElem(PROJECT::ELEM aIndex, _ELEM *aElem)
Definition: project.cpp:361
virtual const wxString DesignBlockLibTblName() const
Return the path and file name of this projects design block library table.
Definition: project.cpp:184
void PinLibrary(const wxString &aLibrary, enum LIB_TYPE_T aLibType)
Definition: project.cpp:190
RSTRING_T
Retain a number of project specific wxStrings, enumerated here:
Definition: project.h:218
std::map< KIID, wxString > m_sheetNames
Definition: project.h:367
std::unique_ptr< LOCKFILE > m_project_lock
Lock.
Definition: project.h:376
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:148
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:160
virtual const wxString SymbolLibTableName() const
Return the path and file name of this projects symbol library table.
Definition: project.cpp:172
virtual _ELEM * GetElem(PROJECT::ELEM aIndex)
Get and set the elements for this project.
Definition: project.cpp:350
virtual DESIGN_BLOCK_LIB_TABLE * DesignBlockLibs()
Return the table of design block libraries.
Definition: project.cpp:431
virtual ~PROJECT()
Definition: project.cpp:69
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:391
virtual void ApplyTextVars(const std::map< wxString, wxString > &aVarsMap)
Applies the given var map, it will create or update existing vars.
Definition: project.cpp:103
virtual bool TextVarResolver(wxString *aToken) const
Definition: project.cpp:75
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:204
virtual const wxString GetSheetName(const KIID &aSheetID)
Return the name of the sheet identified by the given UUID.
Definition: project.cpp:305
std::array< _ELEM *, static_cast< unsigned int >(PROJECT::ELEM::COUNT)> m_elems
Definition: project.h:373
virtual void elemsClear()
Delete all the _ELEMs and set their pointers to NULL.
Definition: project.cpp:58
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition: project.cpp:178
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:320
wxFileName m_project_name
<fullpath>/<basename>.pro
Definition: project.h:354
void Clear()
Clear the _ELEMs and RSTRINGs.
Definition: project.h:274
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:372
void UnpinLibrary(const wxString &aLibrary, enum LIB_TYPE_T aLibType)
Definition: project.cpp:227
std::array< wxString, RSTRING_COUNT > m_rstrings
Definition: project.h:370
const wxString libTableName(const wxString &aLibTableName) const
Return the full path and file name of the project specific library table aLibTableName.
Definition: project.cpp:260
virtual void setProjectFullName(const wxString &aFullPathAndName)
Set the full directory, basename, and extension of the project.
Definition: project.cpp:118
virtual const wxString GetProjectDirectory() const
Return the full path of the project DIRECTORY.
Definition: project.cpp:154
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:97
PROJECT()
Definition: project.cpp:47
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:331
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:166
ELEM
The set of #_ELEMs that a PROJECT can hold.
Definition: project.h:71
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
static wxString GetCurrentDate()
Definition: title_block.cpp:97
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:194
This file is part of the common library.
#define _(s)
static const std::string SymbolLibraryTableFileName
static const std::string ProjectFileExtension
static const std::string DesignBlockLibraryTableFileName
static const std::string FootprintLibraryTableFileName
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
File locking utilities.
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()
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:893
see class PGM_BASE
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:429
std::vector< wxString > pinned_design_block_libs
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:152
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
wxLogTrace helper definitions.
Definition of file extensions used in Kicad.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39