From 5a61baf07c20674142e92a9386f8efd42c64c9e9 Mon Sep 17 00:00:00 2001 From: donovaly Date: Tue, 3 Mar 2020 03:54:08 +0100 Subject: [PATCH] [TD] handle object deletions better see https://forum.freecadweb.org/viewtopic.php?p=366902#p366902 --- .../TechDraw/Gui/ViewProviderDimension.cpp | 9 ++++ src/Mod/TechDraw/Gui/ViewProviderDimension.h | 3 +- src/Mod/TechDraw/Gui/ViewProviderPage.cpp | 46 ++++++++++++++++-- src/Mod/TechDraw/Gui/ViewProviderPage.h | 1 + .../TechDraw/Gui/ViewProviderProjGroup.cpp | 42 ++++++++++++++++- src/Mod/TechDraw/Gui/ViewProviderProjGroup.h | 3 +- .../Gui/ViewProviderProjGroupItem.cpp | 47 +++++++++++++++++++ .../TechDraw/Gui/ViewProviderProjGroupItem.h | 2 + src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp | 28 +++++++++++ src/Mod/TechDraw/Gui/ViewProviderTemplate.h | 1 + 10 files changed, 175 insertions(+), 7 deletions(-) diff --git a/src/Mod/TechDraw/Gui/ViewProviderDimension.cpp b/src/Mod/TechDraw/Gui/ViewProviderDimension.cpp index fab6b5a652d1..f07bccb899c2 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderDimension.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderDimension.cpp @@ -221,3 +221,12 @@ void ViewProviderDimension::handleChangedPropertyType(Base::XMLReader &reader, c LineWidth.setValue(LineWidthProperty.getValue()); } } + +bool ViewProviderDimension::canDelete(App::DocumentObject *obj) const +{ + // deletions of objects from a ProjGroupItem don't necesarily destroy anything + // thus we can pass this action + // we can warn the user if necessary in the object's ViewProvider in the onDelete() function + Q_UNUSED(obj) + return true; +} diff --git a/src/Mod/TechDraw/Gui/ViewProviderDimension.h b/src/Mod/TechDraw/Gui/ViewProviderDimension.h index 4d446adfa311..73cfa721007a 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderDimension.h +++ b/src/Mod/TechDraw/Gui/ViewProviderDimension.h @@ -80,8 +80,9 @@ class TechDrawGuiExport ViewProviderDimension : public ViewProviderDrawingView double prefFontSize() const; double prefWeight() const; int prefStandardAndStyle() const; + virtual bool canDelete(App::DocumentObject* obj) const; -protected: +protected: virtual void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop); private: diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp index 0a2ae493eaf8..aca98bd82951 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp @@ -27,6 +27,8 @@ #ifndef _PreComp_ # include # include +# include +# include # include #include #include @@ -191,11 +193,37 @@ void ViewProviderPage::updateData(const App::Property* prop) Gui::ViewProviderDocumentObject::updateData(prop); } -bool ViewProviderPage::onDelete(const std::vector &items) +bool ViewProviderPage::onDelete(const std::vector &) { - bool rc = ViewProviderDocumentObject::onDelete(items); - removeMDIView(); - return rc; + // warn the user if the Page is not empty + + // check if there are items in the group + auto objs = claimChildren(); + + if (!objs.empty()) + { + // generate dialog + QString bodyMessage; + QTextStream bodyMessageStream(&bodyMessage); + bodyMessageStream << qApp->translate("Std_Delete", + "The page is not empty, therefore the\n following referencing objects might be lost.\n\n" + "Are you sure you want to continue?\n"); + for (auto ObjIterator : objs) + bodyMessageStream << '\n' << QString::fromUtf8(ObjIterator->Label.getValue()); + // show and evaluate the dialog + int DialogResult = QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, + QMessageBox::Yes, QMessageBox::No); + if (DialogResult == QMessageBox::Yes) { + removeMDIView(); + return true; + } else + return false; + } + else { + removeMDIView(); + return true; + } } void ViewProviderPage::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) @@ -421,6 +449,16 @@ void ViewProviderPage::setGraphicsView(QGVPage* gv) m_graphicsView = gv; } +bool ViewProviderPage::canDelete(App::DocumentObject *obj) const +{ + // deletions from a page don't necesarily destroy anything + // thus we can pass this action + // if an object could break something, like e.g. the template object + // its ViewProvider handles this in the onDelete() function + Q_UNUSED(obj) + return true; +} + //! Redo the whole visual page void ViewProviderPage::onGuiRepaint(const TechDraw::DrawPage* dp) { diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.h b/src/Mod/TechDraw/Gui/ViewProviderPage.h index 1fb87865e45f..1a81a39c96f1 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.h +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.h @@ -92,6 +92,7 @@ class TechDrawGuiExport ViewProviderPage : public Gui::ViewProviderDocumentObjec void toggleFrameState(void); void setTemplateMarkers(bool state); void setGraphicsView(QGVPage* gv); + virtual bool canDelete(App::DocumentObject* obj) const; protected: bool setEdit(int ModNum) override; diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp index 8871908f630a..eb4273808c44 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.cpp @@ -27,6 +27,8 @@ # endif # include # include +# include +# include #endif #include @@ -48,7 +50,6 @@ #include - #include "TaskProjGroup.h" #include "ViewProviderProjGroup.h" @@ -146,6 +147,45 @@ bool ViewProviderProjGroup::doubleClicked(void) return true; } +bool ViewProviderProjGroup::onDelete(const std::vector &) +{ + // warn the user if the ProjGroup is not empty + + // check if there are items in the group + auto objs = claimChildren(); + + if (!objs.empty()) + { + // generate dialog + QString bodyMessage; + QTextStream bodyMessageStream(&bodyMessage); + bodyMessageStream << qApp->translate("Std_Delete", + "The projection group is not empty, therefore\n the following referencing objects might be lost.\n\n" + "Are you sure you want to continue?\n"); + for (auto ObjIterator : objs) + bodyMessageStream << '\n' << QString::fromUtf8(ObjIterator->Label.getValue()); + // show and evaluate dialog + int DialogResult = QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, + QMessageBox::Yes, QMessageBox::No); + if (DialogResult == QMessageBox::Yes) + return true; + else + return false; + } + else + return true; +} + +bool ViewProviderProjGroup::canDelete(App::DocumentObject *obj) const +{ + // deletions of views from a ProjGroup don't necesarily destroy anything + // thus we can pass this action + // we can warn the user if necessary in the object's ViewProvider in the onDelete() function + Q_UNUSED(obj) + return true; +} + std::vector ViewProviderProjGroup::claimChildren(void) const { // Collect any child fields diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h index c5842dc1d282..caf7faa7300c 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroup.h @@ -60,7 +60,8 @@ class TechDrawGuiExport ViewProviderProjGroup : public ViewProviderDrawingView virtual TechDraw::DrawProjGroup* getViewObject() const; void unsetEdit(int ModNum); virtual void onChanged(const App::Property *prop); - + virtual bool onDelete(const std::vector &); + virtual bool canDelete(App::DocumentObject* obj) const; protected: bool setEdit(int ModNum); diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp index b00129e34b2a..e0e68f080c16 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.cpp @@ -22,6 +22,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ + #include + #include #endif /// Here the FreeCAD includes sorted by Base,App,Gui...... @@ -41,6 +43,8 @@ #include #include +#include +#include #include "ViewProviderProjGroupItem.h" @@ -142,6 +146,49 @@ bool ViewProviderProjGroupItem::doubleClicked(void) return true; } +bool ViewProviderProjGroupItem::onDelete(const std::vector &) +{ + // we cannot delete the anchor view, thus check if the item is the front item + + bool isAnchor = false; + + // get the item and group + TechDraw::DrawProjGroupItem* dpgi = static_cast(getViewObject()); + TechDraw::DrawProjGroup* dpg = dpgi->getPGroup(); + // get the projection + TechDraw::DrawProjGroupItem* proj = getObject(); + // check if it is the anchor projection + if ((dpg != nullptr) && (dpg->hasProjection(proj->Type.getValueAsString())) + && (dpg->getAnchor() == dpgi)) + isAnchor = true; + + if (isAnchor) + { + // generate dialog + QString bodyMessage; + QTextStream bodyMessageStream(&bodyMessage); + bodyMessageStream << qApp->translate("Std_Delete", + "You cannot delete the anchor view of a projection group!"); + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, + QMessageBox::Ok); + // don't allow to delete + return false; + } + else { + return true; + } +} + +bool ViewProviderProjGroupItem::canDelete(App::DocumentObject *obj) const +{ + // deletions of objects from a ProjGroupItem don't necesarily destroy anything + // thus we can pass this action + // we can warn the user if necessary in the object's ViewProvider in the onDelete() function + Q_UNUSED(obj) + return true; +} + TechDraw::DrawProjGroupItem* ViewProviderProjGroupItem::getViewObject() const { return dynamic_cast(pcObject); diff --git a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h index 48e3091b0754..567ad92ae792 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h +++ b/src/Mod/TechDraw/Gui/ViewProviderProjGroupItem.h @@ -54,6 +54,8 @@ class TechDrawGuiExport ViewProviderProjGroupItem: public ViewProviderViewPart virtual TechDraw::DrawProjGroupItem* getViewObject() const; TechDraw::DrawProjGroupItem* getObject() const; void unsetEdit(int ModNum); + virtual bool onDelete(const std::vector &); + virtual bool canDelete(App::DocumentObject* obj) const; protected: bool setEdit(int ModNum); diff --git a/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp b/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp index 37cf514bfe69..d9ffe4c9ab75 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp @@ -24,6 +24,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +# include # ifdef FC_OS_WIN32 # include # endif @@ -47,6 +49,7 @@ #include #include +#include "DrawGuiUtil.h" #include "QGITemplate.h" #include "QGISVGTemplate.h" #include "QGVPage.h" @@ -182,6 +185,31 @@ void ViewProviderTemplate::setMarkers(bool state) } } +bool ViewProviderTemplate::onDelete(const std::vector &) +{ + // deleting the template will break the page view, thus warn the user + + // get the page + auto page = getTemplate()->getParentPage(); + + // generate dialog + QString bodyMessage; + QTextStream bodyMessageStream(&bodyMessage); + bodyMessageStream << qApp->translate("Std_Delete", + "The following referencing objects might break.\n\n" + "Are you sure you want to continue?\n"); + bodyMessageStream << '\n' << QString::fromUtf8(page->Label.getValue()); + + // show and evaluate dialog + int DialogResult = QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, + QMessageBox::Yes, QMessageBox::No); + if (DialogResult == QMessageBox::Yes) + return true; + else + return false; +} + MDIViewPage* ViewProviderTemplate::getMDIViewPage(void) const { MDIViewPage* myMdi = nullptr; diff --git a/src/Mod/TechDraw/Gui/ViewProviderTemplate.h b/src/Mod/TechDraw/Gui/ViewProviderTemplate.h index 8880c132b251..9fa993f4b5cf 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderTemplate.h +++ b/src/Mod/TechDraw/Gui/ViewProviderTemplate.h @@ -60,6 +60,7 @@ class TechDrawGuiExport ViewProviderTemplate : public Gui::ViewProviderDocumentO virtual Gui::MDIView *getMDIView() const override; void setMarkers(bool state); + virtual bool onDelete(const std::vector &); }; } // namespace TechDrawGui