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{
78 if( !plugin )
79 {
80 wxArrayString dummyList;
81
83 SetLoaded( false );
84 plugin->DesignBlockEnumerate( dummyList, GetFullURI( true ), true, GetProperties() );
85 SetLoaded( true );
86 return true;
87 }
88
89 return false;
90}
91
92
94 LIB_TABLE( aFallBackTable )
95{
96 // not copying fall back, simply search aFallBackTable separately
97 // if "nickName not found".
98}
99
100
101void DESIGN_BLOCK_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
102{
103 T tok;
104 wxString errMsg; // to collect error messages
105
106 // This table may be nested within a larger s-expression, or not.
107 // Allow for parser of that optional containing s-epression to have looked ahead.
108 if( in->CurTok() != T_design_block_lib_table )
109 {
110 in->NeedLEFT();
111
112 if( ( tok = in->NextTok() ) != T_design_block_lib_table )
113 in->Expecting( T_design_block_lib_table );
114 }
115
116 while( ( tok = in->NextTok() ) != T_RIGHT )
117 {
118 std::unique_ptr<DESIGN_BLOCK_LIB_TABLE_ROW> row =
119 std::make_unique<DESIGN_BLOCK_LIB_TABLE_ROW>();
120
121 if( tok == T_EOF )
122 in->Expecting( T_RIGHT );
123
124 if( tok != T_LEFT )
125 in->Expecting( T_LEFT );
126
127 // in case there is a "row integrity" error, tell where later.
128 int lineNum = in->CurLineNumber();
129 tok = in->NextTok();
130
131 // Optionally parse the current version number
132 if( tok == T_version )
133 {
134 in->NeedNUMBER( "version" );
135 m_version = std::stoi( in->CurText() );
136 in->NeedRIGHT();
137 continue;
138 }
139
140 if( tok != T_lib )
141 in->Expecting( T_lib );
142
143 // (name NICKNAME)
144 in->NeedLEFT();
145
146 if( ( tok = in->NextTok() ) != T_name )
147 in->Expecting( T_name );
148
149 in->NeedSYMBOLorNUMBER();
150
151 row->SetNickName( in->FromUTF8() );
152
153 in->NeedRIGHT();
154
155 // After (name), remaining (lib) elements are order independent, and in
156 // some cases optional.
157 bool sawType = false;
158 bool sawOpts = false;
159 bool sawDesc = false;
160 bool sawUri = false;
161 bool sawDisabled = false;
162
163 while( ( tok = in->NextTok() ) != T_RIGHT )
164 {
165 if( tok == T_EOF )
166 in->Unexpected( T_EOF );
167
168 if( tok != T_LEFT )
169 in->Expecting( T_LEFT );
170
171 tok = in->NeedSYMBOLorNUMBER();
172
173 switch( tok )
174 {
175 case T_uri:
176 if( sawUri )
177 in->Duplicate( tok );
178
179 sawUri = true;
180 in->NeedSYMBOLorNUMBER();
181 row->SetFullURI( in->FromUTF8() );
182 break;
183
184 case T_type:
185 if( sawType )
186 in->Duplicate( tok );
187
188 sawType = true;
189 in->NeedSYMBOLorNUMBER();
190 row->SetType( in->FromUTF8() );
191 break;
192
193 case T_options:
194 if( sawOpts )
195 in->Duplicate( tok );
196
197 sawOpts = true;
198 in->NeedSYMBOLorNUMBER();
199 row->SetOptions( in->FromUTF8() );
200 break;
201
202 case T_descr:
203 if( sawDesc )
204 in->Duplicate( tok );
205
206 sawDesc = true;
207 in->NeedSYMBOLorNUMBER();
208 row->SetDescr( in->FromUTF8() );
209 break;
210
211 case T_disabled:
212 if( sawDisabled )
213 in->Duplicate( tok );
214
215 sawDisabled = true;
216 row->SetEnabled( false );
217 break;
218
219 case T_hidden:
220 // Hiding design block libraries is not yet supported. Unclear what path can
221 // set this attribute, but clear it on load.
222 row->SetVisible();
223 break;
224
225 default:
226 in->Unexpected( tok );
227 }
228
229 in->NeedRIGHT();
230 }
231
232 if( !sawType )
233 in->Expecting( T_type );
234
235 if( !sawUri )
236 in->Expecting( T_uri );
237
238 // All nickNames within this table fragment must be unique, so we do not use doReplace
239 // in doInsertRow(). (However a fallBack table can have a conflicting nickName and ours
240 // will supercede that one since in FindLib() we search this table before any fall back.)
241 wxString nickname = row->GetNickName(); // store it to be able to used it
242 // after row deletion if an error occurs
243 bool doReplace = false;
244 LIB_TABLE_ROW* tmp = row.release();
245
246 if( !doInsertRow( tmp, doReplace ) )
247 {
248 delete tmp; // The table did not take ownership of the row.
249
250 wxString msg = wxString::Format( _( "Duplicate library nickname '%s' found in "
251 "design block library table file line %d." ),
252 nickname, lineNum );
253
254 if( !errMsg.IsEmpty() )
255 errMsg << '\n';
256
257 errMsg << msg;
258 }
259 }
260
261 if( !errMsg.IsEmpty() )
262 THROW_IO_ERROR( errMsg );
263}
264
265
266bool DESIGN_BLOCK_LIB_TABLE::operator==( const DESIGN_BLOCK_LIB_TABLE& aDesignBlockTable ) const
267{
268 if( m_rows.size() == aDesignBlockTable.m_rows.size() )
269 {
270 for( unsigned i = 0; i < m_rows.size(); ++i )
271 {
273 != (DESIGN_BLOCK_LIB_TABLE_ROW&) aDesignBlockTable.m_rows[i] )
274 {
275 return false;
276 }
277 }
278
279 return true;
280 }
281
282 return false;
283}
284
285
286void DESIGN_BLOCK_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
287{
288 aOutput->Print( aIndentLevel, "(design_block_lib_table\n" );
289 aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
290
291 for( const LIB_TABLE_ROW& row : m_rows)
292 row.Format( aOutput, aIndentLevel + 1 );
293
294 aOutput->Print( aIndentLevel, ")\n" );
295}
296
297
298long long DESIGN_BLOCK_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
299{
300 long long hash = 0;
301
302 if( aNickname )
303 {
304 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( *aNickname, true );
305
306 wxCHECK( row && row->plugin, hash );
307
308 return row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) )
309 + wxHashTable::MakeKey( *aNickname );
310 }
311
312 for( const wxString& nickname : GetLogicalLibs() )
313 {
314 const DESIGN_BLOCK_LIB_TABLE_ROW* row = nullptr;
315
316 try
317 {
318 row = FindRow( nickname, true );
319 }
320 catch( ... )
321 {
322 // Do nothing if not found: just skip.
323 }
324
325 wxCHECK2( row && row->plugin, continue );
326
327 hash += row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) )
328 + wxHashTable::MakeKey( nickname );
329 }
330
331 return hash;
332}
333
334
335void DESIGN_BLOCK_LIB_TABLE::DesignBlockEnumerate( wxArrayString& aDesignBlockNames, const wxString& aNickname,
336 bool aBestEfforts )
337{
338 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
339 wxASSERT( row->plugin );
340
341 row->plugin->DesignBlockEnumerate( aDesignBlockNames, row->GetFullURI( true ), aBestEfforts,
342 row->GetProperties() );
343}
344
345
347 bool aCheckIfEnabled )
348{
350 static_cast<DESIGN_BLOCK_LIB_TABLE_ROW*>( findRow( aNickname, aCheckIfEnabled ) );
351
352 if( !row )
353 {
354 THROW_IO_ERROR( wxString::Format( _( "design-block-lib-table files contain no library "
355 "named '%s'." ),
356 aNickname ) );
357 }
358
359 if( !row->plugin )
361
362 return row;
363}
364
365
366static void setLibNickname( DESIGN_BLOCK* aModule, const wxString& aNickname,
367 const wxString& aDesignBlockName )
368{
369 // The library cannot know its own name, because it might have been renamed or moved.
370 // Therefore design blocks cannot know their own library nickname when residing in
371 // a design block library.
372 // Only at this API layer can we tell the design block about its actual library nickname.
373 if( aModule )
374 {
375 // remove "const"-ness, I really do want to set nickname without
376 // having to copy the LIB_ID and its two strings, twice each.
377 LIB_ID& dbid = (LIB_ID&) aModule->GetLibId();
378
379 // Catch any misbehaving plugin, which should be setting internal design block name
380 // properly:
381 wxASSERT( aDesignBlockName == dbid.GetLibItemName().wx_str() );
382
383 // and clearing nickname
384 wxASSERT( !dbid.GetLibNickname().size() );
385
386 dbid.SetLibNickname( aNickname );
387 }
388}
389
390
391const DESIGN_BLOCK*
393 const wxString& aDesignBlockName )
394{
395 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
396 wxASSERT( row->plugin );
397
398 return row->plugin->GetEnumeratedDesignBlock( row->GetFullURI( true ), aDesignBlockName,
399 row->GetProperties() );
400}
401
402
403bool DESIGN_BLOCK_LIB_TABLE::DesignBlockExists( const wxString& aNickname,
404 const wxString& aDesignBlockName )
405{
406 try
407 {
408 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
409 wxASSERT( row->plugin );
410
411 return row->plugin->DesignBlockExists( row->GetFullURI( true ), aDesignBlockName,
412 row->GetProperties() );
413 }
414 catch( ... )
415 {
416 return false;
417 }
418}
419
420
422 const wxString& aDesignBlockName,
423 bool aKeepUUID )
424{
425 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
426 wxASSERT( row->plugin );
427
428 DESIGN_BLOCK* ret = row->plugin->DesignBlockLoad( row->GetFullURI( true ), aDesignBlockName,
429 aKeepUUID, row->GetProperties() );
430
431 setLibNickname( ret, row->GetNickName(), aDesignBlockName );
432
433 return ret;
434}
435
436
439 const DESIGN_BLOCK* aDesignBlock, bool aOverwrite )
440{
441 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
442 wxASSERT( row->plugin );
443
444 if( !aOverwrite )
445 {
446 // Try loading the design block to see if it already exists, caller wants overwrite
447 // protection, which is atypical, not the default.
448
449 wxString DesignBlockname = aDesignBlock->GetLibId().GetLibItemName();
450
451 std::unique_ptr<DESIGN_BLOCK> design_block( row->plugin->DesignBlockLoad(
452 row->GetFullURI( true ), DesignBlockname, row->GetProperties() ) );
453
454 if( design_block )
455 return SAVE_SKIPPED;
456 }
457
458 row->plugin->DesignBlockSave( row->GetFullURI( true ), aDesignBlock, row->GetProperties() );
459
460 return SAVE_OK;
461}
462
463
464void DESIGN_BLOCK_LIB_TABLE::DesignBlockDelete( const wxString& aNickname,
465 const wxString& aDesignBlockName )
466
467{
468 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
469 wxASSERT( row->plugin );
470 return row->plugin->DesignBlockDelete( row->GetFullURI( true ), aDesignBlockName,
471 row->GetProperties() );
472}
473
474
476{
477 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
478 wxASSERT( row->plugin );
479 return row->plugin->IsLibraryWritable( row->GetFullURI( true ) );
480}
481
482
483void DESIGN_BLOCK_LIB_TABLE::DesignBlockLibDelete( const wxString& aNickname )
484{
485 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
486 wxASSERT( row->plugin );
487 row->plugin->DeleteLibrary( row->GetFullURI( true ), row->GetProperties() );
488}
489
490
491void DESIGN_BLOCK_LIB_TABLE::DesignBlockLibCreate( const wxString& aNickname )
492{
493 const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true );
494 wxASSERT( row->plugin );
495 row->plugin->CreateLibrary( row->GetFullURI( true ), row->GetProperties() );
496}
497
498
501 bool aKeepUUID )
502{
503 wxString nickname = aDesignBlockId.GetLibNickname();
504 wxString DesignBlockname = aDesignBlockId.GetLibItemName();
505
506 if( nickname.size() )
507 {
508 return DesignBlockLoad( nickname, DesignBlockname, aKeepUUID );
509 }
510
511 // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
512 else
513 {
514 // Search each library going through libraries alphabetically.
515 for( const wxString& library : GetLogicalLibs() )
516 {
517 // DesignBlockLoad() returns NULL on not found, does not throw exception
518 // unless there's an IO_ERROR.
519 DESIGN_BLOCK* ret = DesignBlockLoad( library, DesignBlockname, aKeepUUID );
520
521 if( ret )
522 return ret;
523 }
524
525 return nullptr;
526 }
527}
528
529
531{
532 return ENV_VAR::GetVersionedEnvVarName( wxS( "DESIGN_BLOCK_DIR" ) );
533}
534
535
536class PCM_DESIGN_BLOCK_LIB_TRAVERSER final : public wxDirTraverser
537{
538public:
539 explicit PCM_DESIGN_BLOCK_LIB_TRAVERSER( const wxString& aPath, DESIGN_BLOCK_LIB_TABLE& aTable,
540 const wxString& aPrefix ) :
541 m_lib_table( aTable ),
542 m_path_prefix( aPath ),
543 m_lib_prefix( aPrefix )
544 {
545 wxFileName f( aPath, wxS( "" ) );
546 m_prefix_dir_count = f.GetDirCount();
547 }
548
549 wxDirTraverseResult OnFile( const wxString& aFilePath ) override { return wxDIR_CONTINUE; }
550
551 wxDirTraverseResult OnDir( const wxString& dirPath ) override
552 {
553 wxFileName dir = wxFileName::DirName( dirPath );
554
555 // consider a directory to be a lib if it's name ends with the design block lib dir
556 // extension it is under $KICADn_3RD_PARTY/design_blocks/<pkgid>/ i.e. has nested
557 // level of at least +3.
558 if( dirPath.EndsWith( wxString::Format( wxS( ".%s" ), FILEEXT::KiCadDesignBlockLibPathExtension ) )
559 && dir.GetDirCount() >= m_prefix_dir_count + 3 )
560 {
561 wxString versionedPath;
562 versionedPath.Printf( wxS( "${%s}" ), ENV_VAR::GetVersionedEnvVarName( wxS( "3RD_PARTY" ) ) );
563
564 wxArrayString parts = dir.GetDirs();
565 parts.RemoveAt( 0, m_prefix_dir_count );
566 parts.Insert( versionedPath, 0 );
567
568 wxString libPath = wxJoin( parts, '/' );
569
570 if( !m_lib_table.HasLibraryWithPath( libPath ) )
571 {
572 wxString name = parts.Last().substr( 0, parts.Last().length() - 7 );
573 wxString nickname;
574 nickname.Printf( wxS( "%s%s" ),
576 name );
577
578 if( m_lib_table.HasLibrary( nickname ) )
579 {
580 int increment = 1;
581
582 do
583 {
584 nickname.Printf( wxS( "%s%s_%d" ),
586 name,
587 increment++ );
588 } while( m_lib_table.HasLibrary( nickname ) );
589 }
590
591 m_lib_table.InsertRow( new DESIGN_BLOCK_LIB_TABLE_ROW( nickname, libPath, wxT( "KiCad" ),
592 wxEmptyString,
593 _( "Added by Plugin and Content Manager" ) ) );
594 }
595 }
596
597 return wxDIR_CONTINUE;
598 }
599
600private:
603 wxString m_lib_prefix;
605};
606
607
609{
610 bool tableExists = true;
611 wxFileName fn = GetGlobalTableFileName();
612
613 if( !fn.FileExists() )
614 {
615 tableExists = false;
616
617 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
618 {
619 THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
620 fn.GetPath() ) );
621 }
622
623 // Attempt to copy the default global file table from the KiCad
624 // template folder to the user's home configuration path.
625 SEARCH_STACK ss;
626
627 SystemDirsAppend( &ss );
628
629 const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
630 std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( envVars, wxT( "TEMPLATE_DIR" ) );
631
632 if( v && !v->IsEmpty() )
633 ss.AddPaths( *v, 0 );
634
635 wxString fileName = ss.FindValidPath( FILEEXT::DesignBlockLibraryTableFileName );
636
637 // The fallback is to create an empty global design block table for the user to populate.
638 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
639 {
640 DESIGN_BLOCK_LIB_TABLE emptyTable;
641
642 emptyTable.Save( fn.GetFullPath() );
643 }
644 }
645
646 aTable.clear();
647 aTable.Load( fn.GetFullPath() );
648
649 KICAD_SETTINGS* cfg = GetAppSettings<KICAD_SETTINGS>( "kicad" );
650 const ENV_VAR_MAP& env = Pgm().GetLocalEnvVariables();
651 wxString packagesPath;
652
653 if( std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( env, wxT( "3RD_PARTY" ) ) )
654 packagesPath = *v;
655
656 if( cfg && cfg->m_PcmLibAutoAdd )
657 {
658 // Scan for libraries in PCM packages directory
659
660 wxFileName d( packagesPath, wxS( "" ) );
661 d.AppendDir( wxS( "design_blocks" ) );
662
663 if( d.DirExists() )
664 {
665 PCM_DESIGN_BLOCK_LIB_TRAVERSER traverser( packagesPath, aTable, cfg->m_PcmLibPrefix );
666 wxDir dir( d.GetPath() );
667
668 dir.Traverse( traverser );
669 }
670 }
671
672 if( cfg && cfg->m_PcmLibAutoRemove )
673 {
674 // Remove PCM libraries that no longer exist
675 std::vector<wxString> to_remove;
676
677 for( size_t i = 0; i < aTable.GetCount(); i++ )
678 {
679 LIB_TABLE_ROW& row = aTable.At( i );
680 wxString path = row.GetFullURI( true );
681
682 if( path.StartsWith( packagesPath ) && !wxDir::Exists( path ) )
683 to_remove.push_back( row.GetNickName() );
684 }
685
686 for( const wxString& nickName : to_remove )
687 aTable.RemoveRow( aTable.FindRow( nickName ) );
688 }
689
690 return tableExists;
691}
692
693
695{
696 return GDesignBlockTable;
697}
698
699
701{
702 return GDesignBlockList;
703}
704
705
707{
708 wxFileName fn;
709
710 fn.SetPath( PATHS::GetUserSettingsPath() );
712
713 return fn.GetFullPath();
714}
const char * name
Definition: DXF_plotter.cpp:62
@ 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 Refresh() override
Attempt to reload the library.
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:37
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:100
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).
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
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:463
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition: paths.cpp:592
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:811
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).
std::string::size_type size() const
Definition: utf8.h:117
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:86
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
Definition: env_vars.cpp:77
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:902
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.