diff --git a/TODO.md b/TODO.md index 3b94154..2f80a5e 100644 --- a/TODO.md +++ b/TODO.md @@ -3,8 +3,8 @@ ## Before releasing v0.1.0 - [x] In BoardCanvas search for a workaround of the dynamic allocation of adata.buffer (on canvas resize) - [ ] Bind the chess game editor settings to EditorPrefs.hpp - - [ ] Ask before closing MainWindow/Tabs if anything is not saved - - [ ] Disable the save button in GameTab after saving (and re-enable it on new changes) + - [x] Ask before closing MainWindow/Tabs if anything is not saved + - [x] Disable the save button in GameTab after saving (and re-enable it on new changes) - [ ] Make PGNGameBase use GotoNextGame() instead of ParseNextGame() in the NextGame() method to improve performance ## Additional Features diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 281edd8..6202889 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -64,12 +64,16 @@ MainWindow::MainWindow() } void MainWindow::OnAuiNotebookPageCheck(wxAuiNotebookEvent& event){ - // TODO: Ask the user before closing - //event.Veto(); int selection=event.GetSelection(); TabInfos *t=dynamic_cast(notebook->GetPage(selection)); if(t->is_dirty){ - wxLogDebug("Tab was dirty"); + wxMessageDialog *dial = new wxMessageDialog(NULL, + wxT("This tab contains data that are not saved. Are you sure you want to close it?"), wxT("Information"), + wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); + if(dial->ShowModal() == wxID_YES) + event.Allow(); + else + event.Veto(); } } diff --git a/src/base_tab/BaseManageTab.cpp b/src/base_tab/BaseManageTab.cpp index c9ea29b..84641af 100644 --- a/src/base_tab/BaseManageTab.cpp +++ b/src/base_tab/BaseManageTab.cpp @@ -6,6 +6,7 @@ BaseManageTab::BaseManageTab(wxFrame *parent, std::shared_ptr db, std: TabBase_TabManage(parent), glm(glm), base(db), import_tab(import_tab), games_tab(games_tab) { RefreshInformations(); + has_pending_events=false; } void BaseManageTab::RefreshInformations(){ @@ -22,6 +23,7 @@ void BaseManageTab::RefreshInformations(){ int nedited=games_tab->edited.size(); int ndeleted=games_tab->deleted.size()-nedited; if((ngames+nselect+ndb+nedited+ndeleted) >0){ + has_pending_events=true; ADD_INFO("\n---------- Pending operations ----------"); ADD_INFO("Imports:"); ADD_INFO(" -> "+std::to_string(ngames+nselect)+" game(s)"); @@ -29,6 +31,8 @@ void BaseManageTab::RefreshInformations(){ ADD_INFO("Others:"); ADD_INFO(" -> "+std::to_string(nedited)+" edited game(s)"); ADD_INFO(" -> "+std::to_string(ndeleted)+" deleted game(s)"); + } else { + has_pending_events=false; } } diff --git a/src/base_tab/BaseManageTab.hpp b/src/base_tab/BaseManageTab.hpp index 863754c..92f80d0 100644 --- a/src/base_tab/BaseManageTab.hpp +++ b/src/base_tab/BaseManageTab.hpp @@ -16,9 +16,12 @@ class BaseManageTab : public TabBase_TabManage { BaseImportTab *import_tab; BaseGameTab *games_tab; + bool has_pending_events; + public: BaseManageTab(wxFrame *parent, std::shared_ptr db, std::shared_ptr glm, BaseImportTab *import_tab, BaseGameTab *games_tab); void RefreshInformations(); void Reset(std::shared_ptr db); + bool HasPendingEvents(){return(has_pending_events);}; }; \ No newline at end of file diff --git a/src/base_tab/BaseTab.cpp b/src/base_tab/BaseTab.cpp index 8434840..1342c49 100644 --- a/src/base_tab/BaseTab.cpp +++ b/src/base_tab/BaseTab.cpp @@ -25,8 +25,9 @@ BaseTab::BaseTab(wxFrame *parent, std::string base_file) // Bindings this->Bind(wxEVT_BUTTON, &BaseTab::OnSave, this, ID_SAVE_BUTTON); this->Bind(wxEVT_LIST_ITEM_ACTIVATED, &BaseTab::OnOpenGame, this, ID_TABGAMES_GAME_LIST); - Bind(REFRESH_MANAGE_TAB,[tab=manage_tab](wxCommandEvent &e){ - tab->RefreshInformations(); + Bind(REFRESH_MANAGE_TAB,[p=this](wxCommandEvent &e){ + p->manage_tab->RefreshInformations(); + p->is_dirty=p->manage_tab->HasPendingEvents(); // Refresh tab dirty flag },wxID_ANY); } diff --git a/src/engine_tab/EngineTab.cpp b/src/engine_tab/EngineTab.cpp index 1433bac..91886ee 100644 --- a/src/engine_tab/EngineTab.cpp +++ b/src/engine_tab/EngineTab.cpp @@ -42,6 +42,7 @@ EngineTab::EngineTab(wxWindow *parent, std::string name) Bind(wxEVT_BUTTON, &EngineTab::OnSave, this, ENGINE_SAVE_CONF_BUTTON); Bind(wxEVT_BUTTON, &EngineTab::OnDelete, this, ENGINE_DELETE_CONF_BUTTON); + Bind(wxEVT_PG_CHANGED, [p=this](wxPropertyGridEvent& event){p->is_dirty=true;}); } EngineTab::~EngineTab() { diff --git a/src/game_tab/GameTab.cpp b/src/game_tab/GameTab.cpp index 32534fd..79f6794 100644 --- a/src/game_tab/GameTab.cpp +++ b/src/game_tab/GameTab.cpp @@ -11,6 +11,7 @@ GameTab::GameTab(wxFrame *parent, std::shared_ptr game) // Panels game->BuildAndVerify(); board_panel = new GameTabLeftPanel((wxFrame *)splitter, game); + board_panel->SetSaveToolEnable(false); editor_panel = new GameTabRightPanel((wxFrame *)splitter, game); splitter->SplitVertically(board_panel, editor_panel); @@ -59,6 +60,11 @@ void GameTab::OnGameChange(wxCommandEvent &event) { board_panel->Notify(); RefreshTabTitle(); } + // Update dirty flag + if(!is_linked){ + is_dirty=true; + board_panel->SetSaveToolEnable(true); + } } void GameTab::RefreshTabTitle() { diff --git a/src/game_tab/GameTab.hpp b/src/game_tab/GameTab.hpp index d2f2390..d29f1f3 100644 --- a/src/game_tab/GameTab.hpp +++ b/src/game_tab/GameTab.hpp @@ -29,5 +29,5 @@ public: std::shared_ptr GetGame() { return (std::shared_ptr(game)); } std::shared_ptr GetBase() { return nullptr; }; void OnToolClick(wxCommandEvent &event); - void OnLink(){board_panel->DisableSaveTool();}; + void OnLink(){board_panel->SetSaveToolEnable(false);}; }; diff --git a/src/game_tab/left_panel/GameTabLeftPanel.hpp b/src/game_tab/left_panel/GameTabLeftPanel.hpp index 56297d8..578f8c4 100644 --- a/src/game_tab/left_panel/GameTabLeftPanel.hpp +++ b/src/game_tab/left_panel/GameTabLeftPanel.hpp @@ -21,5 +21,5 @@ public: void OnGotoMove(wxCommandEvent &event); void OnRefreshBoard(wxCommandEvent &event); void ApplyPreferences(); - void DisableSaveTool(){game_toolbar->EnableTool(0,false);}; + void SetSaveToolEnable(bool state){game_toolbar->EnableTool(0,state);}; }; \ No newline at end of file