35#include <wx/stdstream.h>
36#include <wx/zipstrm.h>
38#include <nlohmann/json.hpp>
40#include <wx/wfstream.h>
46 return wxT(
"EasyEDA (JLCEDA) Schematic Importer" );
54 if( aName.Lower().EndsWith( wxS(
".json" ) ) )
56 wxStdInputStream sin( aStream );
57 nlohmann::json js = nlohmann::json::parse( sin,
nullptr,
false );
59 if( js.is_discarded() )
79 else if( aName.Lower().EndsWith( wxS(
".zip" ) ) )
81 std::shared_ptr<wxZipEntry> entry;
82 wxZipInputStream
zip( aStream );
87 while( entry.reset(
zip.GetNextEntry() ), entry.get() != NULL )
89 wxString
name = entry->GetName();
107 wxFFileInputStream in( aFileName );
114 catch( nlohmann::json::exception& )
117 catch( std::exception& )
141 std::map<wxString, int> namesCounter;
145 wxFFileInputStream in( aLibraryPath );
152 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
176 for( wxString shap : dataStrDoc.
shape )
178 if( !shap.Contains( wxS(
"LIB" ) ) )
181 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
182 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
184 if( parts.size() < 1 )
187 wxArrayString paramsRoot = wxSplit( parts[0],
'~',
'\0' );
189 if( paramsRoot.size() < 1 )
192 wxString rootType = paramsRoot[0];
194 if( rootType == wxS(
"LIB" ) )
196 if( paramsRoot.size() < 4 )
200 parser.
Convert( paramsRoot[2] ) );
202 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ),
203 paramsRoot[1], paramsRoot[2] );
205 wxArrayString paramParts = wxSplit( paramsRoot[3],
'`',
'\0' );
207 std::map<wxString, wxString> paramMap;
209 for(
size_t i = 1; i < paramParts.size(); i += 2 )
211 wxString key = paramParts[i - 1];
212 wxString value = paramParts[i];
214 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
217 paramMap[key] = value;
220 int& serial = namesCounter[symbolName];
223 symbolName << wxS(
"_" ) << serial;
227 paramMap[wxS(
"spiceSymbolName" )] = symbolName;
229 if( symbolName == aAliasName )
233 return parser.
ParseSymbol( origin, paramMap, parts );
243 wxString symbolName = wxS(
"Unknown" );
245 std::optional<std::map<wxString, wxString>> c_para;
255 symbolName =
get_def( *c_para, wxS(
"name" ), symbolName );
257 int& serial = namesCounter[symbolName];
260 symbolName << wxS(
"_" ) << serial;
264 if( symbolName != aAliasName )
272 catch( nlohmann::json::exception& e )
274 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
275 aAliasName, aLibraryPath, e.what() ) );
277 catch( std::exception& e )
279 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
280 aAliasName, aLibraryPath, e.what() ) );
288 const wxString& aLibraryPath,
291 std::map<wxString, int> namesCounter;
295 wxFFileInputStream in( aLibraryPath );
302 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
326 for( wxString shap : dataStrDoc.
shape )
328 if( !shap.Contains( wxS(
"LIB" ) ) )
331 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
332 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
334 if( parts.size() < 1 )
337 wxArrayString paramsRoot = wxSplit( parts[0],
'~',
'\0' );
339 if( paramsRoot.size() < 1 )
342 wxString rootType = paramsRoot[0];
344 if( rootType == wxS(
"LIB" ) )
346 if( paramsRoot.size() < 4 )
349 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ),
350 paramsRoot[1], paramsRoot[2] );
352 wxArrayString paramParts = wxSplit( paramsRoot[3],
'`',
'\0' );
354 std::map<wxString, wxString> paramMap;
356 for(
size_t i = 1; i < paramParts.size(); i += 2 )
358 wxString key = paramParts[i - 1];
359 wxString value = paramParts[i];
361 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
364 paramMap[key] = value;
367 int& serial = namesCounter[symbolName];
370 symbolName << wxS(
"_" ) << serial;
374 aSymbolNameList.Add( symbolName );
383 wxString packageName = wxS(
"Unknown" );
387 packageName =
get_def( *symDoc.
c_para, wxS(
"name" ), packageName );
394 aSymbolNameList.Add( packageName );
397 catch( nlohmann::json::exception& e )
399 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
400 aLibraryPath, e.what() ) );
402 catch( std::exception& e )
404 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
405 aLibraryPath, e.what() ) );
411 const wxString& aLibraryPath,
414 wxFFileInputStream in( aLibraryPath );
421 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
427 wxArrayString symbolNameList;
431 for(
const wxString& symbolName : symbolNameList )
436 aSymbolList.push_back( sym );
439 catch( nlohmann::json::exception& e )
441 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
442 aLibraryPath, e.what() ) );
444 catch( std::exception& e )
446 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
447 aLibraryPath, e.what() ) );
453 const wxString& aAliasName,
458 wxFFileInputStream in( aLibraryPath );
465 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
469 return loadSymbol( aLibraryPath, js, aAliasName, aProperties );
471 catch( nlohmann::json::exception& e )
473 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
474 aAliasName, aLibraryPath, e.what() ) );
476 catch( std::exception& e )
478 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
479 aAliasName, aLibraryPath, e.what() ) );
492 wxFFileInputStream in( aFileName );
499 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
534 catch( nlohmann::json::exception& e )
537 wxString::Format(
_(
"Error loading schematic '%s': %s" ), aFileName, e.what() ) );
539 catch( std::exception& e )
542 wxString::Format(
_(
"Error loading schematic '%s': %s" ), aFileName, e.what() ) );
551 wxCHECK( !aFileName.IsEmpty() && aSchematic,
nullptr );
557 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
558 wxS(
"Can't append to a schematic with no root!" ) );
560 rootSheet = &aSchematic->
Root();
566 aSchematic->
SetRoot( rootSheet );
579 wxCHECK_MSG( libTable,
nullptr, wxS(
"Could not load symbol lib table." ) );
static double Convert(const wxString &aValue)
Define a library symbol object.
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
Holds all the data relating to one schematic.
SCH_SHEET_PATH & CurrentSheet() const override
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
void ParseSchematic(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const wxString &aFileName, wxArrayString aShapes)
LIB_SYMBOL * ParseSymbol(const VECTOR2D &aOrigin, std::map< wxString, wxString > aParams, wxArrayString aShapes)
const wxString GetName() const override
Return a brief hard coded name for this SCH_PLUGIN.
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this SCH_PLUGIN can read the specified symbol library file.
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const STRING_UTF8_MAP *aProperties=nullptr) override
Load information from some input file format that this SCH_PLUGIN implementation knows about,...
int GetModifyHash() const override
Return the modification hash from the library cache.
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_PLUGIN can read the specified schematic file.
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const STRING_UTF8_MAP *aProperties=nullptr) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_PLUGIN can read the specified schematic file.
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
A name/value tuple with unique names and optional values.
#define THROW_IO_ERROR(msg)
wxString get_def(const std::map< wxString, wxString > &aMap, const char *aKey, const char *aDefval="")
static void LoadSchematic(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const wxString &aFileName)
static bool FindSchFileInStream(const wxString &aName, wxInputStream &aStream, nlohmann::json &aOut, EASYEDA::DOCUMENT &aDoc, EASYEDA::DOC_TYPE &aDocType)
LIB_SYMBOL * loadSymbol(const wxString &aLibraryPath, nlohmann::json aFileData, const wxString &aAliasName, const STRING_UTF8_MAP *aProperties)
std::optional< std::vector< DOCUMENT > > schematics
std::optional< std::map< wxString, wxString > > c_para
std::optional< nlohmann::json > dataStr
std::optional< DOC_TYPE > docType
std::optional< std::map< wxString, wxString > > c_para