]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #979: Provide modal dialog box for parameters management
authorvsv <vitaly.smetannikov@opencascade.com>
Tue, 19 Apr 2016 13:52:56 +0000 (16:52 +0300)
committervsv <vitaly.smetannikov@opencascade.com>
Tue, 19 Apr 2016 13:53:10 +0000 (16:53 +0300)
src/ModuleBase/ModuleBase_Dialog.cpp
src/ModuleBase/ModuleBase_Tools.cpp
src/ModuleBase/ModuleBase_Tools.h
src/ParametersPlugin/CMakeLists.txt
src/ParametersPlugin/ParametersPlugin_WidgetParamsMgr.cpp
src/ParametersPlugin/ParametersPlugin_WidgetParamsMgr.h
src/XGUI/XGUI_Tools.cpp
src/XGUI/XGUI_Tools.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 42a7d53c5a02f49ea8ae9953ec0cd00bc6d8f4b3..0ac6a72b1e1866a45ef51bd4a0683ed1c98e4ede 100644 (file)
@@ -72,6 +72,7 @@ ModuleBase_Dialog::ModuleBase_Dialog(ModuleBase_IWorkshop* theParent, const QStr
 void ModuleBase_Dialog::initializeWidget(ModuleBase_ModelWidget* theWidget)
 {
   theWidget->setFeature(myFeature);
+  theWidget->restoreValue();
 }
 
 void ModuleBase_Dialog::showEvent(QShowEvent* theEvent)
index 8643bf95a6ab2d83f9b639986cee30ed2a87c689..412b5e1094f7ba66b342d2c98413daae0cff2458 100755 (executable)
@@ -20,6 +20,7 @@
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttrList.h>
+#include <ModelAPI_ResultPart.h>
 #include <Events_Loop.h>
 
 #include <ModelAPI_Data.h>
@@ -45,6 +46,7 @@
 #include <QGraphicsDropShadowEffect>
 #include <QColor>
 #include <QApplication>
+#include <QMessageBox>
 
 #include <sstream>
 #include <string>
@@ -584,6 +586,274 @@ QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
   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)
+{
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+  if (aFeature.get()) {
+    DocumentPtr aFeatureDoc = aFeature->document();
+    // 1. find references in the current document
+    aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
+  }
+}
+
+
+//**************************************************************
+bool isSubOfComposite(const ObjectPtr& theObject)
+{
+  bool isSub = false;
+  std::set<FeaturePtr> aRefFeatures;
+  refsToFeatureInFeatureDocument(theObject, aRefFeatures);
+  std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
+                                       aLast = aRefFeatures.end();
+  for (; anIt != aLast && !isSub; anIt++) {
+    isSub = isSubOfComposite(theObject, *anIt);
+  }
+  return isSub;
+}
+
+//**************************************************************
+bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
+{
+  bool isSub = false;
+  CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
+  if (aComposite.get()) {
+    isSub = aComposite->isSub(theObject);
+    // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
+    // separated by composite sketch feature
+    if (!isSub) {
+      int aNbSubs = aComposite->numberOfSubs();
+      for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
+        isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
+      }
+    }
+  }
+  return isSub;
+}
+
+
+//**************************************************************
+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())
+      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;
+  }
+  QString aPartNames = aPartFeatureNames.join(", ");
+
+  QMessageBox aMessageBox(theParent);
+  aMessageBox.setWindowTitle(QObject::tr("Delete features"));
+  aMessageBox.setIcon(QMessageBox::Warning);
+  aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
+  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);
+    }
+  }
+  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?";
+    aMessageBox.setText(aText);
+    aMessageBox.exec();
+    QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
+
+    if (aButtonRole == QMessageBox::NoRole)
+      return false;
+
+    if (aButtonRole == QMessageBox::ActionRole) {
+      foreach (ObjectPtr aObj, theList)
+        ModelAPI_ReplaceParameterMessage::send(aObj, 0);
+      doDeleteReferences = false;
+    }
+  }
+  return true;
+}
+
 } // namespace ModuleBase_Tools
 
 
index 6aff1f90f55e9f2bbd3b62a5df056a3fcd69d6fb..fd70f33fbfa0a94618b87a3e5eab12e765231387 100755 (executable)
@@ -213,6 +213,84 @@ MODULEBASE_EXPORT void blockUpdateViewer(const bool theValue);
 /// \param theMaxLineInPixels a maximum line width in pixels
 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
+  \param theRefFeatures an output container
+ */
+void MODULEBASE_EXPORT refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
+                                                      std::set<FeaturePtr>& theRefFeatures);
+
+
+/*!
+ Returns true if the object if a sub child of the feature. The feature is casted to the
+ composite one. If it is possible, the sub object check happens. The method is applyed
+ recursively to the feature subs.
+ \param theObject a candidate to be a sub object
+ \param theFeature a candidate to be a composite feature
+ \return a boolean value
+ */
+bool MODULEBASE_EXPORT isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature);
+
+
+/*!
+* Returns true if the result is a sub object of some composite object
+* \param theObject a result object
+* \returns boolean value
+*/
+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);
 }
 
 #endif
index de8a14c2c6eb6909d2d4a57153b2c9d92dce64c1..fbcab9c2d37e9274636b21a0e5d1e92114814a70 100644 (file)
@@ -38,6 +38,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
                     ${PROJECT_SOURCE_DIR}/src/ModuleBase
                     ${SUIT_INCLUDE}
                     ${PYTHON_INCLUDE_DIR}
+                    ${CAS_INCLUDE_DIRS}
 )
 
 MESSAGE(STATUS "PYTHON_LIBRARIES (ParametersPlugin): ${PYTHON_LIBRARIES}")
@@ -52,7 +53,7 @@ SET(PROJECT_LIBRARIES
     ${QT_LIBRARIES}
 )
 
-ADD_DEFINITIONS(-DPARAMETERSPLUGIN_EXPORTS -DHAVE_DEBUG_PYTHON)
+ADD_DEFINITIONS(-DPARAMETERSPLUGIN_EXPORTS -DHAVE_DEBUG_PYTHON ${CAS_DEFINITIONS})
 ADD_LIBRARY(ParametersPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES})
 
 TARGET_LINK_LIBRARIES(ParametersPlugin ${PROJECT_LIBRARIES})
index b9f9720d02b2f0581b1808d208e20a049b73e50a..c360eddee31151e31a1c5d460f99cd5216b8afa9 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "ParametersPlugin_WidgetParamsMgr.h"
 #include "ParametersPlugin_Parameter.h"
+#include "ParametersPlugin_Validators.h"
 
 #include <ModelAPI_ResultParameter.h>
 #include <ModelAPI_AttributeString.h>
@@ -15,6 +16,8 @@
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Session.h>
 
+#include <ModuleBase_Tools.h>
+
 #include <Events_Loop.h>
 
 #include <QLayout>
@@ -117,9 +120,11 @@ ParametersPlugin_WidgetParamsMgr::ParametersPlugin_WidgetParamsMgr(QWidget* theP
   myTable->setColumnWidth(Col_Comment, 200);
   myTable->setMinimumWidth(600);
   myTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+  myTable->setSelectionMode(QAbstractItemView::SingleSelection);
+
   connect(myTable, SIGNAL(doubleClicked(const QModelIndex&)),
           SLOT(onDoubleClick(const QModelIndex&)));
-  //myTable->viewport()->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum));
+  connect(myTable, SIGNAL(itemSelectionChanged()), SLOT(onSelectionChanged()));
 
   myDelegate = new ParametersPlugin_ItemDelegate(myTable);
   connect(myDelegate, SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)), 
@@ -141,31 +146,33 @@ ParametersPlugin_WidgetParamsMgr::ParametersPlugin_WidgetParamsMgr(QWidget* theP
 
   QHBoxLayout* aBtnLayout = new QHBoxLayout(this);
 
-  QToolButton* aUpBtn = new QToolButton(this);
-  aUpBtn->setArrowType(Qt::UpArrow);
-  connect(aUpBtn, SIGNAL(clicked(bool)), SLOT(onUp()));
-  aBtnLayout->addWidget(aUpBtn);
+  myUpBtn = new QToolButton(this);
+  myUpBtn->setArrowType(Qt::UpArrow);
+  connect(myUpBtn, SIGNAL(clicked(bool)), SLOT(onUp()));
+  aBtnLayout->addWidget(myUpBtn);
 
-  QToolButton* aDownBtn = new QToolButton(this);
-  aDownBtn->setArrowType(Qt::DownArrow);
-  connect(aDownBtn, SIGNAL(clicked(bool)), SLOT(onDown()));
-  aBtnLayout->addWidget(aDownBtn);
+  myDownBtn = new QToolButton(this);
+  myDownBtn->setArrowType(Qt::DownArrow);
+  connect(myDownBtn, SIGNAL(clicked(bool)), SLOT(onDown()));
+  aBtnLayout->addWidget(myDownBtn);
 
   aBtnLayout->addStretch();
 
-  QPushButton* aAddBtn = new QPushButton(tr("Add"), this);
-  connect(aAddBtn, SIGNAL(clicked(bool)), SLOT(onAdd()));
-  aBtnLayout->addWidget(aAddBtn);
+  myAddBtn = new QPushButton(tr("Add"), this);
+  connect(myAddBtn, SIGNAL(clicked(bool)), SLOT(onAdd()));
+  aBtnLayout->addWidget(myAddBtn);
 
-  QPushButton* aInsertBtn = new QPushButton(tr("Insert"), this);
-  connect(aInsertBtn, SIGNAL(clicked(bool)), SLOT(onInsert()));
-  aBtnLayout->addWidget(aInsertBtn);
+  myInsertBtn = new QPushButton(tr("Insert"), this);
+  connect(myInsertBtn, SIGNAL(clicked(bool)), SLOT(onInsert()));
+  aBtnLayout->addWidget(myInsertBtn);
 
-  QPushButton* aRemoveBtn = new QPushButton(tr("Remove"), this);
-  connect(aRemoveBtn, SIGNAL(clicked(bool)), SLOT(onRemove()));
-  aBtnLayout->addWidget(aRemoveBtn);
+  myRemoveBtn = new QPushButton(tr("Remove"), this);
+  connect(myRemoveBtn, SIGNAL(clicked(bool)), SLOT(onRemove()));
+  aBtnLayout->addWidget(myRemoveBtn);
 
   aLayout->addLayout(aBtnLayout);
+
+  onSelectionChanged();
 }
 
 QList<QWidget*> ParametersPlugin_WidgetParamsMgr::getControls() const
@@ -175,22 +182,32 @@ QList<QWidget*> ParametersPlugin_WidgetParamsMgr::getControls() const
   return aList;
 }
 
+void ParametersPlugin_WidgetParamsMgr::selectItemScroll(QTreeWidgetItem* aItem)
+{
+  myTable->clearSelection();
+  QModelIndex aParent = myTable->model()->index(0, 0);
+  int aChildIdx = myParameters->indexOfChild(aItem);
+  QModelIndex aIndex = myTable->model()->index(aChildIdx, Col_Name, aParent);
+  myTable->selectionModel()->select(aIndex, 
+    QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
+  myTable->scrollToItem(aItem);
+}
+
+
 bool ParametersPlugin_WidgetParamsMgr::storeValueCustom()
 {
-  for(int i = 0; i < myParameters->childCount(); i++) {
-    QTreeWidgetItem* aItem = myParameters->child(i);
-    if ((aItem->text(Col_Name) == NoName) || (aItem->text(Col_Equation) == NoValue)) {
-      QMessageBox::warning(this, tr("Warning"), tr("Created parameter is not defined properly."));
-
-      // The index of myParameters item
-      QModelIndex aParent = myTable->model()->index(0, 0);
-      int aRow = myParameters->indexOfChild(aItem);
-      QModelIndex aIndex = myTable->model()->index(aRow, Col_Name, aParent);
-      myTable->selectionModel()->select(aIndex, 
-        QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
-      myTable->scrollToItem(aItem);
+  ParametersPlugin_ExpressionValidator aValidator;
+  std::list<std::string> aArgs;
+  std::string aAttrId = ParametersPlugin_Parameter::VARIABLE_ID();
+  std::string aErr;
+  int aId = 0;
+  foreach(FeaturePtr aFeature, myParametersList) {
+    if (!aValidator.isValid(aFeature->attribute(aAttrId), aArgs, aErr)) {
+      QMessageBox::warning(this, tr("Warning"), aErr.c_str());
+      selectItemScroll(myParameters->child(aId));
       return false;
     }
+    aId++;
   }
   return true;
 }
@@ -372,43 +389,168 @@ void ParametersPlugin_WidgetParamsMgr::updateFeaturesPart()
   }
 }
 
-void ParametersPlugin_WidgetParamsMgr::onAdd()
+FeaturePtr ParametersPlugin_WidgetParamsMgr::createParameter() const
 {
   SessionPtr aMgr = ModelAPI_Session::get();
   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
 
   FeaturePtr aFeature = aDoc->addFeature(ParametersPlugin_Parameter::ID());
-  if (!aFeature.get())
-    return;
-  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
-  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  if (aFeature.get()) {
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  }
+  return aFeature;
+}
+
 
+QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::createNewItem() const
+{
   QStringList aValues;
   aValues << NoName;
   aValues << NoValue;
 
   QTreeWidgetItem* aItem = new QTreeWidgetItem(aValues);
   aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
+  return aItem;
+}
+
+
+void ParametersPlugin_WidgetParamsMgr::onAdd()
+{
+  FeaturePtr aFeature = createParameter();
+  if (!aFeature.get())
+    return;
+
+  QTreeWidgetItem* aItem = createNewItem();
   myParameters->addChild(aItem);
   myParametersList.append(aFeature);
       
   myTable->scrollToItem(aItem);
 }
 
+QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::selectedItem() const
+{
+  QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
+  if (aItemsList.count() == 0)
+    return 0;
+
+  QTreeWidgetItem* aCurrentItem = aItemsList.first();
+  if (aCurrentItem->parent() != myParameters)
+    return 0;
+
+  return aCurrentItem;
+}
+
+
 void ParametersPlugin_WidgetParamsMgr::onInsert()
 {
+  QTreeWidgetItem* aCurrentItem = selectedItem();
+  if (!aCurrentItem)
+    return;
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
+
+  FeaturePtr aNewFeature = createParameter();
+  if (!aNewFeature.get())
+    return;
+
+  QTreeWidgetItem* aItem = createNewItem();
+  int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
+  if (aCurrentPos == 0) {
+    aDoc->moveFeature(aNewFeature, FeaturePtr());
+  } else {
+    FeaturePtr aCurFeature = myParametersList.at(aCurrentPos - 1);
+    aDoc->moveFeature(aNewFeature, aCurFeature);
+  }
+  myParametersList.insert(aCurrentPos, aNewFeature);
+  myParameters->insertChild(aCurrentPos, aItem);
 }
 
 void ParametersPlugin_WidgetParamsMgr::onRemove()
 {
+  QTreeWidgetItem* aCurrentItem = selectedItem();
+  if (!aCurrentItem)
+    return;
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
+
+  int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
+  FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
+
+  QObjectPtrList anObjects;
+  anObjects.append(aCurFeature);
+
+  std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
+  ModuleBase_Tools::findReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures);
+
+  bool doDeleteReferences = true;
+  if (ModuleBase_Tools::isDeleteFeatureWithReferences(anObjects, aDirectRefFeatures, 
+      aIndirectRefFeatures, this, doDeleteReferences)) {
+    myParametersList.removeOne(aCurFeature);
+    myParameters->removeChild(aCurrentItem);
+    aDoc->removeFeature(aCurFeature);
+  }
 }
 
 void ParametersPlugin_WidgetParamsMgr::onUp()
 {
+  QTreeWidgetItem* aCurrentItem = selectedItem();
+  if (!aCurrentItem)
+    return;
+
+  QString aName = aCurrentItem->text(0);
+
+  int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
+  if (aCurrentPos == 0)
+    return;
+  FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
+
+  std::string aNm = aCurFeature->data()->name();
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
+
+  FeaturePtr aa = myParametersList.at(aCurrentPos - 1);
+  std::string aN = aa->data()->name();
+
+  if (aCurrentPos == 1)
+    aDoc->moveFeature(aCurFeature, FeaturePtr());
+  else
+    aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos - 2));
+
+  myParametersList.removeOne(aCurFeature);
+  myParametersList.insert(aCurrentPos - 1, aCurFeature);
+
+  myParameters->removeChild(aCurrentItem);
+  myParameters->insertChild(aCurrentPos - 1, aCurrentItem);
+
+  selectItemScroll(aCurrentItem);
 }
 
 void ParametersPlugin_WidgetParamsMgr::onDown()
 {
+  QTreeWidgetItem* aCurrentItem = selectedItem();
+  if (!aCurrentItem)
+    return;
+
+  int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
+  if (aCurrentPos == (myParametersList.count() - 1))
+    return;
+  FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
+  aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos + 1));
+
+  myParametersList.removeOne(aCurFeature);
+  myParametersList.insert(aCurrentPos + 1, aCurFeature);
+
+  myParameters->removeChild(aCurrentItem);
+  myParameters->insertChild(aCurrentPos + 1, aCurrentItem);
+
+  selectItemScroll(aCurrentItem);
 }
 
 
@@ -425,3 +567,19 @@ void ParametersPlugin_WidgetParamsMgr::sendWarning()
 {
   QMessageBox::warning(this, tr("Warning"), myMessage);
 }
+
+void ParametersPlugin_WidgetParamsMgr::onSelectionChanged()
+{
+  QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
+  bool isParameter = false;
+  foreach(QTreeWidgetItem* aItem, aItemsList) {
+    if (aItem->parent() == myParameters) {
+      isParameter = true;
+      break;
+    }
+  }
+  myInsertBtn->setEnabled(isParameter);
+  myRemoveBtn->setEnabled(isParameter);
+  myUpBtn->setEnabled(isParameter);
+  myDownBtn->setEnabled(isParameter);
+}
index 9c574c09ddb26030efb48000c45475e33d3c6813..1ddd00d485eb40852266fe8f81815df46af84d62 100644 (file)
@@ -14,6 +14,8 @@
 class QTreeWidget;
 class QTreeWidgetItem;
 class ParametersPlugin_ItemDelegate;
+class QPushButton;
+class QToolButton;
 
 /*!
  * \ingroup GUI
@@ -71,7 +73,14 @@ private slots:
 
   void sendWarning();
 
+  void onSelectionChanged();
+
 private:
+  FeaturePtr createParameter() const;
+  QTreeWidgetItem* createNewItem() const;
+  QTreeWidgetItem* selectedItem() const;
+  void selectItemScroll(QTreeWidgetItem* aItem);
+
   void updateFeaturesPart();
 
   bool hasName(const QString& theName) const;
@@ -85,6 +94,12 @@ private:
   QList<FeaturePtr> myParametersList;
 
   QString myMessage;
+
+  QPushButton* myAddBtn;
+  QPushButton* myInsertBtn;
+  QPushButton* myRemoveBtn;
+  QToolButton* myUpBtn;
+  QToolButton* myDownBtn;
 };
 
 
index 9bb1dfa84d357c5c5c3cde1cbdad0019ebbab8ea..6d4009a4a9d72ad11fdf0a98b3555a49bdf212f9 100644 (file)
@@ -162,168 +162,6 @@ bool allDocumentsActivated(QString& theNotActivatedNames)
 }
 
 //**************************************************************
-void refsToFeatureInFeatureDocument(const ObjectPtr& theObject, std::set<FeaturePtr>& theRefFeatures)
-{
-  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
-  if (aFeature.get()) {
-    DocumentPtr aFeatureDoc = aFeature->document();
-    // 1. find references in the current document
-    aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
-  }
-}
-
-//**************************************************************
-bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
-{
-  bool isSub = false;
-  CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
-  if (aComposite.get()) {
-    isSub = aComposite->isSub(theObject);
-    // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
-    // separated by composite sketch feature
-    if (!isSub) {
-      int aNbSubs = aComposite->numberOfSubs();
-      for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
-        isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
-      }
-    }
-  }
-  return isSub;
-}
-
-//**************************************************************
-bool isSubOfComposite(const ObjectPtr& theObject)
-{
-  bool isSub = false;
-  std::set<FeaturePtr> aRefFeatures;
-  refsToFeatureInFeatureDocument(theObject, aRefFeatures);
-  std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
-                                       aLast = aRefFeatures.end();
-  for (; anIt != aLast && !isSub; anIt++) {
-    isSub = isSubOfComposite(theObject, *anIt);
-  }
-  return isSub;
-}
-
-//**************************************************************
-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);
-      }
-    }
-  }
-}
 
 XGUI_Workshop* workshop(ModuleBase_IWorkshop* theWorkshop)
 {
index da38e87add14de71a9618366bce4e2670c1f052a..9215bf6ace11838d6e885cad9ce5fdbdb1982935 100644 (file)
@@ -100,59 +100,6 @@ bool canRename(const ObjectPtr& theObject, const QString& theName);
  */
 bool XGUI_EXPORT allDocumentsActivated(QString& theNotActivatedNames);
 
-/*!
-  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
-  \param theRefFeatures an output container
- */
-void XGUI_EXPORT refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
-                                                std::set<FeaturePtr>& theRefFeatures);
-
-/*!
- Returns true if the object if a sub child of the feature. The feature is casted to the
- composite one. If it is possible, the sub object check happens. The method is applyed
- recursively to the feature subs.
- \param theObject a candidate to be a sub object
- \param theFeature a candidate to be a composite feature
- \return a boolean value
- */
-bool XGUI_EXPORT isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature);
-
-/*!
-*/
-void refsDirectToFeatureInAllDocuments(const ObjectPtr& theSourceObject, const ObjectPtr& theObject,
-                                 const QObjectPtrList& theIgnoreList,
-                                 std::set<FeaturePtr>& theDirectRefFeatures, 
-                                 std::set<FeaturePtr>& theAlreadyProcessed);
-
-/*!
- 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 XGUI_EXPORT refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject,
-                                             const ObjectPtr& theObject,
-                                             const QObjectPtrList& theIgnoreList,
-                                             std::set<FeaturePtr>& theDirectRefFeatures,
-                                             std::set<FeaturePtr>& theIndirectRefFeatures,
-                                             std::set<FeaturePtr>& theAlreadyProcessed);
-
-/*!
-* Returns true if the result is a sub object of some composite object
-* \param theObject a result object
-* \returns boolean value
-*/
-bool XGUI_EXPORT isSubOfComposite(const ObjectPtr& theObject);
-
 /*!
  Returns converted workshop
  \param theWorkshop an interface workshop
index e6dfc4bc047ab12a130dd7a1fa460a84cece11dd..33fb1316fc5756aacaf3014fec2619ccb72d0f72 100755 (executable)
@@ -1280,11 +1280,11 @@ void XGUI_Workshop::deleteObjects()
   // 3. delete objects
   std::set<FeaturePtr> anIgnoredFeatures;
   std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
-  findReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures);
+  ModuleBase_Tools::findReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures);
 
   bool doDeleteReferences = true;
-  if (isDeleteFeatureWithReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures,
-                                    desktop(), doDeleteReferences)) {
+  if (ModuleBase_Tools::isDeleteFeatureWithReferences(anObjects, aDirectRefFeatures, 
+      aIndirectRefFeatures, desktop(), doDeleteReferences)) {
     // start operation
     QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text();
     aDescription += " " + aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
@@ -1335,7 +1335,7 @@ void XGUI_Workshop::cleanHistory()
     if (aFeature.get()) {
       std::set<FeaturePtr> alreadyProcessed;
       aDirectRefFeatures.clear();
-      XGUI_Tools::refsDirectToFeatureInAllDocuments(aFeature, aFeature, aFeatures,
+      ModuleBase_Tools::refsDirectToFeatureInAllDocuments(aFeature, aFeature, aFeatures,
                                                     aDirectRefFeatures, alreadyProcessed);
       if (aDirectRefFeatures.empty() && !anUnusedObjects.contains(aFeature))
         anUnusedObjects.append(aFeature);
@@ -1457,110 +1457,11 @@ void XGUI_Workshop::moveObjects()
 }
 
 //**************************************************************
-void XGUI_Workshop::findReferences(const QObjectPtrList& theList,
-                                   std::set<FeaturePtr>& aDirectRefFeatures,
-                                   std::set<FeaturePtr>& aIndirectRefFeatures)
-{
-  foreach (ObjectPtr aDeletedObj, theList) {
-    std::set<FeaturePtr> alreadyProcessed;
-    XGUI_Tools::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;
-  }
-}
-
-bool XGUI_Workshop::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())
-      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;
-  }
-  QString aPartNames = aPartFeatureNames.join(", ");
-
-  QMessageBox aMessageBox(theParent);
-  aMessageBox.setWindowTitle(tr("Delete features"));
-  aMessageBox.setIcon(QMessageBox::Warning);
-  aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
-  aMessageBox.setDefaultButton(QMessageBox::No);
-
-  QString aText;
-  if (!aDirectNames.isEmpty() || !aIndirectNames.isEmpty()) {
-    if (aCanReplaceParameters) {
-      aText = QString(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(tr("(Also these features will be deleted: %1)\n")).arg(aIndirectNames);
-      QPushButton *aReplaceButton = aMessageBox.addButton(tr("Replace"), QMessageBox::ActionRole);
-    } else {
-      aText = QString(tr("Selected features are used in the following features: %1.\nThese features will be deleted.\n")).arg(aDirectNames);
-      if (!aIndirectNames.isEmpty())
-        aText += QString(tr("(Also these features will be deleted: %1)\n")).arg(aIndirectNames);
-    }
-  }
-  if (!aPartNames.isEmpty())
-    aText += QString(tr("The following parts will be deleted: %1.\n")).arg(aPartNames);
-
-  if (!aText.isEmpty()) {
-    aText += "Would you like to continue?";
-    aMessageBox.setText(aText);
-    aMessageBox.exec();
-    QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
-
-    if (aButtonRole == QMessageBox::NoRole)
-      return false;
-
-    if (aButtonRole == QMessageBox::ActionRole) {
-      foreach (ObjectPtr aObj, theList)
-        ModelAPI_ReplaceParameterMessage::send(aObj, this);
-      doDeleteReferences = false;
-    }
-  }
-  return true;
-}
-
 bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theFeatures,
                                    const std::set<FeaturePtr>& theIgnoredFeatures)
 {
   std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
-  findReferences(theFeatures, aDirectRefFeatures, aIndirectRefFeatures);
+  ModuleBase_Tools::findReferences(theFeatures, aDirectRefFeatures, aIndirectRefFeatures);
   return deleteFeaturesInternal(theFeatures, aDirectRefFeatures, aIndirectRefFeatures,
                                 theIgnoredFeatures);
 }
@@ -1758,7 +1659,7 @@ bool XGUI_Workshop::canMoveFeature()
       std::set<FeaturePtr> aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end());
       // 2. Get all reference features to the selected object in the document 
       std::set<FeaturePtr> aRefFeatures;
-      XGUI_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures);
+      ModuleBase_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures);
 
       if (aRefFeatures.empty())
         continue;
index 086f691ab2030ddb6073c42ee9067faeea435cb9..ef44340d538387a4105f39504676dd404a457865 100755 (executable)
@@ -387,28 +387,6 @@ signals:
   /// \param theOperation an operation
    void setGrantedFeatures(ModuleBase_Operation* theOperation);
 
-  //! 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
-  void findReferences(const QObjectPtrList& theList,
-                      std::set<FeaturePtr>& aDirectRefFeatures,
-                      std::set<FeaturePtr>& aIndirectRefFeatures);
-
-  //! 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 isDeleteFeatureWithReferences(const QObjectPtrList& theList,
-                                     const std::set<FeaturePtr>& aDirectRefFeatures,
-                                     const std::set<FeaturePtr>& aIndirectRefFeatures,
-                                     QWidget* theParent,
-                                     bool& doDeleteReferences);
-
   //! \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