Salome HOME
Improvement for key "Delete" processing: should be done only on possible objects...
[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     myAcceptAllToolTip(""),
46     myAcceptAllStatusTip(""),
47     myAcceptToolTip(""),
48     myAcceptStatusTip("")
49 {
50 }
51
52 XGUI_ErrorMgr::~XGUI_ErrorMgr()
53 {
54 }
55
56 void XGUI_ErrorMgr::updateActions(const FeaturePtr& theFeature)
57 {
58   //update Ok Action and header of property panel if the current operation started for the feature
59   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
60   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
61                                       (workshop()->operationMgr()->currentOperation());
62   if (aFOperation && aFOperation->feature() == theFeature) {
63     ModuleBase_ModelWidget* anActiveWidget = activeWidget();
64     bool isApplyEnabledByActiveWidget = false;
65     if (anActiveWidget)
66       isApplyEnabledByActiveWidget = anActiveWidget->getValueState() ==
67                                      ModuleBase_ModelWidget::ModifiedInPP;
68     QString anError = "";
69     QString aWidgetError = "";
70     if (!isApplyEnabledByActiveWidget) {
71       anError = myWorkshop->module()->getFeatureError(theFeature);
72       if (anActiveWidget)
73         aWidgetError = anActiveWidget->getError();
74       if (anError.isEmpty())
75         anError = aWidgetError;
76     }
77     updateAcceptActionState(anError);
78     updateToolTip(anActiveWidget, aWidgetError);
79     myWorkshop->setStatusBarMessage(anError);
80
81 #ifdef DEBUG_ERROR_STATE
82     QString anInfo = ModuleBase_Tools::objectInfo(theFeature);
83
84     QString aResultInfo = QString("valid = %1, anError = %2, aWidgetError = %3")
85                           .arg(anError.isEmpty()).arg(anError).arg(aWidgetError);
86     qDebug(QString("XGUI_ErrorMgr::updateActions for %1, result: %2").arg(anInfo)
87                   .arg(aResultInfo).toStdString().c_str());
88 #endif
89   }
90 }
91
92 void XGUI_ErrorMgr::updateAcceptAllAction(const FeaturePtr& theFeature)
93 {
94   if (myAcceptAllToolTip.isEmpty() && myAcceptToolTip.isEmpty())
95     storeInitialActionValues();
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     anAcceptAllAction->setStatusTip(!anEnabled ? anError : myAcceptAllStatusTip);
110   }
111 }
112
113 bool XGUI_ErrorMgr::isApplyEnabled() const
114 {
115   bool isEnabled = false;
116   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
117   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
118                                       (workshop()->operationMgr()->currentOperation());
119   if (aFOperation) {
120     QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
121     isEnabled = anOkAction && anOkAction->isEnabled();
122   }
123   return isEnabled;
124 }
125
126 void XGUI_ErrorMgr::storeInitialActionValues()
127 {
128   ModuleBase_ModelWidget* anActiveWidget = activeWidget();
129   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
130   QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
131   myAcceptAllToolTip = anAcceptAllAction->toolTip();
132   myAcceptAllStatusTip = anAcceptAllAction->statusTip();
133
134   QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
135   myAcceptToolTip = anOkAction->toolTip();
136   myAcceptStatusTip = anOkAction->toolTip();
137 }
138
139 void XGUI_ErrorMgr::updateAcceptActionState(const QString& theError)
140 {
141   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
142   QAction* anAcceptAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
143
144   if (myAcceptAllToolTip.isEmpty() && myAcceptToolTip.isEmpty())
145     storeInitialActionValues();
146
147   bool anEnabled = theError.isEmpty();
148   anAcceptAction->setEnabled(anEnabled);
149   anAcceptAction->setToolTip(anEnabled ? myAcceptToolTip : theError);
150   anAcceptAction->setStatusTip(anEnabled ? myAcceptStatusTip : theError);
151   // some operations have no property panel, so it is important to check that it is not null
152   if (myPropertyPanel) {
153     // update controls error information
154     QWidget* aWidget = myPropertyPanel->headerWidget();
155     if (aWidget)
156       aWidget->setToolTip(theError);
157   }
158 }
159 void XGUI_ErrorMgr::onWidgetChanged()
160 {
161   ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
162   if (!aModelWidget || !aModelWidget->feature().get())
163     return;
164
165   QString aWidgetError = aModelWidget->getError();
166   updateToolTip(aModelWidget, aWidgetError);
167 }
168
169 void XGUI_ErrorMgr::updateToolTip(ModuleBase_ModelWidget* theWidget,
170                                   const QString& theError)
171 {
172   if (!theWidget)
173     return;
174
175   QList<QWidget*> aWidgetList = theWidget->getControls();
176   foreach(QWidget* aWidget, aWidgetList) {
177     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
178     // We won't set the effect to QLabels - it looks ugly
179     if (aLabel) continue;
180
181     // Get the original tool tip of the widget
182     QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
183     // Add the error message into the tool tip
184     if (!theError.isEmpty()) {
185       if (!aTTip.isEmpty())
186         aTTip.append('\n');
187       aTTip += "Errors:\n" + theError;
188     }
189     aWidget->setToolTip(aTTip);
190     //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
191   }
192 }
193
194 XGUI_Workshop* XGUI_ErrorMgr::workshop() const
195 {
196   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
197   return aConnector->workshop();
198 }
199
200 ModuleBase_ModelWidget* XGUI_ErrorMgr::activeWidget() const
201 {
202   ModuleBase_ModelWidget* anActiveWidget = 0;
203
204   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
205                                       (workshop()->operationMgr()->currentOperation());
206   if (aFOperation) {
207     ModuleBase_IPropertyPanel* aPropertyPanel = aFOperation->propertyPanel();
208     if (aPropertyPanel) {
209       anActiveWidget = aPropertyPanel->activeWidget();
210     }
211   }
212   return anActiveWidget;
213 }
214