From 3f49779daec25adba76f40aedf89ab0faad432f6 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 2 Jul 2024 14:18:18 +0200 Subject: [PATCH] Gui: Extend TaskDialog * Add TaskDialog::autoClosedOnDeletedDocument() * Add option to automatically close task dialog when document is deleted * Expose autoClosedOnDeletedDocument() to Python * Expose autoClosedOnTransactionChange() to Python * Change ControlPy::showDialog() to directly return the task dialog wrapper * Change TaskView::slotDeletedDocument() to close task dialog if requested --- src/Gui/TaskView/TaskDialog.cpp | 10 +++-- src/Gui/TaskView/TaskDialog.h | 13 ++++++ src/Gui/TaskView/TaskDialogPython.cpp | 62 ++++++++++++++++++++++++++- src/Gui/TaskView/TaskDialogPython.h | 6 +++ src/Gui/TaskView/TaskView.cpp | 61 ++++++++++++++++++-------- src/Gui/TaskView/TaskView.h | 10 ++--- 6 files changed, 135 insertions(+), 27 deletions(-) diff --git a/src/Gui/TaskView/TaskDialog.cpp b/src/Gui/TaskView/TaskDialog.cpp index c85aef4a4f..b90c3123cf 100644 --- a/src/Gui/TaskView/TaskDialog.cpp +++ b/src/Gui/TaskView/TaskDialog.cpp @@ -93,10 +93,7 @@ bool TaskDialog::canClose() const msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - return true; - else - return false; + return (ret == QMessageBox::Yes); } //==== calls from the TaskView =============================================================== @@ -116,6 +113,11 @@ void TaskDialog::autoClosedOnTransactionChange() } +void TaskDialog::autoClosedOnDeletedDocument() +{ + +} + void TaskDialog::clicked(int) { diff --git a/src/Gui/TaskView/TaskDialog.h b/src/Gui/TaskView/TaskDialog.h index aaa1d32912..f291d334f3 100644 --- a/src/Gui/TaskView/TaskDialog.h +++ b/src/Gui/TaskView/TaskDialog.h @@ -91,6 +91,15 @@ public: return autoCloseTransaction; } + /// Defines whether a task dialog must be closed if the document is + /// deleted. + void setAutoCloseOnDeletedDocument(bool on) { + autoCloseDeletedDocument = on; + } + bool isAutoCloseOnDeletedDocument() const { + return autoCloseDeletedDocument; + } + const std::string& getDocumentName() const { return documentName; } void setDocumentName(const std::string& doc) @@ -124,6 +133,9 @@ public: /// is called by the framework when the dialog is automatically closed due to /// changing the active transaction virtual void autoClosedOnTransactionChange(); + /// is called by the framework when the dialog is automatically closed due to + /// deleting the document + virtual void autoClosedOnDeletedDocument(); /// is called by the framework if a button is clicked which has no accept or reject role virtual void clicked(int); /// is called by the framework if the dialog is accepted (Ok) @@ -150,6 +162,7 @@ private: std::string documentName; bool escapeButton; bool autoCloseTransaction; + bool autoCloseDeletedDocument; friend class TaskDialogAttorney; }; diff --git a/src/Gui/TaskView/TaskDialogPython.cpp b/src/Gui/TaskView/TaskDialogPython.cpp index 0ced4166b5..7650778226 100644 --- a/src/Gui/TaskView/TaskDialogPython.cpp +++ b/src/Gui/TaskView/TaskDialogPython.cpp @@ -120,7 +120,7 @@ Py::Object ControlPy::showDialog(const Py::Tuple& args) throw Py::RuntimeError("Active task dialog found"); auto dlg = new TaskDialogPython(Py::Object(arg0)); Gui::Control().showDialog(dlg); - return Py::None(); + return (Py::asObject(new TaskDialogPy(dlg))); } Py::Object ControlPy::activeDialog(const Py::Tuple& args) @@ -335,8 +335,14 @@ void TaskDialogPy::init_type() "active transaction"); add_varargs_method("isAutoCloseOnTransactionChange",&TaskDialogPy::isAutoCloseOnTransactionChange, "Checks if the task dialog will be closed when the active transaction has changed -> bool"); + add_varargs_method("setAutoCloseOnDeletedDocument",&TaskDialogPy::setAutoCloseOnDeletedDocument, + "Defines whether a task dialog must be closed if the document is deleted"); + add_varargs_method("isAutoCloseOnDeletedDocument",&TaskDialogPy::isAutoCloseOnDeletedDocument, + "Checks if the task dialog will be closed if the document is deleted -> bool"); add_varargs_method("getDocumentName",&TaskDialogPy::getDocumentName, "Get the name of the document the task dialog is attached to -> str"); + add_varargs_method("setDocumentName",&TaskDialogPy::setDocumentName, + "Set the name of the document the task dialog is attached to"); add_varargs_method("isAllowedAlterDocument",&TaskDialogPy::isAllowedAlterDocument, "Indicates whether this task dialog allows other commands to modify\n" "the document while it is open -> bool"); @@ -442,6 +448,20 @@ Py::Object TaskDialogPy::isAutoCloseOnTransactionChange(const Py::Tuple& args) return Py::Boolean(dialog->isAutoCloseOnTransactionChange()); } +Py::Object TaskDialogPy::setAutoCloseOnDeletedDocument(const Py::Tuple& args) +{ + Py::Boolean value(args[0]); + dialog->setAutoCloseOnDeletedDocument(static_cast(value)); + return Py::None(); +} + +Py::Object TaskDialogPy::isAutoCloseOnDeletedDocument(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) + throw Py::Exception(); + return Py::Boolean(dialog->isAutoCloseOnDeletedDocument()); +} + Py::Object TaskDialogPy::getDocumentName(const Py::Tuple& args) { if (!PyArg_ParseTuple(args.ptr(), "")) @@ -449,6 +469,15 @@ Py::Object TaskDialogPy::getDocumentName(const Py::Tuple& args) return Py::String(dialog->getDocumentName()); } +Py::Object TaskDialogPy::setDocumentName(const Py::Tuple& args) +{ + const char* name {""}; + if (!PyArg_ParseTuple(args.ptr(), "s", &name)) + throw Py::Exception(); + dialog->setDocumentName(name); + return Py::None(); +} + Py::Object TaskDialogPy::isAllowedAlterDocument(const Py::Tuple& args) { if (!PyArg_ParseTuple(args.ptr(), "")) @@ -845,3 +874,34 @@ bool TaskDialogPython::needsFullSpace() const return TaskDialog::needsFullSpace(); } +void TaskDialogPython::autoClosedOnTransactionChange() +{ + Base::PyGILStateLocker lock; + try { + if (dlg.hasAttr(std::string("autoClosedOnTransactionChange"))) { + Py::Callable method(dlg.getAttr(std::string("autoClosedOnTransactionChange"))); + Py::Tuple args; + method.apply(args); + } + } + catch (Py::Exception&) { + Base::PyException e; // extract the Python error text + e.ReportException(); + } +} + +void TaskDialogPython::autoClosedOnDeletedDocument() +{ + Base::PyGILStateLocker lock; + try { + if (dlg.hasAttr(std::string("autoClosedOnDeletedDocument"))) { + Py::Callable method(dlg.getAttr(std::string("autoClosedOnDeletedDocument"))); + Py::Tuple args; + method.apply(args); + } + } + catch (Py::Exception&) { + Base::PyException e; // extract the Python error text + e.ReportException(); + } +} diff --git a/src/Gui/TaskView/TaskDialogPython.h b/src/Gui/TaskView/TaskDialogPython.h index 274a5c4a4d..9247c7932a 100644 --- a/src/Gui/TaskView/TaskDialogPython.h +++ b/src/Gui/TaskView/TaskDialogPython.h @@ -99,8 +99,11 @@ public: /// active transaction. Py::Object setAutoCloseOnTransactionChange(const Py::Tuple&); Py::Object isAutoCloseOnTransactionChange(const Py::Tuple&); + Py::Object setAutoCloseOnDeletedDocument(const Py::Tuple&); + Py::Object isAutoCloseOnDeletedDocument(const Py::Tuple&); Py::Object getDocumentName(const Py::Tuple&); + Py::Object setDocumentName(const Py::Tuple&); /*! Indicates whether this task dialog allows other commands to modify @@ -160,6 +163,9 @@ public: bool isAllowedAlterSelection() const override; bool needsFullSpace() const override; + void autoClosedOnTransactionChange() override; + void autoClosedOnDeletedDocument() override; + public: /// is called by the framework when the dialog is opened void open() override; diff --git a/src/Gui/TaskView/TaskView.cpp b/src/Gui/TaskView/TaskView.cpp index ae231262bc..dbc7cd573b 100644 --- a/src/Gui/TaskView/TaskView.cpp +++ b/src/Gui/TaskView/TaskView.cpp @@ -34,6 +34,7 @@ # include #endif +#include #include #include #include @@ -292,8 +293,8 @@ TaskView::TaskView(QWidget *parent) App::GetApplication().signalActiveDocument.connect (std::bind(&Gui::TaskView::TaskView::slotActiveDocument, this, sp::_1)); connectApplicationDeleteDocument = - App::GetApplication().signalDeletedDocument.connect - (std::bind(&Gui::TaskView::TaskView::slotDeletedDocument, this)); + App::GetApplication().signalDeleteDocument.connect + (std::bind(&Gui::TaskView::TaskView::slotDeletedDocument, this, sp::_1)); connectApplicationUndoDocument = App::GetApplication().signalUndoDocument.connect (std::bind(&Gui::TaskView::TaskView::slotUndoDocument, this, sp::_1)); @@ -456,32 +457,58 @@ void TaskView::slotActiveDocument(const App::Document& doc) updateWatcher(); } -void TaskView::slotDeletedDocument() +void TaskView::slotDeletedDocument(const App::Document& doc) { - if (!ActiveDialog) - updateWatcher(); -} + if (ActiveDialog) { + if (ActiveDialog->isAutoCloseOnDeletedDocument()) { + std::string name = ActiveDialog->getDocumentName(); + if (name.empty()) { + Base::Console().Warning(std::string("TaskView::slotDeletedDocument"), + "No document name set\n"); + } -void TaskView::slotUndoDocument(const App::Document&) -{ - if (ActiveDialog && ActiveDialog->isAutoCloseOnTransactionChange()) { - ActiveDialog->autoClosedOnTransactionChange(); - removeDialog(); + if (name == doc.getName()) { + ActiveDialog->autoClosedOnDeletedDocument(); + removeDialog(); + } + } } - if (!ActiveDialog) + if (!ActiveDialog) { updateWatcher(); + } } -void TaskView::slotRedoDocument(const App::Document&) +void TaskView::transactionChangeOnDocument(const App::Document& doc) { - if (ActiveDialog && ActiveDialog->isAutoCloseOnTransactionChange()) { - ActiveDialog->autoClosedOnTransactionChange(); - removeDialog(); + if (ActiveDialog) { + if (ActiveDialog->isAutoCloseOnTransactionChange()) { + std::string name = ActiveDialog->getDocumentName(); + if (name.empty()) { + Base::Console().Warning(std::string("TaskView::transactionChangeOnDocument"), + "No document name set\n"); + } + + if (name == doc.getName()) { + ActiveDialog->autoClosedOnTransactionChange(); + removeDialog(); + } + } } - if (!ActiveDialog) + if (!ActiveDialog) { updateWatcher(); + } +} + +void TaskView::slotUndoDocument(const App::Document& doc) +{ + transactionChangeOnDocument(doc); +} + +void TaskView::slotRedoDocument(const App::Document& doc) +{ + transactionChangeOnDocument(doc); } /// @cond DOXERR diff --git a/src/Gui/TaskView/TaskView.h b/src/Gui/TaskView/TaskView.h index 7b58e76aa3..19b318a943 100644 --- a/src/Gui/TaskView/TaskView.h +++ b/src/Gui/TaskView/TaskView.h @@ -181,6 +181,11 @@ private: void adjustMinimumSizeHint(); void saveCurrentWidth(); void tryRestoreWidth(); + void slotActiveDocument(const App::Document&); + void slotDeletedDocument(const App::Document&); + void slotUndoDocument(const App::Document&); + void slotRedoDocument(const App::Document&); + void transactionChangeOnDocument(const App::Document&); protected: void keyPressEvent(QKeyEvent* event) override; @@ -195,11 +200,6 @@ protected: // removes the running dialog after accept() or reject() from the TaskView void removeDialog(); - void slotActiveDocument(const App::Document&); - void slotDeletedDocument(); - void slotUndoDocument(const App::Document&); - void slotRedoDocument(const App::Document&); - std::vector ActiveWatcher; QSint::ActionPanel* taskPanel;