25#include <magic_enum.hpp>
28#include <unordered_set>
38using namespace std::chrono_literals;
59 std::vector<LIBRARY_TABLE_TYPE> aTablesToLoad )
73 wxCHECK_MSG(
false,
m_tables,
"Invalid scope passed to loadTables" );
77 std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>>& aTarget = getTarget();
79 if( aTablesToLoad.size() == 0 )
84 aTarget.erase( type );
88 if( fn.IsFileReadable() )
90 std::unique_ptr<LIBRARY_TABLE>
table = std::make_unique<LIBRARY_TABLE>( fn, aScope );
92 if(
table->Type() != type )
94 auto actualName = magic_enum::enum_name(
table->Type() );
95 auto expectedName = magic_enum::enum_name( type );
96 wxLogWarning( wxS(
"Library table '%s' has type %s but expected %s; skipping" ),
98 wxString( actualName.data(), actualName.size() ),
99 wxString( expectedName.data(), expectedName.size() ) );
103 aTarget[type] = std::move(
table );
108 wxLogTrace(
traceLibraries,
"No library table found at %s", fn.GetFullPath() );
116 std::unordered_set<wxString> seenTables;
121 seenTables.insert( aTable.Path() );
133 file.MakeAbsolute( wxFileName( aTable.Path() ).GetPath() );
136 wxString src = file.GetFullPath();
138 if( seenTables.contains( src ) )
140 wxLogTrace(
traceLibraries,
"Library table %s has already been loaded!", src );
142 row.SetErrorDescription(
_(
"A reference to this library table already exists" ) );
146 auto child = std::make_unique<LIBRARY_TABLE>( file, aRootTable.
Scope() );
148 processOneTable( *child );
153 row.SetErrorDescription( child->ErrorDescription() );
161 processOneTable( aRootTable );
172 default: wxCHECK(
false, wxEmptyString );
181 wxCHECK( !
m_tables.contains( aType ), );
202 const wxString& aPrefix ) :
208 wxFileName f( aBasePath,
"" );
214 .value_or(
nullptr );
218 wxDirTraverseResult
OnFile(
const wxString& aFilePath )
override
220 wxFileName file = wxFileName::FileName( aFilePath );
224 if( file.GetExt() == wxT(
"kicad_sym" )
231 return wxDIR_CONTINUE;
235 wxDirTraverseResult
OnDir(
const wxString& dirPath )
override
238 wxFileName dir = wxFileName::DirName( dirPath );
242 if( dirPath.EndsWith( wxS(
".pretty" ) )
248 else if( dirPath.EndsWith( designBlockExt )
255 return wxDIR_CONTINUE;
263 if( aTable->
HasRow( aNickname ) )
269 aNickname = wxString::Format(
"%s%s_%d",
m_lib_prefix, aBaseName, increment );
271 }
while( aTable->
HasRow( aNickname ) );
282 int aExtensionLength )
284 wxString versionedPath = wxString::Format( wxS(
"${%s}" ),
287 wxArrayString parts = aSource.GetDirs();
289 parts.Insert( versionedPath, 0 );
292 parts.Add( aSource.GetFullName() );
294 wxString libPath = wxJoin( parts,
'/' );
298 wxString
name = parts.Last().substr( 0, parts.Last().length() - aExtensionLength );
303 wxLogTrace(
traceLibraries,
"Manager: Adding PCM lib '%s' as '%s'", libPath, nickname );
315 wxLogTrace(
traceLibraries,
"Manager: Not adding existing PCM lib '%s'", libPath );
340 return fn.GetFullPath();
346 if( wxFileName fn( aPath ); fn.IsFileReadable() )
366 std::vector<LIBRARY_TABLE_TYPE> invalidTables;
376 invalidTables.emplace_back( tableType );
379 return invalidTables;
388 table.SetType( aType );
389 table.Rows().clear();
393 if( !defaultLib.IsFileReadable() )
395 wxLogTrace(
traceLibraries,
"Warning: couldn't read default library table for %s at '%s'",
396 magic_enum::enum_name( aType ), defaultLib.GetFullPath() );
399 if( aPopulateDefaultLibraries )
405 chained.
SetURI( defaultLib.GetFullPath() );
411 table.Format( &formatter );
429 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
430 adapter->GlobalTablesChanged( aTablesToLoad );
438 wxCHECK( settings, );
446 wxFileName d( *packagesPath,
"" );
451 wxDir dir( d.GetPath() );
453 dir.Traverse( traverser );
457 table->Save().map_error(
460 wxLogTrace(
traceLibraries, wxT(
"Warning: save failed after PCM auto-add: %s" ),
467 auto cleanupRemovedPCMLibraries =
473 auto toErase = std::ranges::remove_if(
table->Rows(),
476 wxString path = GetFullURI( &aRow, true );
477 return path.StartsWith( *packagesPath ) && !wxFile::Exists( path );
480 table->Rows().erase( toErase.begin(), toErase.end() );
482 if( !toErase.empty() )
484 table->Save().map_error(
487 wxLogTrace(
traceLibraries, wxT(
"Warning: save failed after PCM auto-remove: %s" ),
514 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
515 adapter->ProjectChanged();
523 for(
const std::unique_ptr<LIBRARY_MANAGER_ADAPTER>& adapter :
m_adapters | std::views::values )
524 adapter->AbortAsyncLoad();
529 std::unique_ptr<LIBRARY_MANAGER_ADAPTER>&& aAdapter )
533 wxCHECK_MSG( !
m_adapters.contains( aType ), ,
"You should only register an adapter once!" );
571 wxCHECK_MSG(
false, std::nullopt,
"Table() requires a single scope" );
578 magic_enum::enum_name( aType ) );
605 bool aIncludeInvalid )
const
607 std::map<wxString, LIBRARY_TABLE_ROW*> rows;
608 std::vector<wxString> rowOrder;
610 std::list<std::ranges::ref_view<const std::map<LIBRARY_TABLE_TYPE, std::unique_ptr<LIBRARY_TABLE>>>> tables;
615 tables = { std::views::all(
m_tables ) };
630 std::function<void(
const std::unique_ptr<LIBRARY_TABLE>&)> processTable =
631 [&](
const std::unique_ptr<LIBRARY_TABLE>& aTable )
633 if( aTable->Type() != aType )
636 if( aTable->IsOk() || aIncludeInvalid )
640 if( row.IsOk() || aIncludeInvalid )
648 if( row.Disabled() || row.Hidden() )
655 if( !rows.contains( row.Nickname() ) )
656 rowOrder.emplace_back( row.Nickname() );
658 rows[ row.Nickname() ] = &row;
665 for(
const std::unique_ptr<LIBRARY_TABLE>&
table :
666 std::views::join( tables ) | std::views::values )
668 processTable(
table );
671 std::vector<LIBRARY_TABLE_ROW*> ret;
673 for(
const wxString& row : rowOrder )
674 ret.emplace_back( rows[row] );
685 if( row->Nickname() == aNickname )
694 const wxString& aUri,
710 if( std::optional<LIBRARY_MANAGER_ADAPTER*> adapter =
Adapter( aType ); adapter )
711 ( *adapter )->ReloadLibraryEntry( aNickname, aScope );
716 std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad )
718 if( wxFileName::IsDirReadable( aProjectPath ) )
725 wxLogTrace(
traceLibraries,
"New project path %s is not readable, not loading project tables", aProjectPath );
731 std::initializer_list<LIBRARY_TABLE_TYPE> aTablesToLoad )
741 bool aSubstituted )
const
743 if( std::optional<const LIBRARY_TABLE_ROW*>
result =
GetRow( aType, aNickname ) )
765 return path.GetFullPath();
772 if( aURI1.Find(
"://" ) != wxNOT_FOUND )
775 return aURI1 == aURI2;
779 const wxFileName fn1( aURI1 );
780 const wxFileName fn2( aURI2 );
833 bool me = aChangedTables.size() == 0;
868 std::optional<LIB_STATUS> status =
LoadOne( &lib );
870 if( status.has_value() )
874 if( status.value().error.has_value() )
910 return row->Nickname();
919 std::vector<wxString> ret;
920 std::vector<LIBRARY_TABLE_ROW*> rows =
m_manager.Rows(
Type() );
922 wxLogTrace(
traceLibraries,
"GetLibraryNames: checking %zu rows from table", rows.size() );
926 wxString nickname = row->Nickname();
927 std::optional<const LIB_DATA*> loaded =
fetchIfLoaded( nickname );
930 ret.emplace_back( nickname );
933 wxLogTrace(
traceLibraries,
"GetLibraryNames: returning %zu of %zu libraries", ret.size(), rows.size() );
940 std::optional<const LIB_DATA*> r =
fetchIfLoaded( aNickname );
943 return !aCheckEnabled || !r.value()->row->Disabled();
972 if( std::optional<const LIB_DATA*> optRow =
fetchIfLoaded( aNickname ); optRow )
973 return ( *optRow )->row->Description();
980 bool aIncludeInvalid )
const
994 const wxString& aUri,
1031 return std::nullopt;
1034 return loaded /
static_cast<float>( total );
1040 wxLogTrace(
traceLibraries,
"BlockUntilLoaded: entry, acquiring m_loadMutex" );
1041 std::unique_lock<std::mutex> asyncLock(
m_loadMutex );
1045 for(
const std::future<void>& future :
m_futures )
1048 wxLogTrace(
traceLibraries,
"BlockUntilLoaded: all futures complete, loadCount=%zu, loadTotal=%zu",
1079 return it->second.status.error;
1086 return it->second.status.error;
1089 return std::nullopt;
1095 std::vector<std::pair<wxString, LIB_STATUS>> ret;
1099 if( row->Disabled() )
1104 ret.emplace_back( std::make_pair( row->Nickname(), *
result ) );
1109 ret.emplace_back( std::make_pair( row->Nickname(),
1112 .error =
LIBRARY_ERROR(
_(
"Library not found in library table" ) )
1129 if( !errors.IsEmpty() )
1130 errors += wxS(
"\n" );
1132 errors += wxString::Format(
_(
"Library '%s': %s" ),
1133 nickname, status.error->message );
1145 std::shared_mutex& aMutex )
1147 bool wasLoaded =
false;
1150 std::unique_lock lock( aMutex );
1151 auto it = aTarget.find( aNickname );
1153 if( it != aTarget.end() && it->second.plugin )
1156 aTarget.erase( it );
1164 if( !
result.has_value() )
1166 wxLogTrace(
traceLibraries,
"ReloadLibraryEntry: failed to reload %s (%s): %s",
1167 aNickname, magic_enum::enum_name( aScopeToReload ),
1168 result.error().message );
1242 return std::nullopt;
1254 return std::nullopt;
1258 return std::nullopt;
1272 return std::nullopt;
1284 return std::nullopt;
1288 return std::nullopt;
1294 std::map<wxString, LIB_DATA>& aTarget,
1295 std::shared_mutex& aMutex )
1297 bool present =
false;
1300 std::shared_lock lock( aMutex );
1301 present = aTarget.contains( aNickname ) && aTarget.at( aNickname ).plugin;
1309 wxLogTrace(
traceLibraries,
"Library %s (%s) not yet loaded, will attempt...",
1310 aNickname, magic_enum::enum_name( aScope ) );
1314 std::unique_lock lock( aMutex );
1317 aTarget[ row->
Nickname() ].row = row;
1320 return &aTarget.at( aNickname );
1324 return tl::unexpected(
plugin.error() );
1331 std::shared_lock lock( aMutex );
1332 return &aTarget.at( aNickname );
1349 wxString msg = wxString::Format(
_(
"Library %s not found" ), aNickname );
1360 return it->second.status;
1367 return it->second.status;
1370 return std::nullopt;
1376 std::unique_lock<std::mutex> asyncLock(
m_loadMutex, std::try_to_lock );
1382 []( std::future<void>& aFuture )
1384 return aFuture.valid()
1385 && aFuture.wait_for( 0s ) == std::future_status::ready;
1390 wxLogTrace(
traceLibraries,
"Cannot AsyncLoad, futures from a previous call remain!" );
1394 std::vector<LIBRARY_TABLE_ROW*> rows =
m_manager.Rows(
Type() );
1401 wxLogTrace(
traceLibraries,
"AsyncLoad: no libraries left to load; exiting" );
1408 [&](
const wxString& aLib, std::map<wxString, LIB_DATA>& aMap, std::shared_mutex& aMutex )
1410 std::shared_lock lock( aMutex );
1412 if(
auto it = aMap.find( aLib ); it != aMap.end() )
1414 LOAD_STATUS status = it->second.status.load_status;
1425 wxString nickname = row->Nickname();
1442 wxString uri =
getUri( row );
1445 [
this, nickname, scope, uri]()
1447 if( m_abort.load() )
1450 LIBRARY_RESULT<LIB_DATA*> result = loadIfNeeded( nickname );
1452 if( result.has_value() )
1454 LIB_DATA* lib = *result;
1459 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL ? globalLibsMutex()
1460 : m_librariesMutex );
1461 lib->status.load_status = LOAD_STATUS::LOADING;
1464 enumerateLibrary( lib, uri );
1467 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL ? globalLibsMutex()
1468 : m_librariesMutex );
1469 lib->status.load_status = LOAD_STATUS::LOADED;
1472 catch( IO_ERROR& e )
1474 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL ? globalLibsMutex()
1475 : m_librariesMutex );
1476 lib->status.load_status = LOAD_STATUS::LOAD_ERROR;
1477 lib->status.error = LIBRARY_ERROR( { e.What() } );
1478 wxLogTrace( traceLibraries,
"%s: plugin threw exception: %s", nickname, e.What() );
1483 std::unique_lock lock( scope == LIBRARY_TABLE_SCOPE::GLOBAL ? globalLibsMutex()
1484 : m_librariesMutex );
1486 std::map<wxString, LIB_DATA>& target = ( scope == LIBRARY_TABLE_SCOPE::GLOBAL ) ? globalLibs()
1489 target[nickname].status = LIB_STATUS( {
1490 .load_status = LOAD_STATUS::LOAD_ERROR,
1491 .error = result.error()
1496 }, BS::pr::lowest ) );
1499 size_t total = m_loadTotal.load();
1502 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().