From 5a383f4433a8bf1c02b40b3f48ff303d6a1f3bf0 Mon Sep 17 00:00:00 2001 From: Sergo Date: Wed, 21 Sep 2016 01:44:34 -0400 Subject: [PATCH] PartDesign: fix Datum editing, showing/hiding objects --- src/Mod/PartDesign/Gui/ReferenceSelection.cpp | 11 ++++ src/Mod/PartDesign/Gui/ReferenceSelection.h | 17 ++++++ .../PartDesign/Gui/TaskDatumParameters.cpp | 58 +++++++++++++++++-- src/Mod/PartDesign/Gui/TaskDatumParameters.h | 3 +- src/Mod/PartDesign/Gui/ViewProviderDatum.cpp | 38 +++++------- 5 files changed, 97 insertions(+), 30 deletions(-) diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp index cbb33e5906..03131054ff 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp @@ -169,6 +169,17 @@ bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, c return false; } +bool NoDependentsSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName) +{ + if (support && !support->testIfLinkDAGCompatible(pObj)) { + this->notAllowedReason = QT_TR_NOOP("Selecting this will cause circular dependency."); + return false; + } + + return refSelection.allow(pDoc, pObj, sSubName); +} + + namespace PartDesignGui { diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.h b/src/Mod/PartDesign/Gui/ReferenceSelection.h index 954303451f..acb39dfb24 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.h +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.h @@ -54,6 +54,23 @@ public: bool allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName); }; +class NoDependentsSelection : public Gui::SelectionFilterGate +{ + ReferenceSelection refSelection; + const App::DocumentObject* support; + +public: + NoDependentsSelection(const App::DocumentObject* support_, + const bool edge_, const bool plane_, const bool planar_, const bool point_ = false) + : Gui::SelectionFilterGate((Gui::SelectionFilter*)0), refSelection(support_, edge_, plane_, planar_, point_), support(support_) + { + } + /** + * Allow the user to pick only objects wich are not in objs getDependencyList + */ + bool allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName); +}; + // Convenience methods /// Extract reference from Selection void getReferencedSelection(const App::DocumentObject* thisObj, const Gui::SelectionChanges& msg, diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp index 047d23d943..bc6fcf46c5 100644 --- a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp @@ -34,6 +34,7 @@ #endif #include +#include #include #include #include @@ -50,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -202,6 +202,7 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p ui->superplacementX->bind(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Base.x"))); ui->superplacementY->bind(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Base.y"))); ui->superplacementZ->bind(App::ObjectIdentifier::parse(pcDatum,std::string("superPlacement.Base.z"))); + visibilityAutomation(true); updateSuperplacementUI(); updateReferencesUI(); updateListOfModes(eMapMode(pcDatum->MapMode.getValue())); @@ -222,6 +223,8 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p DatumView->setPickable(false); + Gui::Selection().addSelectionGate(new NoDependentsSelection(DatumView->getObject(), true, true, true)); + // connect object deletion with slot auto bnd = boost::bind(&TaskDatumParameters::objectDeleted, this, _1); Gui::Document* document = Gui::Application::Instance->getDocument(DatumView->getObject()->getDocument()); @@ -230,6 +233,9 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p TaskDatumParameters::~TaskDatumParameters() { + visibilityAutomation(false); + Gui::Selection().rmvSelectionGate(); + connectDelObject.disconnect(); if (DatumView) resetViewMode(); @@ -358,6 +364,7 @@ void TaskDatumParameters::onSelectionChanged(const Gui::SelectionChanges& msg) std::vector refnames = pcDatum->Support.getSubValues(); App::DocumentObject* selObj = pcDatum->getDocument()->getObject(msg.pObjectName); if (selObj == pcDatum) return;//prevent self-referencing + std::string subname = msg.pSubName; // Remove subname for planes and datum features @@ -840,7 +847,7 @@ void TaskDatumParameters::onRefName4(const QString &text) } -bool TaskDatumParameters::getFlip() const +bool TaskDatumParameters::getFlip() const { return ui->checkBoxFlip->isChecked(); } @@ -881,6 +888,50 @@ void TaskDatumParameters::changeEvent(QEvent *e) } } +void TaskDatumParameters::visibilityAutomation(bool opening_not_closing) +{ + if (opening_not_closing){ + //crash guards + if (!DatumView) + return; + if (!DatumView->getObject()) + return; + if (!DatumView->getObject()->getNameInDocument()) + return; + try{ + QString code = QString::fromLatin1( + "import TempoVis\n" + "from Show.DepGraphTools import getAllDependent, isContainer\n" + "tv = TempoVis.TempoVis(App.ActiveDocument)\n" + "dep_features = [o for o in getAllDependent(%1) if not isContainer(o)]\n" + "if %1.isDerivedFrom('PartDesign::CoordinateSystem'):\n" + "\tvisible_features = [feat for feat in %1.InList if feat.isDerivedFrom('PartDesign::FeaturePrimitive')]\n" + "\tdep_features = [feat for feat in dep_features if feat not in visible_features]\n" + "tv.hide(dep_features)\n" + "if not %1.isDerivedFrom('PartDesign::CoordinateSystem'):\n" + "\t\tif len(%1.Support) > 0:\n" + "\t\t\ttv.show([lnk[0] for lnk in %1.Support])" + ); + QByteArray code_2 = code.arg( + QString::fromLatin1("App.ActiveDocument.") + + QString::fromLatin1(DatumView->getObject()->getNameInDocument()) + ).toLatin1(); + Base::Interpreter().runString(code_2.constData()); + } + catch (Base::PyException &e){ + e.ReportException(); + } + } + else { + try { + Base::Interpreter().runString("del(tv)"); + } + catch (Base::PyException &e) { + e.ReportException(); + } + } +} + //************************************************************************** //************************************************************************** // TaskDialog @@ -998,7 +1049,7 @@ bool TaskDlgDatumParameters::accept() Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); if (!DatumView->getObject()->isValid()) throw Base::Exception(DatumView->getObject()->getStatusString()); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()"); Gui::Command::commitCommand(); //we need to add the copied features to the body after the command action, as otherwise freecad crashs unexplainable @@ -1023,7 +1074,6 @@ bool TaskDlgDatumParameters::reject() Gui::Command::abortCommand(); Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - return true; } diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.h b/src/Mod/PartDesign/Gui/TaskDatumParameters.h index 5bfcfecce4..8e78788c51 100644 --- a/src/Mod/PartDesign/Gui/TaskDatumParameters.h +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.h @@ -83,6 +83,7 @@ private Q_SLOTS: void onButtonRef3(const bool checked = true); void onButtonRef4(const bool checked = true); void onModeSelect(void); + void visibilityAutomation(bool opening_not_closing); protected: void changeEvent(QEvent *e); @@ -90,7 +91,7 @@ protected: private: void resetViewMode(); void objectDeleted(const Gui::ViewProviderDocumentObject&); - void onSelectionChanged(const Gui::SelectionChanges& msg); + void onSelectionChanged(const Gui::SelectionChanges& msg) override; void updateReferencesUI(); /** diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp index ffc2195973..29681fb542 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp @@ -254,7 +254,6 @@ bool ViewProviderDatum::setEdit(int ModNum) // clear the selection (convenience) Gui::Selection().clearSelection(); - // always change to PartDesign WB, remember where we come from oldWb = Gui::Command::assureWorkbench("PartDesignWorkbench"); // start the edit dialog @@ -275,22 +274,21 @@ bool ViewProviderDatum::doubleClicked(void) std::string Msg("Edit "); Msg += this->pcObject->Label.getValue(); Gui::Command::openCommand(Msg.c_str()); + + Part::Datum* pcDatum = static_cast(getObject()); PartDesign::Body* activeBody = getActiveView()->getActiveObject(PDBODYKEY); - // TODO check if this feature belongs to the active body - // and if not set the body it belongs to as active (2015-09-08, Fat-Zer) - if (activeBody != NULL) { - // TODO Rewrite this (2015-09-08, Fat-Zer) - // Drop into insert mode so that the user doesn't see all the geometry that comes later in the tree - // Also, this way the user won't be tempted to use future geometry as external references for the sketch - oldTip = activeBody->Tip.getValue(); - if (oldTip != this->pcObject) - Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); - else - oldTip = NULL; - } else { - oldTip = NULL; + auto datumBody = PartDesignGui::getBodyFor(pcDatum, false); + + if (datumBody != NULL) { + if (datumBody != activeBody) { + Gui::Command::doCommand(Gui::Command::Gui, + "Gui.getDocument('%s').ActiveView.setActiveObject('%s', App.getDocument('%s').getObject('%s'))", + datumBody->getDocument()->getName(), + PDBODYKEY, + datumBody->getDocument()->getName(), + datumBody->getNameInDocument()); + } } - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s',0)",this->pcObject->getNameInDocument()); return true; } @@ -303,16 +301,6 @@ void ViewProviderDatum::unsetEdit(int ModNum) if (ModNum == ViewProvider::Default) { // when pressing ESC make sure to close the dialog Gui::Control().closeDialog(); - PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); - - if ((activeBody != NULL) && (oldTip != NULL)) { - Gui::Selection().clearSelection(); - Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument()); - Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); - oldTip = NULL; - } else { - oldTip = NULL; - } } else { Gui::ViewProviderGeometryObject::unsetEdit(ModNum);