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
|
// Since this will be called from python, cannot assume that code will
|
||||||
// not pass a bad aFaceId.
|
// 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
|
// @todo : throw an exception here for python's benefit, at least that
|
||||||
// way it gets some explanatory text.
|
// 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
|
// Since this will be called from python, cannot assume that code will
|
||||||
// not pass a bad aFrameType.
|
// 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
|
// @todo : throw an exception here for python's benefit, at least that
|
||||||
// way it gets some explanatory text.
|
// 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
|
// Since this will be called from python, cannot assume that code will
|
||||||
// not pass a bad aFrameType.
|
// 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
|
// @todo : throw an exception here for python's benefit, at least that
|
||||||
// way it gets some explanatory text.
|
// way it gets some explanatory text.
|
||||||
|
@ -383,8 +383,7 @@ bool KIWAY::PlayersClose( bool doForce )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void KIWAY::ExpressMail( FRAME_T aDestination,
|
void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload, wxWindow* aSource )
|
||||||
MAIL_T aCommand, std::string aPayload, wxWindow* aSource )
|
|
||||||
{
|
{
|
||||||
KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource );
|
KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource );
|
||||||
|
|
||||||
|
@ -481,9 +480,9 @@ bool KIWAY::ProcessEvent( wxEvent& aEvent )
|
||||||
|
|
||||||
void KIWAY::OnKiwayEnd()
|
void KIWAY::OnKiwayEnd()
|
||||||
{
|
{
|
||||||
for( unsigned i=0; i < arrayDim( m_kiface ); ++i )
|
for( KIFACE* i : m_kiface )
|
||||||
{
|
{
|
||||||
if( m_kiface[i] )
|
if( i )
|
||||||
m_kiface[i]->OnKifaceEnd();
|
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 ) :
|
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,
|
KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
|
||||||
const std::string& aPayload, wxWindow* aSource ) :
|
wxWindow* aSource ) :
|
||||||
wxEvent( aCommand, wxEVENT_ID ),
|
wxEvent( aCommand, wxEVENT_ID ),
|
||||||
m_destination( aDestination ),
|
m_destination( aDestination ),
|
||||||
m_payload( aPayload )
|
m_payload( aPayload )
|
||||||
|
|
|
@ -976,10 +976,6 @@ void CVPCB_MAINFRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIL_STATUS:
|
|
||||||
SetStatusText( payload, 1 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
; // ignore most
|
; // ignore most
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,14 +373,22 @@ bool CVPCB_MAINFRAME::ReadNetListAndFpFiles( const std::string& aNetlist )
|
||||||
|
|
||||||
bool CVPCB_MAINFRAME::SaveFootprintAssociation( bool doSaveSchematic )
|
bool CVPCB_MAINFRAME::SaveFootprintAssociation( bool doSaveSchematic )
|
||||||
{
|
{
|
||||||
|
std::string payload;
|
||||||
STRING_FORMATTER sf;
|
STRING_FORMATTER sf;
|
||||||
|
|
||||||
m_netlist.FormatBackAnnotation( &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 )
|
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_component.h>
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
#include <sch_view.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.
|
* 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 )
|
void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||||
{
|
{
|
||||||
const std::string& payload = mail.GetPayload();
|
std::string& payload = mail.GetPayload();
|
||||||
|
|
||||||
switch( mail.Command() )
|
switch( mail.Command() )
|
||||||
{
|
{
|
||||||
|
@ -259,8 +260,33 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||||
ExecuteRemoteCommand( payload.c_str() );
|
ExecuteRemoteCommand( payload.c_str() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIL_SCH_PCB_UPDATE_REQUEST:
|
case MAIL_SCH_GET_NETLIST:
|
||||||
doUpdatePcb( payload );
|
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;
|
break;
|
||||||
|
|
||||||
case MAIL_BACKANNOTATE_FOOTPRINTS:
|
case MAIL_BACKANNOTATE_FOOTPRINTS:
|
||||||
|
@ -311,7 +337,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||||
|
|
||||||
case MAIL_SCH_SAVE:
|
case MAIL_SCH_SAVE:
|
||||||
if( SaveProject() )
|
if( SaveProject() )
|
||||||
Kiway().ExpressMail( FRAME_CVPCB, MAIL_STATUS, _( "Schematic saved" ).ToStdString() );
|
payload = "success";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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
|
// There may be no parent window so use KIWAY message to refresh the schematic editor
|
||||||
// in case any symbols have changed.
|
// 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()
|
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 );
|
NETLIST_EXPORTER_KICAD exporter( this, net_atoms, g_ConnectionGraph );
|
||||||
|
STRING_FORMATTER formatter;
|
||||||
STRING_FORMATTER formatter;
|
|
||||||
|
|
||||||
// @todo : trim GNL_ALL down to minimum for CVPCB
|
// @todo : trim GNL_ALL down to minimum for CVPCB
|
||||||
exporter.Format( &formatter, GNL_ALL );
|
exporter.Format( &formatter, GNL_ALL );
|
||||||
|
|
||||||
Kiway().ExpressMail( FRAME_CVPCB,
|
std::string packet = formatter.GetString(); // an abbreviated "kicad" (s-expr) netlist
|
||||||
MAIL_EESCHEMA_NETLIST,
|
Kiway().ExpressMail( FRAME_CVPCB, MAIL_EESCHEMA_NETLIST, packet, this );
|
||||||
formatter.GetString(), // an abbreviated "kicad" (s-expr) netlist
|
|
||||||
this
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,7 @@
|
||||||
#include <build_version.h>
|
#include <build_version.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
|
||||||
#include <netlist_exporter_kicad.h>
|
|
||||||
#include <connection_graph.h>
|
#include <connection_graph.h>
|
||||||
#include <kiway.h>
|
|
||||||
#include <dialogs/dialog_fields_editor_global.h>
|
#include <dialogs/dialog_fields_editor_global.h>
|
||||||
|
|
||||||
#include <sch_view.h>
|
#include <sch_view.h>
|
||||||
|
@ -886,58 +884,8 @@ void SCH_EDIT_FRAME::CloseErc()
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event )
|
void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
doUpdatePcb( "" );
|
std::string payload;
|
||||||
}
|
Kiway().ExpressMail( FRAME_PCB, MAIL_PCB_UPDATE, payload, this );
|
||||||
|
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1559,16 +1559,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void RecalculateConnections();
|
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 );
|
void SetCurrentSheet( SCH_SHEET_PATH *aSheet );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -344,7 +344,7 @@ public:
|
||||||
* aCommand in there.
|
* aCommand in there.
|
||||||
*/
|
*/
|
||||||
VTBL_ENTRY void ExpressMail( FRAME_T aDestination, MAIL_T aCommand,
|
VTBL_ENTRY void ExpressMail( FRAME_T aDestination, MAIL_T aCommand,
|
||||||
std::string aPayload, wxWindow* aSource = NULL );
|
std::string& aPayload, wxWindow* aSource = NULL );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Prj
|
* Function Prj
|
||||||
|
@ -395,7 +395,7 @@ private:
|
||||||
|
|
||||||
bool set_kiface( FACE_T aFaceType, KIFACE* aKiface )
|
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;
|
m_kiface[aFaceType] = aKiface;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -59,17 +59,15 @@ public:
|
||||||
* returns the payload, which can be any text but it typicall self
|
* returns the payload, which can be any text but it typicall self
|
||||||
* identifying s-expression.
|
* 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; }
|
void SetPayload( const std::string& aPayload ) { m_payload = aPayload; }
|
||||||
|
|
||||||
KIWAY_EXPRESS* Clone() const override { return new KIWAY_EXPRESS( *this ); }
|
KIWAY_EXPRESS* Clone() const override { return new KIWAY_EXPRESS( *this ); }
|
||||||
|
|
||||||
//KIWAY_EXPRESS() {}
|
//KIWAY_EXPRESS() {}
|
||||||
|
|
||||||
KIWAY_EXPRESS( FRAME_T aDestination,
|
KIWAY_EXPRESS( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
|
||||||
MAIL_T aCommand,
|
wxWindow* aSource = NULL );
|
||||||
const std::string& aPayload,
|
|
||||||
wxWindow* aSource = NULL );
|
|
||||||
|
|
||||||
KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther );
|
KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther );
|
||||||
|
|
||||||
|
@ -82,7 +80,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FRAME_T m_destination; ///< could have been a bitmap indicating multiple recipients
|
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.
|
// possible new ideas here.
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,19 +40,13 @@ enum MAIL_T
|
||||||
MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing
|
MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing
|
||||||
MAIL_SCH_SAVE, ///< CVPCB->SCH save the schematic
|
MAIL_SCH_SAVE, ///< CVPCB->SCH save the schematic
|
||||||
MAIL_EESCHEMA_NETLIST, ///< SCH->CVPCB netlist immediately after launching CVPCB
|
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
|
MAIL_IMPORT_FILE, ///< Import a different format file
|
||||||
|
MAIL_SCH_GET_NETLIST, ///< Fetch a netlist
|
||||||
///< 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_REFRESH, ///< The the schematic editor to refresh the display.
|
MAIL_SCH_REFRESH, ///< The the schematic editor to refresh the display.
|
||||||
|
|
||||||
MAIL_LIB_EDIT,
|
MAIL_LIB_EDIT,
|
||||||
MAIL_FP_EDIT,
|
MAIL_FP_EDIT
|
||||||
|
|
||||||
///< General-puspose messages
|
|
||||||
MAIL_STATUS
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAIL_TYPE_H_
|
#endif // MAIL_TYPE_H_
|
||||||
|
|
|
@ -141,9 +141,8 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE,
|
std::string packet = wxString::Format( "%d\n%s", SCH_IO_MGR::SCH_EAGLE, sch.GetFullPath() );
|
||||||
wxString::Format( "%d\n%s", SCH_IO_MGR::SCH_EAGLE,
|
schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this );
|
||||||
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.
|
||||||
|
@ -184,8 +183,8 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
|
||||||
pcbframe->Show( true );
|
pcbframe->Show( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
pcbframe->Kiway().ExpressMail( FRAME_PCB, MAIL_IMPORT_FILE,
|
std::string packet = wxString::Format( "%d\n%s", IO_MGR::EAGLE, pcb.GetFullPath() );
|
||||||
wxString::Format( "%d\n%s", IO_MGR::EAGLE, pcb.GetFullPath() ).ToStdString(), this );
|
pcbframe->Kiway().ExpressMail( FRAME_PCB, MAIL_IMPORT_FILE, packet, 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() )
|
||||||
|
|
|
@ -256,7 +256,9 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* aTreePrjFrame )
|
||||||
{
|
{
|
||||||
wxCommandEvent dummy;
|
wxCommandEvent dummy;
|
||||||
frame->OnRunPcbFpEditor( 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;
|
break;
|
||||||
|
|
||||||
|
@ -264,7 +266,9 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* aTreePrjFrame )
|
||||||
{
|
{
|
||||||
wxCommandEvent dummy;
|
wxCommandEvent dummy;
|
||||||
frame->OnRunSchLibEditor( 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;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,6 @@
|
||||||
|
|
||||||
#include <collectors.h>
|
#include <collectors.h>
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
#include <board_netlist_updater.h>
|
|
||||||
#include <netlist_reader.h>
|
|
||||||
#include <pcb_netlist.h>
|
#include <pcb_netlist.h>
|
||||||
#include <dialogs/dialog_update_pcb.h>
|
#include <dialogs/dialog_update_pcb.h>
|
||||||
|
|
||||||
|
@ -384,56 +382,12 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||||
ExecuteRemoteCommand( payload.c_str() );
|
ExecuteRemoteCommand( payload.c_str() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIL_SCH_PCB_UPDATE:
|
case MAIL_PCB_UPDATE:
|
||||||
{
|
{
|
||||||
NETLIST netlist;
|
NETLIST netlist;
|
||||||
size_t split = payload.find( '\n' );
|
|
||||||
wxCHECK( split != std::string::npos, /*void*/ );
|
|
||||||
|
|
||||||
// Extract options and netlist
|
if( FetchNetlistFromSchematic( netlist, ANNOTATION_DIALOG ) )
|
||||||
std::string options = payload.substr( 0, split );
|
UpdatePCBFromNetlist( netlist );
|
||||||
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" );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#include <kiway_player.h>
|
#include <kiway_player.h>
|
||||||
#include <trace_helpers.h>
|
#include <trace_helpers.h>
|
||||||
#include <lockfile.cpp>
|
#include <lockfile.cpp>
|
||||||
|
#include <pcb_netlist.h>
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
#include <pcbnew_id.h>
|
#include <pcbnew_id.h>
|
||||||
#include <io_mgr.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)
|
// - first, assign valid timestamps to footprints (no reannotation)
|
||||||
// - second, perform schematic annotation and update footprint references
|
// - second, perform schematic annotation and update footprint references
|
||||||
// based on timestamps
|
// based on timestamps
|
||||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST,
|
NETLIST netlist;
|
||||||
"no-annotate;by-reference", this );
|
FetchNetlistFromSchematic( netlist, NO_ANNOTATION );
|
||||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST,
|
DoUpdatePCBFromNetlist( netlist, false );
|
||||||
"quiet-annotate;by-timestamp", this );
|
FetchNetlistFromSchematic( netlist, QUIET_ANNOTATION );
|
||||||
|
DoUpdatePCBFromNetlist( netlist, true );
|
||||||
|
|
||||||
std::unordered_map<wxString, wxString> netRemap;
|
std::unordered_map<wxString, wxString> netRemap;
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include <dialog_edit_footprint_for_BoardEditor.h>
|
#include <dialog_edit_footprint_for_BoardEditor.h>
|
||||||
#include <dialog_board_setup.h>
|
#include <dialog_board_setup.h>
|
||||||
#include <dialog_configure_paths.h>
|
#include <dialog_configure_paths.h>
|
||||||
|
#include <dialog_update_pcb.h>
|
||||||
#include <convert_to_biu.h>
|
#include <convert_to_biu.h>
|
||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
|
@ -70,9 +71,13 @@
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tool/tool_dispatcher.h>
|
#include <tool/tool_dispatcher.h>
|
||||||
#include <tools/pcb_actions.h>
|
#include <tools/pcb_actions.h>
|
||||||
|
#include <tools/selection_tool.h>
|
||||||
#include <gestfich.h>
|
#include <gestfich.h>
|
||||||
#include <executable_names.h>
|
#include <executable_names.h>
|
||||||
#include <eda_dockart.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)
|
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
|
||||||
#include <python_scripting.h>
|
#include <python_scripting.h>
|
||||||
|
@ -1150,6 +1155,15 @@ void PCB_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
|
||||||
|
|
||||||
|
|
||||||
void PCB_EDIT_FRAME::OnUpdatePCBFromSch( wxCommandEvent& event )
|
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() )
|
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 "
|
"opened in stand-alone mode. In order to create or update "
|
||||||
"PCBs from schematics, you need to launch the KiCad project manager "
|
"PCBs from schematics, you need to launch the KiCad project manager "
|
||||||
"and create a PCB project." ) );
|
"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
|
wxFileName schfn( Prj().GetProjectPath(), Prj().GetProjectName(), SchematicFileExtension );
|
||||||
// If this is not the case, open the schematic editor
|
|
||||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true );
|
|
||||||
|
|
||||||
if( !frame->IsShown() )
|
frame->OpenProjectFiles( std::vector<wxString>( 1, schfn.GetFullPath() ) );
|
||||||
{
|
// Because the schematic editor frame is not on screen, iconize it:
|
||||||
wxFileName schfn( Prj().GetProjectPath(), Prj().GetProjectName(), SchematicFileExtension );
|
// However, another valid option is to do not iconize the schematic editor frame
|
||||||
|
// and show it
|
||||||
frame->OpenProjectFiles( std::vector<wxString>( 1, schfn.GetFullPath() ) );
|
frame->Iconize( true );
|
||||||
// Because the schematic editor frame is not on screen, iconize it:
|
// we show the schematic editor frame, because do not show is seen as
|
||||||
// However, another valid option is to do not iconize the schematic editor frame
|
// a not yet opened schematic by Kicad manager, which is not the case
|
||||||
// and show it
|
frame->Show( true );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
// netlist handling:
|
||||||
void InstallNetlistFrame( wxDC* DC );
|
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
|
* Function ReadPcbNetlist
|
||||||
* reads \a aNetlistFileName and updates the footprints (load missing footprints and
|
* reads \a aNetlistFileName and updates the footprints (load missing footprints and
|
||||||
|
|
Loading…
Reference in New Issue