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