KiCad PCB EDA Suite
symbol_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) 2016 Wayne Stambaugh <[email protected]>
5 * Copyright (C) 2022 CERN
6 * Copyright (C) 2016-2022 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 <lib_id.h>
28#include <lib_table_lexer.h>
29#include <pgm_base.h>
30#include <search_stack.h>
33#include <systemdirsappend.h>
34#include <symbol_lib_table.h>
35#include <lib_symbol.h>
36
37#include <wx/dir.h>
38#include "sim/sim_model.h"
39
40#define OPT_SEP '|'
41
42using namespace LIB_TABLE_T;
43
44
45static const wxString global_tbl_name( "sym-lib-table" );
46
47
48const char* SYMBOL_LIB_TABLE::PropPowerSymsOnly = "pwr_sym_only";
49const char* SYMBOL_LIB_TABLE::PropNonPowerSymsOnly = "non_pwr_sym_only";
50int SYMBOL_LIB_TABLE::m_modifyHash = 1; // starts at 1 and goes up
51
52
57
58
60{
61 return LIB_TABLE_ROW::operator == ( aRow ) && type == aRow.type;
62}
63
64
65void SYMBOL_LIB_TABLE_ROW::SetType( const wxString& aType )
66{
68
69 if( SCH_IO_MGR::SCH_FILE_T( -1 ) == type )
70 type = SCH_IO_MGR::SCH_LEGACY;
71
73}
74
75
77{
78 if( !plugin )
79 {
80 wxArrayString dummyList;
81
82 plugin.set( SCH_IO_MGR::FindPlugin( type ) );
83 SetLoaded( false );
84 plugin->SetLibTable( static_cast<SYMBOL_LIB_TABLE*>( GetParent() ) );
85 plugin->EnumerateSymbolLib( dummyList, GetFullURI( true ), GetProperties() );
86 SetLoaded( true );
87 return true;
88 }
89
90 return false;
91}
92
93
94void SYMBOL_LIB_TABLE_ROW::GetSubLibraryNames( std::vector<wxString>& aNames ) const
95{
96 if( !plugin )
97 return;
98
99 plugin->GetSubLibraryNames( aNames );
100}
101
102
104 LIB_TABLE( aFallBackTable )
105{
106 // not copying fall back, simply search aFallBackTable separately
107 // if "nickName not found".
108}
109
110
112{
114}
115
116
117void SYMBOL_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
118{
119 T tok;
120 wxString errMsg; // to collect error messages
121
122 // This table may be nested within a larger s-expression, or not.
123 // Allow for parser of that optional containing s-epression to have looked ahead.
124 if( in->CurTok() != T_sym_lib_table )
125 {
126 in->NeedLEFT();
127
128 if( ( tok = in->NextTok() ) != T_sym_lib_table )
129 in->Expecting( T_sym_lib_table );
130 }
131
132 while( ( tok = in->NextTok() ) != T_RIGHT )
133 {
134 std::unique_ptr< SYMBOL_LIB_TABLE_ROW > row = std::make_unique<SYMBOL_LIB_TABLE_ROW>();
135
136 if( tok == T_EOF )
137 in->Expecting( T_RIGHT );
138
139 if( tok != T_LEFT )
140 in->Expecting( T_LEFT );
141
142 // in case there is a "row integrity" error, tell where later.
143 int lineNum = in->CurLineNumber();
144 tok = in->NextTok();
145
146 // Optionally parse the current version number
147 if( tok == T_version )
148 {
149 in->NeedNUMBER( "version" );
150 m_version = std::stoi( in->CurText() );
151 in->NeedRIGHT();
152 continue;
153 }
154
155 if( tok != T_lib )
156 in->Expecting( T_lib );
157
158 // (name NICKNAME)
159 in->NeedLEFT();
160
161 if( ( tok = in->NextTok() ) != T_name )
162 in->Expecting( T_name );
163
164 in->NeedSYMBOLorNUMBER();
165
166 row->SetNickName( in->FromUTF8() );
167
168 in->NeedRIGHT();
169
170 // After (name), remaining (lib) elements are order independent, and in
171 // some cases optional.
172 bool sawType = false;
173 bool sawOpts = false;
174 bool sawDesc = false;
175 bool sawUri = false;
176 bool sawDisabled = false;
177 bool sawHidden = false;
178
179 while( ( tok = in->NextTok() ) != T_RIGHT )
180 {
181 if( tok == T_EOF )
182 in->Unexpected( T_EOF );
183
184 if( tok != T_LEFT )
185 in->Expecting( T_LEFT );
186
187 tok = in->NeedSYMBOLorNUMBER();
188
189 switch( tok )
190 {
191 case T_uri:
192 if( sawUri )
193 in->Duplicate( tok );
194 sawUri = true;
195 in->NeedSYMBOLorNUMBER();
196 row->SetFullURI( in->FromUTF8() );
197 break;
198
199 case T_type:
200 if( sawType )
201 in->Duplicate( tok );
202 sawType = true;
203 in->NeedSYMBOLorNUMBER();
204 row->SetType( in->FromUTF8() );
205 break;
206
207 case T_options:
208 if( sawOpts )
209 in->Duplicate( tok );
210 sawOpts = true;
211 in->NeedSYMBOLorNUMBER();
212 row->SetOptions( in->FromUTF8() );
213 break;
214
215 case T_descr:
216 if( sawDesc )
217 in->Duplicate( tok );
218 sawDesc = true;
219 in->NeedSYMBOLorNUMBER();
220 row->SetDescr( in->FromUTF8() );
221 break;
222
223 case T_disabled:
224 if( sawDisabled )
225 in->Duplicate( tok );
226 sawDisabled = true;
227 row->SetEnabled( false );
228 break;
229
230 case T_hidden:
231 if( sawHidden )
232 in->Duplicate( tok );
233 sawHidden = true;
234 row->SetVisible( false );
235 break;
236
237 default:
238 in->Unexpected( tok );
239 }
240
241 in->NeedRIGHT();
242 }
243
244 if( !sawType )
245 in->Expecting( T_type );
246
247 if( !sawUri )
248 in->Expecting( T_uri );
249
250 // all nickNames within this table fragment must be unique, so we do not
251 // use doReplace in InsertRow(). (However a fallBack table can have a
252 // conflicting nickName and ours will supercede that one since in
253 // FindLib() we search this table before any fall back.)
254 wxString nickname = row->GetNickName(); // store it to be able to used it
255 // after row deletion if an error occurs
256 LIB_TABLE_ROW* tmp = row.release();
257
258 if( !InsertRow( tmp ) )
259 {
260 delete tmp; // The table did not take ownership of the row.
261
262 wxString msg = wxString::Format( _( "Duplicate library nickname '%s' found in symbol "
263 "library table file line %d" ),
264 nickname,
265 lineNum );
266
267 if( !errMsg.IsEmpty() )
268 errMsg << '\n';
269
270 errMsg << msg;
271 }
272 }
273
274 if( !errMsg.IsEmpty() )
275 THROW_IO_ERROR( errMsg );
276}
277
278
279void SYMBOL_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
280{
281 aOutput->Print( aIndentLevel, "(sym_lib_table\n" );
282 aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
283
284 for( LIB_TABLE_ROWS_CITER it = m_rows.begin(); it != m_rows.end(); ++it )
285 {
286 it->Format( aOutput, aIndentLevel+1 );
287 }
288
289 aOutput->Print( aIndentLevel, ")\n" );
290}
291
292
294{
295 int hash = 0;
296 std::vector< wxString > libNames = GetLogicalLibs();
297
298 for( const auto& libName : libNames )
299 {
300 const SYMBOL_LIB_TABLE_ROW* row = FindRow( libName, true );
301
302 if( !row || !row->plugin )
303 {
304 wxFAIL;
305 continue;
306 }
307
308 hash += row->plugin->GetModifyHash();
309 }
310
311 hash += m_modifyHash;
312
313 return hash;
314}
315
316
317void SYMBOL_LIB_TABLE::EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames,
318 bool aPowerSymbolsOnly )
319{
320 SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
321 wxCHECK( row && row->plugin, /* void */ );
322
323 wxString options = row->GetOptions();
324
325 if( aPowerSymbolsOnly )
326 row->SetOptions( row->GetOptions() + " " + PropPowerSymsOnly );
327
328 row->SetLoaded( false );
329 row->plugin->EnumerateSymbolLib( aAliasNames, row->GetFullURI( true ), row->GetProperties() );
330 row->SetLoaded( true );
331
332 if( aPowerSymbolsOnly )
333 row->SetOptions( options );
334}
335
336
337SYMBOL_LIB_TABLE_ROW* SYMBOL_LIB_TABLE::FindRow( const wxString& aNickname, bool aCheckIfEnabled )
338{
340 dynamic_cast< SYMBOL_LIB_TABLE_ROW* >( findRow( aNickname, aCheckIfEnabled ) );
341
342 if( !row )
343 return nullptr;
344
345 // We've been 'lazy' up until now, but it cannot be deferred any longer,
346 // instantiate a PLUGIN of the proper kind if it is not already in this
347 // SYMBOL_LIB_TABLE_ROW.
348 if( !row->plugin )
349 {
350 row->setPlugin( SCH_IO_MGR::FindPlugin( row->type ) );
351 row->plugin->SetLibTable( this );
352 }
353
354 return row;
355}
356
357
358void SYMBOL_LIB_TABLE::LoadSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
359 const wxString& aNickname, bool aPowerSymbolsOnly )
360{
361 SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
362 wxCHECK( row && row->plugin, /* void */ );
363
364 std::lock_guard<std::mutex> lock( row->GetMutex() );
365
366 wxString options = row->GetOptions();
367
368 if( aPowerSymbolsOnly )
369 row->SetOptions( row->GetOptions() + " " + PropPowerSymsOnly );
370
371 row->SetLoaded( false );
372 row->plugin->SetLibTable( this );
373 row->plugin->EnumerateSymbolLib( aSymbolList, row->GetFullURI( true ), row->GetProperties() );
374 row->SetLoaded( true );
375
376 if( aPowerSymbolsOnly )
377 row->SetOptions( options );
378
379 // The library cannot know its own name, because it might have been renamed or moved.
380 // Therefore footprints cannot know their own library nickname when residing in
381 // a symbol library.
382 // Only at this API layer can we tell the symbol about its actual library nickname.
383 for( LIB_SYMBOL* symbol : aSymbolList )
384 {
385 LIB_ID id = symbol->GetLibId();
386
387 id.SetLibNickname( row->GetNickName() );
388 symbol->SetLibId( id );
389 }
390}
391
392
393LIB_SYMBOL* SYMBOL_LIB_TABLE::LoadSymbol( const wxString& aNickname, const wxString& aSymbolName )
394{
395 SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
396
397 if( !row || !row->plugin )
398 return nullptr;
399
400 // If another thread is loading this library at the moment; continue
401 std::unique_lock<std::mutex> lock( row->GetMutex(), std::try_to_lock );
402
403 if( !lock.owns_lock() )
404 return nullptr;
405
406 LIB_SYMBOL* symbol = row->plugin->LoadSymbol( row->GetFullURI( true ), aSymbolName,
407 row->GetProperties() );
408
409 if( symbol )
410 {
411 // The library cannot know its own name, because it might have been renamed or moved.
412 // Therefore footprints cannot know their own library nickname when residing in
413 // a symbol library.
414 // Only at this API layer can we tell the symbol about its actual library nickname.
415 LIB_ID id = symbol->GetLibId();
416
417 id.SetLibNickname( row->GetNickName() );
418 symbol->SetLibId( id );
419
420 SIM_MODEL::MigrateSimModel<LIB_SYMBOL, LIB_FIELD>( *symbol, nullptr );
421 }
422
423 return symbol;
424}
425
426
428 const LIB_SYMBOL* aSymbol, bool aOverwrite )
429{
430 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
431 wxCHECK( row && row->plugin, SAVE_SKIPPED );
432
433 if( !row->plugin->IsSymbolLibWritable( row->GetFullURI( true ) ) )
434 return SAVE_SKIPPED;
435
436 if( !aOverwrite )
437 {
438 // Try loading the footprint to see if it already exists, caller wants overwrite
439 // protection, which is atypical, not the default.
440
441 wxString name = aSymbol->GetLibId().GetLibItemName();
442
443 std::unique_ptr<LIB_SYMBOL> symbol( row->plugin->LoadSymbol( row->GetFullURI( true ),
444 name, row->GetProperties() ) );
445
446 if( symbol.get() )
447 return SAVE_SKIPPED;
448 }
449
450 try
451 {
452 row->plugin->SaveSymbol( row->GetFullURI( true ), aSymbol, row->GetProperties() );
453 }
454 catch( const IO_ERROR& )
455 {
456 return SAVE_SKIPPED;
457 }
458
459 return SAVE_OK;
460}
461
462
463void SYMBOL_LIB_TABLE::DeleteSymbol( const wxString& aNickname, const wxString& aSymbolName )
464{
465 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
466 wxCHECK( row && row->plugin, /* void */ );
467 return row->plugin->DeleteSymbol( row->GetFullURI( true ), aSymbolName, row->GetProperties() );
468}
469
470
471bool SYMBOL_LIB_TABLE::IsSymbolLibWritable( const wxString& aNickname )
472{
473 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
474 wxCHECK( row && row->plugin, false );
475 return row->plugin->IsSymbolLibWritable( row->GetFullURI( true ) );
476}
477
478bool SYMBOL_LIB_TABLE::IsSymbolLibLoaded( const wxString& aNickname )
479{
480 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
481 wxCHECK( row, false );
482 return row->GetIsLoaded();
483}
484
485
486void SYMBOL_LIB_TABLE::DeleteSymbolLib( const wxString& aNickname )
487{
488 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
489 wxCHECK( row && row->plugin, /* void */ );
490 row->plugin->DeleteSymbolLib( row->GetFullURI( true ), row->GetProperties() );
491}
492
493
494void SYMBOL_LIB_TABLE::CreateSymbolLib( const wxString& aNickname )
495{
496 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
497 wxCHECK( row && row->plugin, /* void */ );
498 row->plugin->CreateSymbolLib( row->GetFullURI( true ), row->GetProperties() );
499}
500
501
503{
504 wxString nickname = aLibId.GetLibNickname();
505 wxString name = aLibId.GetLibItemName();
506
507 if( nickname.size() )
508 {
509 return LoadSymbol( nickname, name );
510 }
511 else
512 {
513 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
514 std::vector<wxString> nicks = GetLogicalLibs();
515
516 // Search each library going through libraries alphabetically.
517 for( unsigned i = 0; i < nicks.size(); ++i )
518 {
519 // FootprintLoad() returns NULL on not found, does not throw exception
520 // unless there's an IO_ERROR.
521 LIB_SYMBOL* ret = LoadSymbol( nicks[i], name );
522
523 if( ret )
524 return ret;
525 }
526
527 return nullptr;
528 }
529}
530
531
533{
534 return "KICAD7_SYMBOL_DIR";
535}
536
537
538class PCM_SYM_LIB_TRAVERSER final : public wxDirTraverser
539{
540public:
541 explicit PCM_SYM_LIB_TRAVERSER( const wxString& aPath, SYMBOL_LIB_TABLE& aTable,
542 const wxString& aPrefix ) :
543 m_lib_table( aTable ),
544 m_path_prefix( aPath ),
545 m_lib_prefix( aPrefix )
546 {
547 wxFileName f( aPath, "" );
548 m_prefix_dir_count = f.GetDirCount();
549 }
550
551 wxDirTraverseResult OnFile( const wxString& aFilePath ) override
552 {
553 wxFileName file = wxFileName::FileName( aFilePath );
554
555 // consider a file to be a lib if it's name ends with .kicad_sym and
556 // it is under $KICAD7_3RD_PARTY/symbols/<pkgid>/ i.e. has nested level of at least +2
557 if( file.GetExt() == wxT( "kicad_sym" ) && file.GetDirCount() >= m_prefix_dir_count + 2 )
558 {
559 wxArrayString parts = file.GetDirs();
560 parts.RemoveAt( 0, m_prefix_dir_count );
561 parts.Insert( "${KICAD7_3RD_PARTY}", 0 );
562 parts.Add( file.GetFullName() );
563
564 wxString libPath = wxJoin( parts, '/' );
565
566 if( !m_lib_table.HasLibraryWithPath( libPath ) )
567 {
568 wxString name = parts.Last().substr( 0, parts.Last().length() - 10 );
569 wxString nickname = wxString::Format( "%s%s", m_lib_prefix, name );
570
571 if( m_lib_table.HasLibrary( nickname ) )
572 {
573 int increment = 1;
574 do
575 {
576 nickname = wxString::Format( "%s%s_%d", m_lib_prefix, name, increment );
577 increment++;
578 } while( m_lib_table.HasLibrary( nickname ) );
579 }
580
582 new SYMBOL_LIB_TABLE_ROW( nickname, libPath, wxT( "KiCad" ), wxEmptyString,
583 _( "Added by Plugin and Content Manager" ) ) );
584 }
585 }
586
587 return wxDIR_CONTINUE;
588 }
589
590 wxDirTraverseResult OnDir( const wxString& dirPath ) override { return wxDIR_CONTINUE; }
591
592private:
595 wxString m_lib_prefix;
597};
598
599
601{
602 bool tableExists = true;
603 wxFileName fn = GetGlobalTableFileName();
604
605 if( !fn.FileExists() )
606 {
607 tableExists = false;
608
609 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
610 {
611 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
612 fn.GetPath() ) );
613 }
614
615 // Attempt to copy the default global file table from the KiCad
616 // template folder to the user's home configuration path.
617 SEARCH_STACK ss;
618
619 SystemDirsAppend( &ss );
620
621 wxString templatePath =
622 Pgm().GetLocalEnvVariables().at( wxT( "KICAD7_TEMPLATE_DIR" ) ).GetValue();
623
624 if( !templatePath.IsEmpty() )
625 ss.AddPaths( templatePath, 0 );
626
627 wxString fileName = ss.FindValidPath( global_tbl_name );
628
629 // The fallback is to create an empty global symbol table for the user to populate.
630 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
631 {
632 SYMBOL_LIB_TABLE emptyTable;
633
634 emptyTable.Save( fn.GetFullPath() );
635 }
636 }
637
638 aTable.Clear();
639 aTable.Load( fn.GetFullPath() );
640
641 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
643
644 wxString packagesPath = Pgm().GetLocalEnvVariables().at( wxT( "KICAD7_3RD_PARTY" ) ).GetValue();
645
646 if( settings->m_PcmLibAutoAdd )
647 {
648 // Scan for libraries in PCM packages directory
649 wxFileName d( packagesPath, "" );
650 d.AppendDir( "symbols" );
651
652 if( d.DirExists() )
653 {
654 PCM_SYM_LIB_TRAVERSER traverser( packagesPath, aTable, settings->m_PcmLibPrefix );
655 wxDir dir( d.GetPath() );
656
657 dir.Traverse( traverser );
658 }
659 }
660
661 if( settings->m_PcmLibAutoRemove )
662 {
663 // Remove PCM libraries that no longer exist
664 std::vector<wxString> to_remove;
665
666 for( size_t i = 0; i < aTable.GetCount(); i++ )
667 {
668 LIB_TABLE_ROW& row = aTable.At( i );
669 wxString path = row.GetFullURI( true );
670
671 if( path.StartsWith( packagesPath ) && !wxFile::Exists( path ) )
672 to_remove.push_back( row.GetNickName() );
673 }
674
675 for( const wxString& nickName : to_remove )
676 aTable.RemoveRow( aTable.FindRow( nickName ) );
677 }
678
679 return tableExists;
680}
681
682
684{
685 wxFileName fn;
686
688 fn.SetName( global_tbl_name );
689
690 return fn.GetFullPath();
691}
692
693
695{
696 return global_tbl_name;
697}
const char * name
Definition: DXF_plotter.cpp:56
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
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 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:98
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
Define a library symbol object.
Definition: lib_symbol.h:99
LIB_ID GetLibId() const override
Definition: lib_symbol.h:141
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:142
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
const wxString & GetOptions() const
Return the options string, which may hold a password or anything else needed to instantiate the under...
std::mutex & GetMutex()
bool GetIsLoaded() const
LIB_TABLE * GetParent() const
void SetLoaded(bool aLoaded)
Mark the row as being a loaded library.
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
void SetOptions(const wxString &aOptions)
Change the library options strings.
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
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.
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:310
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:433
wxDirTraverseResult OnFile(const wxString &aFilePath) override
wxDirTraverseResult OnDir(const wxString &dirPath) override
SYMBOL_LIB_TABLE & m_lib_table
PCM_SYM_LIB_TRAVERSER(const wxString &aPath, SYMBOL_LIB_TABLE &aTable, const wxString &aPrefix)
static SCH_FILE_T EnumFromStr(const wxString &aFileType)
Return the #SCH_FILE_T from the corresponding plugin type name: "kicad", "legacy",...
Definition: sch_io_mgr.cpp:101
void set(SCH_PLUGIN *aPlugin)
Definition: sch_io_mgr.h:562
virtual void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
Definition: sch_plugin.cpp:67
virtual int GetModifyHash() const =0
Return the modification hash from the library cache.
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const STRING_UTF8_MAP *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
Definition: sch_plugin.cpp:94
virtual void DeleteSymbol(const wxString &aLibraryPath, const wxString &aSymbolName, const STRING_UTF8_MAP *aProperties=nullptr)
Delete the entire LIB_SYMBOL associated with aAliasName from the library aLibraryPath.
Definition: sch_plugin.cpp:102
virtual LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aPartName, const STRING_UTF8_MAP *aProperties=nullptr)
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
Definition: sch_plugin.cpp:85
virtual void SetLibTable(SYMBOL_LIB_TABLE *aTable)
Some library plugins need to have access to their parent library table.
Definition: sch_io_mgr.h:515
virtual void CreateSymbolLib(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Create a new empty symbol library at aLibraryPath.
Definition: sch_plugin.cpp:110
virtual bool DeleteSymbolLib(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Delete an existing symbol library and returns true if successful, or if library does not exist return...
Definition: sch_plugin.cpp:117
virtual void GetSubLibraryNames(std::vector< wxString > &aNames)
Retrieves a list of sub-libraries in this library.
Definition: sch_io_mgr.h:463
virtual bool IsSymbolLibWritable(const wxString &aLibraryPath)
Return true if the library at aLibraryPath is writable.
Definition: sch_plugin.cpp:125
Look for files in a number of paths.
Definition: search_stack.h:42
void AddPaths(const wxString &aPaths, int aIndex=-1)
Insert or append path(s).
T * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
bool operator==(const SYMBOL_LIB_TABLE_ROW &aRow) const
void SetType(const wxString &aType) override
Change the schematic plugin type represented by this row.
void GetSubLibraryNames(std::vector< wxString > &aNames) const
void setPlugin(SCH_PLUGIN *aPlugin)
bool Refresh()
Attempt to reload the library.
SCH_PLUGIN::SCH_PLUGIN_RELEASER plugin
void LoadSymbolLib(std::vector< LIB_SYMBOL * > &aAliasList, const wxString &aNickname, bool aPowerSymbolsOnly=false)
void DeleteSymbol(const wxString &aNickname, const wxString &aSymbolName)
Deletes the aSymbolName from the library given by aNickname.
static SYMBOL_LIB_TABLE & GetGlobalLibTable()
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...
static const wxString & GetSymbolLibTableFileName()
SYMBOL_LIB_TABLE(SYMBOL_LIB_TABLE *aFallBackTable=nullptr)
Build a symbol library table by pre-pending this table fragment in front of aFallBackTable.
static const char * PropPowerSymsOnly
bool IsSymbolLibWritable(const wxString &aNickname)
Return true if the library given by aNickname is writable.
bool IsSymbolLibLoaded(const wxString &aNickname)
Return true if the library given by aNickname was successfully loaded.
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
void DeleteSymbolLib(const wxString &aNickname)
void CreateSymbolLib(const wxString &aNickname)
static wxString GetGlobalTableFileName()
Fetch the global symbol library table file name.
void EnumerateSymbolLib(const wxString &aNickname, wxArrayString &aAliasNames, bool aPowerSymbolsOnly=false)
Return a list of symbol alias names contained within the library given by aNickname.
static bool LoadGlobalTable(SYMBOL_LIB_TABLE &aTable)
Load the global symbol library table into aTable.
static const wxString GlobalPathEnvVariableName()
Return the name of the environment variable used to hold the directory of locally installed "KiCad sp...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
LIB_SYMBOL * LoadSymbolWithOptionalNickname(const LIB_ID &aId)
Load a LIB_SYMBOL having aFootprintId with possibly an empty library nickname.
static const char * PropNonPowerSymsOnly
SAVE_T SaveSymbol(const wxString &aNickname, const LIB_SYMBOL *aSymbol, bool aOverwrite=true)
Write aSymbol to an existing library given by aNickname.
SAVE_T
The set of return values from SaveSymbol() below.
SYMBOL_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an SYMBOL_LIB_TABLE_ROW if aNickName is found in this table or in any chained fallBack table f...
static int m_modifyHash
helper for GetModifyHash()
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER
see class PGM_BASE
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
SYMBOL_LIB_TABLE g_symbolLibraryTable
The global symbol library table.
static const wxString global_tbl_name("sym-lib-table")
void SystemDirsAppend(SEARCH_STACK *aSearchStack)
Append system places to aSearchStack in a platform specific way and pertinent to KiCad programs.
System directories search utilities.