]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Error management -- Introduce ErrorMgr
authorspo <sergey.pokhodenko@opencascade.com>
Wed, 22 Jul 2015 11:10:54 +0000 (14:10 +0300)
committerspo <sergey.pokhodenko@opencascade.com>
Wed, 5 Aug 2015 14:34:04 +0000 (17:34 +0300)
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_IErrorMgr.cpp [new file with mode: 0644]
src/ModuleBase/ModuleBase_IErrorMgr.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_IPropertyPanel.h
src/XGUI/CMakeLists.txt
src/XGUI/XGUI_ErrorMgr.cpp [new file with mode: 0644]
src/XGUI/XGUI_ErrorMgr.h [new file with mode: 0644]
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_PropertyPanel.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 54fc7c1b1107f81bcb1ac7d5710c9bf8393e9c78..5e76d8985043eef36cecc2c057fd6f5a6a686f10 100644 (file)
@@ -12,6 +12,7 @@ SET(PROJECT_HEADERS
   ModuleBase_FilterFactory.h
   ModuleBase_FilterValidated.h
   ModuleBase_IDocumentDataModel.h
+  ModuleBase_IErrorMgr.h
   ModuleBase_IModule.h
   ModuleBase_IPrefMgr.h
   ModuleBase_IPropertyPanel.h
@@ -59,6 +60,7 @@ SET(PROJECT_SOURCES
   ModuleBase_FilterFactory.cpp
   ModuleBase_FilterValidated.cpp
   ModuleBase_IDocumentDataModel.cpp
+  ModuleBase_IErrorMgr.cpp
   ModuleBase_IModule.cpp
   ModuleBase_IPrefMgr.cpp
   ModuleBase_IPropertyPanel.cpp
diff --git a/src/ModuleBase/ModuleBase_IErrorMgr.cpp b/src/ModuleBase/ModuleBase_IErrorMgr.cpp
new file mode 100644 (file)
index 0000000..1d1c8a8
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModuleBase_ErrorMgr.cpp
+// Created:     22 July 2015
+// Author:      Sergey POKHODENKO
+
+#include "ModuleBase_IErrorMgr.h"
+
+#include "ModuleBase_IPropertyPanel.h"
+#include "ModuleBase_ModelWidget.h"
+
+ModuleBase_IErrorMgr::ModuleBase_IErrorMgr(QObject* theParent /*= 0*/)
+  : QObject(theParent)
+  , myPropertyPanel(NULL)
+{
+
+}
+
+ModuleBase_IErrorMgr::~ModuleBase_IErrorMgr()
+{
+
+}
+
+void ModuleBase_IErrorMgr::setPropertyPanel(ModuleBase_IPropertyPanel* theProp)
+{
+  myPropertyPanel = theProp; 
+
+  if (myPropertyPanel) {
+    foreach(const ModuleBase_ModelWidget* aWgt, myPropertyPanel->modelWidgets()) {
+      connect(aWgt, SIGNAL(afterValuesChanged()), this, SLOT(onWidgetChanged()));
+      connect(aWgt, SIGNAL(afterValuesRestored()), this, SLOT(onWidgetChanged()));
+    }
+  }
+}
diff --git a/src/ModuleBase/ModuleBase_IErrorMgr.h b/src/ModuleBase/ModuleBase_IErrorMgr.h
new file mode 100644 (file)
index 0000000..c459183
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        ModuleBase_IErrorMgr.h
+// Created:     22 July 2015
+// Author:      Sergey POKHODENKO
+
+#ifndef ModuleBase_IErrorMgr_H
+#define ModuleBase_IErrorMgr_H
+
+#include "ModuleBase.h"
+#include <QObject>
+
+class ModuleBase_IPropertyPanel;
+
+class MODULEBASE_EXPORT ModuleBase_IErrorMgr : public QObject
+{
+  Q_OBJECT
+public:
+  /// Default constructor
+  ModuleBase_IErrorMgr(QObject* theParent = 0);
+  /// Virtual destructor
+  virtual ~ModuleBase_IErrorMgr();
+
+  /// \brief Set property pane to the operation
+  /// \param theProp a property panel instance
+  virtual void setPropertyPanel(ModuleBase_IPropertyPanel* theProp);
+
+  /// \return Currently installed property panel
+  ModuleBase_IPropertyPanel* propertyPanel() const { return myPropertyPanel; }
+
+public slots:
+  /// SLOT, that is called after the operation is validated and feature validation errors have changed.
+  virtual void onValidationStateChanged() = 0;
+
+protected slots:
+  /// Process values changed event for processing feature attribute validation errors.
+  virtual void onWidgetChanged() = 0;
+
+protected:
+  /// Access to property panel
+  ModuleBase_IPropertyPanel* myPropertyPanel;
+};
+
+#endif // ModuleBase_IErrorMgr_H
\ No newline at end of file
index 12c96548e6a11cd27ed5b1be4152303d9a3b63dd..516fdf3a6430e374fae22b2c022e58e6cb2dc8b0 100644 (file)
@@ -29,6 +29,9 @@ public:
   /// \param theParent is a parent of the property panel
   ModuleBase_IPropertyPanel(QWidget* theParent);
 
+  /// Returns header widget
+  virtual QWidget* headerWidget() const = 0;
+
   /// Returns currently active widget
   virtual ModuleBase_ModelWidget* activeWidget() const = 0;
 
index 1cc72f76c5c777dfa905e0049c522fd7836893fb..704b5ea05eba5c0437e012945bed97d60970b880 100644 (file)
@@ -12,6 +12,7 @@ SET(PROJECT_HEADERS
        XGUI_DataModel.h
        XGUI_Displayer.h
        XGUI_ErrorDialog.h
+       XGUI_ErrorMgr.h
        XGUI_HistoryMenu.h
        XGUI_ModuleConnector.h
        XGUI_ObjectsBrowser.h
@@ -39,6 +40,7 @@ SET(PROJECT_SOURCES
        XGUI_DataModel.cpp
        XGUI_Displayer.cpp
        XGUI_ErrorDialog.cpp
+       XGUI_ErrorMgr.cpp
        XGUI_HistoryMenu.cpp
        XGUI_ModuleConnector.cpp
        XGUI_ObjectsBrowser.cpp
diff --git a/src/XGUI/XGUI_ErrorMgr.cpp b/src/XGUI/XGUI_ErrorMgr.cpp
new file mode 100644 (file)
index 0000000..f46a929
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        XGUI_ErrorMgr.cpp
+// Created:     22 July 2015
+// Author:      Sergey POKHODENKO
+
+#include "XGUI_ErrorMgr.h"
+
+#include "XGUI_OperationMgr.h"
+
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ModelWidget.h>
+
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <QLabel>
+
+XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent /*= 0*/)
+  : ModuleBase_IErrorMgr(theParent)
+{
+
+}
+
+XGUI_ErrorMgr::~XGUI_ErrorMgr()
+{
+
+}
+
+const char* toString(ModelAPI_ExecState theExecState) 
+{
+#define TO_STRING(__NAME__) case __NAME__: return #__NAME__;
+  switch (theExecState) {
+  TO_STRING(ModelAPI_StateDone)
+  TO_STRING(ModelAPI_StateMustBeUpdated)
+  TO_STRING(ModelAPI_StateExecFailed)
+  TO_STRING(ModelAPI_StateInvalidArgument)
+  TO_STRING(ModelAPI_StateNothing)
+  default: "Unknown ExecState.";
+  }
+#undef TO_STRING
+}
+
+void XGUI_ErrorMgr::onValidationStateChanged()
+{
+  XGUI_OperationMgr* anOperationMgr = dynamic_cast<XGUI_OperationMgr*>(sender());
+  if (!anOperationMgr || !anOperationMgr->currentOperation())
+    return;
+
+  if (!myPropertyPanel)
+    return;
+
+  // get feature
+  FeaturePtr aFeature = anOperationMgr->currentOperation()->feature();
+  if (!aFeature.get())
+    return;
+
+  // set error indication
+  QString anError = QString::fromStdString(aFeature->error());
+  if (anError.isEmpty()) {
+    bool isDone = ( aFeature->data()->execState() == ModelAPI_StateDone
+                 || aFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
+    if (!isDone)
+      anError = toString(aFeature->data()->execState());
+  }
+
+  QWidget* aWidget = myPropertyPanel->headerWidget();
+  if (aWidget) {
+    aWidget->setToolTip(anError);
+    aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
+  }
+}
+
+void XGUI_ErrorMgr::onWidgetChanged()
+{
+  static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+
+  ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
+  if (!aModelWidget || !aModelWidget->feature().get())
+    return;
+
+  std::string anAttributeID = aModelWidget->attributeID();
+  AttributePtr anAttribute = aModelWidget->feature()->attribute(anAttributeID);
+  if (!anAttribute.get())
+    return;
+
+  std::string aValidatorID;
+  std::string anErrorMsg;
+  if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {
+    if (anErrorMsg.empty())
+      anErrorMsg = "unknown error.";
+    anErrorMsg = "Attribute \"" + anAttributeID + "\" invalidated by \"" + aValidatorID + "\" with error: " + anErrorMsg;
+  }
+
+  QString anError = QString::fromStdString(anErrorMsg);
+  QList<QWidget*> aWidgetList = aModelWidget->getControls();
+  foreach(QWidget* aWidget, aWidgetList) {
+    QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
+    // We won't set the effect to QLabels - it looks ugly
+    if (aLabel) continue;
+
+    // Get the original tool tip of the widget
+    QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
+    // Add the error message into the tool tip
+    if (!anError.isEmpty()) {
+      if (!aTTip.isEmpty())
+        aTTip.append('\n');
+      aTTip += "Errors:\n" + anError;
+    }
+    aWidget->setToolTip(aTTip);
+    aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
+  }
+}
diff --git a/src/XGUI/XGUI_ErrorMgr.h b/src/XGUI/XGUI_ErrorMgr.h
new file mode 100644 (file)
index 0000000..3664479
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        XGUI_ErrorMgr.h
+// Created:     22 July 2015
+// Author:      Sergey POKHODENKO
+
+#ifndef XGUI_ErrorMgr_H
+#define XGUI_ErrorMgr_H
+
+#include "XGUI.h"
+
+#include <ModuleBase_IErrorMgr.h>
+
+class XGUI_EXPORT XGUI_ErrorMgr : public ModuleBase_IErrorMgr
+{
+  Q_OBJECT
+public:
+  XGUI_ErrorMgr(QObject* theParent = 0);
+  /// Virtual destructor
+  virtual ~XGUI_ErrorMgr();
+
+public slots:
+  /// Reimplemented from ModuleBase_ErrorMgr::onValidationStateChanged().
+  virtual void onValidationStateChanged();
+
+protected slots:
+  /// Reimplemented from ModuleBase_ErrorMgr::onWidgetChanged().
+  virtual void onWidgetChanged();
+};
+
+#endif // XGUI_ErrorMgr_H
\ No newline at end of file
index 0a9c7189e20ec4b99de9dcf091d517d7fbc0680d..4760cffb5a5fe2c8b32bd739a84306e51d5d2dbd 100644 (file)
@@ -56,6 +56,8 @@ XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent)
   ModuleBase_Tools::zeroMargins(aBtnLay);
   aMainLayout->addWidget(aFrm, aPanelRow++, kPanelColumn);
 
+  myHeaderWidget = aFrm;
+
   QStringList aBtnNames;
   aBtnNames << QString(PROP_PANEL_HELP)
             << QString(PROP_PANEL_OK)
index 6a982c1c66e8c6795fec689ba8c426e20f9d57ef..9ba7754edaca4a4ae7ee9d2ee048fca2c6237f03 100644 (file)
@@ -50,6 +50,9 @@ Q_OBJECT
 
   virtual ~XGUI_PropertyPanel();
 
+  /// Returns header widget
+  virtual QWidget* headerWidget() const { return myHeaderWidget; }
+
   /// Returns main widget of the property panel, which children will be created
   /// by WidgetFactory using the XML definition
   ModuleBase_PageBase* contentWidget();
@@ -108,6 +111,9 @@ Q_OBJECT
   */
   virtual void activateWidget(ModuleBase_ModelWidget* theWidget);
 
+ protected:
+  QWidget* myHeaderWidget;
+
  private:
   ModuleBase_PageWidget* myPanelPage;
   QList<ModuleBase_ModelWidget*> myWidgets;
index 95db6cca3be195be5c7305ad586f47b054b6fe47..294452c6cc6465b6b73776bd0813170072958a6c 100644 (file)
@@ -8,6 +8,7 @@
 #include "XGUI_ContextMenuMgr.h"
 #include "XGUI_Displayer.h"
 #include "XGUI_ErrorDialog.h"
+#include "XGUI_ErrorMgr.h"
 #include "XGUI_ModuleConnector.h"
 #include "XGUI_ObjectsBrowser.h"
 #include "XGUI_OperationMgr.h"
@@ -125,6 +126,7 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
   myOperationMgr = new XGUI_OperationMgr(this, 0);
   myActionsMgr = new XGUI_ActionsMgr(this);
   myErrorDlg = new XGUI_ErrorDialog(QApplication::desktop());
+  myErrorMgr = new XGUI_ErrorMgr(this);
   myContextMenuMgr = new XGUI_ContextMenuMgr(this);
   connect(myContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), this,
           SLOT(onContextMenuCommand(const QString&, bool)));
@@ -150,6 +152,9 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
           SLOT(onOperationCommitted(ModuleBase_Operation*)));
   connect(myOperationMgr, SIGNAL(operationAborted(ModuleBase_Operation*)), 
           SLOT(onOperationAborted(ModuleBase_Operation*)));
+  connect(myOperationMgr, SIGNAL(validationStateChanged(bool)), 
+          myErrorMgr, SLOT(onValidationStateChanged()));
+
   if (myMainWindow)
     connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit()));
   connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&)));
@@ -483,6 +488,8 @@ void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
   myModule->propertyPanelDefined(theOperation);
 
   myPropertyPanel->setWindowTitle(theOperation->getDescription()->description());
+
+  myErrorMgr->setPropertyPanel(myPropertyPanel);
 }
 
 /*
index c0ecf8d730bfcf06c163589dc055795764b37563..aa7dfaa767f57d920f379fc750e61220ea033661 100644 (file)
@@ -24,6 +24,7 @@ class XGUI_ActionsMgr;
 class XGUI_ContextMenuMgr;
 class XGUI_Displayer;
 class XGUI_ErrorDialog;
+class XGUI_ErrorMgr;
 class XGUI_ModuleConnector;
 class XGUI_ObjectsBrowser;
 class XGUI_OperationMgr;
@@ -399,6 +400,7 @@ private:
 private:
   AppElements_MainWindow* myMainWindow;
   ModuleBase_IModule* myModule;
+  XGUI_ErrorMgr* myErrorMgr;
   XGUI_ObjectsBrowser* myObjectBrowser;
   XGUI_PropertyPanel* myPropertyPanel;
   XGUI_SelectionMgr* mySelector;