1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "XGUI_ErrorMgr.h"
22 #include "XGUI_OperationMgr.h"
23 #include "XGUI_ModuleConnector.h"
24 #include "XGUI_Workshop.h"
25 #include "XGUI_ActionsMgr.h"
27 #include <ModuleBase_IPropertyPanel.h>
28 #include <ModuleBase_IWorkshop.h>
29 #include <ModuleBase_IModule.h>
30 #include <ModuleBase_ModelWidget.h>
31 #include <ModuleBase_OperationFeature.h>
33 #include <ModuleBase_Tools.h>
36 #include <ModelAPI_Attribute.h>
37 #include <ModelAPI_Session.h>
38 #include <ModelAPI_Validator.h>
42 #include <QApplication>
43 #include <QDesktopWidget>
46 #include <QHBoxLayout>
49 const QString INVALID_VALUE = "invalid_action";
51 //#define DEBUG_ERROR_STATE
53 XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent, ModuleBase_IWorkshop* theWorkshop)
54 : ModuleBase_IErrorMgr(theParent),
57 myWorkshop(theWorkshop),
58 myAcceptAllToolTip(""),
59 myAcceptAllStatusTip(""),
65 XGUI_ErrorMgr::~XGUI_ErrorMgr()
69 void XGUI_ErrorMgr::updateActions(const FeaturePtr& theFeature)
71 //update Ok Action and header of property panel if the current operation started for the feature
72 XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
73 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
74 (workshop()->operationMgr()->currentOperation());
75 if (aFOperation && aFOperation->feature() == theFeature) {
76 ModuleBase_ModelWidget* anActiveWidget = activeWidget();
77 bool isApplyEnabledByActiveWidget = false;
79 isApplyEnabledByActiveWidget = anActiveWidget->getValueState() ==
80 ModuleBase_ModelWidget::ModifiedInPP;
82 QString aWidgetError = "";
83 if (!isApplyEnabledByActiveWidget) {
84 anError = myWorkshop->module()->getFeatureError(theFeature);
86 aWidgetError = anActiveWidget->getError();
87 if (anError.isEmpty())
88 anError = aWidgetError;
90 updateAcceptActionState(anError);
91 updateToolTip(anActiveWidget, aWidgetError);
92 myWorkshop->setStatusBarMessage(anError);
94 #ifdef DEBUG_ERROR_STATE
95 QString anInfo = ModuleBase_Tools::objectInfo(theFeature);
97 QString aResultInfo = QString("valid = %1, anError = %2, aWidgetError = %3")
98 .arg(anError.isEmpty()).arg(anError).arg(aWidgetError);
99 qDebug(QString("XGUI_ErrorMgr::updateActions for %1, result: %2").arg(anInfo)
100 .arg(aResultInfo).toStdString().c_str());
105 void XGUI_ErrorMgr::updateAcceptAllAction(const FeaturePtr& theFeature)
107 if (myAcceptAllToolTip.isEmpty() && myAcceptToolTip.isEmpty())
108 storeInitialActionValues();
110 QString anError = "";
111 /// to allow the module have the button always enabled
112 bool isActionStateEnabled =
113 myWorkshop->module()->isActionEnableStateFixed(XGUI_ActionsMgr::AcceptAll);
114 if (!isActionStateEnabled) {
115 anError = myWorkshop->module()->getFeatureError(theFeature);
116 if (anError.isEmpty()) {
117 ModuleBase_ModelWidget* anActiveWidget = activeWidget();
119 anError = anActiveWidget->getError();
122 XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
123 if (workshop()->isFeatureOfNested(theFeature)) {
124 QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
125 bool anEnabled = anError.isEmpty();
126 anAcceptAllAction->setEnabled(anEnabled);
127 anAcceptAllAction->setToolTip(!anEnabled ? anError : myAcceptAllToolTip);
128 anAcceptAllAction->setStatusTip(!anEnabled ? anError : myAcceptAllStatusTip);
132 bool XGUI_ErrorMgr::isApplyEnabled() const
134 bool isEnabled = false;
135 XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
136 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
137 (workshop()->operationMgr()->currentOperation());
139 QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
140 isEnabled = anOkAction && anOkAction->isEnabled();
145 void XGUI_ErrorMgr::storeInitialActionValues()
147 ModuleBase_ModelWidget* anActiveWidget = activeWidget();
148 XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
149 QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
150 myAcceptAllToolTip = anAcceptAllAction->toolTip();
151 myAcceptAllStatusTip = anAcceptAllAction->statusTip();
153 QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
154 myAcceptToolTip = anOkAction->toolTip();
155 myAcceptStatusTip = anOkAction->toolTip();
158 void XGUI_ErrorMgr::updateAcceptActionState(const QString& theError)
160 XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
161 QAction* anAcceptAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
162 QAction* anAcceptPlusAction =
163 anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptPlus);
165 if (myAcceptAllToolTip.isEmpty() && myAcceptToolTip.isEmpty())
166 storeInitialActionValues();
168 bool anEnabled = theError.isEmpty();
169 anAcceptAction->setEnabled(anEnabled);
170 anAcceptPlusAction->setEnabled(anEnabled);
171 anAcceptAction->setToolTip(anEnabled ? myAcceptToolTip : theError);
172 anAcceptAction->setStatusTip(anEnabled ? myAcceptStatusTip : theError);
173 // some operations have no property panel, so it is important to check that it is not null
174 if (myPropertyPanel) {
175 // update controls error information
176 QWidget* aWidget = myPropertyPanel->headerWidget();
178 aWidget->setToolTip(theError);
181 void XGUI_ErrorMgr::onWidgetChanged()
183 ModuleBase_ModelWidget* aModelWidget = dynamic_cast<ModuleBase_ModelWidget*>(sender());
184 if (!aModelWidget || !aModelWidget->feature().get())
187 QString aWidgetError = aModelWidget->getError();
188 updateToolTip(aModelWidget, aWidgetError);
191 void XGUI_ErrorMgr::updateToolTip(ModuleBase_ModelWidget* theWidget,
192 const QString& theError)
197 QList<QWidget*> aWidgetList = theWidget->getControls();
198 foreach(QWidget* aWidget, aWidgetList) {
199 QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
200 // We won't set the effect to QLabels - it looks ugly
201 if (aLabel) continue;
203 // Get the original tool tip of the widget
204 QString aTTip = aWidget->toolTip().section("Errors:\n", 0, 0).trimmed();
205 // Add the error message into the tool tip
206 if (!theError.isEmpty()) {
207 if (!aTTip.isEmpty())
209 aTTip += "Errors:\n" + theError;
211 aWidget->setToolTip(aTTip);
212 //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;");
216 XGUI_Workshop* XGUI_ErrorMgr::workshop() const
218 XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
219 return aConnector->workshop();
222 ModuleBase_ModelWidget* XGUI_ErrorMgr::activeWidget() const
224 ModuleBase_ModelWidget* anActiveWidget = 0;
226 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
227 (workshop()->operationMgr()->currentOperation());
229 ModuleBase_IPropertyPanel* aPropertyPanel = aFOperation->propertyPanel();
230 if (aPropertyPanel) {
231 anActiveWidget = aPropertyPanel->activeWidget();
234 return anActiveWidget;