Procházet zdrojové kódy

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.
Itamar před 4 roky
rodič
revize
329cb134d6

+ 3 - 2
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<GUI::Label> m_filename_label;
     RefPtr<GUI::Label> m_cursor_label;
     RefPtr<Editor> m_editor;
-    bool m_document_dirty {false};
+    bool m_document_dirty { false };
 };
 
 }

+ 34 - 0
Userland/DevTools/HackStudio/HackStudioWidget.cpp

@@ -896,6 +896,9 @@ void HackStudioWidget::create_toolbar(GUI::Widget& parent)
 NonnullRefPtr<GUI::Action> 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;
+}
+
 }

+ 7 - 0
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<String> selected_file_paths() const;
@@ -112,6 +118,7 @@ private:
     void build(TerminalWrapper& wrapper);
 
     void hide_action_tabs();
+    bool any_document_is_dirty() const;
 
     NonnullRefPtrVector<EditorWrapper> m_all_editor_wrappers;
     RefPtr<EditorWrapper> m_current_editor_wrapper;

+ 6 - 0
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();