1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: XGUI_ErrorMgr.cpp
4 // Created: 22 July 2015
5 // Author: Sergey POKHODENKO
7 #include "XGUI_ErrorMgr.h"
9 #include "XGUI_OperationMgr.h"
10 #include "XGUI_ModuleConnector.h"
11 #include "XGUI_Workshop.h"
12 #include "XGUI_ActionsMgr.h"
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>
20 #include <ModelAPI_Attribute.h>
21 #include <ModelAPI_Session.h>
22 #include <ModelAPI_Validator.h>
26 #include <QApplication>
27 #include <QDesktopWidget>
30 #include <QHBoxLayout>
33 const QString INVALID_VALUE = "invalid_action";
36 XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent, ModuleBase_IWorkshop* theWorkshop)
37 : ModuleBase_IErrorMgr(theParent),
40 myWorkshop(theWorkshop)
45 XGUI_ErrorMgr::~XGUI_ErrorMgr()
50 void XGUI_ErrorMgr::updateActions(const FeaturePtr& theFeature)
52 QString anError = myWorkshop->module()->getFeatureError(theFeature);
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);
64 void XGUI_ErrorMgr::updateAcceptAllAction(const FeaturePtr& theFeature)
66 QString anError = myWorkshop->module()->getFeatureError(theFeature);
68 XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
69 if (workshop()->isFeatureOfNested(theFeature)) {
70 QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL);
71 bool anEnabled = anError.isEmpty();
72 anAcceptAllAction->setEnabled(anEnabled);
73 anAcceptAllAction->setToolTip(anError);
77 bool XGUI_ErrorMgr::canProcessClick(QAction* theAction, const FeaturePtr& theFeature)
79 QString anError = myWorkshop->module()->getFeatureError(theFeature);
80 bool isActionEnabled = anError.isEmpty();
81 if (!isActionEnabled && !anError.isEmpty()) {
83 myErrorDialog = new QDialog(QApplication::desktop(), Qt::Popup);
84 QHBoxLayout* aLay = new QHBoxLayout(myErrorDialog);
85 aLay->setContentsMargins(0, 0, 0, 0);
87 QFrame* aMarginWidget = new QFrame(myErrorDialog);
88 aMarginWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
90 aLay->addWidget(aMarginWidget);
91 QHBoxLayout* aMarginLay = new QHBoxLayout(aMarginWidget);
92 aMarginLay->setContentsMargins(4, 4, 4, 4);
94 myErrorLabel = new QLabel(aMarginWidget);
95 aMarginLay->addWidget(myErrorLabel);
97 myErrorLabel->setText(anError);
98 myErrorDialog->move(QCursor::pos());
99 myErrorDialog->show();
101 return isActionEnabled;
104 void XGUI_ErrorMgr::updateActionState(QAction* theAction, const FeaturePtr& theFeature/*,
105 const bool theEnabled*/)
107 QString anError = myWorkshop->module()->getFeatureError(theFeature);
108 bool anEnabled = anError.isEmpty();
110 bool isActionEnabled = theAction->data() != INVALID_VALUE;
111 if (anEnabled != isActionEnabled) {
112 // update enable state of the button
113 theAction->setIcon(anEnabled ? QIcon(":pictures/button_ok.png"): QIcon(":pictures/button_ok_error.png"));
115 theAction->setData("");
117 theAction->setData(INVALID_VALUE);
119 // some operations have no property panel, so it is important to check that it is not null
120 if (myPropertyPanel) {
121 // update controls error information
122 QWidget* aWidget = myPropertyPanel->headerWidget();
124 aWidget->setToolTip(anError);
128 /*const char* toString(ModelAPI_ExecState theExecState)
130 #define TO_STRING(__NAME__) case __NAME__: return #__NAME__;
131 switch (theExecState) {
132 TO_STRING(ModelAPI_StateDone)
133 TO_STRING(ModelAPI_StateMustBeUpdated)
134 TO_STRING(ModelAPI_StateExecFailed)
135 TO_STRING(ModelAPI_StateInvalidArgument)
136 TO_STRING(ModelAPI_StateNothing)
137 default: return "Unknown ExecState.";
142 /*void XGUI_ErrorMgr::onValidationStateChanged()
144 XGUI_OperationMgr* anOperationMgr = dynamic_cast<XGUI_OperationMgr*>(sender());
147 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
148 (anOperationMgr->currentOperation());
149 if (!myPropertyPanel || !aFOperation)
152 FeaturePtr aFeature = aFOperation->feature();
153 QString anError = getFeatureError(aFeature);
155 QWidget* aWidget = myPropertyPanel->headerWidget();
157 aWidget->setToolTip(anError);
158 aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
162 /*QString XGUI_ErrorMgr::getFeatureError(const FeaturePtr& theFeature) const
166 if (!theFeature.get() || !theFeature->data()->isValid())
169 // set error indication
170 anError = QString::fromStdString(theFeature->error());
171 if (anError.isEmpty()) {
172 bool isDone = ( theFeature->data()->execState() == ModelAPI_StateDone
173 || theFeature->data()->execState() == ModelAPI_StateMustBeUpdated );
175 anError = toString(theFeature->data()->execState());
181 void XGUI_ErrorMgr::onWidgetChanged()
183 static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
185 ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
186 if (!aModelWidget || !aModelWidget->feature().get())
189 std::string anAttributeID = aModelWidget->attributeID();
190 AttributePtr anAttribute = aModelWidget->feature()->attribute(anAttributeID);
191 if (!anAttribute.get())
194 std::string aValidatorID;
195 std::string anErrorMsg;
196 if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {
197 if (anErrorMsg.empty())
198 anErrorMsg = "unknown error.";
199 anErrorMsg = anAttributeID + " - " + aValidatorID + ": " + anErrorMsg;
202 QString anError = QString::fromStdString(anErrorMsg);
203 QList<QWidget*> aWidgetList = aModelWidget->getControls();
204 foreach(QWidget* aWidget, aWidgetList) {
205 QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
206 // We won't set the effect to QLabels - it looks ugly
207 if (aLabel) continue;
209 // Get the original tool tip of the widget
210 QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
211 // Add the error message into the tool tip
212 if (!anError.isEmpty()) {
213 if (!aTTip.isEmpty())
215 aTTip += "Errors:\n" + anError;
217 aWidget->setToolTip(aTTip);
218 //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
222 XGUI_Workshop* XGUI_ErrorMgr::workshop() const
224 XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
225 return aConnector->workshop();