From ba8119ee40e4a1f84df10304dd420d0b9c0a9527 Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 1 Apr 2015 10:29:05 +0300 Subject: [PATCH] External edge to be removed with all references. The same mechanizm should be applied like one used by the delete operation from the popup menu. --- src/PartSet/PartSet_Module.cpp | 85 ++------------- src/PartSet/PartSet_WidgetShapeSelector.cpp | 19 +++- src/PartSet/PartSet_WidgetShapeSelector.h | 3 +- src/XGUI/XGUI_Workshop.cpp | 114 +++++++++++--------- src/XGUI/XGUI_Workshop.h | 15 ++- 5 files changed, 110 insertions(+), 126 deletions(-) diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 0fb009497..841387209 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -537,23 +537,20 @@ void PartSet_Module::onAction(bool isChecked) bool PartSet_Module::deleteObjects() { + // 1. check whether the delete should be processed in the module ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); bool isSketchOp = PartSet_SketcherMgr::isSketchOperation(anOperation), isNestedOp = PartSet_SketcherMgr::isNestedSketchOperation(anOperation); if (!isSketchOp && !isNestedOp) return false; - // sketch feature should be skipped, only sub-features can be removed - // when sketch operation is active - CompositeFeaturePtr aSketch = mySketchMgr->activeSketch(); - + // 2. find selected presentations // selected objects should be collected before the current operation abort because // the abort leads to selection lost on constraint objects. It can be corrected after #386 issue XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); XGUI_Workshop* aWorkshop = aConnector->workshop(); ModuleBase_ISelection* aSel = aConnector->selection(); QObjectPtrList aSelectedObj = aSel->selectedPresentations(); - // if there are no selected objects in the viewer, that means that the selection in another // place cased this method. It is necessary to return the false value to understande in above // method that delete is not processed @@ -564,80 +561,20 @@ bool PartSet_Module::deleteObjects() if (isNestedOp) anOperation->abort(); - std::set aRefFeatures; - foreach (ObjectPtr aObj, aSelectedObj) - { - //ResultPartPtr aPart = std::dynamic_pointer_cast(aObj); - //if (aPart) { - // TODO: check for what there is this condition. It is placed here historicaly because - // ther is this condition during remove features. - //} else { - FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); - if (aFeature.get() != NULL) { - aObj->document()->refsToFeature(aFeature, aRefFeatures, false); - } - //} - } - + // 3. start operation QString aDescription = aWorkshop->contextMenuMgr()->action("DELETE_CMD")->text(); - /** - // according to #355 feature, it is not necessary to inform about dependencies during - // sketch delete operation - // - if (!aRefFeatures.empty()) { - QStringList aRefNames; - std::set::const_iterator anIt = aRefFeatures.begin(), - aLast = aRefFeatures.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = (*anIt); - if (aFeature == aSketch) - continue; - aRefNames.append((*anIt)->name().c_str()); - } - if (!aRefNames.empty()) { - QString aNames = aRefNames.join(", "); - aDescription += aNames.prepend(" "); - - QMainWindow* aDesktop = aWorkshop->desktop(); - QMessageBox::StandardButton aRes = QMessageBox::warning( - aDesktop, tr("Delete features"), - QString(tr("Selected features are used in the following features: %1.\ - These features will be deleted also. Would you like to continue?")).arg(aNames), - QMessageBox::No | QMessageBox::Yes, QMessageBox::No); - if (aRes != QMessageBox::Yes) - return; - } - }*/ - SessionPtr aMgr = ModelAPI_Session::get(); aMgr->startOperation(aDescription.toStdString()); - std::set::const_iterator anIt = aRefFeatures.begin(), - aLast = aRefFeatures.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aRefFeature = (*anIt); - if (aRefFeature == aSketch) - continue; - aRefFeature->document()->removeFeature(aRefFeature); - } - foreach (ObjectPtr aObj, aSelectedObj) - { - DocumentPtr aDoc = aObj->document(); - //ResultPartPtr aPart = std::dynamic_pointer_cast(aObj); - //if (aPart) { - // if (aDoc == aMgr->activeDocument()) { - // aDoc->close(); - // } - //} else { - //FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); - if (aFeature.get() != NULL) { - aDoc->removeFeature(aFeature); - } - //} - } + // 4. delete features + // sketch feature should be skipped, only sub-features can be removed + // when sketch operation is active + std::set anIgnoredFeatures; + anIgnoredFeatures.insert(mySketchMgr->activeSketch()); + aWorkshop->deleteFeatures(aSelectedObj, anIgnoredFeatures); + + // 5. stop operation aWorkshop->displayer()->updateViewer(); - //myDisplayer->updateViewer(); aMgr->finishOperation(); return true; diff --git a/src/PartSet/PartSet_WidgetShapeSelector.cpp b/src/PartSet/PartSet_WidgetShapeSelector.cpp index fdda90f35..7352c1344 100644 --- a/src/PartSet/PartSet_WidgetShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetShapeSelector.cpp @@ -10,9 +10,21 @@ #include #include +#include + #include #include +#include + +PartSet_WidgetShapeSelector::PartSet_WidgetShapeSelector(QWidget* theParent, + ModuleBase_IWorkshop* theWorkshop, + const Config_WidgetAPI* theData, + const std::string& theParentId) +: ModuleBase_WidgetShapeSelector(theParent, theWorkshop, theData, theParentId) +{ +} + bool PartSet_WidgetShapeSelector::setObject(ObjectPtr theSelectedObject, GeomShapePtr theShape) { ObjectPtr aSelectedObject = theSelectedObject; @@ -97,7 +109,12 @@ void PartSet_WidgetShapeSelector::removeExternal() DocumentPtr aDoc = myExternalObject->document(); FeaturePtr aFeature = ModelAPI_Feature::feature(myExternalObject); if (aFeature.get() != NULL) { - aDoc->removeFeature(aFeature); + QObjectPtrList anObjects; + anObjects.append(aFeature); + // the external feature should be removed with all references, sketch feature should be ignored + std::set anIgnoredFeatures; + anIgnoredFeatures.insert(sketch()); + XGUI_Workshop::deleteFeatures(anObjects, anIgnoredFeatures); } myExternalObject = NULL; } diff --git a/src/PartSet/PartSet_WidgetShapeSelector.h b/src/PartSet/PartSet_WidgetShapeSelector.h index 1ad2f2197..e529e33ec 100644 --- a/src/PartSet/PartSet_WidgetShapeSelector.h +++ b/src/PartSet/PartSet_WidgetShapeSelector.h @@ -30,8 +30,7 @@ Q_OBJECT /// \param theData the widget configuation. The attribute of the model widget is obtained from /// \param theParentId is Id of a parent of the current attribute PartSet_WidgetShapeSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, - const Config_WidgetAPI* theData, const std::string& theParentId) - : ModuleBase_WidgetShapeSelector(theParent, theWorkshop, theData, theParentId) {} + const Config_WidgetAPI* theData, const std::string& theParentId); virtual ~PartSet_WidgetShapeSelector() {} diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 0f02f7eb7..7498ab831 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -106,6 +106,8 @@ QString objectInfo(ObjectPtr theObj) } if (aFeature.get()) { aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str()); + if (aFeature->data().get() && aFeature->data()->isValid()) + aFeatureStr.append(QString("(name=%1)").arg(aFeature->data()->name().c_str()).toStdString().c_str()); } return aFeatureStr; } @@ -1303,7 +1305,7 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) } else if (theId == "DEACTIVATE_PART_CMD") activatePart(ResultPartPtr()); else if (theId == "DELETE_CMD") - deleteObjects(aObjects); + deleteObjects(); else if (theId == "COLOR_CMD") changeColor(aObjects); else if (theId == "SHOW_CMD") @@ -1353,90 +1355,106 @@ void XGUI_Workshop::activatePart(ResultPartPtr theFeature) //} //************************************************************** -void XGUI_Workshop::deleteObjects(const QObjectPtrList& theList) +void XGUI_Workshop::deleteObjects() { ModuleBase_IModule* aModule = module(); + // 1. allow the module to delete objects, do nothing if it has succeed if (aModule->deleteObjects()) return; if (!isActiveOperationAborted()) return; + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + // 1. start operation + QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text(); + aDescription += tr(" %1"); + QStringList aObjectNames; + foreach (ObjectPtr aObj, anObjects) { + if (!aObj->data().get()) + continue; + aObjectNames << QString::fromStdString(aObj->data()->name()); + } + aDescription = aDescription.arg(aObjectNames.join(", ")); - QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow; - std::set aRefFeatures; - foreach (ObjectPtr aObj, theList) + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->startOperation(aDescription.toStdString()); + // 2. close the documents of the removed parts if the result part is in a list of selected objects + foreach (ObjectPtr aObj, anObjects) { ResultPartPtr aPart = std::dynamic_pointer_cast(aObj); if (aPart) { - // TODO: check for what there is this condition. It is placed here historicaly because - // ther is this condition during remove features. - } else { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - if (aFeature.get() != NULL) { - aObj->document()->refsToFeature(aFeature, aRefFeatures, false); + DocumentPtr aDoc = aObj->document(); + if (aDoc == aMgr->activeDocument()) { + aDoc->close(); } } } + // 3. delete objects + QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow; + std::set anIgnoredFeatures; + if (deleteFeatures(anObjects, anIgnoredFeatures, aDesktop, true)) { + myDisplayer->updateViewer(); + aMgr->finishOperation(); + updateCommandStatus(); + } + else { + aMgr->abortOperation(); + } +} - if (!aRefFeatures.empty()) { +//************************************************************** +bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList, + std::set theIgnoredFeatures, + QWidget* theParent, + const bool theAskAboutDeleteReferences) +{ + // 1. find all referenced features + std::set aRefFeatures; + foreach (ObjectPtr aObj, theList) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); + if (aFeature.get() != NULL) { + aObj->document()->refsToFeature(aFeature, aRefFeatures, false); + } + } + // 2. warn about the references remove, break the delete operation if the user chose it + if (theAskAboutDeleteReferences && !aRefFeatures.empty()) { QStringList aRefNames; std::set::const_iterator anIt = aRefFeatures.begin(), aLast = aRefFeatures.end(); for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = (*anIt); - std::string aFName = aFeature->data()->name().c_str(); - std::string aName = (*anIt)->name().c_str(); aRefNames.append((*anIt)->name().c_str()); } QString aNames = aRefNames.join(", "); QMessageBox::StandardButton aRes = QMessageBox::warning( - aDesktop, tr("Delete features"), + theParent, tr("Delete features"), QString(tr("Selected features are used in the following features: %1.\ These features will be deleted also. Would you like to continue?")).arg(aNames), QMessageBox::No | QMessageBox::Yes, QMessageBox::No); if (aRes != QMessageBox::Yes) - return; + return false; } - QString aDescription = tr("Delete %1"); - QStringList aObjectNames; - foreach (ObjectPtr aObj, theList) { - if (!aObj->data().get()) - continue; - aObjectNames << QString::fromStdString(aObj->data()->name()); - } - aDescription = aDescription.arg(aObjectNames.join(", ")); - SessionPtr aMgr = ModelAPI_Session::get(); - aMgr->startOperation(aDescription.toStdString()); + // 3. remove referenced features std::set::const_iterator anIt = aRefFeatures.begin(), aLast = aRefFeatures.end(); for (; anIt != aLast; anIt++) { - FeaturePtr aRefFeature = (*anIt); - DocumentPtr aDoc = aRefFeature->document(); - aDoc->removeFeature(aRefFeature); - } - + FeaturePtr aFeature = (*anIt); + DocumentPtr aDoc = aFeature->document(); + if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) + aDoc->removeFeature(aFeature); + } - foreach (ObjectPtr aObj, theList) - { - DocumentPtr aDoc = aObj->document(); - ResultPartPtr aPart = std::dynamic_pointer_cast(aObj); - if (aPart) { - if (aDoc == aMgr->activeDocument()) { - aDoc->close(); - } - } else { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - if (aFeature) { + // 4. remove the parameter features + foreach (ObjectPtr aObj, theList) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); + if (aFeature) { + DocumentPtr aDoc = aObj->document(); + if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) aDoc->removeFeature(aFeature); - } } } - - myDisplayer->updateViewer(); - aMgr->finishOperation(); - updateCommandStatus(); + return true; } bool hasResults(QObjectPtrList theObjects, const std::set& theTypes) diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index baeff4448..ff4a8708a 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -164,7 +164,7 @@ Q_OBJECT void activatePart(std::shared_ptr theFeature); //! Delete features - void deleteObjects(const QObjectPtrList& theList); + void deleteObjects(); //! Returns true if there is at least one selected body/construction/group result //! \return boolean value @@ -213,6 +213,19 @@ Q_OBJECT */ bool isActiveOperationAborted(); + //! Delete features. Delete the referenced features. There can be a question with a list of referenced + //! objects. + //! \param theList an objects to be deleted + //! \param theIgnoredFeatures a list of features to be ignored during delete + //! \param theParent a parent widget for the question message box + //! \param theAskAboutDeleteReferences if true, the message box with a list of references to the + //! objects features appear. If the user chose do not continue, the deletion is not performed + //! \return the success of the delete + static bool deleteFeatures(const QObjectPtrList& theList, + std::set theIgnoredFeatures = std::set(), + QWidget* theParent = 0, + const bool theAskAboutDeleteReferences = false); + signals: /// Emitted when selection happens in Salome viewer void salomeViewerSelection(); -- 2.39.2