mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
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:
parent
320a298394
commit
e81956f292
@ -284,6 +284,12 @@ wxString FILEEXT::KiCadSchematicFileWildcard()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString FILEEXT::AltiumProjectFilesWildcard()
|
||||||
|
{
|
||||||
|
return _( "Altium Project files" ) + AddFileExtListToFilter( { "PrjPcb" } );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString FILEEXT::CadstarArchiveFilesWildcard()
|
wxString FILEEXT::CadstarArchiveFilesWildcard()
|
||||||
{
|
{
|
||||||
return _( "CADSTAR Archive files" ) + AddFileExtListToFilter( { "csa", "cpa" } );
|
return _( "CADSTAR Archive files" ) + AddFileExtListToFilter( { "csa", "cpa" } );
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <kiface_base.h>
|
#include <kiface_base.h>
|
||||||
|
#include <kiway.h>
|
||||||
#include <kiway_express.h>
|
#include <kiway_express.h>
|
||||||
#include <eda_dde.h>
|
#include <eda_dde.h>
|
||||||
#include <connection_graph.h>
|
#include <connection_graph.h>
|
||||||
@ -34,7 +35,9 @@
|
|||||||
#include <netlist_exporters/netlist_exporter_kicad.h>
|
#include <netlist_exporters/netlist_exporter_kicad.h>
|
||||||
#include <project/project_file.h>
|
#include <project/project_file.h>
|
||||||
#include <project/net_settings.h>
|
#include <project/net_settings.h>
|
||||||
|
#include <project_sch.h>
|
||||||
#include <richio.h>
|
#include <richio.h>
|
||||||
|
#include <symbol_lib_table.h>
|
||||||
#include <tools/ee_actions.h>
|
#include <tools/ee_actions.h>
|
||||||
#include <tools/sch_editor_control.h>
|
#include <tools/sch_editor_control.h>
|
||||||
#include <advanced_config.h>
|
#include <advanced_config.h>
|
||||||
@ -835,6 +838,55 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||||||
|
|
||||||
switch( mail.Command() )
|
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:
|
case MAIL_CROSS_PROBE:
|
||||||
ExecuteRemoteCommand( payload.c_str() );
|
ExecuteRemoteCommand( payload.c_str() );
|
||||||
break;
|
break;
|
||||||
@ -957,7 +1009,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||||||
|
|
||||||
std::string fnameStr;
|
std::string fnameStr;
|
||||||
wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
|
wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
|
||||||
wxASSERT( !fnameStr.empty() );
|
|
||||||
|
|
||||||
int importFormat;
|
int importFormat;
|
||||||
|
|
||||||
|
@ -1330,7 +1330,8 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
|||||||
case SCH_IO_MGR::SCH_EASYEDAPRO:
|
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.
|
// 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!" ) );
|
wxS( "Import schematic: path is not absolute!" ) );
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -160,6 +160,7 @@ ASCH_SYMBOL::ASCH_SYMBOL( const std::map<wxString, wxString>& aProps )
|
|||||||
{
|
{
|
||||||
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::COMPONENT );
|
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::COMPONENT );
|
||||||
|
|
||||||
|
uniqueid = ALTIUM_PROPS_UTILS::ReadString( aProps, "UNIQUEID", "" );
|
||||||
currentpartid = ALTIUM_PROPS_UTILS::ReadInt( aProps, "CURRENTPARTID", ALTIUM_COMPONENT_NONE );
|
currentpartid = ALTIUM_PROPS_UTILS::ReadInt( aProps, "CURRENTPARTID", ALTIUM_COMPONENT_NONE );
|
||||||
libreference = ALTIUM_PROPS_UTILS::ReadString( aProps, "LIBREFERENCE", "" );
|
libreference = ALTIUM_PROPS_UTILS::ReadString( aProps, "LIBREFERENCE", "" );
|
||||||
sourcelibraryname = ALTIUM_PROPS_UTILS::ReadString( aProps, "SOURCELIBRARYNAME", "" );
|
sourcelibraryname = ALTIUM_PROPS_UTILS::ReadString( aProps, "SOURCELIBRARYNAME", "" );
|
||||||
|
@ -151,6 +151,7 @@ struct ASCH_SYMBOL
|
|||||||
{
|
{
|
||||||
int currentpartid;
|
int currentpartid;
|
||||||
int m_indexInSheet;
|
int m_indexInSheet;
|
||||||
|
wxString uniqueid;
|
||||||
wxString libreference;
|
wxString libreference;
|
||||||
wxString sourcelibraryname;
|
wxString sourcelibraryname;
|
||||||
wxString componentdescription;
|
wxString componentdescription;
|
||||||
|
@ -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* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic,
|
||||||
SCH_SHEET* aAppendToMe,
|
SCH_SHEET* aAppendToMe,
|
||||||
const std::map<std::string, UTF8>* aProperties )
|
const std::map<std::string, UTF8>* aProperties )
|
||||||
{
|
{
|
||||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
wxCHECK( ( !aFileName.IsEmpty() || !aProperties->empty() ) && aSchematic, nullptr );
|
||||||
|
|
||||||
wxFileName fileName( aFileName );
|
wxFileName fileName( aFileName );
|
||||||
fileName.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
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();
|
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() );
|
SYMBOL_LIB_TABLE* libTable = PROJECT_SCH::SchSymbolLibTable( &m_schematic->Prj() );
|
||||||
|
|
||||||
wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." );
|
wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." );
|
||||||
@ -452,18 +533,9 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
|
|||||||
PROJECT_SCH::SchSymbolLibTable( &m_schematic->Prj() );
|
PROJECT_SCH::SchSymbolLibTable( &m_schematic->Prj() );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sheetPath.push_back( m_rootSheet );
|
if( aFileName.empty() )
|
||||||
|
LoadSchematicProject( aSchematic, aProperties );
|
||||||
SCH_SCREEN* rootScreen = m_rootSheet->GetScreen();
|
else
|
||||||
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 );
|
ParseAltiumSch( aFileName );
|
||||||
|
|
||||||
if( m_reporter )
|
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
|
// each component has its own symbol for now
|
||||||
SCH_SYMBOL* symbol = new SCH_SYMBOL();
|
SCH_SYMBOL* symbol = new SCH_SYMBOL();
|
||||||
|
|
||||||
|
const_cast<KIID&>( symbol->m_Uuid ) = KIID( elem.uniqueid );
|
||||||
symbol->SetPosition( elem.location + m_sheetOffset );
|
symbol->SetPosition( elem.location + m_sheetOffset );
|
||||||
|
|
||||||
for( SCH_FIELD& field : symbol->GetFields() )
|
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.
|
// TODO: keep it simple for now, and only set position.
|
||||||
// component->SetOrientation( elem.orientation );
|
// 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->SetLibId( libId );
|
||||||
symbol->SetUnit( std::max( 0, elem.currentpartid ) );
|
symbol->SetUnit( std::max( 0, elem.currentpartid ) );
|
||||||
symbol->GetField( FIELD_T::DESCRIPTION )->SetText( elem.componentdescription );
|
symbol->GetField( FIELD_T::DESCRIPTION )->SetText( elem.componentdescription );
|
||||||
|
@ -96,6 +96,9 @@ public:
|
|||||||
SCH_SHEET* aAppendToMe = nullptr,
|
SCH_SHEET* aAppendToMe = nullptr,
|
||||||
const std::map<std::string, UTF8>* aProperties = nullptr ) override;
|
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.
|
// unimplemented functions. Will trigger a not_implemented IO error.
|
||||||
//void SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties = NULL ) override;
|
//void SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties = NULL ) override;
|
||||||
|
|
||||||
|
@ -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 SCH_SHEET::CountSheets() const
|
||||||
{
|
{
|
||||||
int count = 1; //1 = this!!
|
int count = 1; //1 = this!!
|
||||||
|
@ -305,6 +305,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
int CountSheets() const;
|
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.
|
* Return the filename corresponding to this sheet.
|
||||||
*
|
*
|
||||||
|
@ -51,6 +51,7 @@ enum MAIL_T
|
|||||||
MAIL_PCB_GET_NETLIST, // Fetch a netlist from PCB layout
|
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_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_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_LIB_EDIT,
|
||||||
MAIL_FP_EDIT,
|
MAIL_FP_EDIT,
|
||||||
MAIL_RELOAD_LIB, // Reload Library List if one was added
|
MAIL_RELOAD_LIB, // Reload Library List if one was added
|
||||||
|
@ -247,6 +247,7 @@ public:
|
|||||||
static wxString CsvFileWildcard();
|
static wxString CsvFileWildcard();
|
||||||
static wxString PcbFileWildcard();
|
static wxString PcbFileWildcard();
|
||||||
static wxString CadstarArchiveFilesWildcard();
|
static wxString CadstarArchiveFilesWildcard();
|
||||||
|
static wxString AltiumProjectFilesWildcard();
|
||||||
static wxString EagleFilesWildcard();
|
static wxString EagleFilesWildcard();
|
||||||
static wxString EasyEdaArchiveWildcard();
|
static wxString EasyEdaArchiveWildcard();
|
||||||
static wxString EasyEdaProFileWildcard();
|
static wxString EasyEdaProFileWildcard();
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
#include <richio.h>
|
#include <richio.h>
|
||||||
|
|
||||||
|
#include <wx/fileconf.h>
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
|
#include <wx/wfstream.h>
|
||||||
|
|
||||||
#include <kiway.h>
|
#include <kiway.h>
|
||||||
#include <kiway_player.h>
|
#include <kiway_player.h>
|
||||||
@ -32,14 +34,21 @@
|
|||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
#include <sch_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 <sch_io/sch_io_mgr.h>
|
||||||
#include <pcb_io/pcb_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_import_utils.h>
|
||||||
#include <io/easyedapro/easyedapro_parser.h>
|
#include <io/easyedapro/easyedapro_parser.h>
|
||||||
#include <io/common/plugin_common_choose_project.h>
|
#include <io/common/plugin_common_choose_project.h>
|
||||||
#include <dialogs/dialog_import_choose_project.h>
|
#include <dialogs/dialog_import_choose_project.h>
|
||||||
|
|
||||||
|
#include <wx/log.h>
|
||||||
|
|
||||||
|
|
||||||
IMPORT_PROJ_HELPER::IMPORT_PROJ_HELPER( KICAD_MANAGER_FRAME* aFrame,
|
IMPORT_PROJ_HELPER::IMPORT_PROJ_HELPER( KICAD_MANAGER_FRAME* aFrame,
|
||||||
const std::vector<wxString>& aSchFileExtensions,
|
const std::vector<wxString>& aSchFileExtensions,
|
||||||
@ -146,16 +155,22 @@ void IMPORT_PROJ_HELPER::ImportIndividualFile( KICAD_T aFT, int aImportedFileTyp
|
|||||||
if( appImportFile.empty() )
|
if( appImportFile.empty() )
|
||||||
return;
|
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;
|
std::stringstream ss;
|
||||||
ss << aImportedFileType << '\n' << TO_UTF8( appImportFile );
|
ss << aImportedFileType << '\n' << TO_UTF8( aFile );
|
||||||
|
|
||||||
for( const auto& [key, value] : m_properties )
|
for( const auto& [key, value] : m_properties )
|
||||||
ss << '\n' << key << '\n' << value.wx_str();
|
ss << '\n' << key << '\n' << value.wx_str();
|
||||||
|
|
||||||
std::string packet = ss.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() )
|
if( !frame->IsShownOnScreen() )
|
||||||
frame->Show( true );
|
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 )
|
void IMPORT_PROJ_HELPER::ImportFiles( int aImportedSchFileType, int aImportedPcbFileType )
|
||||||
{
|
{
|
||||||
m_properties.clear();
|
m_properties.clear();
|
||||||
@ -211,6 +316,12 @@ void IMPORT_PROJ_HELPER::ImportFiles( int aImportedSchFileType, int aImportedPcb
|
|||||||
{
|
{
|
||||||
EasyEDAProProjectHandler();
|
EasyEDAProProjectHandler();
|
||||||
}
|
}
|
||||||
|
else if( aImportedSchFileType == SCH_IO_MGR::SCH_ALTIUM
|
||||||
|
|| aImportedPcbFileType == PCB_IO_MGR::ALTIUM_DESIGNER )
|
||||||
|
{
|
||||||
|
AltiumProjectHandler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ImportIndividualFile( SCHEMATIC_T, aImportedSchFileType );
|
ImportIndividualFile( SCHEMATIC_T, aImportedSchFileType );
|
||||||
ImportIndividualFile( PCB_T, aImportedPcbFileType );
|
ImportIndividualFile( PCB_T, aImportedPcbFileType );
|
||||||
|
@ -23,8 +23,10 @@
|
|||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
#include <core/typeinfo.h>
|
#include <core/typeinfo.h>
|
||||||
#include <core/utf8.h>
|
#include <core/utf8.h>
|
||||||
|
#include <frame_type.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
class KICAD_MANAGER_FRAME;
|
class KICAD_MANAGER_FRAME;
|
||||||
|
|
||||||
@ -69,7 +71,13 @@ private:
|
|||||||
void OutputCopyError( const wxFileName& aSrc, const wxFileName& aFileCopy );
|
void OutputCopyError( const wxFileName& aSrc, const wxFileName& aFileCopy );
|
||||||
void ImportIndividualFile( KICAD_T aKicad_T, int aImportedFileType );
|
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 EasyEDAProProjectHandler();
|
||||||
|
|
||||||
|
void AltiumProjectHandler();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -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 )
|
void KICAD_MANAGER_FRAME::OnImportCadstarArchiveFiles( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
ImportNonKiCadProject( _( "Import CADSTAR Archive Project Files" ),
|
ImportNonKiCadProject( _( "Import CADSTAR Archive Project Files" ),
|
||||||
|
@ -72,6 +72,7 @@ enum id_kicad_frm {
|
|||||||
ID_IMPORT_EAGLE_PROJECT,
|
ID_IMPORT_EAGLE_PROJECT,
|
||||||
ID_IMPORT_EASYEDA_PROJECT,
|
ID_IMPORT_EASYEDA_PROJECT,
|
||||||
ID_IMPORT_EASYEDAPRO_PROJECT,
|
ID_IMPORT_EASYEDAPRO_PROJECT,
|
||||||
|
ID_IMPORT_ALTIUM_PROJECT,
|
||||||
|
|
||||||
ID_GIT_INITIALIZE_PROJECT, // Initialize a new git repository in an existing 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
|
ID_GIT_CLONE_PROJECT, // Clone a project from a remote repository
|
||||||
|
@ -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_EAGLE_PROJECT, KICAD_MANAGER_FRAME::OnImportEagleFiles )
|
||||||
EVT_MENU( ID_IMPORT_EASYEDA_PROJECT, KICAD_MANAGER_FRAME::OnImportEasyEdaFiles )
|
EVT_MENU( ID_IMPORT_EASYEDA_PROJECT, KICAD_MANAGER_FRAME::OnImportEasyEdaFiles )
|
||||||
EVT_MENU( ID_IMPORT_EASYEDAPRO_PROJECT, KICAD_MANAGER_FRAME::OnImportEasyEdaProFiles )
|
EVT_MENU( ID_IMPORT_EASYEDAPRO_PROJECT, KICAD_MANAGER_FRAME::OnImportEasyEdaProFiles )
|
||||||
|
EVT_MENU( ID_IMPORT_ALTIUM_PROJECT, KICAD_MANAGER_FRAME::OnImportAltiumProjectFiles )
|
||||||
|
|
||||||
// Range menu events
|
// Range menu events
|
||||||
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END,
|
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END,
|
||||||
|
@ -101,6 +101,11 @@ public:
|
|||||||
const std::vector<std::string>& aPcbFileExtensions,
|
const std::vector<std::string>& aPcbFileExtensions,
|
||||||
int aSchFileType, int aPcbFileType );
|
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.
|
* Open dialog to import CADSTAR Schematic and PCB Archive files.
|
||||||
*/
|
*/
|
||||||
|
@ -112,6 +112,10 @@ void KICAD_MANAGER_FRAME::doReCreateMenuBar()
|
|||||||
importMenu->SetTitle( _( "Import Non-KiCad Project..." ) );
|
importMenu->SetTitle( _( "Import Non-KiCad Project..." ) );
|
||||||
importMenu->SetIcon( BITMAPS::import_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..." ),
|
importMenu->Add( _( "CADSTAR Project..." ),
|
||||||
_( "Import CADSTAR Archive Schematic and PCB (*.csa, *.cpa)" ),
|
_( "Import CADSTAR Archive Schematic and PCB (*.csa, *.cpa)" ),
|
||||||
ID_IMPORT_CADSTAR_ARCHIVE_PROJECT,
|
ID_IMPORT_CADSTAR_ARCHIVE_PROJECT,
|
||||||
|
@ -1275,6 +1275,14 @@ bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
|||||||
case PCB_IO_MGR::EASYEDAPRO:
|
case PCB_IO_MGR::EASYEDAPRO:
|
||||||
return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
|
return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
|
||||||
KICTL_NONKICAD_ONLY | KICTL_IMPORT_LIB );
|
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;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -362,6 +362,13 @@ ACOMPONENT6::ACOMPONENT6( ALTIUM_BINARY_PARSER& aReader )
|
|||||||
commenton = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "COMMENTON" ), false );
|
commenton = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "COMMENTON" ), false );
|
||||||
sourcedesignator = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SOURCEDESIGNATOR" ), wxT( "" ) );
|
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 =
|
sourcefootprintlibrary =
|
||||||
ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "SOURCEFOOTPRINTLIBRARY" ), wxT( "" ) );
|
ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "SOURCEFOOTPRINTLIBRARY" ), wxT( "" ) );
|
||||||
pattern = ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "PATTERN" ), wxT( "" ) );
|
pattern = ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "PATTERN" ), wxT( "" ) );
|
||||||
|
@ -409,6 +409,8 @@ struct ACOMPONENT6
|
|||||||
bool locked;
|
bool locked;
|
||||||
bool nameon;
|
bool nameon;
|
||||||
bool commenton;
|
bool commenton;
|
||||||
|
wxString sourceUniqueID;
|
||||||
|
wxString sourceHierachicalPath;
|
||||||
wxString sourcedesignator;
|
wxString sourcedesignator;
|
||||||
wxString sourcefootprintlibrary;
|
wxString sourcefootprintlibrary;
|
||||||
wxString pattern;
|
wxString pattern;
|
||||||
|
@ -1329,6 +1329,16 @@ void ALTIUM_PCB::ParseComponents6Data( const ALTIUM_PCB_COMPOUND_FILE& aAltiumPc
|
|||||||
|
|
||||||
footprint->SetReference( reference );
|
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->SetLocked( elem.locked );
|
||||||
footprint->Reference().SetVisible( elem.nameon );
|
footprint->Reference().SetVisible( elem.nameon );
|
||||||
footprint->Value().SetVisible( elem.commenton );
|
footprint->Value().SetVisible( elem.commenton );
|
||||||
|
@ -341,3 +341,14 @@ FOOTPRINT* PCB_IO_ALTIUM_DESIGNER::FootprintLoad( const wxString& aLibraryPath,
|
|||||||
aFootprintName,
|
aFootprintName,
|
||||||
aLibraryPath ) );
|
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;
|
||||||
|
}
|
@ -64,6 +64,8 @@ public:
|
|||||||
bool aKeepUUID = false,
|
bool aKeepUUID = false,
|
||||||
const std::map<std::string, UTF8>* aProperties = nullptr ) override;
|
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 FootprintExists( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = nullptr );
|
||||||
|
|
||||||
bool IsLibraryWritable( const wxString& aLibraryPath ) override { return false; }
|
bool IsLibraryWritable( const wxString& aLibraryPath ) override { return false; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user