Core: Enable TaskDialogs to associate view (#17373)
* Core: Add possibility for task dialogs to associate a view and be able to close when associated view is closed. * TaskImage: Use task dialog view association. * Sketcher: Use task dialog view association. Preventing crash (https://github.com/FreeCAD/FreeCAD/issues/16702) * EditableDatumLabel: Use QPointer to prevent crash
This commit is contained in:
@@ -1411,6 +1411,11 @@ void Application::viewActivated(MDIView* pcView)
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets called if a view gets closed
|
||||
void Application::viewClosed(MDIView* pcView)
|
||||
{
|
||||
signalCloseView(pcView);
|
||||
}
|
||||
|
||||
void Application::updateActive()
|
||||
{
|
||||
|
||||
@@ -97,6 +97,8 @@ public:
|
||||
void detachView(Gui::BaseView* pcView);
|
||||
/// get called if a view gets activated, this manage the whole activation scheme
|
||||
void viewActivated(Gui::MDIView* pcView);
|
||||
/// get called if a view gets closed
|
||||
void viewClosed(Gui::MDIView* pcView);
|
||||
/// call update to all documents and all views (costly!)
|
||||
void onUpdate();
|
||||
/// call update to all views of the active document
|
||||
@@ -137,6 +139,8 @@ public:
|
||||
boost::signals2::signal<void (const Gui::Document&)> signalShowHidden;
|
||||
/// signal on activating view
|
||||
boost::signals2::signal<void (const Gui::MDIView*)> signalActivateView;
|
||||
/// signal on closing view
|
||||
boost::signals2::signal<void (const Gui::MDIView*)> signalCloseView;
|
||||
/// signal on entering in edit mode
|
||||
boost::signals2::signal<void (const Gui::ViewProviderDocumentObject&)> signalInEdit;
|
||||
/// signal on leaving edit mode
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define GUI_EDITABLEDATUMLABEL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <Gui/QuantitySpinBox.h>
|
||||
|
||||
#include "SoDatumLabel.h"
|
||||
@@ -98,7 +99,7 @@ private:
|
||||
private:
|
||||
SoSeparator* root;
|
||||
SoTransform* transform;
|
||||
View3DInventorViewer* viewer;
|
||||
QPointer<View3DInventorViewer> viewer;
|
||||
QuantitySpinBox* spinBox;
|
||||
SoNodeSensor* cameraSensor;
|
||||
SbVec3f midpos;
|
||||
|
||||
@@ -209,6 +209,8 @@ void MDIView::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
if (canClose()) {
|
||||
e->accept();
|
||||
Application::Instance->viewClosed(this);
|
||||
|
||||
if (!bIsPassive) {
|
||||
// must be detached so that the last view can get asked
|
||||
Document* doc = this->getGuiDocument();
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
# include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include <App/Document.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/ViewProviderDocumentObject.h>
|
||||
|
||||
|
||||
#include "TaskDialog.h"
|
||||
#include "TaskView.h"
|
||||
|
||||
@@ -42,6 +49,8 @@ TaskDialog::TaskDialog()
|
||||
: QObject(nullptr), pos(North)
|
||||
, escapeButton(true)
|
||||
, autoCloseTransaction(false)
|
||||
, autoCloseDeletedDocument(false)
|
||||
, autoCloseClosedView(false)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -96,6 +105,25 @@ bool TaskDialog::canClose() const
|
||||
return (ret == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void TaskDialog::associateToObject3dView(App::DocumentObject* obj)
|
||||
{
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gui::Document* guiDoc = Gui::Application::Instance->getDocument(obj->getDocument());
|
||||
auto* vp = Gui::Application::Instance->getViewProvider(obj);
|
||||
auto* vpdo = static_cast<Gui::ViewProviderDocumentObject*>(vp);
|
||||
auto* view = guiDoc->openEditingView3D(vpdo);
|
||||
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
|
||||
setAssociatedView(view);
|
||||
setAutoCloseOnClosedView(true);
|
||||
}
|
||||
|
||||
//==== calls from the TaskView ===============================================================
|
||||
|
||||
void TaskDialog::open()
|
||||
@@ -118,6 +146,11 @@ void TaskDialog::autoClosedOnDeletedDocument()
|
||||
|
||||
}
|
||||
|
||||
void TaskDialog::autoClosedOnClosedView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TaskDialog::clicked(int)
|
||||
{
|
||||
|
||||
|
||||
@@ -33,10 +33,11 @@
|
||||
|
||||
|
||||
namespace App {
|
||||
|
||||
class DocumentObject;
|
||||
}
|
||||
|
||||
namespace Gui {
|
||||
class MDIView;
|
||||
namespace TaskView {
|
||||
|
||||
class TaskContent;
|
||||
@@ -104,6 +105,22 @@ public:
|
||||
{ return documentName; }
|
||||
void setDocumentName(const std::string& doc)
|
||||
{ documentName = doc; }
|
||||
|
||||
/// Defines whether a task dialog must be closed if the associated view
|
||||
/// is deleted.
|
||||
void setAutoCloseOnClosedView(bool on) {
|
||||
autoCloseClosedView = on;
|
||||
}
|
||||
bool isAutoCloseOnClosedView() const {
|
||||
return autoCloseClosedView;
|
||||
}
|
||||
void associateToObject3dView(App::DocumentObject* obj);
|
||||
|
||||
const Gui::MDIView* getAssociatedView() const
|
||||
{ return associatedView; }
|
||||
void setAssociatedView(const Gui::MDIView* view)
|
||||
{ associatedView = view; }
|
||||
|
||||
/*!
|
||||
Indicates whether this task dialog allows other commands to modify
|
||||
the document while it is open.
|
||||
@@ -136,6 +153,9 @@ public:
|
||||
/// is called by the framework when the dialog is automatically closed due to
|
||||
/// deleting the document
|
||||
virtual void autoClosedOnDeletedDocument();
|
||||
/// is called by the framework when the dialog is automatically closed due to
|
||||
/// closing of associated view
|
||||
virtual void autoClosedOnClosedView();
|
||||
/// 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)
|
||||
@@ -160,9 +180,11 @@ protected:
|
||||
|
||||
private:
|
||||
std::string documentName;
|
||||
const Gui::MDIView* associatedView;
|
||||
bool escapeButton;
|
||||
bool autoCloseTransaction;
|
||||
bool autoCloseDeletedDocument;
|
||||
bool autoCloseClosedView;
|
||||
|
||||
friend class TaskDialogAttorney;
|
||||
};
|
||||
|
||||
@@ -679,9 +679,7 @@ TaskImageDialog::TaskImageDialog(Image::ImagePlane* obj)
|
||||
{
|
||||
addTaskBox(Gui::BitmapFactory().pixmap("image-plane"), widget);
|
||||
|
||||
auto doc = obj->getDocument();
|
||||
setDocumentName(doc->getName());
|
||||
setAutoCloseOnDeletedDocument(true);
|
||||
associateToObject3dView(obj);
|
||||
}
|
||||
|
||||
void TaskImageDialog::open()
|
||||
|
||||
@@ -295,6 +295,9 @@ TaskView::TaskView(QWidget *parent)
|
||||
connectApplicationDeleteDocument =
|
||||
App::GetApplication().signalDeleteDocument.connect
|
||||
(std::bind(&Gui::TaskView::TaskView::slotDeletedDocument, this, sp::_1));
|
||||
connectApplicationClosedView =
|
||||
Gui::Application::Instance->signalCloseView.connect
|
||||
(std::bind(&Gui::TaskView::TaskView::slotViewClosed, this, sp::_1));
|
||||
connectApplicationUndoDocument =
|
||||
App::GetApplication().signalUndoDocument.connect
|
||||
(std::bind(&Gui::TaskView::TaskView::slotUndoDocument, this, sp::_1));
|
||||
@@ -310,6 +313,7 @@ TaskView::~TaskView()
|
||||
{
|
||||
connectApplicationActiveDocument.disconnect();
|
||||
connectApplicationDeleteDocument.disconnect();
|
||||
connectApplicationClosedView.disconnect();
|
||||
connectApplicationUndoDocument.disconnect();
|
||||
connectApplicationRedoDocument.disconnect();
|
||||
Gui::Selection().Detach(this);
|
||||
@@ -479,6 +483,29 @@ void TaskView::slotDeletedDocument(const App::Document& doc)
|
||||
}
|
||||
}
|
||||
|
||||
void TaskView::slotViewClosed(const Gui::MDIView* view)
|
||||
{
|
||||
// It can happen that only a view is closed an not the document
|
||||
if (ActiveDialog) {
|
||||
if (ActiveDialog->isAutoCloseOnClosedView()) {
|
||||
const Gui::MDIView* associatedView = ActiveDialog->getAssociatedView();
|
||||
if (!associatedView) {
|
||||
Base::Console().Warning(std::string("TaskView::slotViewClosed"),
|
||||
"No view associated\n");
|
||||
}
|
||||
|
||||
if (associatedView == view) {
|
||||
ActiveDialog->autoClosedOnClosedView();
|
||||
removeDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ActiveDialog) {
|
||||
updateWatcher();
|
||||
}
|
||||
}
|
||||
|
||||
void TaskView::transactionChangeOnDocument(const App::Document& doc)
|
||||
{
|
||||
if (ActiveDialog) {
|
||||
|
||||
@@ -37,6 +37,7 @@ class Property;
|
||||
}
|
||||
|
||||
namespace Gui {
|
||||
class MDIView;
|
||||
class ControlSingleton;
|
||||
namespace DockWnd{
|
||||
class ComboView;
|
||||
@@ -183,6 +184,7 @@ private:
|
||||
void tryRestoreWidth();
|
||||
void slotActiveDocument(const App::Document&);
|
||||
void slotDeletedDocument(const App::Document&);
|
||||
void slotViewClosed(const Gui::MDIView*);
|
||||
void slotUndoDocument(const App::Document&);
|
||||
void slotRedoDocument(const App::Document&);
|
||||
void transactionChangeOnDocument(const App::Document&);
|
||||
@@ -210,6 +212,7 @@ protected:
|
||||
|
||||
Connection connectApplicationActiveDocument;
|
||||
Connection connectApplicationDeleteDocument;
|
||||
Connection connectApplicationClosedView;
|
||||
Connection connectApplicationUndoDocument;
|
||||
Connection connectApplicationRedoDocument;
|
||||
};
|
||||
|
||||
@@ -79,6 +79,8 @@ TaskDlgEditSketch::TaskDlgEditSketch(ViewProviderSketch* sketchView)
|
||||
std::bind(&SketcherGui::TaskDlgEditSketch::slotToolChanged, this, sp::_1));
|
||||
|
||||
ToolSettings->setHidden(true);
|
||||
|
||||
associateToObject3dView(sketchView->getObject());
|
||||
}
|
||||
|
||||
TaskDlgEditSketch::~TaskDlgEditSketch()
|
||||
@@ -145,4 +147,10 @@ bool TaskDlgEditSketch::reject()
|
||||
}
|
||||
|
||||
|
||||
void TaskDlgEditSketch::autoClosedOnClosedView()
|
||||
{
|
||||
// Make sure the edit mode is exited when the view is closed.
|
||||
reject();
|
||||
}
|
||||
|
||||
#include "moc_TaskDlgEditSketch.cpp"
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void autoClosedOnClosedView() override;
|
||||
|
||||
/// returns for Close and Help button
|
||||
QDialogButtonBox::StandardButtons getStandardButtons() const override
|
||||
|
||||
Reference in New Issue
Block a user