Salome HOME
Update of pictures by ABA
[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
11 #include <ModuleBase_IPropertyPanel.h>
12 #include <ModuleBase_ModelWidget.h>
13 #include <ModuleBase_OperationFeature.h>
14
15 #include <ModelAPI_Attribute.h>
16 #include <ModelAPI_Session.h>
17 #include <ModelAPI_Validator.h>
18
19 #include <QLabel>
20 #include <QAction>
21 #include <QApplication>
22 #include <QDesktopWidget>
23 #include <QDialog>
24 #include <QCursor>
25 #include <QHBoxLayout>
26 #include <QLabel>
27
28 const QString INVALID_VALUE = "invalid_action";
29
30
31 XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent /*= 0*/)
32   : ModuleBase_IErrorMgr(theParent),
33     myErrorDialog(0),
34     myErrorLabel(0)
35 {
36
37 }
38
39 XGUI_ErrorMgr::~XGUI_ErrorMgr()
40 {
41
42 }
43
44 bool XGUI_ErrorMgr::canProcessClick(QAction* theAction, const FeaturePtr& theFeature)
45 {
46   QString aData = theAction->data().toString();
47
48   bool isActionEnabled = theAction->data() != INVALID_VALUE;
49
50   QString anError = getFeatureError(theFeature);
51   if (!isActionEnabled && !anError.isEmpty()) {
52     if (!myErrorDialog) {
53       myErrorDialog = new QDialog(QApplication::desktop(), Qt::Popup);
54       QHBoxLayout* aLay = new QHBoxLayout(myErrorDialog);
55       aLay->setContentsMargins(0, 0, 0, 0);
56
57       QFrame* aMarginWidget = new QFrame(myErrorDialog);
58       aMarginWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
59
60       aLay->addWidget(aMarginWidget);
61       QHBoxLayout* aMarginLay = new QHBoxLayout(aMarginWidget);
62       aMarginLay->setContentsMargins(4, 4, 4, 4);
63
64       myErrorLabel = new QLabel(aMarginWidget);
65       aMarginLay->addWidget(myErrorLabel);
66     }
67     myErrorLabel->setText(anError);
68     myErrorDialog->move(QCursor::pos());
69     myErrorDialog->show();
70   }
71   return isActionEnabled;
72 }
73
74 void XGUI_ErrorMgr::updateActionState(QAction* theAction, const FeaturePtr& theFeature,
75                                       const bool theEnabled)
76 {
77   bool isActionEnabled = theAction->data() != INVALID_VALUE;
78   if (theEnabled  != isActionEnabled) {
79     // update enable state of the button
80     theAction->setIcon(theEnabled ? QIcon(":pictures/button_ok.png"): QIcon(":pictures/button_ok_error.png"));
81     if (theEnabled)
82       theAction->setData("");
83     else
84       theAction->setData(INVALID_VALUE);
85   }
86
87   // update controls error information
88   QWidget* aWidget = myPropertyPanel->headerWidget();
89   if (theEnabled)
90     aWidget->setToolTip("");
91   else
92     aWidget->setToolTip(getFeatureError(theFeature));
93 }
94
95 const char* toString(ModelAPI_ExecState theExecState) 
96 {
97 #define TO_STRING(__NAME__) case __NAME__: return #__NAME__;
98   switch (theExecState) {
99   TO_STRING(ModelAPI_StateDone)
100   TO_STRING(ModelAPI_StateMustBeUpdated)
101   TO_STRING(ModelAPI_StateExecFailed)
102   TO_STRING(ModelAPI_StateInvalidArgument)
103   TO_STRING(ModelAPI_StateNothing)
104   default: return "Unknown ExecState.";
105   }
106 #undef TO_STRING
107 }
108
109 /*void XGUI_ErrorMgr::onValidationStateChanged()
110 {
111   XGUI_OperationMgr* anOperationMgr = dynamic_cast<XGUI_OperationMgr*>(sender());
112   if (!anOperationMgr)
113     return;
114   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
115                                                   (anOperationMgr->currentOperation());
116   if (!myPropertyPanel || !aFOperation)
117     return;
118
119   FeaturePtr aFeature = aFOperation->feature();
120   QString anError = getFeatureError(aFeature);
121
122   QWidget* aWidget = myPropertyPanel->headerWidget();
123   if (aWidget) {
124     aWidget->setToolTip(anError);
125     aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
126   }
127 }*/
128
129 QString XGUI_ErrorMgr::getFeatureError(const FeaturePtr& theFeature) const
130 {
131   QString anError;
132   // get feature
133   if (!theFeature.get() || !theFeature->data()->isValid())
134     return anError;
135
136   // set error indication
137   anError = QString::fromStdString(theFeature->error());
138   if (anError.isEmpty()) {
139     bool isDone = ( theFeature->data()->execState() == ModelAPI_StateDone
140                  || theFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
141     if (!isDone)
142       anError = toString(theFeature->data()->execState());
143   }
144
145   return anError;
146 }
147
148 void XGUI_ErrorMgr::onWidgetChanged()
149 {
150   static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
151
152   ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
153   if (!aModelWidget || !aModelWidget->feature().get())
154     return;
155
156   std::string anAttributeID = aModelWidget->attributeID();
157   AttributePtr anAttribute = aModelWidget->feature()->attribute(anAttributeID);
158   if (!anAttribute.get())
159     return;
160
161   std::string aValidatorID;
162   std::string anErrorMsg;
163   if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {
164     if (anErrorMsg.empty())
165       anErrorMsg = "unknown error.";
166     anErrorMsg = anAttributeID + " - " + aValidatorID + ": " + anErrorMsg;
167   }
168
169   QString anError = QString::fromStdString(anErrorMsg);
170   QList<QWidget*> aWidgetList = aModelWidget->getControls();
171   foreach(QWidget* aWidget, aWidgetList) {
172     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
173     // We won't set the effect to QLabels - it looks ugly
174     if (aLabel) continue;
175
176     // Get the original tool tip of the widget
177     QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
178     // Add the error message into the tool tip
179     if (!anError.isEmpty()) {
180       if (!aTTip.isEmpty())
181         aTTip.append('\n');
182       aTTip += "Errors:\n" + anError;
183     }
184     aWidget->setToolTip(aTTip);
185     //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
186   }
187 }