KiCad PCB EDA Suite
Loading...
Searching...
No Matches
fp_lib_table.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) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2012 Wayne Stambaugh <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26
27#include <kiface_base.h>
28#include <env_vars.h>
29#include <footprint_info.h>
30#include <lib_id.h>
31#include <lib_table_lexer.h>
32#include <paths.h>
33#include <pgm_base.h>
34#include <search_stack.h>
37#include <systemdirsappend.h>
38#include <fp_lib_table.h>
39#include <footprint.h>
40
41#include <wx/dir.h>
42#include <wx/hash.h>
43
44#define OPT_SEP '|'
45
46using namespace LIB_TABLE_T;
47
48
50{
51 return LIB_TABLE_ROW::operator == ( aRow ) && type == aRow.type;
52}
53
54
55void FP_LIB_TABLE_ROW::SetType( const wxString& aType )
56{
58
59 if( PCB_IO_MGR::PCB_FILE_T( -1 ) == type )
61
62 plugin.reset();
63}
64
65
67{
68 if( plugin )
69 return plugin->CanReadLibrary( GetFullURI( true ) );
70
71 return false;
72}
73
74
76 LIB_TABLE( aFallBackTable )
77{
78 // not copying fall back, simply search aFallBackTable separately
79 // if "nickName not found".
80}
81
82
83void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
84{
85 T tok;
86 wxString errMsg; // to collect error messages
87
88 // This table may be nested within a larger s-expression, or not.
89 // Allow for parser of that optional containing s-expression to have looked ahead.
90 if( in->CurTok() != T_fp_lib_table )
91 {
92 in->NeedLEFT();
93
94 if( ( tok = in->NextTok() ) != T_fp_lib_table )
95 in->Expecting( T_fp_lib_table );
96 }
97
98 while( ( tok = in->NextTok() ) != T_RIGHT )
99 {
100 std::unique_ptr<FP_LIB_TABLE_ROW> row = std::make_unique<FP_LIB_TABLE_ROW>();
101
102 if( tok == T_EOF )
103 in->Expecting( T_RIGHT );
104
105 if( tok != T_LEFT )
106 in->Expecting( T_LEFT );
107
108 // in case there is a "row integrity" error, tell where later.
109 int lineNum = in->CurLineNumber();
110 tok = in->NextTok();
111
112 // Optionally parse the current version number
113 if( tok == T_version )
114 {
115 in->NeedNUMBER( "version" );
116 m_version = std::stoi( in->CurText() );
117 in->NeedRIGHT();
118 continue;
119 }
120
121 if( tok != T_lib )
122 in->Expecting( T_lib );
123
124 // (name NICKNAME)
125 in->NeedLEFT();
126
127 if( ( tok = in->NextTok() ) != T_name )
128 in->Expecting( T_name );
129
130 in->NeedSYMBOLorNUMBER();
131
132 row->SetNickName( in->FromUTF8() );
133
134 in->NeedRIGHT();
135
136 // After (name), remaining (lib) elements are order independent, and in
137 // some cases optional.
138 bool sawType = false;
139 bool sawOpts = false;
140 bool sawDesc = false;
141 bool sawUri = false;
142 bool sawDisabled = false;
143
144 while( ( tok = in->NextTok() ) != T_RIGHT )
145 {
146 if( tok == T_EOF )
147 in->Unexpected( T_EOF );
148
149 if( tok != T_LEFT )
150 in->Expecting( T_LEFT );
151
152 tok = in->NeedSYMBOLorNUMBER();
153
154 switch( tok )
155 {
156 case T_uri:
157 if( sawUri )
158 in->Duplicate( tok );
159
160 sawUri = true;
161 in->NeedSYMBOLorNUMBER();
162 row->SetFullURI( in->FromUTF8() );
163 break;
164
165 case T_type:
166 if( sawType )
167 in->Duplicate( tok );
168
169 sawType = true;
170 in->NeedSYMBOLorNUMBER();
171 row->SetType( in->FromUTF8() );
172 break;
173
174 case T_options:
175 if( sawOpts )
176 in->Duplicate( tok );
177
178 sawOpts = true;
179 in->NeedSYMBOLorNUMBER();
180 row->SetOptions( in->FromUTF8() );
181 break;
182
183 case T_descr:
184 if( sawDesc )
185 in->Duplicate( tok );
186
187 sawDesc = true;
188 in->NeedSYMBOLorNUMBER();
189 row->SetDescr( in->FromUTF8() );
190 break;
191
192 case T_disabled:
193 if( sawDisabled )
194 in->Duplicate( tok );
195
196 sawDisabled = true;
197 row->SetEnabled( false );
198 break;
199
200 case T_hidden:
201 // Hiding footprint libraries is not yet supported. Unclear what path can set this
202 // attribute, but clear it on load.
203 row->SetVisible();
204 break;
205
206 default:
207 in->Unexpected( tok );
208 }
209
210 in->NeedRIGHT();
211 }
212
213 if( !sawType )
214 in->Expecting( T_type );
215
216 if( !sawUri )
217 in->Expecting( T_uri );
218
219 // All nickNames within this table fragment must be unique, so we do not use doReplace
220 // in doInsertRow(). (However a fallBack table can have a conflicting nickName and ours
221 // will supersede that one since in FindLib() we search this table before any fall back.)
222 wxString nickname = row->GetNickName(); // store it to be able to used it
223 // after row deletion if an error occurs
224 bool doReplace = false;
225 LIB_TABLE_ROW* tmp = row.release();
226
227 if( !doInsertRow( tmp, doReplace ) )
228 {
229 delete tmp; // The table did not take ownership of the row.
230
231 wxString msg = wxString::Format( _( "Duplicate library nickname '%s' found in "
232 "footprint library table file line %d." ),
233 nickname,
234 lineNum );
235
236 if( !errMsg.IsEmpty() )
237 errMsg << '\n';
238
239 errMsg << msg;
240 }
241 }
242
243 if( !errMsg.IsEmpty() )
244 THROW_IO_ERROR( errMsg );
245}
246
247
248bool FP_LIB_TABLE::operator==( const FP_LIB_TABLE& aFpTable ) const
249{
250 if( m_rows.size() == aFpTable.m_rows.size() )
251 {
252 for( unsigned i = 0; i < m_rows.size(); ++i )
253 {
254 if( (FP_LIB_TABLE_ROW&)m_rows[i] != (FP_LIB_TABLE_ROW&)aFpTable.m_rows[i] )
255 return false;
256 }
257
258 return true;
259 }
260
261 return false;
262}
263
264
265void FP_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
266{
267 aOutput->Print( aIndentLevel, "(fp_lib_table\n" );
268 aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
269
270 for( LIB_TABLE_ROWS_CITER it = m_rows.begin(); it != m_rows.end(); ++it )
271 it->Format( aOutput, aIndentLevel+1 );
272
273 aOutput->Print( aIndentLevel, ")\n" );
274}
275
276
277long long FP_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
278{
279 long long hash = 0;
280
281 if( aNickname )
282 {
283 const FP_LIB_TABLE_ROW* row = FindRow( *aNickname, true );
284
285 wxCHECK( row && row->plugin, hash );
286
287 return row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) ) +
288 wxHashTable::MakeKey( *aNickname );
289 }
290
291 for( const wxString& nickname : GetLogicalLibs() )
292 {
293 const FP_LIB_TABLE_ROW* row = nullptr;
294
295 try
296 {
297 row = FindRow( nickname, true );
298 }
299 catch( ... )
300 {
301 // Do nothing if not found: just skip.
302 }
303
304 wxCHECK2( row && row->plugin, continue );
305
306 hash += row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) ) +
307 wxHashTable::MakeKey( nickname );
308 }
309
310 return hash;
311}
312
313
314void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname,
315 bool aBestEfforts )
316{
317 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
318 wxASSERT( row->plugin );
319
320 row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), aBestEfforts,
321 row->GetProperties() );
322}
323
324
325const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname, bool aCheckIfEnabled )
326{
327 FP_LIB_TABLE_ROW* row = static_cast<FP_LIB_TABLE_ROW*>( findRow( aNickname, aCheckIfEnabled ) );
328
329 if( !row )
330 {
331 // We don't generally show this string to the user (who is unlikely to know what
332 // "fp-lib-table" means), and translating it may produce Sentry KICAD-YP.
333 wxString msg = wxString::Format( wxS( "'%s' not found in fp-lib-table." ), aNickname );
334 THROW_IO_ERROR( msg );
335 }
336
337 // We've been 'lazy' up until now, but it cannot be deferred any longer; instantiate a
338 // PCB_IO of the proper kind if it is not already in this FP_LIB_TABLE_ROW.
339 if( !row->plugin )
340 row->setPlugin( PCB_IO_MGR::PluginFind( row->type ) );
341
342 return row;
343}
344
345
346static void setLibNickname( FOOTPRINT* aModule, const wxString& aNickname,
347 const wxString& aFootprintName )
348{
349 // The library cannot know its own name, because it might have been renamed or moved.
350 // Therefore footprints cannot know their own library nickname when residing in
351 // a footprint library.
352 // Only at this API layer can we tell the footprint about its actual library nickname.
353 if( aModule )
354 {
355 // remove "const"-ness, I really do want to set nickname without
356 // having to copy the LIB_ID and its two strings, twice each.
357 LIB_ID& fpid = (LIB_ID&) aModule->GetFPID();
358
359 // Catch any misbehaving plugin, which should be setting internal footprint name properly:
360 wxASSERT( aFootprintName == fpid.GetLibItemName().wx_str() );
361
362 // and clearing nickname
363 wxASSERT( !fpid.GetLibNickname().size() );
364
365 fpid.SetLibNickname( aNickname );
366 }
367}
368
369
370const FOOTPRINT* FP_LIB_TABLE::GetEnumeratedFootprint( const wxString& aNickname,
371 const wxString& aFootprintName )
372{
373 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
374 wxASSERT( row->plugin );
375
376 return row->plugin->GetEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
377 row->GetProperties() );
378}
379
380
381bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& aFootprintName )
382{
383 try
384 {
385 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
386 wxASSERT( row->plugin );
387
388 return row->plugin->FootprintExists( row->GetFullURI( true ), aFootprintName,
389 row->GetProperties() );
390 }
391 catch( ... )
392 {
393 return false;
394 }
395}
396
397
398FOOTPRINT* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname,
399 const wxString& aFootprintName, bool aKeepUUID )
400{
401 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
402 wxASSERT( row->plugin );
403
404 FOOTPRINT* ret = row->plugin->FootprintLoad( row->GetFullURI( true ), aFootprintName,
405 aKeepUUID, row->GetProperties() );
406
407 setLibNickname( ret, row->GetNickName(), aFootprintName );
408
409 return ret;
410}
411
412
414 const FOOTPRINT* aFootprint, bool aOverwrite )
415{
416 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
417 wxASSERT( row->plugin );
418
419 if( !aOverwrite )
420 {
421 // Try loading the footprint to see if it already exists, caller wants overwrite
422 // protection, which is atypical, not the default.
423
424 wxString fpname = aFootprint->GetFPID().GetLibItemName();
425
426 std::unique_ptr<FOOTPRINT> footprint( row->plugin->FootprintLoad( row->GetFullURI( true ),
427 fpname,
428 row->GetProperties() ) );
429
430 if( footprint.get() )
431 return SAVE_SKIPPED;
432 }
433
434 row->plugin->FootprintSave( row->GetFullURI( true ), aFootprint, row->GetProperties() );
435
436 return SAVE_OK;
437}
438
439
440void FP_LIB_TABLE::FootprintDelete( const wxString& aNickname, const wxString& aFootprintName )
441{
442 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
443 wxASSERT( row->plugin );
444 return row->plugin->FootprintDelete( row->GetFullURI( true ), aFootprintName,
445 row->GetProperties() );
446}
447
448
449bool FP_LIB_TABLE::IsFootprintLibWritable( const wxString& aNickname )
450{
451 try
452 {
453 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
454
455 if( !row || !row->plugin )
456 return false;
457
458 return row->plugin->IsLibraryWritable( row->GetFullURI( true ) );
459 }
460 catch( ... )
461 {
462 }
463
464 // aNickname not found, so the library is not writable
465 return false;
466}
467
468
469void FP_LIB_TABLE::FootprintLibDelete( const wxString& aNickname )
470{
471 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
472 wxASSERT( row->plugin );
473 row->plugin->DeleteLibrary( row->GetFullURI( true ), row->GetProperties() );
474}
475
476
477void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
478{
479 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
480 wxASSERT( row->plugin );
481 row->plugin->CreateLibrary( row->GetFullURI( true ), row->GetProperties() );
482}
483
484
486 bool aKeepUUID )
487{
488 wxString nickname = aFootprintId.GetLibNickname();
489 wxString fpname = aFootprintId.GetLibItemName();
490
491 if( nickname.size() )
492 {
493 return FootprintLoad( nickname, fpname, aKeepUUID );
494 }
495
496 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
497 else
498 {
499 std::vector<wxString> nicks = GetLogicalLibs();
500
501 // Search each library going through libraries alphabetically.
502 for( unsigned i = 0; i < nicks.size(); ++i )
503 {
504 // FootprintLoad() returns NULL on not found, does not throw exception
505 // unless there's an IO_ERROR.
506 FOOTPRINT* ret = FootprintLoad( nicks[i], fpname, aKeepUUID );
507
508 if( ret )
509 return ret;
510 }
511
512 return nullptr;
513 }
514}
515
516
518{
519 return ENV_VAR::GetVersionedEnvVarName( wxS( "FOOTPRINT_DIR" ) );
520}
521
522
523class PCM_FP_LIB_TRAVERSER final : public wxDirTraverser
524{
525public:
526 explicit PCM_FP_LIB_TRAVERSER( const wxString& aPath, FP_LIB_TABLE& aTable,
527 const wxString& aPrefix ) :
528 m_lib_table( aTable ),
529 m_path_prefix( aPath ),
530 m_lib_prefix( aPrefix )
531 {
532 wxFileName f( aPath, wxS( "" ) );
533 m_prefix_dir_count = f.GetDirCount();
534 }
535
536 wxDirTraverseResult OnFile( const wxString& aFilePath ) override { return wxDIR_CONTINUE; }
537
538 wxDirTraverseResult OnDir( const wxString& dirPath ) override
539 {
540 wxFileName dir = wxFileName::DirName( dirPath );
541
542 // consider a directory to be a lib if it's name ends with .pretty and
543 // it is under $KICADn_3RD_PARTY/footprints/<pkgid>/ i.e. has nested level of at least +3
544 if( dirPath.EndsWith( wxS( ".pretty" ) ) && dir.GetDirCount() >= m_prefix_dir_count + 3 )
545 {
546 wxString versionedPath = wxString::Format(
547 wxS( "${%s}" ), ENV_VAR::GetVersionedEnvVarName( wxS( "3RD_PARTY" ) ) );
548
549 wxArrayString parts = dir.GetDirs();
550 parts.RemoveAt( 0, m_prefix_dir_count );
551 parts.Insert( versionedPath, 0 );
552
553 wxString libPath = wxJoin( parts, '/' );
554
555 if( !m_lib_table.HasLibraryWithPath( libPath ) )
556 {
557 wxString name = parts.Last().substr( 0, parts.Last().length() - 7 );
558 wxString nickname = wxString::Format( wxS( "%s%s" ), m_lib_prefix, name );
559
560 if( m_lib_table.HasLibrary( nickname ) )
561 {
562 int increment = 1;
563 do
564 {
565 nickname = wxString::Format( wxS( "%s%s_%d" ), m_lib_prefix, name,
566 increment );
567 increment++;
568 } while( m_lib_table.HasLibrary( nickname ) );
569 }
570
572 new FP_LIB_TABLE_ROW( nickname, libPath, wxT( "KiCad" ), wxEmptyString,
573 _( "Added by Plugin and Content Manager" ) ) );
574 }
575 }
576
577 return wxDIR_CONTINUE;
578 }
579
580private:
583 wxString m_lib_prefix;
585};
586
587
589{
590 bool tableExists = true;
591 wxFileName fn = GetGlobalTableFileName();
592
593 if( !fn.FileExists() )
594 {
595 tableExists = false;
596
597 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
598 {
599 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
600 fn.GetPath() ) );
601 }
602
603 // Attempt to copy the default global file table from the KiCad
604 // template folder to the user's home configuration path.
605 SEARCH_STACK ss;
606
607 SystemDirsAppend( &ss );
608
609 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
610 std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( envVars, wxT( "TEMPLATE_DIR" ) );
611
612 if( v && !v->IsEmpty() )
613 ss.AddPaths( *v, 0 );
614
615 wxString fileName = ss.FindValidPath( FILEEXT::FootprintLibraryTableFileName );
616
617 // The fallback is to create an empty global footprint table for the user to populate.
618 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
619 {
620 FP_LIB_TABLE emptyTable;
621
622 emptyTable.Save( fn.GetFullPath() );
623 }
624 }
625
626 aTable.Load( fn.GetFullPath() );
627
628 KICAD_SETTINGS* cfg = GetAppSettings<KICAD_SETTINGS>( "kicad" );
629 const ENV_VAR_MAP& env = Pgm().GetLocalEnvVariables();
630 wxString packagesPath;
631
632 if( std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( env, wxT( "3RD_PARTY" ) ) )
633 packagesPath = *v;
634
635 if( cfg && cfg->m_PcmLibAutoAdd )
636 {
637 // Scan for libraries in PCM packages directory
638
639 wxFileName d( packagesPath, wxS( "" ) );
640 d.AppendDir( wxS( "footprints" ) );
641
642 if( d.DirExists() )
643 {
644 PCM_FP_LIB_TRAVERSER traverser( packagesPath, aTable, cfg->m_PcmLibPrefix );
645 wxDir dir( d.GetPath() );
646
647 dir.Traverse( traverser );
648 }
649 }
650
651 if( cfg && cfg->m_PcmLibAutoRemove )
652 {
653 // Remove PCM libraries that no longer exist
654 std::vector<wxString> to_remove;
655
656 for( size_t i = 0; i < aTable.GetCount(); i++ )
657 {
658 LIB_TABLE_ROW& row = aTable.At( i );
659 wxString path = row.GetFullURI( true );
660
661 if( path.StartsWith( packagesPath ) && !wxDir::Exists( path ) )
662 to_remove.push_back( row.GetNickName() );
663 }
664
665 for( const wxString& nickName : to_remove )
666 aTable.RemoveRow( aTable.FindRow( nickName ) );
667 }
668
669 return tableExists;
670}
671
672
674{
675 wxFileName fn;
676
677 fn.SetPath( PATHS::GetUserSettingsPath() );
679
680 return fn.GetFullPath();
681}
const char * name
Definition: DXF_plotter.cpp:62
const LIB_ID & GetFPID() const
Definition: footprint.h:251
Hold a record identifying a library accessed by the appropriate footprint library #PLUGIN object in t...
Definition: fp_lib_table.h:42
void setPlugin(PCB_IO *aPlugin)
Definition: fp_lib_table.h:87
void SetType(const wxString &aType) override
Change the type represented by this row.
bool LibraryExists() const override
IO_RELEASER< PCB_IO > plugin
Definition: fp_lib_table.h:95
bool operator==(const FP_LIB_TABLE_ROW &aRow) const
PCB_IO_MGR::PCB_FILE_T type
Definition: fp_lib_table.h:96
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
void FootprintDelete(const wxString &aNickname, const wxString &aFootprintName)
Delete the aFootprintName from the library given by aNickname.
static bool LoadGlobalTable(FP_LIB_TABLE &aTable)
Load the global footprint library table into aTable.
bool operator==(const FP_LIB_TABLE &aFpTable) const
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname, bool aBestEfforts)
Return a list of footprint names contained within the library given by aNickname.
void FootprintLibCreate(const wxString &aNickname)
FP_LIB_TABLE(FP_LIB_TABLE *aFallBackTable=nullptr)
Build a footprint library table by pre-pending this table fragment in front of aFallBackTable.
const FOOTPRINT * GetEnumeratedFootprint(const wxString &aNickname, const wxString &aFootprintName)
A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management.
static const wxString GlobalPathEnvVariableName()
Return the name of the environment variable used to hold the directory of locally installed "KiCad sp...
FOOTPRINT * FootprintLoadWithOptionalNickname(const LIB_ID &aFootprintId, bool aKeepUUID=false)
Load a footprint having aFootprintId with possibly an empty nickname.
long long GenerateTimestamp(const wxString *aNickname)
Generate a hashed timestamp representing the last-mod-times of the library indicated by aNickname,...
void FootprintLibDelete(const wxString &aNickname)
bool FootprintExists(const wxString &aNickname, const wxString &aFootprintName)
Indicates whether or not the given footprint already exists in the given library.
virtual void Parse(LIB_TABLE_LEXER *aLexer) override
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
bool IsFootprintLibWritable(const wxString &aNickname)
Return true if the library given by aNickname is writable.
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
SAVE_T
The set of return values from FootprintSave() below.
Definition: fp_lib_table.h:191
FOOTPRINT * FootprintLoad(const wxString &aNickname, const wxString &aFootprintName, bool aKeepUUID=false)
Load a footprint having aFootprintName from the library given by aNickname.
SAVE_T FootprintSave(const wxString &aNickname, const FOOTPRINT *aFootprint, bool aOverwrite=true)
Write aFootprint to an existing library given by aNickname.
static wxString GetGlobalTableFileName()
wxString m_PcmLibPrefix
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition: lib_id.cpp:100
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
const std::map< std::string, UTF8 > * GetProperties() const
Return the constant #PROPERTIES for this library (LIB_TABLE_ROW).
const wxString & GetNickName() const
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
bool operator==(const LIB_TABLE_ROW &r) const
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
int m_version
Versioning to handle importing old tables.
LIB_TABLE_ROW & At(unsigned aIndex)
Get the 'n'th LIB_TABLE_ROW object.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
LIB_TABLE_ROWS m_rows
Owning set of rows.
bool doInsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Performs the mechanics of inserting a row, but without locking or reindexing.
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
bool HasLibraryWithPath(const wxString &aPath) const
Test for the existence of aPath in the library table.
bool RemoveRow(const LIB_TABLE_ROW *aRow)
Removes a row from the table and frees the pointer.
unsigned GetCount() const
Get the number of rows contained in the table.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
LIB_TABLE_ROW * findRow(const wxString &aNickname, bool aCheckIfEnabled=false) const
Return a LIB_TABLE_ROW if aNickname is found in this table or in any chained fallBack table fragment,...
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:322
int PRINTF_FUNC_N Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:463
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition: paths.cpp:592
static PCB_IO * PluginFind(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: pcb_io_mgr.cpp:68
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Return the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
Definition: pcb_io_mgr.cpp:93
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:56
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: pcb_io_mgr.h:58
PCM_FP_LIB_TRAVERSER(const wxString &aPath, FP_LIB_TABLE &aTable, const wxString &aPrefix)
wxDirTraverseResult OnFile(const wxString &aFilePath) override
wxDirTraverseResult OnDir(const wxString &dirPath) override
FP_LIB_TABLE & m_lib_table
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition: pgm_base.cpp:811
Look for files in a number of paths.
Definition: search_stack.h:43
void AddPaths(const wxString &aPaths, int aIndex=-1)
Insert or append path(s).
std::string::size_type size() const
Definition: utf8.h:117
wxString wx_str() const
Definition: utf8.cpp:45
static void setLibNickname(DESIGN_BLOCK *aModule, const wxString &aNickname, const wxString &aDesignBlockName)
#define _(s)
Functions related to environment variables, including help functions.
static void setLibNickname(FOOTPRINT *aModule, const wxString &aNickname, const wxString &aFootprintName)
static const std::string FootprintLibraryTableFileName
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER
KICOMMON_API std::optional< wxString > GetVersionedEnvVarValue(const std::map< wxString, ENV_VAR_ITEM > &aMap, const wxString &aBaseName)
Attempt to retrieve the value of a versioned environment variable, such as KICAD8_TEMPLATE_DIR.
Definition: env_vars.cpp:86
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
Definition: env_vars.cpp:77
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:902
see class PGM_BASE
void SystemDirsAppend(SEARCH_STACK *aSearchStack)
Append system places to aSearchStack in a platform specific way and pertinent to KiCad programs.
System directories search utilities.