Salome HOME
79a7c1ae0a27983326f7bb640b466b0b8789f390
[modules/shaper.git] / src / XGUI / XGUI_ErrorMgr.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        XGUI_ErrorMgr.cpp
4 // Created:     22 July 2015
5 // Author:      Sergey POKHODENKO
6
7 #include "XGUI_ErrorMgr.h"
8
9 #include "XGUI_OperationMgr.h"
10 #include "XGUI_ModuleConnector.h"
11 #include "XGUI_Workshop.h"
12 #include "XGUI_ActionsMgr.h"
13
14 #include <ModuleBase_IPropertyPanel.h>
15 #include <ModuleBase_IWorkshop.h>
16 #include <ModuleBase_IModule.h>
17 #include <ModuleBase_ModelWidget.h>
18 #include <ModuleBase_OperationFeature.h>
19
20 #include <ModuleBase_Tools.h>
21 #include <QDebug>
22
23 #include <ModelAPI_Attribute.h>
24 #include <ModelAPI_Session.h>
25 #include <ModelAPI_Validator.h>
26
27 #include <QLabel>
28 #include <QAction>
29 #include <QApplication>
30 #include <QDesktopWidget>
31 #include <QDialog>
32 #include <QCursor>
33 #include <QHBoxLayout>
34 #include <QLabel>
35
36 const QString INVALID_VALUE = "invalid_action";
37
38 //#define DEBUG_ERROR_STATE
39
40 XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent, ModuleBase_IWorkshop* theWorkshop)
41   : ModuleBase_IErrorMgr(theParent),
42     myErrorDialog(0),
43     myErrorLabel(0),
44     myWorkshop(theWorkshop)
45 {
46   ModuleBase_ModelWidget* anActiveWidget = activeWidget();
47   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
48   QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
49   myAcceptAllToolTip = anAcceptAllAction->toolTip();
50
51   QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
52   myAcceptToolTip = anOkAction->toolTip();
53 }
54
55 XGUI_ErrorMgr::~XGUI_ErrorMgr()
56 {
57 }
58
59 void XGUI_ErrorMgr::updateActions(const FeaturePtr& theFeature)
60 {
61   //update Ok Action and header of property panel if the current operation started for the feature
62   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
63   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
64                                       (workshop()->operationMgr()->currentOperation());
65   if (aFOperation && aFOperation->feature() == theFeature) {
66     ModuleBase_ModelWidget* anActiveWidget = activeWidget();
67     bool isApplyEnabledByActiveWidget = false;
68     if (anActiveWidget)
69       isApplyEnabledByActiveWidget = anActiveWidget->getValueState() ==
70                                      ModuleBase_ModelWidget::ModifiedInPP;
71     QString anError = "";
72     QString aWidgetError = "";
73     if (!isApplyEnabledByActiveWidget) {
74       anError = myWorkshop->module()->getFeatureError(theFeature);
75       if (anActiveWidget)
76         aWidgetError = anActiveWidget->getError();
77       if (anError.isEmpty())
78         anError = aWidgetError;
79     }
80     updateAcceptActionState(anError);
81     updateToolTip(anActiveWidget, aWidgetError);
82     myWorkshop->setStatusBarMessage(anError);
83
84 #ifdef DEBUG_ERROR_STATE
85     QString anInfo = ModuleBase_Tools::objectInfo(theFeature);
86
87     QString aResultInfo = QString("valid = %1, anError = %2, aWidgetError = %3")
88                           .arg(anError.isEmpty()).arg(anError).arg(aWidgetError);
89     qDebug(QString("XGUI_ErrorMgr::updateActions for %1, result: %2").arg(anInfo)
90                   .arg(aResultInfo).toStdString().c_str());
91 #endif
92   }
93 }
94
95 void XGUI_ErrorMgr::updateAcceptAllAction(const FeaturePtr& theFeature)
96 {
97   QString anError = myWorkshop->module()->getFeatureError(theFeature);
98   if (anError.isEmpty()) {
99     ModuleBase_ModelWidget* anActiveWidget = activeWidget();
100     if (anActiveWidget)
101       anError = anActiveWidget->getError();
102   }
103   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
104   if (workshop()->isFeatureOfNested(theFeature)) {
105     QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
106     bool anEnabled = anError.isEmpty();
107     anAcceptAllAction->setEnabled(anEnabled);
108     anAcceptAllAction->setToolTip(!anEnabled ? anError : myAcceptAllToolTip);
109   }
110 }
111
112 bool XGUI_ErrorMgr::isApplyEnabled() const
113 {
114   bool isEnabled = false;
115   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
116   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
117                                       (workshop()->operationMgr()->currentOperation());
118   if (aFOperation) {
119     QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
120     isEnabled = anOkAction && anOkAction->isEnabled();
121   }
122   return isEnabled;
123 }
124
125 void XGUI_ErrorMgr::updateAcceptActionState(const QString& theError)
126 {
127   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
128   QAction* anAcceptAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
129
130   bool anEnabled = theError.isEmpty();
131
132   anAcceptAction->setEnabled(anEnabled);
133   anAcceptAction->setToolTip(anEnabled ? myAcceptToolTip : theError);
134   // some operations have no property panel, so it is important to check that it is not null
135   if (myPropertyPanel) {
136     // update controls error information
137     QWidget* aWidget = myPropertyPanel->headerWidget();
138     if (aWidget)
139       aWidget->setToolTip(theError);
140   }
141 }
142 void XGUI_ErrorMgr::onWidgetChanged()
143 {
144   ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
145   if (!aModelWidget || !aModelWidget->feature().get())
146     return;
147
148   QString aWidgetError = aModelWidget->getError();
149   updateToolTip(aModelWidget, aWidgetError);
150 }
151
152 void XGUI_ErrorMgr::updateToolTip(ModuleBase_ModelWidget* theWidget,
153                                   const QString& theError)
154 {
155   if (!theWidget)
156     return;
157
158   QList<QWidget*> aWidgetList = theWidget->getControls();
159   foreach(QWidget* aWidget, aWidgetList) {
160     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
161     // We won't set the effect to QLabels - it looks ugly
162     if (aLabel) continue;
163
164     // Get the original tool tip of the widget
165     QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
166     // Add the error message into the tool tip
167     if (!theError.isEmpty()) {
168       if (!aTTip.isEmpty())
169         aTTip.append('\n');
170       aTTip += "Errors:\n" + theError;
171     }
172     aWidget->setToolTip(aTTip);
173     //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
174   }
175 }
176
177 XGUI_Workshop* XGUI_ErrorMgr::workshop() const
178 {
179   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
180   return aConnector->workshop();
181 }
182
183 ModuleBase_ModelWidget* XGUI_ErrorMgr::activeWidget() const
184 {
185   ModuleBase_ModelWidget* anActiveWidget = 0;
186
187   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
188                                       (workshop()->operationMgr()->currentOperation());
189   if (aFOperation) {
190     ModuleBase_IPropertyPanel* aPropertyPanel = aFOperation->propertyPanel();
191     if (aPropertyPanel) {
192       anActiveWidget = aPropertyPanel->activeWidget();
193     }
194   }
195   return anActiveWidget;
196 }
197