diff --git a/common/libraries/library_manager.cpp b/common/libraries/library_manager.cpp index 9c870abc10..71108ee2fe 100644 --- a/common/libraries/library_manager.cpp +++ b/common/libraries/library_manager.cpp @@ -147,6 +147,43 @@ void LIBRARY_MANAGER::loadNestedTables( LIBRARY_TABLE& aRootTable ) } +wxString LIBRARY_MANAGER::tableFileName( LIBRARY_TABLE_TYPE aType ) +{ + switch( aType ) + { + case LIBRARY_TABLE_TYPE::SYMBOL: return FILEEXT::SymbolLibraryTableFileName; + case LIBRARY_TABLE_TYPE::FOOTPRINT: return FILEEXT::FootprintLibraryTableFileName; + case LIBRARY_TABLE_TYPE::DESIGN_BLOCK: return FILEEXT::DesignBlockLibraryTableFileName; + } + + wxCHECK( false, wxEmptyString ); +} + + +void LIBRARY_MANAGER::createEmptyTable( LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope ) +{ + + + if( aScope == LIBRARY_TABLE_SCOPE::GLOBAL ) + { + wxCHECK( !m_tables.contains( aType ), /* void */ ); + wxFileName fn( PATHS::GetUserSettingsPath(), tableFileName( aType ) ); + + m_tables[aType] = std::make_unique( fn.GetFullPath(), + LIBRARY_TABLE_SCOPE::GLOBAL ); + } + else if( aScope == LIBRARY_TABLE_SCOPE::PROJECT ) + { + wxCHECK( !m_projectTables.contains( aType ), /* void */ ); + wxFileName fn( Pgm().GetSettingsManager().Prj().GetProjectDirectory(), + tableFileName( aType ) ); + + m_projectTables[aType] = std::make_unique( fn.GetFullPath(), + LIBRARY_TABLE_SCOPE::PROJECT ); + } +} + + class PCM_LIB_TRAVERSER final : public wxDirTraverser { public: @@ -386,7 +423,7 @@ std::optional LIBRARY_MANAGER::Adapter( LIBRARY_TABLE_ std::optional LIBRARY_MANAGER::Table( LIBRARY_TABLE_TYPE aType, - LIBRARY_TABLE_SCOPE aScope ) const + LIBRARY_TABLE_SCOPE aScope ) { switch( aScope ) { @@ -410,7 +447,12 @@ std::optional LIBRARY_MANAGER::Table( LIBRARY_TABLE_TYPE aType, { // TODO: handle multiple projects if( !m_projectTables.contains( aType ) ) - return std::nullopt; + { + if( !Pgm().GetSettingsManager().Prj().IsNullProject() ) + createEmptyTable( aType, LIBRARY_TABLE_SCOPE::PROJECT ); + else + return std::nullopt; + } return m_projectTables.at( aType ).get(); } diff --git a/eeschema/sch_io/altium/sch_io_altium.cpp b/eeschema/sch_io/altium/sch_io_altium.cpp index 00784b3971..d997e2fd9b 100644 --- a/eeschema/sch_io/altium/sch_io_altium.cpp +++ b/eeschema/sch_io/altium/sch_io_altium.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,6 @@ #include #include #include -#include #include #include @@ -501,17 +501,10 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI rootScreen->m_sheetInstances.emplace_back( sheetInstance ); - // TODO(JE) library tables -#if 0 - SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &m_schematic->Project() ); - - wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." ); - if( aFileName.empty() ) LoadSchematicProject( aSchematic, aProperties ); else ParseAltiumSch( aFileName ); -#endif if( m_reporter ) { @@ -4847,7 +4840,8 @@ void SCH_IO_ALTIUM::doEnumerateSymbolLib( const wxString& aLibraryPath, { ensureLoadedLibrary( aLibraryPath, aProperties ); - bool powerSymbolsOnly = ( aProperties && aProperties->contains( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) ); + bool powerSymbolsOnly = ( aProperties && + aProperties->contains( SYMBOL_LIBRARY_MANAGER_ADAPTER::PropPowerSymsOnly ) ); auto it = m_libCache.find( aLibraryPath ); diff --git a/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp b/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp index 5643056feb..adc25122ec 100644 --- a/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp +++ b/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -100,12 +102,10 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi CADSTAR_SCH_ARCHIVE_LOADER csaLoader( aFileName, m_reporter, m_progressReporter ); csaLoader.Load( aSchematic, rootSheet ); - // TODO(JE) library tables -#if 0 - // SAVE SYMBOLS TO PROJECT LIBRARY: - SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &aSchematic->Project() ); - - wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." ); + // Save symbols to project library + SYMBOL_LIBRARY_MANAGER_ADAPTER* adapter = PROJECT_SCH::SymbolLibManager( &aSchematic->Project() ); + LIBRARY_TABLE* table = adapter->ProjectTable().value_or( nullptr ); + wxCHECK_MSG( table, nullptr, "Could not load symbol lib table." ); wxFileName prj_fn = aSchematic->Project().GetProjectFullName(); wxString libName = CADSTAR_SCH_ARCHIVE_LOADER::CreateLibName( prj_fn, nullptr ); @@ -115,29 +115,21 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi IO_RELEASER sch_plugin( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) ); - if( !libTable->HasLibrary( libName ) ) + if( !table->HasRow( libName ) ) { // Create a new empty symbol library. sch_plugin->CreateLibrary( libFileName.GetFullPath() ); wxString libTableUri = "${KIPRJMOD}/" + libFileName.GetFullName(); // Add the new library to the project symbol library table. - libTable->InsertRow( - new SYMBOL_LIB_TABLE_ROW( libName, libTableUri, wxString( "KiCad" ) ) ); + LIBRARY_TABLE_ROW& row = table->InsertRow(); + row.SetNickname( libName ); + row.SetURI( libTableUri ); + row.SetType( "KiCad" ); - // Save project symbol library table. - wxFileName libtab_fn( aSchematic->Project().GetProjectPath(), - SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() ); + adapter->Manager().Save( table ); - // So output formatter goes out of scope and closes the file before reloading. - { - FILE_OUTPUTFORMATTER formatter( libtab_fn.GetFullPath() ); - libTable->Format( &formatter, 0 ); - } - - // Relaod the symbol library table. - aSchematic->Project().SetElem( PROJECT::ELEM::SYMBOL_LIB_TABLE, NULL ); - PROJECT_SCH::SchSymbolLibTable( &aSchematic->Project() ); + adapter->LoadOne( libName ); } // set properties to prevent save file on every symbol save @@ -164,7 +156,6 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi } }; } -#endif // Need to fix up junctions after import to retain connectivity aSchematic->FixupJunctionsAfterImport(); diff --git a/eeschema/sch_io/eagle/sch_io_eagle.cpp b/eeschema/sch_io/eagle/sch_io_eagle.cpp index c00108149f..54efa3c5f8 100644 --- a/eeschema/sch_io/eagle/sch_io_eagle.cpp +++ b/eeschema/sch_io/eagle/sch_io_eagle.cpp @@ -422,39 +422,29 @@ SCH_SHEET* SCH_IO_EAGLE::LoadSchematicFile( const wxString& aFileName, SCHEMATIC m_sheetPath.SetPageNumber( wxT( "1" ) ); } - // TODO(JE) library tables -#if 0 - SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &m_schematic->Project() ); - - wxCHECK_MSG( libTable, nullptr, wxT( "Could not load symbol lib table." ) ); + SYMBOL_LIBRARY_MANAGER_ADAPTER* adapter = PROJECT_SCH::SymbolLibManager( &aSchematic->Project() ); + LIBRARY_TABLE* table = adapter->ProjectTable().value_or( nullptr ); + wxCHECK_MSG( table, nullptr, "Could not load symbol lib table." ); m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) ); /// @note No check is being done here to see if the existing symbol library exists so this /// will overwrite the existing one. - if( !libTable->HasLibrary( getLibName() ) ) + if( !table->HasRow( getLibName() ) ) { // Create a new empty symbol library. m_pi->CreateLibrary( getLibFileName().GetFullPath() ); wxString libTableUri = wxT( "${KIPRJMOD}/" ) + getLibFileName().GetFullName(); // Add the new library to the project symbol library table. - libTable->InsertRow( new SYMBOL_LIB_TABLE_ROW( getLibName(), libTableUri, - wxT( "KiCad" ) ) ); + LIBRARY_TABLE_ROW& row = table->InsertRow(); + row.SetNickname( getLibName() ); + row.SetURI( libTableUri ); + row.SetType( "KiCad" ); - // Save project symbol library table. - wxFileName fn( m_schematic->Project().GetProjectPath(), - SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() ); + adapter->Manager().Save( table ); - // So output formatter goes out of scope and closes the file before reloading. - { - FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() ); - libTable->Format( &formatter, 0 ); - } - - // Reload the symbol library table. - m_schematic->Project().SetElem( PROJECT::ELEM::SYMBOL_LIB_TABLE, nullptr ); - PROJECT_SCH::SchSymbolLibTable( &m_schematic->Project() ); + adapter->LoadOne( getLibName() ); } m_eagleDoc = std::make_unique( currentNode, this ); @@ -467,7 +457,7 @@ SCH_SHEET* SCH_IO_EAGLE::LoadSchematicFile( const wxString& aFileName, SCHEMATIC loadDrawing( m_eagleDoc->drawing ); m_pi->SaveLibrary( getLibFileName().GetFullPath() ); -#endif + SCH_SCREENS allSheets( m_rootSheet ); allSheets.UpdateSymbolLinks(); // Update all symbol library links for all sheets. diff --git a/eeschema/sch_io/easyeda/sch_io_easyeda.cpp b/eeschema/sch_io/easyeda/sch_io_easyeda.cpp index a3199d0522..656e721f78 100644 --- a/eeschema/sch_io/easyeda/sch_io_easyeda.cpp +++ b/eeschema/sch_io/easyeda/sch_io_easyeda.cpp @@ -645,10 +645,6 @@ SCH_SHEET* SCH_IO_EASYEDA::LoadSchematicFile( const wxString& aFileName, SCHEMAT const_cast( rootSheet->m_Uuid ) = screen->GetUuid(); } - // TODO(JE) library tables - // SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &aSchematic->Project() ); - // - // wxCHECK_MSG( libTable, nullptr, wxS( "Could not load symbol lib table." ) ); LoadSchematic( aSchematic, rootSheet, aFileName ); aSchematic->CurrentSheet().UpdateAllScreenReferences(); diff --git a/eeschema/sch_io/easyedapro/sch_io_easyedapro.cpp b/eeschema/sch_io/easyedapro/sch_io_easyedapro.cpp index dac25f5046..85107afad4 100644 --- a/eeschema/sch_io/easyedapro/sch_io_easyedapro.cpp +++ b/eeschema/sch_io/easyedapro/sch_io_easyedapro.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -47,6 +46,8 @@ #include #include #include +#include +#include struct SCH_IO_EASYEDAPRO::PRJ_DATA @@ -461,10 +462,6 @@ SCH_SHEET* SCH_IO_EASYEDAPRO::LoadSchematicFile( const wxString& aFileName, const_cast( rootSheet->m_Uuid ) = screen->GetUuid(); } - // TODO(JE) library tables - // SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &aSchematic->Project() ); - // wxCHECK_MSG( libTable, nullptr, wxS( "Could not load symbol lib table." ) ); - SCH_EASYEDAPRO_PARSER parser( nullptr, nullptr ); wxFileName fname( aFileName ); wxString libName = EASYEDAPRO::ShortenLibName( fname.GetName() ); @@ -607,32 +604,26 @@ SCH_SHEET* SCH_IO_EASYEDAPRO::LoadSchematicFile( const wxString& aFileName, IO_RELEASER sch_plugin( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) ); - // TODO(JE) library tables -#if 0 - if( !libTable->HasLibrary( libName ) ) + SYMBOL_LIBRARY_MANAGER_ADAPTER* adapter = PROJECT_SCH::SymbolLibManager( &aSchematic->Project() ); + LIBRARY_TABLE* table = adapter->ProjectTable().value_or( nullptr ); + wxCHECK_MSG( table, nullptr, "Could not load symbol lib table." ); + + if( !table->HasRow( libName ) ) { // Create a new empty symbol library. sch_plugin->CreateLibrary( libFileName.GetFullPath() ); wxString libTableUri = wxS( "${KIPRJMOD}/" ) + libFileName.GetFullName(); // Add the new library to the project symbol library table. - libTable->InsertRow( new SYMBOL_LIB_TABLE_ROW( libName, libTableUri, wxS( "KiCad" ) ) ); + LIBRARY_TABLE_ROW& row = table->InsertRow(); + row.SetNickname( libName ); + row.SetURI( libTableUri ); + row.SetType( "KiCad" ); - // Save project symbol library table. - wxFileName fn( aSchematic->Project().GetProjectPath(), - SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() ); + adapter->Manager().Save( table ); - // So output formatter goes out of scope and closes the file before reloading. - { - FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() ); - libTable->Format( &formatter, 0 ); - } - - // Relaod the symbol library table. - aSchematic->Project().SetElem( PROJECT::ELEM::SYMBOL_LIB_TABLE, NULL ); - PROJECT_SCH::SchSymbolLibTable( &aSchematic->Project() ); + adapter->LoadOne( libName ); } -#endif // set properties to prevent save file on every symbol save std::map properties; diff --git a/eeschema/sch_io/ltspice/sch_io_ltspice.cpp b/eeschema/sch_io/ltspice/sch_io_ltspice.cpp index 95d689865b..398e3628ae 100644 --- a/eeschema/sch_io/ltspice/sch_io_ltspice.cpp +++ b/eeschema/sch_io/ltspice/sch_io_ltspice.cpp @@ -71,10 +71,6 @@ SCH_SHEET* SCH_IO_LTSPICE::LoadSchematicFile( const wxString& aFileName, SCHEMAT const_cast( rootSheet->m_Uuid ) = screen->GetUuid(); } - // TODO(JE) library tables - // SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &aSchematic->Project() ); - // wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." ); - // Windows path: C:\Users\USERNAME\AppData\Local\LTspice\lib wxFileName ltspiceDataDir( KIPLATFORM::ENV::GetUserLocalDataPath(), wxEmptyString ); ltspiceDataDir.AppendDir( wxS( "LTspice" ) ); diff --git a/include/libraries/library_manager.h b/include/libraries/library_manager.h index 4ee9b76ed6..929f24e856 100644 --- a/include/libraries/library_manager.h +++ b/include/libraries/library_manager.h @@ -57,8 +57,16 @@ public: std::optional Adapter( LIBRARY_TABLE_TYPE aType ) const; + /** + * Retrieves a given table; creating a new empty project table if a valid project is + * loaded and the given table type doesn't exist in the project. + * @param aType determines which type of table to return + * @param aScope determines whether to return a global or project table + * @return the given table if it exists (which should be the case unless a project table is + * requested and there is no valid project loaded) + */ std::optional Table( LIBRARY_TABLE_TYPE aType, - LIBRARY_TABLE_SCOPE aScope ) const; + LIBRARY_TABLE_SCOPE aScope ); /** * Returns a flattened list of libraries of the given type @@ -115,6 +123,10 @@ private: void loadNestedTables( LIBRARY_TABLE& aTable ); + static wxString tableFileName( LIBRARY_TABLE_TYPE aType ); + + void createEmptyTable( LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope ); + std::map> m_tables; /// Map of full URI to table object for tables that are referenced by global or project tables @@ -147,6 +159,8 @@ public: virtual ~LIBRARY_MANAGER_ADAPTER(); + LIBRARY_MANAGER& Manager() const { return m_manager; } + /// The type of library table this adapter works with virtual LIBRARY_TABLE_TYPE Type() const = 0;