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;
#include <libxml/parser.h>
#include <libxml/tree.h>
+#include <string>
+#include <algorithm>
+
Config_WidgetAPI::Config_WidgetAPI(std::string theRawXml)
{
myDoc = xmlParseDoc(BAD_CAST theRawXml.c_str());
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);
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:
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
#include <ModelAPI_Attribute.h>
#include <ModelAPI_Events.h>
-#include "Config_WidgetAPI.h"
+#include <Config_Keywords.h>
+#include <Config_WidgetAPI.h>
#include <Events_Loop.h>
myParentId(theParentId)
{
myIsComputedDefault = false;
+ myIsObligatory = theData ? theData->getBooleanAttribute(FEATURE_OBLIGATORY, true) : true;
myAttributeID = theData ? theData->widgetId() : "";
}
return theObject->data()->attribute(attributeID())->isInitialized();
}
+void ModuleBase_ModelWidget::enableFocusProcessing()
+{
+ QList<QWidget*> aMyControls = getControls();
+ foreach(QWidget* eachControl, aMyControls) {
+ if(!myFocusInWidgets.contains(eachControl)) {
+ enableFocusProcessing(eachControl);
+ }
+ }
+}
+
bool ModuleBase_ModelWidget::focusTo()
{
QList<QWidget*> aControls = getControls();
return true;
}
+
void ModuleBase_ModelWidget::updateObject(ObjectPtr theObj) const
{
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
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);
bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
{
QWidget* aWidget = dynamic_cast<QWidget*>(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);
}
/// \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
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
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
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;
#include <ModuleBase.h>
#include <ModuleBase_IOperation.h>
-#include "ModelAPI_Feature.h"
+#include <ModelAPI_Feature.h>
#include <QObject>
#include <QString>
/// \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
//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);
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);
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:
QString anObjName = QString::fromStdString(attributeID());
myEditor->setObjectName(anObjName);
myEditor->setReadOnly(true);
- processFocus(myEditor);
aControlLay->addWidget(myEditor);
QString aTTip = QString::fromStdString(theData->widgetTooltip());
void PartSet_OperationFeatureBase::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
{
myActiveWidget = theWidget;
+ activateByPreselection();
+ if (myInitFeature && myActiveWidget) {
+ ModuleBase_WidgetPoint2D* aWgt = dynamic_cast<ModuleBase_WidgetPoint2D*>(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;
myPreSelection.remove(aPrs);
emit activateNextWidget(myActiveWidget);
}
- }
- if (myInitFeature && myActiveWidget) {
- ModuleBase_WidgetPoint2D* aWgt = dynamic_cast<ModuleBase_WidgetPoint2D*>(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();
}
}
}
virtual void onWidgetActivated(ModuleBase_ModelWidget* theWidget);
protected:
+ ///
+ void activateByPreselection();
/// Set value to the active widget
/// \param theFeature the feature
/// \param theX the horizontal coordinate
void PartSet_OperationFeatureCreate::startOperation()
{
PartSet_OperationSketchBase::startOperation();
- //setPointSelectionMode(!myInitFeature ? SM_FirstPoint : SM_SecondPoint);
-
emit multiSelectionEnabled(false);
}
<validator id="SketchPlugin_ResultLine"/>
<validator id="SketchPlugin_DistanceAttr" parameters="ConstraintEntityA"/>
</feature_or_attribute_selector>
- <point_selector id="ConstraintFlyoutValuePnt" internal="1"/>
+ <point_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
<doublevalue_editor label="Value" tooltip="Constraint value" id="ConstraintValue" default="computed"/>
<validator id="PartSet_DistanceValidator"/>
</feature>
<feature_selector id="ConstraintEntityA" label="Line" tooltip="Select an line in the viewer">
<validator id="SketchPlugin_ResultLine"/>
</feature_selector>
- <point_selector id="ConstraintFlyoutValuePnt" internal="1"/>
+ <point_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
<doublevalue_editor label="Value" tooltip="Constraint value" id="ConstraintValue" default="computed"/>
<validator id="PartSet_LengthValidator"/>
</feature>
<feature_selector id="ConstraintEntityA" label="Circle or Arc" tooltip="Select a circle or an arc in the viewer">
<validator id="SketchPlugin_ResultArc"/>
</feature_selector>
- <point_selector id="ConstraintFlyoutValuePnt" internal="1"/>
+ <point_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
<doublevalue_editor label="Value" tooltip="Constraint value" id="ConstraintValue" default="computed"/>
<validator id="PartSet_RadiusValidator"/>
</feature>
<validator id="SketchPlugin_ResultLine"/>
<validator id="SketchPlugin_DifferentObjects"/>
</feature_selector>
- <point_selector id="ConstraintFlyoutValuePnt" internal="1"/>
+ <point_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
<validator id="PartSet_ParallelValidator"/>
</feature>
#include "XGUI_OperationMgr.h"
#include "ModuleBase_Operation.h"
-#include <ModelAPI_Validator.h>
-#include <ModelAPI_FeatureValidator.h>
#include <QMessageBox>
#include <QApplication>
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;
}
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;*/
}
/// \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
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()) {