KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-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 <env_vars.h>
28#include <lib_id.h>
29#include <lib_table_lexer.h>
30#include <paths.h>
31#include <pgm_base.h>
32#include <search_stack.h>
35#include <systemdirsappend.h>
36#include <symbol_lib_table.h>
37#include <lib_symbol.h>
40
41#include <wx/dir.h>
42#include "sim/sim_model.h"
43
44#define OPT_SEP '|'
45
46using namespace LIB_TABLE_T;
47
48
49static const wxString global_tbl_name( "sym-lib-table" );
50
51
52const char* SYMBOL_LIB_TABLE::PropPowerSymsOnly = "pwr_sym_only";
53const char* SYMBOL_LIB_TABLE::PropNonPowerSymsOnly = "non_pwr_sym_only";
54int SYMBOL_LIB_TABLE::m_modifyHash = 1; // starts at 1 and goes up
55
56
61
62
64{
65 return LIB_TABLE_ROW::operator == ( aRow ) && type == aRow.type;
66}
67
68
69void SYMBOL_LIB_TABLE_ROW::SetType( const wxString& aType )
70{
72
73 if( type == SCH_IO_MGR::SCH_FILE_UNKNOWN )
74 type = SCH_IO_MGR::SCH_KICAD;
75
76 plugin.reset();
77}
78
79
81{
82 if( !plugin )
83 {
84 wxArrayString dummyList;
85
86 plugin.reset( SCH_IO_MGR::FindPlugin( type ) );
87 SetLoaded( false );
88 plugin->SetLibTable( static_cast<SYMBOL_LIB_TABLE*>( GetParent() ) );
89 plugin->EnumerateSymbolLib( dummyList, GetFullURI( true ), GetProperties() );
90 SetLoaded( true );
91 return true;
92 }
93
94 return false;
95}
96
97
98void SYMBOL_LIB_TABLE_ROW::GetSubLibraryNames( std::vector<wxString>& aNames ) const
99{
100 if( !plugin )
101 return;
102
103 plugin->GetSubLibraryNames( aNames );
104}
105
106
107wxString SYMBOL_LIB_TABLE_ROW::GetSubLibraryDescription( const wxString& aName ) const
108{
109 if( !plugin )
110 return wxEmptyString;
111
112 return plugin->GetSubLibraryDescription( aName );
113}
114
115
116void SYMBOL_LIB_TABLE_ROW::ShowSettingsDialog( wxWindow* aParent ) const
117{
118 wxCHECK( plugin, /* void */ );
119
120 if( type != SCH_IO_MGR::SCH_DATABASE )
121 return;
122
123 DIALOG_DATABASE_LIB_SETTINGS dlg( aParent, static_cast<SCH_IO_DATABASE*>( plugin.get() ) );
124 dlg.ShowModal();
125}
126
127
129 LIB_TABLE( aFallBackTable )
130{
131 // not copying fall back, simply search aFallBackTable separately
132 // if "nickName not found".
133}
134
135
137{
139}
140
141
142void SYMBOL_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
143{
144 T tok;
145 wxString errMsg; // to collect error messages
146
147 // This table may be nested within a larger s-expression, or not.
148 // Allow for parser of that optional containing s-epression to have looked ahead.
149 if( in->CurTok() != T_sym_lib_table )
150 {
151 in->NeedLEFT();
152
153 if( ( tok = in->NextTok() ) != T_sym_lib_table )
154 in->Expecting( T_sym_lib_table );
155 }
156
157 while( ( tok = in->NextTok() ) != T_RIGHT )
158 {
159 std::unique_ptr< SYMBOL_LIB_TABLE_ROW > row = std::make_unique<SYMBOL_LIB_TABLE_ROW>();
160
161 if( tok == T_EOF )
162 in->Expecting( T_RIGHT );
163
164 if( tok != T_LEFT )
165 in->Expecting( T_LEFT );
166
167 // in case there is a "row integrity" error, tell where later.
168 int lineNum = in->CurLineNumber();
169 tok = in->NextTok();
170
171 // Optionally parse the current version number
172 if( tok == T_version )
173 {
174 in->NeedNUMBER( "version" );
175 m_version = std::stoi( in->CurText() );
176 in->NeedRIGHT();
177 continue;
178 }
179
180 if( tok != T_lib )
181 in->Expecting( T_lib );
182
183 // (name NICKNAME)
184 in->NeedLEFT();
185
186 if( ( tok = in->NextTok() ) != T_name )
187 in->Expecting( T_name );
188
189 in->NeedSYMBOLorNUMBER();
190
191 row->SetNickName( in->FromUTF8() );
192
193 in->NeedRIGHT();
194
195 // After (name), remaining (lib) elements are order independent, and in
196 // some cases optional.
197 bool sawType = false;
198 bool sawOpts = false;
199 bool sawDesc = false;
200 bool sawUri = false;
201 bool sawDisabled = false;
202 bool sawHidden = false;
203
204 while( ( tok = in->NextTok() ) != T_RIGHT )
205 {
206 if( tok == T_EOF )
207 in->Unexpected( T_EOF );
208
209 if( tok != T_LEFT )
210 in->Expecting( T_LEFT );
211
212 tok = in->NeedSYMBOLorNUMBER();
213
214 switch( tok )
215 {
216 case T_uri:
217 if( sawUri )
218 in->Duplicate( tok );
219 sawUri = true;
220 in->NeedSYMBOLorNUMBER();
221 row->SetFullURI( in->FromUTF8() );
222 break;
223
224 case T_type:
225 if( sawType )
226 in->Duplicate( tok );
227 sawType = true;
228 in->NeedSYMBOLorNUMBER();
229 row->SetType( in->FromUTF8() );
230 break;
231
232 case T_options:
233 if( sawOpts )
234 in->Duplicate( tok );
235 sawOpts = true;
236 in->NeedSYMBOLorNUMBER();
237 row->SetOptions( in->FromUTF8() );
238 break;
239
240 case T_descr:
241 if( sawDesc )
242 in->Duplicate( tok );
243 sawDesc = true;
244 in->NeedSYMBOLorNUMBER();
245 row->SetDescr( in->FromUTF8() );
246 break;
247
248 case T_disabled:
249 if( sawDisabled )
250 in->Duplicate( tok );
251 sawDisabled = true;
252 row->SetEnabled( false );
253 break;
254
255 case T_hidden:
256 if( sawHidden )
257 in->Duplicate( tok );
258 sawHidden = true;
259 row->SetVisible( false );
260 break;
261
262 default:
263 in->Unexpected( tok );
264 }
265
266 in->NeedRIGHT();
267 }
268
269 if( !sawType )
270 in->Expecting( T_type );
271
272 if( !sawUri )
273 in->Expecting( T_uri );
274
275 // All nickNames within this table fragment must be unique, so we do not use doReplace
276 // in doInsertRow(). (However a fallBack table can have a conflicting nickName and ours
277 // will supercede that one since in FindLib() we search this table before any fall back.)
278 wxString nickname = row->GetNickName(); // store it to be able to used it
279 // after row deletion if an error occurs
280 bool doReplace = false;
281 LIB_TABLE_ROW* tmp = row.release();
282
283 if( !doInsertRow( tmp, doReplace ) )
284 {
285 delete tmp; // The table did not take ownership of the row.
286
287 wxString msg = wxString::Format( _( "Duplicate library nickname '%s' found in symbol "
288 "library table file line %d" ),
289 nickname,
290 lineNum );
291
292 if( !errMsg.IsEmpty() )
293 errMsg << '\n';
294
295 errMsg << msg;
296 }
297 }
298
299 if( !errMsg.IsEmpty() )
300 THROW_IO_ERROR( errMsg );
301}
302
303
304void SYMBOL_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
305{
306 aOutput->Print( aIndentLevel, "(sym_lib_table\n" );
307 aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
308
309 for( const LIB_TABLE_ROW& row : m_rows )
310 row.Format( aOutput, aIndentLevel + 1 );
311
312 aOutput->Print( aIndentLevel, ")\n" );
313}
314
315
317{
318 int hash = 0;
319 std::vector< wxString > libNames = GetLogicalLibs();
320
321 for( const auto& libName : libNames )
322 {
323 const SYMBOL_LIB_TABLE_ROW* row = FindRow( libName, true );
324
325 if( !row || !row->plugin )
326 {
327 continue;
328 }
329
330 hash += row->plugin->GetModifyHash();
331 }
332
333 hash += m_modifyHash;
334
335 return hash;
336}
337
338
339void SYMBOL_LIB_TABLE::EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames,
340 bool aPowerSymbolsOnly )
341{
342 SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
343 wxCHECK( row && row->plugin, /* void */ );
344
345 wxString options = row->GetOptions();
346
347 if( aPowerSymbolsOnly )
348 row->SetOptions( row->GetOptions() + " " + PropPowerSymsOnly );
349
350 row->SetLoaded( false );
351 row->plugin->EnumerateSymbolLib( aAliasNames, row->GetFullURI( true ), row->GetProperties() );
352 row->SetLoaded( true );
353
354 if( aPowerSymbolsOnly )
355 row->SetOptions( options );
356}
357
358
359SYMBOL_LIB_TABLE_ROW* SYMBOL_LIB_TABLE::FindRow( const wxString& aNickname, bool aCheckIfEnabled )
360{
362 dynamic_cast< SYMBOL_LIB_TABLE_ROW* >( findRow( aNickname, aCheckIfEnabled ) );
363
364 if( !row )
365 return nullptr;
366
367 // We've been 'lazy' up until now, but it cannot be deferred any longer,
368 // instantiate a PLUGIN of the proper kind if it is not already in this
369 // SYMBOL_LIB_TABLE_ROW.
370 if( !row->plugin )
371 row->setPlugin( SCH_IO_MGR::FindPlugin( row->type ) );
372
373 row->plugin->SetLibTable( this );
374
375 return row;
376}
377
378
379void SYMBOL_LIB_TABLE::LoadSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
380 const wxString& aNickname, bool aPowerSymbolsOnly )
381{
382 SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
383
384 if( !row || !row->plugin )
385 return;
386
387 std::lock_guard<std::mutex> lock( row->GetMutex() );
388
389 wxString options = row->GetOptions();
390
391 if( aPowerSymbolsOnly )
392 row->SetOptions( row->GetOptions() + " " + PropPowerSymsOnly );
393
394 row->SetLoaded( false );
395 row->plugin->SetLibTable( this );
396 row->plugin->EnumerateSymbolLib( aSymbolList, row->GetFullURI( true ), row->GetProperties() );
397 row->SetLoaded( true );
398
399 if( aPowerSymbolsOnly )
400 row->SetOptions( options );
401
402 // The library cannot know its own name, because it might have been renamed or moved.
403 // Therefore footprints cannot know their own library nickname when residing in
404 // a symbol library.
405 // Only at this API layer can we tell the symbol about its actual library nickname.
406 for( LIB_SYMBOL* symbol : aSymbolList )
407 {
408 LIB_ID id = symbol->GetLibId();
409
410 id.SetLibNickname( row->GetNickName() );
411 symbol->SetLibId( id );
412 }
413}
414
415
416LIB_SYMBOL* SYMBOL_LIB_TABLE::LoadSymbol( const wxString& aNickname, const wxString& aSymbolName )
417{
418 SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
419
420 if( !row || !row->plugin )
421 return nullptr;
422
423 // If another thread is loading this library at the moment; continue
424 std::unique_lock<std::mutex> lock( row->GetMutex(), std::try_to_lock );
425
426 if( !lock.owns_lock() )
427 return nullptr;
428
429 LIB_SYMBOL* symbol = row->plugin->LoadSymbol( row->GetFullURI( true ), aSymbolName,
430 row->GetProperties() );
431
432 if( symbol )
433 {
434 // The library cannot know its own name, because it might have been renamed or moved.
435 // Therefore footprints cannot know their own library nickname when residing in
436 // a symbol library.
437 // Only at this API layer can we tell the symbol about its actual library nickname.
438 LIB_ID id = symbol->GetLibId();
439
440 id.SetLibNickname( row->GetNickName() );
441 symbol->SetLibId( id );
442
443 SIM_MODEL::MigrateSimModel<LIB_SYMBOL>( *symbol, nullptr );
444 }
445
446 return symbol;
447}
448
449
451 const LIB_SYMBOL* aSymbol, bool aOverwrite )
452{
453 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
454 wxCHECK( row && row->plugin, SAVE_SKIPPED );
455
456 if( !row->plugin->IsLibraryWritable( row->GetFullURI( true ) ) )
457 return SAVE_SKIPPED;
458
459 if( !aOverwrite )
460 {
461 // Try loading the footprint to see if it already exists, caller wants overwrite
462 // protection, which is atypical, not the default.
463
464 wxString name = aSymbol->GetLibId().GetLibItemName();
465
466 std::unique_ptr<LIB_SYMBOL> symbol( row->plugin->LoadSymbol( row->GetFullURI( true ),
467 name, row->GetProperties() ) );
468
469 if( symbol.get() )
470 return SAVE_SKIPPED;
471 }
472
473 try
474 {
475 row->plugin->SaveSymbol( row->GetFullURI( true ), aSymbol, row->GetProperties() );
476 }
477 catch( const IO_ERROR& )
478 {
479 return SAVE_SKIPPED;
480 }
481
482 return SAVE_OK;
483}
484
485
486void SYMBOL_LIB_TABLE::DeleteSymbol( const wxString& aNickname, const wxString& aSymbolName )
487{
488 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
489 wxCHECK( row && row->plugin, /* void */ );
490 return row->plugin->DeleteSymbol( row->GetFullURI( true ), aSymbolName, row->GetProperties() );
491}
492
493
494bool SYMBOL_LIB_TABLE::IsSymbolLibWritable( const wxString& aNickname )
495{
496 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
497 wxCHECK( row && row->plugin, false );
498 return row->plugin->IsLibraryWritable( row->GetFullURI( true ) );
499}
500
501bool SYMBOL_LIB_TABLE::IsSymbolLibLoaded( const wxString& aNickname )
502{
503 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
504 wxCHECK( row, false );
505 return row->GetIsLoaded();
506}
507
508
509void SYMBOL_LIB_TABLE::DeleteSymbolLib( const wxString& aNickname )
510{
511 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
512 wxCHECK( row && row->plugin, /* void */ );
513 row->plugin->DeleteLibrary( row->GetFullURI( true ), row->GetProperties() );
514}
515
516
517void SYMBOL_LIB_TABLE::CreateSymbolLib( const wxString& aNickname )
518{
519 const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname, true );
520 wxCHECK( row && row->plugin, /* void */ );
521 row->plugin->CreateLibrary( row->GetFullURI( true ), row->GetProperties() );
522}
523
524
526{
527 wxString nickname = aLibId.GetLibNickname();
528 wxString name = aLibId.GetLibItemName();
529
530 if( nickname.size() )
531 {
532 return LoadSymbol( nickname, name );
533 }
534 else
535 {
536 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
537 std::vector<wxString> nicks = GetLogicalLibs();
538
539 // Search each library going through libraries alphabetically.
540 for( unsigned i = 0; i < nicks.size(); ++i )
541 {
542 // FootprintLoad() returns NULL on not found, does not throw exception
543 // unless there's an IO_ERROR.
544 LIB_SYMBOL* ret = LoadSymbol( nicks[i], name );
545
546 if( ret )
547 return ret;
548 }
549
550 return nullptr;
551 }
552}
553
554
556{
557 return ENV_VAR::GetVersionedEnvVarName( wxS( "SYMBOL_DIR" ) );
558}
559
560
561class PCM_SYM_LIB_TRAVERSER final : public wxDirTraverser
562{
563public:
564 explicit PCM_SYM_LIB_TRAVERSER( const wxString& aPath, SYMBOL_LIB_TABLE& aTable,
565 const wxString& aPrefix ) :
566 m_lib_table( aTable ),
567 m_path_prefix( aPath ),
568 m_lib_prefix( aPrefix )
569 {
570 wxFileName f( aPath, "" );
571 m_prefix_dir_count = f.GetDirCount();
572 }
573
574 wxDirTraverseResult OnFile( const wxString& aFilePath ) override
575 {
576 wxFileName file = wxFileName::FileName( aFilePath );
577
578 // consider a file to be a lib if it's name ends with .kicad_sym and
579 // it is under $KICADn_3RD_PARTY/symbols/<pkgid>/ i.e. has nested level of at least +2
580 if( file.GetExt() == wxT( "kicad_sym" ) && file.GetDirCount() >= m_prefix_dir_count + 2 )
581 {
582 wxString versionedPath = wxString::Format( wxS( "${%s}" ),
583 ENV_VAR::GetVersionedEnvVarName( wxS( "3RD_PARTY" ) ) );
584
585 wxArrayString parts = file.GetDirs();
586 parts.RemoveAt( 0, m_prefix_dir_count );
587 parts.Insert( versionedPath, 0 );
588 parts.Add( file.GetFullName() );
589
590 wxString libPath = wxJoin( parts, '/' );
591
592 if( !m_lib_table.HasLibraryWithPath( libPath ) )
593 {
594 wxString name = parts.Last().substr( 0, parts.Last().length() - 10 );
595 wxString nickname = wxString::Format( "%s%s", m_lib_prefix, name );
596
597 if( m_lib_table.HasLibrary( nickname ) )
598 {
599 int increment = 1;
600 do
601 {
602 nickname = wxString::Format( "%s%s_%d", m_lib_prefix, name, increment );
603 increment++;
604 } while( m_lib_table.HasLibrary( nickname ) );
605 }
606
608 new SYMBOL_LIB_TABLE_ROW( nickname, libPath, wxT( "KiCad" ), wxEmptyString,
609 _( "Added by Plugin and Content Manager" ) ), false );
610 }
611 }
612
613 return wxDIR_CONTINUE;
614 }
615
616 wxDirTraverseResult OnDir( const wxString& dirPath ) override { return wxDIR_CONTINUE; }
617
618private:
621 wxString m_lib_prefix;
623};
624
625
627{
628 bool tableExists = true;
629 wxFileName fn = GetGlobalTableFileName();
630
631 if( !fn.FileExists() )
632 {
633 tableExists = false;
634
635 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
636 {
637 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
638 fn.GetPath() ) );
639 }
640
641 // Attempt to copy the default global file table from the KiCad
642 // template folder to the user's home configuration path.
643 SEARCH_STACK ss;
644
645 SystemDirsAppend( &ss );
646
647 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
648 std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( envVars,
649 wxT( "TEMPLATE_DIR" ) );
650
651 if( v && !v->IsEmpty() )
652 ss.AddPaths( *v, 0 );
653
654 wxString fileName = ss.FindValidPath( global_tbl_name );
655
656 // The fallback is to create an empty global symbol table for the user to populate.
657 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
658 {
659 SYMBOL_LIB_TABLE emptyTable;
660
661 emptyTable.Save( fn.GetFullPath() );
662 }
663 }
664
665 aTable.Load( fn.GetFullPath() );
666
668 KICAD_SETTINGS* settings = mgr.GetAppSettings<KICAD_SETTINGS>( "kicad" );
669
670 wxCHECK( settings, false );
671
672 wxString packagesPath;
673 const ENV_VAR_MAP& vars = Pgm().GetLocalEnvVariables();
674
675 if( std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( vars, wxT( "3RD_PARTY" ) ) )
676 packagesPath = *v;
677
678 if( settings->m_PcmLibAutoAdd )
679 {
680 // Scan for libraries in PCM packages directory
681 wxFileName d( packagesPath, "" );
682 d.AppendDir( "symbols" );
683
684 if( d.DirExists() )
685 {
686 PCM_SYM_LIB_TRAVERSER traverser( packagesPath, aTable, settings->m_PcmLibPrefix );
687 wxDir dir( d.GetPath() );
688
689 dir.Traverse( traverser );
690 }
691 }
692
693 if( settings->m_PcmLibAutoRemove )
694 {
695 // Remove PCM libraries that no longer exist
696 std::vector<wxString> to_remove;
697
698 for( size_t i = 0; i < aTable.GetCount(); i++ )
699 {
700 LIB_TABLE_ROW& row = aTable.At( i );
701 wxString path = row.GetFullURI( true );
702
703 if( path.StartsWith( packagesPath ) && !wxFile::Exists( path ) )
704 to_remove.push_back( row.GetNickName() );
705 }
706
707 for( const wxString& nickName : to_remove )
708 {
709 SYMBOL_LIB_TABLE_ROW* row = aTable.FindRow( nickName );
710
711 wxCHECK2( row, continue );
712
713 aTable.RemoveRow( row );
714 }
715 }
716
717 return tableExists;
718}
719
720
722{
723 if( m_rows.size() != aOther.m_rows.size() )
724 return false;
725
726 unsigned i;
727
728 for( i = 0; i < m_rows.size(); ++i )
729 {
730 const SYMBOL_LIB_TABLE_ROW& curr = static_cast<const SYMBOL_LIB_TABLE_ROW&>( m_rows[i] );
731 const SYMBOL_LIB_TABLE_ROW& curr_other = static_cast<const SYMBOL_LIB_TABLE_ROW&>( aOther.m_rows[i] );
732
733 if( curr != curr_other )
734 return false;
735 }
736
737 return true;
738}
739
740
742{
743 wxFileName fn;
744
745 fn.SetPath( PATHS::GetUserSettingsPath() );
746 fn.SetName( global_tbl_name );
747
748 return fn.GetFullPath();
749}
750
751
753{
754 return global_tbl_name;
755}
const char * name
Definition: DXF_plotter.cpp:57
int ShowModal() override
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
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
Define a library symbol object.
Definition: lib_symbol.h:78
const LIB_ID & GetLibId() const override
Definition: lib_symbol.h:143
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:144
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
const std::map< std::string, UTF8 > * GetProperties() const
Return the constant #PROPERTIES for this library (LIB_TABLE_ROW).
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.
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:458
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition: paths.cpp:531
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)
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition: pgm_base.cpp:924
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
A KiCad database library provides both symbol and footprint metadata, so there are "shim" plugins on ...
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:107
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(const wxString &aFilename)
Returns a handle to the a given settings by type If the settings have already been loaded,...
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
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
bool Refresh() override
Attempt to reload the library.
void setPlugin(SCH_IO *aPlugin)
void ShowSettingsDialog(wxWindow *aWindow) const override
wxString GetSubLibraryDescription(const wxString &aName) const
IO_RELEASER< SCH_IO > 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
bool operator==(const SYMBOL_LIB_TABLE &aOther) const
Compares this table against another.
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()
static const wxChar global_tbl_name[]
#define _(s)
Functions related to environment variables, including help functions.
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
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
SYMBOL_LIB_TABLE g_symbolLibraryTable
The global symbol library 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.