KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_io_easyedapro_v3.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
27
31
32#include <font/fontconfig.h>
34#include <reporter.h>
35#include <schematic.h>
36#include <sch_screen.h>
37#include <sch_sheet.h>
38#include <string_utils.h>
40
41#include <core/map_helpers.h>
42
43#include <wx/filename.h>
44#include <wx/log.h>
45
46#include <set>
47
48
49static long long getFileTimestamp( const wxString& aFileName )
50{
51 wxFileName fileName( aFileName );
52
53 if( fileName.IsFileReadable() && fileName.GetModificationTime().IsValid() )
54 return fileName.GetModificationTime().GetValue().GetValue();
55
56 return 0;
57}
58
59
61 const EASYEDAPRO::V3_SYMBOL_LIB_ITEM& aItem, const wxString& aLibName,
62 const wxString& aSymbolName,
63 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobs,
64 SCH_EASYEDAPRO_V3_PARSER& aSymbolParser )
65{
66 const EASYEDAPRO::V3_DOC_RAW* rawDoc = aParser.FindRawDoc( wxS( "SYMBOL" ), aItem.symbolUuid );
67
68 if( !rawDoc )
69 return nullptr;
70
71 static const std::map<wxString, wxString> emptyAttributes;
72 const EASYEDAPRO::PRJ_DEVICE* device = aItem.hasDevice ? &aItem.device : nullptr;
73 const std::map<wxString, wxString>& attributes = aItem.hasDevice ? aItem.device.attributes : emptyAttributes;
74
75 EASYEDAPRO::SYM_INFO symInfo = aSymbolParser.ParseSymbol( *rawDoc, attributes, aBlobs );
76
77 if( !symInfo.libSymbol )
78 return nullptr;
79
80 LIB_SYMBOL& symbol = *symInfo.libSymbol;
81
82 symbol.SetLibId( EASYEDAPRO::ToKiCadLibID( aLibName, aSymbolName ) );
83 symbol.SetName( aSymbolName );
84
85 if( device )
86 {
87 if( auto fpUuid = get_opt( device->attributes, "Footprint" ) )
88 {
89 wxString fpTitle = *fpUuid;
90 const nlohmann::json& index = aParser.GetLibraryIndex();
91
92 if( index.contains( "footprints" ) && index.at( "footprints" ).is_object() )
93 {
94 const nlohmann::json& footprints = index.at( "footprints" );
95 const std::string key( fpUuid->ToUTF8() );
96
97 if( footprints.contains( key ) )
98 fpTitle = EASYEDAPRO::GetV3LibraryItemTitle( footprints.at( key ), *fpUuid );
99 }
100
101 symbol.GetFootprintField().SetText( aLibName + wxS( ":" ) + fpTitle );
102 }
103
105
106 wxString keywords = EASYEDAPRO::KeywordsFromV3Tags( device->tags );
107
108 if( !keywords.empty() )
109 symbol.SetKeyWords( keywords );
110 }
111
112 return symInfo.libSymbol.release();
113}
114
115
117 SCH_IO( wxS( "EasyEDA Pro (JLCEDA) Schematic v3" ) )
118{
119}
120
121
123
124
126{
127 long long timestamp = getFileTimestamp( aLibraryPath );
128
129 if( !m_cachedLibraryParser || m_cachedLibraryPath != aLibraryPath || m_cachedLibraryTimestamp != timestamp )
130 {
131 m_cachedLibraryParser = std::make_unique<EASYEDAPRO::V3_DOC_PARSER>( aLibraryPath );
132 m_cachedLibraryParser->LoadLibrary();
133 m_cachedLibraryPath = aLibraryPath;
134 m_cachedLibraryTimestamp = timestamp;
135 }
136
137 return *m_cachedLibraryParser;
138}
139
140
141bool SCH_IO_EASYEDAPRO_V3::CanReadSchematicFile( const wxString& aFileName ) const
142{
143 return EASYEDAPRO::V3_DOC_PARSER::IsV3Archive( aFileName );
144}
145
146
147bool SCH_IO_EASYEDAPRO_V3::CanReadLibrary( const wxString& aFileName ) const
148{
149 if( !SCH_IO::CanReadLibrary( aFileName ) )
150 return false;
151
152 return EASYEDAPRO::V3_DOC_PARSER::IsV3Library( aFileName, wxS( "SYMBOL" ) );
153}
154
155
157{
158 std::vector<LIB_SYMBOL*> result;
159
160 result.reserve( m_importedLibSymbols.size() );
161
162 for( const std::unique_ptr<LIB_SYMBOL>& symbol : m_importedLibSymbols )
163 result.push_back( new LIB_SYMBOL( *symbol ) );
164
165 return result;
166}
167
168
169void SCH_IO_EASYEDAPRO_V3::EnumerateSymbolLib( wxArrayString& aSymbolNameList, const wxString& aLibraryPath,
170 const std::map<std::string, UTF8>* aProperties )
171{
172 FONTCONFIG_REPORTER_SCOPE fontconfigScope( nullptr );
173
174 const EASYEDAPRO::V3_DOC_PARSER& v3 = getCachedLibraryParser( aLibraryPath );
175
176 for( const auto& [name, item] : EASYEDAPRO::BuildV3SymbolLibraryMap( v3 ) )
177 {
178 aSymbolNameList.Add( name );
179 }
180}
181
182
183void SCH_IO_EASYEDAPRO_V3::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList, const wxString& aLibraryPath,
184 const std::map<std::string, UTF8>* aProperties )
185{
186 FONTCONFIG_REPORTER_SCOPE fontconfigScope( nullptr );
187
188 const EASYEDAPRO::V3_DOC_PARSER& v3 = getCachedLibraryParser( aLibraryPath );
189 std::map<wxString, EASYEDAPRO::V3_SYMBOL_LIB_ITEM> items = EASYEDAPRO::BuildV3SymbolLibraryMap( v3 );
190 std::map<wxString, EASYEDAPRO::BLOB> blobs = EASYEDAPRO::BuildV3BlobMap( v3 );
191
192 wxString libName = LIB_ID::FixIllegalChars( wxFileName( aLibraryPath ).GetName(), true );
193
194 SCH_EASYEDAPRO_V3_PARSER parser( nullptr, nullptr );
195
196 for( const auto& [symbolName, item] : items )
197 {
198 try
199 {
200 if( LIB_SYMBOL* symbol = LoadV3LibrarySymbolItem( v3, item, libName, symbolName, blobs, parser ) )
201 aSymbolList.push_back( symbol );
202 }
203 catch( nlohmann::json::exception& e )
204 {
205 Report(
206 wxString::Format( _( "EasyEDA Pro v3 symbol '%s' in '%s' was skipped due to parse error: %s" ),
207 symbolName, aLibraryPath, e.what() ) , RPT_SEVERITY_WARNING );
208 }
209 }
210}
211
212
213LIB_SYMBOL* SCH_IO_EASYEDAPRO_V3::LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
214 const std::map<std::string, UTF8>* aProperties )
215{
216 FONTCONFIG_REPORTER_SCOPE fontconfigScope( nullptr );
217
218 const EASYEDAPRO::V3_DOC_PARSER& v3 = getCachedLibraryParser( aLibraryPath );
219 std::map<wxString, EASYEDAPRO::V3_SYMBOL_LIB_ITEM> items = EASYEDAPRO::BuildV3SymbolLibraryMap( v3 );
220
221 auto itemIt = items.find( aAliasName );
222
223 if( itemIt == items.end() )
224 return nullptr;
225
226 wxString libName = LIB_ID::FixIllegalChars( wxFileName( aLibraryPath ).GetName(), true );
227
228 SCH_EASYEDAPRO_V3_PARSER parser( nullptr, nullptr );
229
230 try
231 {
232 return LoadV3LibrarySymbolItem( v3, itemIt->second, libName, aAliasName,
233 EASYEDAPRO::BuildV3BlobMap( v3 ), parser );
234 }
235 catch( nlohmann::json::exception& e )
236 {
237 THROW_IO_ERRORF( _( "Cannot load symbol '%s' from '%s': %s" ), aAliasName, aLibraryPath, e.what() );
238 }
239}
240
241
242SCH_SHEET* SCH_IO_EASYEDAPRO_V3::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
243 SCH_SHEET* aAppendToMe,
244 const std::map<std::string, UTF8>* aProperties )
245{
246 wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
247
249
250 SCH_SHEET* rootSheet = nullptr;
251
252 if( aAppendToMe )
253 {
254 wxCHECK_MSG( aSchematic->IsValid(), nullptr, wxS( "Can't append to a schematic with no root!" ) );
255
256 rootSheet = aAppendToMe;
257 }
258 else
259 {
260 rootSheet = new SCH_SHEET( aSchematic );
261 rootSheet->SetFileName( aFileName );
262 aSchematic->SetTopLevelSheets( { rootSheet } );
263 }
264
265 if( !rootSheet->GetScreen() )
266 {
267 SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
268
269 screen->SetFileName( aFileName );
270 rootSheet->SetScreen( screen );
271
272 const_cast<KIID&>( rootSheet->m_Uuid ) = screen->GetUuid();
273 }
274
275 EASYEDAPRO::V3_DOC_PARSER v3( aFileName );
276 v3.Load();
277
279
280 std::map<wxString, EASYEDAPRO::PRJ_SCHEMATIC> prjSchematics = project.at( "schematics" );
281
282 wxString schematicToLoad;
283
284 if( aProperties && aProperties->contains( "sch_id" ) )
285 {
286 schematicToLoad = wxString::FromUTF8( aProperties->at( "sch_id" ) );
287 }
288 else if( prjSchematics.size() == 1 )
289 {
290 schematicToLoad = prjSchematics.begin()->first;
291 }
292 else if( m_choose_project_handler )
293 {
294 std::vector<IMPORT_PROJECT_DESC> chosen =
296
297 if( !chosen.empty() )
298 schematicToLoad = chosen[0].SchematicId;
299 }
300 else if( !prjSchematics.empty() )
301 {
302 schematicToLoad = prjSchematics.begin()->first;
303 }
304
305 if( schematicToLoad.empty() )
306 return nullptr;
307
308 auto prjSchIt = prjSchematics.find( schematicToLoad );
309
310 if( prjSchIt == prjSchematics.end() )
311 THROW_IO_ERRORF( _( "Schematic document '%s' not found in '%s'" ), schematicToLoad, aFileName );
312
313 wxFileName sourceName( aFileName );
314 wxString libName = EASYEDAPRO::ShortenLibName( sourceName.GetName() );
315
316 wxString rootBaseName = EscapeString( prjSchIt->second.name, CTX_FILENAME );
317
318 wxFileName rootFname( aFileName );
319 rootFname.SetFullName( rootBaseName + wxS( "." ) + wxString::FromUTF8( FILEEXT::KiCadSchematicFileExtension ) );
320
321 rootSheet->SetName( prjSchIt->second.name );
322 rootSheet->SetFileName( rootFname.GetFullPath() );
323 rootSheet->GetScreen()->SetFileName( rootFname.GetFullPath() );
324
325 SCH_EASYEDAPRO_V3_PARSER parser( nullptr, nullptr );
326
327 std::map<wxString, EASYEDAPRO::PRJ_SYMBOL> prjSymbols;
328 std::map<wxString, EASYEDAPRO::PRJ_FOOTPRINT> prjFootprints;
329 std::map<wxString, EASYEDAPRO::PRJ_DEVICE> prjDevices;
330
331 try
332 {
333 if( project.contains( "symbols" ) )
334 prjSymbols = project.at( "symbols" );
335
336 if( project.contains( "footprints" ) )
337 prjFootprints = project.at( "footprints" );
338
339 if( project.contains( "devices" ) )
340 prjDevices = project.at( "devices" );
341 }
342 catch( nlohmann::json::exception& e )
343 {
344 THROW_IO_ERRORF( _( "Failed to parse EasyEDA Pro v3 symbol/device metadata: %s" ), e.what() );
345 }
346
347 // Schematic components reference Symbol (geometry) and Device (BOM attrs) separately.
348 // Build geometry by symbol UUID; assign stable project-lib names from each Device.
349 std::set<wxString> usedLibNames;
350 std::map<wxString, wxString> deviceLibNames =
351 EASYEDAPRO::BuildV3DeviceLibNames( project, prjDevices, &usedLibNames );
352
353 std::map<wxString, EASYEDAPRO::SYM_INFO> symbols;
354 std::map<wxString, EASYEDAPRO::BLOB> blobs = EASYEDAPRO::BuildV3BlobMap( v3 );
355
356 for( const auto& [symbolUuid, rawDoc] : v3.GetRawDocs( wxS( "SYMBOL" ) ) )
357 {
358 auto symMetaIt = prjSymbols.find( symbolUuid );
359
360 if( symMetaIt == prjSymbols.end() )
361 continue;
362
363 EASYEDAPRO::SYM_INFO symInfo;
364
365 try
366 {
367 // Geometry only. Device BOM fields come from the component Device ATTR.
368 symInfo = parser.ParseSymbol( rawDoc, {}, blobs );
369 }
370 catch( nlohmann::json::exception& e )
371 {
372 Report( wxString::Format( _( "EasyEDA Pro v3 symbol '%s' was skipped due to parse error: %s" ),
373 symbolUuid, e.what() ) , RPT_SEVERITY_WARNING );
374 continue;
375 }
376
377 if( !symInfo.libSymbol )
378 continue;
379
380 LIB_ID libID = EASYEDAPRO::ToKiCadLibID( libName, symMetaIt->second.title );
381 symInfo.libSymbol->SetLibId( libID );
382 symInfo.libSymbol->SetName( symMetaIt->second.title );
383
384 symInfo.libSymbol->SetDescription( EASYEDAPRO::NormalizeEasyEDAText( symMetaIt->second.desc ) );
385
386 wxString keywords = EASYEDAPRO::KeywordsFromV3Tags( symMetaIt->second.tags );
387
388 if( !keywords.empty() )
389 symInfo.libSymbol->SetKeyWords( keywords );
390
391 symbols.emplace( symbolUuid, std::move( symInfo ) );
392 }
393
394 const std::vector<EASYEDAPRO::PRJ_SHEET>& prjSchematicSheets = prjSchIt->second.sheets;
395
396 bool rootAssigned = false;
397 int subSheetIndex = 0;
398
399 for( const EASYEDAPRO::PRJ_SHEET& prjSheet : prjSchematicSheets )
400 {
401 const EASYEDAPRO::V3_DOC_RAW* pageRawDoc = v3.FindRawDoc( wxS( "SCH_PAGE" ), prjSheet.uuid );
402
403 if( !pageRawDoc )
404 {
405 Report( wxString::Format( _( "EasyEDA Pro v3 schematic page '%s' was not found and was skipped." ),
406 prjSheet.uuid ) , RPT_SEVERITY_WARNING );
407 continue;
408 }
409
410 wxString sheetId = wxString::Format( "%d", prjSheet.id );
411
412 // The first page fills the root sheet so no empty index sheet is left behind;
413 // any remaining pages become subsheets hanging off the root.
414 if( !rootAssigned )
415 {
416 SCH_SHEET_PATH sheetPath;
417 sheetPath.push_back( rootSheet );
418 sheetPath.SetPageNumber( sheetId );
419 aSchematic->SetCurrentSheet( sheetPath );
420
421 try
422 {
423 parser.ParseSchematic( aSchematic, rootSheet, project, symbols, blobs, *pageRawDoc, libName );
424 }
425 catch( nlohmann::json::exception& e )
426 {
427 Report(
428 wxString::Format( _( "EasyEDA Pro v3 schematic page '%s' was skipped due to parse error: %s" ),
429 prjSheet.uuid, e.what() ) , RPT_SEVERITY_WARNING );
430 continue;
431 }
432
433 rootSheet->SetName( prjSheet.name );
434 rootSheet->GetScreen()->SetPageNumber( sheetId );
435 rootAssigned = true;
436 continue;
437 }
438
439 wxString sheetBaseName = sheetId + wxS( "_" ) + EscapeString( prjSheet.name, CTX_FILENAME );
440
441 wxFileName sheetFname( aFileName );
442 sheetFname.SetFullName( sheetBaseName + wxS( "." )
443 + wxString::FromUTF8( FILEEXT::KiCadSchematicFileExtension ) );
444
445 wxFileName relSheetPath( sheetFname );
446 relSheetPath.MakeRelativeTo( rootFname.GetPath() );
447
448 std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
449 subSheet->SetFileName( relSheetPath.GetFullPath() );
450 subSheet->SetName( prjSheet.name );
451
452 SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
453 screen->SetFileName( sheetFname.GetFullPath() );
454 screen->SetPageNumber( sheetId );
455 subSheet->SetScreen( screen );
456
457 VECTOR2I pos;
458 pos.x = schIUScale.MilsToIU( 200 );
459 pos.y = schIUScale.MilsToIU( 200 ) + ( subSheet->GetSize().y + schIUScale.MilsToIU( 200 ) ) * subSheetIndex;
460
461 subSheet->SetPosition( pos );
462
463 SCH_SHEET_PATH sheetPath;
464 sheetPath.push_back( rootSheet );
465 sheetPath.push_back( subSheet.get() );
466 sheetPath.SetPageNumber( sheetId );
467 aSchematic->SetCurrentSheet( sheetPath );
468
469 try
470 {
471 parser.ParseSchematic( aSchematic, subSheet.get(), project, symbols, blobs, *pageRawDoc, libName );
472 }
473 catch( nlohmann::json::exception& e )
474 {
475 Report(
476 wxString::Format( _( "EasyEDA Pro v3 schematic page '%s' was skipped due to parse error: %s" ),
477 prjSheet.uuid, e.what() ) , RPT_SEVERITY_WARNING );
478 continue;
479 }
480
481 rootSheet->GetScreen()->Append( subSheet.release() );
482 subSheetIndex++;
483 }
484
485 // Loading a schematic must not write to disk, so the project library is left to the reconciler
486 m_importedLibSymbols.clear();
487
488 std::set<wxString> symbolsFromDevices;
489
490 // Project library entries are devices: geometry from Symbol + BOM fields from Device.
491 for( const auto& [devUuid, device] : prjDevices )
492 {
493 auto symbolAttr = get_opt( device.attributes, "Symbol" );
494
495 if( !symbolAttr )
496 continue;
497
498 const EASYEDAPRO::V3_DOC_RAW* symbolDoc = v3.FindRawDoc( wxS( "SYMBOL" ), *symbolAttr );
499
500 if( !symbolDoc )
501 continue;
502
503 EASYEDAPRO::SYM_INFO deviceSymInfo;
504
505 try
506 {
507 deviceSymInfo = parser.ParseSymbol( *symbolDoc, device.attributes, blobs );
508 }
509 catch( nlohmann::json::exception& e )
510 {
511 Report( wxString::Format( _( "EasyEDA Pro v3 device '%s' was skipped due to parse error: %s" ),
512 device.title, e.what() ) , RPT_SEVERITY_WARNING );
513 continue;
514 }
515
516 if( !deviceSymInfo.libSymbol )
517 continue;
518
519 auto nameIt = deviceLibNames.find( devUuid );
520 wxString itemName = ( nameIt != deviceLibNames.end() ) ? nameIt->second : device.title;
521
522 LIB_ID libID = EASYEDAPRO::ToKiCadLibID( libName, itemName );
523 deviceSymInfo.libSymbol->SetLibId( libID );
524 deviceSymInfo.libSymbol->SetName( itemName );
525
526 if( auto fpUuid = get_opt( device.attributes, "Footprint" ) )
527 {
528 if( auto prjFp = get_opt( prjFootprints, *fpUuid ) )
529 deviceSymInfo.libSymbol->GetFootprintField().SetText( libName + wxS( ":" ) + prjFp->title );
530 }
531
532 wxString description = device.description;
533
534 if( description.empty() )
535 description = get_def( device.attributes, wxS( "Description" ), wxEmptyString );
536
537 if( !description.empty() )
538 {
540 EASYEDAPRO::ResolveDeviceFieldVariables( description, device.attributes ) ) );
541 }
542
543 wxString keywords = EASYEDAPRO::KeywordsFromV3Tags( device.tags );
544
545 if( !keywords.empty() )
546 deviceSymInfo.libSymbol->SetKeyWords( keywords );
547
548 m_importedLibSymbols.emplace_back( std::move( deviceSymInfo.libSymbol ) );
549 symbolsFromDevices.insert( *symbolAttr );
550 }
551
552 // Keep geometry-only entries for symbols not referenced by any device (e.g. some helpers).
553 for( auto& [symbolUuid, symInfo] : symbols )
554 {
555 if( !symInfo.libSymbol || symbolsFromDevices.contains( symbolUuid ) )
556 continue;
557
558 wxString itemName = EASYEDAPRO::MakeUniqueLibName( usedLibNames, symInfo.libSymbol->GetName(),
559 symbolUuid );
560 LIB_ID libID = EASYEDAPRO::ToKiCadLibID( libName, itemName );
561 symInfo.libSymbol->SetLibId( libID );
562 symInfo.libSymbol->SetName( itemName );
563
564 m_importedLibSymbols.emplace_back( std::move( symInfo.libSymbol ) );
565 }
566
568 aSchematic->FixupJunctionsAfterImport();
569
570 if( v3.GetSkippedCount() > 0 )
571 {
572 Report( wxString::Format( _( "EasyEDA (JLCEDA) Pro v3 import skipped %d unsupported object(s)." ),
573 v3.GetSkippedCount() ) , RPT_SEVERITY_WARNING );
574 }
575
576 return rootSheet;
577}
int index
const char * name
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
void SetPageNumber(const wxString &aPageNumber)
Definition base_screen.h:75
Parses EasyEDA Pro v3 .epro2 archives.
const V3_DOC_RAW * FindRawDoc(const wxString &aDocType, const wxString &aUuid) const
static bool IsV3Library(const wxString &aFileName, const wxString &aRequiredDocType=wxEmptyString)
Return true if aFileName looks like an EasyEDA Pro v3 library archive.
const nlohmann::json & GetLibraryIndex() const
static bool IsV3Archive(const wxString &aFileName)
Return true if aFileName looks like an EasyEDA Pro v3 archive.
const KIID m_Uuid
Definition eda_item.h:531
RAII class to set and restore the fontconfig reporter.
Definition reporter.h:368
const wxString & GetName() const
Return a brief hard coded name for this IO interface.
Definition io_base.h:79
virtual void Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) const
Definition io_base.cpp:124
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
Definition io_base.cpp:71
Definition kiid.h:46
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition lib_id.cpp:205
Define a library symbol object.
Definition lib_symbol.h:114
SCH_FIELD & GetFootprintField()
Return reference to the footprint field.
Definition lib_symbol.h:436
void SetDescription(const wxString &aDescription)
Gets the Description field text value *‍/.
void SetKeyWords(const wxString &aKeyWords)
void SetLibId(const LIB_ID &aLibId)
virtual void SetName(const wxString &aName)
static LOAD_INFO_REPORTER & GetInstance()
Definition reporter.cpp:306
CHOOSE_PROJECT_HANDLER m_choose_project_handler
Callback to choose projects to import.
Holds all the data relating to one schematic.
Definition schematic.h:90
void SetCurrentSheet(const SCH_SHEET_PATH &aPath)
Definition schematic.h:194
int FixupJunctionsAfterImport()
Add junctions to this schematic where required.
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 nlohmann::json &aProject, std::map< wxString, EASYEDAPRO::SYM_INFO > &aSymbolMap, const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap, const EASYEDAPRO::V3_DOC_RAW &aDoc, const wxString &aLibName)
EASYEDAPRO::SYM_INFO ParseSymbol(const EASYEDAPRO::V3_DOC_RAW &aDoc, const std::map< wxString, wxString > &aDeviceAttributes, const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap={})
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.
std::vector< LIB_SYMBOL * > GetImportedCachedLibrarySymbols() override
Return the canonical symbol definitions produced by the last LoadSchematicFile().
std::unique_ptr< EASYEDAPRO::V3_DOC_PARSER > m_cachedLibraryParser
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,...
const EASYEDAPRO::V3_DOC_PARSER & getCachedLibraryParser(const wxString &aLibraryPath) const
~SCH_IO_EASYEDAPRO_V3() override
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
std::vector< std::unique_ptr< LIB_SYMBOL > > m_importedLibSymbols
Definitions from the last LoadSchematicFile, cloned out to the import reconciler on request.
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...
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.
SCH_IO(const wxString &aName)
Definition sch_io.h:384
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
void SetName(const wxString &aName)
Definition sch_sheet.h:137
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_ERRORF(msg,...)
wxString get_def(const std::map< wxString, wxString > &aMap, const char *aKey, const char *aDefval="")
Definition map_helpers.h:60
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
Definition map_helpers.h:30
nlohmann::json BuildV3ProjectIndexFromRawDocs(const V3_DOC_PARSER &aParser, bool aIncludeLibraryMetadata=true)
Build a minimal legacy-style project index from parsed v3 raw documents.
LIB_ID ToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
wxString MakeUniqueLibName(std::set< wxString > &aUsedNames, const wxString &aName, const wxString &aFallback)
Allocate a unique library item name, recording it in aUsedNames.
wxString KeywordsFromV3Tags(const nlohmann::json &aTags)
Build KiCad keywords from a v3 tags object (parent_tag / child_tag name fields).
wxString GetV3LibraryItemTitle(const nlohmann::json &aMetadata, const wxString &aUuid)
wxString ResolveDeviceFieldVariables(const wxString &aInput, const std::map< wxString, wxString > &aDeviceAttributes)
Resolve EasyEDA ={Var} / ={A}text{B} field expressions against device attributes.
wxString NormalizeEasyEDAText(wxString aText)
Replace EasyEDA temperature glyph (℃) with °C.
std::vector< IMPORT_PROJECT_DESC > ProjectToSelectorDialog(const nlohmann::json &aProject, bool aPcbOnly=false, bool aSchOnly=false)
wxString ShortenLibName(wxString aProjectName)
std::map< wxString, V3_SYMBOL_LIB_ITEM > BuildV3SymbolLibraryMap(const V3_DOC_PARSER &aParser)
std::map< wxString, BLOB > BuildV3BlobMap(const V3_DOC_PARSER &aParser)
std::map< wxString, wxString > BuildV3DeviceLibNames(nlohmann::json &aProject, const std::map< wxString, PRJ_DEVICE > &aDevices, std::set< wxString > *aUsedNames=nullptr)
Stable project-lib item names keyed by Device UUID (one entry per Device).
@ RPT_SEVERITY_WARNING
static long long getFileTimestamp(const wxString &aFileName)
static LIB_SYMBOL * LoadV3LibrarySymbolItem(const EASYEDAPRO::V3_DOC_PARSER &aParser, const EASYEDAPRO::V3_SYMBOL_LIB_ITEM &aItem, const wxString &aLibName, const wxString &aSymbolName, const std::map< wxString, EASYEDAPRO::BLOB > &aBlobs, SCH_EASYEDAPRO_V3_PARSER &aSymbolParser)
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::map< wxString, wxString > attributes
std::unique_ptr< LIB_SYMBOL > libSymbol
Raw parsed document from an EasyEDA Pro v3 .epru stream.
Build the schematic-library name map for a v3 .elibz2.
wxString result
Test unit parsing edge cases and error handling.
VECTOR2I v3(-2, 1)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
Definition of file extensions used in Kicad.