43#include <compoundfilereader.h>
48 const std::vector<ALTIUM_PROJECT_VARIANT>& aVariants )
50 std::map<wxString, FOOTPRINT*> fpByRef;
51 std::map<KIID, std::vector<FOOTPRINT*>> fpByUid;
55 fpByRef[fp->GetReference()] = fp;
61 if(
path.size() >= 2 )
62 fpByUid[
path.back()].push_back( fp );
69 if( !pv.description.empty() && pv.description != pv.name )
82 if( it != fpByUid.end() && it->second.size() == 1 )
83 target = it->second.front();
90 if( it != fpByRef.end() )
102 if( entry.
kind == 1 )
104 fpVariant->
SetDNP(
true );
108 else if( entry.
kind == 0 )
112 if( key.CmpNoCase( wxS(
"LibReference" ) ) == 0 )
114 else if( key.CmpNoCase( wxS(
"Description" ) ) == 0 )
116 else if( key.CmpNoCase( wxS(
"Footprint" ) ) == 0 )
125 const std::map<wxString, wxString>& aParameters )
133 static const std::set<wxString> reserved = {
134 wxS(
"LAYER" ), wxS(
"FILENAME" ), wxS(
"FILEPATH" ),
135 wxS(
"PROJECTNAME" ), wxS(
"VARIANT" ), wxS(
"VARIANT_DESC" ),
136 wxS(
"ISSUE_DATE" ), wxS(
"CURRENT_DATE" ), wxS(
"CURRENT_TIME_LOCALE" ),
137 wxS(
"CURRENT_TIME_HH_MM_SS" ), wxS(
"REVISION" ), wxS(
"TITLE" ),
138 wxS(
"COMPANY" ), wxS(
"COMMENT1" ), wxS(
"COMMENT2" ),
139 wxS(
"COMMENT3" ), wxS(
"COMMENT4" ), wxS(
"COMMENT5" ),
140 wxS(
"COMMENT6" ), wxS(
"COMMENT7" ), wxS(
"COMMENT8" ),
141 wxS(
"COMMENT9" ), wxS(
"VCSHASH" ), wxS(
"VCSSHORTHASH" ),
142 wxS(
"KICAD_VERSION" ), wxS(
"PAPER" ), wxS(
"SHEETNAME" ),
143 wxS(
"SHEETPATH" ), wxS(
"DRC_WARNING" ), wxS(
"DRC_ERROR" ),
144 wxS(
"ERC_WARNING" ), wxS(
"ERC_ERROR" )
147 std::map<wxString, wxString>& textVars = aProject->
GetTextVars();
150 for(
const auto& [
name, value] : aParameters )
152 if( reserved.count(
name ) )
156 if( textVars.count(
name ) )
159 textVars[
name] = value;
169 PCB_IO( wxS(
"Altium Designer" ) )
183 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
185 std::map<wxString, PCB_LAYER_ID> retval;
190 retval.insert( { layerDesc.Name, layerDesc.AutoMapLayer } );
223 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
235 m_board->SetFileName( aFileName );
238 const std::map<ALTIUM_PCB_DIR, std::string> mapping = {
270 pcb.
Parse( altiumPcbFile, mapping );
272 catch( CFB::CFBException& exception )
279 const wxString& projectFile =
m_props->at(
"project_file" );
283 if( !variants.empty() )
297 if( aLibraryPath.IsEmpty() )
300 wxFileName fn( aLibraryPath );
302 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
303 return fn.GetModificationTime().GetValue().GetValue();
323 if( aLibraryPath.Lower().EndsWith( wxS(
".pcblib" ) ) )
325 libFiles.
m_Files.emplace_back( std::make_unique<ALTIUM_PCB_COMPOUND_FILE>( aLibraryPath ) );
327 else if( aLibraryPath.Lower().EndsWith( wxS(
".intlib" ) ) )
329 std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE> lib = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>( aLibraryPath );
331 for(
const auto& [pcbLibName, pcbCfe] : lib->EnumDir(
L"PCBLib" ) )
333 std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE> libFile = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>();
335 if( lib->DecodeIntLibStream( *pcbCfe, libFile.get() ) )
336 libFiles.
m_Files.emplace_back( std::move( libFile ) );
342 catch( CFB::CFBException& exception )
350 const wxString& aLibraryPath,
bool aBestEfforts,
351 const std::map<std::string, UTF8>* aProperties )
360 for( std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>& altiumLibFile :
m_fplibFiles[aLibraryPath].m_Files )
365 const std::vector<std::string> streamName = {
"Library",
"Data" };
366 const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile->FindStream( streamName );
368 if( libraryData ==
nullptr )
376 std::map<wxString, wxString> properties = parser.
ReadProperties();
378 uint32_t numberOfFootprints = parser.
Read<uint32_t>();
387 bool footprintListNotTruncated =
true;
389 if ( patternMap.size() < numberOfFootprints )
391 numberOfFootprints = patternMap.size();
392 footprintListNotTruncated =
false;
395 aFootprintNames.Alloc( numberOfFootprints );
397 for(
size_t i = 0; i < numberOfFootprints; i++ )
402 wxString fpPattern( charBuffer, wxConvISO8859_1 );
404 auto it = patternMap.find( fpPattern );
406 if( it != patternMap.end() )
408 aFootprintNames.Add( it->second );
412 THROW_IO_ERROR( wxString::Format(
"Component name not found: '%s'", fpPattern ) );
420 THROW_IO_ERROR( wxString::Format(
"%s stream was not parsed correctly",
426 THROW_IO_ERROR( wxString::Format(
"%s stream is not fully parsed",
431 catch( CFB::CFBException& exception )
439 const wxString& aFootprintName,
bool aKeepUUID,
440 const std::map<std::string, UTF8>* aProperties )
445 THROW_IO_ERROR( wxString::Format(
_(
"No footprints in library '%s'" ), aLibraryPath ) );
449 for( std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>& altiumLibFile :
m_fplibFiles[aLibraryPath].m_Files )
451 altiumLibFile->CacheLibModels();
452 auto [dirName, fpCfe] = altiumLibFile->FindLibFootprintDirName( aFootprintName );
454 if( dirName.IsEmpty() )
462 catch( CFB::CFBException& exception )
467 THROW_IO_ERROR( wxString::Format(
_(
"Footprint '%s' not found in '%s'." ),
475 std::vector<FOOTPRINT*> footprints;
478 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