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: in->Unexpected( tok );
209 }
210
211 in->NeedRIGHT();
212 }
213
214 if( !sawType )
215 in->Expecting( T_type );
216
217 if( !sawUri )
218 in->Expecting( T_uri );
219
220 // All nickNames within this table fragment must be unique, so we do not use doReplace
221 // in doInsertRow(). (However a fallBack table can have a conflicting nickName and ours
222 // will supercede that one since in FindLib() we search this table before any fall back.)
223 wxString nickname = row->GetNickName(); // store it to be able to used it
224 // after row deletion if an error occurs
225 bool doReplace = false;
226 LIB_TABLE_ROW* tmp = row.release();
227
228 if( !doInsertRow( tmp, doReplace ) )
229 {
230 delete tmp; // The table did not take ownership of the row.
231
232 wxString msg = wxString::Format( _( "Duplicate library nickname '%s' found in "
233 "design block library table file line %d." ),
234 nickname, lineNum );
235
236 if( !errMsg.IsEmpty() )
237 errMsg << '\n';
238
239 errMsg << msg;
240 }
241 }
242
243 if( !errMsg.IsEmpty() )
244 THROW_IO_ERROR( errMsg );
245}
246
247
248bool DESIGN_BLOCK_LIB_TABLE::operator==( const DESIGN_BLOCK_LIB_TABLE& aDesignBlockTable ) const
249{
250 if( m_rows.size() == aDesignBlockTable.m_rows.size() )
251 {
252 for( unsigned i = 0; i < m_rows.size(); ++i )
253 {
255 != (DESIGN_BLOCK_LIB_TABLE_ROW&) aDesignBlockTable.m_rows[i] )
256 return false;
257 }
258
259 return true;
260 }
261
262 return false;
263}
264
265
266void DESIGN_BLOCK_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
267{
268 aOutput->Print( aIndentLevel, "(design_block_lib_table\n" );
269 aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
270
271 for( LIB_TABLE_ROWS_CITER it = m_rows.begin(); it != m_rows.end(); ++it )
272 it->Format( aOutput, aIndentLevel + 1 );
273
274 aOutput->Print( aIndentLevel, ")\n" );
275}
276
277
278long long DESIGN_BLOCK_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
279{
280 long long hash = 0;
281
282 if( aNickname )
283 {
284 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( *aNickname, true );
285
286 wxCHECK( row && row->plugin, hash );
287
288 return row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) )
289 + wxHashTable::MakeKey( *aNickname );
290 }
291
292 for( const wxString& nickname : GetLogicalLibs() )
293 {
294 const DESIGN_BLOCK_LIB_TABLE_ROW* row = nullptr;
295
296 try
297 {
298 row = FindRow( nickname, true );
299 }
300 catch( ... )
301 {
302 // Do nothing if not found: just skip.
303 }
304
305 wxCHECK2( row && row->plugin, continue );
306
307 hash += row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) )
308 + wxHashTable::MakeKey( nickname );
309 }
310
311 return hash;
312}
313
314
315void DESIGN_BLOCK_LIB_TABLE::DesignBlockEnumerate( wxArrayString& aDesignBlockNames,
316 const wxString& aNickname, bool aBestEfforts )
317{
318 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
319 wxASSERT( row->plugin );
320 row->plugin->DesignBlockEnumerate( aDesignBlockNames, row->GetFullURI( true ), aBestEfforts,
321 row->GetProperties() );
322}
323
324
326 bool aCheckIfEnabled )
327{
329 static_cast<DESIGN_BLOCK_LIB_TABLE_ROW*>( findRow( aNickname, aCheckIfEnabled ) );
330
331 if( !row )
332 {
333 wxString msg = wxString::Format(
334 _( "design-block-lib-table files contain no library named '%s'." ), aNickname );
335 THROW_IO_ERROR( msg );
336 }
337
338 if( !row->plugin )
340
341 return row;
342}
343
344
345static void setLibNickname( DESIGN_BLOCK* aModule, const wxString& aNickname,
346 const wxString& aDesignBlockName )
347{
348 // The library cannot know its own name, because it might have been renamed or moved.
349 // Therefore design blocks cannot know their own library nickname when residing in
350 // a design block library.
351 // Only at this API layer can we tell the design block about its actual library nickname.
352 if( aModule )
353 {
354 // remove "const"-ness, I really do want to set nickname without
355 // having to copy the LIB_ID and its two strings, twice each.
356 LIB_ID& dbid = (LIB_ID&) aModule->GetLibId();
357
358 // Catch any misbehaving plugin, which should be setting internal design block name
359 // properly:
360 wxASSERT( aDesignBlockName == dbid.GetLibItemName().wx_str() );
361
362 // and clearing nickname
363 wxASSERT( !dbid.GetLibNickname().size() );
364
365 dbid.SetLibNickname( aNickname );
366 }
367}
368
369
370const DESIGN_BLOCK*
372 const wxString& aDesignBlockName )
373{
374 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
375 wxASSERT( row->plugin );
376
377 return row->plugin->GetEnumeratedDesignBlock( row->GetFullURI( true ), aDesignBlockName,
378 row->GetProperties() );
379}
380
381
382bool DESIGN_BLOCK_LIB_TABLE::DesignBlockExists( const wxString& aNickname,
383 const wxString& aDesignBlockName )
384{
385 try
386 {
387 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
388 wxASSERT( row->plugin );
389
390 return row->plugin->DesignBlockExists( row->GetFullURI( true ), aDesignBlockName,
391 row->GetProperties() );
392 }
393 catch( ... )
394 {
395 return false;
396 }
397}
398
399
401 const wxString& aDesignBlockName,
402 bool aKeepUUID )
403{
404 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
405 wxASSERT( row->plugin );
406
407 DESIGN_BLOCK* ret = row->plugin->DesignBlockLoad( row->GetFullURI( true ), aDesignBlockName,
408 aKeepUUID, row->GetProperties() );
409
410 setLibNickname( ret, row->GetNickName(), aDesignBlockName );
411
412 return ret;
413}
414
415
418 const DESIGN_BLOCK* aDesignBlock, bool aOverwrite )
419{
420 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
421 wxASSERT( row->plugin );
422
423 if( !aOverwrite )
424 {
425 // Try loading the design block to see if it already exists, caller wants overwrite
426 // protection, which is atypical, not the default.
427
428 wxString DesignBlockname = aDesignBlock->GetLibId().GetLibItemName();
429
430 std::unique_ptr<DESIGN_BLOCK> design_block( row->plugin->DesignBlockLoad(
431 row->GetFullURI( true ), DesignBlockname, row->GetProperties() ) );
432
433 if( design_block.get() )
434 return SAVE_SKIPPED;
435 }
436
437 row->plugin->DesignBlockSave( row->GetFullURI( true ), aDesignBlock, row->GetProperties() );
438
439 return SAVE_OK;
440}
441
442
443void DESIGN_BLOCK_LIB_TABLE::DesignBlockDelete( const wxString& aNickname,
444 const wxString& aDesignBlockName )
445
446{
447 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
448 wxASSERT( row->plugin );
449 return row->plugin->DesignBlockDelete( row->GetFullURI( true ), aDesignBlockName,
450 row->GetProperties() );
451}
452
453
455{
456 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
457 wxASSERT( row->plugin );
458 return row->plugin->IsLibraryWritable( row->GetFullURI( true ) );
459}
460
461
462void DESIGN_BLOCK_LIB_TABLE::DesignBlockLibDelete( const wxString& aNickname )
463{
464 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
465 wxASSERT( row->plugin );
466 row->plugin->DeleteLibrary( row->GetFullURI( true ), row->GetProperties() );
467}
468
469
470void DESIGN_BLOCK_LIB_TABLE::DesignBlockLibCreate( const wxString& aNickname )
471{
472 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
473 wxASSERT( row->plugin );
474 row->plugin->CreateLibrary( row->GetFullURI( true ), row->GetProperties() );
475}
476
477
480 bool aKeepUUID )
481{
482 wxString nickname = aDesignBlockId.GetLibNickname();
483 wxString DesignBlockname = aDesignBlockId.GetLibItemName();
484
485 if( nickname.size() )
486 {
487 return DesignBlockLoad( nickname, DesignBlockname, aKeepUUID );
488 }
489
490 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
491 else
492 {
493 std::vector<wxString> nicks = GetLogicalLibs();
494
495 // Search each library going through libraries alphabetically.
496 for( unsigned i = 0; i < nicks.size(); ++i )
497 {
498 // DesignBlockLoad() returns NULL on not found, does not throw exception
499 // unless there's an IO_ERROR.
500 DESIGN_BLOCK* ret = DesignBlockLoad( nicks[i], DesignBlockname, aKeepUUID );
501
502 if( ret )
503 return ret;
504 }
505
506 return nullptr;
507 }
508}
509
510
512{
513 return ENV_VAR::GetVersionedEnvVarName( wxS( "DESIGN_BLOCK_DIR" ) );
514}
515
516
517class PCM_DESIGN_BLOCK_LIB_TRAVERSER final : public wxDirTraverser
518{
519public:
520 explicit PCM_DESIGN_BLOCK_LIB_TRAVERSER( const wxString& aPath, DESIGN_BLOCK_LIB_TABLE& aTable,
521 const wxString& aPrefix ) :
522 m_lib_table( aTable ),
523 m_path_prefix( aPath ), m_lib_prefix( aPrefix )
524 {
525 wxFileName f( aPath, wxS( "" ) );
526 m_prefix_dir_count = f.GetDirCount();
527 }
528
529 wxDirTraverseResult OnFile( const wxString& aFilePath ) override { return wxDIR_CONTINUE; }
530
531 wxDirTraverseResult OnDir( const wxString& dirPath ) override
532 {
533 wxFileName dir = wxFileName::DirName( dirPath );
534
535 // consider a directory to be a lib if it's name ends with the design block lib dir
536 // extension it is under $KICADn_3RD_PARTY/design_blocks/<pkgid>/ i.e. has nested
537 // level of at least +3.
538 if( dirPath.EndsWith( wxString::Format( wxS( ".%s" ),
540 && dir.GetDirCount() >= m_prefix_dir_count + 3 )
541 {
542 wxString versionedPath = wxString::Format(
543 wxS( "${%s}" ), 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 =
562 wxString::Format( wxS( "%s%s_%d" ), m_lib_prefix, name, increment );
563 increment++;
564 } while( m_lib_table.HasLibrary( nickname ) );
565 }
566
568 nickname, libPath, wxT( "KiCad" ), wxEmptyString,
569 _( "Added by Plugin and Content Manager" ) ) );
570 }
571 }
572
573 return wxDIR_CONTINUE;
574 }
575
576private:
579 wxString m_lib_prefix;
581};
582
583
585{
586 bool tableExists = true;
587 wxFileName fn = GetGlobalTableFileName();
588
589 if( !fn.FileExists() )
590 {
591 tableExists = false;
592
593 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
594 {
595 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
596 fn.GetPath() ) );
597 }
598
599 // Attempt to copy the default global file table from the KiCad
600 // template folder to the user's home configuration path.
601 SEARCH_STACK ss;
602
603 SystemDirsAppend( &ss );
604
605 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
606 std::optional<wxString> v =
607 ENV_VAR::GetVersionedEnvVarValue( envVars, wxT( "TEMPLATE_DIR" ) );
608
609 if( v && !v->IsEmpty() )
610 ss.AddPaths( *v, 0 );
611
612 wxString fileName = ss.FindValidPath( FILEEXT::DesignBlockLibraryTableFileName );
613
614 // The fallback is to create an empty global design block table for the user to populate.
615 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
616 {
617 DESIGN_BLOCK_LIB_TABLE emptyTable;
618
619 emptyTable.Save( fn.GetFullPath() );
620 }
621 }
622
623 aTable.clear();
624 aTable.Load( fn.GetFullPath() );
625
627 KICAD_SETTINGS* settings = mgr.GetAppSettings<KICAD_SETTINGS>( "kicad" );
628
629 const ENV_VAR_MAP& env = Pgm().GetLocalEnvVariables();
630 wxString packagesPath;
631
632 if( std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( env, wxT( "3RD_PARTY" ) ) )
633 packagesPath = *v;
634
635 if( settings->m_PcmLibAutoAdd )
636 {
637 // Scan for libraries in PCM packages directory
638
639 wxFileName d( packagesPath, wxS( "" ) );
640 d.AppendDir( wxS( "design_blocks" ) );
641
642 if( d.DirExists() )
643 {
644 PCM_DESIGN_BLOCK_LIB_TRAVERSER traverser( packagesPath, aTable,
645 settings->m_PcmLibPrefix );
646 wxDir dir( d.GetPath() );
647
648 dir.Traverse( traverser );
649 }
650 }
651
652 if( settings->m_PcmLibAutoRemove )
653 {
654 // Remove PCM libraries that no longer exist
655 std::vector<wxString> to_remove;
656
657 for( size_t i = 0; i < aTable.GetCount(); i++ )
658 {
659 LIB_TABLE_ROW& row = aTable.At( i );
660 wxString path = row.GetFullURI( true );
661
662 if( path.StartsWith( packagesPath ) && !wxDir::Exists( path ) )
663 to_remove.push_back( row.GetNickName() );
664 }
665
666 for( const wxString& nickName : to_remove )
667 aTable.RemoveRow( aTable.FindRow( nickName ) );
668 }
669
670 return tableExists;
671}
672
673
675{
676 return GDesignBlockTable;
677}
678
679
681{
682 return GDesignBlockList;
683}
684
685
687{
688 wxFileName fn;
689
690 fn.SetPath( PATHS::GetUserSettingsPath() );
692
693 return fn.GetFullPath();
694}
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
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)
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.