#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)