-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D\r
-\r
-// File: ModuleBase_ModelWidget.cpp\r
-// Created: 25 Apr 2014\r
-// Author: Natalia ERMOLAEVA\r
-\r
-#include "ModuleBase_ModelWidget.h"\r
-#include "ModuleBase_ViewerPrs.h"\r
-#include "ModuleBase_Tools.h"\r
-#include "ModuleBase_WidgetValidator.h"\r
-\r
-#include <Events_InfoMessage.h>\r
-\r
-#include <ModelAPI_Data.h>\r
-#include <ModelAPI_Attribute.h>\r
-#include <ModelAPI_Events.h>\r
-#include <ModelAPI_Session.h>\r
-#include <ModelAPI_Validator.h>\r
-\r
-#include <Config_Keywords.h>\r
-#include <Config_WidgetAPI.h>\r
-#include <Config_Translator.h>\r
-#include <Config_PropManager.h>\r
-\r
-#include <Events_Loop.h>\r
-\r
-#include <QEvent>\r
-#include <QLabel>\r
-#include <QFocusEvent>\r
-#include <QTextCodec>\r
-\r
-//#define DEBUG_VALUE_STATE\r
-\r
-//#define DEBUG_WIDGET_INSTANCE\r
-//#define DEBUG_ENABLE_SKETCH_INPUT_FIELDS\r
-\r
-ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent,\r
- const Config_WidgetAPI* theData)\r
- : QWidget(theParent),\r
- myIsEditing(false),\r
- myState(Stored),\r
- myIsValueStateBlocked(false),\r
- myFlushUpdateBlocked(false),\r
- myWidgetValidator(0)\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::ModuleBase_ModelWidget");\r
-#endif\r
-\r
- myIsInternal = theData->getBooleanAttribute(ATTR_INTERNAL, false);\r
-\r
- myDefaultValue = theData->getProperty(ATTR_DEFAULT);\r
- myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);\r
- myIsComputedDefault = theData->getProperty(ATTR_DEFAULT) == DOUBLE_WDG_DEFAULT_COMPUTED;\r
- myAttributeID = theData ? theData->widgetId() : "";\r
- myIsObligatory = theData->getBooleanAttribute(ATTR_OBLIGATORY, true);\r
-\r
- myIsValueEnabled = On; // not defined or "true"\r
- std::string anEnableValue = theData->getProperty(DOUBLE_WDG_ENABLE_VALUE);\r
- if (anEnableValue == "false")\r
- myIsValueEnabled = Off;\r
- if (anEnableValue == DOUBLE_WDG_ENABLE_VALUE_BY_PREFERENCES)\r
- myIsValueEnabled = DefinedInPreferences;\r
-\r
- connect(this, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged()));\r
- connect(this, SIGNAL(valuesModified()), this, SLOT(onWidgetValuesModified()));\r
-}\r
-\r
-ModuleBase_ModelWidget::~ModuleBase_ModelWidget()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::~ModuleBase_ModelWidget");\r
-#endif\r
-}\r
-\r
-bool ModuleBase_ModelWidget::reset()\r
-{\r
- bool aResult = resetCustom();\r
- if (aResult)\r
- setValueState(Reset);\r
-\r
- return aResult;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const\r
-{\r
- return theObject->data()->attribute(attributeID())->isInitialized();\r
-}\r
-\r
-bool ModuleBase_ModelWidget::isValueEnabled() const\r
-{\r
- bool anEnabled = true;\r
- if (myIsValueEnabled == DefinedInPreferences) {\r
-#ifdef DEBUG_ENABLE_SKETCH_INPUT_FIELDS\r
- bool aCanDisable = true;//Config_PropManager::boolean(SKETCH_TAB_NAME, "disable_input_fields", "true");\r
-#else\r
- bool aCanDisable = Config_PropManager::boolean(SKETCH_TAB_NAME, "disable_input_fields", "true");\r
-#endif\r
- if (aCanDisable)\r
- anEnabled = false;\r
- }\r
- else if (myIsValueEnabled == Off)\r
- anEnabled = false;\r
- return anEnabled;\r
-}\r
-\r
-void ModuleBase_ModelWidget::processValueState()\r
-{\r
- if (myState == ModifiedInPP || myState == ModifiedInViewer)\r
- storeValue();\r
-}\r
-\r
-QString ModuleBase_ModelWidget::getValueStateError() const\r
-{\r
- QString anError = "";\r
-\r
- ModuleBase_ModelWidget::ValueState aState = getValueState();\r
- if (aState != ModuleBase_ModelWidget::Stored) {\r
- AttributePtr anAttr = feature()->attribute(attributeID());\r
- if (anAttr.get()) {\r
- QString anAttributeName = anAttr->id().c_str();\r
- switch (aState) {\r
- case ModuleBase_ModelWidget::ModifiedInViewer:\r
- anError = "Attribute \"" + anAttributeName +\r
- "\" is locked by modification value in the viewer.";\r
- break;\r
- case ModuleBase_ModelWidget::Reset:\r
- anError = "Attribute \"" + anAttributeName + "\" is not initialized.";\r
- break;\r
- case ModuleBase_ModelWidget::ModifiedInPP: // Apply should be enabled in this mode\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
- return anError;\r
-}\r
-\r
-QString ModuleBase_ModelWidget::getError(const bool theValueStateChecked) const\r
-{\r
- QString anError;\r
-\r
- if (!feature().get())\r
- return anError;\r
-\r
- std::string anAttributeID = attributeID();\r
- AttributePtr anAttribute = feature()->attribute(anAttributeID);\r
- if (!anAttribute.get())\r
- return anError;\r
-\r
- std::string aValidatorID;\r
- Events_InfoMessage anErrorMsg;\r
-\r
- static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();\r
- if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {\r
- if (anErrorMsg.empty())\r
- anErrorMsg = "unknown error.";\r
- anErrorMsg = anAttributeID + " - " + aValidatorID + ": " + anErrorMsg.messageString();\r
- }\r
-\r
- if (!anErrorMsg.empty()) {\r
- std::string aStr = Config_Translator::translate(anErrorMsg);\r
- std::string aCodec = Config_Translator::codec(anErrorMsg.context());\r
- anError = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());\r
- }\r
-\r
- if (anError.isEmpty() && theValueStateChecked)\r
- anError = getValueStateError();\r
-\r
- anError = translateString(anError);\r
- return anError;\r
-}\r
-\r
-\r
-QString ModuleBase_ModelWidget::translateString(const QString& theMsg) const\r
-{\r
- if (!theMsg.isEmpty()) {\r
- std::string aContext = feature()->getKind();\r
- std::string aStr = Config_Translator::translate(aContext, theMsg.toStdString().c_str());\r
- std::string aCodec = Config_Translator::codec(aContext);\r
- return QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());\r
- }\r
- return theMsg;\r
-}\r
-\r
-\r
-void ModuleBase_ModelWidget::enableFocusProcessing()\r
-{\r
- QList<QWidget*> aMyControls = getControls();\r
- foreach(QWidget* eachControl, aMyControls) {\r
- eachControl->setFocusPolicy(Qt::StrongFocus);\r
- eachControl->installEventFilter(this);\r
- }\r
-}\r
-\r
-void ModuleBase_ModelWidget::setHighlighted(bool isHighlighted)\r
-{\r
- QList<QWidget*> aWidgetList = getControls();\r
- foreach(QWidget* aWidget, aWidgetList) {\r
- QLabel* aLabel = qobject_cast<QLabel*>(aWidget);\r
- // We won't set the effect to QLabels - it looks ugly\r
- if(aLabel) continue;\r
- // If effect is the installed on a different widget, setGraphicsEffect() will\r
- // remove the effect from the widget and install it on this widget.\r
- // That's why we create a new effect for each widget\r
- ModuleBase_Tools::setShadowEffect(aWidget, isHighlighted);\r
- }\r
-}\r
-\r
-void ModuleBase_ModelWidget::setFeature(const FeaturePtr& theFeature, const bool theToStoreValue,\r
- const bool isUpdateFlushed)\r
-{\r
- /// it is possible to give this flag as parameter in storeValue/storeCustomValue\r
- /// after debug, it may be corrected\r
- myFlushUpdateBlocked = !isUpdateFlushed;\r
- myFeature = theFeature;\r
- if (theToStoreValue) {\r
- /// it is possible that the attribute is filled before the operation is started,\r
- /// e.g. by reentrant operation case some attributes are filled by values of\r
- /// feature of previous operation, we should not lost them here\r
- if (!theFeature->data()->attribute(attributeID())->isInitialized())\r
- storeValue();\r
- }\r
- myFlushUpdateBlocked = false;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::focusTo()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::focusTo");\r
-#endif\r
- QList<QWidget*> aControls = getControls();\r
- QList<QWidget*>::const_iterator anIt = aControls.begin(), aLast = aControls.end();\r
- bool isFocusAccepted = false;\r
- for (; anIt != aLast && !isFocusAccepted; anIt++) {\r
- QWidget* aWidget = *anIt;\r
- if (aWidget && aWidget->focusPolicy() != Qt::NoFocus) {\r
- ModuleBase_Tools::setFocus(aWidget, "ModuleBase_ModelWidget::focusTo()");\r
- isFocusAccepted = true;\r
- }\r
- }\r
- return isFocusAccepted;\r
-}\r
-\r
-void ModuleBase_ModelWidget::activate()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::activate");\r
-#endif\r
- // the control value is stored to the mode by the focus in on the widget\r
- // we need the value is initialized in order to enable the apply button in the property panel.\r
- // It should happens in the creation mode only because all fields are filled in the edition mode\r
- if (!isEditingMode()) {\r
- AttributePtr anAttribute = myFeature->data()->attribute(myAttributeID);\r
- if (anAttribute.get() != NULL && !anAttribute->isInitialized())\r
- initializeValueByActivate();\r
- }\r
-\r
- if (myWidgetValidator)\r
- myWidgetValidator->activateFilters(true);\r
-\r
- activateCustom();\r
-}\r
-\r
-void ModuleBase_ModelWidget::deactivate()\r
-{\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::deactivate");\r
-#endif\r
- myIsValueStateBlocked = false;\r
- myState = Stored;\r
- if (myWidgetValidator)\r
- myWidgetValidator->activateFilters(false);\r
-}\r
-\r
-void ModuleBase_ModelWidget::initializeValueByActivate()\r
-{\r
- if (isComputedDefault()) {\r
- if (myFeature->compute(myAttributeID)) {\r
- restoreValue();\r
- }\r
- }\r
- else {\r
- storeValue();\r
- }\r
-}\r
-\r
-QWidget* ModuleBase_ModelWidget::getControlAcceptingFocus(const bool isFirst)\r
-{\r
- QWidget* aControl = 0;\r
-\r
- QList<QWidget*> aControls = getControls();\r
- int aSize = aControls.size();\r
-\r
- if (isFirst) {\r
- for (int i = 0; i < aSize && !aControl; i++) {\r
- if (aControls[i]->focusPolicy() != Qt::NoFocus)\r
- aControl = aControls[i];\r
- }\r
- }\r
- else {\r
- for (int i = aSize - 1; i >= 0 && !aControl; i--) {\r
- if (aControls[i]->focusPolicy() != Qt::NoFocus)\r
- aControl = aControls[i];\r
- }\r
- }\r
- return aControl;\r
-}\r
-\r
-void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)\r
-{\r
- myDefaultValue = theValue;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::storeValue()\r
-{\r
- setValueState(Stored);\r
-\r
- emit beforeValuesChanged();\r
- bool isDone = storeValueCustom();\r
- emit afterValuesChanged();\r
-\r
- return isDone;\r
-}\r
-#ifdef DEBUG_VALUE_STATE\r
-std::string getDebugInfo(const ModuleBase_ModelWidget::ValueState& theState)\r
-{\r
- std::string anInfo;\r
- switch (theState) {\r
- case ModuleBase_ModelWidget::Stored: anInfo = "Stored "; break;\r
- case ModuleBase_ModelWidget::ModifiedInPP: anInfo = "ModifiedInPP "; break;\r
- case ModuleBase_ModelWidget::ModifiedInViewer: anInfo = "ModifiedInViewer"; break;\r
- case ModuleBase_ModelWidget::Reset: anInfo = "Reset "; break;\r
- default: break;\r
- }\r
- return anInfo;\r
-}\r
-\r
-#endif\r
-ModuleBase_ModelWidget::ValueState ModuleBase_ModelWidget::setValueState\r
- (const ModuleBase_ModelWidget::ValueState& theState)\r
-{\r
- ValueState aState = myState;\r
-\r
- if (myState != theState && !myIsValueStateBlocked) {\r
-#ifdef DEBUG_VALUE_STATE\r
- qDebug(QString("setValueState: previous state = %1,\t new state = %2")\r
- .arg(getDebugInfo(myState).c_str())\r
- .arg(getDebugInfo(theState).c_str()).toStdString().c_str());\r
-#endif\r
- myState = theState;\r
- emit valueStateChanged(aState);\r
- }\r
- return aState;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::blockValueState(const bool theBlocked)\r
-{\r
- bool isBlocked = myIsValueStateBlocked;\r
- myIsValueStateBlocked = theBlocked;\r
- return isBlocked;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::restoreValue()\r
-{\r
- emit beforeValuesRestored();\r
- bool isDone = restoreValueCustom();\r
- emit afterValuesRestored();\r
-\r
- return isDone;\r
-}\r
-\r
-void ModuleBase_ModelWidget::updateObject(ObjectPtr theObject)\r
-{\r
- if (!myFlushUpdateBlocked) {\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::updateObject");\r
-#endif\r
- ModuleBase_Tools::flushUpdated(theObject);\r
- emit objectUpdated();\r
- }\r
-}\r
-\r
-void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)\r
-{\r
- //blockUpdateViewer(true);\r
-#ifdef DEBUG_WIDGET_INSTANCE\r
- qDebug("ModuleBase_ModelWidget::moveObject");\r
-#endif\r
-\r
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);\r
- ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);\r
- Events_Loop::loop()->flush(anEvent);\r
-\r
- //blockUpdateViewer(false);\r
-}\r
-\r
-bool ModuleBase_ModelWidget::processEnter()\r
-{\r
- return false;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::processDelete()\r
-{\r
- // we consider that model objects eats delete key in order to\r
- // do nothing by for example symbol delete in line edit or spin box\r
- return true;\r
-}\r
-\r
-bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)\r
-{\r
- QWidget* aWidget = qobject_cast<QWidget*>(theObject);\r
- if (theEvent->type() == QEvent::FocusIn) {\r
- #ifdef _DEBUG\r
- // The following two lines are for debugging purpose only\r
- QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);\r
- bool isWinFocus = aFocusEvent->reason() == Qt::ActiveWindowFocusReason;\r
- #endif\r
- if (getControls().contains(aWidget)) {\r
- emit focusInWidget(this);\r
- }\r
- }\r
- else if (theEvent->type() == QEvent::FocusOut) {\r
- QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);\r
-\r
- Qt::FocusReason aReason = aFocusEvent->reason();\r
- bool aMouseOrKey = aReason == Qt::MouseFocusReason ||\r
- aReason == Qt::TabFocusReason ||\r
- aReason == Qt::BacktabFocusReason ||\r
- aReason == Qt::OtherFocusReason; // to process widget->setFocus()\r
- if (aMouseOrKey && getControls().contains(aWidget)) {\r
- if (getValueState() == ModifiedInPP) {\r
- storeValue();\r
- }\r
- }\r
- }\r
- // pass the event on to the parent class\r
-\r
- return QObject::eventFilter(theObject, theEvent);\r
-}\r
-\r
-//**************************************************************\r
-void ModuleBase_ModelWidget::onWidgetValuesChanged()\r
-{\r
- storeValue();\r
-}\r
-\r
-//**************************************************************\r
-void ModuleBase_ModelWidget::onWidgetValuesModified()\r
-{\r
- setValueState(ModifiedInPP);\r
-}\r
+// Copyright (C) 2014-2024 CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "ModuleBase_ModelWidget.h"
+#include "ModuleBase_IPropertyPanel.h"
+#include "ModuleBase_ViewerPrs.h"
+#include "ModuleBase_Tools.h"
+#include "ModuleBase_WidgetValidator.h"
+
+#include <Events_InfoMessage.h>
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Attribute.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <Config_Keywords.h>
+#include <Config_WidgetAPI.h>
+#include <Config_Translator.h>
+#include <Config_PropManager.h>
+
+#include <Events_Loop.h>
+
+#include <QEvent>
+#include <QLabel>
+#include <QFocusEvent>
+#include <QTextCodec>
+
+//#define DEBUG_VALUE_STATE
+
+//#define DEBUG_WIDGET_INSTANCE
+//#define DEBUG_ENABLE_SKETCH_INPUT_FIELDS
+
+//**************************************************************
+ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent,
+ const Config_WidgetAPI* theData)
+ : QWidget(theParent),
+ myWidgetValidator(0),
+ myState(Stored),
+ myIsEditing(false),
+ myIsValueStateBlocked(false),
+ myFlushUpdateBlocked(false)
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::ModuleBase_ModelWidget");
+#endif
+
+ myFeatureId = theData->featureId();
+
+ myIsInternal = theData->getBooleanAttribute(ATTR_INTERNAL, false);
+ myUseExternalParts = theData->getBooleanAttribute("allow_parts_content", false);
+
+ myIsModifiedInEdit = theData->getProperty(ATTR_MODIFIED_IN_EDIT);
+
+ myUpdateVisualAttributes = theData->getBooleanAttribute(ATTR_VISUAL_CHANGED, false);
+
+ myDefaultValue = theData->getProperty(ATTR_DEFAULT);
+ myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);
+ myIsComputedDefault = theData->getProperty(ATTR_DEFAULT) == DOUBLE_WDG_DEFAULT_COMPUTED;
+ myAttributeID = theData ? theData->widgetId() : "";
+ myIsObligatory = theData->getBooleanAttribute(ATTR_OBLIGATORY, true);
+
+ myIsValueEnabled = On; // not defined or "true"
+ std::string anEnableValue = theData->getProperty(DOUBLE_WDG_ENABLE_VALUE);
+ if (anEnableValue == "false")
+ myIsValueEnabled = Off;
+ if (anEnableValue == DOUBLE_WDG_ENABLE_VALUE_BY_PREFERENCES)
+ myIsValueEnabled = DefinedInPreferences;
+
+ connect(this, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged()));
+ connect(this, SIGNAL(valuesModified()), this, SLOT(onWidgetValuesModified()));
+}
+
+//**************************************************************
+ModuleBase_ModelWidget::~ModuleBase_ModelWidget()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::~ModuleBase_ModelWidget");
+#endif
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::reset()
+{
+ bool aResult = resetCustom();
+ if (aResult)
+ setValueState(Reset);
+
+ return aResult;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const
+{
+ return theObject->data()->attribute(attributeID())->isInitialized();
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::selectionModes(int& theModuleSelectionModes, QIntList& theModes)
+{
+ theModuleSelectionModes = -1;
+ if (myWidgetValidator)
+ myWidgetValidator->selectionModes(theModuleSelectionModes, theModes);
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::selectionFilters(QIntList& theModuleSelectionFilters,
+ SelectMgr_ListOfFilter& theSelectionFilters)
+{
+ if (myWidgetValidator)
+ myWidgetValidator->selectionFilters(theModuleSelectionFilters, theSelectionFilters);
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::isValueEnabled() const
+{
+ bool anEnabled = true;
+ if (myIsValueEnabled == DefinedInPreferences) {
+#ifdef DEBUG_ENABLE_SKETCH_INPUT_FIELDS
+ bool aCanDisable = false;
+#else
+ //Config_PropManager::boolean(SKETCH_TAB_NAME, "disable_input_fields", "true");
+ bool aCanDisable = true;
+#endif
+ if (aCanDisable)
+ anEnabled = false;
+ }
+ else if (myIsValueEnabled == Off)
+ anEnabled = false;
+ return anEnabled;
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::processValueState()
+{
+ if (myState == ModifiedInPP || myState == ModifiedInViewer)
+ storeValue();
+}
+
+//**************************************************************
+Events_InfoMessage ModuleBase_ModelWidget::getValueStateError() const
+{
+ Events_InfoMessage aMessage;
+ aMessage.setContext(context());
+
+ ModuleBase_ModelWidget::ValueState aState = getValueState();
+ if (aState != ModuleBase_ModelWidget::Stored) {
+ AttributePtr anAttr = feature()->attribute(attributeID());
+ if (anAttr.get()) {
+ const std::string& anAttributeName = anAttr->id();
+ switch (aState) {
+ case ModuleBase_ModelWidget::ModifiedInViewer:
+ aMessage = "Attribute \"%1\" is locked by modification value in the viewer.";
+ aMessage.addParameter(anAttributeName);
+ break;
+ case ModuleBase_ModelWidget::Reset:
+ aMessage = "Attribute \"%1\" is not initialized.";
+ aMessage.addParameter(anAttributeName);
+ break;
+ case ModuleBase_ModelWidget::ModifiedInPP: // Apply should be enabled in this mode
+ default:
+ break;
+ }
+ }
+ }
+ return aMessage;
+}
+
+//**************************************************************
+QString ModuleBase_ModelWidget::getError(const bool theValueStateChecked) const
+{
+ QString anError;
+
+ if (!feature().get())
+ return anError;
+
+ std::string anAttributeID = attributeID();
+ AttributePtr anAttribute = feature()->attribute(anAttributeID);
+ if (!anAttribute.get())
+ return anError;
+
+ std::string aValidatorID;
+ Events_InfoMessage anErrorMsg;
+
+ static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+ if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) {
+ if (anErrorMsg.empty())
+ anErrorMsg = "Unknown error.";
+
+ if (anErrorMsg.context().empty()) {
+ anErrorMsg.setContext(context() + ":" + aValidatorID);
+ }
+ }
+
+ if (anErrorMsg.empty() && theValueStateChecked) {
+ anErrorMsg = getValueStateError();
+ }
+
+ if (!anErrorMsg.empty()) {
+ anError = ModuleBase_Tools::translate(anErrorMsg);
+ }
+
+ return anError;
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::enableFocusProcessing()
+{
+ QList<QWidget*> aMyControls = getControls();
+ foreach(QWidget* eachControl, aMyControls) {
+ eachControl->setFocusPolicy(Qt::StrongFocus);
+ eachControl->installEventFilter(this);
+ }
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::setHighlighted(bool isHighlighted)
+{
+ QList<QWidget*> aWidgetList = getControls();
+ foreach(QWidget* aWidget, aWidgetList) {
+ QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
+ // We won't set the effect to QLabels - it looks ugly
+ if(aLabel) continue;
+ // If effect is the installed on a different widget, setGraphicsEffect() will
+ // remove the effect from the widget and install it on this widget.
+ // That's why we create a new effect for each widget
+ ModuleBase_Tools::setShadowEffect(aWidget, isHighlighted);
+ }
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::setFeature(const FeaturePtr& theFeature, const bool theToStoreValue,
+ const bool isUpdateFlushed)
+{
+ /// it is possible to give this flag as parameter in storeValue/storeCustomValue
+ /// after debug, it may be corrected
+ myFlushUpdateBlocked = !isUpdateFlushed;
+ myFeature = theFeature;
+ if (theToStoreValue) {
+ /// it is possible that the attribute is filled before the operation is started,
+ /// e.g. by reentrant operation case some attributes are filled by values of
+ /// feature of previous operation, we should not lost them here
+ if (!theFeature->data()->attribute(attributeID())->isInitialized())
+ storeValue();
+ }
+ myFlushUpdateBlocked = false;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::focusTo()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::focusTo");
+#endif
+ QList<QWidget*> aControls = getControls();
+ QList<QWidget*>::const_iterator anIt = aControls.begin(), aLast = aControls.end();
+ bool isFocusAccepted = false;
+ for (; anIt != aLast && !isFocusAccepted; anIt++) {
+ QWidget* aWidget = *anIt;
+ if (aWidget && aWidget->focusPolicy() != Qt::NoFocus) {
+ ModuleBase_Tools::setFocus(aWidget, "ModuleBase_ModelWidget::focusTo()");
+ isFocusAccepted = true;
+ }
+ }
+ return isFocusAccepted;
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::activate()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::activate");
+#endif
+ // the control value is stored to the mode by the focus in on the widget
+ // we need the value is initialized in order to enable the apply button in the property panel.
+ // It should happens in the creation mode only because all fields are filled in the edition mode
+ if (!isEditingMode()) {
+ AttributePtr anAttribute = myFeature->data()->attribute(myAttributeID);
+ if (anAttribute.get() != NULL && !anAttribute->isInitialized())
+ initializeValueByActivate();
+ }
+ activateCustom();
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::deactivate()
+{
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::deactivate");
+#endif
+ myIsValueStateBlocked = false;
+ myState = Stored;
+ if (myWidgetValidator)
+ myWidgetValidator->clearValidatedCash();
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::initializeValueByActivate()
+{
+ if (isComputedDefault()) {
+ if (myFeature->compute(myAttributeID)) {
+ restoreValue();
+ }
+ }
+ else {
+ storeValue();
+ }
+}
+
+//**************************************************************
+QWidget* ModuleBase_ModelWidget::getControlAcceptingFocus(const bool isFirst)
+{
+ QWidget* aControl = 0;
+
+ QList<QWidget*> aControls = getControls();
+ int aSize = aControls.size();
+
+ if (isFirst) {
+ for (int i = 0; i < aSize && !aControl; i++) {
+ if (aControls[i]->focusPolicy() != Qt::NoFocus)
+ aControl = aControls[i];
+ }
+ }
+ else {
+ for (int i = aSize - 1; i >= 0 && !aControl; i--) {
+ if (aControls[i]->focusPolicy() != Qt::NoFocus)
+ aControl = aControls[i];
+ }
+ }
+ return aControl;
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)
+{
+ myDefaultValue = theValue;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::storeValue()
+{
+ setValueState(Stored);
+
+ emit beforeValuesChanged();
+ bool isDone = false;
+ // value is stored only in creation mode and in edition if there is not
+ // XML flag prohibited modification in edit mode(macro feature circle/arc)
+ if (!isEditingMode() || isModifiedInEdit().empty())
+ isDone = storeValueCustom();
+ else {
+ /// store value in an alternative attribute if possible(attribute has the same type)
+ std::string aWidgetAttribute = attributeID();
+ myAttributeID = isModifiedInEdit();
+ storeValueCustom();
+ myAttributeID = aWidgetAttribute;
+ // operation will be restarted but if isDone == true, PagedContainer will try to set focus
+ // to the current widget, but will be already deleted
+ isDone = false;
+ }
+
+ emit afterValuesChanged();
+
+ return isDone;
+}
+#ifdef DEBUG_VALUE_STATE
+
+//**************************************************************
+std::string getDebugInfo(const ModuleBase_ModelWidget::ValueState& theState)
+{
+ std::string anInfo;
+ switch (theState) {
+ case ModuleBase_ModelWidget::Stored: anInfo = "Stored "; break;
+ case ModuleBase_ModelWidget::ModifiedInPP: anInfo = "ModifiedInPP "; break;
+ case ModuleBase_ModelWidget::ModifiedInViewer: anInfo = "ModifiedInViewer"; break;
+ case ModuleBase_ModelWidget::Reset: anInfo = "Reset "; break;
+ default: break;
+ }
+ return anInfo;
+}
+#endif
+
+//**************************************************************
+ModuleBase_ModelWidget::ValueState ModuleBase_ModelWidget::setValueState
+ (const ModuleBase_ModelWidget::ValueState& theState)
+{
+ ValueState aState = myState;
+
+ if (myState != theState && !myIsValueStateBlocked) {
+#ifdef DEBUG_VALUE_STATE
+ qDebug(QString("setValueState: previous state = %1,\t new state = %2")
+ .arg(getDebugInfo(myState).c_str())
+ .arg(getDebugInfo(theState).c_str()).toStdString().c_str());
+#endif
+ myState = theState;
+ emit valueStateChanged(aState);
+ }
+ return aState;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::blockValueState(const bool theBlocked)
+{
+ bool isBlocked = myIsValueStateBlocked;
+ myIsValueStateBlocked = theBlocked;
+ return isBlocked;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::restoreValue()
+{
+ if (!isEnabled()) {
+ // This code works in inspection panel
+ ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+ if (!aValidators->isCase(myFeature, attributeID()))
+ return false; // if it is not an active case for the widget
+ }
+ emit beforeValuesRestored();
+ bool isDone = restoreValueCustom();
+ emit afterValuesRestored();
+
+ return isDone;
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::updateObject(ObjectPtr theObject)
+{
+ if (!myFlushUpdateBlocked) {
+#ifdef DEBUG_WIDGET_INSTANCE
+ qDebug("ModuleBase_ModelWidget::updateObject");
+#endif
+ if (myFeature.get() && myUpdateVisualAttributes) {
+ static const Events_ID anEvent = Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES);
+ ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent);
+ }
+ ModuleBase_Tools::flushUpdated(theObject);
+ emit objectUpdated();
+ }
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::canProcessAction(ModuleBase_ActionType theActionType,
+ bool& isActionEnabled)
+{
+ isActionEnabled = false;
+ switch (theActionType) {
+ case ActionEnter: return false;
+ case ActionEscape: return false;
+ case ActionDelete: return true;
+ case ActionSelection: return true;
+ case ActionUndo:
+ case ActionRedo:
+ default:
+ return false;
+ }
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::processAction(ModuleBase_ActionType theActionType,
+ const ActionParamPtr& theParam)
+{
+ switch (theActionType) {
+ case ActionEnter:
+ return processEnter();
+ case ActionEscape:
+ return processEscape();
+ case ActionDelete:
+ return processDelete();
+ case ActionSelection:
+ processSelection();
+ case ActionUndo:
+ case ActionRedo:
+ default:
+ return false;
+ }
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::processEnter()
+{
+ return false;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::processEscape()
+{
+ return false;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::processDelete()
+{
+ // we consider that model objects eats delete key in order to
+ // do nothing by for example symbol delete in line edit or spin box
+ return true;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::processSelection()
+{
+ return false;
+}
+
+//**************************************************************
+bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
+{
+ QWidget* aWidget = qobject_cast<QWidget*>(theObject);
+ if (theEvent->type() == QEvent::FocusIn) {
+ QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);
+ Qt::FocusReason aReason = aFocusEvent->reason();
+ bool aMouseOrKey = aReason == Qt::MouseFocusReason ||
+ /*aReason == Qt::TabFocusReason ||
+ //aReason == Qt::BacktabFocusReason ||*/
+ aReason == Qt::OtherFocusReason; // to process widget->setFocus()
+ if (aMouseOrKey && getControls().contains(aWidget)) {
+ //if (getControls().contains(aWidget)) {
+ emitFocusInWidget();
+ }
+ }
+ else if (theEvent->type() == QEvent::FocusOut) {
+ QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);
+
+ Qt::FocusReason aReason = aFocusEvent->reason();
+ bool aMouseOrKey = aReason == Qt::MouseFocusReason ||
+ aReason == Qt::TabFocusReason ||
+ aReason == Qt::BacktabFocusReason ||
+ aReason == Qt::OtherFocusReason; // to process widget->setFocus()
+ if (aMouseOrKey && getControls().contains(aWidget)) {
+ if (getValueState() == ModifiedInPP) {
+ storeValue();
+ }
+ }
+ }
+ // pass the event on to the parent class
+
+ return QObject::eventFilter(theObject, theEvent);
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::onWidgetValuesChanged()
+{
+ storeValue();
+}
+
+//**************************************************************
+void ModuleBase_ModelWidget::onWidgetValuesModified()
+{
+ setValueState(ModifiedInPP);
+}
+
+//**************************************************************
+QString ModuleBase_ModelWidget::translate(const std::string& theStr) const
+{
+ return ModuleBase_Tools::translate(context(), theStr);
+}
+
+//**************************************************************
+ModuleBase_ModelWidget* ModuleBase_ModelWidget::findModelWidget(ModuleBase_IPropertyPanel* theProp,
+ QWidget* theWidget)
+{
+ ModuleBase_ModelWidget* aModelWidget = 0;
+ if (!theWidget)
+ return aModelWidget;
+
+ QObject* aParent = theWidget->parent();
+ while (aParent) {
+ aModelWidget = qobject_cast<ModuleBase_ModelWidget*>(aParent);
+ if (aModelWidget)
+ break;
+ aParent = aParent->parent();
+ }
+ return aModelWidget;
+}