Salome HOME
1. Correction for perfomance problem by Apply button state update: do not listen...
[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, NULL);
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
60 void XGUI_ErrorMgr::updateActions(const FeaturePtr& theFeature)
61 {
62   //update Ok Action and header of property panel if the current operation started for the feature
63   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
64   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
65                                       (workshop()->operationMgr()->currentOperation());
66   if (aFOperation && aFOperation->feature() == theFeature) {
67     QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
68     
69     ModuleBase_ModelWidget* anActiveWidget = activeWidget();
70     bool isApplyEnabledByActiveWidget = false;
71     if (anActiveWidget)
72       isApplyEnabledByActiveWidget = anActiveWidget->getValueState() ==
73                                      ModuleBase_ModelWidget::ModifiedInPP;
74     QString anError = "";
75     QString aWidgetError = "";
76     if (!isApplyEnabledByActiveWidget) {
77       anError = myWorkshop->module()->getFeatureError(theFeature);
78       if (anActiveWidget)
79         aWidgetError = anActiveWidget->getError();
80       if (anError.isEmpty())
81         anError = aWidgetError;
82     }
83     updateActionState(anOkAction, anError);
84     updateToolTip(anActiveWidget, aWidgetError);
85
86 #ifdef DEBUG_ERROR_STATE
87     QString anInfo = ModuleBase_Tools::objectInfo(theFeature);
88
89     QString aResultInfo = QString("valid = %1, anError = %2, aWidgetError = %3")
90                           .arg(anError.isEmpty()).arg(anError).arg(aWidgetError);
91     qDebug(QString("XGUI_ErrorMgr::updateActions for %1, result: %2").arg(anInfo)
92                   .arg(aResultInfo).toStdString().c_str());
93 #endif
94   }
95 }
96
97 void XGUI_ErrorMgr::updateAcceptAllAction(const FeaturePtr& theFeature)
98 {
99   QString anError = myWorkshop->module()->getFeatureError(theFeature);
100   if (anError.isEmpty()) {
101     ModuleBase_ModelWidget* anActiveWidget = activeWidget();
102     if (anActiveWidget)
103       anError = anActiveWidget->getError();
104   }
105   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
106   if (workshop()->isFeatureOfNested(theFeature)) {
107     QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL);
108     bool anEnabled = anError.isEmpty();
109     anAcceptAllAction->setEnabled(anEnabled);
110     anAcceptAllAction->setToolTip(!anEnabled ? anError : myAcceptAllToolTip);
111   }
112 }
113
114 bool XGUI_ErrorMgr::isApplyEnabled() const
115 {
116   bool isEnabled = false;
117   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
118   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
119                                       (workshop()->operationMgr()->currentOperation());
120   if (aFOperation) {
121     QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
122     isEnabled = anOkAction && anOkAction->isEnabled();
123   }
124   return isEnabled;
125 }
126
127 void XGUI_ErrorMgr::updateActionState(QAction* theAction, const QString& theError)
128 {
129   bool anEnabled = theError.isEmpty();
130
131   theAction->setEnabled(anEnabled);
132   theAction->setToolTip(anEnabled ? myAcceptToolTip : theError);
133   // some operations have no property panel, so it is important to check that it is not null
134   if (myPropertyPanel) {
135     // update controls error information
136     QWidget* aWidget = myPropertyPanel->headerWidget();
137     if (aWidget)
138       aWidget->setToolTip(theError);
139   }
140 }
141 void XGUI_ErrorMgr::onWidgetChanged()
142 {
143   ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
144   if (!aModelWidget || !aModelWidget->feature().get())
145     return;
146
147   QString aWidgetError = aModelWidget->getError();
148   updateToolTip(aModelWidget, aWidgetError);
149 }
150
151 void XGUI_ErrorMgr::updateToolTip(ModuleBase_ModelWidget* theWidget,
152                                   const QString& theError)
153 {
154   if (!theWidget)
155     return;
156
157   QList<QWidget*> aWidgetList = theWidget->getControls();
158   foreach(QWidget* aWidget, aWidgetList) {
159     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
160     // We won't set the effect to QLabels - it looks ugly
161     if (aLabel) continue;
162
163     // Get the original tool tip of the widget
164     QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
165     // Add the error message into the tool tip
166     if (!theError.isEmpty()) {
167       if (!aTTip.isEmpty())
168         aTTip.append('\n');
169       aTTip += "Errors:\n" + theError;
170     }
171     aWidget->setToolTip(aTTip);
172     //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
173   }
174 }
175
176 XGUI_Workshop* XGUI_ErrorMgr::workshop() const
177 {
178   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
179   return aConnector->workshop();
180 }
181
182 ModuleBase_ModelWidget* XGUI_ErrorMgr::activeWidget() const
183 {
184   ModuleBase_ModelWidget* anActiveWidget = 0;
185
186   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
187                                       (workshop()->operationMgr()->currentOperation());
188   if (aFOperation) {
189     ModuleBase_IPropertyPanel* aPropertyPanel = aFOperation->propertyPanel();
190     if (aPropertyPanel) {
191       anActiveWidget = aPropertyPanel->activeWidget();
192     }
193   }
194   return anActiveWidget;
195 }
196