From 5f58fe16435ff27a0b2a396dab42a75a893d3e2c Mon Sep 17 00:00:00 2001 From: Xavier Cooney Date: Tue, 22 Dec 2020 16:15:15 +1100 Subject: Spreadsheet: Prompt user before closing with unsaved changes --- Applications/Spreadsheet/Spreadsheet.cpp | 4 +++- Applications/Spreadsheet/SpreadsheetWidget.cpp | 28 ++++++++++++++++++++++++++ Applications/Spreadsheet/SpreadsheetWidget.h | 1 + Applications/Spreadsheet/Workbook.cpp | 1 + Applications/Spreadsheet/Workbook.h | 3 +++ Applications/Spreadsheet/main.cpp | 8 ++++++++ 6 files changed, 44 insertions(+), 1 deletion(-) (limited to 'Applications/Spreadsheet') diff --git a/Applications/Spreadsheet/Spreadsheet.cpp b/Applications/Spreadsheet/Spreadsheet.cpp index 4a9e57c2f2..f0f28b3e80 100644 --- a/Applications/Spreadsheet/Spreadsheet.cpp +++ b/Applications/Spreadsheet/Spreadsheet.cpp @@ -163,8 +163,10 @@ void Sheet::update() // Grab a copy as updates might insert cells into the table. for (auto& it : m_cells) { - if (it.value->dirty()) + if (it.value->dirty()) { cells_copy.append(it.value); + m_workbook.set_dirty(true); + } } for (auto& cell : cells_copy) diff --git a/Applications/Spreadsheet/SpreadsheetWidget.cpp b/Applications/Spreadsheet/SpreadsheetWidget.cpp index 5734b888f0..6e94ed4093 100644 --- a/Applications/Spreadsheet/SpreadsheetWidget.cpp +++ b/Applications/Spreadsheet/SpreadsheetWidget.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -216,6 +217,33 @@ void SpreadsheetWidget::load(const StringView& filename) setup_tabs(m_workbook->sheets()); } +bool SpreadsheetWidget::request_close() +{ + if (!m_workbook->dirty()) + return true; + + auto result = GUI::MessageBox::show(window(), "The spreadsheet has been modified. Would you like to save?", "Unsaved changes", GUI::MessageBox::Type::Warning, GUI::MessageBox::InputType::YesNoCancel); + + if (result == GUI::MessageBox::ExecYes) { + if (current_filename().is_empty()) { + String name = "workbook"; + Optional save_path = GUI::FilePicker::get_save_filepath(window(), name, "sheets"); + if (!save_path.has_value()) + return false; + + save(save_path.value()); + } else { + save(current_filename()); + } + return true; + } + + if (result == GUI::MessageBox::ExecNo) + return true; + + return false; +} + void SpreadsheetWidget::add_sheet() { StringBuilder name; diff --git a/Applications/Spreadsheet/SpreadsheetWidget.h b/Applications/Spreadsheet/SpreadsheetWidget.h index 10eb908da0..c13531fc2a 100644 --- a/Applications/Spreadsheet/SpreadsheetWidget.h +++ b/Applications/Spreadsheet/SpreadsheetWidget.h @@ -41,6 +41,7 @@ public: void save(const StringView& filename); void load(const StringView& filename); + bool request_close(); void add_sheet(); void add_sheet(NonnullRefPtr&&); diff --git a/Applications/Spreadsheet/Workbook.cpp b/Applications/Spreadsheet/Workbook.cpp index ca0f932f76..db5bf16cb5 100644 --- a/Applications/Spreadsheet/Workbook.cpp +++ b/Applications/Spreadsheet/Workbook.cpp @@ -183,6 +183,7 @@ Result Workbook::save(const StringView& filename) } set_filename(filename); + set_dirty(false); return true; } diff --git a/Applications/Spreadsheet/Workbook.h b/Applications/Spreadsheet/Workbook.h index c03fbfa5ab..63c016d501 100644 --- a/Applications/Spreadsheet/Workbook.h +++ b/Applications/Spreadsheet/Workbook.h @@ -42,6 +42,8 @@ public: const String& current_filename() const { return m_current_filename; } bool set_filename(const String& filename); + bool dirty() { return m_dirty; } + void set_dirty(bool dirty) { m_dirty = dirty; } bool has_sheets() const { return !m_sheets.is_empty(); } @@ -70,6 +72,7 @@ private: WorkbookObject* m_workbook_object { nullptr }; String m_current_filename; + bool m_dirty { false }; }; } diff --git a/Applications/Spreadsheet/main.cpp b/Applications/Spreadsheet/main.cpp index c9ab4321bb..0bfde24459 100644 --- a/Applications/Spreadsheet/main.cpp +++ b/Applications/Spreadsheet/main.cpp @@ -114,9 +114,17 @@ int main(int argc, char* argv[]) app_menu.add_separator(); app_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { + if (!spreadsheet_widget.request_close()) + return; app->quit(0); })); + window->on_close_request = [&]() -> GUI::Window::CloseRequestDecision { + if (spreadsheet_widget.request_close()) + return GUI::Window::CloseRequestDecision::Close; + return GUI::Window::CloseRequestDecision::StayOpen; + }; + auto& file_menu = menubar->add_menu("File"); file_menu.add_action(GUI::CommonActions::make_open_action([&](auto&) { Optional load_path = GUI::FilePicker::get_open_filepath(window); -- cgit v1.2.3