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>
36#include <project_sch.h>
37#include <reporter.h>
38#include <schematic.h>
40#include <sch_io/sch_io_mgr.h>
41#include <sch_screen.h>
42#include <sch_sheet.h>
43#include <string_utils.h>
45
46#include <core/map_helpers.h>
47
48#include <wx/filename.h>
49#include <wx/log.h>
50
51#include <set>
52
53
54static long long getFileTimestamp( const wxString& aFileName )
55{
56 wxFileName fileName( aFileName );
57
58 if( fileName.IsFileReadable() && fileName.GetModificationTime().IsValid() )
59 return fileName.GetModificationTime().GetValue().GetValue();
60
61 return 0;
62}
63
64
66 const EASYEDAPRO::V3_SYMBOL_LIB_ITEM& aItem, const wxString& aLibName,
67 const wxString& aSymbolName,
68 const std::map<wxString, EASYEDAPRO::BLOB>& aBlobs,
69 SCH_EASYEDAPRO_V3_PARSER& aSymbolParser )
70{
71 const EASYEDAPRO::V3_DOC_RAW* rawDoc = aParser.FindRawDoc( wxS( "SYMBOL" ), aItem.symbolUuid );
72
73 if( !rawDoc )
74 return nullptr;
75
76 static const std::map<wxString, wxString> emptyAttributes;
77 const EASYEDAPRO::PRJ_DEVICE* device = aItem.hasDevice ? &aItem.device : nullptr;
78 const std::map<wxString, wxString>& attributes = aItem.hasDevice ? aItem.device.attributes : emptyAttributes;
79
80 EASYEDAPRO::SYM_INFO symInfo = aSymbolParser.ParseSymbol( *rawDoc, attributes, aBlobs );
81
82 if( !symInfo.libSymbol )
83 return nullptr;
84
85 LIB_SYMBOL& symbol = *symInfo.libSymbol;
86
87 symbol.SetLibId( EASYEDAPRO::ToKiCadLibID( aLibName, aSymbolName ) );
88 symbol.SetName( aSymbolName );
89
90 if( device )
91 {
92 if( auto fpUuid = get_opt( device->attributes, "Footprint" ) )
93 {
94 wxString fpTitle = *fpUuid;
95 const nlohmann::json& index = aParser.GetLibraryIndex();
96
97 if( index.contains( "footprints" ) && index.at( "footprints" ).is_object() )
98 {
99 const nlohmann::json& footprints = index.at( "footprints" );
100 const std::string key( fpUuid->ToUTF8() );
101
102 if( footprints.contains( key ) )
103 fpTitle = EASYEDAPRO::GetV3LibraryItemTitle( footprints.at( key ), *fpUuid );
104 }
105
106 symbol.GetFootprintField().SetText( aLibName + wxS( ":" ) + fpTitle );
107 }
108
110
111 wxString keywords = EASYEDAPRO::KeywordsFromV3Tags( device->tags );
112
113 if( !keywords.empty() )
114 symbol.SetKeyWords( keywords );
115 }
116
117 return symInfo.libSymbol.release();
118}
119
120
122 SCH_IO( wxS( "EasyEDA Pro (JLCEDA) Schematic v3" ) )
123{
125}
126
127
129
130
132{
133 long long timestamp = getFileTimestamp( aLibraryPath );
134
135 if( !m_cachedLibraryParser || m_cachedLibraryPath != aLibraryPath || m_cachedLibraryTimestamp != timestamp )
136 {
137 m_cachedLibraryParser = std::make_unique<EASYEDAPRO::V3_DOC_PARSER>( aLibraryPath );
138 m_cachedLibraryParser->LoadLibrary();
139 m_cachedLibraryPath = aLibraryPath;
140 m_cachedLibraryTimestamp = timestamp;
141 }
142
143 return *m_cachedLibraryParser;
144}
145
146
147bool SCH_IO_EASYEDAPRO_V3::CanReadSchematicFile( const wxString& aFileName ) const
148{
149 return EASYEDAPRO::V3_DOC_PARSER::IsV3Archive( aFileName );
150}
151
152
153bool SCH_IO_EASYEDAPRO_V3::CanReadLibrary( const wxString& aFileName ) const
154{
155 if( !SCH_IO::CanReadLibrary( aFileName ) )
156 return false;
157
158 return EASYEDAPRO::V3_DOC_PARSER::IsV3Library( aFileName, wxS( "SYMBOL" ) );
159}
160
161
162void SCH_IO_EASYEDAPRO_V3::EnumerateSymbolLib( wxArrayString& aSymbolNameList, const wxString& aLibraryPath,
163 const std::map<std::string, UTF8>* aProperties )
164{
165 FONTCONFIG_REPORTER_SCOPE fontconfigScope( nullptr );
166
167 const EASYEDAPRO::V3_DOC_PARSER& v3 = getCachedLibraryParser( aLibraryPath );
168
169 for( const auto& [name, item] : EASYEDAPRO::BuildV3SymbolLibraryMap( v3 ) )
170 {
171 aSymbolNameList.Add( name );
172 }
173}
174
175
176void SCH_IO_EASYEDAPRO_V3::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList, const wxString& aLibraryPath,
177 const std::map<std::string, UTF8>* aProperties )
178{
179 FONTCONFIG_REPORTER_SCOPE fontconfigScope( nullptr );
180
181 const EASYEDAPRO::V3_DOC_PARSER& v3 = getCachedLibraryParser( aLibraryPath );
182 std::map<wxString, EASYEDAPRO::V3_SYMBOL_LIB_ITEM> items = EASYEDAPRO::BuildV3SymbolLibraryMap( v3 );
183 std::map<wxString, EASYEDAPRO::BLOB> blobs = EASYEDAPRO::BuildV3BlobMap( v3 );
184
185 wxString libName = LIB_ID::FixIllegalChars( wxFileName( aLibraryPath ).GetName(), true );
186
187 SCH_EASYEDAPRO_V3_PARSER parser( nullptr, nullptr );
188
189 for( const auto& [symbolName, item] : items )
190 {
191 try
192 {
193 if( LIB_SYMBOL* symbol = LoadV3LibrarySymbolItem( v3, item, libName, symbolName, blobs, parser ) )
194 aSymbolList.push_back( symbol );
195 }
196 catch( nlohmann::json::exception& e )
197 {
198 wxLogWarning(
199 wxString::Format( _( "EasyEDA Pro v3 symbol '%s' in '%s' was skipped due to parse error: %s" ),
200 symbolName, aLibraryPath, e.what() ) );
201 }
202 }
203}
204
205
206LIB_SYMBOL* SCH_IO_EASYEDAPRO_V3::LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
207 const std::map<std::string, UTF8>* aProperties )
208{
209 FONTCONFIG_REPORTER_SCOPE fontconfigScope( nullptr );
210
211 const EASYEDAPRO::V3_DOC_PARSER& v3 = getCachedLibraryParser( aLibraryPath );
212 std::map<wxString, EASYEDAPRO::V3_SYMBOL_LIB_ITEM> items = EASYEDAPRO::BuildV3SymbolLibraryMap( v3 );
213
214 auto itemIt = items.find( aAliasName );
215
216 if( itemIt == items.end() )
217 return nullptr;
218
219 wxString libName = LIB_ID::FixIllegalChars( wxFileName( aLibraryPath ).GetName(), true );
220
221 SCH_EASYEDAPRO_V3_PARSER parser( nullptr, nullptr );
222
223 try
224 {
225 return LoadV3LibrarySymbolItem( v3, itemIt->second, libName, aAliasName,
226 EASYEDAPRO::BuildV3BlobMap( v3 ), parser );
227 }
228 catch( nlohmann::json::exception& e )
229 {
231 wxString::Format( _( "Cannot load symbol '%s' from '%s': %s" ), aAliasName, aLibraryPath, e.what() ) );
232 }
233}
234
235
236SCH_SHEET* SCH_IO_EASYEDAPRO_V3::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
237 SCH_SHEET* aAppendToMe,
238 const std::map<std::string, UTF8>* aProperties )
239{
240 wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
241
243
244 SCH_SHEET* rootSheet = nullptr;
245
246 if( aAppendToMe )
247 {
248 wxCHECK_MSG( aSchematic->IsValid(), nullptr, wxS( "Can't append to a schematic with no root!" ) );
249
250 rootSheet = aAppendToMe;
251 }
252 else
253 {
254 rootSheet = new SCH_SHEET( aSchematic );
255 rootSheet->SetFileName( aFileName );
256 aSchematic->SetTopLevelSheets( { rootSheet } );
257 }
258
259 if( !rootSheet->GetScreen() )
260 {
261 SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
262
263 screen->SetFileName( aFileName );
264 rootSheet->SetScreen( screen );
265
266 const_cast<KIID&>( rootSheet->m_Uuid ) = screen->GetUuid();
267 }
268
269 EASYEDAPRO::V3_DOC_PARSER v3( aFileName );
270 v3.Load();
271
273
274 std::map<wxString, EASYEDAPRO::PRJ_SCHEMATIC> prjSchematics = project.at( "schematics" );
275
276 wxString schematicToLoad;
277
278 if( aProperties && aProperties->contains( "sch_id" ) )
279 {
280 schematicToLoad = wxString::FromUTF8( aProperties->at( "sch_id" ) );
281 }
282 else if( prjSchematics.size() == 1 )
283 {
284 schematicToLoad = prjSchematics.begin()->first;
285 }
286 else if( m_choose_project_handler )
287 {
288 std::vector<IMPORT_PROJECT_DESC> chosen =
290
291 if( !chosen.empty() )
292 schematicToLoad = chosen[0].SchematicId;
293 }
294 else if( !prjSchematics.empty() )
295 {
296 schematicToLoad = prjSchematics.begin()->first;
297 }
298
299 if( schematicToLoad.empty() )
300 return nullptr;
301
302 auto prjSchIt = prjSchematics.find( schematicToLoad );
303
304 if( prjSchIt == prjSchematics.end() )
305 {
307 wxString::Format( _( "Schematic document '%s' not found in '%s'" ), schematicToLoad, aFileName ) );
308 }
309
310 wxFileName sourceName( aFileName );
311 wxString libName = EASYEDAPRO::ShortenLibName( sourceName.GetName() );
312
313 wxFileName libFileName( sourceName.GetPath(), libName, FILEEXT::KiCadSymbolLibFileExtension );
314
315 wxString rootBaseName = EscapeString( prjSchIt->second.name, CTX_FILENAME );
316
317 wxFileName rootFname( aFileName );
318 rootFname.SetFullName( rootBaseName + wxS( "." ) + wxString::FromUTF8( FILEEXT::KiCadSchematicFileExtension ) );
319
320 rootSheet->SetName( prjSchIt->second.name );
321 rootSheet->SetFileName( rootFname.GetFullPath() );
322 rootSheet->GetScreen()->SetFileName( rootFname.GetFullPath() );
323
324 SCH_EASYEDAPRO_V3_PARSER parser( nullptr, nullptr );
325
326 std::map<wxString, EASYEDAPRO::PRJ_SYMBOL> prjSymbols;
327 std::map<wxString, EASYEDAPRO::PRJ_FOOTPRINT> prjFootprints;
328 std::map<wxString, EASYEDAPRO::PRJ_DEVICE> prjDevices;
329
330 try
331 {
332 if( project.contains( "symbols" ) )
333 prjSymbols = project.at( "symbols" );
334
335 if( project.contains( "footprints" ) )
336 prjFootprints = project.at( "footprints" );
337
338 if( project.contains( "devices" ) )
339 prjDevices = project.at( "devices" );
340 }
341 catch( nlohmann::json::exception& e )
342 {
344 wxString::Format( _( "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 wxLogWarning( wxString::Format( _( "EasyEDA Pro v3 symbol '%s' was skipped due to parse error: %s" ),
373 symbolUuid, e.what() ) );
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 wxLogWarning( wxString::Format( _( "EasyEDA Pro v3 schematic page '%s' was not found and was skipped." ),
406 prjSheet.uuid ) );
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 wxLogWarning(
428 wxString::Format( _( "EasyEDA Pro v3 schematic page '%s' was skipped due to parse error: %s" ),
429 prjSheet.uuid, e.what() ) );
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 wxLogWarning(
476 wxString::Format( _( "EasyEDA Pro v3 schematic page '%s' was skipped due to parse error: %s" ),
477 prjSheet.uuid, e.what() ) );
478 continue;
479 }
480
481 rootSheet->GetScreen()->Append( subSheet.release() );
482 subSheetIndex++;
483 }
484
485 IO_RELEASER<SCH_IO> schPlugin( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
486
487 SYMBOL_LIBRARY_ADAPTER* symAdapter = PROJECT_SCH::SymbolLibAdapter( &aSchematic->Project() );
488 LIBRARY_TABLE* table = symAdapter->ProjectTable().value_or( nullptr );
489 wxCHECK_MSG( table, nullptr, "Could not load symbol lib table." );
490
491 if( !table->HasRow( libName ) )
492 {
493 schPlugin->CreateLibrary( libFileName.GetFullPath() );
494 wxString libTableUri = wxS( "${KIPRJMOD}/" ) + libFileName.GetFullName();
495
496 LIBRARY_TABLE_ROW& row = table->InsertRow();
497 row.SetNickname( libName );
498 row.SetURI( libTableUri );
499 row.SetType( "KiCad" );
500
501 table->Save();
502 symAdapter->LoadOne( libName );
503 }
504
505 std::map<std::string, UTF8> properties;
506 properties.emplace( SCH_IO_KICAD_SEXPR::PropBuffering, wxEmptyString );
507
508 std::set<wxString> symbolsSavedViaDevices;
509
510 // Project library entries are devices: geometry from Symbol + BOM fields from Device.
511 for( const auto& [devUuid, device] : prjDevices )
512 {
513 auto symbolAttr = get_opt( device.attributes, "Symbol" );
514
515 if( !symbolAttr )
516 continue;
517
518 const EASYEDAPRO::V3_DOC_RAW* symbolDoc = v3.FindRawDoc( wxS( "SYMBOL" ), *symbolAttr );
519
520 if( !symbolDoc )
521 continue;
522
523 EASYEDAPRO::SYM_INFO deviceSymInfo;
524
525 try
526 {
527 deviceSymInfo = parser.ParseSymbol( *symbolDoc, device.attributes, blobs );
528 }
529 catch( nlohmann::json::exception& e )
530 {
531 wxLogWarning( wxString::Format( _( "EasyEDA Pro v3 device '%s' was skipped due to parse error: %s" ),
532 device.title, e.what() ) );
533 continue;
534 }
535
536 if( !deviceSymInfo.libSymbol )
537 continue;
538
539 auto nameIt = deviceLibNames.find( devUuid );
540 wxString itemName = ( nameIt != deviceLibNames.end() ) ? nameIt->second : device.title;
541
542 LIB_ID libID = EASYEDAPRO::ToKiCadLibID( libName, itemName );
543 deviceSymInfo.libSymbol->SetLibId( libID );
544 deviceSymInfo.libSymbol->SetName( itemName );
545
546 if( auto fpUuid = get_opt( device.attributes, "Footprint" ) )
547 {
548 if( auto prjFp = get_opt( prjFootprints, *fpUuid ) )
549 deviceSymInfo.libSymbol->GetFootprintField().SetText( libName + wxS( ":" ) + prjFp->title );
550 }
551
552 wxString description = device.description;
553
554 if( description.empty() )
555 description = get_def( device.attributes, wxS( "Description" ), wxEmptyString );
556
557 if( !description.empty() )
558 {
560 EASYEDAPRO::ResolveDeviceFieldVariables( description, device.attributes ) ) );
561 }
562
563 wxString keywords = EASYEDAPRO::KeywordsFromV3Tags( device.tags );
564
565 if( !keywords.empty() )
566 deviceSymInfo.libSymbol->SetKeyWords( keywords );
567
568 schPlugin->SaveSymbol( libFileName.GetFullPath(), deviceSymInfo.libSymbol.release(), &properties );
569 symbolsSavedViaDevices.insert( *symbolAttr );
570 }
571
572 // Keep geometry-only entries for symbols not referenced by any device (e.g. some helpers).
573 for( auto& [symbolUuid, symInfo] : symbols )
574 {
575 if( !symInfo.libSymbol || symbolsSavedViaDevices.contains( symbolUuid ) )
576 continue;
577
578 wxString itemName = EASYEDAPRO::MakeUniqueLibName( usedLibNames, symInfo.libSymbol->GetName(),
579 symbolUuid );
580 LIB_ID libID = EASYEDAPRO::ToKiCadLibID( libName, itemName );
581 symInfo.libSymbol->SetLibId( libID );
582 symInfo.libSymbol->SetName( itemName );
583
584 schPlugin->SaveSymbol( libFileName.GetFullPath(), symInfo.libSymbol.release(), &properties );
585 }
586
587 schPlugin->SaveLibrary( libFileName.GetFullPath() );
588
590 aSchematic->FixupJunctionsAfterImport();
591
592 if( v3.GetSkippedCount() > 0 )
593 {
594 wxLogWarning( wxString::Format( _( "EasyEDA (JLCEDA) Pro v3 import skipped %d unsupported object(s)." ),
595 v3.GetSkippedCount() ) );
596 }
597
598 return rootSheet;
599}
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
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
Definition io_base.h:237
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:44
std::optional< LIBRARY_TABLE * > ProjectTable() const
Retrieves the project library table for this adapter type, or nullopt if one doesn't exist.
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
void SetURI(const wxString &aUri)
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.
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
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.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition schematic.h:105
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::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.
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.
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
SCH_IO(const wxString &aName)
Definition sch_io.h:375
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.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib) override
Loads or reloads the given library, if it exists.
static REPORTER & GetInstance()
Definition reporter.cpp:279
#define _(s)
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
#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
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).
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.
std::vector< std::vector< std::string > > table
VECTOR2I v3(-2, 1)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
Definition of file extensions used in Kicad.