From 83f8eddb963d9c5ad4da7bb7bf7b555df660559f Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 15 Jul 2015 07:35:50 +0300 Subject: [PATCH] #748 - move part problem --- src/ModuleBase/ModuleBase_IModule.h | 6 +++ src/PartSet/PartSet_Module.cpp | 14 ++++++ src/PartSet/PartSet_Module.h | 6 +++ src/XGUI/XGUI_Workshop.cpp | 70 ++++++++++++++++++++--------- 4 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index d6bd6e9af..ae8e4645f 100644 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -120,6 +120,12 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject //! Returns True if there are available Redos and there is not an active operation virtual bool canRedo() const; + /// Returnas true if the action can be applyed to the object + /// \param theObject a checked object + /// \param theActionId an identifier of action, to be found in the menu manager like "DELETE_CMD" + /// \return the a booean result + virtual bool canApplyAction(const ObjectPtr& theObject, const QString& theActionId) const = 0; + /// Returns True if the current operation can be committed. By default it is true. /// \return a boolean value virtual bool canCommitOperation() const; diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 8bde3e6f8..0d493f7f2 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -331,6 +331,20 @@ bool PartSet_Module::canRedo() const return aCanRedo; } +bool PartSet_Module::canApplyAction(const ObjectPtr& theObject, const QString& theActionId) const +{ + bool aValid = true; + if (theActionId == "DELETE_CMD" || theActionId == "MOVE_CMD") { + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + if (aFeature) { + // part features are removed in the PartSet module only. + if (aFeature->getKind() == PartSetPlugin_Part::ID()) + aValid = false; + } + } + return aValid; +} + bool PartSet_Module::canCommitOperation() const { return mySketchMgr->canCommitOperation(); diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index f97713ce7..a17c85599 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -100,6 +100,12 @@ public: /// \return the boolean result virtual bool canRedo() const; + /// Returnas true if the action can be applyed to the object + /// \param theObject a checked object + /// \param theActionId an identifier of action, to be found in the menu manager like "DELETE_CMD" + /// \return the a booean result + virtual bool canApplyAction(const ObjectPtr& theObject, const QString& theActionId) const; + /// Returns True if the current operation can be committed. Asks the sketch manager. /// \return a boolean value virtual bool canCommitOperation() const; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 92c158662..8aa17ceb6 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1077,15 +1077,19 @@ void XGUI_Workshop::moveObjects() SessionPtr aMgr = ModelAPI_Session::get(); - QString aDescription = contextMenuMgr()->action("MOVE_CMD")->text(); + QString anActionId = "MOVE_CMD"; + QString aDescription = contextMenuMgr()->action(anActionId)->text(); aMgr->startOperation(aDescription.toStdString()); QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); DocumentPtr anActiveDocument = aMgr->activeDocument(); FeaturePtr aCurrentFeature = anActiveDocument->currentFeature(true); - foreach (ObjectPtr aObj, anObjects) { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); + foreach (ObjectPtr aObject, anObjects) { + if (!myModule->canApplyAction(aObject, anActionId)) + continue; + + FeaturePtr aFeature = std::dynamic_pointer_cast(aObject); if (aFeature.get()) { anActiveDocument->moveFeature(aFeature, aCurrentFeature); aCurrentFeature = anActiveDocument->currentFeature(true); @@ -1155,7 +1159,8 @@ These features will be deleted also. Would you like to continue?")).arg(aNames), anInfo.clear(); #endif - QString anId = QString::fromStdString("DELETE_CMD"); + QString anActionId = "DELETE_CMD"; + QString anId = QString::fromStdString(anActionId.toStdString().c_str()); QStringList anObjectGroups = contextMenuMgr()->actionObjectGroups(anId); // 4. remove the parameter features foreach (ObjectPtr aObj, theList) { @@ -1165,13 +1170,16 @@ These features will be deleted also. Would you like to continue?")).arg(aNames), if (!anObjectGroups.contains(aGroupName.c_str())) continue; + if (!myModule->canApplyAction(aObj, anActionId)) + continue; + FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); if (aFeature) { - // TODO: to learn the workshop to delegate the Part object deletion to the PartSet module + /*// TODO: to learn the workshop to delegate the Part object deletion to the PartSet module // part features are removed in the PartSet module. This condition should be moved there if (aFeature->getKind() == "Part") continue; - + */ DocumentPtr aDoc = aObj->document(); if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) { #ifdef DEBUG_DELETE @@ -1233,30 +1241,48 @@ std::list toCurrentFeatures(const ObjectPtr& theObject) bool XGUI_Workshop::canMoveFeature() { + QString anActionId = "MOVE_CMD"; + QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + QObjectPtrList aValidatedObjects; foreach (ObjectPtr aObject, aObjects) { + if (myModule->canApplyAction(aObject, anActionId)) + aValidatedObjects.append(aObject); + } + if (aValidatedObjects.size() != aObjects.size()) + aObjects = aValidatedObjects; + + bool aCanMove = !aObjects.empty(); + + QObjectPtrList::const_iterator anIt = aObjects.begin(), aLast = aObjects.end(); + for (; anIt != aLast && aCanMove; anIt++) { + ObjectPtr aObject = *anIt; // 1. Get features placed between selected and current in the document std::list aFeaturesBetween = toCurrentFeatures(aObject); // if aFeaturesBetween is empty it means wrong order or aObject is the current feature if (aFeaturesBetween.empty()) - return false; - std::set aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end()); - // 2. Get all reference features to the selected object in the document - std::set aRefFeatures; - XGUI_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures); + aCanMove = false; + else { + std::set aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end()); + // 2. Get all reference features to the selected object in the document + std::set aRefFeatures; + XGUI_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures); - if (aRefFeatures.empty()) - continue; - // 3. Find any placed features in all reference features - std::set aIntersectionFeatures; - std::set_intersection(aRefFeatures.begin(), aRefFeatures.end(), - aPlacedFeatures.begin(), aPlacedFeatures.end(), - std::inserter(aIntersectionFeatures, aIntersectionFeatures.begin())); - // 4. Return false if any reference feature is placed before curent feature - if (!aIntersectionFeatures.empty()) - return false; + if (aRefFeatures.empty()) + continue; + else { + // 3. Find any placed features in all reference features + std::set aIntersectionFeatures; + std::set_intersection(aRefFeatures.begin(), aRefFeatures.end(), + aPlacedFeatures.begin(), aPlacedFeatures.end(), + std::inserter(aIntersectionFeatures, aIntersectionFeatures.begin())); + // 4. Return false if any reference feature is placed before curent feature + if (!aIntersectionFeatures.empty()) + aCanMove = false; + } + } } - return true; + return aCanMove; } //************************************************************** -- 2.39.2