29#include <lib_table_lexer.h>
55using namespace LIB_TABLE_T;
93 if( in->CurTok() != T_design_block_lib_table )
97 if( ( tok = in->NextTok() ) != T_design_block_lib_table )
98 in->Expecting( T_design_block_lib_table );
101 while( ( tok = in->NextTok() ) != T_RIGHT )
103 std::unique_ptr<DESIGN_BLOCK_LIB_TABLE_ROW> row =
104 std::make_unique<DESIGN_BLOCK_LIB_TABLE_ROW>();
107 in->Expecting( T_RIGHT );
110 in->Expecting( T_LEFT );
113 int lineNum = in->CurLineNumber();
117 if( tok == T_version )
119 in->NeedNUMBER(
"version" );
126 in->Expecting( T_lib );
131 if( ( tok = in->NextTok() ) != T_name )
132 in->Expecting( T_name );
134 in->NeedSYMBOLorNUMBER();
136 row->SetNickName( in->FromUTF8() );
142 bool sawType =
false;
143 bool sawOpts =
false;
144 bool sawDesc =
false;
146 bool sawDisabled =
false;
148 while( ( tok = in->NextTok() ) != T_RIGHT )
151 in->Unexpected( T_EOF );
154 in->Expecting( T_LEFT );
156 tok = in->NeedSYMBOLorNUMBER();
162 in->Duplicate( tok );
164 in->NeedSYMBOLorNUMBER();
165 row->SetFullURI( in->FromUTF8() );
170 in->Duplicate( tok );
172 in->NeedSYMBOLorNUMBER();
173 row->SetType( in->FromUTF8() );
178 in->Duplicate( tok );
180 in->NeedSYMBOLorNUMBER();
181 row->SetOptions( in->FromUTF8() );
186 in->Duplicate( tok );
188 in->NeedSYMBOLorNUMBER();
189 row->SetDescr( in->FromUTF8() );
194 in->Duplicate( tok );
196 row->SetEnabled(
false );
205 default: in->Unexpected( tok );
212 in->Expecting( T_type );
215 in->Expecting( T_uri );
220 wxString nickname = row->GetNickName();
222 bool doReplace =
false;
229 wxString msg = wxString::Format(
_(
"Duplicate library nickname '%s' found in "
230 "design block library table file line %d." ),
233 if( !errMsg.IsEmpty() )
240 if( !errMsg.IsEmpty() )
249 for(
unsigned i = 0; i <
m_rows.size(); ++i )
265 aOutput->
Print( aIndentLevel,
"(design_block_lib_table\n" );
269 it->Format( aOutput, aIndentLevel + 1 );
271 aOutput->
Print( aIndentLevel,
")\n" );
283 wxCHECK( row && row->
plugin, hash );
286 + wxHashTable::MakeKey( *aNickname );
295 row =
FindRow( nickname,
true );
302 wxCHECK2( row && row->
plugin,
continue );
305 + wxHashTable::MakeKey( nickname );
313 const wxString& aNickname,
bool aBestEfforts )
317 row->
plugin->DesignBlockEnumerate( aDesignBlockNames, row->
GetFullURI(
true ), aBestEfforts,
331 bool aCheckIfEnabled )
338 wxString msg = wxString::Format(
339 _(
"design-block-lib-table files contain no library named '%s'." ), aNickname );
351 const wxString& aDesignBlockName )
376 const wxString& aDesignBlockName )
381 return row->
plugin->GetEnumeratedDesignBlock( row->
GetFullURI(
true ), aDesignBlockName,
387 const wxString& aDesignBlockName )
394 return row->
plugin->DesignBlockExists( row->
GetFullURI(
true ), aDesignBlockName,
405 const wxString& aDesignBlockName,
434 std::unique_ptr<DESIGN_BLOCK> design_block( row->
plugin->DesignBlockLoad(
437 if( design_block.get() )
448 const wxString& aDesignBlockName )
453 return row->
plugin->DesignBlockDelete( row->
GetFullURI(
true ), aDesignBlockName,
489 if( nickname.size() )
500 for(
unsigned i = 0; i < nicks.size(); ++i )
525 const wxString& aPrefix ) :
529 wxFileName f( aPath, wxS(
"" ) );
533 wxDirTraverseResult
OnFile(
const wxString& aFilePath )
override {
return wxDIR_CONTINUE; }
535 wxDirTraverseResult
OnDir(
const wxString& dirPath )
override
537 wxFileName dir = wxFileName::DirName( dirPath );
541 if( dirPath.EndsWith( wxS(
".pretty" ) ) && dir.GetDirCount() >=
m_prefix_dir_count + 3 )
543 wxString versionedPath = wxString::Format(
546 wxArrayString parts = dir.GetDirs();
548 parts.Insert( versionedPath, 0 );
550 wxString libPath = wxJoin( parts,
'/' );
554 wxString
name = parts.Last().substr( 0, parts.Last().length() - 7 );
569 nickname, libPath, wxT(
"KiCad" ), wxEmptyString,
570 _(
"Added by Plugin and Content Manager" ) ) );
574 return wxDIR_CONTINUE;
587 bool tableExists =
true;
590 if( !fn.FileExists() )
594 if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
596 THROW_IO_ERROR( wxString::Format(
_(
"Cannot create global library table path '%s'." ),
607 std::optional<wxString> v =
610 if( v && !v->IsEmpty() )
616 if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(),
false ) )
620 emptyTable.
Save( fn.GetFullPath() );
625 aTable.
Load( fn.GetFullPath() );
631 wxString packagesPath;
640 wxFileName d( packagesPath, wxS(
"" ) );
641 d.AppendDir( wxS(
"design_blocks" ) );
647 wxDir dir( d.GetPath() );
649 dir.Traverse( traverser );
656 std::vector<wxString> to_remove;
658 for(
size_t i = 0; i < aTable.
GetCount(); i++ )
663 if(
path.StartsWith( packagesPath ) && !wxDir::Exists(
path ) )
667 for(
const wxString& nickName : to_remove )
694 return fn.GetFullPath();
@ 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 PrefetchLib(const wxString &aNickname)
If possible, prefetches the specified library (e.g.
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
A logical library item identifier and consists of various portions much like a URI.
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
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,...
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
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
DESIGN_BLOCK_LIB_TABLE & m_lib_table
size_t m_prefix_dir_count
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
virtual SETTINGS_MANAGER & GetSettingsManager() const
Look for files in a number of paths.
void AddPaths(const wxString &aPaths, int aIndex=-1)
Insert or append path(s).
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
std::string::size_type size() const
static void setLibNickname(DESIGN_BLOCK *aModule, const wxString &aNickname, const wxString &aDesignBlockName)
static const wxChar global_tbl_name[]
DESIGN_BLOCK_LIB_TABLE GDesignBlockTable
The global design block library table.
DESIGN_BLOCK_LIST_IMPL GDesignBlockList
The global footprint info table.
Functions related to environment variables, including help functions.
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
#define THROW_IO_ERROR(msg)
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)
Attempts to retrieve the value of a versioned environment variable, such as KICAD8_TEMPLATE_DIR.
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Constructs a versioned environment variable based on this KiCad major version.
PGM_BASE & Pgm()
The global Program "get" accessor.
void SystemDirsAppend(SEARCH_STACK *aSearchStack)
Append system places to aSearchStack in a platform specific way and pertinent to KiCad programs.
System directories search utilities.