25#include <magic_enum.hpp>
28#include <unordered_set>
38using namespace std::chrono_literals;
59 std::vector<LIBRARY_TABLE_TYPE> aTablesToLoad )
78 wxCHECK_MSG(
false,
m_tables,
"Invalid scope passed to loadTables" );
82 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>>& aTarget = getTarget();
84 if( aTablesToLoad.size() == 0 )
89 aTarget.erase( type );
93 if( fn.IsFileReadable() )
95 std::unique_ptr<LIBRARY_TABLE>
table = std::make_unique<LIBRARY_TABLE>( fn, aScope );
97 if(
table->Type() != type )
99 auto actualName = magic_enum::enum_name(
table->Type() );
100 auto expectedName = magic_enum::enum_name( type );
101 wxLogWarning( wxS(
"Library table '%s' has type %s but expected %s; skipping" ),
103 wxString( actualName.data(), actualName.size() ),
104 wxString( expectedName.data(), expectedName.size() ) );
108 aTarget[type] = std::move(
table );
113 wxLogTrace(
traceLibraries,
"No library table found at %s", fn.GetFullPath() );
121 std::unordered_set<wxString> seenTables;
126 seenTables.insert( aTable.Path() );
138 file.MakeAbsolute( wxFileName( aTable.Path() ).GetPath() );
141 wxString src = file.GetFullPath();
143 if( seenTables.contains( src ) )
145 wxLogTrace(
traceLibraries,
"Library table %s has already been loaded!", src );
147 row.SetErrorDescription(
_(
"A reference to this library table already exists" ) );
151 auto child = std::make_unique<LIBRARY_TABLE>( file, aRootTable.
Scope() );
153 processOneTable( *child );
158 row.SetErrorDescription( child->ErrorDescription() );
166 processOneTable( aRootTable );
177 default: wxCHECK(
false, wxEmptyString );
186 wxCHECK( !
m_tables.contains( aType ), );
207 const wxString& aPrefix ) :
213 wxFileName f( aBasePath,
"" );
219 .value_or(
nullptr );
223 wxDirTraverseResult
OnFile(
const wxString& aFilePath )
override
225 wxFileName file = wxFileName::FileName( aFilePath );
229 if( file.GetExt() == wxT(
"kicad_sym" )
236 return wxDIR_CONTINUE;
240 wxDirTraverseResult
OnDir(
const wxString& dirPath )
override
243 wxFileName dir = wxFileName::DirName( dirPath );
247 if( dirPath.EndsWith( wxS(
".pretty" ) )
253 else if( dirPath.EndsWith( designBlockExt )
260 return wxDIR_CONTINUE;
268 if( aTable->
HasRow( aNickname ) )
274 aNickname = wxString::Format(
"%s%s_%d",
m_lib_prefix, aBaseName, increment );
276 }
while( aTable->
HasRow( aNickname ) );
287 int aExtensionLength )
289 wxString versionedPath = wxString::Format( wxS(
"${%s}" ),
292 wxArrayString parts = aSource.GetDirs();
294 parts.Insert( versionedPath, 0 );
297 parts.Add( aSource.GetFullName() );
299 wxString libPath = wxJoin( parts,
'/' );
303 wxString
name = parts.Last().substr( 0, parts.Last().length() - aExtensionLength );
308 wxLogTrace(
traceLibraries,
"Manager: Adding PCM lib '%s' as '%s'", libPath, nickname );
320 wxLogTrace(
traceLibraries,
"Manager: Not adding existing PCM lib '%s'", libPath );
345 return fn.GetFullPath();
356 return fn.GetFullPath();
362 if( wxFileName fn( aPath ); fn.IsFileReadable() )
382 std::vector<LIBRARY_TABLE_TYPE> invalidTables;
392 invalidTables.emplace_back( tableType );
395 return invalidTables;
404 table.SetType( aType );
405 table.Rows().clear();
409 if( !defaultLib.IsFileReadable() )
411 wxLogTrace(
traceLibraries,
"Warning: couldn't read default library table for %s at '%s'",
412 magic_enum::enum_name( aType ), defaultLib.GetFullPath() );
415 if( aPopulateDefaultLibraries )
421 chained.
SetURI( defaultLib.GetFullPath() );
427 table.Format( &formatter );
445 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
446 adapter->GlobalTablesChanged( aTablesToLoad );
454 wxCHECK( settings, );
462 wxFileName d( *packagesPath,
"" );
467 wxDir dir( d.GetPath() );
469 dir.Traverse( traverser );
473 table->Save().map_error(
476 wxLogTrace(
traceLibraries, wxT(
"Warning: save failed after PCM auto-add: %s" ),
483 auto cleanupRemovedPCMLibraries =
489 auto toErase = std::ranges::remove_if(
table->Rows(),
492 wxString path = GetFullURI( &aRow, true );
494 return path.StartsWith( *packagesPath )
495 && !wxFileName::Exists( path );
498 bool hadRemovals = !toErase.empty();
499 table->Rows().erase( toErase.begin(), toErase.end() );
503 table->Save().map_error(
506 wxLogTrace(
traceLibraries, wxT(
"Warning: save failed after PCM auto-remove: %s" ),
533 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
534 adapter->ProjectChanged();
542 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
543 adapter->AbortAsyncLoad();
548 std::unique_ptr<LIBRARY_MANAGER_ADAPTER>&& aAdapter )
552 wxCHECK_MSG( !
m_adapters.contains( aType ), ,
"You should only register an adapter once!" );
590 wxCHECK_MSG(
false, std::nullopt,
"Table() requires a single scope" );
597 magic_enum::enum_name( aType ) );
624 bool aIncludeInvalid )
const
626 std::map<wxString, LIBRARY_TABLE_ROW*> rows;
627 std::vector<wxString> rowOrder;
629 std::list<std::ranges::ref_view<const std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>>>> tables;
634 tables = { std::views::all(
m_tables ) };
649 std::function<void(
const std::unique_ptr<LIBRARY_TABLE>&)> processTable =
650 [&](
const std::unique_ptr<LIBRARY_TABLE>& aTable )
652 if( aTable->Type() != aType )
655 if( aTable->IsOk() || aIncludeInvalid )
659 if( row.IsOk() || aIncludeInvalid )
667 if( row.Disabled() || row.Hidden() )
674 if( !rows.contains( row.Nickname() ) )
675 rowOrder.emplace_back( row.Nickname() );
677 rows[ row.Nickname() ] = &row;
684 for(
const std::unique_ptr<LIBRARY_TABLE>&
table :
685 std::views::join( tables ) | std::views::values )
687 processTable(
table );
690 std::vector<LIBRARY_TABLE_ROW*> ret;
692 for(
const wxString& row : rowOrder )
693 ret.emplace_back( rows[row] );
704 auto key = std::make_tuple( aType, aScope, aNickname );
712 if( row->Nickname() == aNickname )
715 m_rowCache[std::make_tuple( aType, aScope, aNickname )] = row;
725 const wxString& aUri,
741 if( std::optional<LIBRARY_MANAGER_ADAPTER*> adapter =
Adapter( aType ); adapter )
742 ( *adapter )->ReloadLibraryEntry( aNickname, aScope );
747 std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad )
749 if( wxFileName::IsDirReadable( aProjectPath ) )
756 wxLogTrace(
traceLibraries,
"New project path %s is not readable, not loading project tables", aProjectPath );
762 std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad )
774 if( std::optional<const LIBRARY_TABLE_ROW*>
result =
GetRow( aType, aNickname ) )
796 return path.GetFullPath();
803 if( aURI1.Find(
"://" ) != wxNOT_FOUND )
806 return aURI1 == aURI2;
810 const wxFileName fn1( aURI1 );
811 const wxFileName fn2( aURI2 );
864 bool me = aChangedTables.size() == 0;
899 std::optional<LIB_STATUS> status =
LoadOne( &lib );
901 if( status.has_value() )
905 if( status.value().error.has_value() )
941 return row->Nickname();
950 std::vector<wxString> ret;
951 std::vector<LIBRARY_TABLE_ROW*> rows =
m_manager.Rows(
Type() );
953 wxLogTrace(
traceLibraries,
"GetLibraryNames: checking %zu rows from table", rows.size() );
957 wxString nickname = row->Nickname();
958 std::optional<const LIB_DATA*> loaded =
fetchIfLoaded( nickname );
961 ret.emplace_back( nickname );
964 wxLogTrace(
traceLibraries,
"GetLibraryNames: returning %zu of %zu libraries", ret.size(), rows.size() );
971 std::optional<const LIB_DATA*> r =
fetchIfLoaded( aNickname );
974 return !aCheckEnabled || !r.value()->row->Disabled();
1003 if( std::optional<const LIB_DATA*> optRow =
fetchIfLoaded( aNickname ); optRow )
1004 return ( *optRow )->row->Description();
1006 return std::nullopt;
1011 bool aIncludeInvalid )
const
1025 const wxString& aUri,
1062 return std::nullopt;
1065 return loaded /
static_cast<float>( total );
1071 wxLogTrace(
traceLibraries,
"BlockUntilLoaded: entry, acquiring m_loadMutex" );
1072 std::unique_lock<std::mutex> asyncLock(
m_loadMutex );
1076 for(
const std::future<void>& future :
m_futures )
1079 wxLogTrace(
traceLibraries,
"BlockUntilLoaded: all futures complete, loadCount=%zu, loadTotal=%zu",
1110 return it->second.status.error;
1117 return it->second.status.error;
1120 return std::nullopt;
1126 std::vector<std::pair<wxString, LIB_STATUS>> ret;
1130 if( row->Disabled() )
1135 ret.emplace_back( std::make_pair( row->Nickname(), *
result ) );
1140 ret.emplace_back( std::make_pair( row->Nickname(),
1143 .error =
LIBRARY_ERROR(
_(
"Library not found in library table" ) )
1160 if( !errors.IsEmpty() )
1161 errors += wxS(
"\n" );
1163 errors += wxString::Format(
_(
"Library '%s': %s" ),
1164 nickname, status.error->message );
1176 std::shared_mutex& aMutex )
1178 bool wasLoaded =
false;
1181 std::unique_lock lock( aMutex );
1182 auto it = aTarget.find( aNickname );
1184 if( it != aTarget.end() && it->second.plugin )
1187 aTarget.erase( it );
1195 if( !
result.has_value() )
1197 wxLogTrace(
traceLibraries,
"ReloadLibraryEntry: failed to reload %s (%s): %s",
1198 aNickname, magic_enum::enum_name( aScopeToReload ),
1199 result.error().message );
1273 return std::nullopt;
1285 return std::nullopt;
1289 return std::nullopt;
1303 return std::nullopt;
1315 return std::nullopt;
1319 return std::nullopt;
1325 std::map<wxString, LIB_DATA>& aTarget,
1326 std::shared_mutex& aMutex )
1328 bool present =
false;
1331 std::shared_lock lock( aMutex );
1332 present = aTarget.contains( aNickname ) && aTarget.at( aNickname ).plugin;
1340 wxLogTrace(
traceLibraries,
"Library %s (%s) not yet loaded, will attempt...",
1341 aNickname, magic_enum::enum_name( aScope ) );
1345 std::unique_lock lock( aMutex );
1348 aTarget[ row->
Nickname() ].row = row;
1351 return &aTarget.at( aNickname );
1355 return tl::unexpected(
plugin.error() );
1362 std::shared_lock lock( aMutex );
1363 return &aTarget.at( aNickname );
1380 wxString msg = wxString::Format(
_(
"Library %s not found" ), aNickname );
1391 return it->second.status;
1398 return it->second.status;
1401 return std::nullopt;
1407 std::unique_lock<std::mutex> asyncLock(
m_loadMutex, std::try_to_lock );
1413 []( std::future<void>& aFuture )
1415 return aFuture.valid()
1416 && aFuture.wait_for( 0s ) == std::future_status::ready;
1421 wxLogTrace(
traceLibraries,
"Cannot AsyncLoad, futures from a previous call remain!" );
1425 std::vector<LIBRARY_TABLE_ROW*> rows =
m_manager.Rows(
Type() );
1432 wxLogTrace(
traceLibraries,
"AsyncLoad: no libraries left to load; exiting" );
1439 [&](
const wxString& aLib, std::map<wxString, LIB_DATA>& aMap, std::shared_mutex& aMutex )
1441 std::shared_lock lock( aMutex );
1443 if(
auto it = aMap.find( aLib ); it != aMap.end() )
1445 LOAD_STATUS status = it->second.status.load_status;
1463 auto workQueue = std::make_shared<std::vector<LOAD_WORK>>();
1464 workQueue->reserve( rows.size() );
1468 wxString nickname = row->Nickname();
1483 workQueue->emplace_back( LOAD_WORK{ nickname, scope,
getUri( row ) } );
1486 if( workQueue->empty() )
1488 wxLogTrace(
traceLibraries,
"AsyncLoad: all libraries already loaded; exiting" );
1495 size_t poolSize =
tp.get_thread_count();
1496 size_t maxLoadThreads = std::max<size_t>( 1, poolSize > 2 ? poolSize - 2 : 1 );
1497 size_t numWorkers = std::min( maxLoadThreads, workQueue->size() );
1499 auto workIndex = std::make_shared<std::atomic<size_t>>( 0 );
1501 wxLogTrace(
traceLibraries,
"AsyncLoad: %zu libraries to load, using %zu worker threads (pool has %zu)",
1502 workQueue->size(), numWorkers, poolSize );
1504 for(
size_t w = 0; w < numWorkers; ++w )
1507 [
this, workQueue, workIndex]()
1511 if( m_abort.load() )
1514 size_t idx = workIndex->fetch_add( 1 );
1516 if( idx >= workQueue->size() )
1519 const LOAD_WORK& work = ( *workQueue )[idx];
1520 LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( work.nickname );
1522 if( result.has_value() )
1524 LIB_DATA* lib = *result;
1529 std::unique_lock lock(
1530 work.scope == LIBRARY_TABLE_SCOPE::GLOBAL
1532 : m_librariesMutex );
1533 lib->status.load_status = LOAD_STATUS::LOADING;
1536 enumerateLibrary( lib, work.uri );
1539 std::unique_lock lock(
1540 work.scope == LIBRARY_TABLE_SCOPE::GLOBAL
1542 : m_librariesMutex );
1543 lib->status.load_status = LOAD_STATUS::LOADED;
1546 catch( IO_ERROR& e )
1548 std::unique_lock lock(
1549 work.scope == LIBRARY_TABLE_SCOPE::GLOBAL
1551 : m_librariesMutex );
1552 lib->status.load_status = LOAD_STATUS::LOAD_ERROR;
1553 lib->status.error = LIBRARY_ERROR( { e.What() } );
1554 wxLogTrace( traceLibraries,
"%s: plugin threw exception: %s",
1555 work.nickname, e.What() );
1560 std::unique_lock lock(
1561 work.scope == LIBRARY_TABLE_SCOPE::GLOBAL
1563 : m_librariesMutex );
1565 std::map<wxString, LIB_DATA>& target =
1566 ( work.scope == LIBRARY_TABLE_SCOPE::GLOBAL ) ? globalLibs()
1569 target[work.nickname].status = LIB_STATUS( {
1570 .load_status = LOAD_STATUS::LOAD_ERROR,
1571 .error = result.error()
1577 }, BS::pr::lowest ) );
1580 wxLogTrace(
traceLibraries,
"Started async load of %zu libraries", workQueue->size() );
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::mutex m_rowCacheMutex
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)
std::map< ROW_CACHE_KEY, LIBRARY_TABLE_ROW * > m_rowCache
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)
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
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={})
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
static wxString StockTablePath(LIBRARY_TABLE_TYPE aType)
std::optional< LIBRARY_TABLE_ROW * > GetRow(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH)
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
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().