for(; aRefIter != aRefs.end(); aRefIter++) {
std::shared_ptr<ModelAPI_CompositeFeature> aComposite =
std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aRefIter);
- if (aComposite.get()) {
+ if (aComposite.get() && aComposite->isSub(theFeature)) {
aComposite->removeFeature(theFeature);
}
}
#include <ModelAPI_AttributeDocRef.h>
#include <list>
#include <map>
+#include <iostream>
+
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
+
+//#define DEBUG_REMOVE_FEATURES
+
+#ifdef DEBUG_REMOVE_FEATURES
+void printMapInfo(const std::map<FeaturePtr, std::set<FeaturePtr> >& theMainList,
+ const std::string& thePrefix)
+{
+ std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = theMainList.begin(),
+ aMainLast = theMainList.end();
+ std::string anInfo;
+ for (; aMainIt != aMainLast; aMainIt++) {
+ FeaturePtr aMainListFeature = aMainIt->first;
+ std::set<FeaturePtr> aMainRefList = aMainIt->second;
+ std::set<FeaturePtr>::const_iterator anIt = aMainRefList.begin(), aLast = aMainRefList.end();
+ std::string aRefsInfo;
+ for (; anIt != aLast; anIt++) {
+ aRefsInfo += (*anIt)->name().c_str();
+ if (anIt != aLast)
+ aRefsInfo += ", ";
+ }
+ if (!aRefsInfo.empty()) {
+ anInfo = anInfo + aMainListFeature->name().c_str() + ": " + aRefsInfo + "\n";
+ }
+ }
+ std::cout << thePrefix.c_str() << ": " << anInfo.c_str() << std::endl;
+}
+
+void printListInfo(const std::set<FeaturePtr>& theMainList,
+ const std::string& thePrefix)
+{
+ std::set<FeaturePtr>::const_iterator aMainIt = theMainList.begin(),
+ aMainLast = theMainList.end();
+ std::string anInfo;
+ for (; aMainIt != aMainLast; aMainIt++) {
+ FeaturePtr aRefFeature = *aMainIt;
+ anInfo += aRefFeature->name().c_str();
+ if (aMainIt != aMainLast)
+ anInfo += ", ";
+ }
+ std::cout << thePrefix.c_str() << ": " << anInfo.c_str() << std::endl;
+}
+#endif
namespace ModelAPI_Tools {
}
}
+bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay,
+ const bool theUseComposite,
+ const bool theUseRecursion)
+{
+#ifdef DEBUG_REMOVE_FEATURES
+ printListInfo(theFeatures, "selection: ");
+#endif
+
+ std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+ ModelAPI_Tools::findAllReferences(theFeatures, aReferences, theUseComposite, theUseRecursion);
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(aReferences, "allDependencies: ");
+#endif
+
+ std::set<FeaturePtr> aFeaturesRefsTo;
+ ModelAPI_Tools::findRefsToFeatures(theFeatures, aReferences, aFeaturesRefsTo);
+#ifdef DEBUG_REMOVE_FEATURES
+ printListInfo(aFeaturesRefsTo, "references: ");
+#endif
+
+ std::set<FeaturePtr> aFeatures = theFeatures;
+ if (!aFeaturesRefsTo.empty())
+ aFeatures.insert(aFeaturesRefsTo.begin(), aFeaturesRefsTo.end());
+#ifdef DEBUG_REMOVE_FEATURES
+ printListInfo(aFeatures, "removeFeatures: ");
+#endif
+
+ return ModelAPI_Tools::removeFeatures(aFeatures, false);
+}
+
+bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay)
+{
+ bool isDone = false;
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (aFeature.get()) {
+ DocumentPtr aDoc = aFeature->document();
+ // flush REDISPLAY signal after remove feature
+ aDoc->removeFeature(aFeature);
+ isDone = true;
+ }
+ }
+ if (isDone && theFlushRedisplay) {
+ // the redisplay signal should be flushed in order to erase the feature presentation in the viewer
+ // if should be done after removeFeature() of document
+ Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
+ }
+ return true;
+}
+
+// Fills the references list by all references of the feature from the references map.
+// This is a recusive method to find references by next found feature in the map of references.
+// \param theFeature a feature to find references
+// \param theReferencesMap a map of references
+// \param theReferences an out container of references
+void addRefsToFeature(const FeaturePtr& theFeature,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferencesMap,
+ std::set<FeaturePtr>& theReferences)
+{
+ if (theReferencesMap.find(theFeature) == theReferencesMap.end())
+ return; // this feature is not in the selection list, so exists without references to it
+ std::set<FeaturePtr> aMainReferences = theReferencesMap.at(theFeature);
+
+ std::set<FeaturePtr>::const_iterator anIt = aMainReferences.begin(),
+ aLast = aMainReferences.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aRefFeature = *anIt;
+ if (theReferences.find(aRefFeature) == theReferences.end())
+ theReferences.insert(aRefFeature);
+ addRefsToFeature(aRefFeature, theReferencesMap, theReferences);
+ }
+}
+
+// For each feature from the feature list it searches references to the feature and append them
+// to the references map. This is a recusive method.
+// \param theFeature a feature to find references
+// \param theReferencesMap a map of references
+// \param theReferences an out container of references
+void findReferences(const std::set<FeaturePtr>& theFeatures,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ const bool theUseComposite, const bool theUseRecursion)
+{
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (aFeature.get() && theReferences.find(aFeature) == theReferences.end()) {
+ DocumentPtr aSelFeatureDoc = aFeature->document();
+ std::set<FeaturePtr> aSelRefFeatures;
+ aSelFeatureDoc->refsToFeature(aFeature, aSelRefFeatures, false/*do not emit signals*/);
+ if (theUseComposite) { // do not filter selection
+ theReferences[aFeature] = aSelRefFeatures;
+ }
+ else { // filter references to skip composition features of the current feature
+ std::set<FeaturePtr> aFilteredFeatures;
+ std::set<FeaturePtr>::const_iterator anIt = aSelRefFeatures.begin(),
+ aLast = aSelRefFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aCFeature = *anIt;
+ CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCFeature);
+ if (aComposite.get() && aComposite->isSub(aFeature))
+ continue; /// composite of the current feature should be skipped
+ aFilteredFeatures.insert(aCFeature);
+ }
+ theReferences[aFeature] = aFilteredFeatures;
+ }
+ if (theUseRecursion)
+ findReferences(aSelRefFeatures, theReferences, theUseComposite, theUseRecursion);
+ }
+ }
+}
+
+void findAllReferences(const std::set<FeaturePtr>& theFeatures,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ const bool theUseComposite,
+ const bool theUseRecursion)
+{
+ // For dependencies, find main_list:
+ // sk_1(ext_1, vertex_1)
+ // ext_1(bool_1, sk_3)
+ // vertex_1()
+ // sk_2(ext_2)
+ // ext_2(bool_2)
+ // sk_3()
+ // Information: bool_1 is not selected, ext_2(bool_2) exists
+ // find all referenced features
+ std::map<FeaturePtr, std::set<FeaturePtr> > aMainList;
+ findReferences(theFeatures, aMainList, theUseComposite, theUseRecursion);
+
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(aMainList, "firstDependencies");
+#endif
+ // find all dependencies for each object:
+ // sk_1(ext_1, vertex_1) + (sk_3, bool_1)
+ // ext_1(bool_1, sk_3)
+ // vertex_1()
+ // sk_2(ext_2) + (bool_1)
+ // ext_2(bool_1)
+ // sk_3()
+ std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = aMainList.begin(),
+ aMainLast = aMainList.end();
+ for (; aMainIt != aMainLast; aMainIt++) {
+ FeaturePtr aMainListFeature = aMainIt->first;
+ //std::string aName = aMainListFeature->name();
+ std::set<FeaturePtr> aMainRefList = aMainIt->second;
+ std::set<FeaturePtr> anAddRefFeatures;
+
+ std::set<FeaturePtr>::const_iterator anIt = aMainRefList.begin(),
+ aLast = aMainRefList.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ addRefsToFeature(aFeature, aMainList, aMainRefList);
+ }
+ theReferences[aMainListFeature] = aMainRefList;
+ }
+
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(theReferences, "allDependencies");
+#endif
+}
+
+void findRefsToFeatures(const std::set<FeaturePtr>& theFeatures,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ std::set<FeaturePtr>& theFeaturesRefsTo)
+{
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (theReferences.find(aFeature) == theReferences.end())
+ continue;
+ std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
+ std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
+ for (; aRefIt != aRefLast; aRefIt++) {
+ FeaturePtr aRefFeature = *aRefIt;
+ CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aRefFeature);
+ if (aComposite.get() && aComposite->isSub(aFeature))
+ continue; /// composite of the current feature should not be removed
+
+ if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
+ theFeaturesRefsTo.find(aRefFeature) == theFeaturesRefsTo.end()) // it is not added
+ theFeaturesRefsTo.insert(aRefFeature);
+ }
+ }
+}
+
} // namespace ModelAPI_Tools
#include <GeomAPI_Shape.h>
#include <vector>
+#include <map>
+#include <set>
namespace ModelAPI_Tools {
/// Returns shape from the given Result object
*/
MODELAPI_EXPORT void allResults(const FeaturePtr& theFeature, std::list<ResultPtr>& theResults);
+
+/*! Removes features from the document
+* \param theFeatures a list of features to be removed
+* \param theFlushRedisplay a boolean value if the redisplay signal should be flushed
+* \return true if at least one feature is removed
+*/
+MODELAPI_EXPORT bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay = false,
+ const bool theUseComposite = false,
+ const bool theUseRecursion = true);
+
+/*! Removes features from the document
+* \param theFeatures a list of features to be removed
+* \param theFlushRedisplay a boolean value if the redisplay signal should be flushed
+* \return true if at least one feature is removed
+*/
+MODELAPI_EXPORT bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
+ const bool theFlushRedisplay);
+
+/*! Build a map of references for the given set of features
+* \param theFeatures a list of features
+* \param theReferences a map of all references to the features
+* \param theUseComposite state if the composite features of the reference should be in the map
+* \param theUseRecursion state if references for features out of the sources feature
+ list are put into the result container. E.g. if theFeatures contains "Sketch_2", map will
+ contain references to this feature also.
+*/
+MODELAPI_EXPORT void findAllReferences(const std::set<FeaturePtr>& theFeatures,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ const bool theUseComposite = true,
+ const bool theUseRecursion = true);
+
+/*! In the map of references find all features referenced to the source feature
+* \param theFeatures a list of features to find references
+* \param theReferences a map of all references to the features
+* \param theFeaturesRefsTo an out list of referenced features
+*/
+MODELAPI_EXPORT void findRefsToFeatures(const std::set<FeaturePtr>& aFeatures,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& aReferences,
+ std::set<FeaturePtr>& aFeaturesRefsTo);
}
#endif
\r
/// Make some functionality after the objects are hidden in viewer\r
/// \param theObjects a list of hidden objects\r
- virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects) {};\r
+ //virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects) {};\r
\r
/// Returns true if selection for the object can be activate.\r
/// By default a result or feature of the current operation can not be activated\r
return aResult;
}
-void findReferences(const QObjectPtrList& theList,
- std::set<FeaturePtr>& aDirectRefFeatures,
- std::set<FeaturePtr>& aIndirectRefFeatures)
-{
- foreach (ObjectPtr aDeletedObj, theList) {
- std::set<FeaturePtr> alreadyProcessed;
- refsToFeatureInAllDocuments(aDeletedObj, aDeletedObj, theList, aDirectRefFeatures,
- aIndirectRefFeatures, alreadyProcessed);
- std::set<FeaturePtr> aDifference;
- std::set_difference(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end(),
- aDirectRefFeatures.begin(), aDirectRefFeatures.end(),
- std::inserter(aDifference, aDifference.begin()));
- aIndirectRefFeatures = aDifference;
- }
-}
-
-//**************************************************************
-void refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject, const ObjectPtr& theObject,
- const QObjectPtrList& theIgnoreList,
- std::set<FeaturePtr>& theDirectRefFeatures,
- std::set<FeaturePtr>& theIndirectRefFeatures,
- std::set<FeaturePtr>& theAlreadyProcessed)
-{
- refsDirectToFeatureInAllDocuments(theSourceObject, theObject, theIgnoreList, theDirectRefFeatures,
- theAlreadyProcessed);
-
- // Run recursion. It is possible recursive dependency, like the following: plane, extrusion uses plane,
- // axis is built on extrusion. Delete of a plane should check the dependency from the axis also.
- std::set<FeaturePtr>::const_iterator aFeatureIt = theDirectRefFeatures.begin();
- for (; aFeatureIt != theDirectRefFeatures.end(); ++aFeatureIt) {
- std::set<FeaturePtr> aRecursiveRefFeatures;
- refsToFeatureInAllDocuments(theSourceObject, *aFeatureIt, theIgnoreList,
- aRecursiveRefFeatures, aRecursiveRefFeatures, theAlreadyProcessed);
- theIndirectRefFeatures.insert(aRecursiveRefFeatures.begin(), aRecursiveRefFeatures.end());
- }
-
-}
-
-
-
-//**************************************************************
-void refsDirectToFeatureInAllDocuments(const ObjectPtr& theSourceObject, const ObjectPtr& theObject,
- const QObjectPtrList& theIgnoreList,
- std::set<FeaturePtr>& theDirectRefFeatures,
- std::set<FeaturePtr>& theAlreadyProcessed)
-{
- FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
- if (!aFeature.get())
- return;
- if (theAlreadyProcessed.find(aFeature) != theAlreadyProcessed.end())
- return;
- theAlreadyProcessed.insert(aFeature);
-
- //convert ignore object list to containt sub-features if the composite feature is in the list
- QObjectPtrList aFullIgnoreList;
- QObjectPtrList::const_iterator anIIt = theIgnoreList.begin(), anILast = theIgnoreList.end();
- for (; anIIt != anILast; anIIt++) {
- aFullIgnoreList.append(*anIIt);
- CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*anIIt);
- // if the current feature is aborted, the composite is removed and has invalid data
- if (aComposite.get() && aComposite->data()->isValid()) {
- int aNbSubs = aComposite->numberOfSubs();
- for (int aSub = 0; aSub < aNbSubs; aSub++) {
- aFullIgnoreList.append(aComposite->subFeature(aSub));
- }
- }
- }
-
- // 1. find references in the current document
- std::set<FeaturePtr> aRefFeatures;
- refsToFeatureInFeatureDocument(theObject, aRefFeatures);
- std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
- aLast = aRefFeatures.end();
- for (; anIt != aLast; anIt++) {
- // composite feature should not be deleted when the sub feature is to be deleted
- if (!isSubOfComposite(theSourceObject, *anIt) && !aFullIgnoreList.contains(*anIt))
- theDirectRefFeatures.insert(*anIt);
- }
-
- // 2. find references in all documents if the document of the feature is
- // "PartSet". Features of this document can be used in all other documents
- DocumentPtr aFeatureDoc = aFeature->document();
-
- SessionPtr aMgr = ModelAPI_Session::get();
- DocumentPtr aModuleDoc = aMgr->moduleDocument();
- if (aFeatureDoc == aModuleDoc) {
- // the feature and results of the feature should be found in references
- std::list<ObjectPtr> aObjects;
- aObjects.push_back(aFeature);
- typedef std::list<std::shared_ptr<ModelAPI_Result> > ResultsList;
- const ResultsList& aResults = aFeature->results();
- ResultsList::const_iterator aRIter = aResults.begin();
- for (; aRIter != aResults.cend(); aRIter++) {
- ResultPtr aRes = *aRIter;
- if (aRes.get())
- aObjects.push_back(aRes);
- }
- // get all opened documents; found features in the documents;
- // get a list of objects where a feature refers;
- // search in these objects the deleted objects.
- SessionPtr aMgr = ModelAPI_Session::get();
- std::list<DocumentPtr> anOpenedDocs = aMgr->allOpenedDocuments();
- std::list<DocumentPtr>::const_iterator anIt = anOpenedDocs.begin(),
- aLast = anOpenedDocs.end();
- std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
- for (; anIt != aLast; anIt++) {
- DocumentPtr aDocument = *anIt;
- if (aDocument == aFeatureDoc)
- continue; // this document has been already processed in 1.1
-
- int aFeaturesCount = aDocument->size(ModelAPI_Feature::group());
- for (int aId = 0; aId < aFeaturesCount; aId++) {
- ObjectPtr anObject = aDocument->object(ModelAPI_Feature::group(), aId);
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
- if (!aFeature.get())
- continue;
-
- aRefs.clear();
- aFeature->data()->referencesToObjects(aRefs);
- std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRef = aRefs.begin();
- bool aHasReferenceToObject = false;
- for(; aRef != aRefs.end() && !aHasReferenceToObject; aRef++) {
- std::list<ObjectPtr>::iterator aRefObj = aRef->second.begin();
- for(; aRefObj != aRef->second.end() && !aHasReferenceToObject; aRefObj++) {
- std::list<ObjectPtr>::const_iterator aObjIt = aObjects.begin();
- for(; aObjIt != aObjects.end() && !aHasReferenceToObject; aObjIt++) {
- aHasReferenceToObject = *aObjIt == *aRefObj;
- }
- }
- }
- if (aHasReferenceToObject && !isSubOfComposite(theSourceObject, aFeature) &&
- !theIgnoreList.contains(aFeature))
- theDirectRefFeatures.insert(aFeature);
- }
- }
- }
-}
-
//**************************************************************
void refsToFeatureInFeatureDocument(const ObjectPtr& theObject, std::set<FeaturePtr>& theRefFeatures)
{
return isSub;
}
+//**************************************************************
+bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
+{
+ bool isResult = false;
+
+ if (!theFeature->data()->isValid())
+ return isResult;
+
+ ResultPtr aFirstResult = theFeature->firstResult();
+ if (!aFirstResult.get())
+ return isResult;
+
+ return aFirstResult->groupName() == theGroupOfResult;
+}
//**************************************************************
-bool isDeleteFeatureWithReferences(const QObjectPtrList& theList,
- const std::set<FeaturePtr>& aDirectRefFeatures,
- const std::set<FeaturePtr>& aIndirectRefFeatures,
- QWidget* theParent,
- bool& doDeleteReferences)
-{
- doDeleteReferences = true;
-
- QString aDirectNames, aIndirectNames;
- if (!aDirectRefFeatures.empty()) {
- QStringList aDirectRefNames;
- foreach (const FeaturePtr& aFeature, aDirectRefFeatures)
- aDirectRefNames.append(aFeature->name().c_str());
- aDirectNames = aDirectRefNames.join(", ");
-
- QStringList aIndirectRefNames;
- foreach (const FeaturePtr& aFeature, aIndirectRefFeatures)
- aIndirectRefNames.append(aFeature->name().c_str());
- aIndirectNames = aIndirectRefNames.join(", ");
- }
-
- bool aCanReplaceParameters = !aDirectRefFeatures.empty();
- QStringList aPartFeatureNames;
- foreach (ObjectPtr aObj, theList) {
- FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
- // invalid feature data means that the feature is already removed in model,
- // we needn't process it. E.g. delete of feature from create operation. The operation abort
- // will delete the operation
- if (!aFeature->data()->isValid())
- continue;
- ResultPtr aFirstResult = aFeature->firstResult();
- if (!aFirstResult.get())
+bool askToDelete(const std::set<FeaturePtr> theFeatures,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ QWidget* theParent,
+ std::set<FeaturePtr>& theReferencesToDelete)
+{
+ std::set<FeaturePtr> aFeaturesRefsTo;
+ std::set<FeaturePtr> aFeaturesRefsToParameter;
+ std::set<FeaturePtr> aParameterFeatures;
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ // separate features to references to parameter features and references to others
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (theReferences.find(aFeature) == theReferences.end())
continue;
- std::string aResultGroupName = aFirstResult->groupName();
- if (aResultGroupName == ModelAPI_ResultPart::group())
- aPartFeatureNames.append(aFeature->name().c_str());
- if (aCanReplaceParameters && aResultGroupName != ModelAPI_ResultParameter::group())
- aCanReplaceParameters = false;
+ std::set<FeaturePtr> aRefFeatures;
+ std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
+ std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
+ for (; aRefIt != aRefLast; aRefIt++) {
+ FeaturePtr aRefFeature = *aRefIt;
+ if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
+ aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
+ aRefFeatures.insert(aRefFeature);
+ }
+
+ if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
+ aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
+ aParameterFeatures.insert(aFeature);
+ }
+ else {
+ theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
+ }
+ }
+
+ std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
+ anIt = aFeaturesRefsToParameter.begin();
+ aLast = aFeaturesRefsToParameter.end();
+ // separate features to references to parameter features and references to others
+ QStringList aParamFeatureNames;
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
+ aFeaturesRefsToParameterOnly.insert(aFeature);
+ aParamFeatureNames.append(aFeature->name().c_str());
+ }
+ }
+ aParamFeatureNames.sort();
+ QStringList aPartFeatureNames, anOtherFeatureNames;
+ anIt = theReferencesToDelete.begin();
+ aLast = theReferencesToDelete.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
+ aPartFeatureNames.append(aFeature->name().c_str());
+ else
+ anOtherFeatureNames.append(aFeature->name().c_str());
}
- QString aPartNames = aPartFeatureNames.join(", ");
+ aPartFeatureNames.sort();
+ anOtherFeatureNames.sort();
+
+ bool aCanReplaceParameters = !aFeaturesRefsToParameterOnly.empty();
QMessageBox aMessageBox(theParent);
aMessageBox.setWindowTitle(QObject::tr("Delete features"));
aMessageBox.setDefaultButton(QMessageBox::No);
QString aText;
- if (!aDirectNames.isEmpty() || !aIndirectNames.isEmpty()) {
- if (aCanReplaceParameters) {
- aText = QString(QObject::tr("Selected parameters are used in the following features: %1.\nThese features will be deleted.\nOr parameters could be replaced by their values.\n")
- .arg(aDirectNames));
- if (!aIndirectNames.isEmpty())
- aText += QString(QObject::tr("(Also these features will be deleted: %1)\n")).arg(aIndirectNames);
- QPushButton *aReplaceButton = aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
- } else {
- aText = QString(QObject::tr("Selected features are used in the following features: %1.\nThese features will be deleted.\n")).arg(aDirectNames);
- if (!aIndirectNames.isEmpty())
- aText += QString(QObject::tr("(Also these features will be deleted: %1)\n")).arg(aIndirectNames);
- }
+ QString aSep = ", ";
+ if (!aPartFeatureNames.empty())
+ aText += QString(QObject::tr("The following parts will be deleted: %1.\n")).arg(aPartFeatureNames.join(aSep));
+ if (!anOtherFeatureNames.empty())
+ aText += QString(QObject::tr("Selected features are used in the following features: %1.\nThese features will be deleted.\n"))
+ .arg(anOtherFeatureNames.join(aSep));
+ if (!aParamFeatureNames.empty()) {
+ aText += QString(QObject::tr("Selected parameters are used in the following features: %1.\nThese features will be deleted.\nOr parameters could be replaced by their values.\n"))
+ .arg(aParamFeatureNames.join(aSep));
+ QPushButton *aReplaceButton = aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
}
- if (!aPartNames.isEmpty())
- aText += QString(QObject::tr("The following parts will be deleted: %1.\n")).arg(aPartNames);
if (!aText.isEmpty()) {
aText += "Would you like to continue?";
return false;
if (aButtonRole == QMessageBox::ActionRole) {
- foreach (ObjectPtr aObj, theList)
+ foreach (FeaturePtr aObj, aParameterFeatures)
ModelAPI_ReplaceParameterMessage::send(aObj, 0);
- doDeleteReferences = false;
}
+ else
+ theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(), aFeaturesRefsToParameterOnly.end());
}
return true;
}
+//**************************************************************
+void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
+{
+ QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
+ for(; anIt != aLast; anIt++) {
+ ObjectPtr anObject = *anIt;
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+ // for parameter result, use the corresponded reature to be removed
+ if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
+ aFeature = ModelAPI_Feature::feature(anObject);
+ }
+ theFeatures.insert(aFeature);
+ }
+}
+
} // namespace ModuleBase_Tools
#include <QPixmap>
+#include <map>
+
class QWidget;
class QLayout;
class QDoubleSpinBox;
MODULEBASE_EXPORT QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
int theMaxLineInPixels = 150);
-//! Find all referenced features. Return direct and indirect lists of referenced object
-//! \param theList an objects to be checked
-//! \param aDirectRefFeatures a list of direct reference features
-//! \param aIndirectRefFeatures a list of features which depend on the feature through others
-MODULEBASE_EXPORT void findReferences(const QObjectPtrList& theList,
- std::set<FeaturePtr>& aDirectRefFeatures,
- std::set<FeaturePtr>& aIndirectRefFeatures);
-/*!
- Returns a container of references feature to the source object. The search happens in the object
- document and in other Part documents if the object belongs to the PartSet. The search is recursive,
- in other words it is applyed to set of the found objects until it is possible.
- It do not returns the referenced features to the object if this references is a composite feature
- which has the object as a sub object.
- \param theSourceObject an object, which references are searched
- \param theObject an intermediate recursive object, should be set in the source object
- \param theIgnoreList an ignore list, the found referernces which coincide with the objects are ignored
- \param theDirectRefFeatures direct references
- \param theIndirectRefFeatures indirect references. These are features that refers to the direct features
- \param theAlreadyProcessed set of processed elements, used for optimization (do not reanalyse processed)
- \return a boolean value
- */
-void MODULEBASE_EXPORT refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject,
- const ObjectPtr& theObject,
- const QObjectPtrList& theIgnoreList,
- std::set<FeaturePtr>& theDirectRefFeatures,
- std::set<FeaturePtr>& theIndirectRefFeatures,
- std::set<FeaturePtr>& theAlreadyProcessed);
-
-/*!
-*/
-void MODULEBASE_EXPORT refsDirectToFeatureInAllDocuments(const ObjectPtr& theSourceObject,
- const ObjectPtr& theObject,
- const QObjectPtrList& theIgnoreList,
- std::set<FeaturePtr>& theDirectRefFeatures,
- std::set<FeaturePtr>& theAlreadyProcessed);
-
/*!
Returns a container of referenced feature to the current object in the object document.
\param theObject an object, which will be casted to a feature type
bool MODULEBASE_EXPORT isSubOfComposite(const ObjectPtr& theObject);
-//! Shows a dialog box about references. Ask whether they should be also removed.
-//! \param theList an objects to be checked
-//! \param aDirectRefFeatures a list of direct reference features
-//! \param aIndirectRefFeatures a list of features which depend on the feature through others
-//! \param theParent a parent widget for the question message box
-//! \param doDeleteReferences if there are parameters between features, ask if they should be
-//! replaced to their meaning without corresponded features remove
-//! \return true if in message box answer is Yes
-bool MODULEBASE_EXPORT isDeleteFeatureWithReferences(const QObjectPtrList& theList,
- const std::set<FeaturePtr>& aDirectRefFeatures,
- const std::set<FeaturePtr>& aIndirectRefFeatures,
- QWidget* theParent,
- bool& doDeleteReferences);
+/*!
+* Shows a dialog box about references. Ask whether they should be also removed.
+* \param theFeatures a list of features
+* \param theReferences a map of all references to the features
+* \param theParent a parent widget for the question message box
+* \param theReferencesToDelete an out set for references features to be removed
+* \return true if in message box answer is Yes
+*/
+bool MODULEBASE_EXPORT askToDelete(const std::set<FeaturePtr> aFeatures,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ QWidget* theParent,
+ std::set<FeaturePtr>& theReferencesToDelete);
+
+/*!
+* Converts a list of objects to set of corresponded features. If object is result, it is ingored
+* because the feauture only might be removed. But if result is in a parameter group, the feature
+* of this parameter is to be removed
+* \param theObjects a list of objects
+* \param theFeatures an out conteiner of features
+*/
+void MODULEBASE_EXPORT convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures);
+
}
#endif
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
#include <ModuleBase_Tools.h>
QObjectPtrList anObjects;
anObjects.append(aCurFeature);
- std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
- ModuleBase_Tools::findReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures);
+ std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+ std::set<FeaturePtr> aFeatures;
+ ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
+ ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
- bool doDeleteReferences = true;
- if (ModuleBase_Tools::isDeleteFeatureWithReferences(anObjects, aDirectRefFeatures,
- aIndirectRefFeatures, this, doDeleteReferences)) {
-
- std::set<FeaturePtr> aFeaturesToDelete;
- if (doDeleteReferences) {
- aFeaturesToDelete = aDirectRefFeatures;
- aFeaturesToDelete.insert(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end());
- }
- aDoc->removeFeature(aCurFeature);
- std::set<FeaturePtr>::const_iterator anIt = aFeaturesToDelete.begin(),
- aLast = aFeaturesToDelete.end();
- for (; anIt != aLast; anIt++) {
- FeaturePtr aFeature = (*anIt);
- DocumentPtr aDoc = aFeature->document();
- aDoc->removeFeature(aFeature);
- }
+ std::set<FeaturePtr> aFeatureRefsToDelete;
+ if (ModuleBase_Tools::askToDelete(aFeatures, aReferences, this, aFeatureRefsToDelete)) {
+ if (!aFeatureRefsToDelete.empty())
+ aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
+ ModelAPI_Tools::removeFeatures(aFeatures, false);
Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
if (aFeature.get() != NULL) {
QObjectPtrList anObjects;
anObjects.append(aFeature);
- // the external feature should be removed with all references, sketch feature should be ignored
- std::set<FeaturePtr> anIgnoredFeatures;
- // the current feature should be ignored, because it can use the external feature in the
- // attributes and, therefore have a references to it. So, the delete functionality tries
- // to delete this feature. Test case is creation of a constraint on external point,
- // use in this control after an external point, the point of the sketch.
- anIgnoredFeatures.insert(theFeature);
- workshop(theWorkshop)->deleteFeatures(anObjects, anIgnoredFeatures);
+ // the external feature should be removed with all references, composite sketch feature will be ignored
+ workshop(theWorkshop)->deleteFeatures(anObjects);
}
}
}
return mySketchMgr->canDisplayObject(theObject);
}
-void PartSet_Module::processHiddenObject(const std::list<ObjectPtr>& theObjects)
+/*void PartSet_Module::processHiddenObject(const std::list<ObjectPtr>& theObjects)
{
mySketchMgr->processHiddenObject(theObjects);
-}
+}*/
bool PartSet_Module::canActivateSelection(const ObjectPtr& theObject) const
{
/// Make some functionality after the objects are hidden in viewer
/// \param theObjects a list of hidden objects
- virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects);
+ //virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects);
/// Returns true if selection for the object can be activate.
/// For sketch operation allow the selection activation if the operation is edit, for other
return aSwitchedOn;
}
-void PartSet_SketcherMgr::processHiddenObject(const std::list<ObjectPtr>& theObjects)
+/*void PartSet_SketcherMgr::processHiddenObject(const std::list<ObjectPtr>& theObjects)
{
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
(getCurrentOperation());
}
}
}
-}
+}*/
bool PartSet_SketcherMgr::canDisplayCurrentCreatedFeature() const
{
/// Check the given objects either there are some results of the current sketch. If so,
/// it suggests to delete them as there are no functionality to show back hidden sketch objects
/// \param theObjects a list of hidden objects
- virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects);
+ //virtual void processHiddenObject(const std::list<ObjectPtr>& theObjects);
/// Returns true if the mouse is over viewer or property panel value is changed
/// \return boolean result
anObjects.append(aSketchFeature);
XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
- aWorkshop->deleteFeatures(anObjects, std::set<FeaturePtr>());
+ aWorkshop->deleteFeatures(anObjects);
aMgr->finishOperation();
#endif
#include <ModelAPI_Events.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
+#include <ModelAPI_Tools.h>
#include <SketchPlugin_SketchEntity.h>
std::list<ObjectPtr>::iterator anInitIter = anInitialList.begin();
std::list<ObjectPtr>::iterator aTargetIter = aTargetList.begin();
std::vector<bool>::iterator aUsedIter = isUsed.begin();
+ std::set<FeaturePtr> aFeaturesToBeRemoved;
for (; aUsedIter != isUsed.end(); aUsedIter++) {
if (!(*aUsedIter)) {
aRefListOfShapes->remove(*anInitIter);
DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
FeaturePtr aFeature = aDoc ? aDoc->feature(aRC) : FeaturePtr();
if (aFeature)
- aDoc->removeFeature(aFeature);
+ aFeaturesToBeRemoved.insert(aFeature);
+ //aDoc->removeFeature(aFeature);
}
} else {
for (int i = 0; i <= aNbCopies && aTargetIter != aTargetList.end(); i++)
if (anInitIter != anInitialList.end())
anInitIter++;
}
+ ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
// change number of copies
if (aCurrentNbCopies != 0 && aNbCopies != aCurrentNbCopies) {
bool isAdd = aNbCopies > aCurrentNbCopies;
aTargetList = aRefListOfRotated->list();
aTargetIter = aTargetList.begin();
ObjectPtr anObjToCopy = *aTargetIter;
+ std::set<FeaturePtr> aFeaturesToBeRemoved;
while (aTargetIter != aTargetList.end()) {
aRefListOfRotated->remove(*aTargetIter);
aTargetIter++;
DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
FeaturePtr aFeature = aDoc ? aDoc->feature(aRC) : FeaturePtr();
if (aFeature)
- aDoc->removeFeature(aFeature);
+ aFeaturesToBeRemoved.insert(aFeature);
+ //aDoc->removeFeature(aFeature);
}
ind++;
}
anObjToCopy = *aTargetIter;
}
}
+ ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
for (aTargetIter = aTargetList.begin(); aTargetIter != aTargetList.end(); aTargetIter++)
aRefListOfRotated->append(*aTargetIter);
data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
std::list<ObjectPtr> aTargetList = aRefListOfRotated->list();
std::list<ObjectPtr>::iterator aTargetIter = aTargetList.begin();
+ std::set<FeaturePtr> aFeaturesToBeRemoved;
while (aTargetIter != aTargetList.end()) {
aTargetIter++;
for (int i = 0; i < aNbCopies && aTargetIter != aTargetList.end(); i++, aTargetIter++) {
DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
FeaturePtr aFeature = aDoc ? aDoc->feature(aRC) : FeaturePtr();
if (aFeature)
- aDoc->removeFeature(aFeature);
+ aFeaturesToBeRemoved.insert(aFeature);
+ //aDoc->removeFeature(aFeature);
}
}
+ ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
+
aRefListOfRotated->clear();
std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
data()->attribute(SketchPlugin_Constraint::ENTITY_A()))->clear();
#include <iterator>
-//#define DEBUG_CLEAN_HISTORY
-
#ifdef _DEBUG
#include <QDebug>
#include <iostream>
#include <dlfcn.h>
#endif
-
QString XGUI_Workshop::MOVE_TO_END_COMMAND = QObject::tr("Move to the end");
//#define DEBUG_DELETE
//#define DEBUG_FEATURE_NAME
+//#define DEBUG_CLEAN_HISTORY
XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
: QObject(),
myDisplayer->activateObjects(aModes, theList);
}
-
//**************************************************************
void XGUI_Workshop::deleteObjects()
{
ModuleBase_IModule* aModule = module();
- // 1. allow the module to delete objects, do nothing if it has succeed
+ // allow the module to delete objects, do nothing if it has succeed
if (aModule->deleteObjects()) {
updateCommandStatus();
return;
if (!(hasFeature || hasParameter))
return;
- // 3. delete objects
- std::set<FeaturePtr> anIgnoredFeatures;
- std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
- ModuleBase_Tools::findReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures);
-
- bool doDeleteReferences = true;
- if (ModuleBase_Tools::isDeleteFeatureWithReferences(anObjects, aDirectRefFeatures,
- aIndirectRefFeatures, desktop(), doDeleteReferences)) {
- // start operation
- QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text() + " %1";
- aDescription = aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
- ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module());
- operationMgr()->startOperation(anOpAction);
+ // delete objects
+ std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+ std::set<FeaturePtr> aFeatures;
+ ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
+ ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
+
+ bool aDone = false;
+ QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text() + " %1";
+ aDescription = aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
+ ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module());
+
+ operationMgr()->startOperation(anOpAction);
+ std::set<FeaturePtr> aFeatureRefsToDelete;
+ if (ModuleBase_Tools::askToDelete(aFeatures, aReferences, desktop(), aFeatureRefsToDelete)) {
// WORKAROUND, should be done before each object remove, if it presents in XGUI_DataModel tree
// It is necessary to clear selection in order to avoid selection changed event during
// deletion and negative consequences connected with processing of already deleted items
mySelector->clearSelection();
- // delete and commit/abort operation in model
- if (deleteFeaturesInternal(anObjects, aDirectRefFeatures, aIndirectRefFeatures,
- anIgnoredFeatures, doDeleteReferences))
- operationMgr()->commitOperation();
- else
- operationMgr()->abortOperation(operationMgr()->currentOperation());
+ if (!aFeatureRefsToDelete.empty())
+ aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
+ aDone = ModelAPI_Tools::removeFeatures(aFeatures, false);
}
+ if (aDone)
+ operationMgr()->commitOperation();
+ else
+ operationMgr()->abortOperation(operationMgr()->currentOperation());
}
//**************************************************************
}
}
-void printMapInfo(const std::map<FeaturePtr, std::set<FeaturePtr> >& theMainList,
- const QString& thePrefix)
-{
- std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = theMainList.begin(),
- aMainLast = theMainList.end();
- QStringList aMapInfo;
- for (; aMainIt != aMainLast; aMainIt++) {
- QStringList anInfo;
- FeaturePtr aMainListFeature = aMainIt->first;
- std::set<FeaturePtr> aMainRefList = aMainIt->second;
- foreach (FeaturePtr aRefFeature, aMainRefList) {
- anInfo.append(aRefFeature->name().c_str());
- }
- aMapInfo.append(QString("%1: %2\n").arg(aMainListFeature->name().c_str()).arg(anInfo.join(",")));
- }
- qDebug(QString("%1: %2\n%3").arg(thePrefix).arg(aMapInfo.size()).arg(aMapInfo.join("\n")).toStdString().c_str());
-}
-
//**************************************************************
void XGUI_Workshop::cleanHistory()
{
return;
QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
- QObjectPtrList aFeatures;
- foreach (ObjectPtr anObject, anObjects) {
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
- // for parameter result, use the corresponded reature to be removed
- if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
- aFeature = ModelAPI_Feature::feature(anObject);
- }
- aFeatures.append(aFeature);
- }
+ std::set<FeaturePtr> aFeatures;
+ ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
#ifdef DEBUG_CLEAN_HISTORY
- QObjectPtrList::const_iterator aFIt;
QStringList anInfo;
+ std::set<FeaturePtr>::const_iterator aFIt;
for (aFIt = aFeatures.begin(); aFIt != aFeatures.end(); ++aFIt) {
FeaturePtr aFeature = ModelAPI_Feature::feature(*aFIt);
anInfo.append(aFeature->name().c_str());
qDebug(QString("cleanHistory for: [%1] - %2").arg(aFeatures.size()).arg(anInfoStr).toStdString().c_str());
#endif
- // For dependencies, find main_list:
- // sk_1(ext_1, vertex_1)
- // ext_1(bool_1, sk_3)
- // vertex_1()
- // sk_2(ext_2)
- // ext_2(bool_2)
- // sk_3()
- // Information: bool_1 is not selected
- // find all referenced features
- std::map<FeaturePtr, std::set<FeaturePtr> > aMainList;
- foreach(ObjectPtr anObject, aFeatures) {
- FeaturePtr aSelFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
- /// composite ??? see refsDirectToFeatureInAllDocuments
- /// other documents ???
- if (aSelFeature.get()) {
- DocumentPtr aSelFeatureDoc = aSelFeature->document();
- std::set<FeaturePtr> aSelRefFeatures;
- // 1. find references in the current document
- aSelFeatureDoc->refsToFeature(aSelFeature, aSelRefFeatures, false/*do not emit signals*/);
- //if (aMainList.find(aSelFeature) != aMainList.end())
- aMainList[aSelFeature] = aSelRefFeatures;
- }
- }
-#ifdef DEBUG_CLEAN_HISTORY
- printMapInfo(aMainList, "firstDependencies");
-#endif
- // find all dependencies for each object:
- // sk_1(ext_1, vertex_1) + (sk_3, bool_1)
- // ext_1(bool_1, sk_3)
- // vertex_1()
- // sk_2(ext_2) + (bool_1)
- // ext_2(bool_1)
- // sk_3()
- std::map<FeaturePtr, std::set<FeaturePtr> > anExtendedMainList;
- std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = aMainList.begin(),
- aMainLast = aMainList.end();
- for (; aMainIt != aMainLast; aMainIt++) {
- FeaturePtr aMainListFeature = aMainIt->first;
- //std::string aName = aMainListFeature->name();
- std::set<FeaturePtr> aMainRefList = aMainIt->second;
- std::set<FeaturePtr> anAddRefFeatures;
- foreach (FeaturePtr aRefFeature, aMainRefList) {
- addRefsToFeature(aRefFeature, aMainList, aMainRefList);
- }
- anExtendedMainList[aMainListFeature] = aMainRefList;
- }
-
-#ifdef DEBUG_CLEAN_HISTORY
- printMapInfo(anExtendedMainList, "allDependencies");
-#endif
+ std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+ ModelAPI_Tools::findAllReferences(aFeatures, aReferences, true, false);
// find for each object whether all reference values are in the map as key, that means that there is
// no other reference in the model to this object, so it might be removed by cleaning history
// sk_1(ext_1, vertex_1) + (sk_3, bool_1) - cann't be deleted, dependency to bool_1
// ext_2(bool_1) - cann't be deleted, dependency to bool_1
// sk_3()
// Information: bool_1 is not selected
- QList<ObjectPtr> anUnusedObjects;
- aMainIt = anExtendedMainList.begin(), aMainLast = anExtendedMainList.end();
+ std::set<FeaturePtr> anUnusedObjects;
+ std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = aReferences.begin(),
+ aMainLast = aReferences.end();
for (; aMainIt != aMainLast; aMainIt++) {
FeaturePtr aMainListFeature = aMainIt->first;
std::set<FeaturePtr> aMainRefList = aMainIt->second;
bool aFeatureOutOfTheList = false;
for (; aRefIt != aRefLast && !aFeatureOutOfTheList; aRefIt++) {
FeaturePtr aRefFeature = *aRefIt;
- aFeatureOutOfTheList = anExtendedMainList.find(aRefFeature) == anExtendedMainList.end();
+ aFeatureOutOfTheList = aReferences.find(aRefFeature) == aReferences.end();
}
if (!aFeatureOutOfTheList)
- anUnusedObjects.append(aMainListFeature);
+ anUnusedObjects.insert(aMainListFeature);
}
#ifdef DEBUG_CLEAN_HISTORY
anInfo.clear();
for (aFIt = anUnusedObjects.begin(); aFIt != anUnusedObjects.end(); ++aFIt) {
- FeaturePtr aFeature = ModelAPI_Feature::feature(*aFIt);
+ FeaturePtr aFeature = *aFIt;
anInfo.append(aFeature->name().c_str());
}
qDebug(QString("unused objects: [%1] - %2").arg(anInfo.size()).arg(anInfo.join(";\t")).toStdString().c_str());
// warn about the references remove, break the delete operation if the user chose it
if (!anUnusedObjects.empty()) {
QStringList aNames;
- foreach (const ObjectPtr& anObject, anUnusedObjects) {
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+ foreach (const FeaturePtr& aFeature, anUnusedObjects) {
aNames.append(aFeature->name().c_str());
}
+ aNames.sort();
QString anUnusedNames = aNames.join(", ");
QString anActionId = "CLEAN_HISTORY_CMD";
mySelector->clearSelection();
std::set<FeaturePtr> anIgnoredFeatures;
- if (removeFeatures(anUnusedObjects, anIgnoredFeatures, anActionId, true)) {
+ if (ModelAPI_Tools::removeFeatures(anUnusedObjects, true)) {
operationMgr()->commitOperation();
}
else {
}
//**************************************************************
-bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theFeatures,
- const std::set<FeaturePtr>& theIgnoredFeatures)
-{
- std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
- ModuleBase_Tools::findReferences(theFeatures, aDirectRefFeatures, aIndirectRefFeatures);
- return deleteFeaturesInternal(theFeatures, aDirectRefFeatures, aIndirectRefFeatures,
- theIgnoredFeatures);
-}
-
-bool XGUI_Workshop::deleteFeaturesInternal(const QObjectPtrList& theList,
- const std::set<FeaturePtr>& aDirectRefFeatures,
- const std::set<FeaturePtr>& aIndirectRefFeatures,
- const std::set<FeaturePtr>& theIgnoredFeatures,
- const bool doDeleteReferences)
-{
- bool isDone = false;
- if (doDeleteReferences) {
- std::set<FeaturePtr> aFeaturesToDelete = aDirectRefFeatures;
- aFeaturesToDelete.insert(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end());
- std::set<FeaturePtr>::const_iterator anIt = aFeaturesToDelete.begin(),
- aLast = aFeaturesToDelete.end();
-#ifdef DEBUG_DELETE
- QStringList anInfo;
-#endif
- for (; anIt != aLast; anIt++) {
- FeaturePtr aFeature = (*anIt);
- DocumentPtr aDoc = aFeature->document();
- if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) {
- // flush REDISPLAY signal after remove feature
- aDoc->removeFeature(aFeature);
- isDone = true;
-#ifdef DEBUG_DELETE
- anInfo.append(ModuleBase_Tools::objectInfo(aFeature).toStdString().c_str());
-#endif
- }
- }
-#ifdef DEBUG_DELETE
- qDebug(QString("remove references:%1").arg(anInfo.join("; ")).toStdString().c_str());
- anInfo.clear();
-#endif
- }
-
- QString anActionId = "DELETE_CMD";
- isDone = removeFeatures(theList, theIgnoredFeatures, anActionId, false) || isDone;
-
- if (isDone) {
- // the redisplay signal should be flushed in order to erase the feature presentation in the viewer
- // if should be done after removeFeature() of document
- Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
- }
- return isDone;
-}
-
-//**************************************************************
-bool XGUI_Workshop::removeFeatures(const QObjectPtrList& theList,
- const std::set<FeaturePtr>& theIgnoredFeatures,
- const QString& theActionId,
- const bool theFlushRedisplay)
+bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theObjects)
{
- bool isDone = false;
-
- QString anId = QString::fromStdString(theActionId.toStdString().c_str());
- QStringList anObjectGroups = contextMenuMgr()->actionObjectGroups(anId);
- // 4. remove the parameter features
- foreach (ObjectPtr aObj, theList) {
- // features and parameters can be removed here,
- // the results are removed only by a corresponded feature remove
- std::string aGroupName = aObj->groupName();
- if (!anObjectGroups.contains(aGroupName.c_str()))
- continue;
-
- FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
- if (aFeature) {
- /*// 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
- QString anInfoStr = ModuleBase_Tools::objectInfo(aFeature);
- anInfo.append(anInfoStr);
- qDebug(QString("remove feature :%1").arg(anInfoStr).toStdString().c_str());
-#endif
- // flush REDISPLAY signal after remove feature
- aDoc->removeFeature(aFeature);
- isDone = true;
- }
- }
- }
- if (isDone && theFlushRedisplay) {
- // the redisplay signal should be flushed in order to erase the feature presentation in the viewer
- // if should be done after removeFeature() of document
- Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
- }
+ std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
+ std::set<FeaturePtr> aFeatures;
+ ModuleBase_Tools::convertToFeatures(theObjects, aFeatures);
-#ifdef DEBUG_DELETE
- qDebug(QString("remove features:%1").arg(anInfo.join("; ")).toStdString().c_str());
-#endif
- return true;
+ return ModelAPI_Tools::removeFeaturesAndReferences(aFeatures);
}
bool hasResults(QObjectPtrList theObjects, const std::set<std::string>& theTypes)
//! Delete features. Delete the referenced features. There can be a question with a list of
//! referenced objects.
//! \param theFeatures a list of objects to be deleted
- //! \param theIgnoredFeatures a list of features to be ignored during delete
- bool deleteFeatures(const QObjectPtrList& theFeatures,
- const std::set<FeaturePtr>& theIgnoredFeatures = std::set<FeaturePtr>());
+ bool deleteFeatures(const QObjectPtrList& theFeatures);
/// Deactivates the object, if it is active and the module returns that the activation
/// of selection for the object is not possible currently(the current operation uses it)
/// \param theOperation an operation
void setGrantedFeatures(ModuleBase_Operation* theOperation);
- //! \param theIgnoredFeatures a list of features to be ignored during delete
- //! \param theList an objects to be checked
- //! \param aDirectRefFeatures a list of direct reference features
- //! \param aIndirectRefFeatures a list of features which depend on the feature through others
- //! \param doDeleteReferences flag if referenced features should be removed also
- bool deleteFeaturesInternal(const QObjectPtrList& theList,
- const std::set<FeaturePtr>& aDirectRefFeatures,
- const std::set<FeaturePtr>& aIndirectRefFeatures,
- const std::set<FeaturePtr>& theIgnoredFeatures,
- const bool doDeleteReferences = true);
-
private:
/// Display all results
//void displayAllResults();
//! \param theSlot - onUndo(int) or onRedo(int) SLOT
void addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot);
-
- /// Calls removeFeature of the document for each object in the list
- //! \param theList an objects to be deleted
- //! \param theIgnoredFeatures a list of features to be ignored during delete
- //! \param theActionId an action command key to find context menu object types enabled for remove
- //! \param theFlushRedisplay a boolean value if the redisplay signal should be flushed
- bool removeFeatures(const QObjectPtrList& theList,
- const std::set<FeaturePtr>& theIgnoredFeatures,
- const QString& theActionId,
- const bool theFlushRedisplay);
-
//! Creates list of actions (commands) by given history list from session
QList<ActionInfo> processHistoryList(const std::list<std::string>&) const;