Support synchronous messaging over KIWAY EXPRESS.
This allows us to make the various netlist and pcb update routines more atomic and less reliant on carefully sequenced asynchronous messages. This is also a prelude to adding support for footprint testing without a netlist.
This commit is contained in:
parent
52e3a1d7c4
commit
77f15eeeaf
|
@ -149,7 +149,7 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
|||
{
|
||||
// Since this will be called from python, cannot assume that code will
|
||||
// not pass a bad aFaceId.
|
||||
if( unsigned( aFaceId ) >= arrayDim( m_kiface ) )
|
||||
if( (unsigned) aFaceId >= arrayDim( m_kiface ) )
|
||||
{
|
||||
// @todo : throw an exception here for python's benefit, at least that
|
||||
// way it gets some explanatory text.
|
||||
|
@ -301,7 +301,7 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow
|
|||
{
|
||||
// Since this will be called from python, cannot assume that code will
|
||||
// not pass a bad aFrameType.
|
||||
if( unsigned( aFrameType ) >= KIWAY_PLAYER_COUNT )
|
||||
if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
|
||||
{
|
||||
// @todo : throw an exception here for python's benefit, at least that
|
||||
// way it gets some explanatory text.
|
||||
|
@ -349,7 +349,7 @@ bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
|
|||
{
|
||||
// Since this will be called from python, cannot assume that code will
|
||||
// not pass a bad aFrameType.
|
||||
if( unsigned( aFrameType ) >= KIWAY_PLAYER_COUNT )
|
||||
if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
|
||||
{
|
||||
// @todo : throw an exception here for python's benefit, at least that
|
||||
// way it gets some explanatory text.
|
||||
|
@ -383,8 +383,7 @@ bool KIWAY::PlayersClose( bool doForce )
|
|||
}
|
||||
|
||||
|
||||
void KIWAY::ExpressMail( FRAME_T aDestination,
|
||||
MAIL_T aCommand, std::string aPayload, wxWindow* aSource )
|
||||
void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload, wxWindow* aSource )
|
||||
{
|
||||
KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource );
|
||||
|
||||
|
@ -481,9 +480,9 @@ bool KIWAY::ProcessEvent( wxEvent& aEvent )
|
|||
|
||||
void KIWAY::OnKiwayEnd()
|
||||
{
|
||||
for( unsigned i=0; i < arrayDim( m_kiface ); ++i )
|
||||
for( KIFACE* i : m_kiface )
|
||||
{
|
||||
if( m_kiface[i] )
|
||||
m_kiface[i]->OnKifaceEnd();
|
||||
if( i )
|
||||
i->OnKifaceEnd();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,15 +42,15 @@ const wxEventType KIWAY_EXPRESS::wxEVENT_ID = 30000; // commmon accross all l
|
|||
|
||||
|
||||
KIWAY_EXPRESS::KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ) :
|
||||
wxEvent( anOther )
|
||||
wxEvent( anOther ),
|
||||
m_destination( anOther.m_destination ),
|
||||
m_payload( anOther.m_payload )
|
||||
{
|
||||
m_destination = anOther.m_destination;
|
||||
m_payload = anOther.m_payload;
|
||||
}
|
||||
|
||||
|
||||
KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, MAIL_T aCommand,
|
||||
const std::string& aPayload, wxWindow* aSource ) :
|
||||
KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
|
||||
wxWindow* aSource ) :
|
||||
wxEvent( aCommand, wxEVENT_ID ),
|
||||
m_destination( aDestination ),
|
||||
m_payload( aPayload )
|
||||
|
|
|
@ -976,10 +976,6 @@ void CVPCB_MAINFRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||
*/
|
||||
break;
|
||||
|
||||
case MAIL_STATUS:
|
||||
SetStatusText( payload, 1 );
|
||||
break;
|
||||
|
||||
default:
|
||||
; // ignore most
|
||||
}
|
||||
|
|
|
@ -373,14 +373,22 @@ bool CVPCB_MAINFRAME::ReadNetListAndFpFiles( const std::string& aNetlist )
|
|||
|
||||
bool CVPCB_MAINFRAME::SaveFootprintAssociation( bool doSaveSchematic )
|
||||
{
|
||||
std::string payload;
|
||||
STRING_FORMATTER sf;
|
||||
|
||||
m_netlist.FormatBackAnnotation( &sf );
|
||||
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_BACKANNOTATE_FOOTPRINTS, sf.GetString() );
|
||||
payload = sf.GetString();
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_BACKANNOTATE_FOOTPRINTS, payload );
|
||||
|
||||
if( doSaveSchematic )
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_SAVE, std::string( "" ) );
|
||||
{
|
||||
payload = "";
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_SAVE, payload );
|
||||
|
||||
return true; // we can't tell if it was successful, so just assume the best
|
||||
if( payload == "success" )
|
||||
SetStatusText( _( "Schematic saved" ), 1 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
#include <sch_component.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_view.h>
|
||||
|
||||
#include <reporter.h>
|
||||
#include <netlist_exporters/netlist_exporter_kicad.h>
|
||||
|
||||
/**
|
||||
* Execute a remote command sent by Pcbnew via a socket connection.
|
||||
|
@ -251,7 +252,7 @@ void SCH_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
|
|||
|
||||
void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||
{
|
||||
const std::string& payload = mail.GetPayload();
|
||||
std::string& payload = mail.GetPayload();
|
||||
|
||||
switch( mail.Command() )
|
||||
{
|
||||
|
@ -259,8 +260,33 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||
ExecuteRemoteCommand( payload.c_str() );
|
||||
break;
|
||||
|
||||
case MAIL_SCH_PCB_UPDATE_REQUEST:
|
||||
doUpdatePcb( payload );
|
||||
case MAIL_SCH_GET_NETLIST:
|
||||
if( payload.find( "quiet-annotate" ) != std::string::npos )
|
||||
{
|
||||
SCH_SCREENS schematic;
|
||||
schematic.UpdateSymbolLinks();
|
||||
SCH_SHEET_LIST sheets( g_RootSheet );
|
||||
sheets.AnnotatePowerSymbols();
|
||||
AnnotateComponents( true, UNSORTED, INCREMENTAL_BY_REF, 0, false, false, true,
|
||||
NULL_REPORTER::GetInstance() );
|
||||
}
|
||||
|
||||
if( payload.find( "no-annotate" ) == std::string::npos )
|
||||
{
|
||||
// Ensure schematic is OK for netlist creation (especially that it is fully annotated):
|
||||
if( !prepareForNetlist() )
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
|
||||
NETLIST_EXPORTER_KICAD exporter( this, net_atoms );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
exporter.Format( &formatter, GNL_ALL );
|
||||
|
||||
payload = formatter.GetString();
|
||||
}
|
||||
break;
|
||||
|
||||
case MAIL_BACKANNOTATE_FOOTPRINTS:
|
||||
|
@ -311,7 +337,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||
|
||||
case MAIL_SCH_SAVE:
|
||||
if( SaveProject() )
|
||||
Kiway().ExpressMail( FRAME_CVPCB, MAIL_STATUS, _( "Schematic saved" ).ToStdString() );
|
||||
payload = "success";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1495,7 +1495,8 @@ void LIB_EDIT_FRAME::refreshSchematic()
|
|||
{
|
||||
// There may be no parent window so use KIWAY message to refresh the schematic editor
|
||||
// in case any symbols have changed.
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_REFRESH, std::string( "" ), this );
|
||||
std::string dummyPayload;
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_REFRESH, dummyPayload, this );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -193,20 +193,15 @@ bool SCH_EDIT_FRAME::prepareForNetlist()
|
|||
|
||||
void SCH_EDIT_FRAME::sendNetlistToCvpcb()
|
||||
{
|
||||
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
|
||||
|
||||
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
|
||||
NETLIST_EXPORTER_KICAD exporter( this, net_atoms, g_ConnectionGraph );
|
||||
|
||||
STRING_FORMATTER formatter;
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
// @todo : trim GNL_ALL down to minimum for CVPCB
|
||||
exporter.Format( &formatter, GNL_ALL );
|
||||
|
||||
Kiway().ExpressMail( FRAME_CVPCB,
|
||||
MAIL_EESCHEMA_NETLIST,
|
||||
formatter.GetString(), // an abbreviated "kicad" (s-expr) netlist
|
||||
this
|
||||
);
|
||||
std::string packet = formatter.GetString(); // an abbreviated "kicad" (s-expr) netlist
|
||||
Kiway().ExpressMail( FRAME_CVPCB, MAIL_EESCHEMA_NETLIST, packet, this );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -68,9 +68,7 @@
|
|||
#include <build_version.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <netlist_exporter_kicad.h>
|
||||
#include <connection_graph.h>
|
||||
#include <kiway.h>
|
||||
#include <dialogs/dialog_fields_editor_global.h>
|
||||
|
||||
#include <sch_view.h>
|
||||
|
@ -886,58 +884,8 @@ void SCH_EDIT_FRAME::CloseErc()
|
|||
|
||||
void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event )
|
||||
{
|
||||
doUpdatePcb( "" );
|
||||
}
|
||||
|
||||
|
||||
void SCH_EDIT_FRAME::doUpdatePcb( const wxString& aUpdateOptions )
|
||||
{
|
||||
wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
|
||||
|
||||
fn.SetExt( PcbFileExtension );
|
||||
|
||||
if( Kiface().IsSingle() )
|
||||
{
|
||||
DisplayError( this, _( "Cannot update the PCB, because the Schematic Editor is"
|
||||
" opened in stand-alone mode. In order to create/update"
|
||||
" PCBs from schematics, you need to launch Kicad shell"
|
||||
" and create a PCB project." ) );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB, true );
|
||||
|
||||
// a pcb frame can be already existing, but not yet used.
|
||||
// this is the case when running the footprint editor, or the footprint viewer first
|
||||
// if the frame is not visible, the board is not yet loaded
|
||||
if( !frame->IsVisible() )
|
||||
{
|
||||
frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
|
||||
frame->Show( true );
|
||||
}
|
||||
|
||||
// On Windows, Raise() does not bring the window on screen, when iconized
|
||||
if( frame->IsIconized() )
|
||||
frame->Iconize( false );
|
||||
|
||||
frame->Raise();
|
||||
}
|
||||
|
||||
auto net_atoms = CreateNetlist( aUpdateOptions.Contains( "no-annotate" ),
|
||||
aUpdateOptions.Contains( "quiet-annotate" ) );
|
||||
|
||||
NETLIST_EXPORTER_KICAD exporter( this, net_atoms, g_ConnectionGraph );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
exporter.Format( &formatter, GNL_ALL );
|
||||
|
||||
auto updateOptions = aUpdateOptions.ToStdString();
|
||||
auto netlistString = formatter.GetString();
|
||||
auto finalNetlist = updateOptions + "\n" + netlistString;
|
||||
|
||||
// Now, send the "kicad" (s-expr) netlist to Pcbnew
|
||||
Kiway().ExpressMail( FRAME_PCB, MAIL_SCH_PCB_UPDATE, finalNetlist, this );
|
||||
std::string payload;
|
||||
Kiway().ExpressMail( FRAME_PCB, MAIL_PCB_UPDATE, payload, this );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1559,16 +1559,6 @@ public:
|
|||
*/
|
||||
void RecalculateConnections();
|
||||
|
||||
/**
|
||||
* Updates netlist and sends it to pcbnew.
|
||||
* @param aUpdateOptions is a string defining update options:
|
||||
* - "no-annotate" does not perform schematic annotation
|
||||
* - "quiet-annotate" performs schematic annotation without showing annotation dialog
|
||||
* aUpdateOptions may also contain other options accepted for netlist reader.
|
||||
* @see PCB_EDIT_FRAME::KiwayMailIn()
|
||||
*/
|
||||
void doUpdatePcb( const wxString& aUpdateOptions = "" );
|
||||
|
||||
void SetCurrentSheet( SCH_SHEET_PATH *aSheet );
|
||||
|
||||
/**
|
||||
|
|
|
@ -344,7 +344,7 @@ public:
|
|||
* aCommand in there.
|
||||
*/
|
||||
VTBL_ENTRY void ExpressMail( FRAME_T aDestination, MAIL_T aCommand,
|
||||
std::string aPayload, wxWindow* aSource = NULL );
|
||||
std::string& aPayload, wxWindow* aSource = NULL );
|
||||
|
||||
/**
|
||||
* Function Prj
|
||||
|
@ -395,7 +395,7 @@ private:
|
|||
|
||||
bool set_kiface( FACE_T aFaceType, KIFACE* aKiface )
|
||||
{
|
||||
if( unsigned( aFaceType ) < unsigned( KIWAY_FACE_COUNT ) )
|
||||
if( (unsigned) aFaceType < (unsigned) KIWAY_FACE_COUNT )
|
||||
{
|
||||
m_kiface[aFaceType] = aKiface;
|
||||
return true;
|
||||
|
|
|
@ -59,17 +59,15 @@ public:
|
|||
* returns the payload, which can be any text but it typicall self
|
||||
* identifying s-expression.
|
||||
*/
|
||||
const std::string& GetPayload() { return m_payload; }
|
||||
std::string& GetPayload() { return m_payload; }
|
||||
void SetPayload( const std::string& aPayload ) { m_payload = aPayload; }
|
||||
|
||||
KIWAY_EXPRESS* Clone() const override { return new KIWAY_EXPRESS( *this ); }
|
||||
|
||||
//KIWAY_EXPRESS() {}
|
||||
|
||||
KIWAY_EXPRESS( FRAME_T aDestination,
|
||||
MAIL_T aCommand,
|
||||
const std::string& aPayload,
|
||||
wxWindow* aSource = NULL );
|
||||
KIWAY_EXPRESS( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
|
||||
wxWindow* aSource = NULL );
|
||||
|
||||
KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther );
|
||||
|
||||
|
@ -82,7 +80,7 @@ public:
|
|||
|
||||
private:
|
||||
FRAME_T m_destination; ///< could have been a bitmap indicating multiple recipients
|
||||
std::string m_payload; ///< very often s-expression text, but not always
|
||||
std::string& m_payload; ///< very often s-expression text, but not always
|
||||
|
||||
// possible new ideas here.
|
||||
};
|
||||
|
|
|
@ -40,19 +40,13 @@ enum MAIL_T
|
|||
MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing
|
||||
MAIL_SCH_SAVE, ///< CVPCB->SCH save the schematic
|
||||
MAIL_EESCHEMA_NETLIST, ///< SCH->CVPCB netlist immediately after launching CVPCB
|
||||
MAIL_SCH_PCB_UPDATE, ///< SCH->PCB forward update
|
||||
MAIL_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)
|
||||
MAIL_SCH_PCB_UPDATE_REQUEST,
|
||||
MAIL_SCH_GET_NETLIST, ///< Fetch a netlist
|
||||
MAIL_SCH_REFRESH, ///< The the schematic editor to refresh the display.
|
||||
|
||||
MAIL_LIB_EDIT,
|
||||
MAIL_FP_EDIT,
|
||||
|
||||
///< General-puspose messages
|
||||
MAIL_STATUS
|
||||
MAIL_FP_EDIT
|
||||
};
|
||||
|
||||
#endif // MAIL_TYPE_H_
|
||||
|
|
|
@ -141,9 +141,8 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
|
|||
}
|
||||
}
|
||||
|
||||
schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE,
|
||||
wxString::Format( "%d\n%s", SCH_IO_MGR::SCH_EAGLE,
|
||||
sch.GetFullPath() ).ToStdString(), this );
|
||||
std::string packet = wxString::Format( "%d\n%s", SCH_IO_MGR::SCH_EAGLE, sch.GetFullPath() );
|
||||
schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this );
|
||||
|
||||
if( !schframe->IsShown() ) // the frame exists, (created by the dialog field editor)
|
||||
// but no project loaded.
|
||||
|
@ -184,8 +183,8 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
|
|||
pcbframe->Show( true );
|
||||
}
|
||||
|
||||
pcbframe->Kiway().ExpressMail( FRAME_PCB, MAIL_IMPORT_FILE,
|
||||
wxString::Format( "%d\n%s", IO_MGR::EAGLE, pcb.GetFullPath() ).ToStdString(), this );
|
||||
std::string packet = wxString::Format( "%d\n%s", IO_MGR::EAGLE, pcb.GetFullPath() );
|
||||
pcbframe->Kiway().ExpressMail( FRAME_PCB, MAIL_IMPORT_FILE, packet, this );
|
||||
|
||||
// On Windows, Raise() does not bring the window on screen, when iconized
|
||||
if( pcbframe->IsIconized() )
|
||||
|
|
|
@ -256,7 +256,9 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* aTreePrjFrame )
|
|||
{
|
||||
wxCommandEvent dummy;
|
||||
frame->OnRunPcbFpEditor( dummy );
|
||||
kiway.ExpressMail( FRAME_PCB_MODULE_EDITOR, MAIL_FP_EDIT, fullFileName.ToStdString() );
|
||||
|
||||
std::string packet = fullFileName.ToStdString();
|
||||
kiway.ExpressMail( FRAME_PCB_MODULE_EDITOR, MAIL_FP_EDIT, packet );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -264,7 +266,9 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* aTreePrjFrame )
|
|||
{
|
||||
wxCommandEvent dummy;
|
||||
frame->OnRunSchLibEditor( dummy );
|
||||
kiway.ExpressMail( FRAME_SCH_LIB_EDITOR, MAIL_LIB_EDIT, fullFileName.ToStdString() );
|
||||
|
||||
std::string packet = fullFileName.ToStdString();
|
||||
kiway.ExpressMail( FRAME_SCH_LIB_EDITOR, MAIL_LIB_EDIT, packet );
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -50,8 +50,6 @@
|
|||
|
||||
#include <collectors.h>
|
||||
#include <pcbnew.h>
|
||||
#include <board_netlist_updater.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <pcb_netlist.h>
|
||||
#include <dialogs/dialog_update_pcb.h>
|
||||
|
||||
|
@ -384,56 +382,12 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||
ExecuteRemoteCommand( payload.c_str() );
|
||||
break;
|
||||
|
||||
case MAIL_SCH_PCB_UPDATE:
|
||||
case MAIL_PCB_UPDATE:
|
||||
{
|
||||
NETLIST netlist;
|
||||
size_t split = payload.find( '\n' );
|
||||
wxCHECK( split != std::string::npos, /*void*/ );
|
||||
|
||||
// Extract options and netlist
|
||||
std::string options = payload.substr( 0, split );
|
||||
std::string netlistData = payload.substr( split + 1 );
|
||||
|
||||
// Quiet update options
|
||||
bool by_reference = options.find( "by-reference" ) != std::string::npos;
|
||||
bool by_timestamp = options.find( "by-timestamp" ) != std::string::npos;
|
||||
wxASSERT( !( by_reference && by_timestamp ) ); // only one at a time please
|
||||
|
||||
try
|
||||
{
|
||||
STRING_LINE_READER* lineReader = new STRING_LINE_READER( netlistData, _( "Eeschema netlist" ) );
|
||||
KICAD_NETLIST_READER netlistReader( lineReader, &netlist );
|
||||
netlistReader.LoadNetlist();
|
||||
}
|
||||
catch( const IO_ERROR& )
|
||||
{
|
||||
assert( false ); // should never happen
|
||||
}
|
||||
|
||||
if( by_reference || by_timestamp )
|
||||
{
|
||||
netlist.SetDeleteExtraFootprints( false );
|
||||
netlist.SetFindByTimeStamp( by_timestamp );
|
||||
netlist.SetReplaceFootprints( true );
|
||||
|
||||
BOARD_NETLIST_UPDATER updater( this, GetBoard() );
|
||||
updater.SetLookupByTimestamp( by_timestamp );
|
||||
updater.SetDeleteUnusedComponents( false );
|
||||
updater.SetReplaceFootprints( true );
|
||||
updater.SetDeleteSinglePadNets( false );
|
||||
updater.UpdateNetlist( netlist );
|
||||
}
|
||||
else
|
||||
{
|
||||
DIALOG_UPDATE_PCB updateDialog( this, &netlist );
|
||||
updateDialog.ShowModal();
|
||||
|
||||
auto selectionTool = static_cast<SELECTION_TOOL*>(
|
||||
m_toolManager->FindTool( "pcbnew.InteractiveSelection" ) );
|
||||
|
||||
if( !selectionTool->GetSelection().Empty() )
|
||||
GetToolManager()->InvokeTool( "pcbnew.InteractiveEdit" );
|
||||
}
|
||||
if( FetchNetlistFromSchematic( netlist, ANNOTATION_DIALOG ) )
|
||||
UpdatePCBFromNetlist( netlist );
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <kiway_player.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <lockfile.cpp>
|
||||
|
||||
#include <pcb_netlist.h>
|
||||
#include <pcbnew.h>
|
||||
#include <pcbnew_id.h>
|
||||
#include <io_mgr.h>
|
||||
|
@ -967,10 +967,11 @@ bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
|
|||
// - 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 );
|
||||
NETLIST netlist;
|
||||
FetchNetlistFromSchematic( netlist, NO_ANNOTATION );
|
||||
DoUpdatePCBFromNetlist( netlist, false );
|
||||
FetchNetlistFromSchematic( netlist, QUIET_ANNOTATION );
|
||||
DoUpdatePCBFromNetlist( netlist, true );
|
||||
|
||||
std::unordered_map<wxString, wxString> netRemap;
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <dialog_edit_footprint_for_BoardEditor.h>
|
||||
#include <dialog_board_setup.h>
|
||||
#include <dialog_configure_paths.h>
|
||||
#include <dialog_update_pcb.h>
|
||||
#include <convert_to_biu.h>
|
||||
#include <view/view.h>
|
||||
#include <view/view_controls.h>
|
||||
|
@ -70,9 +71,13 @@
|
|||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/selection_tool.h>
|
||||
#include <gestfich.h>
|
||||
#include <executable_names.h>
|
||||
#include <eda_dockart.h>
|
||||
#include <board_netlist_updater.h>
|
||||
#include <netlist_reader.h>
|
||||
#include <pcb_netlist.h>
|
||||
|
||||
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
|
||||
#include <python_scripting.h>
|
||||
|
@ -1150,6 +1155,15 @@ void PCB_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
|
|||
|
||||
|
||||
void PCB_EDIT_FRAME::OnUpdatePCBFromSch( wxCommandEvent& event )
|
||||
{
|
||||
NETLIST netlist;
|
||||
|
||||
if( FetchNetlistFromSchematic( netlist, ANNOTATION_DIALOG ) )
|
||||
UpdatePCBFromNetlist( netlist );
|
||||
}
|
||||
|
||||
|
||||
bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist, FETCH_NETLIST_MODE aMode )
|
||||
{
|
||||
if( Kiface().IsSingle() )
|
||||
{
|
||||
|
@ -1157,30 +1171,73 @@ void PCB_EDIT_FRAME::OnUpdatePCBFromSch( wxCommandEvent& event )
|
|||
"opened in stand-alone mode. In order to create or update "
|
||||
"PCBs from schematics, you need to launch the KiCad project manager "
|
||||
"and create a PCB project." ) );
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
// Update PCB requires a netlist. Therefore the schematic editor must be running
|
||||
// If this is not the case, open the schematic editor
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true );
|
||||
|
||||
if( !frame->IsShown() )
|
||||
{
|
||||
// Update PCB requires a netlist. Therefore the schematic editor must be running
|
||||
// If this is not the case, open the schematic editor
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true );
|
||||
wxFileName schfn( Prj().GetProjectPath(), Prj().GetProjectName(), SchematicFileExtension );
|
||||
|
||||
if( !frame->IsShown() )
|
||||
{
|
||||
wxFileName schfn( Prj().GetProjectPath(), Prj().GetProjectName(), SchematicFileExtension );
|
||||
|
||||
frame->OpenProjectFiles( std::vector<wxString>( 1, schfn.GetFullPath() ) );
|
||||
// Because the schematic editor frame is not on screen, iconize it:
|
||||
// However, another valid option is to do not iconize the schematic editor frame
|
||||
// and show it
|
||||
frame->Iconize( true );
|
||||
// we show the schematic editor frame, because do not show is seen as
|
||||
// a not yet opened schematic by Kicad manager, which is not the case
|
||||
frame->Show( true );
|
||||
}
|
||||
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST, "", this );
|
||||
frame->OpenProjectFiles( std::vector<wxString>( 1, schfn.GetFullPath() ) );
|
||||
// Because the schematic editor frame is not on screen, iconize it:
|
||||
// However, another valid option is to do not iconize the schematic editor frame
|
||||
// and show it
|
||||
frame->Iconize( true );
|
||||
// we show the schematic editor frame, because do not show is seen as
|
||||
// a not yet opened schematic by Kicad manager, which is not the case
|
||||
frame->Show( true );
|
||||
}
|
||||
|
||||
std::string payload;
|
||||
|
||||
if( aMode == NO_ANNOTATION )
|
||||
payload = "no-annotate";
|
||||
else if( aMode = QUIET_ANNOTATION )
|
||||
payload = "quiet-annotate";
|
||||
|
||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_GET_NETLIST, payload, this );
|
||||
|
||||
try
|
||||
{
|
||||
auto lineReader = new STRING_LINE_READER( payload, _( "Eeschema netlist" ) );
|
||||
KICAD_NETLIST_READER netlistReader( lineReader, &aNetlist );
|
||||
netlistReader.LoadNetlist();
|
||||
}
|
||||
catch( const IO_ERROR& )
|
||||
{
|
||||
assert( false ); // should never happen
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::UpdatePCBFromNetlist( NETLIST& aNetlist )
|
||||
{
|
||||
DIALOG_UPDATE_PCB updateDialog( this, &aNetlist );
|
||||
updateDialog.ShowModal();
|
||||
|
||||
auto selectionTool = static_cast<SELECTION_TOOL*>(
|
||||
m_toolManager->FindTool( "pcbnew.InteractiveSelection" ) );
|
||||
|
||||
if( !selectionTool->GetSelection().Empty() )
|
||||
GetToolManager()->InvokeTool( "pcbnew.InteractiveEdit" );
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::DoUpdatePCBFromNetlist( NETLIST& aNetlist, bool aUseTimestamps )
|
||||
{
|
||||
BOARD_NETLIST_UPDATER updater( this, GetBoard() );
|
||||
updater.SetLookupByTimestamp( aUseTimestamps );
|
||||
updater.SetDeleteUnusedComponents( false );
|
||||
updater.SetReplaceFootprints( true );
|
||||
updater.SetDeleteSinglePadNets( false );
|
||||
updater.UpdateNetlist( aNetlist );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1559,6 +1559,28 @@ public:
|
|||
// netlist handling:
|
||||
void InstallNetlistFrame( wxDC* DC );
|
||||
|
||||
/**
|
||||
* Function FetchNetlistFromSchematic
|
||||
* @param aNetlist a NETLIST owned by the caller. This function fills it in.
|
||||
* @return true if a netlist was fetched.
|
||||
*/
|
||||
enum FETCH_NETLIST_MODE { NO_ANNOTATION, QUIET_ANNOTATION, ANNOTATION_DIALOG };
|
||||
bool FetchNetlistFromSchematic( NETLIST& aNetlist, FETCH_NETLIST_MODE aMode );
|
||||
|
||||
/**
|
||||
* Function UpdatePCBFromNetlist
|
||||
* @param aNetlist
|
||||
*/
|
||||
void UpdatePCBFromNetlist( NETLIST& aNetlist );
|
||||
|
||||
/**
|
||||
* Function DoUpdatePCBFromNetlist
|
||||
* An automated version of UpdatePCBFromNetlist which skips the UI dialog.
|
||||
* @param aNetlist
|
||||
* @param aUseTimestamps
|
||||
*/
|
||||
void DoUpdatePCBFromNetlist( NETLIST& aNetlist, bool aUseTimestamps );
|
||||
|
||||
/**
|
||||
* Function ReadPcbNetlist
|
||||
* reads \a aNetlistFileName and updates the footprints (load missing footprints and
|
||||
|
|
Loading…
Reference in New Issue