Refactor Eagle project import to use Kiway::ExpressMail()

This commit is contained in:
Maciej Suminski 2018-02-26 11:34:36 +01:00
parent 9016344bb3
commit 1f078f533b
9 changed files with 128 additions and 106 deletions

View File

@ -253,6 +253,30 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
GetCanvas()->Refresh(); GetCanvas()->Refresh();
break; break;
case MAIL_IMPORT_FILE:
{
// Extract file format type and path (plugin type and path separated with \n)
size_t split = payload.find( '\n' );
wxCHECK( split != std::string::npos, /*void*/ );
int importFormat;
try
{
importFormat = std::stoi( payload.substr( 0, split ) );
}
catch( std::invalid_argument& e )
{
wxFAIL;
importFormat = -1;
}
std::string path = payload.substr( split + 1 );
wxASSERT( !path.empty() );
if( importFormat >= 0 )
importFile( path, importFormat );
}
default: default:
; ;
} }

View File

@ -676,7 +676,7 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
} }
// For now there is only one import plugin // For now there is only one import plugin
ImportFile( dlg.GetPath(), SCH_IO_MGR::SCH_EAGLE ); importFile( dlg.GetPath(), SCH_IO_MGR::SCH_EAGLE );
} }
@ -752,7 +752,7 @@ bool SCH_EDIT_FRAME::doAutoSave()
} }
bool SCH_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType ) bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
{ {
wxString fullFileName( aFileName ); wxString fullFileName( aFileName );

View File

@ -812,14 +812,6 @@ public:
bool IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria ); bool IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria );
/**
* Load the given filename but sets the path to the current project path.
*
* @param full filepath of file to be imported.
* @param aFileType SCH_FILE_T value for file type
*/
bool ImportFile( const wxString& aFileName, int aFileType ) override;
/** /**
* Checks if any of the screens has unsaved changes and asks the user whether to save or * Checks if any of the screens has unsaved changes and asks the user whether to save or
* drop them. * drop them.
@ -1126,6 +1118,14 @@ public:
wxPoint GetLastSheetPinPosition() const { return m_lastSheetPinPosition; } wxPoint GetLastSheetPinPosition() const { return m_lastSheetPinPosition; }
private: private:
/**
* Load the given filename but sets the path to the current project path.
*
* @param full filepath of file to be imported.
* @param aFileType SCH_FILE_T value for file type
*/
bool importFile( const wxString& aFileName, int aFileType );
bool validateSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ); bool validateSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy );
/** /**

View File

@ -179,27 +179,6 @@ public:
return false; return false;
} }
/**
* Function ImportFile
* load the given filename but sets the path to the current project path.
* @param full filepath of file to be imported.
* @param aFileType enum value for filetype
*/
VTBL_ENTRY bool ImportFile( const wxString& aFileName, int aFileType )
{
// overload me for your wxFrame type.
return false;
}
/**
* Rematch ophaned zones and vias to schematic nets.
*/
VTBL_ENTRY bool FixEagleNets()
{
return false;
};
/** /**
* Create a list of net names currently in use by the player . * Create a list of net names currently in use by the player .

View File

@ -40,6 +40,7 @@ enum MAIL_T
MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing at cvpcb termination MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing at cvpcb termination
MAIL_EESCHEMA_NETLIST, ///< EESCHEMA->CVPCB netlist immediately after launching CVPCB MAIL_EESCHEMA_NETLIST, ///< EESCHEMA->CVPCB netlist immediately after launching CVPCB
MAIL_SCH_PCB_UPDATE, ///< Sch->PCB forward update MAIL_SCH_PCB_UPDATE, ///< Sch->PCB forward update
MAIL_IMPORT_FILE, ///< Import a different format file
///< Sch->PCB forward update, requests SCH to re-generate netlist and send it to PCB ///< Sch->PCB forward update, requests SCH to re-generate netlist and send it to PCB
///< via another mail (kind of bootstrap) ///< via another mail (kind of bootstrap)

View File

@ -47,11 +47,6 @@
#include <io_mgr.h> #include <io_mgr.h>
#include <sch_io_mgr.h> #include <sch_io_mgr.h>
#include <pcb_edit_frame.h>
#include <sch_edit_frame.h>
#include <netlist.h>
class PCB_EDIT_FRAME;
#include "kicad.h" #include "kicad.h"
@ -124,17 +119,16 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
SetProjectFileName( pro.GetFullPath() ); SetProjectFileName( pro.GetFullPath() );
wxString prj_filename = GetProjectFileName(); wxString prj_filename = GetProjectFileName();
wxString sch_filename = sch.GetFullPath();
if( sch.FileExists() ) if( sch.FileExists() )
{ {
SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway.Player( FRAME_SCH, false ); KIWAY_PLAYER* schframe = Kiway.Player( FRAME_SCH, false );
if( !schframe ) if( !schframe )
{ {
try try // SCH frame was not available, try to start it
{ {
schframe = (SCH_EDIT_FRAME*) Kiway.Player( FRAME_SCH, true ); schframe = Kiway.Player( FRAME_SCH, true );
} }
catch( IO_ERROR err ) catch( IO_ERROR err )
{ {
@ -144,7 +138,8 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
} }
} }
schframe->ImportFile( sch_filename, SCH_IO_MGR::SCH_EAGLE ); schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE,
wxString::Format( "%d\n%s", SCH_IO_MGR::SCH_EAGLE, sch.GetFullPath() ).ToStdString(), this );
if( !schframe->IsShown() ) // the frame exists, (created by the dialog field editor) if( !schframe->IsShown() ) // the frame exists, (created by the dialog field editor)
// but no project loaded. // but no project loaded.
@ -161,13 +156,13 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
if( pcb.FileExists() ) if( pcb.FileExists() )
{ {
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway.Player( FRAME_PCB, false ); KIWAY_PLAYER* pcbframe = Kiway.Player( FRAME_PCB, false );
if( !pcbframe ) if( !pcbframe )
{ {
try try // PCB frame was not available, try to start it
{ {
pcbframe = (PCB_EDIT_FRAME*) Kiway.Player( FRAME_PCB, true ); pcbframe = Kiway.Player( FRAME_PCB, true );
} }
catch( IO_ERROR err ) catch( IO_ERROR err )
{ {
@ -182,22 +177,17 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
// if the frame is not visible, the board is not yet loaded // if the frame is not visible, the board is not yet loaded
if( !pcbframe->IsVisible() ) if( !pcbframe->IsVisible() )
{ {
pcbframe->ImportFile( pcb.GetFullPath(), IO_MGR::EAGLE );
pcbframe->Show( true ); pcbframe->Show( true );
} }
pcbframe->Kiway().ExpressMail( FRAME_PCB, MAIL_IMPORT_FILE,
wxString::Format( "%d\n%s", IO_MGR::EAGLE, pcb.GetFullPath() ).ToStdString(), this );
// On Windows, Raise() does not bring the window on screen, when iconized // On Windows, Raise() does not bring the window on screen, when iconized
if( pcbframe->IsIconized() ) if( pcbframe->IsIconized() )
pcbframe->Iconize( false ); pcbframe->Iconize( false );
pcbframe->Raise(); pcbframe->Raise();
// Two stage project update:
// - first, assign valid timestamps to footprints
// - second, perform schematic annotation and update footprint references
pcbframe->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST, "no-annotate;by-reference", this );
pcbframe->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST, "quiet-annotate;by-timestamp", this );
pcbframe->FixEagleNets();
} }
ReCreateTreePrj(); ReCreateTreePrj();

View File

@ -411,6 +411,30 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
break; break;
} }
case MAIL_IMPORT_FILE:
{
// Extract file format type and path (plugin type and path separated with \n)
size_t split = payload.find( '\n' );
wxCHECK( split != std::string::npos, /*void*/ );
int importFormat;
try
{
importFormat = std::stoi( payload.substr( 0, split ) );
}
catch( std::invalid_argument& e )
{
wxFAIL;
importFormat = -1;
}
std::string path = payload.substr( split + 1 );
wxASSERT( !path.empty() );
if( importFormat >= 0 )
importFile( path, importFormat );
}
// many many others. // many many others.
default: default:
; ;

View File

@ -836,7 +836,7 @@ bool PCB_EDIT_FRAME::doAutoSave()
} }
bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType ) bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
{ {
switch( (IO_MGR::PCB_FILE_T) aFileType ) switch( (IO_MGR::PCB_FILE_T) aFileType )
{ {
@ -854,15 +854,15 @@ bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
UpdateTitle(); UpdateTitle();
OnModify(); OnModify();
// Extract a footprint library from the design and add it to the fp-lib-table
wxString newLibPath; wxString newLibPath;
ArchiveModulesOnBoard( true, newfilename.GetName(), &newLibPath ); ArchiveModulesOnBoard( true, newfilename.GetName(), &newLibPath );
if( newLibPath.Length()>0 ) if( newLibPath.Length() > 0 )
{ {
FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs(); FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs();
const wxString& project_env = PROJECT_VAR_NAME; const wxString& project_env = PROJECT_VAR_NAME;
wxString rel_path; wxString rel_path, env_path;
wxString env_path;
wxGetEnv( project_env, &env_path ); wxGetEnv( project_env, &env_path );
@ -874,9 +874,7 @@ bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
newLibPath = rel_path; newLibPath = rel_path;
FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(), FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(),
newLibPath, newLibPath, wxT( "KiCad" ), wxEmptyString );
wxT( "KiCad" ),
wxEmptyString ); // options
prjlibtable->InsertRow( row ); prjlibtable->InsertRow( row );
} }
@ -893,12 +891,23 @@ bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
wxString msg = wxString::Format( _( wxString msg = wxString::Format( _(
"Error occurred saving project specific footprint library " "Error occurred saving project specific footprint library "
"table:\n\n%s" ), "table:\n\n%s" ),
GetChars( ioe.What() ) GetChars( ioe.What() ) );
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }
// Two stage netlist update:
// - first, assign valid timestamps to footprints (no reannotation)
// - second, perform schematic annotation and update footprint references
// based on timestamps
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST,
"no-annotate;by-reference", this );
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST,
"quiet-annotate;by-timestamp", this );
fixEagleNets();
return true; return true;
} }
@ -912,53 +921,49 @@ bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
} }
bool PCB_EDIT_FRAME::FixEagleNets() bool PCB_EDIT_FRAME::fixEagleNets()
{ {
KIWAY_PLAYER* schematicFrame = Kiway().Player( FRAME_SCH, false ); KIWAY_PLAYER* schematicFrame = Kiway().Player( FRAME_SCH, false );
// if the schematic file was also loaded. Fix any instances of ophaned zones and vias. // if the schematic file was also loaded. Fix any instances of ophaned zones and vias.
if( schematicFrame ) if( !schematicFrame )
return false;
// Get list of nets from schematic.
wxArrayString nets = schematicFrame->ListNets();
// perform netlist matching to prevent ophaned zones.
for( auto zone : GetBoard()->Zones() )
{ {
// Get list of nets from schematic. wxString zoneNet = zone->GetNet()->GetNetname();
wxArrayString nets = schematicFrame->ListNets(); wxString localNet = "/" + zoneNet;
// perform netlist matching to prevent ophaned zones. for( unsigned int i = 0; i < nets.GetCount(); i++ )
for( auto zone : GetBoard()->Zones() )
{ {
wxString zoneNet = zone->GetNet()->GetNetname(); if( nets[i].EndsWith( localNet ) )
wxString localNet = "/" + zoneNet;
for( int i = 0; i < nets.GetCount(); i++ )
{ {
if( nets[i].EndsWith( localNet ) ) NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] );
{
NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] );
if( net ) if( net )
{ zone->SetNetCode( net->GetNet() );
zone->SetNetCode( net->GetNet() );
}
}
} }
} }
}
// perform netlist matching to prevent ophaned tracks/vias. // perform netlist matching to prevent ophaned tracks/vias.
for( auto track : GetBoard()->Tracks() ) for( auto track : GetBoard()->Tracks() )
{
wxString trackNet = track->GetNet()->GetNetname();
wxString localNet = "/" + trackNet;
for( unsigned int i = 0; i < nets.GetCount(); i++ )
{ {
wxString trackNet = track->GetNet()->GetNetname(); if( nets[i].EndsWith( localNet ) )
wxString localNet = "/" + trackNet;
for( int i = 0; i < nets.GetCount(); i++ )
{ {
if( nets[i].EndsWith( localNet ) ) NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] );
{
NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] );
if( net ) if( net )
{ track->SetNetCode( net->GetNet() );
track->SetNetCode( net->GetNet() );
}
}
} }
} }
} }

View File

@ -233,6 +233,18 @@ protected:
*/ */
void duplicateItems( bool aIncrement ) override; void duplicateItems( bool aIncrement ) override;
/**
* Load the given filename but sets the path to the current project path.
* @param full filepath of file to be imported.
* @param aFileType PCB_FILE_T value for filetype
*/
bool importFile( const wxString& aFileName, int aFileType );
/**
* Rematch orphaned zones and vias to schematic nets.
*/
bool fixEagleNets();
// protected so that PCB::IFACE::CreateWindow() is the only factory. // protected so that PCB::IFACE::CreateWindow() is the only factory.
PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ); PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
@ -869,19 +881,6 @@ public:
*/ */
bool AppendBoardFile( const wxString& aFullFileName, int aCtl ); bool AppendBoardFile( const wxString& aFullFileName, int aCtl );
/**
* Function ImportFile
* load the given filename but sets the path to the current project path.
* @param full filepath of file to be imported.
* @param aFileType PCB_FILE_T value for filetype
*/
bool ImportFile( const wxString& aFileName, int aFileType ) override;
/**
* Rematch ophaned zones and vias to schematic nets.
*/
bool FixEagleNets() override;
/** /**
* Function SavePcbFile * Function SavePcbFile
* writes the board data structures to \a a aFileName * writes the board data structures to \a a aFileName