diff --git a/common/eda_base_frame.cpp b/common/eda_base_frame.cpp index 43c6cfe0fc..1696bd4a64 100644 --- a/common/eda_base_frame.cpp +++ b/common/eda_base_frame.cpp @@ -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; +} diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h index e3a4abfbb0..69e8eb94dc 100644 --- a/cvpcb/cvpcb_mainframe.h +++ b/cvpcb/cvpcb_mainframe.h @@ -136,6 +136,16 @@ public: 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 */ diff --git a/eeschema/libedit/lib_edit_frame.cpp b/eeschema/libedit/lib_edit_frame.cpp index 30af356ab5..7f1ab91754 100644 --- a/eeschema/libedit/lib_edit_frame.cpp +++ b/eeschema/libedit/lib_edit_frame.cpp @@ -237,16 +237,11 @@ void LIB_EDIT_FRAME::setupTools() 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 ) + if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION + && IsContentModified() ) { - for( const auto& libNickname : m_libMgr->GetLibraryNames() ) - { - if( m_libMgr->IsLibraryModified( libNickname ) ) - { - aEvent.Veto(); - return; - } - } + aEvent.Veto(); + return; } if( saveAllLibraries( true ) ) @@ -821,3 +816,22 @@ bool LIB_EDIT_FRAME::HasLibModifications() const 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; +} diff --git a/eeschema/libedit/lib_edit_frame.h b/eeschema/libedit/lib_edit_frame.h index a273764412..e17233061a 100644 --- a/eeschema/libedit/lib_edit_frame.h +++ b/eeschema/libedit/lib_edit_frame.h @@ -123,6 +123,13 @@ public: */ 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. * diff --git a/eeschema/libedit/toolbars_libedit.cpp b/eeschema/libedit/toolbars_libedit.cpp index f7c6091742..9d941fb567 100644 --- a/eeschema/libedit/toolbars_libedit.cpp +++ b/eeschema/libedit/toolbars_libedit.cpp @@ -157,14 +157,10 @@ void LIB_EDIT_FRAME::SyncToolbars() const wxString& libName = libId.GetLibNickname(); const wxString& partName = libId.GetLibItemName(); bool isEditable = m_my_part && m_my_part->IsRoot(); - bool modified = m_libMgr->HasModifications(); - if( !modified && !partName.IsEmpty() && m_libMgr->IsPartModified( partName, libName ) ) - modified = true; - - m_mainToolBar->Toggle( ACTIONS::saveAll, modified ); - m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); - m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::saveAll, IsContentModified() ); + m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 ); + m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); m_mainToolBar->Toggle( ACTIONS::zoomTool, IsCurrentTool( ACTIONS::zoomTool ) ); m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet, (bool) m_my_part ); m_mainToolBar->Toggle( EE_ACTIONS::showDeMorganStandard, diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 54e2a454ab..f836a0e819 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -1164,3 +1164,11 @@ void SCH_EDIT_FRAME::FixupJunctions() GetCurrentSheet().UpdateAllScreenReferences(); SetScreen( GetCurrentSheet().LastScreen() ); } + + +bool SCH_EDIT_FRAME::IsContentModified() +{ + SCH_SHEET_LIST sheetList( g_RootSheet ); + + return sheetList.IsModified(); +} diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 420b87cfb9..8694c153e6 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -305,6 +305,13 @@ public: void ReCreateOptToolbar() 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 * current screen and update the date in frame reference. diff --git a/eeschema/toolbars_sch_editor.cpp b/eeschema/toolbars_sch_editor.cpp index 34e69f399b..caca7a6a3d 100644 --- a/eeschema/toolbars_sch_editor.cpp +++ b/eeschema/toolbars_sch_editor.cpp @@ -166,13 +166,12 @@ void SCH_EDIT_FRAME::ReCreateOptToolbar() void SCH_EDIT_FRAME::SyncToolbars() -{ +{ #define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, IsCurrentTool( tool ) ) 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::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); diff --git a/include/eda_base_frame.h b/include/eda_base_frame.h index 751970fb16..6c022ef3a8 100644 --- a/include/eda_base_frame.h +++ b/include/eda_base_frame.h @@ -484,6 +484,13 @@ public: * Whether or not the window supports setting a shutdown block reason */ 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(); }; diff --git a/pagelayout_editor/files.cpp b/pagelayout_editor/files.cpp index c47f7e138a..2042eb00d2 100644 --- a/pagelayout_editor/files.cpp +++ b/pagelayout_editor/files.cpp @@ -43,7 +43,7 @@ bool PL_EDITOR_FRAME::saveCurrentPageLayout() saveEvent.SetId( wxID_SAVE ); Files_io( saveEvent ); - return( !GetScreen()->IsModify() ); + return !IsContentModified(); } @@ -55,7 +55,7 @@ void PL_EDITOR_FRAME::OnFileHistory( wxCommandEvent& event ) if( filename != wxEmptyString ) { - if( GetScreen()->IsModify() ) + if( IsContentModified() ) { if( !HandleUnsavedChanges( this, _( "The current page layout has been modified. " "Save changes?" ), @@ -90,7 +90,7 @@ void PL_EDITOR_FRAME::Files_io( wxCommandEvent& event ) if( filename.IsEmpty() && id == wxID_SAVE ) 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. " "Save changes?" ), diff --git a/pagelayout_editor/menubar.cpp b/pagelayout_editor/menubar.cpp index ec517fec10..3cd4c4ba76 100644 --- a/pagelayout_editor/menubar.cpp +++ b/pagelayout_editor/menubar.cpp @@ -45,7 +45,7 @@ void PL_EDITOR_FRAME::ReCreateMenuBar() wxMenuBar* menuBar = new wxMenuBar(); 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 diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index 083e04739c..3ddc26745e 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -252,6 +252,12 @@ bool PL_EDITOR_FRAME::OpenProjectFiles( const std::vector& aFileSet, i } +bool PL_EDITOR_FRAME::IsContentModified() +{ + return GetScreen() && GetScreen()->IsModify(); +} + + void PL_EDITOR_FRAME::OnExit( wxCommandEvent& aEvent ) { 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 if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION - && GetScreen()->IsModify() ) + && IsContentModified() ) { aEvent.Veto(); return; } - if( GetScreen()->IsModify() ) + if( IsContentModified() ) { wxFileName filename = GetCurrFileName(); wxString msg = _( "Save changes to \"%s\" before closing?" ); diff --git a/pagelayout_editor/pl_editor_frame.h b/pagelayout_editor/pl_editor_frame.h index 0ee4d115ab..9985b6db3f 100644 --- a/pagelayout_editor/pl_editor_frame.h +++ b/pagelayout_editor/pl_editor_frame.h @@ -98,6 +98,12 @@ public: */ 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 diff --git a/pagelayout_editor/toolbars_pl_editor.cpp b/pagelayout_editor/toolbars_pl_editor.cpp index 66bbf0c7eb..a56b7fbfa6 100644 --- a/pagelayout_editor/toolbars_pl_editor.cpp +++ b/pagelayout_editor/toolbars_pl_editor.cpp @@ -150,7 +150,7 @@ void PL_EDITOR_FRAME::SyncToolbars() { #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::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool ); diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index ce0db2fd2c..5950fad32b 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -277,7 +277,7 @@ bool PCB_EDIT_FRAME::Files_io_from_id( int id ) case ID_NEW_BOARD: { - if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) + if( IsContentModified() ) { wxFileName fileName = GetBoard()->GetFileName(); wxString saveMsg = @@ -433,7 +433,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in return false; } - if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) + if( IsContentModified() ) { if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ), [&]()->bool { return SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); } ) ) diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index 7ca26f766b..3dc4b1b867 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -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 ) { @@ -449,7 +454,7 @@ const BOX2I FOOTPRINT_EDIT_FRAME::GetDocumentExtents() const 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 if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION ) diff --git a/pcbnew/footprint_edit_frame.h b/pcbnew/footprint_edit_frame.h index c03fcd9464..70cb5223b9 100644 --- a/pcbnew/footprint_edit_frame.h +++ b/pcbnew/footprint_edit_frame.h @@ -61,6 +61,13 @@ public: ///> @copydoc PCB_BASE_EDIT_FRAME::GetModel() 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; BOARD_DESIGN_SETTINGS& GetDesignSettings() const override; diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp index 9bf203ad82..9b04021d3f 100644 --- a/pcbnew/footprint_editor_utils.cpp +++ b/pcbnew/footprint_editor_utils.cpp @@ -189,7 +189,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId(); - if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) + if( IsContentModified() ) { if( !HandleUnsavedChanges( this, _( "The current footprint has been modified. " "Save changes?" ), diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index ec783993f3..1fc7a9b2cf 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -100,7 +100,7 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery ) if( GetBoard() == NULL ) return false; - if( aQuery && GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) + if( aQuery && IsContentModified() ) { wxSafeYield( this, true ); // Allow frame to come to front before showing warning. diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp index bd9c86970d..eeff759719 100644 --- a/pcbnew/menubar_footprint_editor.cpp +++ b/pcbnew/menubar_footprint_editor.cpp @@ -48,7 +48,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() wxMenuBar* menuBar = new wxMenuBar(); auto modifiedDocumentCondition = [this]( const SELECTION& sel ) { - return !GetBoard()->Modules().empty() && GetScreen()->IsModify(); + return IsContentModified(); }; auto haveFootprintCondition = [this]( const SELECTION& aSelection ) { return GetBoard()->GetFirstModule() != nullptr; @@ -228,16 +228,16 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() placeMenu->AddItem( PCB_ACTIONS::placePad, haveFootprintCondition ); placeMenu->AddSeparator(); - placeMenu->AddItem( PCB_ACTIONS::placeText, haveFootprintCondition ); - placeMenu->AddItem( PCB_ACTIONS::drawArc, haveFootprintCondition ); - placeMenu->AddItem( PCB_ACTIONS::drawCircle, haveFootprintCondition ); - placeMenu->AddItem( PCB_ACTIONS::drawLine, haveFootprintCondition ); + placeMenu->AddItem( PCB_ACTIONS::placeText, haveFootprintCondition ); + placeMenu->AddItem( PCB_ACTIONS::drawArc, haveFootprintCondition ); + placeMenu->AddItem( PCB_ACTIONS::drawCircle, haveFootprintCondition ); + placeMenu->AddItem( PCB_ACTIONS::drawLine, haveFootprintCondition ); placeMenu->AddItem( PCB_ACTIONS::drawPolygon, haveFootprintCondition ); - placeMenu->AddItem( PCB_ACTIONS::drawZoneKeepout, haveFootprintCondition ); + placeMenu->AddItem( PCB_ACTIONS::drawZoneKeepout, haveFootprintCondition ); placeMenu->AddSeparator(); - placeMenu->AddItem( PCB_ACTIONS::setAnchor, haveFootprintCondition ); - placeMenu->AddItem( ACTIONS::gridSetOrigin, haveFootprintCondition ); + placeMenu->AddItem( PCB_ACTIONS::setAnchor, haveFootprintCondition ); + placeMenu->AddItem( ACTIONS::gridSetOrigin, haveFootprintCondition ); placeMenu->Resolve(); diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp index b06586a906..01cb7c1cf2 100644 --- a/pcbnew/menubar_pcb_editor.cpp +++ b/pcbnew/menubar_pcb_editor.cpp @@ -51,7 +51,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() wxMenuBar* menuBar = new wxMenuBar(); auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) { - return GetScreen()->IsModify(); + return IsContentModified(); }; // Recreate all menus: diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 5e69a02dbc..756fff6e3d 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -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 { if( GetScreen() ) @@ -471,7 +477,7 @@ 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() ) + && IsContentModified() ) { aEvent.Veto(); return; @@ -486,7 +492,7 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) if( open_dlg ) open_dlg->Close( true ); - if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) + if( IsContentModified() ) { wxFileName fileName = GetBoard()->GetFileName(); wxString msg = _( "Save changes to \"%s\" before closing?" ); diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index d243ce278f..02e674a434 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -298,6 +298,13 @@ public: 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 * the already loaded, and load new plugins if any diff --git a/pcbnew/toolbars_footprint_editor.cpp b/pcbnew/toolbars_footprint_editor.cpp index 795605d8db..a823b1f40c 100644 --- a/pcbnew/toolbars_footprint_editor.cpp +++ b/pcbnew/toolbars_footprint_editor.cpp @@ -225,9 +225,9 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars() auto& opts = GetDisplayOptions(); if( IsCurrentFPFromBoard() ) - m_mainToolBar->Toggle( PCB_ACTIONS::saveToBoard, GetScreen() && GetScreen()->IsModify() ); + m_mainToolBar->Toggle( PCB_ACTIONS::saveToBoard, IsContentModified() ); 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::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); diff --git a/pcbnew/toolbars_pcb_editor.cpp b/pcbnew/toolbars_pcb_editor.cpp index 2126afd6b4..ed2ee6145f 100644 --- a/pcbnew/toolbars_pcb_editor.cpp +++ b/pcbnew/toolbars_pcb_editor.cpp @@ -670,7 +670,7 @@ void PCB_EDIT_FRAME::SyncToolbars() KIGFX::GAL_DISPLAY_OPTIONS& galOpts = GetGalDisplayOptions(); 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::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 ); TOGGLE_TOOL( m_mainToolBar, ACTIONS::zoomTool );