From 1f078f533b3765cc5b5820fe5d824d53ab65f1ff Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 26 Feb 2018 11:34:36 +0100 Subject: [PATCH] Refactor Eagle project import to use Kiway::ExpressMail() --- eeschema/cross-probing.cpp | 24 +++++++++++ eeschema/files-io.cpp | 4 +- eeschema/sch_edit_frame.h | 16 +++---- include/kiway_player.h | 21 --------- include/mail_type.h | 1 + kicad/import_project.cpp | 32 +++++--------- pcbnew/cross-probing.cpp | 24 +++++++++++ pcbnew/files.cpp | 87 ++++++++++++++++++++------------------ pcbnew/pcb_edit_frame.h | 25 ++++++----- 9 files changed, 128 insertions(+), 106 deletions(-) diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 3a14b0f527..2350fe0e9d 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -253,6 +253,30 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) GetCanvas()->Refresh(); 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: ; } diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index 4717d7f8fb..20a067632c 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -676,7 +676,7 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent ) } // 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 ); diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 568df46441..7f4d420062 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -812,14 +812,6 @@ public: 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 * drop them. @@ -1126,6 +1118,14 @@ public: wxPoint GetLastSheetPinPosition() const { return m_lastSheetPinPosition; } 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 ); /** diff --git a/include/kiway_player.h b/include/kiway_player.h index 88c21ffa4a..a2cb4cde09 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -179,27 +179,6 @@ public: 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 . diff --git a/include/mail_type.h b/include/mail_type.h index 152be5dbdd..782477cbf8 100644 --- a/include/mail_type.h +++ b/include/mail_type.h @@ -40,6 +40,7 @@ enum MAIL_T MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing at cvpcb termination MAIL_EESCHEMA_NETLIST, ///< EESCHEMA->CVPCB netlist immediately after launching CVPCB 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 ///< via another mail (kind of bootstrap) diff --git a/kicad/import_project.cpp b/kicad/import_project.cpp index 5ed616d835..62a6ab6216 100644 --- a/kicad/import_project.cpp +++ b/kicad/import_project.cpp @@ -47,11 +47,6 @@ #include #include -#include -#include -#include - -class PCB_EDIT_FRAME; #include "kicad.h" @@ -124,17 +119,16 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event ) SetProjectFileName( pro.GetFullPath() ); wxString prj_filename = GetProjectFileName(); - wxString sch_filename = sch.GetFullPath(); 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 ) { - 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 ) { @@ -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) // but no project loaded. @@ -161,13 +156,13 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event ) 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 ) { - 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 ) { @@ -182,22 +177,17 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event ) // if the frame is not visible, the board is not yet loaded if( !pcbframe->IsVisible() ) { - pcbframe->ImportFile( pcb.GetFullPath(), IO_MGR::EAGLE ); 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 if( pcbframe->IsIconized() ) pcbframe->Iconize( false ); 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(); diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index b1cfbd8934..20284eeaa8 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -411,6 +411,30 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) 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. default: ; diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index af5657d663..dbaff26777 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -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 ) { @@ -854,15 +854,15 @@ bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType ) UpdateTitle(); OnModify(); + // Extract a footprint library from the design and add it to the fp-lib-table wxString newLibPath; ArchiveModulesOnBoard( true, newfilename.GetName(), &newLibPath ); - if( newLibPath.Length()>0 ) + if( newLibPath.Length() > 0 ) { FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs(); const wxString& project_env = PROJECT_VAR_NAME; - wxString rel_path; - wxString env_path; + wxString rel_path, env_path; wxGetEnv( project_env, &env_path ); @@ -874,9 +874,7 @@ bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType ) newLibPath = rel_path; FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(), - newLibPath, - wxT( "KiCad" ), - wxEmptyString ); // options + newLibPath, wxT( "KiCad" ), wxEmptyString ); prjlibtable->InsertRow( row ); } @@ -893,12 +891,23 @@ bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType ) wxString msg = wxString::Format( _( "Error occurred saving project specific footprint library " "table:\n\n%s" ), - GetChars( ioe.What() ) - ); + GetChars( ioe.What() ) ); 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; } @@ -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 ); // 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. - wxArrayString nets = schematicFrame->ListNets(); + wxString zoneNet = zone->GetNet()->GetNetname(); + wxString localNet = "/" + zoneNet; - // perform netlist matching to prevent ophaned zones. - for( auto zone : GetBoard()->Zones() ) + for( unsigned int i = 0; i < nets.GetCount(); i++ ) { - wxString zoneNet = zone->GetNet()->GetNetname(); - wxString localNet = "/" + zoneNet; - - for( int i = 0; i < nets.GetCount(); i++ ) + if( nets[i].EndsWith( localNet ) ) { - if( nets[i].EndsWith( localNet ) ) - { - NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] ); + NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] ); - if( net ) - { - zone->SetNetCode( net->GetNet() ); - } - } + if( net ) + zone->SetNetCode( net->GetNet() ); } } + } - // perform netlist matching to prevent ophaned tracks/vias. - for( auto track : GetBoard()->Tracks() ) + // perform netlist matching to prevent ophaned tracks/vias. + 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(); - wxString localNet = "/" + trackNet; - - for( int i = 0; i < nets.GetCount(); i++ ) + if( nets[i].EndsWith( localNet ) ) { - if( nets[i].EndsWith( localNet ) ) - { - NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] ); + NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] ); - if( net ) - { - track->SetNetCode( net->GetNet() ); - } - } + if( net ) + track->SetNetCode( net->GetNet() ); } } } diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index b9793cd867..b2d5d1e31a 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -233,6 +233,18 @@ protected: */ 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. PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ); @@ -869,19 +881,6 @@ public: */ 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 * writes the board data structures to \a a aFileName