Salome HOME
#1721 Selecting arcs in mirror constraint is too long and removes other edges
[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 = "";
98   /// to allow the module have the button always enabled
99   bool isActionStateEnabled = myWorkshop->module()->isActionEnableStateFixed(XGUI_ActionsMgr::AcceptAll);
100   if (!isActionStateEnabled) {
101     anError = myWorkshop->module()->getFeatureError(theFeature);
102     if (anError.isEmpty()) {
103       ModuleBase_ModelWidget* anActiveWidget = activeWidget();
104       if (anActiveWidget)
105         anError = anActiveWidget->getError();
106     }
107   }
108   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
109   if (workshop()->isFeatureOfNested(theFeature)) {
110     QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
111     bool anEnabled = anError.isEmpty();
112     anAcceptAllAction->setEnabled(anEnabled);
113     anAcceptAllAction->setToolTip(!anEnabled ? anError : myAcceptAllToolTip);
114     anAcceptAllAction->setStatusTip(!anEnabled ? anError : myAcceptAllStatusTip);
115   }
116 }
117
118 bool XGUI_ErrorMgr::isApplyEnabled() const
119 {
120   bool isEnabled = false;
121   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
122   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
123                                       (workshop()->operationMgr()->currentOperation());
124   if (aFOperation) {
125     QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
126     isEnabled = anOkAction && anOkAction->isEnabled();
127   }
128   return isEnabled;
129 }
130
131 void XGUI_ErrorMgr::storeInitialActionValues()
132 {
133   ModuleBase_ModelWidget* anActiveWidget = activeWidget();
134   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
135   QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
136   myAcceptAllToolTip = anAcceptAllAction->toolTip();
137   myAcceptAllStatusTip = anAcceptAllAction->statusTip();
138
139   QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
140   myAcceptToolTip = anOkAction->toolTip();
141   myAcceptStatusTip = anOkAction->toolTip();
142 }
143
144 void XGUI_ErrorMgr::updateAcceptActionState(const QString& theError)
145 {
146   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
147   QAction* anAcceptAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
148
149   if (myAcceptAllToolTip.isEmpty() && myAcceptToolTip.isEmpty())
150     storeInitialActionValues();
151
152   bool anEnabled = theError.isEmpty();
153   anAcceptAction->setEnabled(anEnabled);
154   anAcceptAction->setToolTip(anEnabled ? myAcceptToolTip : theError);
155   anAcceptAction->setStatusTip(anEnabled ? myAcceptStatusTip : theError);
156   // some operations have no property panel, so it is important to check that it is not null
157   if (myPropertyPanel) {
158     // update controls error information
159     QWidget* aWidget = myPropertyPanel->headerWidget();
160     if (aWidget)
161       aWidget->setToolTip(theError);
162   }
163 }
164 void XGUI_ErrorMgr::onWidgetChanged()
165 {
166   ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
167   if (!aModelWidget || !aModelWidget->feature().get())
168     return;
169
170   QString aWidgetError = aModelWidget->getError();
171   updateToolTip(aModelWidget, aWidgetError);
172 }
173
174 void XGUI_ErrorMgr::updateToolTip(ModuleBase_ModelWidget* theWidget,
175                                   const QString& theError)
176 {
177   if (!theWidget)
178     return;
179
180   QList<QWidget*> aWidgetList = theWidget->getControls();
181   foreach(QWidget* aWidget, aWidgetList) {
182     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
183     // We won't set the effect to QLabels - it looks ugly
184     if (aLabel) continue;
185
186     // Get the original tool tip of the widget
187     QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
188     // Add the error message into the tool tip
189     if (!theError.isEmpty()) {
190       if (!aTTip.isEmpty())
191         aTTip.append('\n');
192       aTTip += "Errors:\n" + theError;
193     }
194     aWidget->setToolTip(aTTip);
195     //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
196   }
197 }
198
199 XGUI_Workshop* XGUI_ErrorMgr::workshop() const
200 {
201   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
202   return aConnector->workshop();
203 }
204
205 ModuleBase_ModelWidget* XGUI_ErrorMgr::activeWidget() const
206 {
207   ModuleBase_ModelWidget* anActiveWidget = 0;
208
209   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
210                                       (workshop()->operationMgr()->currentOperation());
211   if (aFOperation) {
212     ModuleBase_IPropertyPanel* aPropertyPanel = aFOperation->propertyPanel();
213     if (aPropertyPanel) {
214       anActiveWidget = aPropertyPanel->activeWidget();
215     }
216   }
217   return anActiveWidget;
218 }
219