kicad_cli: Allow upgrade of legacy and non-kicad footprint libraries

This commit is contained in:
Roberto Fernandez Bautista 2024-02-13 22:19:24 +01:00
parent f7ddd211d9
commit 091f9c82e1
6 changed files with 105 additions and 79 deletions

View File

@ -50,12 +50,6 @@ int CLI::FP_UPGRADE_COMMAND::doPerform( KIWAY& aKiway )
fpJob->m_outputLibraryPath = m_argOutput;
fpJob->m_force = m_argParser.get<bool>( 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;

View File

@ -866,7 +866,7 @@ void PANEL_FP_LIB_TABLE::onMigrateLibraries( wxCommandEvent& event )
wxString options = m_cur_grid->GetCellValue( row, COL_OPTIONS );
std::unique_ptr<STRING_UTF8_MAP> 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<PCB_IO> oldFilePI( PCB_IO_MGR::PluginFind( oldFileType ) );
IO_RELEASER<PCB_IO> 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<const FOOTPRINT> 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() )

View File

@ -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();

View File

@ -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<PCB_IO> oldFilePI( PCB_IO_MGR::PluginFind( oldFileType ) );
IO_RELEASER<PCB_IO> 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<const FOOTPRINT> 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.

View File

@ -227,6 +227,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_

View File

@ -767,8 +767,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() )
{
@ -780,52 +779,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;