Unify unsaved changes detection logic in all frames

Create an IsContentModified() function in each frame
that provides if the content has been modified, and
use that instead of always copying the checks.
This commit is contained in:
Ian McInerney 2019-12-19 15:34:01 +00:00
parent e7557d3b88
commit b9d8849b28
25 changed files with 135 additions and 45 deletions

View File

@ -791,3 +791,8 @@ void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
} }
bool EDA_BASE_FRAME::IsContentModified()
{
// This function should be overridden in child classes
return false;
}

View File

@ -136,6 +136,16 @@ public:
ITEM_PREV ///< The previous item ITEM_PREV ///< The previous item
}; };
/**
* Get if the current associations have been modified but not saved.
*
* @return true if the any changes have not been saved
*/
bool IsContentModified() override
{
return m_modified;
}
/** /**
* @return a pointer on the Footprint Viewer frame, if exists, or NULL * @return a pointer on the Footprint Viewer frame, if exists, or NULL
*/ */

View File

@ -237,17 +237,12 @@ void LIB_EDIT_FRAME::setupTools()
void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
{ {
// Shutdown blocks must be determined and vetoed as early as possible // Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION ) if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
{ && IsContentModified() )
for( const auto& libNickname : m_libMgr->GetLibraryNames() )
{
if( m_libMgr->IsLibraryModified( libNickname ) )
{ {
aEvent.Veto(); aEvent.Veto();
return; return;
} }
}
}
if( saveAllLibraries( true ) ) if( saveAllLibraries( true ) )
Destroy(); Destroy();
@ -821,3 +816,22 @@ bool LIB_EDIT_FRAME::HasLibModifications() const
return m_libMgr->HasModifications(); return m_libMgr->HasModifications();
} }
bool LIB_EDIT_FRAME::IsContentModified()
{
wxCHECK( m_libMgr, false );
// Test if the currently edited part is modified
if( GetScreen() && GetScreen()->IsModify() && GetCurPart() )
return true;
// Test if any library has been modified
for( const auto& libNickname : m_libMgr->GetLibraryNames() )
{
if( m_libMgr->IsLibraryModified( libNickname ) )
return true;
}
return false;
}

View File

@ -123,6 +123,13 @@ public:
*/ */
void SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) override; void SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) override;
/**
* Get if any parts or libraries have been modified but not saved.
*
* @return true if the any changes have not been saved
*/
bool IsContentModified() override;
/** /**
* Check if any pending libraries have been modified. * Check if any pending libraries have been modified.
* *

View File

@ -157,12 +157,8 @@ void LIB_EDIT_FRAME::SyncToolbars()
const wxString& libName = libId.GetLibNickname(); const wxString& libName = libId.GetLibNickname();
const wxString& partName = libId.GetLibItemName(); const wxString& partName = libId.GetLibItemName();
bool isEditable = m_my_part && m_my_part->IsRoot(); bool isEditable = m_my_part && m_my_part->IsRoot();
bool modified = m_libMgr->HasModifications();
if( !modified && !partName.IsEmpty() && m_libMgr->IsPartModified( partName, libName ) ) m_mainToolBar->Toggle( ACTIONS::saveAll, IsContentModified() );
modified = true;
m_mainToolBar->Toggle( ACTIONS::saveAll, modified );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::zoomTool, IsCurrentTool( ACTIONS::zoomTool ) ); m_mainToolBar->Toggle( ACTIONS::zoomTool, IsCurrentTool( ACTIONS::zoomTool ) );

View File

@ -1164,3 +1164,11 @@ void SCH_EDIT_FRAME::FixupJunctions()
GetCurrentSheet().UpdateAllScreenReferences(); GetCurrentSheet().UpdateAllScreenReferences();
SetScreen( GetCurrentSheet().LastScreen() ); SetScreen( GetCurrentSheet().LastScreen() );
} }
bool SCH_EDIT_FRAME::IsContentModified()
{
SCH_SHEET_LIST sheetList( g_RootSheet );
return sheetList.IsModified();
}

View File

@ -305,6 +305,13 @@ public:
void ReCreateOptToolbar() override; void ReCreateOptToolbar() override;
void ReCreateMenuBar() override; void ReCreateMenuBar() override;
/**
* Get if the current schematic has been modified but not saved.
*
* @return true if the any changes have not been saved
*/
bool IsContentModified() override;
/** /**
* Must be called after a schematic change in order to set the "modify" flag of the * Must be called after a schematic change in order to set the "modify" flag of the
* current screen and update the date in frame reference. * current screen and update the date in frame reference.

View File

@ -170,9 +170,8 @@ void SCH_EDIT_FRAME::SyncToolbars()
#define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) ) #define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) )
KIGFX::GAL_DISPLAY_OPTIONS& galOpts = GetGalDisplayOptions(); KIGFX::GAL_DISPLAY_OPTIONS& galOpts = GetGalDisplayOptions();
SCH_SHEET_LIST sheetList( g_RootSheet );
m_mainToolBar->Toggle( ACTIONS::save, sheetList.IsModified() ); m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );

View File

@ -484,6 +484,13 @@ public:
* Whether or not the window supports setting a shutdown block reason * Whether or not the window supports setting a shutdown block reason
*/ */
bool SupportsShutdownBlockReason(); bool SupportsShutdownBlockReason();
/**
* Get if the contents of the frame have been modified since the last save.
*
* @return true if the contents of the frame have not been saved
*/
virtual bool IsContentModified();
}; };

View File

@ -43,7 +43,7 @@ bool PL_EDITOR_FRAME::saveCurrentPageLayout()
saveEvent.SetId( wxID_SAVE ); saveEvent.SetId( wxID_SAVE );
Files_io( saveEvent ); Files_io( saveEvent );
return( !GetScreen()->IsModify() ); return !IsContentModified();
} }
@ -55,7 +55,7 @@ void PL_EDITOR_FRAME::OnFileHistory( wxCommandEvent& event )
if( filename != wxEmptyString ) if( filename != wxEmptyString )
{ {
if( GetScreen()->IsModify() ) if( IsContentModified() )
{ {
if( !HandleUnsavedChanges( this, _( "The current page layout has been modified. " if( !HandleUnsavedChanges( this, _( "The current page layout has been modified. "
"Save changes?" ), "Save changes?" ),
@ -90,7 +90,7 @@ void PL_EDITOR_FRAME::Files_io( wxCommandEvent& event )
if( filename.IsEmpty() && id == wxID_SAVE ) if( filename.IsEmpty() && id == wxID_SAVE )
id = wxID_SAVEAS; id = wxID_SAVEAS;
if( ( id == wxID_NEW || id == wxID_OPEN ) && GetScreen()->IsModify() ) if( ( id == wxID_NEW || id == wxID_OPEN ) && IsContentModified() )
{ {
if( !HandleUnsavedChanges( this, _( "The current page layout has been modified. " if( !HandleUnsavedChanges( this, _( "The current page layout has been modified. "
"Save changes?" ), "Save changes?" ),

View File

@ -45,7 +45,7 @@ void PL_EDITOR_FRAME::ReCreateMenuBar()
wxMenuBar* menuBar = new wxMenuBar(); wxMenuBar* menuBar = new wxMenuBar();
auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) { auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen() && GetScreen()->IsModify(); return IsContentModified();
}; };
static FILE_HISTORY_MENU* openRecentMenu; // Open Recent submenu, static to remember this menu static FILE_HISTORY_MENU* openRecentMenu; // Open Recent submenu, static to remember this menu

View File

@ -252,6 +252,12 @@ bool PL_EDITOR_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, i
} }
bool PL_EDITOR_FRAME::IsContentModified()
{
return GetScreen() && GetScreen()->IsModify();
}
void PL_EDITOR_FRAME::OnExit( wxCommandEvent& aEvent ) void PL_EDITOR_FRAME::OnExit( wxCommandEvent& aEvent )
{ {
if( aEvent.GetId() == wxID_EXIT ) if( aEvent.GetId() == wxID_EXIT )
@ -266,13 +272,13 @@ void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
{ {
// Shutdown blocks must be determined and vetoed as early as possible // Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
&& GetScreen()->IsModify() ) && IsContentModified() )
{ {
aEvent.Veto(); aEvent.Veto();
return; return;
} }
if( GetScreen()->IsModify() ) if( IsContentModified() )
{ {
wxFileName filename = GetCurrFileName(); wxFileName filename = GetCurrFileName();
wxString msg = _( "Save changes to \"%s\" before closing?" ); wxString msg = _( "Save changes to \"%s\" before closing?" );

View File

@ -98,6 +98,12 @@ public:
*/ */
bool InsertPageLayoutDescrFile( const wxString& aFullFileName ); bool InsertPageLayoutDescrFile( const wxString& aFullFileName );
/**
* Get if the page layout has been modified but not saved.
*
* @return true if the any changes have not been saved
*/
bool IsContentModified() override;
/* /*
* Function OnExit * Function OnExit

View File

@ -150,7 +150,7 @@ void PL_EDITOR_FRAME::SyncToolbars()
{ {
#define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) ) #define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) )
m_mainToolBar->Toggle( ACTIONS::save, GetScreen() && GetScreen()->IsModify() ); m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );

View File

@ -277,7 +277,7 @@ bool PCB_EDIT_FRAME::Files_io_from_id( int id )
case ID_NEW_BOARD: case ID_NEW_BOARD:
{ {
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( IsContentModified() )
{ {
wxFileName fileName = GetBoard()->GetFileName(); wxFileName fileName = GetBoard()->GetFileName();
wxString saveMsg = wxString saveMsg =
@ -433,7 +433,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
return false; return false;
} }
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( IsContentModified() )
{ {
if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ), if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
[&]()->bool { return SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); } ) ) [&]()->bool { return SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); } ) )

View File

@ -240,6 +240,11 @@ FOOTPRINT_EDIT_FRAME::~FOOTPRINT_EDIT_FRAME()
} }
bool FOOTPRINT_EDIT_FRAME::IsContentModified()
{
return GetScreen() && GetScreen()->IsModify() && GetBoard() && GetBoard()->GetFirstModule();
}
void FOOTPRINT_EDIT_FRAME::SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) void FOOTPRINT_EDIT_FRAME::SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType )
{ {
@ -449,7 +454,7 @@ const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents() const
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
{ {
if( GetScreen()->IsModify() && GetBoard()->GetFirstModule() ) if( IsContentModified() )
{ {
// Shutdown blocks must be determined and vetoed as early as possible // Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION ) if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION )

View File

@ -61,6 +61,13 @@ public:
///> @copydoc PCB_BASE_EDIT_FRAME::GetModel() ///> @copydoc PCB_BASE_EDIT_FRAME::GetModel()
BOARD_ITEM_CONTAINER* GetModel() const override; BOARD_ITEM_CONTAINER* GetModel() const override;
/**
* Get if any footprints or libraries have been modified but not saved.
*
* @return true if the any changes have not been saved
*/
bool IsContentModified() override;
bool IsCurrentFPFromBoard() const; bool IsCurrentFPFromBoard() const;
BOARD_DESIGN_SETTINGS& GetDesignSettings() const override; BOARD_DESIGN_SETTINGS& GetDesignSettings() const override;

View File

@ -189,7 +189,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{ {
LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId(); LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId();
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( IsContentModified() )
{ {
if( !HandleUnsavedChanges( this, _( "The current footprint has been modified. " if( !HandleUnsavedChanges( this, _( "The current footprint has been modified. "
"Save changes?" ), "Save changes?" ),

View File

@ -100,7 +100,7 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery )
if( GetBoard() == NULL ) if( GetBoard() == NULL )
return false; return false;
if( aQuery && GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( aQuery && IsContentModified() )
{ {
wxSafeYield( this, true ); // Allow frame to come to front before showing warning. wxSafeYield( this, true ); // Allow frame to come to front before showing warning.

View File

@ -48,7 +48,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
wxMenuBar* menuBar = new wxMenuBar(); wxMenuBar* menuBar = new wxMenuBar();
auto modifiedDocumentCondition = [this]( const SELECTION& sel ) { auto modifiedDocumentCondition = [this]( const SELECTION& sel ) {
return !GetBoard()->Modules().empty() && GetScreen()->IsModify(); return IsContentModified();
}; };
auto haveFootprintCondition = [this]( const SELECTION& aSelection ) { auto haveFootprintCondition = [this]( const SELECTION& aSelection ) {
return GetBoard()->GetFirstModule() != nullptr; return GetBoard()->GetFirstModule() != nullptr;

View File

@ -51,7 +51,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
wxMenuBar* menuBar = new wxMenuBar(); wxMenuBar* menuBar = new wxMenuBar();
auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) { auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) {
return GetScreen()->IsModify(); return IsContentModified();
}; };
// Recreate all menus: // Recreate all menus:

View File

@ -390,6 +390,12 @@ void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
} }
bool PCB_EDIT_FRAME::IsContentModified()
{
return GetScreen() && GetScreen()->IsModify() && GetBoard() && !GetBoard()->IsEmpty();
}
bool PCB_EDIT_FRAME::isAutoSaveRequired() const bool PCB_EDIT_FRAME::isAutoSaveRequired() const
{ {
if( GetScreen() ) if( GetScreen() )
@ -471,7 +477,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
{ {
// Shutdown blocks must be determined and vetoed as early as possible // Shutdown blocks must be determined and vetoed as early as possible
if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
&& GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) && IsContentModified() )
{ {
aEvent.Veto(); aEvent.Veto();
return; return;
@ -486,7 +492,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
if( open_dlg ) if( open_dlg )
open_dlg->Close( true ); open_dlg->Close( true );
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( IsContentModified() )
{ {
wxFileName fileName = GetBoard()->GetFileName(); wxFileName fileName = GetBoard()->GetFileName();
wxString msg = _( "Save changes to \"%s\" before closing?" ); wxString msg = _( "Save changes to \"%s\" before closing?" );

View File

@ -298,6 +298,13 @@ public:
void OnQuit( wxCommandEvent& event ); void OnQuit( wxCommandEvent& event );
/**
* Get if the current board has been modified but not saved.
*
* @return true if the any changes have not been saved
*/
bool IsContentModified() override;
/** /**
* Reload the Python plugins if they are newer than * Reload the Python plugins if they are newer than
* the already loaded, and load new plugins if any * the already loaded, and load new plugins if any

View File

@ -225,9 +225,9 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars()
auto& opts = GetDisplayOptions(); auto& opts = GetDisplayOptions();
if( IsCurrentFPFromBoard() ) if( IsCurrentFPFromBoard() )
m_mainToolBar->Toggle( PCB_ACTIONS::saveToBoard, GetScreen() && GetScreen()->IsModify() ); m_mainToolBar->Toggle( PCB_ACTIONS::saveToBoard, IsContentModified() );
else else
m_mainToolBar->Toggle( PCB_ACTIONS::saveToLibrary, GetScreen() && GetScreen()->IsModify() ); m_mainToolBar->Toggle( PCB_ACTIONS::saveToLibrary, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );

View File

@ -670,7 +670,7 @@ void PCB_EDIT_FRAME::SyncToolbars()
KIGFX::GAL_DISPLAY_OPTIONS& galOpts = GetGalDisplayOptions(); KIGFX::GAL_DISPLAY_OPTIONS& galOpts = GetGalDisplayOptions();
int zoneMode = opts.m_DisplayZonesMode; int zoneMode = opts.m_DisplayZonesMode;
m_mainToolBar->Toggle( ACTIONS::save, GetScreen() && GetScreen()->IsModify() ); m_mainToolBar->Toggle( ACTIONS::save, IsContentModified() );
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );
TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );