diff --git a/kicad/cli/command_fp_upgrade.cpp b/kicad/cli/command_fp_upgrade.cpp index e6526e9f4f..c97473d224 100644 --- a/kicad/cli/command_fp_upgrade.cpp +++ b/kicad/cli/command_fp_upgrade.cpp @@ -50,12 +50,6 @@ int CLI::FP_UPGRADE_COMMAND::doPerform( KIWAY& aKiway ) fpJob->m_outputLibraryPath = m_argOutput; fpJob->m_force = m_argParser.get( ARG_FORCE ); - if( !wxDir::Exists( fpJob->m_libraryPath ) ) - { - wxFprintf( stderr, _( "Footprint library path does not exist or is not accessible\n" ) ); - return EXIT_CODES::ERR_INVALID_INPUT_FILE; - } - int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, fpJob.get() ); return exitCode; diff --git a/pcbnew/dialogs/panel_fp_lib_table.cpp b/pcbnew/dialogs/panel_fp_lib_table.cpp index a08b3f3ac6..d569f4ed32 100644 --- a/pcbnew/dialogs/panel_fp_lib_table.cpp +++ b/pcbnew/dialogs/panel_fp_lib_table.cpp @@ -866,7 +866,7 @@ void PANEL_FP_LIB_TABLE::onMigrateLibraries( 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( PCB_IO_MGR::ConvertLibrary( props.get(), legacyLib.GetFullPath(), newLib.GetFullPath() ) ) { relPath = NormalizePath( newLib.GetFullPath(), &Pgm().GetLocalEnvVariables(), m_project ); @@ -888,45 +888,6 @@ void PANEL_FP_LIB_TABLE::onMigrateLibraries( wxCommandEvent& event ) } -bool PANEL_FP_LIB_TABLE::convertLibrary( STRING_UTF8_MAP* aOldFileProps, - const wxString& aOldFilePath, - const wxString& aNewFilePath) -{ - PCB_IO_MGR::PCB_FILE_T oldFileType = PCB_IO_MGR::GuessPluginTypeFromLibPath( aOldFilePath ); - - if( oldFileType == PCB_IO_MGR::FILE_TYPE_NONE ) - return false; - - - IO_RELEASER oldFilePI( PCB_IO_MGR::PluginFind( oldFileType ) ); - IO_RELEASER kicadPI( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) ); - wxArrayString fpNames; - wxFileName newFileName( aNewFilePath ); - - if( !newFileName.DirExists() && !wxFileName::Mkdir( aNewFilePath, wxS_DIR_DEFAULT ) ) - return false; - - try - { - bool bestEfforts = false; // throw on first error - oldFilePI->FootprintEnumerate( fpNames, aOldFilePath, bestEfforts, aOldFileProps ); - - for ( const wxString& fpName : fpNames ) - { - std::unique_ptr fp( oldFilePI->GetEnumeratedFootprint( aOldFilePath, fpName, aOldFileProps ) ); - kicadPI->FootprintSave( aNewFilePath, fp.get() ); - } - - } - catch( ... ) - { - return false; - } - - return true; -} - - void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event ) { if( !m_cur_grid->CommitPendingChanges() ) diff --git a/pcbnew/dialogs/panel_fp_lib_table.h b/pcbnew/dialogs/panel_fp_lib_table.h index 998a8098df..f9e94e88bf 100644 --- a/pcbnew/dialogs/panel_fp_lib_table.h +++ b/pcbnew/dialogs/panel_fp_lib_table.h @@ -68,9 +68,6 @@ private: void populateEnvironReadOnlyTable(); void populatePluginList(); - bool convertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath, - const wxString& aNewFilePath ); - FP_LIB_TABLE_GRID* global_model() const { return (FP_LIB_TABLE_GRID*) m_global_grid->GetTable(); diff --git a/pcbnew/pcb_io/pcb_io_mgr.cpp b/pcbnew/pcb_io/pcb_io_mgr.cpp index 1bbf8e6789..8e5823f5a0 100644 --- a/pcbnew/pcb_io/pcb_io_mgr.cpp +++ b/pcbnew/pcb_io/pcb_io_mgr.cpp @@ -183,6 +183,45 @@ void PCB_IO_MGR::Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* a THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) ); } + +bool PCB_IO_MGR::ConvertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath, + const wxString& aNewFilePath ) +{ + PCB_IO_MGR::PCB_FILE_T oldFileType = PCB_IO_MGR::GuessPluginTypeFromLibPath( aOldFilePath ); + + if( oldFileType == PCB_IO_MGR::FILE_TYPE_NONE ) + return false; + + + IO_RELEASER oldFilePI( PCB_IO_MGR::PluginFind( oldFileType ) ); + IO_RELEASER kicadPI( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) ); + wxArrayString fpNames; + wxFileName newFileName( aNewFilePath ); + + if( !newFileName.DirExists() && !wxFileName::Mkdir( aNewFilePath, wxS_DIR_DEFAULT ) ) + return false; + + try + { + bool bestEfforts = false; // throw on first error + oldFilePI->FootprintEnumerate( fpNames, aOldFilePath, bestEfforts, aOldFileProps ); + + for ( const wxString& fpName : fpNames ) + { + std::unique_ptr fp( oldFilePI->GetEnumeratedFootprint( aOldFilePath, fpName, aOldFileProps ) ); + kicadPI->FootprintSave( aNewFilePath, fp.get() ); + } + + } + catch( ... ) + { + return false; + } + + return true; +} + + // These text strings are "truth" for identifying the plugins. If you change the spellings, // you will obsolete library tables, so don't do it. Additions are OK. diff --git a/pcbnew/pcb_io/pcb_io_mgr.h b/pcbnew/pcb_io/pcb_io_mgr.h index a4b8ea3ed4..7dbe468ad9 100644 --- a/pcbnew/pcb_io/pcb_io_mgr.h +++ b/pcbnew/pcb_io/pcb_io_mgr.h @@ -228,6 +228,12 @@ public: */ static void Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard, const STRING_UTF8_MAP* aProperties = nullptr ); + + /** + * Convert a schematic symbol library to the latest KiCad format + */ + static bool ConvertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath, + const wxString& aNewFilePath ); }; #endif // PCB_IO_MGR_H_ diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index e976bee249..ba3992939e 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -753,8 +753,7 @@ int PCBNEW_JOBS_HANDLER::JobExportFpUpgrade( JOB* aJob ) if( upgradeJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO ); + PCB_IO_MGR::PCB_FILE_T fileType = PCB_IO_MGR::GuessPluginTypeFromLibPath( upgradeJob->m_libraryPath ); if( !upgradeJob->m_outputLibraryPath.IsEmpty() ) { @@ -766,52 +765,82 @@ int PCBNEW_JOBS_HANDLER::JobExportFpUpgrade( JOB* aJob ) return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; } } - - PCB_IO_KICAD_SEXPR pcb_io( CTL_FOR_LIBRARY ); - FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath ); - - try + else if( fileType != PCB_IO_MGR::KICAD_SEXP ) { - fpLib.Load(); - } - catch(...) - { - m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR ); - return CLI::EXIT_CODES::ERR_UNKNOWN; + 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; } - bool shouldSave = upgradeJob->m_force; - - for( const auto& footprint : fpLib.GetFootprints() ) + if( fileType == PCB_IO_MGR::KICAD_SEXP ) { - if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad() < SEXPR_BOARD_FILE_VERSION ) + if( !wxDir::Exists( upgradeJob->m_libraryPath ) ) { - shouldSave = true; + m_reporter->Report( _( "Footprint library path does not exist or is not accessible\n" ), + RPT_SEVERITY_INFO ); + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; } - } - if( shouldSave ) - { - m_reporter->Report( _( "Saving footprint library\n" ), RPT_SEVERITY_INFO ); + + if( aJob->IsCli() ) + m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO ); + + PCB_IO_KICAD_SEXPR pcb_io( CTL_FOR_LIBRARY ); + FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath ); try { - if( !upgradeJob->m_outputLibraryPath.IsEmpty() ) - { - fpLib.SetPath( upgradeJob->m_outputLibraryPath ); - } - - fpLib.Save(); + fpLib.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; + + for( const auto& footprint : fpLib.GetFootprints() ) + { + if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad() + < SEXPR_BOARD_FILE_VERSION ) + { + shouldSave = true; + } + } + + if( shouldSave ) + { + m_reporter->Report( _( "Saving footprint library\n" ), RPT_SEVERITY_INFO ); + + try + { + if( !upgradeJob->m_outputLibraryPath.IsEmpty() ) + { + fpLib.SetPath( upgradeJob->m_outputLibraryPath ); + } + + fpLib.Save(); + } + catch( ... ) + { + m_reporter->Report( _( "Unable to save library\n" ), RPT_SEVERITY_ERROR ); + return CLI::EXIT_CODES::ERR_UNKNOWN; + } + } + else + { + m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO ); + } } else { - m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO ); + if( !PCB_IO_MGR::ConvertLibrary( nullptr, upgradeJob->m_libraryPath, 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;