Protect the Kiway dereference

Also find a few more places where we are reaching into a new frame to
perform actions that need to have dialogs closed.

Running actions should also wait for the next cycle rather than being
immediately executed when we are calling into a new frame.  This allow
for the cleanup actions onClose() to happen prior to the next action
starting

Fixes https://gitlab.com/kicad/code/kicad/issues/11891
This commit is contained in:
Seth Hillbrand 2022-07-14 11:36:07 -07:00
parent 00c7b64b13
commit 93fb00d815
6 changed files with 40 additions and 4 deletions

View File

@ -123,6 +123,7 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
if( kiwayHolder ) if( kiwayHolder )
SetKiway( this, &kiwayHolder->Kiway() ); SetKiway( this, &kiwayHolder->Kiway() );
if( HasKiway() )
Kiway().SetBlockingDialog( this ); Kiway().SetBlockingDialog( this );
Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this ); Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
@ -146,6 +147,7 @@ DIALOG_SHIM::~DIALOG_SHIM()
if( IsQuasiModal() ) if( IsQuasiModal() )
EndQuasiModal( wxID_CANCEL ); EndQuasiModal( wxID_CANCEL );
if( HasKiway() )
Kiway().SetBlockingDialog( nullptr ); Kiway().SetBlockingDialog( nullptr );
if( m_qmodal_parent_disabler ) if( m_qmodal_parent_disabler )

View File

@ -1533,6 +1533,11 @@ void SIM_PLOT_FRAME::onProbe( wxCommandEvent& event )
if( m_schematicFrame == nullptr ) if( m_schematicFrame == nullptr )
return; return;
wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simProbe ); m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simProbe );
m_schematicFrame->Raise(); m_schematicFrame->Raise();
} }
@ -1545,6 +1550,11 @@ void SIM_PLOT_FRAME::onTune( wxCommandEvent& event )
if( m_schematicFrame == nullptr ) if( m_schematicFrame == nullptr )
return; return;
wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simTune ); m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simTune );
m_schematicFrame->Raise(); m_schematicFrame->Raise();
} }

View File

@ -626,7 +626,7 @@ int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false ); symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
schframe->Raise(); schframe->Raise();
schframe->GetToolManager()->RunAction( EE_ACTIONS::placeSymbol, true, symbol ); schframe->GetToolManager()->RunAction( EE_ACTIONS::placeSymbol, false, symbol );
} }
return 0; return 0;

View File

@ -56,6 +56,15 @@ public:
return *m_kiway; return *m_kiway;
} }
/**
* Safety check before asking for the Kiway reference
* @return true if kiway is non-null
*/
bool HasKiway() const
{
return m_kiway != nullptr;
}
/** /**
* Return a reference to the #PROJECT associated with this #KIWAY. * Return a reference to the #PROJECT associated with this #KIWAY.
*/ */

View File

@ -183,6 +183,11 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
{ {
KIWAY_PLAYER* schframe = Kiway().Player( FRAME_SCH, true ); KIWAY_PLAYER* schframe = Kiway().Player( FRAME_SCH, true );
wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
packet = StrPrintf( "%d\n%s", aSchFileType, TO_UTF8( schCopy.GetFullPath() ) ); packet = StrPrintf( "%d\n%s", aSchFileType, TO_UTF8( schCopy.GetFullPath() ) );
schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this ); schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this );
@ -203,6 +208,11 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
{ {
KIWAY_PLAYER* pcbframe = Kiway().Player( FRAME_PCB_EDITOR, true ); KIWAY_PLAYER* pcbframe = Kiway().Player( FRAME_PCB_EDITOR, true );
wxWindow* blocking_dialog = pcbframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
if( !pcbframe->IsVisible() ) if( !pcbframe->IsVisible() )
pcbframe->Show( true ); pcbframe->Show( true );

View File

@ -798,6 +798,11 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
return; return;
} }
wxWindow* blocking_dialog = pcbframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
BOARD_COMMIT commit( pcbframe ); BOARD_COMMIT commit( pcbframe );
@ -836,7 +841,7 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
commit.Push( wxT( "Insert footprint" ) ); commit.Push( wxT( "Insert footprint" ) );
pcbframe->Raise(); pcbframe->Raise();
toolMgr->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint ); toolMgr->RunAction( PCB_ACTIONS::placeFootprint, false, newFootprint );
newFootprint->ClearFlags(); newFootprint->ClearFlags();
} }