47#include <compoundfilereader.h>
52 const std::vector<ALTIUM_PROJECT_VARIANT>& aVariants )
54 std::map<wxString, FOOTPRINT*> fpByRef;
55 std::map<KIID, std::vector<FOOTPRINT*>> fpByUid;
59 fpByRef[fp->GetReference()] = fp;
65 if(
path.size() >= 2 )
66 fpByUid[
path.back()].push_back( fp );
73 if( !pv.description.empty() && pv.description != pv.name )
86 if( it != fpByUid.end() && it->second.size() == 1 )
87 target = it->second.front();
94 if( it != fpByRef.end() )
106 if( entry.
kind == 1 )
108 fpVariant->
SetDNP(
true );
112 else if( entry.
kind == 0 )
116 if( key.CmpNoCase( wxS(
"LibReference" ) ) == 0 )
118 else if( key.CmpNoCase( wxS(
"Description" ) ) == 0 )
120 else if( key.CmpNoCase( wxS(
"Footprint" ) ) == 0 )
129 const std::map<wxString, wxString>& aParameters )
137 static const std::set<wxString> reserved = {
138 wxS(
"LAYER" ), wxS(
"FILENAME" ), wxS(
"FILEPATH" ),
139 wxS(
"PROJECTNAME" ), wxS(
"VARIANT" ), wxS(
"VARIANT_DESC" ),
140 wxS(
"ISSUE_DATE" ), wxS(
"CURRENT_DATE" ), wxS(
"CURRENT_TIME_LOCALE" ),
141 wxS(
"CURRENT_TIME_HH_MM_SS" ), wxS(
"REVISION" ), wxS(
"TITLE" ),
142 wxS(
"COMPANY" ), wxS(
"COMMENT1" ), wxS(
"COMMENT2" ),
143 wxS(
"COMMENT3" ), wxS(
"COMMENT4" ), wxS(
"COMMENT5" ),
144 wxS(
"COMMENT6" ), wxS(
"COMMENT7" ), wxS(
"COMMENT8" ),
145 wxS(
"COMMENT9" ), wxS(
"VCSHASH" ), wxS(
"VCSSHORTHASH" ),
146 wxS(
"KICAD_VERSION" ), wxS(
"PAPER" ), wxS(
"SHEETNAME" ),
147 wxS(
"SHEETPATH" ), wxS(
"DRC_WARNING" ), wxS(
"DRC_ERROR" ),
148 wxS(
"ERC_WARNING" ), wxS(
"ERC_ERROR" )
151 std::map<wxString, wxString>& textVars = aProject->
GetTextVars();
154 for(
const auto& [
name, value] : aParameters )
156 if( reserved.count(
name ) )
160 if( textVars.count(
name ) )
163 textVars[
name] = value;
173 PCB_IO( wxS(
"Altium Designer" ) )
187 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
189 std::map<wxString, PCB_LAYER_ID> retval;
194 retval.insert( { layerDesc.Name, layerDesc.AutoMapLayer } );
227 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
239 m_board->SetFileName( aFileName );
242 const std::map<ALTIUM_PCB_DIR, std::string> mapping = {
273 pcb.
Parse( altiumPcbFile, mapping );
275 catch( CFB::CFBException& exception )
282 const wxString& projectFile =
m_props->at(
"project_file" );
286 if( !variants.empty() )
300 if( aLibraryPath.IsEmpty() )
303 wxFileName fn( aLibraryPath );
305 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
306 return fn.GetModificationTime().GetValue().GetValue();
326 if( aLibraryPath.Lower().EndsWith( wxS(
".pcblib" ) ) )
328 libFiles.
m_Files.emplace_back( std::make_unique<ALTIUM_PCB_COMPOUND_FILE>( aLibraryPath ) );
330 else if( aLibraryPath.Lower().EndsWith( wxS(
".intlib" ) ) )
332 std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE> lib = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>( aLibraryPath );
334 for(
const auto& [pcbLibName, pcbCfe] : lib->EnumDir(
L"PCBLib" ) )
336 std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE> libFile = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>();
338 if( lib->DecodeIntLibStream( *pcbCfe, libFile.get() ) )
339 libFiles.
m_Files.emplace_back( std::move( libFile ) );
345 catch( CFB::CFBException& exception )
353 const wxString& aLibraryPath,
bool aBestEfforts,
354 const std::map<std::string, UTF8>* aProperties )
363 for( std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>& altiumLibFile :
m_fplibFiles[aLibraryPath].m_Files )
368 const std::vector<std::string> streamName = {
"Library",
"Data" };
369 const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile->FindStream( streamName );
371 if( libraryData ==
nullptr )
379 std::map<wxString, wxString> properties = parser.
ReadProperties();
381 uint32_t numberOfFootprints = parser.
Read<uint32_t>();
390 bool footprintListNotTruncated =
true;
392 if ( patternMap.size() < numberOfFootprints )
394 numberOfFootprints = patternMap.size();
395 footprintListNotTruncated =
false;
398 aFootprintNames.Alloc( numberOfFootprints );
400 for(
size_t i = 0; i < numberOfFootprints; i++ )
405 wxString fpPattern( charBuffer, wxConvISO8859_1 );
407 auto it = patternMap.find( fpPattern );
409 if( it != patternMap.end() )
411 aFootprintNames.Add( it->second );
415 THROW_IO_ERROR( wxString::Format(
"Component name not found: '%s'", fpPattern ) );
423 THROW_IO_ERROR( wxString::Format(
"%s stream was not parsed correctly",
429 THROW_IO_ERROR( wxString::Format(
"%s stream is not fully parsed",
434 catch( CFB::CFBException& exception )
442 const wxString& aFootprintName,
bool aKeepUUID,
443 const std::map<std::string, UTF8>* aProperties )
448 THROW_IO_ERROR( wxString::Format(
_(
"No footprints in library '%s'" ), aLibraryPath ) );
452 for( std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>& altiumLibFile :
m_fplibFiles[aLibraryPath].m_Files )
454 altiumLibFile->CacheLibModels();
455 auto [dirName, fpCfe] = altiumLibFile->FindLibFootprintDirName( aFootprintName );
457 if( dirName.IsEmpty() )
465 catch( CFB::CFBException& exception )
470 THROW_IO_ERROR( wxString::Format(
_(
"Footprint '%s' not found in '%s'." ),
478 std::vector<FOOTPRINT*> footprints;
481 footprints.push_back( fp );
std::string FormatPath(const std::vector< std::string > &aVectorPath)
Helper for debug logging (vector -> string)
@ EXTENDPRIMITIVEINFORMATION
std::vector< ALTIUM_PROJECT_VARIANT > ParseAltiumProjectVariants(const wxString &aPrjPcbPath)
Parse all [ProjectVariantN] sections from an Altium .PrjPcb project file.
std::map< wxString, wxString > ParseAltiumProjectParameters(const wxString &aPrjPcbPath)
Parse all [ParameterN] sections from an Altium .PrjPcb project file.
KIID AltiumUniqueIdToKiid(const wxString &aUniqueId)
Derive a stable KIID from an Altium component unique id.
std::map< wxString, ValueType, DETAIL::CASE_INSENSITIVE_COMPARER > CASE_INSENSITIVE_MAP
size_t GetRemainingBytes() const
wxScopedCharBuffer ReadCharBuffer()
size_t ReadAndSetSubrecordLength()
std::map< wxString, wxString > ReadProperties(std::function< std::map< wxString, wxString >(const std::string &)> handleBinaryData=[](const std::string &) { return std::map< wxString, wxString >();})
FOOTPRINT * ParseFootprint(ALTIUM_PCB_COMPOUND_FILE &altiumLibFile, const wxString &aFootprintName)
void Parse(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const std::map< ALTIUM_PCB_DIR, std::string > &aFileMapping)
Information pertinent to a Pcbnew printed circuit board.
void AddVariant(const wxString &aVariantName)
const FOOTPRINTS & Footprints() const
void SetVariantDescription(const wxString &aVariantName, const wxString &aDescription)
RAII class to set and restore the fontconfig reporter.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
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.
virtual void RegisterCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
static LOAD_INFO_REPORTER & GetInstance()
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
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...
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.
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
~PCB_IO_ALTIUM_DESIGNER()
static bool checkFileHeader(const wxString &aFileName)
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
void loadAltiumLibrary(const wxString &aLibraryPath)
static std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
std::map< wxString, ALTIUM_FILE_CACHE > m_fplibFiles
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
BOARD * m_board
The board BOARD being worked on, no ownership here.
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
PCB_IO(const wxString &aName)
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
Container for project specific data.
void IncrementTextVarsTicker()
virtual std::map< wxString, wxString > & GetTextVars() const
static REPORTER & GetInstance()
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
const std::vector< uint8_t > COMPOUND_FILE_HEADER
bool fileHasBinaryHeader(const wxString &aFilePath, const std::vector< uint8_t > &aHeader, size_t aOffset)
Check if a file starts with a defined binary header.
void ApplyAltiumProjectVariantsToBoard(BOARD *aBoard, const std::vector< ALTIUM_PROJECT_VARIANT > &aVariants)
Pcbnew PLUGIN for Altium *.PcbDoc format.
void ApplyAltiumProjectParametersToProject(PROJECT *aProject, const std::map< wxString, wxString > &aParameters)
Register Altium project parameters as KiCad project text variables so that imported board text refere...
void ApplyAltiumProjectVariantsToBoard(BOARD *aBoard, const std::vector< ALTIUM_PROJECT_VARIANT > &aVariants)
Apply parsed Altium project variants to a board by setting FOOTPRINT_VARIANT data on each footprint w...
void ApplyAltiumProjectParametersToProject(PROJECT *aProject, const std::map< wxString, wxString > &aParameters)
Register Altium project parameters as KiCad project text variables so that imported board text refere...
A project-level assembly variant parsed from an Altium .PrjPcb file.
A single component variation within an Altium project variant.
std::map< wxString, wxString > alternateFields
std::vector< std::unique_ptr< ALTIUM_PCB_COMPOUND_FILE > > m_Files