41#include <wx/filename.h>
46 PCB_IO( wxS(
"EasyEDA (JLCEDA) Pro v3" ) )
87 wxFileName fileName( aLibraryPath );
89 if( !fileName.FileExists() )
92 wxDateTime modified = fileName.GetModificationTime();
94 if( !modified.IsValid() )
97 return modified.GetTicks();
102 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
106 std::map<wxString, wxString> footprintMap =
109 for(
const auto& [
name, uuid] : footprintMap )
110 aFootprintNames.Add(
name );
116 std::vector<FOOTPRINT*>
result;
128 bool aKeepUUID,
const std::map<std::string, UTF8>* aProperties )
134 std::map<wxString, wxString> footprintMap =
137 auto fpIt = footprintMap.find( aFootprintName );
139 if( fpIt == footprintMap.end() )
147 const nlohmann::json&
index =
v3.GetLibraryIndex();
156 catch( nlohmann::json::exception& e )
158 THROW_IO_ERRORF(
_(
"Cannot load footprint '%s' from '%s': %s" ), aFootprintName, aLibraryPath, e.what() );
162 THROW_IO_ERRORF(
_(
"Cannot load footprint '%s' from '%s'" ), aFootprintName, aLibraryPath );
165 if(
index.contains(
"devices" ) &&
index.at(
"devices" ).is_object() )
167 for(
const auto& [devUuid, deviceJson] :
index.at(
"devices" ).items() )
169 if( !deviceJson.is_object() || !deviceJson.contains(
"attributes" )
170 || !deviceJson.at(
"attributes" ).is_object() )
175 const nlohmann::json& attrs = deviceJson.at(
"attributes" );
177 if( !attrs.contains(
"Footprint" )
185 wxString modelTransform;
187 if( attrs.contains(
"3D Model" ) )
190 if( attrs.contains(
"3D Model Title" ) )
193 modelTitle = modelUuid;
195 if( attrs.contains(
"3D Model Transform" ) )
216 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
223 m_board->SetFileName( aFileName );
244 pcbToLoad = wxString::FromUTF8(
m_props->at(
"pcb_id" ) );
248 std::map<wxString, nlohmann::json> prjPcbs =
project.at(
"pcbs" );
250 if( prjPcbs.size() == 1 )
252 pcbToLoad = prjPcbs.begin()->first;
256 std::vector<IMPORT_PROJECT_DESC> chosen =
259 if( !chosen.empty() )
260 pcbToLoad = chosen[0].PCBId;
262 else if( !prjPcbs.empty() )
264 pcbToLoad = prjPcbs.begin()->first;
268 if( pcbToLoad.empty() )
275 wxFileName sourceName( aFileName );
280 std::map<wxString, std::unique_ptr<FOOTPRINT>> footprints;
281 std::set<wxString> usedLibNames;
283 for(
const auto& [uuid, rawDoc] : adapter.
GetRawDocs( wxS(
"FOOTPRINT" ) ) )
285 std::unique_ptr<FOOTPRINT> footprint( parser.
ParseFootprint( blobs, rawDoc ) );
290 std::string uuidKey = std::string( uuid.ToUTF8() );
291 const nlohmann::json& fpMetas =
project.at(
"footprints" );
292 wxString fpTitle = uuid;
294 if( fpMetas.contains( uuidKey ) )
299 footprints.emplace( uuid, std::move( footprint ) );
305 THROW_IO_ERRORF(
_(
"PCB document '%s' not found in '%s'" ), pcbToLoad, aFileName );
307 std::multimap<wxString, EASYEDAPRO::POURED> poured;
314 for(
auto& [uuid, footprint] : footprints )
322 Report( wxString::Format(
_(
"EasyEDA (JLCEDA) Pro v3 import skipped %d unsupported object(s)." ),
Information pertinent to a Pcbnew printed circuit board.
Parses EasyEDA Pro v3 .epro2 archives.
void Load()
Load all v3 docs from the archive.
const V3_DOC_RAW * FindRawDoc(const wxString &aDocType, const wxString &aUuid) const
const std::map< wxString, V3_DOC_RAW > & GetRawDocs(const wxString &aDocType) const
static bool IsV3Library(const wxString &aFileName, const wxString &aRequiredDocType=wxEmptyString)
Return true if aFileName looks like an EasyEDA Pro v3 library archive.
int GetSkippedCount() const
static bool IsV3Archive(const wxString &aFileName)
Return true if aFileName looks like an EasyEDA Pro v3 archive.
virtual void SetVisible(bool aVisible)
virtual void SetText(const wxString &aText)
RAII class to set and restore the fontconfig reporter.
virtual void Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) const
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
static LOAD_INFO_REPORTER & GetInstance()
void FillFootprintModelInfo(FOOTPRINT *footprint, const wxString &modelUuid, const wxString &modelTitle, const wxString &modelTransform) const
void ParseBoard(BOARD *aBoard, const nlohmann::json &aProject, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap, const std::multimap< wxString, EASYEDAPRO::POURED > &aPouredMap, const EASYEDAPRO::V3_DOC_RAW &aDoc, const wxString &aFpLibName)
FOOTPRINT * ParseFootprint(const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap, const EASYEDAPRO::V3_DOC_RAW &aDoc)
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
std::unique_ptr< EASYEDAPRO::V3_DOC_PARSER > m_cachedLibraryParser
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
~PCB_IO_EASYEDAPRO_V3() override
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
wxString m_cachedLibraryPath
std::vector< std::unique_ptr< FOOTPRINT > > m_importedLibFootprints
Definitions from the last LoadBoard, cloned out to the import reconciler on request.
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
const EASYEDAPRO::V3_DOC_PARSER & getCachedLibraryParser(const wxString &aLibraryPath) const
long long m_cachedLibraryTimestamp
FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
BOARD * m_board
The board BOARD being worked on, no ownership here.
PCB_IO(const wxString &aName)
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
CHOOSE_PROJECT_HANDLER m_choose_project_handler
Callback to choose projects to import.
Container for project specific data.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_ERRORF(msg,...)
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 GetV3LibraryItemTitle(const nlohmann::json &aMetadata, const wxString &aUuid)
std::vector< IMPORT_PROJECT_DESC > ProjectToSelectorDialog(const nlohmann::json &aProject, bool aPcbOnly=false, bool aSchOnly=false)
wxString ShortenLibName(wxString aProjectName)
wxString V3JsonToString(const nlohmann::json &aValue, const wxString &aDefault)
std::map< wxString, wxString > BuildV3LibraryItemMap(const V3_DOC_PARSER &aParser, const char *aIndexKey, const wxString &aDocType)
std::map< wxString, BLOB > BuildV3BlobMap(const V3_DOC_PARSER &aParser)
Raw parsed document from an EasyEDA Pro v3 .epru stream.
wxString result
Test unit parsing edge cases and error handling.