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-2024 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 use doReplace
209 // in doInsertRow(). (However a fallBack table can have a conflicting nickName and ours
210 // will supercede that one since in FindLib() we search this table before any fall back.)
211 wxString nickname = row->GetNickName(); // store it to be able to used it
212 // after row deletion if an error occurs
213 bool doReplace = false;
214 LIB_TABLE_ROW* tmp = row.release();
215
216 if( !doInsertRow( tmp, doReplace ) )
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 try
448 {
449 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
450
451 if( !row || !row->plugin )
452 return false;
453
454 return row->plugin->IsLibraryWritable( row->GetFullURI( true ) );
455 }
456 catch( ... )
457 {
458 }
459
460 // aNickname not found, so the library is not writable
461 return false;
462}
463
464
465void FP_LIB_TABLE::FootprintLibDelete( const wxString& aNickname )
466{
467 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
468 wxASSERT( row->plugin );
469 row->plugin->DeleteLibrary( row->GetFullURI( true ), row->GetProperties() );
470}
471
472
473void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
474{
475 const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true );
476 wxASSERT( row->plugin );
477 row->plugin->CreateLibrary( row->GetFullURI( true ), row->GetProperties() );
478}
479
480
482 bool aKeepUUID )
483{
484 wxString nickname = aFootprintId.GetLibNickname();
485 wxString fpname = aFootprintId.GetLibItemName();
486
487 if( nickname.size() )
488 {
489 return FootprintLoad( nickname, fpname, aKeepUUID );
490 }
491
492 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
493 else
494 {
495 std::vector<wxString> nicks = GetLogicalLibs();
496
497 // Search each library going through libraries alphabetically.
498 for( unsigned i = 0; i < nicks.size(); ++i )
499 {
500 // FootprintLoad() returns NULL on not found, does not throw exception
501 // unless there's an IO_ERROR.
502 FOOTPRINT* ret = FootprintLoad( nicks[i], fpname, aKeepUUID );
503
504 if( ret )
505 return ret;
506 }
507
508 return nullptr;
509 }
510}
511
512
514{
515 return ENV_VAR::GetVersionedEnvVarName( wxS( "FOOTPRINT_DIR" ) );
516}
517
518
519class PCM_FP_LIB_TRAVERSER final : public wxDirTraverser
520{
521public:
522 explicit PCM_FP_LIB_TRAVERSER( const wxString& aPath, FP_LIB_TABLE& aTable,
523 const wxString& aPrefix ) :
524 m_lib_table( aTable ),
525 m_path_prefix( aPath ),
526 m_lib_prefix( aPrefix )
527 {
528 wxFileName f( aPath, wxS( "" ) );
529 m_prefix_dir_count = f.GetDirCount();
530 }
531
532 wxDirTraverseResult OnFile( const wxString& aFilePath ) override { return wxDIR_CONTINUE; }
533
534 wxDirTraverseResult OnDir( const wxString& dirPath ) override
535 {
536 wxFileName dir = wxFileName::DirName( dirPath );
537
538 // consider a directory to be a lib if it's name ends with .pretty and
539 // it is under $KICADn_3RD_PARTY/footprints/<pkgid>/ i.e. has nested level of at least +3
540 if( dirPath.EndsWith( wxS( ".pretty" ) ) && dir.GetDirCount() >= m_prefix_dir_count + 3 )
541 {
542 wxString versionedPath = wxString::Format( wxS( "${%s}" ),
543 ENV_VAR::GetVersionedEnvVarName( wxS( "3RD_PARTY" ) ) );
544
545 wxArrayString parts = dir.GetDirs();
546 parts.RemoveAt( 0, m_prefix_dir_count );
547 parts.Insert( versionedPath, 0 );
548
549 wxString libPath = wxJoin( parts, '/' );
550
551 if( !m_lib_table.HasLibraryWithPath( libPath ) )
552 {
553 wxString name = parts.Last().substr( 0, parts.Last().length() - 7 );
554 wxString nickname = wxString::Format( wxS( "%s%s" ), m_lib_prefix, name );
555
556 if( m_lib_table.HasLibrary( nickname ) )
557 {
558 int increment = 1;
559 do
560 {
561 nickname = wxString::Format( wxS( "%s%s_%d" ), m_lib_prefix, name, increment );
562 increment++;
563 } while( m_lib_table.HasLibrary( nickname ) );
564 }
565
567 new FP_LIB_TABLE_ROW( nickname, libPath, wxT( "KiCad" ), wxEmptyString,
568 _( "Added by Plugin and Content Manager" ) ) );
569 }
570 }
571
572 return wxDIR_CONTINUE;
573 }
574
575private:
578 wxString m_lib_prefix;
580};
581
582
584{
585 bool tableExists = true;
586 wxFileName fn = GetGlobalTableFileName();
587
588 if( !fn.FileExists() )
589 {
590 tableExists = false;
591
592 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
593 {
594 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
595 fn.GetPath() ) );
596 }
597
598 // Attempt to copy the default global file table from the KiCad
599 // template folder to the user's home configuration path.
600 SEARCH_STACK ss;
601
602 SystemDirsAppend( &ss );
603
604 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
605 std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( envVars,
606 wxT( "TEMPLATE_DIR" ) );
607
608 if( v && !v->IsEmpty() )
609 ss.AddPaths( *v, 0 );
610
611 wxString fileName = ss.FindValidPath( global_tbl_name );
612
613 // The fallback is to create an empty global footprint table for the user to populate.
614 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
615 {
616 FP_LIB_TABLE emptyTable;
617
618 emptyTable.Save( fn.GetFullPath() );
619 }
620 }
621
622 aTable.Load( fn.GetFullPath() );
623
626
627 const ENV_VAR_MAP& env = Pgm().GetLocalEnvVariables();
628 wxString packagesPath;
629
630 if( std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( env, wxT( "3RD_PARTY" ) ) )
631 packagesPath = *v;
632
633 if( settings->m_PcmLibAutoAdd )
634 {
635 // Scan for libraries in PCM packages directory
636
637 wxFileName d( packagesPath, wxS( "" ) );
638 d.AppendDir( wxS( "footprints" ) );
639
640 if( d.DirExists() )
641 {
642 PCM_FP_LIB_TRAVERSER traverser( packagesPath, aTable, settings->m_PcmLibPrefix );
643 wxDir dir( d.GetPath() );
644
645 dir.Traverse( traverser );
646 }
647 }
648
649 if( settings->m_PcmLibAutoRemove )
650 {
651 // Remove PCM libraries that no longer exist
652 std::vector<wxString> to_remove;
653
654 for( size_t i = 0; i < aTable.GetCount(); i++ )
655 {
656 LIB_TABLE_ROW& row = aTable.At( i );
657 wxString path = row.GetFullURI( true );
658
659 if( path.StartsWith( packagesPath ) && !wxDir::Exists( path ) )
660 to_remove.push_back( row.GetNickName() );
661 }
662
663 for( const wxString& nickName : to_remove )
664 aTable.RemoveRow( aTable.FindRow( nickName ) );
665 }
666
667 return tableExists;
668}
669
670
672{
673 wxFileName fn;
674
675 fn.SetPath( PATHS::GetUserSettingsPath() );
676 fn.SetName( global_tbl_name );
677
678 return fn.GetFullPath();
679}
const char * name
Definition: DXF_plotter.cpp:57
const LIB_ID & GetFPID() const
Definition: footprint.h:248
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 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 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:531
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:69
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:94
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:924
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
static void setLibNickname(DESIGN_BLOCK *aModule, const wxString &aNickname, const wxString &aDesignBlockName)
static const wxChar global_tbl_name[]
#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:1060
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.