From 329cb134d6f5b47a3238eaae9a4e672403faf00d Mon Sep 17 00:00:00 2001 From: Itamar Date: Sat, 1 May 2021 13:42:07 +0300 Subject: [PATCH] HackStudio: Show dialog on build and exit if there are unsaved changes If the user tries to exit HackStudio, or build the project, when there are unsaved changes in some of the editors, A Yes/No/Cancel dialog will be shown. --- Userland/DevTools/HackStudio/EditorWrapper.h | 5 +-- .../DevTools/HackStudio/HackStudioWidget.cpp | 34 +++++++++++++++++++ .../DevTools/HackStudio/HackStudioWidget.h | 7 ++++ Userland/DevTools/HackStudio/main.cpp | 6 ++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/Userland/DevTools/HackStudio/EditorWrapper.h b/Userland/DevTools/HackStudio/EditorWrapper.h index ea72912180..5493be746e 100644 --- a/Userland/DevTools/HackStudio/EditorWrapper.h +++ b/Userland/DevTools/HackStudio/EditorWrapper.h @@ -37,7 +37,8 @@ public: void set_mode_displayable(); void set_mode_non_displayable(); void set_filename(const String&); - const String& filename() const {return m_filename;} + const String& filename() const { return m_filename; } + bool document_dirty() const { return m_document_dirty; } private: EditorWrapper(); @@ -48,7 +49,7 @@ private: RefPtr m_filename_label; RefPtr m_cursor_label; RefPtr m_editor; - bool m_document_dirty {false}; + bool m_document_dirty { false }; }; } diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp index 5f7f0e5d32..5082480f96 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp +++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp @@ -896,6 +896,9 @@ void HackStudioWidget::create_toolbar(GUI::Widget& parent) NonnullRefPtr HackStudioWidget::create_build_action() { return GUI::Action::create("&Build", { Mod_Ctrl, Key_B }, Gfx::Bitmap::load_from_file("/res/icons/16x16/build.png"), [this](auto&) { + if (warn_unsaved_changes("There are unsaved changes, do you want to save before building?") == ContinueDecision::No) + return; + reveal_action_tab(*m_terminal_wrapper); build(*m_terminal_wrapper); m_stop_action->set_enabled(true); @@ -1129,4 +1132,35 @@ HackStudioWidget::~HackStudioWidget() } } +HackStudioWidget::ContinueDecision HackStudioWidget::warn_unsaved_changes(const String& prompt) +{ + if (!any_document_is_dirty()) + return ContinueDecision::Yes; + + auto result = GUI::MessageBox::show(window(), prompt, "Unsaved changes", GUI::MessageBox::Type::Warning, GUI::MessageBox::InputType::YesNoCancel); + + if (result == GUI::MessageBox::ExecCancel) + return ContinueDecision::No; + + if (result == GUI::MessageBox::ExecYes) { + for (auto& editor_wrapper : m_all_editor_wrappers) { + if (editor_wrapper.document_dirty()) { + editor_wrapper.save(); + } + } + } + + return ContinueDecision::Yes; +} + +bool HackStudioWidget::any_document_is_dirty() const +{ + for (auto& editor_wrapper : m_all_editor_wrappers) { + if (editor_wrapper.document_dirty()) { + return true; + } + } + return false; +} + } diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.h b/Userland/DevTools/HackStudio/HackStudioWidget.h index 5d386712fa..be71cd480b 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.h +++ b/Userland/DevTools/HackStudio/HackStudioWidget.h @@ -50,6 +50,12 @@ public: return *m_locator; } + enum class ContinueDecision { + No, + Yes + }; + ContinueDecision warn_unsaved_changes(const String& prompt); + private: static String get_full_path_of_serenity_source(const String& file); Vector selected_file_paths() const; @@ -112,6 +118,7 @@ private: void build(TerminalWrapper& wrapper); void hide_action_tabs(); + bool any_document_is_dirty() const; NonnullRefPtrVector m_all_editor_wrappers; RefPtr m_current_editor_wrapper; diff --git a/Userland/DevTools/HackStudio/main.cpp b/Userland/DevTools/HackStudio/main.cpp index 0cb393c89b..cea0bda219 100644 --- a/Userland/DevTools/HackStudio/main.cpp +++ b/Userland/DevTools/HackStudio/main.cpp @@ -81,6 +81,12 @@ int main(int argc, char** argv) s_hack_studio_widget->initialize_menubar(menubar); s_window->set_menubar(menubar); + s_window->on_close_request = [&]() -> GUI::Window::CloseRequestDecision { + if (s_hack_studio_widget->warn_unsaved_changes("There are unsaved changes, do you want to save before exiting?") == HackStudioWidget::ContinueDecision::Yes) + return GUI::Window::CloseRequestDecision::Close; + return GUI::Window::CloseRequestDecision::StayOpen; + }; + s_window->show(); s_hack_studio_widget->update_actions();