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()
|
||||
{
|
||||
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
|
||||
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 )
|
||||
{
|
||||
// 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. "
|
||||
"Save changes?" ),
|
||||
[&]()->bool { return SaveFootprintAssociation( false ); } ) )
|
||||
{
|
||||
Event.Veto();
|
||||
aEvent.Veto();
|
||||
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
|
||||
// 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().SchSymbolLibTable();
|
||||
|
||||
SetShutdownBlockReason( _( "Schematic file changes are unsaved" ) );
|
||||
|
||||
if( is_new )
|
||||
{
|
||||
// mark new, unsaved file as modified.
|
||||
|
|
|
@ -189,6 +189,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
|||
GetCanvas()->GetView()->SetBoundary( bbox );
|
||||
|
||||
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 ) )
|
||||
Destroy();
|
||||
else
|
||||
Event.Veto();
|
||||
aEvent.Veto();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -301,6 +301,9 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
|
|||
DefaultExecFlags();
|
||||
|
||||
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 )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
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?
|
||||
return;
|
||||
|
||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||
|
||||
if( sheetList.IsModified() )
|
||||
{
|
||||
|
|
|
@ -466,6 +466,24 @@ public:
|
|||
virtual void RefreshCanvas() { };
|
||||
|
||||
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 )
|
||||
{
|
||||
// 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() )
|
||||
{
|
||||
wxFileName filename = GetCurrFileName();
|
||||
|
@ -764,6 +772,16 @@ void PL_EDITOR_FRAME::OnNewPageLayout()
|
|||
UpdateTitleAndInfo();
|
||||
|
||||
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();
|
||||
InitExitKey();
|
||||
|
||||
// Default shutdown reason until a file is loaded
|
||||
SetShutdownBlockReason( _( "Footprint changes are unsaved" ) );
|
||||
|
||||
Raise(); // On some window managers, this is needed
|
||||
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() )
|
||||
{
|
||||
// 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 msg = _( "Save changes to \"%s\" before closing?" );
|
||||
|
||||
if( !HandleUnsavedChanges( this, wxString::Format( msg, footprintName ),
|
||||
[&]() -> bool { return SaveFootprint( GetBoard()->GetFirstModule() ); } ) )
|
||||
{
|
||||
Event.Veto();
|
||||
aEvent.Veto();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -470,7 +480,7 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
|||
Clear_Pcb( false );
|
||||
|
||||
// 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() );
|
||||
ActivateGalCanvas();
|
||||
|
||||
// Default shutdown reason until a file is loaded
|
||||
SetShutdownBlockReason( _( "New PCB file is unsaved" ) );
|
||||
|
||||
// disable Export STEP item if kicad2step does not exist
|
||||
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.
|
||||
// For some reason, if the board editor frame is destroyed when the DRC
|
||||
// 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() ),
|
||||
[&]()->bool { return Files_io_from_id( ID_SAVE_BOARD ); } ) )
|
||||
{
|
||||
Event.Veto();
|
||||
aEvent.Veto();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -538,7 +549,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
|||
Show( false );
|
||||
|
||||
// Close frame:
|
||||
Event.Skip();
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
|
@ -672,6 +683,8 @@ void PCB_EDIT_FRAME::onBoardLoaded()
|
|||
|
||||
SetMsgPanel( GetBoard() );
|
||||
SetStatusText( wxEmptyString );
|
||||
|
||||
SetShutdownBlockReason( _( "PCB file changes are unsaved" ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue