From 37868f0c69fb4eed9c5545f7e9d639c9a91061a0 Mon Sep 17 00:00:00 2001 From: sbh Date: Wed, 24 Sep 2014 15:52:30 +0400 Subject: [PATCH] Issue #144 If an operation has valid feature after initialization by preselection - commit it immediately --- src/Config/Config_Keywords.h | 1 + src/Config/Config_WidgetAPI.cpp | 16 ++++++++ src/Config/Config_WidgetAPI.h | 8 ++++ src/ModuleBase/ModuleBase_IOperation.h | 7 ++-- src/ModuleBase/ModuleBase_ModelWidget.cpp | 28 +++++++++---- src/ModuleBase/ModuleBase_ModelWidget.h | 22 ++++++---- src/ModuleBase/ModuleBase_Operation.cpp | 10 +++++ src/ModuleBase/ModuleBase_Operation.h | 5 ++- src/ModuleBase/ModuleBase_WidgetFactory.cpp | 13 +----- src/ModuleBase/ModuleBase_WidgetFactory.h | 5 --- src/ModuleBase/ModuleBase_WidgetFeature.cpp | 1 - src/PartSet/PartSet_OperationFeatureBase.cpp | 21 +++++++--- src/PartSet/PartSet_OperationFeatureBase.h | 2 + .../PartSet_OperationFeatureCreate.cpp | 2 - src/SketchPlugin/plugin-Sketch.xml | 8 ++-- src/XGUI/XGUI_OperationMgr.cpp | 40 ++++++------------- src/XGUI/XGUI_OperationMgr.h | 4 -- src/XGUI/XGUI_Workshop.cpp | 1 + 18 files changed, 112 insertions(+), 82 deletions(-) diff --git a/src/Config/Config_Keywords.h b/src/Config/Config_Keywords.h index f8f3bd6ed..8f0fda2e1 100644 --- a/src/Config/Config_Keywords.h +++ b/src/Config/Config_Keywords.h @@ -49,6 +49,7 @@ const static char* FEATURE_TEXT = "title"; const static char* FEATURE_KEYSEQUENCE = "keysequence"; const static char* FEATURE_NESTED = "nested"; const static char* FEATURE_INTERNAL = "internal"; +const static char* FEATURE_OBLIGATORY = "obligatory"; // TODO: Rename const static char* PREVIOUS_FEATURE_PARAM = "previous_feature_param"; const static char* ANY_WDG_TOOLTIP = FEATURE_TOOLTIP; diff --git a/src/Config/Config_WidgetAPI.cpp b/src/Config/Config_WidgetAPI.cpp index 333f9219a..7d548ea24 100644 --- a/src/Config/Config_WidgetAPI.cpp +++ b/src/Config/Config_WidgetAPI.cpp @@ -12,6 +12,9 @@ #include #include +#include +#include + Config_WidgetAPI::Config_WidgetAPI(std::string theRawXml) { myDoc = xmlParseDoc(BAD_CAST theRawXml.c_str()); @@ -90,6 +93,19 @@ std::string Config_WidgetAPI::getProperty(const char* thePropName) const return result; } +bool Config_WidgetAPI::getBooleanAttribute(const char* theAttributeName, bool theDefault) const +{ + std::string prop = getProperty(theAttributeName); + std::transform(prop.begin(), prop.end(), prop.begin(), ::tolower); + bool result = theDefault; + if (prop == "true" || prop == "1") { + result = true; + } else if (prop == "false" || prop == "0") { + result = false; + } + return result; +} + std::string Config_WidgetAPI::widgetId() const { return getProperty(_ID); diff --git a/src/Config/Config_WidgetAPI.h b/src/Config/Config_WidgetAPI.h index 02131a2de..44349fc41 100644 --- a/src/Config/Config_WidgetAPI.h +++ b/src/Config/Config_WidgetAPI.h @@ -41,6 +41,14 @@ class CONFIG_EXPORT Config_WidgetAPI std::string getProperty(const char* thePropName) const; + /// Checks if the XML representation of widget has given attribute, + /// if yes - returns it's bool value, if no, or if the value can not + /// be converted to bool - returns theDefault. + /// \param theAttributeName attribute to check + /// \param theDefault default value on bad data + /// \return the boolean result + bool getBooleanAttribute(const char* theAttributeName, bool theDefault) const; + bool isComputedDefault() const; protected: diff --git a/src/ModuleBase/ModuleBase_IOperation.h b/src/ModuleBase/ModuleBase_IOperation.h index 28822efa5..bc10a14c4 100644 --- a/src/ModuleBase/ModuleBase_IOperation.h +++ b/src/ModuleBase/ModuleBase_IOperation.h @@ -66,11 +66,10 @@ Q_OBJECT virtual bool isGranted() const { return false; } /** - * Must return True if the given opertation can be launched as nested to current one. - * By default it returns false and it has to be redefined for operations which expect - * launching of nested operations + * Must return True if the operation's feature is valid. + * Since IOperation does not have any feature returns false. */ - virtual bool isValid(ModuleBase_IOperation* theOperation) const { return false; } + virtual bool isValid() const { return false; } /// Sets a list of model widgets, according to the operation feature xml definition /// \param theXmlRepresentation an xml feature definition diff --git a/src/ModuleBase/ModuleBase_ModelWidget.cpp b/src/ModuleBase/ModuleBase_ModelWidget.cpp index c6670f24a..f3da462d4 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.cpp +++ b/src/ModuleBase/ModuleBase_ModelWidget.cpp @@ -8,7 +8,8 @@ #include #include -#include "Config_WidgetAPI.h" +#include +#include #include @@ -21,6 +22,7 @@ ModuleBase_ModelWidget::ModuleBase_ModelWidget(QObject* theParent, const Config_ myParentId(theParentId) { myIsComputedDefault = false; + myIsObligatory = theData ? theData->getBooleanAttribute(FEATURE_OBLIGATORY, true) : true; myAttributeID = theData ? theData->widgetId() : ""; } @@ -29,6 +31,16 @@ bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const return theObject->data()->attribute(attributeID())->isInitialized(); } +void ModuleBase_ModelWidget::enableFocusProcessing() +{ + QList aMyControls = getControls(); + foreach(QWidget* eachControl, aMyControls) { + if(!myFocusInWidgets.contains(eachControl)) { + enableFocusProcessing(eachControl); + } + } +} + bool ModuleBase_ModelWidget::focusTo() { QList aControls = getControls(); @@ -43,6 +55,7 @@ bool ModuleBase_ModelWidget::focusTo() return true; } + void ModuleBase_ModelWidget::updateObject(ObjectPtr theObj) const { Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); @@ -50,7 +63,7 @@ void ModuleBase_ModelWidget::updateObject(ObjectPtr theObj) const ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent); } -void ModuleBase_ModelWidget::processFocus(QWidget* theWidget) +void ModuleBase_ModelWidget::enableFocusProcessing(QWidget* theWidget) { theWidget->setFocusPolicy(Qt::StrongFocus); theWidget->installEventFilter(this); @@ -60,11 +73,10 @@ void ModuleBase_ModelWidget::processFocus(QWidget* theWidget) bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent) { QWidget* aWidget = dynamic_cast(theObject); - if (theEvent->type() == QEvent::FocusIn && myFocusInWidgets.contains(aWidget)) { + if (theEvent->type() == QEvent::MouseButtonRelease && + myFocusInWidgets.contains(aWidget)) { emit focusInWidget(this); - return true; - } else { - // pass the event on to the parent class - return QObject::eventFilter(theObject, theEvent); - } + } + // pass the event on to the parent class + return QObject::eventFilter(theObject, theEvent); } diff --git a/src/ModuleBase/ModuleBase_ModelWidget.h b/src/ModuleBase/ModuleBase_ModelWidget.h index 968f5960c..91b973854 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.h +++ b/src/ModuleBase/ModuleBase_ModelWidget.h @@ -52,10 +52,13 @@ Q_OBJECT /// \return the boolean result bool isInitialized(ObjectPtr theObject) const; - bool isComputedDefault() - { - return myIsComputedDefault; - } + /// Returns true, if default value of the widget should be computed + /// on operation's execute, like radius for circle's constraint (can not be zero) + bool isComputedDefault() { return myIsComputedDefault; } + + /// Returns false for non-obligatory widgets which are + /// valid even if they are not initialized + bool isObligatory() { return myIsObligatory; } /// Saves the internal parameters to the given feature /// \param theObject a model feature to be changed @@ -63,6 +66,7 @@ Q_OBJECT virtual bool restoreValue() = 0; + void enableFocusProcessing(); /// Set focus to the first control of the current widget. The focus policy of the control is checked. /// If the widget has the NonFocus focus policy, it is skipped. /// \return the state whether the widget can accept the focus @@ -125,14 +129,18 @@ signals: void updateObject(ObjectPtr theObj) const; + private: /// Let the widget process FocusIn events - void processFocus(QWidget* theWidget); + void enableFocusProcessing(QWidget* theWidget); - std::string myAttributeID; /// the attribute name of the model feature + protected: + std::string myAttributeID; /// the attribute name of the model feature std::string myParentId; /// name of parent FeaturePtr myFeature; - bool myIsComputedDefault; + bool myIsComputedDefault; /// Value should be computed on execute, + /// like radius for circle's constraint (can not be zero) + bool myIsObligatory; /// Non-obligatory widget is valid even if it is not initialized private: /// Contains a list of widgets that may accept focus diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index 9b24d742d..fd0724f28 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -44,6 +44,16 @@ FeaturePtr ModuleBase_Operation::feature() const return myFeature; } +bool ModuleBase_Operation::isValid() const +{ + if (!myFeature) + return true; // rename operation + //Get validators for the Id + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + return aFactory->validate(myFeature); +} + bool ModuleBase_Operation::isNestedOperationsEnabled() const { return true; diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 0a5e1a54d..8e36a7704 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -11,7 +11,7 @@ #include #include -#include "ModelAPI_Feature.h" +#include #include #include @@ -57,6 +57,9 @@ Q_OBJECT /// \return the feature FeaturePtr feature() const; + /// Returns true is feature of operation is valid. + virtual bool isValid() const; + /// Returns whether the nested operations are enabled. /// The state can depend on the operation current state. /// \return enabled state diff --git a/src/ModuleBase/ModuleBase_WidgetFactory.cpp b/src/ModuleBase/ModuleBase_WidgetFactory.cpp index 90886145f..1063cfa9a 100644 --- a/src/ModuleBase/ModuleBase_WidgetFactory.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFactory.cpp @@ -67,7 +67,7 @@ void ModuleBase_WidgetFactory::createWidget(QWidget* theParent) //Create a widget (doublevalue, groupbox, toolbox, etc. QWidget* aWidget = createWidgetByType(aWdgType, theParent); if (aWidget) { - if (!isInternalWidget(aWdgType)) { + if (!myWidgetApi->getBooleanAttribute(FEATURE_INTERNAL, false)) { aWidgetLay->addWidget(aWidget); } else { aWidget->setVisible(false); @@ -264,17 +264,6 @@ QWidget* ModuleBase_WidgetFactory::choiceControl(QWidget* theParent) return aChoiceWgt->getControl(); } -bool ModuleBase_WidgetFactory::isInternalWidget(const std::string& theType) -{ - std::string prop = myWidgetApi->getProperty(FEATURE_INTERNAL); - - std::transform(prop.begin(), prop.end(), prop.begin(), ::tolower); - if (prop.empty() || prop == "false" || prop == "0") { - return false; - } - return true; -} - QString ModuleBase_WidgetFactory::qs(const std::string& theStdString) const { return QString::fromStdString(theStdString); diff --git a/src/ModuleBase/ModuleBase_WidgetFactory.h b/src/ModuleBase/ModuleBase_WidgetFactory.h index 320e88f95..6ea4debf3 100644 --- a/src/ModuleBase/ModuleBase_WidgetFactory.h +++ b/src/ModuleBase/ModuleBase_WidgetFactory.h @@ -49,11 +49,6 @@ class MODULEBASE_EXPORT ModuleBase_WidgetFactory QWidget* fileSelectorControl(QWidget* theParent); QWidget* choiceControl(QWidget* theParent); - /// Check whether the XML definition for the given type contains internal property - /// \param theType the widget type - /// \return the boolean result - bool isInternalWidget(const std::string& theType); - QString qs(const std::string& theStdString) const; private: diff --git a/src/ModuleBase/ModuleBase_WidgetFeature.cpp b/src/ModuleBase/ModuleBase_WidgetFeature.cpp index 22b6c316f..4269711c8 100644 --- a/src/ModuleBase/ModuleBase_WidgetFeature.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFeature.cpp @@ -43,7 +43,6 @@ ModuleBase_WidgetFeature::ModuleBase_WidgetFeature(QWidget* theParent, QString anObjName = QString::fromStdString(attributeID()); myEditor->setObjectName(anObjName); myEditor->setReadOnly(true); - processFocus(myEditor); aControlLay->addWidget(myEditor); QString aTTip = QString::fromStdString(theData->widgetTooltip()); diff --git a/src/PartSet/PartSet_OperationFeatureBase.cpp b/src/PartSet/PartSet_OperationFeatureBase.cpp index 0363a3eae..e369667bb 100644 --- a/src/PartSet/PartSet_OperationFeatureBase.cpp +++ b/src/PartSet/PartSet_OperationFeatureBase.cpp @@ -116,6 +116,18 @@ void PartSet_OperationFeatureBase::mouseReleased(QMouseEvent* theEvent, Handle(V void PartSet_OperationFeatureBase::onWidgetActivated(ModuleBase_ModelWidget* theWidget) { myActiveWidget = theWidget; + activateByPreselection(); + if (myInitFeature && myActiveWidget) { + ModuleBase_WidgetPoint2D* aWgt = dynamic_cast(myActiveWidget); + if (aWgt && aWgt->initFromPrevious(myInitFeature)) { + myInitFeature = FeaturePtr(); + emit activateNextWidget(myActiveWidget); + } + } +} + +void PartSet_OperationFeatureBase::activateByPreselection() +{ if ((myPreSelection.size() > 0) && myActiveWidget) { const ModuleBase_ViewerPrs& aPrs = myPreSelection.front(); ModuleBase_WidgetValueFeature aValue; @@ -124,12 +136,9 @@ void PartSet_OperationFeatureBase::onWidgetActivated(ModuleBase_ModelWidget* the myPreSelection.remove(aPrs); emit activateNextWidget(myActiveWidget); } - } - if (myInitFeature && myActiveWidget) { - ModuleBase_WidgetPoint2D* aWgt = dynamic_cast(myActiveWidget); - if (aWgt && aWgt->initFromPrevious(myInitFeature)) { - myInitFeature = FeaturePtr(); - emit activateNextWidget(myActiveWidget); + // If preselection is enough to make a valid feature - apply it immediately + if(isValid()) { + commit(); } } } diff --git a/src/PartSet/PartSet_OperationFeatureBase.h b/src/PartSet/PartSet_OperationFeatureBase.h index 34548056b..5a0c66bf0 100644 --- a/src/PartSet/PartSet_OperationFeatureBase.h +++ b/src/PartSet/PartSet_OperationFeatureBase.h @@ -62,6 +62,8 @@ Q_OBJECT virtual void onWidgetActivated(ModuleBase_ModelWidget* theWidget); protected: + /// + void activateByPreselection(); /// Set value to the active widget /// \param theFeature the feature /// \param theX the horizontal coordinate diff --git a/src/PartSet/PartSet_OperationFeatureCreate.cpp b/src/PartSet/PartSet_OperationFeatureCreate.cpp index 845efd6a1..2fd670ace 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.cpp +++ b/src/PartSet/PartSet_OperationFeatureCreate.cpp @@ -160,8 +160,6 @@ void PartSet_OperationFeatureCreate::activateNextToCurrentWidget() void PartSet_OperationFeatureCreate::startOperation() { PartSet_OperationSketchBase::startOperation(); - //setPointSelectionMode(!myInitFeature ? SM_FirstPoint : SM_SecondPoint); - emit multiSelectionEnabled(false); } diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 04a99179e..72b96c18b 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -39,7 +39,7 @@ - + @@ -49,7 +49,7 @@ - + @@ -59,7 +59,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index aa677172b..4220b3bd0 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -5,8 +5,6 @@ #include "XGUI_OperationMgr.h" #include "ModuleBase_Operation.h" -#include -#include #include #include @@ -110,33 +108,20 @@ bool XGUI_OperationMgr::abortAllOperations() return result; } -bool XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation) -{ - if (!theOperation) - return false; - //Get operation feature to validate - FeaturePtr aFeature = theOperation->feature(); - if (!aFeature) return true; // rename operation - //Get validators for the Id - SessionPtr aMgr = ModelAPI_Session::get(); - ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - - bool isValid = aFactory->validate(aFeature); - emit operationValidated(isValid); - return isValid; -} - void XGUI_OperationMgr::onValidateOperation() { if (!hasOperation()) return; ModuleBase_Operation* anOperation = currentOperation(); - validateOperation(currentOperation()); + if(anOperation) { + bool isValid = anOperation->isValid(); + emit operationValidated(isValid); + } } bool XGUI_OperationMgr::commitOperation() { - if (validateOperation(currentOperation())) { + if (hasOperation() && currentOperation()->isValid()) { onCommitOperation(); return true; } @@ -150,20 +135,19 @@ void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation) bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation) { - bool aCanStart = true; + return true; + /*bool aCanStart = true; ModuleBase_Operation* aCurrentOp = currentOperation(); if (aCurrentOp) { if (!theOperation->isGranted()) { - if (!aCurrentOp->isValid(theOperation)) { - if (canAbortOperation()) { - aCurrentOp->abort(); - } else { - aCanStart = false; - } + if (canAbortOperation()) { + aCurrentOp->abort(); + } else { + aCanStart = false; } } } - return aCanStart; + return aCanStart;*/ } diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index e43485b5c..b028731a4 100644 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -89,10 +89,6 @@ signals: /// \return the state whether the operation is resumed void resumeOperation(ModuleBase_Operation* theOperation); - /// Checks if given operation is Valid, if so sends operationValidated signal - /// \param theOperation to be validated - /// \return validation state (true means valid) - bool validateOperation(ModuleBase_Operation* theOperation); /// Returns whether the operation can be started. Check if there is already started operation and /// the granted parameter of the launched operation /// \param theOperation an operation to check diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 25866c87c..8ed2acfce 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -495,6 +495,7 @@ void XGUI_Workshop::onOperationStarted() for (; anIt != aLast; anIt++) { aWidget = *anIt; aWidget->setFeature(aOperation->feature()); + aWidget->enableFocusProcessing(); QObject::connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged())); // Init default values if (!aOperation->isEditOperation() && !aWidget->isComputedDefault()) { -- 2.39.2