Add shutdown blocking on Windows for pcbnew, eeschema and pleditor
ADDED: Block shutdown/logoff on Windows when contents have been modified
This commit is contained in:
parent
3ca231aa78
commit
686b768a3d
|
@ -159,6 +159,48 @@ void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
|
||||||
EDA_BASE_FRAME::~EDA_BASE_FRAME()
|
EDA_BASE_FRAME::~EDA_BASE_FRAME()
|
||||||
{
|
{
|
||||||
delete m_autoSaveTimer;
|
delete m_autoSaveTimer;
|
||||||
|
|
||||||
|
if( SupportsShutdownBlockReason() )
|
||||||
|
{
|
||||||
|
RemoveShutdownBlockReason();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool EDA_BASE_FRAME::SupportsShutdownBlockReason()
|
||||||
|
{
|
||||||
|
#if defined( _WIN32 )
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EDA_BASE_FRAME::RemoveShutdownBlockReason()
|
||||||
|
{
|
||||||
|
#if defined( _WIN32 )
|
||||||
|
// Windows: Destroys any block reason that may have existed
|
||||||
|
ShutdownBlockReasonDestroy( GetHandle() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EDA_BASE_FRAME::SetShutdownBlockReason( const wxString& aReason )
|
||||||
|
{
|
||||||
|
#if defined( _WIN32 )
|
||||||
|
// Windows: sets up the pretty message on the shutdown page on why it's being "blocked"
|
||||||
|
// This is used in conjunction with handling WM_QUERYENDSESSION (wxCloseEvent)
|
||||||
|
// ShutdownBlockReasonCreate does not block by itself
|
||||||
|
|
||||||
|
ShutdownBlockReasonDestroy( GetHandle() ); // Destroys any existing or nonexisting reason
|
||||||
|
|
||||||
|
if( !ShutdownBlockReasonCreate( GetHandle(), aReason.wc_str() ) )
|
||||||
|
{
|
||||||
|
// Nothing bad happens if this fails, at worst it uses a generic application is preventing shutdown message
|
||||||
|
wxLogDebug( wxT( "ShutdownBlockReasonCreate failed to set reason: %s" ), aReason );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,8 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
|
|
||||||
// Ensure the toolbars are sync'd properly so the filtering options display correct
|
// Ensure the toolbars are sync'd properly so the filtering options display correct
|
||||||
SyncToolbars();
|
SyncToolbars();
|
||||||
|
|
||||||
|
SetShutdownBlockReason( _( "Symbol to footprint changes are unsaved" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -302,15 +304,22 @@ void CVPCB_MAINFRAME::setupEventHandlers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& Event )
|
void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
||||||
{
|
{
|
||||||
if( m_modified )
|
if( m_modified )
|
||||||
{
|
{
|
||||||
|
// Shutdown blocks must be determined and vetoed as early as possible
|
||||||
|
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION )
|
||||||
|
{
|
||||||
|
aEvent.Veto();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( !HandleUnsavedChanges( this, _( "Symbol to Footprint links have been modified. "
|
if( !HandleUnsavedChanges( this, _( "Symbol to Footprint links have been modified. "
|
||||||
"Save changes?" ),
|
"Save changes?" ),
|
||||||
[&]()->bool { return SaveFootprintAssociation( false ); } ) )
|
[&]()->bool { return SaveFootprintAssociation( false ); } ) )
|
||||||
{
|
{
|
||||||
Event.Veto();
|
aEvent.Veto();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,7 +335,7 @@ void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& Event )
|
||||||
|
|
||||||
// Skip the close event. Looks like needed to have the close event sent to the
|
// Skip the close event. Looks like needed to have the close event sent to the
|
||||||
// root class EDA_BASE_FRAME, and save config
|
// root class EDA_BASE_FRAME, and save config
|
||||||
Event.Skip();
|
aEvent.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -271,6 +271,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
Prj().SetElem( PROJECT::ELEM_SYMBOL_LIB_TABLE, NULL );
|
Prj().SetElem( PROJECT::ELEM_SYMBOL_LIB_TABLE, NULL );
|
||||||
Prj().SchSymbolLibTable();
|
Prj().SchSymbolLibTable();
|
||||||
|
|
||||||
|
SetShutdownBlockReason( _( "Schematic file changes are unsaved" ) );
|
||||||
|
|
||||||
if( is_new )
|
if( is_new )
|
||||||
{
|
{
|
||||||
// mark new, unsaved file as modified.
|
// mark new, unsaved file as modified.
|
||||||
|
|
|
@ -189,6 +189,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
GetCanvas()->GetView()->SetBoundary( bbox );
|
GetCanvas()->GetView()->SetBoundary( bbox );
|
||||||
|
|
||||||
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
|
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
|
||||||
|
|
||||||
|
SetShutdownBlockReason( _( "Library changes are unsaved" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -232,12 +234,25 @@ void LIB_EDIT_FRAME::setupTools()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
||||||
{
|
{
|
||||||
|
// Shutdown blocks must be determined and vetoed as early as possible
|
||||||
|
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION )
|
||||||
|
{
|
||||||
|
for( const auto& libNickname : m_libMgr->GetLibraryNames() )
|
||||||
|
{
|
||||||
|
if( m_libMgr->IsLibraryModified( libNickname ) )
|
||||||
|
{
|
||||||
|
aEvent.Veto();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( saveAllLibraries( true ) )
|
if( saveAllLibraries( true ) )
|
||||||
Destroy();
|
Destroy();
|
||||||
else
|
else
|
||||||
Event.Veto();
|
aEvent.Veto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -301,6 +301,9 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
|
||||||
DefaultExecFlags();
|
DefaultExecFlags();
|
||||||
|
|
||||||
UpdateTitle();
|
UpdateTitle();
|
||||||
|
|
||||||
|
// Default shutdown reason until a file is loaded
|
||||||
|
SetShutdownBlockReason( _( "New schematic file is unsaved" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,6 +500,16 @@ void SCH_EDIT_FRAME::SaveUndoItemInUndoList( SCH_ITEM* aItem, bool aAppend )
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
||||||
{
|
{
|
||||||
|
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||||
|
|
||||||
|
// Shutdown blocks must be determined and vetoed as early as possible
|
||||||
|
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
|
||||||
|
&& sheetList.IsModified() )
|
||||||
|
{
|
||||||
|
aEvent.Veto();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( Kiface().IsSingle() )
|
if( Kiface().IsSingle() )
|
||||||
{
|
{
|
||||||
LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
|
LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
|
||||||
|
@ -518,7 +531,6 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
||||||
if( simFrame && !simFrame->Close() ) // Can close the simulator?
|
if( simFrame && !simFrame->Close() ) // Can close the simulator?
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
|
||||||
|
|
||||||
if( sheetList.IsModified() )
|
if( sheetList.IsModified() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -466,6 +466,24 @@ public:
|
||||||
virtual void RefreshCanvas() { };
|
virtual void RefreshCanvas() { };
|
||||||
|
|
||||||
const wxString& GetAboutTitle() const { return m_AboutTitle; }
|
const wxString& GetAboutTitle() const { return m_AboutTitle; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block reason why the window/application is preventing OS shutdown.
|
||||||
|
* This should be set far ahead of any close event.
|
||||||
|
*
|
||||||
|
* This is mainly intended for Windows platforms where this is a native feature.
|
||||||
|
*/
|
||||||
|
void SetShutdownBlockReason( const wxString& reason );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes any shutdown block reason set
|
||||||
|
*/
|
||||||
|
void RemoveShutdownBlockReason();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the window supports setting a shutdown block reason
|
||||||
|
*/
|
||||||
|
bool SupportsShutdownBlockReason();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,14 @@ void PL_EDITOR_FRAME::OnExit( wxCommandEvent& aEvent )
|
||||||
|
|
||||||
void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
||||||
{
|
{
|
||||||
|
// Shutdown blocks must be determined and vetoed as early as possible
|
||||||
|
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
|
||||||
|
&& GetScreen()->IsModify() )
|
||||||
|
{
|
||||||
|
aEvent.Veto();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( GetScreen()->IsModify() )
|
if( GetScreen()->IsModify() )
|
||||||
{
|
{
|
||||||
wxFileName filename = GetCurrFileName();
|
wxFileName filename = GetCurrFileName();
|
||||||
|
@ -764,6 +772,16 @@ void PL_EDITOR_FRAME::OnNewPageLayout()
|
||||||
UpdateTitleAndInfo();
|
UpdateTitleAndInfo();
|
||||||
|
|
||||||
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
|
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
|
||||||
|
|
||||||
|
if( GetCurrFileName().IsEmpty() )
|
||||||
|
{
|
||||||
|
// Default shutdown reason until a file is loaded
|
||||||
|
SetShutdownBlockReason( _( "New page layout file is unsaved" ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetShutdownBlockReason( _( "Page layout changes are unsaved" ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,9 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
|
||||||
updateTitle();
|
updateTitle();
|
||||||
InitExitKey();
|
InitExitKey();
|
||||||
|
|
||||||
|
// Default shutdown reason until a file is loaded
|
||||||
|
SetShutdownBlockReason( _( "Footprint changes are unsaved" ) );
|
||||||
|
|
||||||
Raise(); // On some window managers, this is needed
|
Raise(); // On some window managers, this is needed
|
||||||
Show( true );
|
Show( true );
|
||||||
}
|
}
|
||||||
|
@ -444,17 +447,24 @@ const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
||||||
{
|
{
|
||||||
if( GetScreen()->IsModify() && GetBoard()->GetFirstModule() )
|
if( GetScreen()->IsModify() && GetBoard()->GetFirstModule() )
|
||||||
{
|
{
|
||||||
|
// Shutdown blocks must be determined and vetoed as early as possible
|
||||||
|
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION )
|
||||||
|
{
|
||||||
|
aEvent.Veto();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wxString footprintName = GetBoard()->GetFirstModule()->GetFPID().GetLibItemName();
|
wxString footprintName = GetBoard()->GetFirstModule()->GetFPID().GetLibItemName();
|
||||||
wxString msg = _( "Save changes to \"%s\" before closing?" );
|
wxString msg = _( "Save changes to \"%s\" before closing?" );
|
||||||
|
|
||||||
if( !HandleUnsavedChanges( this, wxString::Format( msg, footprintName ),
|
if( !HandleUnsavedChanges( this, wxString::Format( msg, footprintName ),
|
||||||
[&]() -> bool { return SaveFootprint( GetBoard()->GetFirstModule() ); } ) )
|
[&]() -> bool { return SaveFootprint( GetBoard()->GetFirstModule() ); } ) )
|
||||||
{
|
{
|
||||||
Event.Veto();
|
aEvent.Veto();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +480,7 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
||||||
Clear_Pcb( false );
|
Clear_Pcb( false );
|
||||||
|
|
||||||
// Close the editor
|
// Close the editor
|
||||||
Event.Skip();
|
aEvent.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,9 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
GetCanvas()->GetView()->SetScale( GetZoomLevelCoeff() / GetScreen()->GetZoom() );
|
GetCanvas()->GetView()->SetScale( GetZoomLevelCoeff() / GetScreen()->GetZoom() );
|
||||||
ActivateGalCanvas();
|
ActivateGalCanvas();
|
||||||
|
|
||||||
|
// Default shutdown reason until a file is loaded
|
||||||
|
SetShutdownBlockReason( _( "New PCB file is unsaved" ) );
|
||||||
|
|
||||||
// disable Export STEP item if kicad2step does not exist
|
// disable Export STEP item if kicad2step does not exist
|
||||||
wxString strK2S = Pgm().GetExecutablePath();
|
wxString strK2S = Pgm().GetExecutablePath();
|
||||||
|
|
||||||
|
@ -464,8 +467,16 @@ void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
||||||
{
|
{
|
||||||
|
// Shutdown blocks must be determined and vetoed as early as possible
|
||||||
|
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
|
||||||
|
&& GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
|
||||||
|
{
|
||||||
|
aEvent.Veto();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// First close the DRC dialog.
|
// First close the DRC dialog.
|
||||||
// For some reason, if the board editor frame is destroyed when the DRC
|
// For some reason, if the board editor frame is destroyed when the DRC
|
||||||
// dialog currently open, Pcbnew crashes, At least on Windows.
|
// dialog currently open, Pcbnew crashes, At least on Windows.
|
||||||
|
@ -483,7 +494,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
||||||
if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
|
if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ),
|
||||||
[&]()->bool { return Files_io_from_id( ID_SAVE_BOARD ); } ) )
|
[&]()->bool { return Files_io_from_id( ID_SAVE_BOARD ); } ) )
|
||||||
{
|
{
|
||||||
Event.Veto();
|
aEvent.Veto();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -538,7 +549,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
||||||
Show( false );
|
Show( false );
|
||||||
|
|
||||||
// Close frame:
|
// Close frame:
|
||||||
Event.Skip();
|
aEvent.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -672,6 +683,8 @@ void PCB_EDIT_FRAME::onBoardLoaded()
|
||||||
|
|
||||||
SetMsgPanel( GetBoard() );
|
SetMsgPanel( GetBoard() );
|
||||||
SetStatusText( wxEmptyString );
|
SetStatusText( wxEmptyString );
|
||||||
|
|
||||||
|
SetShutdownBlockReason( _( "PCB file changes are unsaved" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue