36#include <wx/txtstrm.h>
37#include <wx/wfstream.h>
38#include <wx/mstream.h>
39#include <wx/zipstrm.h>
57 std::map<wxString, EASYEDAPRO::BLOB>
m_Blobs;
76 if( aFileName.Lower().EndsWith( wxS(
".epro" ) ) )
80 else if( aFileName.Lower().EndsWith( wxS(
".zip" ) ) )
82 std::shared_ptr<wxZipEntry> entry;
83 wxFFileInputStream in( aFileName );
84 wxZipInputStream
zip( in );
89 while( entry.reset(
zip.GetNextEntry() ), entry.get() != NULL )
91 wxString
name = entry->GetName();
93 if(
name == wxS(
"project.json" ) )
111 const wxString& aAliasName,
const std::map<std::string, UTF8>* aProperties )
115 wxFileName libFname( aLibraryPath );
146 if( libFname.GetExt() == wxS(
"elibz" ) || libFname.GetExt() == wxS(
"epro" )
147 || libFname.GetExt() == wxS(
"zip" ) )
149 std::map<wxString, EASYEDAPRO::PRJ_SYMBOL> prjSymbols =
project.at(
"symbols" );
150 std::map<wxString, EASYEDAPRO::PRJ_FOOTPRINT> prjFootprints;
151 std::map<wxString, EASYEDAPRO::PRJ_DEVICE> prjDevices;
153 if(
project.contains(
"footprints" ) )
154 prjFootprints =
project.at(
"footprints" );
156 if(
project.contains(
"devices" ) )
157 prjDevices =
project.at(
"devices" );
159 auto prjSymIt = std::find_if( prjSymbols.begin(), prjSymbols.end(),
160 [&](
const auto& pair )
162 return pair.second.title == aAliasName;
165 if( prjSymIt == prjSymbols.end() )
168 wxString prjSymUuid = prjSymIt->first;
170 wxString description;
172 std::map<wxString, wxString> deviceAttributes;
175 for(
auto& [key, device] : prjDevices )
177 auto val =
get_opt( device.attributes,
"Symbol" );
179 if( val && *val == prjSymUuid )
181 description = device.description;
182 deviceAttributes = device.attributes;
184 if( device.custom_tags.is_string() )
185 customTags = device.custom_tags.get<wxString>();
187 if(
auto fpUuid =
get_opt( device.attributes,
"Footprint" ) )
189 if(
auto prjFp =
get_opt( prjFootprints, *fpUuid ) )
191 fpTitle = prjFp->title;
198 auto cb = [&](
const wxString&
name,
const wxString& symUuid, wxInputStream&
zip ) ->
bool
200 if( !
name.EndsWith( wxS(
".esym" ) ) )
203 if( symUuid != prjSymUuid )
206 wxTextInputStream txt(
zip, wxS(
" " ), wxConvUTF8 );
208 std::vector<nlohmann::json> lines;
209 while(
zip.CanRead() )
211 nlohmann::json js = nlohmann::json::parse( txt.ReadLine() );
212 lines.emplace_back( js );
225 wxString keywords = customTags;
226 keywords.Replace( wxS(
":" ), wxS(
" " ),
true );
230 description.Replace( wxS(
"\u2103" ), wxS(
"\u00B0C" ),
true );
246 const wxString& aLibraryPath,
247 const std::map<std::string, UTF8>* aProperties )
249 wxFileName fname( aLibraryPath );
251 if( fname.GetExt() == wxS(
"esym" ) )
253 wxFFileInputStream ffis( aLibraryPath );
254 wxTextInputStream txt( ffis, wxS(
" " ), wxConvUTF8 );
256 while( ffis.CanRead() )
258 wxString line = txt.ReadLine();
260 if( !line.Contains( wxS(
"ATTR" ) ) )
263 nlohmann::json js = nlohmann::json::parse( line );
264 if( js.at( 0 ) ==
"ATTR" && js.at( 3 ) ==
"Symbol" )
266 aSymbolNameList.Add( js.at( 4 ).get<wxString>() );
270 else if( fname.GetExt() == wxS(
"elibz" ) || fname.GetExt() == wxS(
"epro" )
271 || fname.GetExt() == wxS(
"zip" ) )
274 std::map<wxString, nlohmann::json> symbolMap =
project.at(
"symbols" );
276 for(
auto& [key, value] : symbolMap )
280 if( value.contains(
"display_title" ) )
281 title = value.at(
"display_title" ).get<wxString>();
283 title = value.at(
"title" ).get<wxString>();
285 aSymbolNameList.Add( title );
292 const wxString& aLibraryPath,
293 const std::map<std::string, UTF8>* aProperties )
295 wxFileName libFname( aLibraryPath );
296 wxArrayString symbolNameList;
301 if( libFname.GetExt() == wxS(
"elibz" ) || libFname.GetExt() == wxS(
"epro" )
302 || libFname.GetExt() == wxS(
"zip" ) )
307 for(
const wxString& symbolName : symbolNameList )
312 aSymbolList.push_back( sym );
325 wxFileName fname( aProjectPath );
328 if( fname.GetExt() != wxS(
"epro" ) && fname.GetExt() != wxS(
"zip" ) )
333 std::map<wxString, EASYEDAPRO::PRJ_SYMBOL> prjSymbols =
project.at(
"symbols" );
334 std::map<wxString, EASYEDAPRO::PRJ_FOOTPRINT> prjFootprints =
project.at(
"footprints" );
335 std::map<wxString, EASYEDAPRO::PRJ_DEVICE> prjDevices =
project.at(
"devices" );
337 auto cb = [&](
const wxString&
name,
const wxString& baseName, wxInputStream&
zip ) ->
bool
339 if( !
name.EndsWith( wxS(
".esym" ) ) && !
name.EndsWith( wxS(
".eblob" ) ) )
344 if(
name.EndsWith( wxS(
".esym" ) ) )
346 wxString description;
348 std::map<wxString, wxString> deviceAttributes;
351 for(
auto& [key, device] : prjDevices )
353 auto val =
get_opt( device.attributes,
"Symbol" );
355 if( val && *val == baseName )
357 description = device.description;
358 deviceAttributes = device.attributes;
360 if( device.custom_tags.is_string() )
361 customTags = device.custom_tags.get<wxString>();
363 if(
auto fpUuid =
get_opt( device.attributes,
"Footprint" ) )
365 if(
auto prjFp =
get_opt( prjFootprints, *fpUuid ) )
367 fpTitle = prjFp->title;
385 wxString keywords = customTags;
386 keywords.Replace( wxS(
":" ), wxS(
" " ),
true );
390 description.Replace( wxS(
"\u2103" ), wxS(
"\u00B0C" ),
true );
394 m_projectData->m_Symbols.emplace( baseName, std::move( symInfo ) );
396 else if(
name.EndsWith( wxS(
".eblob" ) ) )
398 for(
const nlohmann::json& line : lines )
400 if( line.at( 0 ) ==
"BLOB" )
415 const std::map<std::string, UTF8>* aProperties )
417 wxFileName libFname( aLibraryPath );
420 if( libFname.GetExt() == wxS(
"elibz" ) || libFname.GetExt() == wxS(
"epro" )
421 || libFname.GetExt() == wxS(
"zip" ) )
432 const std::map<std::string, UTF8>* aProperties )
434 wxCHECK( !aFileName.IsEmpty() && aSchematic,
nullptr );
443 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
444 wxS(
"Can't append to a schematic with no root!" ) );
446 rootSheet = aAppendToMe;
467 wxFileName fname( aFileName );
472 if( fname.GetExt() != wxS(
"epro" ) && fname.GetExt() != wxS(
"zip" ) )
477 std::map<wxString, EASYEDAPRO::PRJ_SCHEMATIC> prjSchematics =
project.at(
"schematics" );
479 wxString schematicToLoad;
481 if( aProperties && aProperties->contains(
"sch_id" ) )
483 schematicToLoad = wxString::FromUTF8( aProperties->at(
"sch_id" ) );
487 if( prjSchematics.size() == 1 )
489 schematicToLoad = prjSchematics.begin()->first;
496 if( chosen.size() > 0 )
497 schematicToLoad = chosen[0].SchematicId;
501 if( schematicToLoad.empty() )
506 wxFileName rootFname( aFileName );
507 rootFname.SetFullName( rootBaseName + wxS(
"." )
510 rootSheet->
SetName( prjSchematics[schematicToLoad].
name );
514 const std::vector<EASYEDAPRO::PRJ_SHEET>& prjSchematicSheets =
515 prjSchematics[schematicToLoad].sheets;
522 const int schSheetsCount = prjSchematicSheets.size();
524 auto cbs = [&](
const wxString&
name,
const wxString& baseName, wxInputStream&
zip ) ->
bool
526 if( !
name.EndsWith( wxS(
".esch" ) ) )
529 wxArrayString nameParts = wxSplit(
name,
'\\',
'\0' );
531 if( nameParts.size() == 1 )
532 nameParts = wxSplit(
name,
'/',
'\0' );
534 if( nameParts.size() < 3 )
537 wxString schematicUuid = nameParts[1];
538 wxString sheetFileName = nameParts[2];
539 wxString sheetId = sheetFileName.BeforeLast(
'.' );
541 sheetId.ToInt( &sheetId_i );
543 if( schematicUuid != schematicToLoad )
546 auto prjSheetIt = std::find_if( prjSchematicSheets.begin(), prjSchematicSheets.end(),
549 return s.id == sheetId_i;
552 if( prjSheetIt == prjSchematicSheets.end() )
557 if( schSheetsCount > 1 )
559 wxString sheetBaseName =
562 wxFileName sheetFname( aFileName );
563 sheetFname.SetFullName( sheetBaseName + wxS(
"." )
566 wxFileName relSheetPath( sheetFname );
567 relSheetPath.MakeRelativeTo( rootFname.GetPath() );
569 std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
570 subSheet->SetFileName( relSheetPath.GetFullPath() );
571 subSheet->SetName( prjSheetIt->name );
576 subSheet->SetScreen( screen );
581 + ( subSheet->GetSize().y +
schIUScale.MilsToIU( 200 ) ) * ( sheetId_i - 1 );
583 subSheet->SetPosition( pos );
610 wxCHECK_MSG(
table,
nullptr,
"Could not load symbol lib table." );
612 if( !
table->HasRow( libName ) )
615 sch_plugin->CreateLibrary( libFileName.GetFullPath() );
616 wxString libTableUri = wxS(
"${KIPRJMOD}/" ) + libFileName.GetFullName();
621 row.
SetURI( libTableUri );
630 std::map<std::string, UTF8> properties;
633 for(
auto& [symbolUuid, symInfo] :
m_projectData->m_Symbols )
634 sch_plugin->SaveSymbol( libFileName.GetFullPath(), symInfo.libSymbol.release(),
637 sch_plugin->SaveLibrary( libFileName.GetFullPath() );
constexpr EDA_IU_SCALE schIUScale
void SetPageNumber(const wxString &aPageNumber)
RAII class to set and restore the fontconfig reporter.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
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.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
SCH_FIELD & GetFootprintField()
Return reference to the footprint field.
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()
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.
void SetCurrentSheet(const SCH_SHEET_PATH &aPath)
PROJECT & Project() const
Return a reference to the project this schematic is part of.
void FixupJunctionsAfterImport()
Add junctions to this schematic where required.
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
EASYEDAPRO::SYM_INFO ParseSymbol(const std::vector< nlohmann::json > &aLines, const std::map< wxString, wxString > &aDeviceAttributes)
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 std::vector< nlohmann::json > &aLines, const wxString &aLibName)
void SetText(const wxString &aText) override
void LoadAllDataFromProject(const wxString &aLibraryPath)
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...
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.
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,...
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)
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)
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
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()
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.
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
LIB_ID ToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
void IterateZipFiles(const wxString &aFileName, std::function< bool(const wxString &, const wxString &, wxInputStream &)> aCallback)
std::vector< nlohmann::json > ParseJsonLines(wxInputStream &aInput, const wxString &aSource)
std::vector< IMPORT_PROJECT_DESC > ProjectToSelectorDialog(const nlohmann::json &aProject, bool aPcbOnly=false, bool aSchOnly=false)
nlohmann::json ReadProjectOrDeviceFile(const wxString &aZipFileName)
wxString ShortenLibName(wxString aProjectName)
LIB_SYMBOL * loadSymbol(const wxString &aLibraryPath, nlohmann::json aFileData, const wxString &aAliasName, const std::map< std::string, UTF8 > *aProperties)
static LIB_SYMBOL * loadSymbol(nlohmann::json project, const wxString &aLibraryPath, const wxString &aAliasName, const std::map< std::string, UTF8 > *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::unique_ptr< LIB_SYMBOL > libSymbol
std::map< wxString, EASYEDAPRO::BLOB > m_Blobs
std::map< wxString, EASYEDAPRO::SYM_INFO > m_Symbols
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.