Import Altium Projects

Handle Altium project file format

Parse individual schematic files and layout files
Create top-level schematic file
Link imported UUIDs between schematic symbol and footprints based on
refdes
Create KiCad project
Map Altium layout layers between KiCad

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2117
This commit is contained in:
Seth Hillbrand 2024-08-23 09:54:00 -07:00
parent 320a298394
commit e81956f292
24 changed files with 369 additions and 19 deletions

View File

@ -284,6 +284,12 @@ wxString FILEEXT::KiCadSchematicFileWildcard()
}
wxString FILEEXT::AltiumProjectFilesWildcard()
{
return _( "Altium Project files" ) + AddFileExtListToFilter( { "PrjPcb" } );
}
wxString FILEEXT::CadstarArchiveFilesWildcard()
{
return _( "CADSTAR Archive files" ) + AddFileExtListToFilter( { "csa", "cpa" } );

View File

@ -24,6 +24,7 @@
*/
#include <kiface_base.h>
#include <kiway.h>
#include <kiway_express.h>
#include <eda_dde.h>
#include <connection_graph.h>
@ -34,7 +35,9 @@
#include <netlist_exporters/netlist_exporter_kicad.h>
#include <project/project_file.h>
#include <project/net_settings.h>
#include <project_sch.h>
#include <richio.h>
#include <symbol_lib_table.h>
#include <tools/ee_actions.h>
#include <tools/sch_editor_control.h>
#include <advanced_config.h>
@ -835,6 +838,55 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
switch( mail.Command() )
{
case MAIL_ADD_LOCAL_LIB:
{
std::stringstream ss( payload );
std::string file;
SYMBOL_LIB_TABLE* symLibTbl = PROJECT_SCH::SchSymbolLibTable( &Prj() );
wxCHECK_RET( symLibTbl, "Could not load symbol lib table." );
while( std::getline( ss, file, '\n' ) )
{
if( file.empty() )
continue;
wxFileName fn( file );
IO_RELEASER<SCH_IO> pi;
SCH_IO_MGR::SCH_FILE_T type = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
if( type == SCH_IO_MGR::SCH_FILE_UNKNOWN )
{
wxLogTrace( "KIWAY", "Unknown file type: %s", fn.GetFullPath() );
continue;
}
pi.reset( SCH_IO_MGR::FindPlugin( type ) );
if( !symLibTbl->HasLibrary( fn.GetName() ) )
{
symLibTbl->InsertRow( new SYMBOL_LIB_TABLE_ROW( fn.GetName(), fn.GetFullPath(),
SCH_IO_MGR::ShowType( type ) ) );
wxString tblName = Prj().SymbolLibTableName();
try
{
symLibTbl->Save( tblName );
}
catch( const IO_ERROR& ioe )
{
wxLogError( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() );
}
}
}
Kiway().ExpressMail( FRAME_CVPCB, MAIL_RELOAD_LIB, payload );
Kiway().ExpressMail( FRAME_SCH_SYMBOL_EDITOR, MAIL_RELOAD_LIB, payload );
Kiway().ExpressMail( FRAME_SCH_VIEWER, MAIL_RELOAD_LIB, payload );
break;
}
case MAIL_CROSS_PROBE:
ExecuteRemoteCommand( payload.c_str() );
break;
@ -957,7 +1009,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
std::string fnameStr;
wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
wxASSERT( !fnameStr.empty() );
int importFormat;

View File

@ -1330,7 +1330,8 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
case SCH_IO_MGR::SCH_EASYEDAPRO:
{
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
wxCHECK_MSG( filename.IsAbsolute(), false,
// Unless we are passing the files in aproperties, in which case aFileName can be empty.
wxCHECK_MSG( aFileName.IsEmpty() || filename.IsAbsolute(), false,
wxS( "Import schematic: path is not absolute!" ) );
try

View File

@ -160,6 +160,7 @@ ASCH_SYMBOL::ASCH_SYMBOL( const std::map<wxString, wxString>& aProps )
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::COMPONENT );
uniqueid = ALTIUM_PROPS_UTILS::ReadString( aProps, "UNIQUEID", "" );
currentpartid = ALTIUM_PROPS_UTILS::ReadInt( aProps, "CURRENTPARTID", ALTIUM_COMPONENT_NONE );
libreference = ALTIUM_PROPS_UTILS::ReadString( aProps, "LIBREFERENCE", "" );
sourcelibraryname = ALTIUM_PROPS_UTILS::ReadString( aProps, "SOURCELIBRARYNAME", "" );

View File

@ -151,6 +151,7 @@ struct ASCH_SYMBOL
{
int currentpartid;
int m_indexInSheet;
wxString uniqueid;
wxString libreference;
wxString sourcelibraryname;
wxString componentdescription;

View File

@ -376,11 +376,80 @@ wxFileName SCH_IO_ALTIUM::getLibFileName()
}
SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicProject( SCHEMATIC* aSchematic, const std::map<std::string, UTF8>* aProperties )
{
int x = 1;
int y = 1;
int page = 2; // Start at page 2 since page 1 is the root sheet.
std::map<wxString, SCH_SHEET*> sheets;
wxFileName project( aProperties->at( "project_file" ) );
for( auto& [ key, filestring] : *aProperties )
{
if( !key.starts_with( "sch" ) )
continue;
VECTOR2I pos = VECTOR2I( x * schIUScale.MilsToIU( 1000 ),
y * schIUScale.MilsToIU( 1000 ) );
wxFileName fn( filestring );
wxFileName kicad_fn( fn );
std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>( m_rootSheet, pos );
SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
sheet->SetScreen( screen );
kicad_fn.SetExt( FILEEXT::KiCadSchematicFileExtension );
kicad_fn.SetPath( aSchematic->Prj().GetProjectPath() );
sheet->SetFileName( fn.GetFullPath() );
screen->SetFileName( sheet->GetFileName() );
wxCHECK2( sheet && screen, continue );
wxString pageNo = wxString::Format( wxT( "%d" ), page++ );
m_sheetPath.push_back( sheet.get() );
ParseAltiumSch( fn.GetFullPath() );
m_sheetPath.SetPageNumber( pageNo );
m_sheetPath.pop_back();
SCH_SCREEN* currentScreen = m_rootSheet->GetScreen();
wxCHECK2( currentScreen, continue );
sheet->SetParent( m_sheetPath.Last() );
SCH_SHEET* sheetPtr = sheet.release();
currentScreen->Append( sheetPtr );
sheets[fn.GetFullPath()] = sheetPtr;
x += 2;
if( x > 10 ) // Start next row of sheets.
{
x = 1;
y += 2;
}
}
// If any of the sheets in the project is a subsheet, then remove the sheet from the root sheet.
// The root sheet only contains sheets that are not referenced by any other sheet in a
// pseudo-flat structure.
for( auto& [ filestring, sheet ] : sheets )
{
if( m_rootSheet->CountSheets( filestring ) > 1 )
getCurrentScreen()->Remove( sheet );
}
return m_rootSheet;
}
SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
SCH_SHEET* aAppendToMe,
const std::map<std::string, UTF8>* aProperties )
{
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
wxCHECK( ( !aFileName.IsEmpty() || !aProperties->empty() ) && aSchematic, nullptr );
wxFileName fileName( aFileName );
fileName.SetExt( FILEEXT::KiCadSchematicFileExtension );
@ -419,6 +488,18 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
const_cast<KIID&>( m_rootSheet->m_Uuid ) = screen->GetUuid();
}
m_sheetPath.push_back( m_rootSheet );
SCH_SCREEN* rootScreen = m_rootSheet->GetScreen();
wxCHECK( rootScreen, nullptr );
SCH_SHEET_INSTANCE sheetInstance;
sheetInstance.m_Path = m_sheetPath.Path();
sheetInstance.m_PageNumber = wxT( "#" );
rootScreen->m_sheetInstances.emplace_back( sheetInstance );
SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &m_schematic->Prj() );
wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." );
@ -452,19 +533,10 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
PROJECT_SCH::SchSymbolLibTable( &m_schematic->Prj() );
}
m_sheetPath.push_back( m_rootSheet );
SCH_SCREEN* rootScreen = m_rootSheet->GetScreen();
wxCHECK( rootScreen, nullptr );
SCH_SHEET_INSTANCE sheetInstance;
sheetInstance.m_Path = m_sheetPath.Path();
sheetInstance.m_PageNumber = wxT( "#" );
rootScreen->m_sheetInstances.emplace_back( sheetInstance );
ParseAltiumSch( aFileName );
if( aFileName.empty() )
LoadSchematicProject( aSchematic, aProperties );
else
ParseAltiumSch( aFileName );
if( m_reporter )
{
@ -1447,6 +1519,7 @@ void SCH_IO_ALTIUM::ParseComponent( int aIndex, const std::map<wxString, wxStrin
// each component has its own symbol for now
SCH_SYMBOL* symbol = new SCH_SYMBOL();
const_cast<KIID&>( symbol->m_Uuid ) = KIID( elem.uniqueid );
symbol->SetPosition( elem.location + m_sheetOffset );
for( SCH_FIELD& field : symbol->GetFields() )
@ -1454,6 +1527,15 @@ void SCH_IO_ALTIUM::ParseComponent( int aIndex, const std::map<wxString, wxStrin
// TODO: keep it simple for now, and only set position.
// component->SetOrientation( elem.orientation );
// If Altium has defined a library from which we have the part,
// use this as the designated source library.
if( !elem.sourcelibraryname.IsEmpty() )
{
wxFileName fn( elem.sourcelibraryname );
libId.SetLibNickname( fn.GetName() );
}
symbol->SetLibId( libId );
symbol->SetUnit( std::max( 0, elem.currentpartid ) );
symbol->GetField( FIELD_T::DESCRIPTION )->SetText( elem.componentdescription );

View File

@ -96,6 +96,9 @@ public:
SCH_SHEET* aAppendToMe = nullptr,
const std::map<std::string, UTF8>* aProperties = nullptr ) override;
SCH_SHEET* LoadSchematicProject( SCHEMATIC* aSchematic,
const std::map<std::string, UTF8>* aProperties );
// unimplemented functions. Will trigger a not_implemented IO error.
//void SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties = NULL ) override;

View File

@ -814,6 +814,23 @@ bool SCH_SHEET::LocatePathOfScreen( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aList )
}
int SCH_SHEET::CountSheets( const wxString& aFilename ) const
{
int count = 0;
if( m_screen )
{
if( m_screen->GetFileName().Cmp( aFilename ) == 0 )
count++;
for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_SHEET_T ) )
count += static_cast<SCH_SHEET*>( aItem )->CountSheets( aFilename );
}
return count;
}
int SCH_SHEET::CountSheets() const
{
int count = 1; //1 = this!!

View File

@ -305,6 +305,14 @@ public:
*/
int CountSheets() const;
/**
* Count the number of sheets that refer to a specific file
* including all of the subsheets.
* @param aFileName The filename to search for.
* @return the full count of sheets+subsheets that refer to aFileName
*/
int CountSheets( const wxString& aFileName ) const;
/**
* Return the filename corresponding to this sheet.
*

View File

@ -51,6 +51,7 @@ enum MAIL_T
MAIL_PCB_GET_NETLIST, // Fetch a netlist from PCB layout
MAIL_PCB_UPDATE_LINKS, // Update the schematic symbol paths in the PCB's footprints
MAIL_SCH_REFRESH, // Tell the schematic editor to refresh the display.
MAIL_ADD_LOCAL_LIB, // Add a local library to the project library table
MAIL_LIB_EDIT,
MAIL_FP_EDIT,
MAIL_RELOAD_LIB, // Reload Library List if one was added

View File

@ -247,6 +247,7 @@ public:
static wxString CsvFileWildcard();
static wxString PcbFileWildcard();
static wxString CadstarArchiveFilesWildcard();
static wxString AltiumProjectFilesWildcard();
static wxString EagleFilesWildcard();
static wxString EasyEdaArchiveWildcard();
static wxString EasyEdaProFileWildcard();

View File

@ -24,7 +24,9 @@
#include <string_utils.h>
#include <richio.h>
#include <wx/fileconf.h>
#include <wx/msgdlg.h>
#include <wx/wfstream.h>
#include <kiway.h>
#include <kiway_player.h>
@ -32,14 +34,21 @@
#include <pcb_edit_frame.h>
#include <sch_edit_frame.h>
#include <symbol_lib_table.h>
#include <fp_lib_table.h>
#include <sch_io/sch_io_mgr.h>
#include <pcb_io/pcb_io_mgr.h>
#include <project_sch.h>
#include <project_pcb.h>
#include <io/easyedapro/easyedapro_import_utils.h>
#include <io/easyedapro/easyedapro_parser.h>
#include <io/common/plugin_common_choose_project.h>
#include <dialogs/dialog_import_choose_project.h>
#include <wx/log.h>
IMPORT_PROJ_HELPER::IMPORT_PROJ_HELPER( KICAD_MANAGER_FRAME* aFrame,
const std::vector<wxString>& aSchFileExtensions,
@ -146,16 +155,22 @@ void IMPORT_PROJ_HELPER::ImportIndividualFile( KICAD_T aFT, int aImportedFileTyp
if( appImportFile.empty() )
return;
KIWAY_PLAYER* frame = m_frame->Kiway().Player( frame_type, true );
doImport( appImportFile, frame_type, aImportedFileType );
}
void IMPORT_PROJ_HELPER::doImport( const wxString& aFile, FRAME_T aFrameType, int aImportedFileType )
{
KIWAY_PLAYER* frame = m_frame->Kiway().Player( aFrameType, true );
std::stringstream ss;
ss << aImportedFileType << '\n' << TO_UTF8( appImportFile );
ss << aImportedFileType << '\n' << TO_UTF8( aFile );
for( const auto& [key, value] : m_properties )
ss << '\n' << key << '\n' << value.wx_str();
std::string packet = ss.str();
frame->Kiway().ExpressMail( frame_type, MAIL_IMPORT_FILE, packet, m_frame );
frame->Kiway().ExpressMail( aFrameType, MAIL_IMPORT_FILE, packet, m_frame );
if( !frame->IsShownOnScreen() )
frame->Show( true );
@ -202,6 +217,96 @@ void IMPORT_PROJ_HELPER::EasyEDAProProjectHandler()
}
void IMPORT_PROJ_HELPER::addLocalLibraries( const std::set<wxString>& aNames, FRAME_T aFrameType )
{
KIWAY_PLAYER* frame = m_frame->Kiway().Player( aFrameType, true );
std::stringstream ss;
for( const wxString& name : aNames )
{
wxFileName fname( name );
fname.MakeAbsolute( m_InputFile.GetPath() );
ss << TO_UTF8( fname.GetFullPath() ) << '\n';
}
std::string packet = ss.str();
frame->Kiway().ExpressMail( aFrameType, MAIL_ADD_LOCAL_LIB, packet, m_frame );
}
void IMPORT_PROJ_HELPER::AltiumProjectHandler()
{
wxFFileInputStream stream( m_InputFile.GetFullPath() );
if( !stream.IsOk() )
return;
wxFileConfig config( stream );
wxString groupname;
long groupid;
std::set<wxString> sch_file;
std::set<wxString> pcb_file;
std::set<wxString> sch_libs;
std::set<wxString> pcb_libs;
for( bool more = config.GetFirstGroup( groupname, groupid ); more;
more = config.GetNextGroup( groupname, groupid ) )
{
if( !groupname.StartsWith( wxS( "Document" ) ) )
continue;
wxString number = groupname.Mid( 8 );
long docNumber;
if( !number.ToLong( &docNumber ) )
continue;
wxString path = config.Read( groupname + wxS( "/DocumentPath" ), wxEmptyString );
if( path.empty() )
continue;
wxFileName fname( path );
if( !fname.IsAbsolute() )
fname.MakeAbsolute( m_InputFile.GetPath() );
if( !fname.GetExt().CmpNoCase( "PCBDOC" ) )
pcb_file.insert( fname.GetFullPath() );
if( !fname.GetExt().CmpNoCase( "SCHDOC" ) )
sch_file.insert( fname.GetFullPath() );
if( !fname.GetExt().CmpNoCase( "PCBLIB" ) )
pcb_libs.insert( fname.GetFullPath() );
if( !fname.GetExt().CmpNoCase( "SCHLIB" ) )
sch_libs.insert( fname.GetFullPath() );
}
addLocalLibraries( sch_libs, FRAME_SCH );
addLocalLibraries( pcb_libs, FRAME_PCB_EDITOR );
m_properties["project_file"] = m_InputFile.GetFullPath();
int ii = 0;
for( auto& path : sch_file )
{
std::string key = "sch" + std::to_string( ii++ );
m_properties[key] = path.ToStdString();
}
if( !sch_file.empty() )
doImport( "", FRAME_SCH, SCH_IO_MGR::SCH_ALTIUM );
if( !pcb_file.empty() )
doImport( *pcb_file.begin(), FRAME_PCB_EDITOR, PCB_IO_MGR::ALTIUM_DESIGNER );
}
void IMPORT_PROJ_HELPER::ImportFiles( int aImportedSchFileType, int aImportedPcbFileType )
{
m_properties.clear();
@ -211,6 +316,12 @@ void IMPORT_PROJ_HELPER::ImportFiles( int aImportedSchFileType, int aImportedPcb
{
EasyEDAProProjectHandler();
}
else if( aImportedSchFileType == SCH_IO_MGR::SCH_ALTIUM
|| aImportedPcbFileType == PCB_IO_MGR::ALTIUM_DESIGNER )
{
AltiumProjectHandler();
return;
}
ImportIndividualFile( SCHEMATIC_T, aImportedSchFileType );
ImportIndividualFile( PCB_T, aImportedPcbFileType );

View File

@ -23,8 +23,10 @@
#include <wx/filename.h>
#include <core/typeinfo.h>
#include <core/utf8.h>
#include <frame_type.h>
#include <map>
#include <set>
class KICAD_MANAGER_FRAME;
@ -69,7 +71,13 @@ private:
void OutputCopyError( const wxFileName& aSrc, const wxFileName& aFileCopy );
void ImportIndividualFile( KICAD_T aKicad_T, int aImportedFileType );
void doImport( const wxString& aFile, FRAME_T aFrameType, int aImportedFileType );
void addLocalLibraries( const std::set<wxString>& aLibName, FRAME_T aFrameType );
void EasyEDAProProjectHandler();
void AltiumProjectHandler();
};
#endif

View File

@ -141,6 +141,14 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
}
void KICAD_MANAGER_FRAME::OnImportAltiumProjectFiles( wxCommandEvent& event )
{
ImportNonKiCadProject( _( "Import Altium Project Files" ),
FILEEXT::AltiumProjectFilesWildcard(), { "SchDoc" }, { "PcbDoc" },
SCH_IO_MGR::SCH_ALTIUM, PCB_IO_MGR::ALTIUM_DESIGNER );
}
void KICAD_MANAGER_FRAME::OnImportCadstarArchiveFiles( wxCommandEvent& event )
{
ImportNonKiCadProject( _( "Import CADSTAR Archive Project Files" ),

View File

@ -72,6 +72,7 @@ enum id_kicad_frm {
ID_IMPORT_EAGLE_PROJECT,
ID_IMPORT_EASYEDA_PROJECT,
ID_IMPORT_EASYEDAPRO_PROJECT,
ID_IMPORT_ALTIUM_PROJECT,
ID_GIT_INITIALIZE_PROJECT, // Initialize a new git repository in an existing project
ID_GIT_CLONE_PROJECT, // Clone a project from a remote repository

View File

@ -107,6 +107,7 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
EVT_MENU( ID_IMPORT_EAGLE_PROJECT, KICAD_MANAGER_FRAME::OnImportEagleFiles )
EVT_MENU( ID_IMPORT_EASYEDA_PROJECT, KICAD_MANAGER_FRAME::OnImportEasyEdaFiles )
EVT_MENU( ID_IMPORT_EASYEDAPRO_PROJECT, KICAD_MANAGER_FRAME::OnImportEasyEdaProFiles )
EVT_MENU( ID_IMPORT_ALTIUM_PROJECT, KICAD_MANAGER_FRAME::OnImportAltiumProjectFiles )
// Range menu events
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END,

View File

@ -101,6 +101,11 @@ public:
const std::vector<std::string>& aPcbFileExtensions,
int aSchFileType, int aPcbFileType );
/**
* Open dialog to import Altium project files.
*/
void OnImportAltiumProjectFiles( wxCommandEvent& event );
/**
* Open dialog to import CADSTAR Schematic and PCB Archive files.
*/

View File

@ -112,6 +112,10 @@ void KICAD_MANAGER_FRAME::doReCreateMenuBar()
importMenu->SetTitle( _( "Import Non-KiCad Project..." ) );
importMenu->SetIcon( BITMAPS::import_project );
importMenu->Add( _( "Altium Project..." ),
_( "Import Altium Schematic and PCB (*.PrjPcb)" ),
ID_IMPORT_ALTIUM_PROJECT,
BITMAPS::import_project );
importMenu->Add( _( "CADSTAR Project..." ),
_( "Import CADSTAR Archive Schematic and PCB (*.csa, *.cpa)" ),
ID_IMPORT_CADSTAR_ARCHIVE_PROJECT,

View File

@ -1275,6 +1275,14 @@ bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
case PCB_IO_MGR::EASYEDAPRO:
return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
KICTL_NONKICAD_ONLY | KICTL_IMPORT_LIB );
break;
case PCB_IO_MGR::ALTIUM_DESIGNER:
case PCB_IO_MGR::ALTIUM_CIRCUIT_MAKER:
case PCB_IO_MGR::ALTIUM_CIRCUIT_STUDIO:
case PCB_IO_MGR::SOLIDWORKS_PCB:
return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
KICTL_NONKICAD_ONLY );
default: break;
}

View File

@ -362,6 +362,13 @@ ACOMPONENT6::ACOMPONENT6( ALTIUM_BINARY_PARSER& aReader )
commenton = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "COMMENTON" ), false );
sourcedesignator = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SOURCEDESIGNATOR" ), wxT( "" ) );
sourceUniqueID = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SOURCEUNIQUEID" ), wxT( "" ) );
// Remove leading backslash from sourceUniqueID to match schematic component unique IDs
if( sourceUniqueID.starts_with( wxT( "\\" ) ) )
sourceUniqueID = sourceUniqueID.Mid( 1 );
sourceHierachicalPath = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SOURCEHIERARCHICALPATH" ), wxT( "" ) );
sourcefootprintlibrary =
ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "SOURCEFOOTPRINTLIBRARY" ), wxT( "" ) );
pattern = ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "PATTERN" ), wxT( "" ) );

View File

@ -409,6 +409,8 @@ struct ACOMPONENT6
bool locked;
bool nameon;
bool commenton;
wxString sourceUniqueID;
wxString sourceHierachicalPath;
wxString sourcedesignator;
wxString sourcefootprintlibrary;
wxString pattern;

View File

@ -1329,6 +1329,16 @@ void ALTIUM_PCB::ParseComponents6Data( const ALTIUM_PCB_COMPOUND_FILE& aAltiumPc
footprint->SetReference( reference );
KIID id( elem.sourceUniqueID );
KIID pathid( elem.sourceHierachicalPath );
KIID_PATH path;
path.push_back( pathid );
path.push_back( id );
footprint->SetPath( path );
footprint->SetSheetname( elem.sourceHierachicalPath );
footprint->SetSheetfile( elem.sourceHierachicalPath + wxT( ".kicad_sch" ));
footprint->SetLocked( elem.locked );
footprint->Reference().SetVisible( elem.nameon );
footprint->Value().SetVisible( elem.commenton );

View File

@ -341,3 +341,14 @@ FOOTPRINT* PCB_IO_ALTIUM_DESIGNER::FootprintLoad( const wxString& aLibraryPath,
aFootprintName,
aLibraryPath ) );
}
std::vector<FOOTPRINT*> PCB_IO_ALTIUM_DESIGNER::GetImportedCachedLibraryFootprints()
{
std::vector<FOOTPRINT*> footprints;
for( FOOTPRINT* fp : m_board->Footprints() )
footprints.push_back( fp );
return footprints;
}

View File

@ -64,6 +64,8 @@ public:
bool aKeepUUID = false,
const std::map<std::string, UTF8>* aProperties = nullptr ) override;
std::vector<FOOTPRINT*> GetImportedCachedLibraryFootprints() override;
//bool FootprintExists( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = nullptr );
bool IsLibraryWritable( const wxString& aLibraryPath ) override { return false; }