WIP: CADSTAR Parts now shows up in library tables and is handled correctly (todo: read cadstar header)

This commit is contained in:
Roberto Fernandez Bautista 2023-02-26 23:37:05 +01:00
parent 2da13a9e07
commit e8ead30baf
9 changed files with 163 additions and 60 deletions

View File

@ -137,6 +137,7 @@ const std::string ProjectLocalSettingsFileExtension( "kicad_prl" );
const std::string LegacySchematicFileExtension( "sch" );
const std::string EagleSchematicFileExtension( "sch" );
const std::string CadstarSchematicFileExtension( "csa" );
const std::string CadstarPartsLibraryFileExtension( "lib" );
const std::string KiCadSchematicFileExtension( "kicad_sch" );
const std::string SpiceFileExtension( "cir" );
const std::string CadstarNetlistFileExtension( "frp" );

View File

@ -114,16 +114,8 @@ public:
// If setting a filepath, attempt to auto-detect the format
if( aCol == COL_URI )
{
wxFileName fn( aValue );
for( SCH_IO_MGR::SCH_FILE_T piType : SCH_IO_MGR::SCH_FILE_T_vector )
{
if( SCH_IO_MGR::GetLibraryFileExtension( piType ).Lower() == fn.GetExt().Lower() )
{
SetValue( aRow, COL_TYPE, SCH_IO_MGR::ShowType( piType ) );
break;
}
}
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( aValue );
SetValue( aRow, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) );
}
}
@ -216,6 +208,7 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, P
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD ) );
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_DATABASE ) );
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_CADSTAR_ARCHIVE ) );
EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
@ -549,14 +542,8 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
m_cur_grid->SetCellValue( last_row, COL_NICKNAME, nickname );
// attempt to auto-detect the plugin type
for( SCH_IO_MGR::SCH_FILE_T piType : SCH_IO_MGR::SCH_FILE_T_vector )
{
if( SCH_IO_MGR::GetLibraryFileExtension( piType ).Lower() == fn.GetExt().Lower() )
{
m_cur_grid->SetCellValue( last_row, COL_TYPE, SCH_IO_MGR::ShowType( piType ) );
break;
}
}
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromLibPath( filePath );
m_cur_grid->SetCellValue( last_row, COL_TYPE, SCH_IO_MGR::ShowType( pluginType ) );
// try to use path normalized to an environmental variable or project path
wxString path = NormalizePath( filePath, &envVars, m_project->GetProjectPath() );

View File

@ -156,15 +156,37 @@ const wxString SCH_IO_MGR::GetLibraryFileExtension( SCH_FILE_T aFileType )
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
{
SCH_FILE_T ret = SCH_KICAD; // default guess, unless detected otherwise.
wxFileName fn( aLibPath );
wxFileName fn( aLibPath );
wxString ext = fn.GetExt().Lower();
if( fn.GetExt() == LegacySymbolLibFileExtension )
// .lib is shared between CADSTAR and Legacy KiCad file formats. Let's read the header
if( ext == LegacySymbolLibFileExtension )
{
ret = SCH_LEGACY;
for( SCH_FILE_T pluginType : { SCH_LEGACY, SCH_CADSTAR_ARCHIVE } )
{
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( pluginType ) );
if( pi )
{
if( pi->CheckHeader( aLibPath ) )
return pluginType;
}
}
}
else if( fn.GetExt() == KiCadSymbolLibFileExtension )
for( SCH_IO_MGR::SCH_FILE_T piType : SCH_IO_MGR::SCH_FILE_T_vector )
{
ret = SCH_KICAD;
if( ext == LegacySymbolLibFileExtension )
{
break;
}
else if( SCH_IO_MGR::GetLibraryFileExtension( piType ).Lower() == fn.GetExt().Lower() )
{
ret = piType;
break;
}
}
return ret;

View File

@ -55,35 +55,14 @@ const wxString PartNameFieldName = "Part Name";
void CADSTAR_SCH_ARCHIVE_LOADER::Load( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet )
{
wxCHECK( aSchematic );
wxCHECK( aSchematic, /* void */ );
if( m_progressReporter )
m_progressReporter->SetNumPhases( 3 ); // (0) Read file, (1) Parse file, (2) Load file
Parse();
LONGPOINT designLimit = Assignments.Settings.DesignLimit;
//Note: can't use getKiCadPoint() due VECTOR2I being int - need long long to make the check
long long designSizeXkicad = (long long) designLimit.x / KiCadUnitDivider;
long long designSizeYkicad = (long long) designLimit.y / KiCadUnitDivider;
// Max size limited by the positive dimension of VECTOR2I (which is an int)
constexpr long long maxDesignSizekicad = std::numeric_limits<int>::max();
if( designSizeXkicad > maxDesignSizekicad || designSizeYkicad > maxDesignSizekicad )
{
THROW_IO_ERROR( wxString::Format(
_( "The design is too large and cannot be imported into KiCad. \n"
"Please reduce the maximum design size in CADSTAR by navigating to: \n"
"Design Tab -> Properties -> Design Options -> Maximum Design Size. \n"
"Current Design size: %.2f, %.2f millimeters. \n"
"Maximum permitted design size: %.2f, %.2f millimeters.\n" ),
(double) designSizeXkicad / SCH_IU_PER_MM,
(double) designSizeYkicad / SCH_IU_PER_MM,
(double) maxDesignSizekicad / SCH_IU_PER_MM,
(double) maxDesignSizekicad / SCH_IU_PER_MM ) );
}
checkDesignLimits(); // Throws if error found
// Assume the center at 0,0 since we are going to be translating the design afterwards anyway
m_designCenter = { 0, 0 };
@ -266,6 +245,33 @@ void CADSTAR_SCH_ARCHIVE_LOADER::Load( SCHEMATIC* aSchematic, SCH_SHEET* aRootSh
}
void CADSTAR_SCH_ARCHIVE_LOADER::checkDesignLimits()
{
LONGPOINT designLimit = Assignments.Settings.DesignLimit;
//Note: can't use getKiCadPoint() due VECTOR2I being int - need long long to make the check
long long designSizeXkicad = (long long) designLimit.x / KiCadUnitDivider;
long long designSizeYkicad = (long long) designLimit.y / KiCadUnitDivider;
// Max size limited by the positive dimension of VECTOR2I (which is an int)
constexpr long long maxDesignSizekicad = std::numeric_limits<int>::max();
if( designSizeXkicad > maxDesignSizekicad || designSizeYkicad > maxDesignSizekicad )
{
THROW_IO_ERROR( wxString::Format(
_( "The design is too large and cannot be imported into KiCad. \n"
"Please reduce the maximum design size in CADSTAR by navigating to: \n"
"Design Tab -> Properties -> Design Options -> Maximum Design Size. \n"
"Current Design size: %.2f, %.2f millimeters. \n"
"Maximum permitted design size: %.2f, %.2f millimeters.\n" ),
(double) designSizeXkicad / SCH_IU_PER_MM,
(double) designSizeYkicad / SCH_IU_PER_MM,
(double) maxDesignSizekicad / SCH_IU_PER_MM,
(double) maxDesignSizekicad / SCH_IU_PER_MM ) );
}
}
void CADSTAR_SCH_ARCHIVE_LOADER::loadSheets()
{
const std::vector<LAYER_ID>& orphanSheets = findOrphanSheets();

View File

@ -232,6 +232,8 @@ private:
const VECTOR2I& aTransformCentre = { 0, 0 },
const bool& aMirrorInvert = false );
void checkDesignLimits();
int getKiCadLength( long long aCadstarLength )
{
int mod = aCadstarLength % KiCadUnitDivider;

View File

@ -27,6 +27,8 @@
#include <sch_plugins/cadstar/cadstar_sch_archive_loader.h>
#include <sch_plugins/cadstar/cadstar_sch_archive_plugin.h>
#include <lib_symbol.h>
#include <progress_reporter.h>
#include <string_utf8_map.h>
#include <sch_screen.h>
#include <sch_sheet.h>
@ -43,13 +45,13 @@ const wxString CADSTAR_SCH_ARCHIVE_PLUGIN::GetName() const
const wxString CADSTAR_SCH_ARCHIVE_PLUGIN::GetFileExtension() const
{
return wxT( "csa" );
return CadstarSchematicFileExtension;
}
const wxString CADSTAR_SCH_ARCHIVE_PLUGIN::GetLibraryFileExtension() const
{
return wxT( "lib" );
return CadstarPartsLibraryFileExtension;
}
@ -177,3 +179,63 @@ bool CADSTAR_SCH_ARCHIVE_PLUGIN::CheckHeader( const wxString& aFileName )
// and throw exceptions when parsing
return true;
}
void CADSTAR_SCH_ARCHIVE_PLUGIN::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties )
{
std::vector<LIB_SYMBOL*> symbols;
EnumerateSymbolLib( symbols, aLibraryPath, aProperties );
for( LIB_SYMBOL*& sym : symbols )
aSymbolNameList.Add( sym->GetName() );
}
void CADSTAR_SCH_ARCHIVE_PLUGIN::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties )
{
wxFileName fn( aLibraryPath );
fn.SetExt( "csa" );
fn.SetName( "symbol" );
CADSTAR_SCH_ARCHIVE_LOADER csaLoader( fn.GetFullPath(), m_reporter, m_progressReporter );
if( m_progressReporter )
m_progressReporter->SetNumPhases( 2 ); // (0) Read file, (1) Parse file
csaLoader.Parse();
printf( "symbols: %zd", csaLoader.Library.SymbolDefinitions.size() );
}
LIB_SYMBOL* CADSTAR_SCH_ARCHIVE_PLUGIN::LoadSymbol( const wxString& aLibraryPath,
const wxString& aAliasName,
const STRING_UTF8_MAP* aProperties )
{
return nullptr;
}
void CADSTAR_SCH_ARCHIVE_PLUGIN::GetAvailableSymbolFields( std::vector<wxString>& aNames )
{
std::set<wxString> fieldNames;
for( auto& [libnameStr, libSymbol] : m_libCache )
{
std::vector<LIB_FIELD*> fields;
libSymbol->GetFields( fields );
for( LIB_FIELD* field : fields )
{
if( field->IsMandatory() )
continue;
fieldNames.insert( field->GetName() );
}
}
std::copy( fieldNames.begin(), fieldNames.end(), std::back_inserter( aNames ) );
}

View File

@ -27,17 +27,26 @@
#ifndef CADSTAR_SCH_ARCHIVE_PLUGIN_H_
#define CADSTAR_SCH_ARCHIVE_PLUGIN_H_
#include <map>
#include <sch_io_mgr.h>
#include <reporter.h>
class LIB_SYMBOL;
class SCH_SHEET;
class SCH_SCREEN;
class CADSTAR_SCH_ARCHIVE_PLUGIN : public SCH_PLUGIN
{
public:
CADSTAR_SCH_ARCHIVE_PLUGIN()
{
m_reporter = &WXLOG_REPORTER::GetInstance();
m_progressReporter = nullptr;
}
virtual ~CADSTAR_SCH_ARCHIVE_PLUGIN() {}
const wxString GetName() const override;
void SetReporter( REPORTER* aReporter ) override { m_reporter = aReporter; }
@ -59,17 +68,29 @@ public:
bool CheckHeader( const wxString& aFileName ) override;
CADSTAR_SCH_ARCHIVE_PLUGIN()
void EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
void EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
LIB_SYMBOL* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
void GetAvailableSymbolFields( std::vector<wxString>& aNames ) override;
// Writing to CADSTAR libraries is not supported
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override
{
m_reporter = &WXLOG_REPORTER::GetInstance();
m_progressReporter = nullptr;
return false;
}
~CADSTAR_SCH_ARCHIVE_PLUGIN()
{
}
private:
std::map<wxString, LIB_SYMBOL*> m_libCache;
REPORTER* m_reporter; // current reporter for warnings/errors
PROGRESS_REPORTER* m_progressReporter; // optional; may be nullptr
};

View File

@ -144,17 +144,18 @@ bool SYMBOL_EDIT_FRAME::LoadSymbol( const LIB_ID& aLibId, int aUnit, int aConver
{
LIB_ID libId = aLibId;
// Database library symbols can't be edited, so load the underlying chosen symbol
// Some libraries can't be edited, so load the underlying chosen symbol
if( SYMBOL_LIB_TABLE_ROW* lib = m_libMgr->GetLibrary( aLibId.GetLibNickname() ) )
{
if( lib->SchLibType() == SCH_IO_MGR::SCH_DATABASE )
if( lib->SchLibType() == SCH_IO_MGR::SCH_DATABASE
|| lib->SchLibType() == SCH_IO_MGR::SCH_CADSTAR_ARCHIVE )
{
try
{
LIB_SYMBOL* dbSym = Prj().SchSymbolLibTable()->LoadSymbol( aLibId );
LIB_SYMBOL* readOnlySym = Prj().SchSymbolLibTable()->LoadSymbol( aLibId );
if( dbSym && dbSym->GetSourceLibId().IsValid() )
libId = dbSym->GetSourceLibId();
if( readOnlySym && readOnlySym->GetSourceLibId().IsValid() )
libId = readOnlySym->GetSourceLibId();
}
catch( const IO_ERROR& ioe )
{

View File

@ -122,6 +122,7 @@ extern const std::string ProjectLocalSettingsFileExtension;
extern const std::string LegacySchematicFileExtension;
extern const std::string EagleSchematicFileExtension;
extern const std::string CadstarSchematicFileExtension;
extern const std::string CadstarPartsLibraryFileExtension;
extern const std::string KiCadSchematicFileExtension;
extern const std::string SpiceFileExtension;
extern const std::string CadstarNetlistFileExtension;