From 70fe2a8f1e36d8530ca963f24f0a777a6535c14c Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Tue, 13 Feb 2024 21:53:09 +0100 Subject: [PATCH] kicad_cli: Allow upgrade of legacy and non-kicad symbol libraries --- eeschema/dialogs/panel_sym_lib_table.cpp | 62 +------------------- eeschema/dialogs/panel_sym_lib_table.h | 3 - eeschema/eeschema_jobs_handler.cpp | 72 ++++++++++++++++-------- eeschema/sch_io/sch_io_mgr.cpp | 61 ++++++++++++++++++++ eeschema/sch_io/sch_io_mgr.h | 6 ++ 5 files changed, 116 insertions(+), 88 deletions(-) diff --git a/eeschema/dialogs/panel_sym_lib_table.cpp b/eeschema/dialogs/panel_sym_lib_table.cpp index 49f43253c2..44bbcb38d4 100644 --- a/eeschema/dialogs/panel_sym_lib_table.cpp +++ b/eeschema/dialogs/panel_sym_lib_table.cpp @@ -912,7 +912,7 @@ void PANEL_SYM_LIB_TABLE::onConvertLegacyLibraries( wxCommandEvent& event ) wxString options = m_cur_grid->GetCellValue( row, COL_OPTIONS ); std::unique_ptr props( LIB_TABLE::ParseOptions( options.ToStdString() ) ); - if( convertLibrary( props.get(), legacyLib.GetFullPath(), newLib.GetFullPath() ) ) + if( SCH_IO_MGR::ConvertLibrary( props.get(), legacyLib.GetFullPath(), newLib.GetFullPath() ) ) { relPath = NormalizePath( newLib.GetFullPath(), &Pgm().GetLocalEnvVariables(), m_project ); @@ -938,66 +938,6 @@ void PANEL_SYM_LIB_TABLE::onConvertLegacyLibraries( wxCommandEvent& event ) } -bool PANEL_SYM_LIB_TABLE::convertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath, - const wxString& aNewFilepath ) -{ - SCH_IO_MGR::SCH_FILE_T oldFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aOldFilePath ); - - if( oldFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN ) - return false; - - IO_RELEASER oldFilePI( SCH_IO_MGR::FindPlugin( oldFileType ) ); - IO_RELEASER kicadPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) ); - std::vector symbols; - std::vector newSymbols; - std::map symbolMap; - - try - { - oldFilePI->EnumerateSymbolLib( symbols, aOldFilePath, aOldFileProps ); - - // Copy non-aliases first so we can build a map from symbols to newSymbols - for( LIB_SYMBOL* symbol : symbols ) - { - if( symbol->IsAlias() ) - continue; - - symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) ); - - newSymbols.push_back( new LIB_SYMBOL( *symbol ) ); - symbolMap[symbol] = newSymbols.back(); - } - - // Now do the aliases using the map to hook them up to their newSymbol parents - for( LIB_SYMBOL* symbol : symbols ) - { - if( !symbol->IsAlias() ) - continue; - - symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) ); - - newSymbols.push_back( new LIB_SYMBOL( *symbol ) ); - newSymbols.back()->SetParent( symbolMap[ symbol->GetParent().lock().get() ] ); - } - - // Create a blank library - kicadPI->SaveLibrary( aNewFilepath ); - - // Finally write out newSymbols - for( LIB_SYMBOL* symbol : newSymbols ) - { - kicadPI->SaveSymbol( aNewFilepath, symbol ); - } - } - catch( ... ) - { - return false; - } - - return true; -} - - bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow() { if( !m_cur_grid->CommitPendingChanges() ) diff --git a/eeschema/dialogs/panel_sym_lib_table.h b/eeschema/dialogs/panel_sym_lib_table.h index 235c471b95..cf23e0a835 100644 --- a/eeschema/dialogs/panel_sym_lib_table.h +++ b/eeschema/dialogs/panel_sym_lib_table.h @@ -65,9 +65,6 @@ private: /// by examining all the full_uri columns. void populateEnvironReadOnlyTable(); - bool convertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath, - const wxString& aNewFilePath ); - SYMBOL_LIB_TABLE_GRID* global_model() const; SYMBOL_LIB_TABLE_GRID* project_model() const; diff --git a/eeschema/eeschema_jobs_handler.cpp b/eeschema/eeschema_jobs_handler.cpp index ec3732fec4..34a902ce4d 100644 --- a/eeschema/eeschema_jobs_handler.cpp +++ b/eeschema/eeschema_jobs_handler.cpp @@ -870,17 +870,7 @@ int EESCHEMA_JOBS_HANDLER::JobSymUpgrade( JOB* aJob ) wxFileName fn( upgradeJob->m_libraryPath ); fn.MakeAbsolute(); - SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() ); - - try - { - schLibrary.Load(); - } - catch( ... ) - { - m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR ); - return CLI::EXIT_CODES::ERR_UNKNOWN; - } + SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() ); if( !upgradeJob->m_outputLibraryPath.IsEmpty() ) { @@ -892,31 +882,65 @@ int EESCHEMA_JOBS_HANDLER::JobSymUpgrade( JOB* aJob ) return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; } } - - bool shouldSave = upgradeJob->m_force - || schLibrary.GetFileFormatVersionAtLoad() < SEXPR_SYMBOL_LIB_FILE_VERSION; - - if( shouldSave ) + else if( fileType != SCH_IO_MGR::SCH_KICAD ) { - m_reporter->Report( _( "Saving symbol library in updated format\n" ), RPT_SEVERITY_ACTION ); + m_reporter->Report( _( "Output path must be specified to convert legacy and non-KiCad libraries\n" ), + RPT_SEVERITY_ERROR ); + + return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } + + if( fileType == SCH_IO_MGR::SCH_KICAD ) + { + SCH_IO_KICAD_SEXPR_LIB_CACHE schLibrary( fn.GetFullPath() ); try { - if( !upgradeJob->m_outputLibraryPath.IsEmpty() ) - schLibrary.SetFileName( upgradeJob->m_outputLibraryPath ); - - schLibrary.SetModified(); - schLibrary.Save(); + schLibrary.Load(); } catch( ... ) { - m_reporter->Report( ( "Unable to save library\n" ), RPT_SEVERITY_ERROR ); + m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR ); return CLI::EXIT_CODES::ERR_UNKNOWN; } + + bool shouldSave = + upgradeJob->m_force + || schLibrary.GetFileFormatVersionAtLoad() < SEXPR_SYMBOL_LIB_FILE_VERSION; + + if( shouldSave ) + { + m_reporter->Report( _( "Saving symbol library in updated format\n" ), + RPT_SEVERITY_ACTION ); + + try + { + if( !upgradeJob->m_outputLibraryPath.IsEmpty() ) + { + schLibrary.SetFileName( upgradeJob->m_outputLibraryPath ); + } + + schLibrary.SetModified(); + schLibrary.Save(); + } + catch( ... ) + { + m_reporter->Report( ( "Unable to save library\n" ), RPT_SEVERITY_ERROR ); + return CLI::EXIT_CODES::ERR_UNKNOWN; + } + } + else + { + m_reporter->Report( _( "Symbol library was not updated\n" ), RPT_SEVERITY_INFO ); + } } else { - m_reporter->Report( _( "Symbol library was not updated\n" ), RPT_SEVERITY_INFO ); + if( !SCH_IO_MGR::ConvertLibrary( nullptr, fn.GetAbsolutePath(), upgradeJob->m_outputLibraryPath ) ) + { + m_reporter->Report( ( "Unable to convert library\n" ), RPT_SEVERITY_ERROR ); + return CLI::EXIT_CODES::ERR_UNKNOWN; + } } return CLI::EXIT_CODES::OK; diff --git a/eeschema/sch_io/sch_io_mgr.cpp b/eeschema/sch_io/sch_io_mgr.cpp index f5c849f5d7..caef05fbb3 100644 --- a/eeschema/sch_io/sch_io_mgr.cpp +++ b/eeschema/sch_io/sch_io_mgr.cpp @@ -39,6 +39,7 @@ #include #include +#include #define FMT_UNIMPLEMENTED _( "Plugin \"%s\" does not implement the \"%s\" function." ) #define FMT_NOTFOUND _( "Plugin type \"%s\" is not found." ) @@ -185,3 +186,63 @@ SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromSchPath( const wxString& a return SCH_IO_MGR::SCH_FILE_UNKNOWN; } + + +bool SCH_IO_MGR::ConvertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath, + const wxString& aNewFilepath ) +{ + SCH_IO_MGR::SCH_FILE_T oldFileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aOldFilePath ); + + if( oldFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN ) + return false; + + IO_RELEASER oldFilePI( SCH_IO_MGR::FindPlugin( oldFileType ) ); + IO_RELEASER kicadPI( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) ); + std::vector symbols; + std::vector newSymbols; + std::map symbolMap; + + try + { + oldFilePI->EnumerateSymbolLib( symbols, aOldFilePath, aOldFileProps ); + + // Copy non-aliases first, so we can build a map from symbols to newSymbols + for( LIB_SYMBOL* symbol : symbols ) + { + if( symbol->IsAlias() ) + continue; + + symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) ); + + newSymbols.push_back( new LIB_SYMBOL( *symbol ) ); + symbolMap[symbol] = newSymbols.back(); + } + + // Now do the aliases using the map to hook them up to their newSymbol parents + for( LIB_SYMBOL* symbol : symbols ) + { + if( !symbol->IsAlias() ) + continue; + + symbol->SetName( EscapeString( symbol->GetName(), CTX_LIBID ) ); + + newSymbols.push_back( new LIB_SYMBOL( *symbol ) ); + newSymbols.back()->SetParent( symbolMap[ symbol->GetParent().lock().get() ] ); + } + + // Create a blank library + kicadPI->SaveLibrary( aNewFilepath ); + + // Finally write out newSymbols + for( LIB_SYMBOL* symbol : newSymbols ) + { + kicadPI->SaveSymbol( aNewFilepath, symbol ); + } + } + catch( ... ) + { + return false; + } + + return true; +} diff --git a/eeschema/sch_io/sch_io_mgr.h b/eeschema/sch_io/sch_io_mgr.h index 4cf4cadcfb..8e5076ecc9 100644 --- a/eeschema/sch_io/sch_io_mgr.h +++ b/eeschema/sch_io/sch_io_mgr.h @@ -106,6 +106,12 @@ public: * Return a plugin type given a schematic using the file extension of \a aSchematicPath. */ static SCH_FILE_T GuessPluginTypeFromSchPath( const wxString& aSchematicPath, int aCtl = 0 ); + + /** + * Convert a schematic symbol library to the latest KiCad format + */ + static bool ConvertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath, + const wxString& aNewFilepath ); }; #endif // _SCH_IO_MGR_H_