Salome HOME
Merge remote-tracking branch 'remotes/origin/HigherLevelObjectsHistory'
[modules/shaper.git] / src / XGUI / XGUI_OperationMgr.cpp
index 8fa2501ec7a74c2415e8db584aa9542e2cb88182..e00490f8e16789f31d2ae213fe75a0857a207d2d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "XGUI_OperationMgr.h"
+
+#include "XGUI_ActiveControlMgr.h"
+#include "XGUI_ActiveControlSelector.h"
+#include "XGUI_FacesPanelSelector.h"
 #include "XGUI_ModuleConnector.h"
 #include "XGUI_Workshop.h"
 #include "XGUI_ErrorMgr.h"
+#include "XGUI_FacesPanel.h"
 #include "XGUI_Tools.h"
 #include "XGUI_ObjectsBrowser.h"
 #include "XGUI_ContextMenuMgr.h"
@@ -59,7 +63,7 @@ public:
   /// \param theParent the parent to be deleted when the parent is deleted
   /// \param theOperationMgr the class to perform deletion
   XGUI_ShortCutListener(QObject* theParent, XGUI_OperationMgr* theOperationMgr)
-    : QObject(theParent), myOperationMgr(theOperationMgr)
+    : QObject(theParent), myOperationMgr(theOperationMgr), myIsActive(false)
   {
     qApp->installEventFilter(this);
   }
@@ -202,6 +206,18 @@ ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation*
   return myOperations.at(idx - 1);
 }
 
+ModuleBase_ModelWidget* XGUI_OperationMgr::activeWidget() const
+{
+  ModuleBase_ModelWidget* anActiveWidget = 0;
+  ModuleBase_Operation* anOperation = currentOperation();
+  if (anOperation) {
+    ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+    if (aPanel)
+      anActiveWidget = aPanel->activeWidget();
+  }
+  return anActiveWidget;
+}
+
 bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
 {
   if (hasOperation())
@@ -225,7 +241,7 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
   return isStarted;
 }
 
-bool XGUI_OperationMgr::abortAllOperations()
+bool XGUI_OperationMgr::abortAllOperations(const XGUI_MessageKind& theMessageKind)
 {
   bool aResult = true;
   if(!hasOperation())
@@ -233,16 +249,25 @@ bool XGUI_OperationMgr::abortAllOperations()
 
   if (operationsCount() == 1) {
     ModuleBase_Operation* aCurrentOperation = currentOperation();
-    if (canStopOperation(aCurrentOperation)) {
+    if (canStopOperation(aCurrentOperation, theMessageKind)) {
       abortOperation(aCurrentOperation);
     }
     else
       aResult = false;
   }
   else {
-    myActiveMessageBox = createMessageBox(tr("All active operations will be aborted."));
-    aResult = myActiveMessageBox->exec() == QMessageBox::Ok;
-    myActiveMessageBox = 0;
+    if (theMessageKind == XGUI_AbortOperationMessage) {
+      myActiveMessageBox = createMessageBox(tr("All active operations will be aborted."));
+      aResult = myActiveMessageBox->exec() == QMessageBox::Ok;
+      myActiveMessageBox = 0;
+    }
+    else if (theMessageKind == XGUI_InformationMessage) {
+      QString aMessage = tr("Please validate all your active operations before saving.");
+      myActiveMessageBox = createInformationBox(aMessage);
+      myActiveMessageBox->exec();
+      myActiveMessageBox = 0;
+      aResult = false; // do not perform abort
+    }
     while(aResult && hasOperation()) {
       abortOperation(currentOperation());
     }
@@ -256,7 +281,7 @@ bool XGUI_OperationMgr::commitAllOperations()
   while (hasOperation()) {
     ModuleBase_Operation* anOperation = currentOperation();
     if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) {
-      anOperationProcessed = onCommitOperation();
+      anOperationProcessed = commitOperation();
     } else {
       abortOperation(anOperation);
       anOperationProcessed = true;
@@ -310,32 +335,32 @@ void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperati
   onValidateOperation();
 }
 
-bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
+bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation,
+                                         const XGUI_OperationMgr::XGUI_MessageKind& theMessageKind)
 {
   //in case of nested (sketch) operation no confirmation needed
   if (isGrantedOperation(theOperation->id()))
     return true;
   if (theOperation && theOperation->isModified()) {
-    QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
-
-    myActiveMessageBox = createMessageBox(aMessage);
-    int anAnswer = myActiveMessageBox->exec() == QMessageBox::Ok;
-    myActiveMessageBox = 0;
-    return anAnswer;
+    QString aTitle = theOperation->getDescription()->description();
+    if (theMessageKind == XGUI_AbortOperationMessage) {
+      QString aMessage = tr("%1 operation will be aborted.").arg(aTitle);
+      myActiveMessageBox = createMessageBox(aMessage);
+      bool aResult = myActiveMessageBox->exec() == QMessageBox::Ok;
+      myActiveMessageBox = 0;
+      return aResult;
+    }
+    else if (theMessageKind == XGUI_InformationMessage) {
+      QString aMessage = tr("Please validate your %1 before saving.").arg(aTitle);
+      myActiveMessageBox = createInformationBox(aMessage);
+      myActiveMessageBox->exec();
+      myActiveMessageBox = 0;
+      return false;
+    }
   }
   return true;
 }
 
-bool XGUI_OperationMgr::commitOperation()
-{
-  //if (hasOperation() && currentOperation()->isValid()) {
-  //  onCommitOperation();
-  //  return true;
-  //}
-  //return false;
-  return onCommitOperation();
-}
-
 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
 {
   theOperation->resume();
@@ -407,9 +432,10 @@ bool XGUI_OperationMgr::canStartOperation(const QString& theId, bool& isCommitte
 
 void XGUI_OperationMgr::stopOperation(ModuleBase_Operation* theOperation, bool& isCommitted)
 {
-  if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() && theOperation->isModified())
+  if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() &&
+      theOperation->isModified()) {
     isCommitted = theOperation->commit();
-  else {
+  else {
     isCommitted = false;
     abortOperation(theOperation);
   }
@@ -433,7 +459,7 @@ void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation)
   }
 }
 
-bool XGUI_OperationMgr::onCommitOperation()
+bool XGUI_OperationMgr::commitOperation()
 {
   bool isCommitted = false;
   ModuleBase_Operation* anOperation = currentOperation();
@@ -450,6 +476,11 @@ void XGUI_OperationMgr::onAbortOperation()
   }
 }
 
+void XGUI_OperationMgr::onAbortAllOperation()
+{
+  abortAllOperations();
+}
+
 void XGUI_OperationMgr::onBeforeOperationStarted()
 {
   ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
@@ -519,6 +550,8 @@ void XGUI_OperationMgr::onBeforeOperationAborted()
 void XGUI_OperationMgr::onOperationAborted()
 {
   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
+  XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop);
+  aWorkshop->setStatusBarMessage("");
   emit operationAborted(aSenderOperation);
 }
 
@@ -610,9 +643,10 @@ void XGUI_OperationMgr::onOperationStopped()
 
 bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent)
 {
+  bool isAccepted = false;
+
   // Let the manager decide what to do with the given key combination.
   ModuleBase_Operation* anOperation = currentOperation();
-  bool isAccepted = false;
   switch (theEvent->key()) {
     case Qt::Key_Tab:
     case Qt::Key_Backtab:
@@ -650,6 +684,8 @@ bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent)
             aContext->HilightNextDetected(aView);
           else if ((theEvent->key() == Qt::Key_P))
             aContext->HilightPreviousDetected(aView);
+          aViewer->updateHighlight();
+          isAccepted = true;
         }
       }
     }
@@ -684,7 +720,22 @@ bool XGUI_OperationMgr::onKeyPressed(QObject *theObject, QKeyEvent* theEvent)
         ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
         ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();
         if (anActiveWgt)
-          isAccepted = anActiveWgt && anActiveWgt->processEscape();
+        {
+          isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEscape);
+          if (isAccepted) {
+            ModuleBase_OperationFeature* aFOperation =
+              dynamic_cast<ModuleBase_OperationFeature*>(currentOperation());
+            if (aFOperation)
+              aFOperation->setNeedToBeAborted(true);
+          }
+        }
+      }
+      if (!isAccepted)
+      {
+        XGUI_ActiveControlSelector* anActiveSelector =
+          XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector();
+        if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type())
+          isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionEscape);
       }
       // default Escape button functionality
       if (!isAccepted && aOperation) {
@@ -705,6 +756,8 @@ bool XGUI_OperationMgr::onProcessEnter(QObject* theObject)
   if (!aOperation)
     return isAccepted;
   ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+  if (!aPanel)
+    return isAccepted;
   // the next code is obsolete as we want to process Enter in property panel always
   // only property panel enter is processed in order to do not process enter in application dialogs
   //bool isPPChild = isChildObject(theObject, aPanel);
@@ -724,7 +777,7 @@ bool XGUI_OperationMgr::onProcessEnter(QObject* theObject)
     }
   }
   if (!isAborted) {
-    isAccepted = anActiveWgt && anActiveWgt->processEnter();
+    isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEnter);
     if (!isAccepted) {
       isAccepted =
         myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : "");
@@ -771,11 +824,18 @@ bool XGUI_OperationMgr::onProcessDelete(QObject* theObject)
       if (isPPChildObject) {
         anActiveWgt = aPanel->activeWidget();
         if (anActiveWgt) {
-          isAccepted = anActiveWgt->processDelete();
+          isAccepted = anActiveWgt->processAction(ActionDelete);
         }
       }
     }
   }
+  if (!isAccepted)
+  {
+    XGUI_ActiveControlSelector* anActiveSelector =
+      XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector();
+    if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type())
+      isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionDelete);
+  }
   if (!isAccepted) {
     // after widget, object browser and viewer should process delete
     /// other widgets such as line edit controls should not lead to
@@ -835,4 +895,15 @@ QMessageBox* XGUI_OperationMgr::createMessageBox(const QString& theMessage)
   aMessageBox->setEscapeButton(QMessageBox::No); // operation manager should process Esc key
 
   return aMessageBox;
-}
\ No newline at end of file
+}
+
+QMessageBox* XGUI_OperationMgr::createInformationBox(const QString& theMessage)
+{
+  QMessageBox * aMessageBox = new QMessageBox(QMessageBox::Question,
+    QObject::tr("Validate operation"), theMessage, QMessageBox::Ok,
+    qApp->activeWindow());
+  aMessageBox->setDefaultButton(QMessageBox::Ok);
+  aMessageBox->setEscapeButton(QMessageBox::No); // operation manager should process Esc key
+
+  return aMessageBox;
+}