KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_io_easyeda.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 Alex Shvartzkop <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include "sch_easyeda_parser.h"
22#include "sch_io_easyeda.h"
23
24#include <font/fontconfig.h>
26#include <project_sch.h>
27#include <sch_screen.h>
28#include <sch_sheet.h>
29#include <schematic.h>
30#include <string_utils.h>
31#include <reporter.h>
33#include <wx/log.h>
34#include <wx/stdstream.h>
35#include <wx/zipstrm.h>
36
37#include <json_common.h>
38#include <core/map_helpers.h>
39#include <wx/wfstream.h>
40
41
42static bool FindSchFileInStream( const wxString& aName, wxInputStream& aStream,
43 nlohmann::json& aOut, EASYEDA::DOCUMENT& aDoc,
44 EASYEDA::DOC_TYPE& aDocType )
45{
46 if( aName.Lower().EndsWith( wxS( ".json" ) ) )
47 {
48 wxStdInputStream sin( aStream );
49 nlohmann::json js = nlohmann::json::parse( sin, nullptr, false );
50
51 if( js.is_discarded() )
52 return false;
53
56
57 if( doc.docType )
58 type = *doc.docType;
59 else
60 type = doc.head.docType;
61
63 || type == EASYEDA::DOC_TYPE::SYMBOL )
64 {
65 aOut = js;
66 aDoc = doc;
67 aDocType = type;
68 return true;
69 }
70 }
71 else if( aName.Lower().EndsWith( wxS( ".zip" ) ) )
72 {
73 std::shared_ptr<wxZipEntry> entry;
74 wxZipInputStream zip( aStream );
75
76 if( !zip.IsOk() )
77 return false;
78
79 while( entry.reset( zip.GetNextEntry() ), entry.get() != NULL )
80 {
81 wxString name = entry->GetName();
82
83 if( FindSchFileInStream( name, zip, aOut, aDoc, aDocType ) )
84 return true;
85 }
86 }
87
88 return false;
89}
90
91
92bool SCH_IO_EASYEDA::CanReadSchematicFile( const wxString& aFileName ) const
93{
94 if( !SCH_IO::CanReadSchematicFile( aFileName ) )
95 return false;
96
97 try
98 {
99 wxFFileInputStream in( aFileName );
100 nlohmann::json js;
102 EASYEDA::DOC_TYPE docType;
103
104 return FindSchFileInStream( aFileName, in, js, doc, docType );
105 }
106 catch( nlohmann::json::exception& )
107 {
108 }
109 catch( std::exception& )
110 {
111 }
112
113 return false;
114}
115
116
117bool SCH_IO_EASYEDA::CanReadLibrary( const wxString& aFileName ) const
118{
119 return CanReadSchematicFile( aFileName );
120}
121
122
124{
125 return 0;
126}
127
128
129LIB_SYMBOL* loadSymbol( const wxString& aLibraryPath, nlohmann::json aFileData,
130 const wxString& aAliasName, const std::map<std::string, UTF8>* aProperties )
131{
132 SCH_EASYEDA_PARSER parser( nullptr, nullptr );
133 std::map<wxString, int> namesCounter;
134
135 try
136 {
137 wxFFileInputStream in( aLibraryPath );
138 nlohmann::json js;
139 EASYEDA::DOCUMENT topDoc;
140 EASYEDA::DOC_TYPE topDocType;
141
142 if( !FindSchFileInStream( aLibraryPath, in, js, topDoc, topDocType ) )
143 {
144 THROW_IO_ERROR( wxString::Format( _( "Unable to find a valid schematic file in '%s'" ),
145 aLibraryPath ) );
146 }
147
148 if( topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_SHEET
149 || topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_LIST )
150 {
152
153 for( const EASYEDA::DOCUMENT& subDoc : *schDoc.schematics )
154 {
155 if( subDoc.docType )
156 {
158 continue;
159 }
160 else
161 {
163 continue;
164 }
165
166 EASYEDA::DOCUMENT dataStrDoc = subDoc.dataStr->get<EASYEDA::DOCUMENT>();
167
168 for( wxString shap : dataStrDoc.shape )
169 {
170 if( !shap.Contains( wxS( "LIB" ) ) )
171 continue;
172
173 shap.Replace( wxS( "#@$" ), wxS( "\n" ) );
174 wxArrayString parts = wxSplit( shap, '\n', '\0' );
175
176 if( parts.size() < 1 )
177 continue;
178
179 wxArrayString paramsRoot = wxSplit( parts[0], '~', '\0' );
180
181 if( paramsRoot.size() < 1 )
182 continue;
183
184 wxString rootType = paramsRoot[0];
185
186 if( rootType == wxS( "LIB" ) )
187 {
188 if( paramsRoot.size() < 4 )
189 continue;
190
191 VECTOR2D origin( parser.Convert( paramsRoot[1] ),
192 parser.Convert( paramsRoot[2] ) );
193
194 wxString symbolName = wxString::Format( wxS( "Unknown_%s_%s" ),
195 paramsRoot[1], paramsRoot[2] );
196
197 wxArrayString paramParts = wxSplit( paramsRoot[3], '`', '\0' );
198
199 std::map<wxString, wxString> paramMap;
200
201 for( size_t i = 1; i < paramParts.size(); i += 2 )
202 {
203 wxString key = paramParts[i - 1];
204 wxString value = paramParts[i];
205
206 if( key == wxS( "spiceSymbolName" ) && !value.IsEmpty() )
207 symbolName = value;
208
209 paramMap[key] = value;
210 }
211
212 int& serial = namesCounter[symbolName];
213
214 if( serial > 0 )
215 symbolName << wxS( "_" ) << serial;
216
217 serial++;
218
219 paramMap[wxS( "spiceSymbolName" )] = symbolName;
220
221 if( symbolName == aAliasName )
222 {
223 parts.RemoveAt( 0 );
224
225 LIB_SYMBOL* ksymbol = parser.ParseSymbol( origin, paramMap, parts );
226
227 // Clear reference numbers
228 SCH_FIELD& refField = ksymbol->GetReferenceField();
229 wxString origRef = refField.GetText();
230 wxString reference;
231
232 for( size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
233 reference << origRef[i];
234
235 refField.SetText( reference );
236
237 return ksymbol;
238 }
239 }
240 }
241 }
242 }
243 else if( topDocType == EASYEDA::DOC_TYPE::SYMBOL )
244 {
246
247 wxString symbolName = wxS( "Unknown" );
248
249 std::optional<std::map<wxString, wxString>> c_para;
250
251 if( symDoc.c_para )
252 c_para = symDoc.c_para;
253 else if( topDoc.head.c_para )
254 c_para = topDoc.head.c_para;
255
256 if( !c_para )
257 return nullptr;
258
259 symbolName = get_def( *c_para, wxS( "name" ), symbolName );
260
261 int& serial = namesCounter[symbolName];
262
263 if( serial > 0 )
264 symbolName << wxS( "_" ) << serial;
265
266 serial++;
267
268 if( symbolName != aAliasName )
269 return nullptr;
270
271 VECTOR2D origin( topDoc.head.x, topDoc.head.y );
272
273 LIB_SYMBOL* ksymbol = parser.ParseSymbol( origin, *c_para, topDoc.shape );
274
275 // Clear reference numbers
276 SCH_FIELD& refField = ksymbol->GetReferenceField();
277 wxString origRef = refField.GetText();
278 wxString reference;
279
280 for( size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
281 reference << origRef[i];
282
283 refField.SetText( reference );
284
285 return ksymbol;
286 }
287 }
288 catch( nlohmann::json::exception& e )
289 {
290 THROW_IO_ERROR( wxString::Format( _( "Error loading symbol '%s' from library '%s': %s" ),
291 aAliasName, aLibraryPath, e.what() ) );
292 }
293 catch( std::exception& e )
294 {
295 THROW_IO_ERROR( wxString::Format( _( "Error loading symbol '%s' from library '%s': %s" ),
296 aAliasName, aLibraryPath, e.what() ) );
297 }
298
299 return nullptr;
300}
301
302
303void SCH_IO_EASYEDA::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
304 const wxString& aLibraryPath,
305 const std::map<std::string, UTF8>* aProperties )
306{
307 std::map<wxString, int> namesCounter;
308
309 // Suppress font substitution warnings (RAII - automatically restored on scope exit)
310 FONTCONFIG_REPORTER_SCOPE fontconfigScope( nullptr );
311
312 try
313 {
314 wxFFileInputStream in( aLibraryPath );
315 nlohmann::json js;
316 EASYEDA::DOCUMENT topDoc;
317 EASYEDA::DOC_TYPE topDocType;
318
319 if( !FindSchFileInStream( aLibraryPath, in, js, topDoc, topDocType ) )
320 {
321 THROW_IO_ERROR( wxString::Format( _( "Unable to find a valid schematic file in '%s'" ),
322 aLibraryPath ) );
323 }
324
325 if( topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_SHEET
326 || topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_LIST )
327 {
329
330 for( const EASYEDA::DOCUMENT& subDoc : *schDoc.schematics )
331 {
332 if( subDoc.docType )
333 {
335 continue;
336 }
337 else
338 {
340 continue;
341 }
342
343 EASYEDA::DOCUMENT dataStrDoc = subDoc.dataStr->get<EASYEDA::DOCUMENT>();
344
345 for( wxString shap : dataStrDoc.shape )
346 {
347 if( !shap.Contains( wxS( "LIB" ) ) )
348 continue;
349
350 shap.Replace( wxS( "#@$" ), wxS( "\n" ) );
351 wxArrayString parts = wxSplit( shap, '\n', '\0' );
352
353 if( parts.size() < 1 )
354 continue;
355
356 wxArrayString paramsRoot = wxSplit( parts[0], '~', '\0' );
357
358 if( paramsRoot.size() < 1 )
359 continue;
360
361 wxString rootType = paramsRoot[0];
362
363 if( rootType == wxS( "LIB" ) )
364 {
365 if( paramsRoot.size() < 4 )
366 continue;
367
368 wxString symbolName = wxString::Format( wxS( "Unknown_%s_%s" ),
369 paramsRoot[1], paramsRoot[2] );
370
371 wxArrayString paramParts = wxSplit( paramsRoot[3], '`', '\0' );
372
373 std::map<wxString, wxString> paramMap;
374
375 for( size_t i = 1; i < paramParts.size(); i += 2 )
376 {
377 wxString key = paramParts[i - 1];
378 wxString value = paramParts[i];
379
380 if( key == wxS( "spiceSymbolName" ) && !value.IsEmpty() )
381 symbolName = value;
382
383 paramMap[key] = value;
384 }
385
386 int& serial = namesCounter[symbolName];
387
388 if( serial > 0 )
389 symbolName << wxS( "_" ) << serial;
390
391 serial++;
392
393 aSymbolNameList.Add( symbolName );
394 }
395 }
396 }
397 }
398 else if( topDocType == EASYEDA::DOC_TYPE::SYMBOL )
399 {
401
402 wxString packageName = wxS( "Unknown" );
403
404 if( symDoc.c_para )
405 {
406 packageName = get_def( *symDoc.c_para, wxS( "name" ), packageName );
407 }
408 else if( topDoc.head.c_para )
409 {
410 packageName = get_def( *topDoc.head.c_para, wxS( "name" ), packageName );
411 }
412
413 aSymbolNameList.Add( packageName );
414 }
415 }
416 catch( nlohmann::json::exception& e )
417 {
418 THROW_IO_ERROR( wxString::Format( _( "Error enumerating symbol library '%s': %s" ),
419 aLibraryPath, e.what() ) );
420 }
421 catch( std::exception& e )
422 {
423 THROW_IO_ERROR( wxString::Format( _( "Error enumerating symbol library '%s': %s" ),
424 aLibraryPath, e.what() ) );
425 }
426}
427
428
429void SCH_IO_EASYEDA::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
430 const wxString& aLibraryPath,
431 const std::map<std::string, UTF8>* aProperties )
432{
433 wxFFileInputStream in( aLibraryPath );
434 nlohmann::json js;
435 EASYEDA::DOCUMENT topDoc;
436 EASYEDA::DOC_TYPE topDocType;
437
438 if( !FindSchFileInStream( aLibraryPath, in, js, topDoc, topDocType ) )
439 {
440 THROW_IO_ERROR( wxString::Format( _( "Unable to find a valid schematic file in '%s'" ),
441 aLibraryPath ) );
442 }
443
444 try
445 {
446 wxArrayString symbolNameList;
447
448 EnumerateSymbolLib( symbolNameList, aLibraryPath, aProperties );
449
450 for( const wxString& symbolName : symbolNameList )
451 {
452 LIB_SYMBOL* sym = loadSymbol( aLibraryPath, js, symbolName, aProperties );
453
454 if( sym )
455 aSymbolList.push_back( sym );
456 }
457 }
458 catch( nlohmann::json::exception& e )
459 {
460 THROW_IO_ERROR( wxString::Format( _( "Error enumerating symbol library '%s': %s" ),
461 aLibraryPath, e.what() ) );
462 }
463 catch( std::exception& e )
464 {
465 THROW_IO_ERROR( wxString::Format( _( "Error enumerating symbol library '%s': %s" ),
466 aLibraryPath, e.what() ) );
467 }
468}
469
470
471LIB_SYMBOL* SCH_IO_EASYEDA::LoadSymbol( const wxString& aLibraryPath,
472 const wxString& aAliasName,
473 const std::map<std::string, UTF8>* aProperties )
474{
475 try
476 {
477 wxFFileInputStream in( aLibraryPath );
478 nlohmann::json js;
479 EASYEDA::DOCUMENT topDoc;
480 EASYEDA::DOC_TYPE topDocType;
481
482 if( !FindSchFileInStream( aLibraryPath, in, js, topDoc, topDocType ) )
483 {
484 THROW_IO_ERROR( wxString::Format( _( "Unable to find a valid schematic file in '%s'" ),
485 aLibraryPath ) );
486 }
487
488 return loadSymbol( aLibraryPath, js, aAliasName, aProperties );
489 }
490 catch( nlohmann::json::exception& e )
491 {
492 THROW_IO_ERROR( wxString::Format( _( "Error loading symbol '%s' from library '%s': %s" ),
493 aAliasName, aLibraryPath, e.what() ) );
494 }
495 catch( std::exception& e )
496 {
497 THROW_IO_ERROR( wxString::Format( _( "Error loading symbol '%s' from library '%s': %s" ),
498 aAliasName, aLibraryPath, e.what() ) );
499 }
500}
501
502
503static void LoadSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet, const wxString& aFileName )
504{
505 SCH_EASYEDA_PARSER parser( nullptr, nullptr );
506
507 try
508 {
509 wxFFileInputStream in( aFileName );
510 nlohmann::json js;
511 EASYEDA::DOCUMENT topDoc;
512 EASYEDA::DOC_TYPE topDocType;
513
514 if( !FindSchFileInStream( aFileName, in, js, topDoc, topDocType ) )
515 {
516 THROW_IO_ERROR( wxString::Format( _( "Unable to find a valid schematic file in '%s'" ),
517 aFileName ) );
518 }
519
520 if( topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_SHEET
521 || topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_LIST )
522 {
523 int pageNum = 1;
525
526 for( const EASYEDA::DOCUMENT& subDoc : *schDoc.schematics )
527 {
528 if( subDoc.docType )
529 {
531 continue;
532 }
533 else
534 {
536 continue;
537 }
538
539 EASYEDA::DOCUMENT dataStrDoc = subDoc.dataStr->get<EASYEDA::DOCUMENT>();
540
541 if( schDoc.schematics->size() > 1 )
542 {
543 wxString sheetTitle =
544 !subDoc.title.empty() ? subDoc.title : ( wxString() << pageNum );
545
546 wxString sheetBaseName = EscapeString( sheetTitle, CTX_FILENAME );
547
548 wxFileName sheetFname( aFileName );
549 sheetFname.SetFullName(
550 sheetBaseName + wxS( "." )
551 + wxString::FromUTF8( FILEEXT::KiCadSchematicFileExtension ) );
552
553 wxFileName relSheetPath( sheetFname );
554 relSheetPath.MakeRelativeTo(
555 wxFileName( aRootSheet->GetFileName() ).GetPath() );
556
557 std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
558 subSheet->SetFileName( relSheetPath.GetFullPath() );
559 subSheet->SetName( sheetTitle );
560
561 SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
562 screen->SetFileName( sheetFname.GetFullPath() );
563 screen->SetPageNumber( wxString() << pageNum );
564 subSheet->SetScreen( screen );
565
566 VECTOR2I pos;
567 pos.x = schIUScale.MilsToIU( 200 );
568 pos.y = schIUScale.MilsToIU( 200 )
569 + ( subSheet->GetSize().y + schIUScale.MilsToIU( 200 ) )
570 * ( pageNum - 1 );
571
572 subSheet->SetPosition( pos );
573
574 SCH_SHEET_PATH sheetPath;
575 sheetPath.push_back( aRootSheet );
576 sheetPath.push_back( subSheet.get() );
577 sheetPath.SetPageNumber( wxString() << pageNum );
578 aSchematic->SetCurrentSheet( sheetPath );
579
580 parser.ParseSchematic( aSchematic, subSheet.get(), aFileName,
581 dataStrDoc.shape );
582
583 aRootSheet->GetScreen()->Append( subSheet.release() );
584 }
585 else
586 {
587 parser.ParseSchematic( aSchematic, aRootSheet, aFileName, dataStrDoc.shape );
588 }
589
590 pageNum++;
591 }
592 }
593 }
594 catch( nlohmann::json::exception& e )
595 {
597 wxString::Format( _( "Error loading schematic '%s': %s" ), aFileName, e.what() ) );
598 }
599 catch( std::exception& e )
600 {
602 wxString::Format( _( "Error loading schematic '%s': %s" ), aFileName, e.what() ) );
603 }
604}
605
606
607SCH_SHEET* SCH_IO_EASYEDA::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
608 SCH_SHEET* aAppendToMe,
609 const std::map<std::string, UTF8>* aProperties )
610{
611 wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
612
613 // Collect the font substitution warnings (RAII - automatically reset on scope exit)
615
616 SCH_SHEET* rootSheet = nullptr;
617
618 if( aAppendToMe )
619 {
620 wxCHECK_MSG( aSchematic->IsValid(), nullptr,
621 wxS( "Can't append to a schematic with no root!" ) );
622
623 rootSheet = aAppendToMe;
624 }
625 else
626 {
627 rootSheet = new SCH_SHEET( aSchematic );
628 rootSheet->SetFileName( aFileName );
629 aSchematic->SetTopLevelSheets( { rootSheet } );
630 }
631
632 if( !rootSheet->GetScreen() )
633 {
634 SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
635
636 screen->SetFileName( aFileName );
637 rootSheet->SetScreen( screen );
638
639 // Virtual root sheet UUID must be the same as the schematic file UUID.
640 const_cast<KIID&>( rootSheet->m_Uuid ) = screen->GetUuid();
641 }
642
643 LoadSchematic( aSchematic, rootSheet, aFileName );
645
646 return rootSheet;
647}
const char * name
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
void SetPageNumber(const wxString &aPageNumber)
Definition base_screen.h:75
static double Convert(const wxString &aValue)
const KIID m_Uuid
Definition eda_item.h:531
RAII class to set and restore the fontconfig reporter.
Definition reporter.h:332
Definition kiid.h:44
Define a library symbol object.
Definition lib_symbol.h:79
SCH_FIELD & GetReferenceField()
Return reference to the reference designator field.
Definition lib_symbol.h:333
static LOAD_INFO_REPORTER & GetInstance()
Definition reporter.cpp:247
Holds all the data relating to one schematic.
Definition schematic.h:90
void SetCurrentSheet(const SCH_SHEET_PATH &aPath)
Definition schematic.h:194
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition schematic.h:174
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:189
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.
Definition sch_field.h:128
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.
Definition sch_io.cpp:45
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
const KIID & GetUuid() const
Definition sch_screen.h:529
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.
Definition sch_sheet.h:44
void SetFileName(const wxString &aFilename)
Definition sch_sheet.h:376
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition sch_sheet.h:370
SCH_SCREEN * GetScreen() const
Definition sch_sheet.h:139
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
#define _(s)
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="")
Definition map_helpers.h:60
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:...
@ CTX_FILENAME
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
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682
Definition of file extensions used in Kicad.