37#include <wx/stdstream.h>
38#include <wx/zipstrm.h>
40#include <nlohmann/json.hpp>
42#include <wx/wfstream.h>
49 if( aName.Lower().EndsWith( wxS(
".json" ) ) )
51 wxStdInputStream sin( aStream );
52 nlohmann::json js = nlohmann::json::parse( sin,
nullptr,
false );
54 if( js.is_discarded() )
74 else if( aName.Lower().EndsWith( wxS(
".zip" ) ) )
76 std::shared_ptr<wxZipEntry> entry;
77 wxZipInputStream
zip( aStream );
82 while( entry.reset(
zip.GetNextEntry() ), entry.get() != NULL )
84 wxString
name = entry->GetName();
102 wxFFileInputStream in( aFileName );
109 catch( nlohmann::json::exception& )
112 catch( std::exception& )
136 std::map<wxString, int> namesCounter;
140 wxFFileInputStream in( aLibraryPath );
147 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
171 for( wxString shap : dataStrDoc.
shape )
173 if( !shap.Contains( wxS(
"LIB" ) ) )
176 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
177 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
179 if( parts.size() < 1 )
182 wxArrayString paramsRoot = wxSplit( parts[0],
'~',
'\0' );
184 if( paramsRoot.size() < 1 )
187 wxString rootType = paramsRoot[0];
189 if( rootType == wxS(
"LIB" ) )
191 if( paramsRoot.size() < 4 )
195 parser.
Convert( paramsRoot[2] ) );
197 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ),
198 paramsRoot[1], paramsRoot[2] );
200 wxArrayString paramParts = wxSplit( paramsRoot[3],
'`',
'\0' );
202 std::map<wxString, wxString> paramMap;
204 for(
size_t i = 1; i < paramParts.size(); i += 2 )
206 wxString key = paramParts[i - 1];
207 wxString value = paramParts[i];
209 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
212 paramMap[key] = value;
215 int& serial = namesCounter[symbolName];
218 symbolName << wxS(
"_" ) << serial;
222 paramMap[wxS(
"spiceSymbolName" )] = symbolName;
224 if( symbolName == aAliasName )
228 return parser.
ParseSymbol( origin, paramMap, parts );
238 wxString symbolName = wxS(
"Unknown" );
240 std::optional<std::map<wxString, wxString>> c_para;
250 symbolName =
get_def( *c_para, wxS(
"name" ), symbolName );
252 int& serial = namesCounter[symbolName];
255 symbolName << wxS(
"_" ) << serial;
259 if( symbolName != aAliasName )
267 catch( nlohmann::json::exception& e )
269 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
270 aAliasName, aLibraryPath, e.what() ) );
272 catch( std::exception& e )
274 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
275 aAliasName, aLibraryPath, e.what() ) );
283 const wxString& aLibraryPath,
286 std::map<wxString, int> namesCounter;
290 wxFFileInputStream in( aLibraryPath );
297 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
321 for( wxString shap : dataStrDoc.
shape )
323 if( !shap.Contains( wxS(
"LIB" ) ) )
326 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
327 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
329 if( parts.size() < 1 )
332 wxArrayString paramsRoot = wxSplit( parts[0],
'~',
'\0' );
334 if( paramsRoot.size() < 1 )
337 wxString rootType = paramsRoot[0];
339 if( rootType == wxS(
"LIB" ) )
341 if( paramsRoot.size() < 4 )
344 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ),
345 paramsRoot[1], paramsRoot[2] );
347 wxArrayString paramParts = wxSplit( paramsRoot[3],
'`',
'\0' );
349 std::map<wxString, wxString> paramMap;
351 for(
size_t i = 1; i < paramParts.size(); i += 2 )
353 wxString key = paramParts[i - 1];
354 wxString value = paramParts[i];
356 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
359 paramMap[key] = value;
362 int& serial = namesCounter[symbolName];
365 symbolName << wxS(
"_" ) << serial;
369 aSymbolNameList.Add( symbolName );
378 wxString packageName = wxS(
"Unknown" );
382 packageName =
get_def( *symDoc.
c_para, wxS(
"name" ), packageName );
389 aSymbolNameList.Add( packageName );
392 catch( nlohmann::json::exception& e )
394 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
395 aLibraryPath, e.what() ) );
397 catch( std::exception& e )
399 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
400 aLibraryPath, e.what() ) );
406 const wxString& aLibraryPath,
409 wxFFileInputStream in( aLibraryPath );
416 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
422 wxArrayString symbolNameList;
426 for(
const wxString& symbolName : symbolNameList )
431 aSymbolList.push_back( sym );
434 catch( nlohmann::json::exception& e )
436 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
437 aLibraryPath, e.what() ) );
439 catch( std::exception& e )
441 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
442 aLibraryPath, e.what() ) );
448 const wxString& aAliasName,
453 wxFFileInputStream in( aLibraryPath );
460 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
464 return loadSymbol( aLibraryPath, js, aAliasName, aProperties );
466 catch( nlohmann::json::exception& e )
468 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
469 aAliasName, aLibraryPath, e.what() ) );
471 catch( std::exception& e )
473 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
474 aAliasName, aLibraryPath, e.what() ) );
487 wxFFileInputStream in( aFileName );
494 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
521 wxString sheetTitle =
522 !subDoc.
title.empty() ? subDoc.
title : ( wxString() << pageNum );
526 wxFileName sheetFname( aFileName );
527 sheetFname.SetFullName(
528 sheetBaseName + wxS(
"." )
531 wxFileName relSheetPath( sheetFname );
532 relSheetPath.MakeRelativeTo(
533 wxFileName( aRootSheet->
GetFileName() ).GetPath() );
535 std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
536 subSheet->SetFileName( relSheetPath.GetFullPath() );
537 subSheet->SetName( sheetTitle );
542 subSheet->SetScreen( screen );
550 subSheet->SetPosition( pos );
572 catch( nlohmann::json::exception& e )
575 wxString::Format(
_(
"Error loading schematic '%s': %s" ), aFileName, e.what() ) );
577 catch( std::exception& e )
580 wxString::Format(
_(
"Error loading schematic '%s': %s" ), aFileName, e.what() ) );
589 wxCHECK( !aFileName.IsEmpty() && aSchematic,
nullptr );
595 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
596 wxS(
"Can't append to a schematic with no root!" ) );
598 rootSheet = &aSchematic->
Root();
604 aSchematic->
SetRoot( rootSheet );
617 wxCHECK_MSG( libTable,
nullptr, wxS(
"Could not load symbol lib table." ) );
constexpr EDA_IU_SCALE schIUScale
void SetPageNumber(const wxString &aPageNumber)
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 SetCurrentSheet(const SCH_SHEET_PATH &aPath) 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)
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...
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
int GetModifyHash() const override
Return the modification hash from the library cache.
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.
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_IO implementation knows about,...
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
wxString GetFileName() const
Return the filename corresponding to this sheet.
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.
static const std::string KiCadSchematicFileExtension
#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)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
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
constexpr int MilsToIU(int mils) const
Definition of file extensions used in Kicad.