25#include <magic_enum.hpp>
27#include <unordered_set>
37using namespace std::chrono_literals;
58 std::vector<LIBRARY_TABLE_TYPE> aTablesToLoad )
72 wxCHECK_MSG(
false,
m_tables,
"Invalid scope passed to loadTables" );
76 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>>& aTarget = getTarget();
78 if( aTablesToLoad.size() == 0 )
83 aTarget.erase( type );
87 if( fn.IsFileReadable() )
89 std::unique_ptr<LIBRARY_TABLE>
table = std::make_unique<LIBRARY_TABLE>( fn, aScope );
90 wxCHECK2(
table->Type() == type,
continue );
91 aTarget[type] = std::move(
table );
96 wxLogTrace(
traceLibraries,
"No library table found at %s", fn.GetFullPath() );
104 std::unordered_set<wxString> seenTables;
109 seenTables.insert( aTable.Path() );
121 file.MakeAbsolute( wxFileName( aTable.Path() ).GetPath() );
124 wxString src = file.GetFullPath();
126 if( seenTables.contains( src ) )
128 wxLogTrace(
traceLibraries,
"Library table %s has already been loaded!", src );
130 row.SetErrorDescription(
_(
"A reference to this library table already exists" ) );
134 auto child = std::make_unique<LIBRARY_TABLE>( file, aRootTable.
Scope() );
136 processOneTable( *child );
141 row.SetErrorDescription( child->ErrorDescription() );
149 processOneTable( aRootTable );
160 default: wxCHECK(
false, wxEmptyString );
169 wxCHECK( !
m_tables.contains( aType ), );
190 const wxString& aPrefix ) :
196 wxFileName f( aBasePath,
"" );
200 .value_or(
nullptr );
202 .value_or(
nullptr );
204 .value_or(
nullptr );
208 wxDirTraverseResult
OnFile(
const wxString& aFilePath )
override
210 wxFileName file = wxFileName::FileName( aFilePath );
214 if( file.GetExt() == wxT(
"kicad_sym" ) && file.GetDirCount() >=
m_prefix_dir_count + 2
220 return wxDIR_CONTINUE;
224 wxDirTraverseResult
OnDir(
const wxString& dirPath )
override
226 static wxString designBlockExt = wxString::Format( wxS(
".%s" ),
228 wxFileName dir = wxFileName::DirName( dirPath );
232 if( dirPath.EndsWith( wxS(
".pretty" ) ) && dir.GetDirCount() >=
m_prefix_dir_count + 3
237 else if( dirPath.EndsWith( designBlockExt )
244 return wxDIR_CONTINUE;
252 if( aTable->
HasRow( aNickname ) )
258 aNickname = wxString::Format(
"%s%s_%d",
m_lib_prefix, aBaseName, increment );
260 }
while( aTable->
HasRow( aNickname ) );
271 int aExtensionLength )
273 wxString versionedPath = wxString::Format( wxS(
"${%s}" ),
276 wxArrayString parts = aSource.GetDirs();
278 parts.Insert( versionedPath, 0 );
281 parts.Add( aSource.GetFullName() );
283 wxString libPath = wxJoin( parts,
'/' );
287 wxString
name = parts.Last().substr( 0, parts.Last().length() - aExtensionLength );
292 wxLogTrace(
traceLibraries,
"Manager: Adding PCM lib '%s' as '%s'", libPath, nickname );
304 wxLogTrace(
traceLibraries,
"Manager: Not adding existing PCM lib '%s'", libPath );
328 return fn.GetFullPath();
334 if( wxFileName fn( aPath ); fn.IsFileReadable() )
352 std::vector<LIBRARY_TABLE_TYPE> invalidTables;
360 invalidTables.emplace_back( tableType );
363 return invalidTables;
372 table.SetType( aType );
373 table.Rows().clear();
377 if( !defaultLib.IsFileReadable() )
379 wxLogTrace(
traceLibraries,
"Warning: couldn't read default library table for %s at '%s'",
380 magic_enum::enum_name( aType ), defaultLib.GetFullPath() );
383 if( aPopulateDefaultLibraries )
389 chained.
SetURI( defaultLib.GetFullPath() );
395 table.Format( &formatter );
413 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
414 adapter->GlobalTablesChanged( aTablesToLoad );
422 wxCHECK( settings, );
430 wxFileName d( *packagesPath,
"" );
435 wxDir dir( d.GetPath() );
437 dir.Traverse( traverser );
441 table->Save().map_error(
444 wxLogTrace(
traceLibraries, wxT(
"Warning: save failed after PCM auto-add: %s" ),
451 auto cleanupRemovedPCMLibraries =
457 auto toErase = std::ranges::remove_if(
table->Rows(),
460 wxString path = GetFullURI( &aRow, true );
461 return path.StartsWith( *packagesPath ) && !wxFile::Exists( path );
464 table->Rows().erase( toErase.begin(), toErase.end() );
466 if( !toErase.empty() )
468 table->Save().map_error(
471 wxLogTrace(
traceLibraries, wxT(
"Warning: save failed after PCM auto-remove: %s" ),
498 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
499 adapter->ProjectChanged();
507 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
508 adapter->AbortAsyncLoad();
513 std::unique_ptr<LIBRARY_MANAGER_ADAPTER>&& aAdapter )
517 wxCHECK_MSG( !
m_adapters.contains( aType ), ,
"You should only register an adapter once!" );
555 wxCHECK_MSG(
false, std::nullopt,
"Table() requires a single scope" );
562 magic_enum::enum_name( aType ) );
590 bool aIncludeInvalid )
const
592 std::map<wxString, LIBRARY_TABLE_ROW*> rows;
593 std::vector<wxString> rowOrder;
595 std::list<std::ranges::ref_view<
596 const std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>>
602 tables = { std::views::all(
m_tables ) };
617 std::function<void(
const std::unique_ptr<LIBRARY_TABLE>&)> processTable =
618 [&](
const std::unique_ptr<LIBRARY_TABLE>& aTable )
620 if( aTable->Type() != aType )
623 if( aTable->IsOk() || aIncludeInvalid )
627 if( row.IsOk() || aIncludeInvalid )
635 if( row.Disabled() || row.Hidden() )
642 if( !rows.contains( row.Nickname() ) )
643 rowOrder.emplace_back( row.Nickname() );
645 rows[ row.Nickname() ] = &row;
652 for(
const std::unique_ptr<LIBRARY_TABLE>&
table :
653 std::views::join( tables ) | std::views::values )
655 processTable(
table );
658 std::vector<LIBRARY_TABLE_ROW*> ret;
660 for(
const wxString& row : rowOrder )
661 ret.emplace_back( rows[row] );
668 const wxString& aNickname,
673 if( row->Nickname() == aNickname )
682 const wxString& aUri,
698 if( std::optional<LIBRARY_MANAGER_ADAPTER*> adapter =
Adapter( aType ); adapter )
699 ( *adapter )->ReloadLibraryEntry( aNickname, aScope );
704 std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad )
706 if( wxFileName::IsDirReadable( aProjectPath ) )
713 wxLogTrace(
traceLibraries,
"New project path %s is not readable, not loading project tables",
720 std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad )
730 const wxString& aNickname,
731 bool aSubstituted )
const
733 if( std::optional<const LIBRARY_TABLE_ROW*>
result =
GetRow( aType, aNickname ) )
754 return path.GetFullPath();
761 if( aURI1.Find(
"://" ) != wxNOT_FOUND )
764 return aURI1 == aURI2;
768 const wxFileName fn1( aURI1 );
769 const wxFileName fn2( aURI2 );
822 bool me = aChangedTables.size() == 0;
857 std::optional<LIB_STATUS> status =
LoadOne( &lib );
859 if( status.has_value() )
863 if( status.value().error.has_value() )
899 return row->Nickname();
908 std::vector<wxString> ret;
909 std::vector<LIBRARY_TABLE_ROW*> rows =
m_manager.Rows(
Type() );
911 wxLogTrace(
traceLibraries,
"GetLibraryNames: checking %zu rows from table", rows.size() );
915 wxString nickname = row->Nickname();
916 std::optional<const LIB_DATA*> loaded =
fetchIfLoaded( nickname );
919 ret.emplace_back( nickname );
922 wxLogTrace(
traceLibraries,
"GetLibraryNames: returning %zu of %zu libraries", ret.size(), rows.size() );
928 bool aCheckEnabled )
const
930 if( std::optional<const LIB_DATA*> r =
fetchIfLoaded( aNickname ); r.has_value() )
931 return !aCheckEnabled || !( *r )->row->Disabled();
960 if( std::optional<const LIB_DATA*> optRow =
fetchIfLoaded( aNickname ); optRow )
961 return ( *optRow )->row->Description();
968 bool aIncludeInvalid )
const
982 const wxString& aUri,
1019 return std::nullopt;
1022 return loaded /
static_cast<float>( total );
1028 wxLogTrace(
traceLibraries,
"BlockUntilLoaded: entry, acquiring m_loadMutex" );
1029 std::unique_lock<std::mutex> asyncLock(
m_loadMutex );
1033 for(
const std::future<void>& future :
m_futures )
1036 wxLogTrace(
traceLibraries,
"BlockUntilLoaded: all futures complete, loadCount=%zu, loadTotal=%zu",
1067 return it->second.status.error;
1074 return it->second.status.error;
1077 return std::nullopt;
1083 std::vector<std::pair<wxString, LIB_STATUS>> ret;
1089 ret.emplace_back( std::make_pair( row->Nickname(), *
result ) );
1094 ret.emplace_back( std::make_pair( row->Nickname(),
LIB_STATUS( {
1096 .error =
LIBRARY_ERROR(
_(
"Library not found in library table" ) )
1113 if( !errors.IsEmpty() )
1114 errors += wxS(
"\n" );
1116 errors += wxString::Format(
_(
"Library '%s': %s" ),
1117 nickname, status.error->message );
1130 std::shared_mutex& aMutex )
1132 bool wasLoaded =
false;
1135 std::unique_lock lock( aMutex );
1136 auto it = aTarget.find( aNickname );
1138 if( it != aTarget.end() && it->second.plugin )
1141 aTarget.erase( it );
1148 loadFromScope( aNickname, aScopeToReload, aTarget, aMutex );
1152 "ReloadLibraryEntry: failed to reload %s (%s): %s",
1153 aNickname, magic_enum::enum_name( aScopeToReload ),
1154 result.error().message );
1228 return std::nullopt;
1240 return std::nullopt;
1244 return std::nullopt;
1258 return std::nullopt;
1270 return std::nullopt;
1274 return std::nullopt;
1280 std::map<wxString, LIB_DATA>& aTarget,
1281 std::shared_mutex& aMutex )
1283 bool present =
false;
1286 std::shared_lock lock( aMutex );
1287 present = aTarget.contains( aNickname ) && aTarget.at( aNickname ).plugin;
1295 wxLogTrace(
traceLibraries,
"Library %s (%s) not yet loaded, will attempt...",
1296 aNickname, magic_enum::enum_name( aScope ) );
1300 std::unique_lock lock( aMutex );
1303 aTarget[ row->
Nickname() ].row = row;
1306 return &aTarget.at( aNickname );
1310 return tl::unexpected(
plugin.error() );
1317 std::shared_lock lock( aMutex );
1318 return &aTarget.at( aNickname );
1335 wxString msg = wxString::Format(
_(
"Library %s not found" ), aNickname );
1346 return it->second.status;
1353 return it->second.status;
1356 return std::nullopt;
1362 std::unique_lock<std::mutex> asyncLock(
m_loadMutex, std::try_to_lock );
1368 []( std::future<void>& aFuture )
1370 return aFuture.valid()
1371 && aFuture.wait_for( 0s ) == std::future_status::ready;
1376 wxLogTrace(
traceLibraries,
"Cannot AsyncLoad, futures from a previous call remain!" );
1380 std::vector<LIBRARY_TABLE_ROW*> rows =
m_manager.Rows(
Type() );
1387 wxLogTrace(
traceLibraries,
"AsyncLoad: no libraries left to load; exiting" );
1394 [&](
const wxString& aLib, std::map<wxString, LIB_DATA>& aMap, std::shared_mutex& aMutex )
1396 std::shared_lock lock( aMutex );
1398 if(
auto it = aMap.find( aLib ); it != aMap.end() )
1400 LOAD_STATUS status = it->second.status.load_status;
1411 wxString nickname = row->Nickname();
1427 [
this, nickname, scope]()
1429 if( m_abort.load() )
1432 LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( nickname );
1434 if( result.has_value() )
1436 LIB_DATA* lib = *result;
1441 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL
1443 : m_librariesMutex );
1444 lib->status.load_status = LOAD_STATUS::LOADING;
1447 enumerateLibrary( lib );
1450 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL
1452 : m_librariesMutex );
1453 lib->status.load_status = LOAD_STATUS::LOADED;
1456 catch( IO_ERROR& e )
1458 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL
1460 : m_librariesMutex );
1461 lib->status.load_status = LOAD_STATUS::LOAD_ERROR;
1462 lib->status.error = LIBRARY_ERROR( { e.What() } );
1463 wxLogTrace( traceLibraries,
"%s: plugin threw exception: %s",
1464 nickname, e.What() );
1469 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL
1471 : m_librariesMutex );
1473 std::map<wxString, LIB_DATA>& target =
1474 scope == LIBRARY_TABLE_SCOPE::GLOBAL ? globalLibs() : m_libraries;
1476 target[nickname].status = LIB_STATUS( {
1477 .load_status = LOAD_STATUS::LOAD_ERROR,
1478 .error = result.error()
1483 }, BS::pr::lowest ) );
1486 size_t total = m_loadTotal.load();
1489 wxLogTrace(
traceLibraries,
"Started async load of %zu libraries", total );
virtual bool DeleteLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr)
Delete an existing library and returns true, or if library does not exist returns false,...
virtual bool IsLibraryWritable(const wxString &aLibraryPath)
Return true if the library at aLibraryPath is writable.
virtual void CreateLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr)
Create a new empty library at aLibraryPath empty.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
The interface used by the classes that actually can load IO plugins for the different parts of KiCad ...
std::optional< float > AsyncLoadProgress() const
Returns async load progress between 0.0 and 1.0, or nullopt if load is not in progress.
virtual std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib)=0
virtual std::optional< LIBRARY_ERROR > LibraryError(const wxString &aNickname) const
void ReloadLibraryEntry(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH)
std::optional< LIB_STATUS > GetLibraryStatus(const wxString &aNickname) const
Returns the status of a loaded library, or nullopt if the library hasn't been loaded (yet)
virtual ~LIBRARY_MANAGER_ADAPTER()
std::optional< LIBRARY_TABLE * > ProjectTable() const
Retrieves the project library table for this adapter type, or nullopt if one doesn't exist.
void AbortAsyncLoad()
Aborts any async load in progress; blocks until fully done aborting.
LIBRARY_TABLE * GlobalTable() const
Retrieves the global library table for this adapter type.
virtual std::shared_mutex & globalLibsMutex()=0
LIBRARY_MANAGER_ADAPTER(LIBRARY_MANAGER &aManager)
Constructs a type-specific adapter into the library manager.
void CheckTableRow(LIBRARY_TABLE_ROW &aRow)
bool IsLibraryLoaded(const wxString &aNickname)
std::vector< LIBRARY_TABLE_ROW * > Rows(LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH, bool aIncludeInvalid=false) const
Like LIBRARY_MANAGER::Rows but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< LIBRARY_TABLE_ROW * > FindRowByURI(const wxString &aUri, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::FindRowByURI but filtered to the LIBRARY_TABLE_TYPE of this adapter.
virtual std::map< wxString, LIB_DATA > & globalLibs()=0
virtual LIBRARY_TABLE_TYPE Type() const =0
The type of library table this adapter works with.
bool DeleteLibrary(const wxString &aNickname)
Deletes the given library from disk if it exists; returns true if deleted.
LIBRARY_RESULT< LIB_DATA * > loadIfNeeded(const wxString &aNickname)
Fetches a loaded library, triggering a load of that library if it isn't loaded yet.
wxString GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
std::optional< wxString > FindLibraryByURI(const wxString &aURI) const
std::shared_mutex m_librariesMutex
LIBRARY_MANAGER & Manager() const
void abortLoad()
Aborts any async load in progress; blocks until fully done aborting.
std::optional< wxString > GetLibraryDescription(const wxString &aNickname) const
virtual LIBRARY_RESULT< IO_BASE * > createPlugin(const LIBRARY_TABLE_ROW *row)=0
Creates a concrete plugin for the given row.
void GlobalTablesChanged(std::initializer_list< LIBRARY_TABLE_TYPE > aChangedTables={})
Notify the adapter that the global library tables have changed.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library tables.
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::map< wxString, LIB_DATA > m_libraries
virtual IO_BASE * plugin(const LIB_DATA *aRow)=0
std::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
virtual void ProjectChanged()
Notify the adapter that the active project has changed.
LIBRARY_RESULT< LIB_DATA * > loadFromScope(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope, std::map< wxString, LIB_DATA > &aTarget, std::shared_mutex &aMutex)
std::vector< std::future< void > > m_futures
static wxString getUri(const LIBRARY_TABLE_ROW *aRow)
bool CreateLibrary(const wxString &aNickname)
Creates the library (i.e. saves to disk) for the given row if it exists.
void AsyncLoad()
Loads all available libraries for this adapter type in the background.
virtual bool IsWritable(const wxString &aNickname) const
Return true if the given nickname exists and is not a read-only library.
std::vector< std::pair< wxString, LIB_STATUS > > GetLibraryStatuses() const
Returns a list of all library nicknames and their status (even if they failed to load)
std::atomic< size_t > m_loadTotal
std::atomic< size_t > m_loadCount
LIBRARY_MANAGER & m_manager
std::optional< const LIB_DATA * > fetchIfLoaded(const wxString &aNickname) const
void ReloadTables(LIBRARY_TABLE_SCOPE aScope, std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
static wxString ExpandURI(const wxString &aShortURI, const PROJECT &aProject)
std::optional< LIBRARY_MANAGER_ADAPTER * > Adapter(LIBRARY_TABLE_TYPE aType) const
std::map< wxString, std::unique_ptr< LIBRARY_TABLE > > m_childTables
Map of full URI to table object for tables that are referenced by global or project tables.
void loadNestedTables(LIBRARY_TABLE &aTable)
bool RemoveAdapter(LIBRARY_TABLE_TYPE aType, LIBRARY_MANAGER_ADAPTER *aAdapter)
void ReloadLibraryEntry(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH)
static bool UrisAreEquivalent(const wxString &aURI1, const wxString &aURI2)
std::mutex m_adaptersMutex
std::optional< LIBRARY_TABLE * > Table(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
Retrieves a given table; creating a new empty project table if a valid project is loaded and the give...
void RegisterAdapter(LIBRARY_TABLE_TYPE aType, std::unique_ptr< LIBRARY_MANAGER_ADAPTER > &&aAdapter)
static wxString DefaultGlobalTablePath(LIBRARY_TABLE_TYPE aType)
static std::vector< LIBRARY_TABLE_TYPE > InvalidGlobalTables()
void createEmptyTable(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
void AbortAsyncLoads()
Abort any async library loading operations in progress.
static bool GlobalTablesValid()
std::map< LIBRARY_TABLE_TYPE, std::unique_ptr< LIBRARY_TABLE > > m_projectTables
std::optional< LIBRARY_TABLE_ROW * > FindRowByURI(LIBRARY_TABLE_TYPE aType, const wxString &aUri, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
void LoadProjectTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the project library tables in the given list, or all tables if no list is given
static bool CreateGlobalTable(LIBRARY_TABLE_TYPE aType, bool aPopulateDefaultLibraries)
void loadTables(const wxString &aTablePath, LIBRARY_TABLE_SCOPE aScope, std::vector< LIBRARY_TABLE_TYPE > aTablesToLoad={})
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
static wxString tableFileName(LIBRARY_TABLE_TYPE aType)
std::vector< LIBRARY_TABLE_ROW * > Rows(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH, bool aIncludeInvalid=false) const
Returns a flattened list of libraries of the given type.
void LoadGlobalTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the global library tables in the given list, or all tables if no list is given
std::map< LIBRARY_TABLE_TYPE, std::unique_ptr< LIBRARY_TABLE > > m_tables
void ProjectChanged()
Notify all adapters that the project has changed.
static bool IsTableValid(const wxString &aPath)
std::map< LIBRARY_TABLE_TYPE, std::unique_ptr< LIBRARY_MANAGER_ADAPTER > > m_adapters
std::optional< LIBRARY_TABLE_ROW * > GetRow(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
void SetNickname(const wxString &aNickname)
void SetOk(bool aOk=true)
void SetType(const wxString &aType)
void SetErrorDescription(const wxString &aDescription)
std::map< std::string, UTF8 > GetOptionsMap() const
void SetDescription(const wxString &aDescription)
static const wxString TABLE_TYPE_NAME
void SetURI(const wxString &aUri)
const wxString & URI() const
const wxString & Nickname() const
LIBRARY_TABLE_ROW & InsertRow()
Builds a new row and inserts it at the end of the table; returning a reference to the row.
LIBRARY_TABLE_SCOPE Scope() const
bool HasRow(const wxString &aNickname) const
bool HasRowWithURI(const wxString &aUri, const PROJECT &aProject, bool aSubstituted=false) const
Returns true if the given (fully-expanded) URI exists as a library in this table.
static wxString GetStockTemplatesPath()
Gets the stock (install) templates path.
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
LIBRARY_TABLE * m_designBlockTable
std::set< LIBRARY_TABLE * > m_modified
LIBRARY_MANAGER & m_manager
std::set< LIBRARY_TABLE * > Modified() const
const PROJECT & m_project
PCM_LIB_TRAVERSER(const wxString &aBasePath, LIBRARY_MANAGER &aManager, const wxString &aPrefix)
void ensureUnique(LIBRARY_TABLE *aTable, const wxString &aBaseName, wxString &aNickname) const
LIBRARY_TABLE * m_symbolTable
wxDirTraverseResult OnDir(const wxString &dirPath) override
Handles footprint library and design block library directories, minimum nest level 3.
void addRowIfNecessary(LIBRARY_TABLE *aTable, const wxFileName &aSource, ADD_MODE aMode, int aExtensionLength)
LIBRARY_TABLE * m_fpTable
wxDirTraverseResult OnFile(const wxString &aFilePath) override
Handles symbol library files, minimum nest level 2.
size_t m_prefix_dir_count
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
virtual SETTINGS_MANAGER & GetSettingsManager() const
Container for project specific data.
T * GetAppSettings(const char *aFilename)
Return a handle to the a given settings by type.
static void ResolvePossibleSymlinks(wxFileName &aFilename)
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Functions related to environment variables, including help functions.
static const std::string KiCadDesignBlockLibPathExtension
static const std::string SymbolLibraryTableFileName
static const std::string DesignBlockLibraryTableFileName
static const std::string FootprintLibraryTableFileName
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
LOAD_STATUS
Status of a library load managed by a library adapter.
tl::expected< ResultType, LIBRARY_ERROR > LIBRARY_RESULT
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.
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global program "get" accessor.
std::vector< LIBRARY_TABLE > tables
Storage for an actual loaded library (including library content owned by the plugin)
std::unique_ptr< IO_BASE > plugin
const LIBRARY_TABLE_ROW * row
The overall status of a loaded or loading library.
wxString result
Test unit parsing edge cases and error handling.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
wxLogTrace helper definitions.
Definition of file extensions used in Kicad.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().