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 (C) 2012-2023 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
49static const wxChar global_tbl_name[] = wxT( "fp-lib-table" );
50
51
53{
54 return LIB_TABLE_ROW::operator == ( aRow ) && type == aRow.type;
55}
56
57
58void FP_LIB_TABLE_ROW::SetType( const wxString& aType )
59{
61
62 if( PCB_IO_MGR::PCB_FILE_T( -1 ) == type )
64
65 plugin.reset();
66}
67
68
70 LIB_TABLE( aFallBackTable )
71{
72 // not copying fall back, simply search aFallBackTable separately
73 // if "nickName not found".
74}
75
76
77void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
78{
79 T tok;
80 wxString errMsg; // to collect error messages
81
82 // This table may be nested within a larger s-expression, or not.
83 // Allow for parser of that optional containing s-epression to have looked ahead.
84 if( in->CurTok() != T_fp_lib_table )
85 {
86 in->NeedLEFT();
87
88 if( ( tok = in->NextTok() ) != T_fp_lib_table )
89 in->Expecting( T_fp_lib_table );
90 }
91
92 while( ( tok = in->NextTok() ) != T_RIGHT )
93 {
94 std::unique_ptr<FP_LIB_TABLE_ROW> row = std::make_unique<FP_LIB_TABLE_ROW>();
95
96 if( tok == T_EOF )
97 in->Expecting( T_RIGHT );
98
99 if( tok != T_LEFT )
100 in->Expecting( T_LEFT );
101
102 // in case there is a "row integrity" error, tell where later.
103 int lineNum = in->CurLineNumber();
104 tok = in->NextTok();
105
106 // Optionally parse the current version number
107 if( tok == T_version )
108 {
109 in->NeedNUMBER( "version" );
110 m_version = std::stoi( in->CurText() );
111 in->NeedRIGHT();
112 continue;
113 }
114
115 if( tok != T_lib )
116 in->Expecting( T_lib );
117
118 // (name NICKNAME)
119 in->NeedLEFT();
120
121 if( ( tok = in->NextTok() ) != T_name )
122 in->Expecting( T_name );
123
124 in->NeedSYMBOLorNUMBER();
125
126 row->SetNickName( in->FromUTF8() );
127
128 in->NeedRIGHT();
129
130 // After (name), remaining (lib) elements are order independent, and in
131 // some cases optional.
132 bool sawType = false;
133 bool sawOpts = false;
134 bool sawDesc = false;
135 bool sawUri = false;
136 bool sawDisabled = false;
137
138 while( ( tok = in->NextTok() ) != T_RIGHT )
139 {
140 if( tok == T_EOF )
141 in->Unexpected( T_EOF );
142
143 if( tok != T_LEFT )
144 in->Expecting( T_LEFT );
145
146 tok = in->NeedSYMBOLorNUMBER();
147
148 switch( tok )
149 {
150 case T_uri:
151 if( sawUri )
152 in->Duplicate( tok );
153 sawUri = true;
154 in->NeedSYMBOLorNUMBER();
155 row->SetFullURI( in->FromUTF8() );
156 break;
157
158 case T_type:
159 if( sawType )
160 in->Duplicate( tok );
161 sawType = true;
162 in->NeedSYMBOLorNUMBER();
163 row->SetType( in->FromUTF8() );
164 break;
165
166 case T_options:
167 if( sawOpts )
168 in->Duplicate( tok );
169 sawOpts = true;
170 in->NeedSYMBOLorNUMBER();
171 row->SetOptions( in->FromUTF8() );
172 break;
173
174 case T_descr:
175 if( sawDesc )
176 in->Duplicate( tok );
177 sawDesc = true;
178 in->NeedSYMBOLorNUMBER();
179 row->SetDescr( in->FromUTF8() );
180 break;
181
182 case T_disabled:
183 if( sawDisabled )
184 in->Duplicate( tok );
185 sawDisabled = true;
186 row->SetEnabled( false );
187 break;
188
189 case T_hidden:
190 // Hiding footprint libraries is not yet supported. Unclear what path can set this
191 // attribute, but clear it on load.
192 row->SetVisible();
193 break;
194
195 default:
196 in->Unexpected( tok );
197 }
198
199 in->NeedRIGHT();
200 }
201
202 if( !sawType )
203 in->Expecting( T_type );
204
205 if( !sawUri )
206 in->Expecting( T_uri );
207
208 // all nickNames within this table fragment must be unique, so we do not
209 // use doReplace in InsertRow(). (However a fallBack table can have a
210 // conflicting nickName and ours will supercede that one since in
211 // FindLib() we search this table before any fall back.)
212 wxString nickname = row->GetNickName(); // store it to be able to used it
213 // after row deletion if an error occurs
214 LIB_TABLE_ROW* tmp = row.release();
215
216 if( !InsertRow( tmp ) )
217 {
218 delete tmp; // The table did not take ownership of the row.
219
220 wxString msg = wxString::Format( _( "Duplicate library nickname '%s' found in "
221 "footprint library table file line %d." ),
222 nickname,
223 lineNum );
224
225 if( !errMsg.IsEmpty() )
226 errMsg << '\n';
227
228 errMsg << msg;
229 }
230 }
231
232 if( !errMsg.IsEmpty() )
233 THROW_IO_ERROR( errMsg );
234}
235
236
237bool FP_LIB_TABLE::operator==( const FP_LIB_TABLE& aFpTable ) const
238{
239 if( m_rows.size() == aFpTable.m_rows.size() )
240 {
241 for( unsigned i = 0; i < m_rows.size(); ++i )
242 {
243 if( (FP_LIB_TABLE_ROW&)m_rows[i] != (FP_LIB_TABLE_ROW&)aFpTable.m_rows[i] )
244 return false;
245 }
246
247 return true;
248 }
249
250 return false;
251}
252
253
254void FP_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
255{
256 aOutput->Print( aIndentLevel, "(fp_lib_table\n" );
257 aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
258
259 for( LIB_TABLE_ROWS_CITER it = m_rows.begin(); it != m_rows.end(); ++it )
260 it->Format( aOutput, aIndentLevel+1 );
261
262 aOutput->Print( aIndentLevel, ")\n" );
263}
264
265
266long long FP_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
267{
268 long long hash = 0;
269
270 if( aNickname )
271 {
272 const FP_LIB_TABLE_ROW* row = FindRow( *aNickname, true );
273
274 wxCHECK( row && row->plugin, hash );
275
276 return row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) ) +
277 wxHashTable::MakeKey( *aNickname );
278 }
279
280 for( const wxString& nickname : GetLogicalLibs() )
281 {
282 const FP_LIB_TABLE_ROW* row = nullptr;
283
284 try
285 {
286 row = FindRow( nickname, true );
287 }
288 catch( ... )
289 {
290 // Do nothing if not found: just skip.
291 }
292
293 wxCHECK2( row && row->plugin, continue );
294
295 hash += row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) ) +
296 wxHashTable::MakeKey( nickname );
297 }
298
299 return hash;
300}
301
302
303void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname,
304 bool aBestEfforts )
305{
306 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
307 wxASSERT( row->plugin );
308 row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), aBestEfforts,
309 row->GetProperties() );
310}
311
312
313void FP_LIB_TABLE::PrefetchLib( const wxString& aNickname )
314{
315 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
316 wxASSERT( row->plugin );
317 row->plugin->PrefetchLib( row->GetFullURI( true ), row->GetProperties() );
318}
319
320
321const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname, bool aCheckIfEnabled )
322{
323 FP_LIB_TABLE_ROW* row = static_cast<FP_LIB_TABLE_ROW*>( findRow( aNickname, aCheckIfEnabled ) );
324
325 if( !row )
326 {
327 // We don't generally show this string to the user (who is unlikely to know what
328 // "fp-lib-table" means), and translating it may produce Sentry KICAD-YP.
329 wxString msg = wxString::Format( wxS( "'%s' not found in fp-lib-table." ), aNickname );
330 THROW_IO_ERROR( msg );
331 }
332
333 // We've been 'lazy' up until now, but it cannot be deferred any longer; instantiate a
334 // PCB_IO of the proper kind if it is not already in this FP_LIB_TABLE_ROW.
335 if( !row->plugin )
336 row->setPlugin( PCB_IO_MGR::PluginFind( row->type ) );
337
338 return row;
339}
340
341
342static void setLibNickname( FOOTPRINT* aModule, const wxString& aNickname,
343 const wxString& aFootprintName )
344{
345 // The library cannot know its own name, because it might have been renamed or moved.
346 // Therefore footprints cannot know their own library nickname when residing in
347 // a footprint library.
348 // Only at this API layer can we tell the footprint about its actual library nickname.
349 if( aModule )
350 {
351 // remove "const"-ness, I really do want to set nickname without
352 // having to copy the LIB_ID and its two strings, twice each.
353 LIB_ID& fpid = (LIB_ID&) aModule->GetFPID();
354
355 // Catch any misbehaving plugin, which should be setting internal footprint name properly:
356 wxASSERT( aFootprintName == fpid.GetLibItemName().wx_str() );
357
358 // and clearing nickname
359 wxASSERT( !fpid.GetLibNickname().size() );
360
361 fpid.SetLibNickname( aNickname );
362 }
363}
364
365
366const FOOTPRINT* FP_LIB_TABLE::GetEnumeratedFootprint( const wxString& aNickname,
367 const wxString& aFootprintName )
368{
369 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
370 wxASSERT( row->plugin );
371
372 return row->plugin->GetEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
373 row->GetProperties() );
374}
375
376
377bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& aFootprintName )
378{
379 try
380 {
381 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
382 wxASSERT( row->plugin );
383
384 return row->plugin->FootprintExists( row->GetFullURI( true ), aFootprintName,
385 row->GetProperties() );
386 }
387 catch( ... )
388 {
389 return false;
390 }
391}
392
393
394FOOTPRINT* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname,
395 const wxString& aFootprintName, bool aKeepUUID )
396{
397 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
398 wxASSERT( row->plugin );
399
400 FOOTPRINT* ret = row->plugin->FootprintLoad( row->GetFullURI( true ), aFootprintName,
401 aKeepUUID, row->GetProperties() );
402
403 setLibNickname( ret, row->GetNickName(), aFootprintName );
404
405 return ret;
406}
407
408
410 const FOOTPRINT* aFootprint, bool aOverwrite )
411{
412 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
413 wxASSERT( row->plugin );
414
415 if( !aOverwrite )
416 {
417 // Try loading the footprint to see if it already exists, caller wants overwrite
418 // protection, which is atypical, not the default.
419
420 wxString fpname = aFootprint->GetFPID().GetLibItemName();
421
422 std::unique_ptr<FOOTPRINT> footprint( row->plugin->FootprintLoad( row->GetFullURI( true ),
423 fpname,
424 row->GetProperties() ) );
425
426 if( footprint.get() )
427 return SAVE_SKIPPED;
428 }
429
430 row->plugin->FootprintSave( row->GetFullURI( true ), aFootprint, row->GetProperties() );
431
432 return SAVE_OK;
433}
434
435
436void FP_LIB_TABLE::FootprintDelete( const wxString& aNickname, const wxString& aFootprintName )
437{
438 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
439 wxASSERT( row->plugin );
440 return row->plugin->FootprintDelete( row->GetFullURI( true ), aFootprintName,
441 row->GetProperties() );
442}
443
444
445bool FP_LIB_TABLE::IsFootprintLibWritable( const wxString& aNickname )
446{
447 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
448 wxASSERT( row->plugin );
449 return row->plugin->IsLibraryWritable( row->GetFullURI( true ) );
450}
451
452
453void FP_LIB_TABLE::FootprintLibDelete( const wxString& aNickname )
454{
455 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
456 wxASSERT( row->plugin );
457 row->plugin->DeleteLibrary( row->GetFullURI( true ), row->GetProperties() );
458}
459
460
461void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
462{
463 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
464 wxASSERT( row->plugin );
465 row->plugin->CreateLibrary( row->GetFullURI( true ), row->GetProperties() );
466}
467
468
470 bool aKeepUUID )
471{
472 wxString nickname = aFootprintId.GetLibNickname();
473 wxString fpname = aFootprintId.GetLibItemName();
474
475 if( nickname.size() )
476 {
477 return FootprintLoad( nickname, fpname, aKeepUUID );
478 }
479
480 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
481 else
482 {
483 std::vector<wxString> nicks = GetLogicalLibs();
484
485 // Search each library going through libraries alphabetically.
486 for( unsigned i = 0; i < nicks.size(); ++i )
487 {
488 // FootprintLoad() returns NULL on not found, does not throw exception
489 // unless there's an IO_ERROR.
490 FOOTPRINT* ret = FootprintLoad( nicks[i], fpname, aKeepUUID );
491
492 if( ret )
493 return ret;
494 }
495
496 return nullptr;
497 }
498}
499
500
502{
503 return ENV_VAR::GetVersionedEnvVarName( wxS( "FOOTPRINT_DIR" ) );
504}
505
506
507class PCM_FP_LIB_TRAVERSER final : public wxDirTraverser
508{
509public:
510 explicit PCM_FP_LIB_TRAVERSER( const wxString& aPath, FP_LIB_TABLE& aTable,
511 const wxString& aPrefix ) :
512 m_lib_table( aTable ),
513 m_path_prefix( aPath ),
514 m_lib_prefix( aPrefix )
515 {
516 wxFileName f( aPath, wxS( "" ) );
517 m_prefix_dir_count = f.GetDirCount();
518 }
519
520 wxDirTraverseResult OnFile( const wxString& aFilePath ) override { return wxDIR_CONTINUE; }
521
522 wxDirTraverseResult OnDir( const wxString& dirPath ) override
523 {
524 wxFileName dir = wxFileName::DirName( dirPath );
525
526 // consider a directory to be a lib if it's name ends with .pretty and
527 // it is under $KICADn_3RD_PARTY/footprints/<pkgid>/ i.e. has nested level of at least +3
528 if( dirPath.EndsWith( wxS( ".pretty" ) ) && dir.GetDirCount() >= m_prefix_dir_count + 3 )
529 {
530 wxString versionedPath = wxString::Format( wxS( "${%s}" ),
531 ENV_VAR::GetVersionedEnvVarName( wxS( "3RD_PARTY" ) ) );
532
533 wxArrayString parts = dir.GetDirs();
534 parts.RemoveAt( 0, m_prefix_dir_count );
535 parts.Insert( versionedPath, 0 );
536
537 wxString libPath = wxJoin( parts, '/' );
538
539 if( !m_lib_table.HasLibraryWithPath( libPath ) )
540 {
541 wxString name = parts.Last().substr( 0, parts.Last().length() - 7 );
542 wxString nickname = wxString::Format( wxS( "%s%s" ), m_lib_prefix, name );
543
544 if( m_lib_table.HasLibrary( nickname ) )
545 {
546 int increment = 1;
547 do
548 {
549 nickname = wxString::Format( wxS( "%s%s_%d" ), m_lib_prefix, name, increment );
550 increment++;
551 } while( m_lib_table.HasLibrary( nickname ) );
552 }
553
555 new FP_LIB_TABLE_ROW( nickname, libPath, wxT( "KiCad" ), wxEmptyString,
556 _( "Added by Plugin and Content Manager" ) ) );
557 }
558 }
559
560 return wxDIR_CONTINUE;
561 }
562
563private:
566 wxString m_lib_prefix;
568};
569
570
572{
573 bool tableExists = true;
574 wxFileName fn = GetGlobalTableFileName();
575
576 if( !fn.FileExists() )
577 {
578 tableExists = false;
579
580 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
581 {
582 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
583 fn.GetPath() ) );
584 }
585
586 // Attempt to copy the default global file table from the KiCad
587 // template folder to the user's home configuration path.
588 SEARCH_STACK ss;
589
590 SystemDirsAppend( &ss );
591
592 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
593 std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( envVars,
594 wxT( "TEMPLATE_DIR" ) );
595
596 if( v && !v->IsEmpty() )
597 ss.AddPaths( *v, 0 );
598
599 wxString fileName = ss.FindValidPath( global_tbl_name );
600
601 // The fallback is to create an empty global footprint table for the user to populate.
602 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
603 {
604 FP_LIB_TABLE emptyTable;
605
606 emptyTable.Save( fn.GetFullPath() );
607 }
608 }
609
610 aTable.Clear();
611 aTable.Load( fn.GetFullPath() );
612
615
616 const ENV_VAR_MAP& env = Pgm().GetLocalEnvVariables();
617 wxString packagesPath;
618
619 if( std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( env, wxT( "3RD_PARTY" ) ) )
620 packagesPath = *v;
621
622 if( settings->m_PcmLibAutoAdd )
623 {
624 // Scan for libraries in PCM packages directory
625
626 wxFileName d( packagesPath, wxS( "" ) );
627 d.AppendDir( wxS( "footprints" ) );
628
629 if( d.DirExists() )
630 {
631 PCM_FP_LIB_TRAVERSER traverser( packagesPath, aTable, settings->m_PcmLibPrefix );
632 wxDir dir( d.GetPath() );
633
634 dir.Traverse( traverser );
635 }
636 }
637
638 if( settings->m_PcmLibAutoRemove )
639 {
640 // Remove PCM libraries that no longer exist
641 std::vector<wxString> to_remove;
642
643 for( size_t i = 0; i < aTable.GetCount(); i++ )
644 {
645 LIB_TABLE_ROW& row = aTable.At( i );
646 wxString path = row.GetFullURI( true );
647
648 if( path.StartsWith( packagesPath ) && !wxDir::Exists( path ) )
649 to_remove.push_back( row.GetNickName() );
650 }
651
652 for( const wxString& nickName : to_remove )
653 aTable.RemoveRow( aTable.FindRow( nickName ) );
654 }
655
656 return tableExists;
657}
658
659
661{
662 wxFileName fn;
663
664 fn.SetPath( PATHS::GetUserSettingsPath() );
665 fn.SetName( global_tbl_name );
666
667 return fn.GetFullPath();
668}
const char * name
Definition: DXF_plotter.cpp:57
const LIB_ID & GetFPID() const
Definition: footprint.h:233
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:85
void SetType(const wxString &aType) override
Change the type represented by this row.
IO_RELEASER< PCB_IO > plugin
Definition: fp_lib_table.h:93
bool operator==(const FP_LIB_TABLE_ROW &aRow) const
PCB_IO_MGR::PCB_FILE_T type
Definition: fp_lib_table.h:94
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.
void PrefetchLib(const wxString &aNickname)
If possible, prefetches the specified library (e.g.
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:201
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:99
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 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
const STRING_UTF8_MAP * GetProperties() const
Return the constant #PROPERTIES for this library (LIB_TABLE_ROW).
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.
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.
void Clear()
Delete all rows.
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 Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:458
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition: paths.cpp:510
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:65
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:90
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:923
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
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).
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
std::string::size_type size() const
Definition: utf8.h:111
wxString wx_str() const
Definition: utf8.cpp:45
#define _(s)
Functions related to environment variables, including help functions.
static const wxChar global_tbl_name[]
static void setLibNickname(FOOTPRINT *aModule, const wxString &aNickname, const wxString &aFootprintName)
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)
Attempts to retrieve the value of a versioned environment variable, such as KICAD8_TEMPLATE_DIR.
Definition: env_vars.cpp:83
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Constructs a versioned environment variable based on this KiCad major version.
Definition: env_vars.cpp:74
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
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.