38#include <wx/stdstream.h>
39#include <wx/zipstrm.h>
43#include <wx/wfstream.h>
50 if( aName.Lower().EndsWith( wxS(
".json" ) ) )
52 wxStdInputStream sin( aStream );
53 nlohmann::json js = nlohmann::json::parse( sin,
nullptr,
false );
55 if( js.is_discarded() )
75 else if( aName.Lower().EndsWith( wxS(
".zip" ) ) )
77 std::shared_ptr<wxZipEntry> entry;
78 wxZipInputStream
zip( aStream );
83 while( entry.reset(
zip.GetNextEntry() ), entry.get() != NULL )
85 wxString
name = entry->GetName();
103 wxFFileInputStream in( aFileName );
110 catch( nlohmann::json::exception& )
113 catch( std::exception& )
134 const wxString& aAliasName,
const std::map<std::string, UTF8>* aProperties )
137 std::map<wxString, int> namesCounter;
141 wxFFileInputStream in( aLibraryPath );
148 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
172 for( wxString shap : dataStrDoc.
shape )
174 if( !shap.Contains( wxS(
"LIB" ) ) )
177 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
178 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
180 if( parts.size() < 1 )
183 wxArrayString paramsRoot = wxSplit( parts[0],
'~',
'\0' );
185 if( paramsRoot.size() < 1 )
188 wxString rootType = paramsRoot[0];
190 if( rootType == wxS(
"LIB" ) )
192 if( paramsRoot.size() < 4 )
196 parser.
Convert( paramsRoot[2] ) );
198 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ),
199 paramsRoot[1], paramsRoot[2] );
201 wxArrayString paramParts = wxSplit( paramsRoot[3],
'`',
'\0' );
203 std::map<wxString, wxString> paramMap;
205 for(
size_t i = 1; i < paramParts.size(); i += 2 )
207 wxString key = paramParts[i - 1];
208 wxString value = paramParts[i];
210 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
213 paramMap[key] = value;
216 int& serial = namesCounter[symbolName];
219 symbolName << wxS(
"_" ) << serial;
223 paramMap[wxS(
"spiceSymbolName" )] = symbolName;
225 if( symbolName == aAliasName )
233 wxString origRef = refField.
GetText();
236 for(
size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
237 reference << origRef[i];
251 wxString symbolName = wxS(
"Unknown" );
253 std::optional<std::map<wxString, wxString>> c_para;
263 symbolName =
get_def( *c_para, wxS(
"name" ), symbolName );
265 int& serial = namesCounter[symbolName];
268 symbolName << wxS(
"_" ) << serial;
272 if( symbolName != aAliasName )
281 wxString origRef = refField.
GetText();
284 for(
size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
285 reference << origRef[i];
292 catch( nlohmann::json::exception& e )
294 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
295 aAliasName, aLibraryPath, e.what() ) );
297 catch( std::exception& e )
299 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
300 aAliasName, aLibraryPath, e.what() ) );
308 const wxString& aLibraryPath,
309 const std::map<std::string, UTF8>* aProperties )
311 std::map<wxString, int> namesCounter;
318 wxFFileInputStream in( aLibraryPath );
325 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
349 for( wxString shap : dataStrDoc.
shape )
351 if( !shap.Contains( wxS(
"LIB" ) ) )
354 shap.Replace( wxS(
"#@$" ), wxS(
"\n" ) );
355 wxArrayString parts = wxSplit( shap,
'\n',
'\0' );
357 if( parts.size() < 1 )
360 wxArrayString paramsRoot = wxSplit( parts[0],
'~',
'\0' );
362 if( paramsRoot.size() < 1 )
365 wxString rootType = paramsRoot[0];
367 if( rootType == wxS(
"LIB" ) )
369 if( paramsRoot.size() < 4 )
372 wxString symbolName = wxString::Format( wxS(
"Unknown_%s_%s" ),
373 paramsRoot[1], paramsRoot[2] );
375 wxArrayString paramParts = wxSplit( paramsRoot[3],
'`',
'\0' );
377 std::map<wxString, wxString> paramMap;
379 for(
size_t i = 1; i < paramParts.size(); i += 2 )
381 wxString key = paramParts[i - 1];
382 wxString value = paramParts[i];
384 if( key == wxS(
"spiceSymbolName" ) && !value.IsEmpty() )
387 paramMap[key] = value;
390 int& serial = namesCounter[symbolName];
393 symbolName << wxS(
"_" ) << serial;
397 aSymbolNameList.Add( symbolName );
406 wxString packageName = wxS(
"Unknown" );
410 packageName =
get_def( *symDoc.
c_para, wxS(
"name" ), packageName );
417 aSymbolNameList.Add( packageName );
420 catch( nlohmann::json::exception& e )
422 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
423 aLibraryPath, e.what() ) );
425 catch( std::exception& e )
427 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
428 aLibraryPath, e.what() ) );
434 const wxString& aLibraryPath,
435 const std::map<std::string, UTF8>* aProperties )
437 wxFFileInputStream in( aLibraryPath );
444 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
450 wxArrayString symbolNameList;
454 for(
const wxString& symbolName : symbolNameList )
459 aSymbolList.push_back( sym );
462 catch( nlohmann::json::exception& e )
464 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
465 aLibraryPath, e.what() ) );
467 catch( std::exception& e )
469 THROW_IO_ERROR( wxString::Format(
_(
"Error enumerating symbol library '%s': %s" ),
470 aLibraryPath, e.what() ) );
476 const wxString& aAliasName,
477 const std::map<std::string, UTF8>* aProperties )
481 wxFFileInputStream in( aLibraryPath );
488 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
492 return loadSymbol( aLibraryPath, js, aAliasName, aProperties );
494 catch( nlohmann::json::exception& e )
496 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
497 aAliasName, aLibraryPath, e.what() ) );
499 catch( std::exception& e )
501 THROW_IO_ERROR( wxString::Format(
_(
"Error loading symbol '%s' from library '%s': %s" ),
502 aAliasName, aLibraryPath, e.what() ) );
515 wxFFileInputStream in( aFileName );
522 THROW_IO_ERROR( wxString::Format(
_(
"Unable to find a valid schematic file in '%s'" ),
549 wxString sheetTitle =
550 !subDoc.
title.empty() ? subDoc.
title : ( wxString() << pageNum );
554 wxFileName sheetFname( aFileName );
555 sheetFname.SetFullName(
556 sheetBaseName + wxS(
"." )
559 wxFileName relSheetPath( sheetFname );
560 relSheetPath.MakeRelativeTo(
561 wxFileName( aRootSheet->
GetFileName() ).GetPath() );
563 std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
564 subSheet->SetFileName( relSheetPath.GetFullPath() );
565 subSheet->SetName( sheetTitle );
570 subSheet->SetScreen( screen );
575 + ( subSheet->GetSize().y +
schIUScale.MilsToIU( 200 ) )
578 subSheet->SetPosition( pos );
600 catch( nlohmann::json::exception& e )
603 wxString::Format(
_(
"Error loading schematic '%s': %s" ), aFileName, e.what() ) );
605 catch( std::exception& e )
608 wxString::Format(
_(
"Error loading schematic '%s': %s" ), aFileName, e.what() ) );
615 const std::map<std::string, UTF8>* aProperties )
617 wxCHECK( !aFileName.IsEmpty() && aSchematic,
nullptr );
626 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
627 wxS(
"Can't append to a schematic with no root!" ) );
629 rootSheet = aAppendToMe;
constexpr EDA_IU_SCALE schIUScale
void SetPageNumber(const wxString &aPageNumber)
static double Convert(const wxString &aValue)
RAII class to set and restore the fontconfig reporter.
Define a library symbol object.
SCH_FIELD & GetReferenceField()
Return reference to the reference designator field.
static LOAD_INFO_REPORTER & GetInstance()
Holds all the data relating to one schematic.
void SetCurrentSheet(const SCH_SHEET_PATH &aPath)
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
SCH_SHEET_PATH & CurrentSheet() const
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)
virtual const wxString & GetText() const override
Return the string associated with the text object.
void SetText(const wxString &aText) override
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
int GetModifyHash() const override
Return the modification hash from the library cache.
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const std::map< std::string, UTF8 > *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_IO can read the specified schematic file.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
const KIID & GetUuid() const
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.
static const std::string KiCadSchematicFileExtension
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
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)
LIB_SYMBOL * loadSymbol(const wxString &aLibraryPath, nlohmann::json aFileData, const wxString &aAliasName, const std::map< std::string, UTF8 > *aProperties)
static bool FindSchFileInStream(const wxString &aName, wxInputStream &aStream, nlohmann::json &aOut, EASYEDA::DOCUMENT &aDoc, EASYEDA::DOC_TYPE &aDocType)
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
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
Definition of file extensions used in Kicad.