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 70fe2a8f1e
commit a4a99e3aff
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_outputLibraryPath = m_argOutput;
fpJob->m_force = m_argParser.get<bool>( ARG_FORCE ); 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() ); int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, fpJob.get() );
return exitCode; 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 ); wxString options = m_cur_grid->GetCellValue( row, COL_OPTIONS );
std::unique_ptr<STRING_UTF8_MAP> props( LIB_TABLE::ParseOptions( options.ToStdString() ) ); 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(), relPath = NormalizePath( newLib.GetFullPath(), &Pgm().GetLocalEnvVariables(),
m_project ); 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 ) void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
{ {
if( !m_cur_grid->CommitPendingChanges() ) if( !m_cur_grid->CommitPendingChanges() )

View File

@ -68,9 +68,6 @@ private:
void populateEnvironReadOnlyTable(); void populateEnvironReadOnlyTable();
void populatePluginList(); void populatePluginList();
bool convertLibrary( STRING_UTF8_MAP* aOldFileProps, const wxString& aOldFilePath,
const wxString& aNewFilePath );
FP_LIB_TABLE_GRID* global_model() const FP_LIB_TABLE_GRID* global_model() const
{ {
return (FP_LIB_TABLE_GRID*) m_global_grid->GetTable(); 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() ) ); 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, // 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. // you will obsolete library tables, so don't do it. Additions are OK.

View File

@ -228,6 +228,12 @@ public:
*/ */
static void Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard, static void Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard,
const STRING_UTF8_MAP* aProperties = nullptr ); 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_ #endif // PCB_IO_MGR_H_

View File

@ -753,8 +753,7 @@ int PCBNEW_JOBS_HANDLER::JobExportFpUpgrade( JOB* aJob )
if( upgradeJob == nullptr ) if( upgradeJob == nullptr )
return CLI::EXIT_CODES::ERR_UNKNOWN; return CLI::EXIT_CODES::ERR_UNKNOWN;
if( aJob->IsCli() ) PCB_IO_MGR::PCB_FILE_T fileType = PCB_IO_MGR::GuessPluginTypeFromLibPath( upgradeJob->m_libraryPath );
m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
if( !upgradeJob->m_outputLibraryPath.IsEmpty() ) if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
{ {
@ -766,6 +765,26 @@ int PCBNEW_JOBS_HANDLER::JobExportFpUpgrade( JOB* aJob )
return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT;
} }
} }
else if( fileType != PCB_IO_MGR::KICAD_SEXP )
{
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 == PCB_IO_MGR::KICAD_SEXP )
{
if( !wxDir::Exists( upgradeJob->m_libraryPath ) )
{
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( aJob->IsCli() )
m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
PCB_IO_KICAD_SEXPR pcb_io( CTL_FOR_LIBRARY ); PCB_IO_KICAD_SEXPR pcb_io( CTL_FOR_LIBRARY );
FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath ); FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath );
@ -774,7 +793,7 @@ int PCBNEW_JOBS_HANDLER::JobExportFpUpgrade( JOB* aJob )
{ {
fpLib.Load(); fpLib.Load();
} }
catch(...) catch( ... )
{ {
m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR ); m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
return CLI::EXIT_CODES::ERR_UNKNOWN; return CLI::EXIT_CODES::ERR_UNKNOWN;
@ -784,7 +803,8 @@ int PCBNEW_JOBS_HANDLER::JobExportFpUpgrade( JOB* aJob )
for( const auto& footprint : fpLib.GetFootprints() ) for( const auto& footprint : fpLib.GetFootprints() )
{ {
if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad() < SEXPR_BOARD_FILE_VERSION ) if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad()
< SEXPR_BOARD_FILE_VERSION )
{ {
shouldSave = true; shouldSave = true;
} }
@ -813,6 +833,15 @@ int PCBNEW_JOBS_HANDLER::JobExportFpUpgrade( JOB* aJob )
{ {
m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO ); m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO );
} }
}
else
{
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; return CLI::EXIT_CODES::OK;
} }