]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_ErrorMgr.cpp
Salome HOME
355c8d9a1b5df7882e040fa9d5a119bec19f27fb
[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 <ModelAPI_Attribute.h>
21 #include <ModelAPI_Session.h>
22 #include <ModelAPI_Validator.h>
23
24 #include <QLabel>
25 #include <QAction>
26 #include <QApplication>
27 #include <QDesktopWidget>
28 #include <QDialog>
29 #include <QCursor>
30 #include <QHBoxLayout>
31 #include <QLabel>
32
33 const QString INVALID_VALUE = "invalid_action";
34
35
36 XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent, ModuleBase_IWorkshop* theWorkshop)
37   : ModuleBase_IErrorMgr(theParent),
38     myErrorDialog(0),
39     myErrorLabel(0),
40     myWorkshop(theWorkshop)
41 {
42
43 }
44
45 XGUI_ErrorMgr::~XGUI_ErrorMgr()
46 {
47
48 }
49
50 void XGUI_ErrorMgr::updateActions(const FeaturePtr& theFeature)
51 {
52   QString anError = myWorkshop->module()->getFeatureError(theFeature);
53
54   //update Ok Action and header of property panel if the current operation started for the feature
55   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
56   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
57                                       (workshop()->operationMgr()->currentOperation());
58   if (aFOperation && aFOperation->feature() == theFeature) {
59     QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
60     updateActionState(anOkAction, theFeature);
61   }
62   //update AcceptAll action
63   if (workshop()->isFeatureOfNested(theFeature)) {
64     QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL);
65     bool anEnabled = anError.isEmpty();
66     anAcceptAllAction->setEnabled(anEnabled);
67     anAcceptAllAction->setToolTip(anError);
68   }
69 }
70
71 bool XGUI_ErrorMgr::canProcessClick(QAction* theAction, const FeaturePtr& theFeature)
72 {
73   QString anError = myWorkshop->module()->getFeatureError(theFeature);
74   bool isActionEnabled = anError.isEmpty();
75   if (!isActionEnabled && !anError.isEmpty()) {
76     if (!myErrorDialog) {
77       myErrorDialog = new QDialog(QApplication::desktop(), Qt::Popup);
78       QHBoxLayout* aLay = new QHBoxLayout(myErrorDialog);
79       aLay->setContentsMargins(0, 0, 0, 0);
80
81       QFrame* aMarginWidget = new QFrame(myErrorDialog);
82       aMarginWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
83
84       aLay->addWidget(aMarginWidget);
85       QHBoxLayout* aMarginLay = new QHBoxLayout(aMarginWidget);
86       aMarginLay->setContentsMargins(4, 4, 4, 4);
87
88       myErrorLabel = new QLabel(aMarginWidget);
89       aMarginLay->addWidget(myErrorLabel);
90     }
91     myErrorLabel->setText(anError);
92     myErrorDialog->move(QCursor::pos());
93     myErrorDialog->show();
94   }
95   return isActionEnabled;
96 }
97
98 void XGUI_ErrorMgr::updateActionState(QAction* theAction, const FeaturePtr& theFeature/*,
99                                       const bool theEnabled*/)
100 {
101   QString anError = myWorkshop->module()->getFeatureError(theFeature);
102   bool anEnabled = anError.isEmpty();
103
104   bool isActionEnabled = theAction->data() != INVALID_VALUE;
105   if (anEnabled  != isActionEnabled) {
106     // update enable state of the button
107     theAction->setIcon(anEnabled ? QIcon(":pictures/button_ok.png"): QIcon(":pictures/button_ok_error.png"));
108     if (anEnabled)
109       theAction->setData("");
110     else
111       theAction->setData(INVALID_VALUE);
112   }
113   // some operations have no property panel, so it is important to check that it is not null
114   if (myPropertyPanel) {
115     // update controls error information
116     QWidget* aWidget = myPropertyPanel->headerWidget();
117     if (aWidget)
118       aWidget->setToolTip(anError);
119   }
120 }
121
122 /*const char* toString(ModelAPI_ExecState theExecState) 
123 {
124 #define TO_STRING(__NAME__) case __NAME__: return #__NAME__;
125   switch (theExecState) {
126   TO_STRING(ModelAPI_StateDone)
127   TO_STRING(ModelAPI_StateMustBeUpdated)
128   TO_STRING(ModelAPI_StateExecFailed)
129   TO_STRING(ModelAPI_StateInvalidArgument)
130   TO_STRING(ModelAPI_StateNothing)
131   default: return "Unknown ExecState.";
132   }
133 #undef TO_STRING
134 }*/
135
136 /*void XGUI_ErrorMgr::onValidationStateChanged()
137 {
138   XGUI_OperationMgr* anOperationMgr = dynamic_cast<XGUI_OperationMgr*>(sender());
139   if (!anOperationMgr)
140     return;
141   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
142                                                   (anOperationMgr->currentOperation());
143   if (!myPropertyPanel || !aFOperation)
144     return;
145
146   FeaturePtr aFeature = aFOperation->feature();
147   QString anError = getFeatureError(aFeature);
148
149   QWidget* aWidget = myPropertyPanel->headerWidget();
150   if (aWidget) {
151     aWidget->setToolTip(anError);
152     aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
153   }
154 }*/
155
156 /*QString XGUI_ErrorMgr::getFeatureError(const FeaturePtr& theFeature) const
157 {
158   QString anError;
159   // get feature
160   if (!theFeature.get() || !theFeature->data()->isValid())
161     return anError;
162
163   // set error indication
164   anError = QString::fromStdString(theFeature->error());
165   if (anError.isEmpty()) {
166     bool isDone = ( theFeature->data()->execState() == ModelAPI_StateDone
167                  || theFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
168     if (!isDone)
169       anError = toString(theFeature->data()->execState());
170   }
171
172   return anError;
173 }*/
174
175 void XGUI_ErrorMgr::onWidgetChanged()
176 {
177   static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
178
179   ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
180   if (!aModelWidget || !aModelWidget->feature().get())
181     return;
182
183   std::string anAttributeID = aModelWidget->attributeID();
184   AttributePtr anAttribute = aModelWidget->feature()->attribute(anAttributeID);
185   if (!anAttribute.get())
186     return;
187
188   std::string aValidatorID;
189   std::string anErrorMsg;
190   if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {
191     if (anErrorMsg.empty())
192       anErrorMsg = "unknown error.";
193     anErrorMsg = anAttributeID + " - " + aValidatorID + ": " + anErrorMsg;
194   }
195
196   QString anError = QString::fromStdString(anErrorMsg);
197   QList<QWidget*> aWidgetList = aModelWidget->getControls();
198   foreach(QWidget* aWidget, aWidgetList) {
199     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
200     // We won't set the effect to QLabels - it looks ugly
201     if (aLabel) continue;
202
203     // Get the original tool tip of the widget
204     QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
205     // Add the error message into the tool tip
206     if (!anError.isEmpty()) {
207       if (!aTTip.isEmpty())
208         aTTip.append('\n');
209       aTTip += "Errors:\n" + anError;
210     }
211     aWidget->setToolTip(aTTip);
212     //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
213   }
214 }
215
216 XGUI_Workshop* XGUI_ErrorMgr::workshop() const
217 {
218   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
219   return aConnector->workshop();
220 }