Salome HOME
Make same planes cannot be used twice in partition tool
[modules/shaper.git] / src / XGUI / XGUI_Workshop.cpp
index 9d9b893001d59dae2021650deb8c3b37e7e8ad98..cb56c38795c4e51f8a1c29093dfa6b31a54ee0f2 100755 (executable)
@@ -66,6 +66,8 @@
 #include <ModuleBase_WidgetFactory.h>
 #include <ModuleBase_OperationFeature.h>
 #include <ModuleBase_OperationAction.h>
+#include <ModuleBase_PagedContainer.h>
+#include <ModuleBase_WidgetValidated.h>
 
 #include <Config_Common.h>
 #include <Config_FeatureMessage.h>
@@ -298,12 +300,12 @@ void XGUI_Workshop::initMenu()
   //connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRebuild()));
   //salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
 
-  aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export NewGeom..."), tr("Export the current document into a NewGeom file"),
+  aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export native..."), tr("Export the current document into a native file"),
                                               QIcon(), QKeySequence(),
                                               false, "MEN_DESK_FILE");
   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onSaveAs()));
 
-  aAction = salomeConnector()->addDesktopCommand("OPEN_CMD", tr("Import NewGeom..."), tr("Import a NewGeom file"),
+  aAction = salomeConnector()->addDesktopCommand("OPEN_CMD", tr("Import native..."), tr("Import native file"),
                                               QIcon(), QKeySequence(),
                                               false, "MEN_DESK_FILE");
   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onOpen()));
@@ -567,13 +569,15 @@ void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
     return;
 
   showPropertyPanel();
-  QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation();
-  ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myModuleConnector);
-
   myPropertyPanel->cleanContent();
-  aFactory.createWidget(myPropertyPanel->contentWidget());
 
-  QList<ModuleBase_ModelWidget*> aWidgets = aFactory.getModelWidgets();
+  QList<ModuleBase_ModelWidget*> aWidgets;
+  if (!module()->createWidgets(theOperation, aWidgets)) {
+    QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation();
+    ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myModuleConnector);
+    aFactory.createWidget(myPropertyPanel->contentWidget());
+    aWidgets = aFactory.getModelWidgets();
+  }
 
   // check compatibility of feature and widgets
   FeaturePtr aFeature = aFOperation->feature();
@@ -619,11 +623,13 @@ void XGUI_Workshop::connectToPropertyPanel(const bool isToConnect)
     const QList<ModuleBase_ModelWidget*>& aWidgets = aPropertyPanel->modelWidgets();
     foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
        myModule->connectToPropertyPanel(aWidget, isToConnect);
-      if (isToConnect) {
+       if (isToConnect) {
         connect(aWidget, SIGNAL(valueStateChanged(int)), this, SLOT(onWidgetStateChanged(int)));
+        connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onValuesChanged()));
       }
       else {
         disconnect(aWidget, SIGNAL(valueStateChanged(int)), this, SLOT(onWidgetStateChanged(int)));
+        disconnect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onValuesChanged()));
       }
     }
   }
@@ -896,6 +902,27 @@ void XGUI_Workshop::onWidgetStateChanged(int thePreviousState)
   myModule->widgetStateChanged(thePreviousState);
 }
 
+//******************************************************
+void XGUI_Workshop::onValuesChanged()
+{
+  ModuleBase_ModelWidget* aSenderWidget = (ModuleBase_ModelWidget*)(sender());
+  if (!aSenderWidget || aSenderWidget->canSetValue())
+    return;
+
+  ModuleBase_ModelWidget* anActiveWidget = 0;
+  ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
+  if (anOperation) {
+    ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+    if (aPanel)
+      anActiveWidget = aPanel->activeWidget();
+  }
+  if (anActiveWidget) {
+    ModuleBase_WidgetValidated* aWidgetValidated = dynamic_cast<ModuleBase_WidgetValidated*>
+                                                                           (anActiveWidget);
+    aWidgetValidated->clearValidatedCash();
+  }
+}
+
 ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule)
 {
   QString libName = QString::fromStdString(library(theModule.toStdString()));
@@ -1101,7 +1128,7 @@ void XGUI_Workshop::hidePropertyPanel()
   // in SALOME mode, workstack made the PyConsole the active window,
   // set the focus on it. As a result, shortcuts of the application, like
   // are processed by this console. For example Undo actions.
-  // It is possible that this code is to be moved to NewGeom package
+  // It is possible that this code is to be moved to SHAPER package
   QMainWindow* aDesktop = desktop();
   ModuleBase_Tools::activateWindow(aDesktop, "XGUI_Workshop::hidePropertyPanel()");
   ModuleBase_Tools::setFocus(aDesktop, "XGUI_Workshop::showPropertyPanel()");
@@ -1194,12 +1221,6 @@ void XGUI_Workshop::deleteObjects()
   if (!(hasFeature || hasParameter))
     return;
 
-  // 1. start operation
-  QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text();
-  aDescription += " " + aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
-  ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module());
-  operationMgr()->startOperation(anOpAction);
-
   // 3. delete objects
   std::set<FeaturePtr> anIgnoredFeatures;
   std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
@@ -1208,9 +1229,17 @@ void XGUI_Workshop::deleteObjects()
   bool doDeleteReferences = true;
   if (isDeleteFeatureWithReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures,
                                     desktop(), doDeleteReferences)) {
+    // start operation
+    QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text();
+    aDescription += " " + aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
+    ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module());
+    operationMgr()->startOperation(anOpAction);
+
     // 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();
@@ -1276,6 +1305,21 @@ void XGUI_Workshop::cleanHistory()
 
     QString aText = QString(tr("Unused features are the following: %1.\nThese features will be deleted.\nWould you like to continue?")
                    .arg(anUnusedNames));
+    /*QString aText;
+    if (anUnusedNames.isEmpty()) {
+      aMessageBox.setStandardButtons(QMessageBox::Ok);
+      aMessageBox.setDefaultButton(QMessageBox::Ok);
+
+      aText = QString(tr("All features are relevant, there is nothing to be deleted"));
+    }
+    else {
+      aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
+      aMessageBox.setDefaultButton(QMessageBox::No);
+
+      aText = QString(tr("Unused features are the following: %1.\nThese features will be deleted.\nWould you like to continue?")
+        .arg(anUnusedNames));
+    }*/
+
     aMessageBox.setText(aText);
     if (aMessageBox.exec() == QMessageBox::No)
       return;
@@ -1293,6 +1337,26 @@ void XGUI_Workshop::cleanHistory()
       operationMgr()->abortOperation(operationMgr()->currentOperation());
     }
   }
+  else {
+    QString anActionId = "CLEAN_HISTORY_CMD";
+    QString aDescription = contextMenuMgr()->action(anActionId)->text();
+
+    QMessageBox aMessageBox(desktop());
+    aMessageBox.setWindowTitle(aDescription);
+    aMessageBox.setIcon(QMessageBox::Warning);
+    aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
+    aMessageBox.setDefaultButton(QMessageBox::No);
+
+    QString aText;
+    aMessageBox.setStandardButtons(QMessageBox::Ok);
+    aMessageBox.setDefaultButton(QMessageBox::Ok);
+
+    aText = QString(tr("All features are relevant, there is nothing to be deleted"));
+    aMessageBox.setText(aText);
+
+    if (aMessageBox.exec() == QMessageBox::No)
+      return;
+  }
 }
 
 //**************************************************************
@@ -1355,41 +1419,63 @@ bool XGUI_Workshop::isDeleteFeatureWithReferences(const QObjectPtrList& theList,
 {
   doDeleteReferences = true;
 
+  QString aDirectNames, aIndirectNames;
   if (!aDirectRefFeatures.empty()) {
     QStringList aDirectRefNames;
     foreach (const FeaturePtr& aFeature, aDirectRefFeatures)
       aDirectRefNames.append(aFeature->name().c_str());
-    QString aDirectNames = aDirectRefNames.join(", ");
+    aDirectNames = aDirectRefNames.join(", ");
 
     QStringList aIndirectRefNames;
     foreach (const FeaturePtr& aFeature, aIndirectRefFeatures)
       aIndirectRefNames.append(aFeature->name().c_str());
-    QString aIndirectNames = aIndirectRefNames.join(", ");
-
-    bool canReplaceParameters = true;
-    foreach (ObjectPtr aObj, theList) {
-      FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
-      if (!std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aFeature->firstResult()).get()) { // the feature is not a parameter
-        canReplaceParameters = false;
-        break;
-      }
-    }
+    aIndirectNames = aIndirectRefNames.join(", ");
+  }
 
-    QMessageBox aMessageBox(theParent);
-    aMessageBox.setWindowTitle(tr("Delete features"));
-    aMessageBox.setIcon(QMessageBox::Warning);
-    aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
-    aMessageBox.setDefaultButton(QMessageBox::No);
+  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();
+    std::string aResultGroupName = aFirstResult->groupName();
+    if (aResultGroupName == ModelAPI_ResultPart::group())
+      aPartFeatureNames.append(aFeature->name().c_str());
 
-    QString aText;
-    if (canReplaceParameters) {
-      aText = QString(tr("Selected parameters are used in the following features: %1.\nThese features will be deleted.\n%2Or parameters could be replaced by their values.\nWould you like to continue?"))
-          .arg(aDirectNames).arg(aIndirectNames.isEmpty() ? QString() : QString(tr("(Also these features will be deleted: %1)\n")).arg(aIndirectNames));
+    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%2Would you like to continue?"))
-          .arg(aDirectNames).arg(aIndirectNames.isEmpty() ? QString() : QString(tr("Also these features will be deleted: %1.\n")).arg(aIndirectNames));
+      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());
@@ -1892,8 +1978,14 @@ void XGUI_Workshop::synchronizeGroupInViewer(const DocumentPtr& theDoc,
   int aSize = theDoc->size(theGroup);
   for (int i = 0; i < aSize; i++) {
     aObj = theDoc->object(theGroup, i);
-    if (aObj->isDisplayed())
+    if (aObj->isDisplayed()) {
+      // Hide the presentation with an empty shape. But isDisplayed state of the object should not
+      // be changed to the object becomes visible when the shape becomes not empty
+      ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+      if (aRes.get() && (!aRes->shape().get() || aRes->shape()->isNull()))
+        continue;
       myDisplayer->display(aObj, false);
+    }
   }
   if (theUpdateViewer)
     myDisplayer->updateViewer();