From 5dd20824a5f43d2b9f54a79986b659251c2489a1 Mon Sep 17 00:00:00 2001 From: vsv Date: Tue, 29 May 2018 13:38:22 +0300 Subject: [PATCH] Task 2.7: Completion for Int spin box --- src/ModuleBase/ModuleBase_ParamSpinBox.cpp | 100 ++-------------- src/ModuleBase/ModuleBase_ParamSpinBox.h | 5 +- src/ModuleBase/ModuleBase_Tools.cpp | 100 ++++++++++++++++ src/ModuleBase/ModuleBase_Tools.h | 16 +++ .../ModuleBase_WidgetDoubleValue.cpp | 113 +----------------- src/ModuleBase/ModuleBase_WidgetDoubleValue.h | 9 -- src/ModuleBase/ModuleBase_WidgetIntValue.cpp | 53 +++++++- src/ModuleBase/ModuleBase_WidgetIntValue.h | 9 +- 8 files changed, 188 insertions(+), 217 deletions(-) diff --git a/src/ModuleBase/ModuleBase_ParamSpinBox.cpp b/src/ModuleBase/ModuleBase_ParamSpinBox.cpp index b718998df..8a556c240 100644 --- a/src/ModuleBase/ModuleBase_ParamSpinBox.cpp +++ b/src/ModuleBase/ModuleBase_ParamSpinBox.cpp @@ -39,7 +39,6 @@ ModuleBase_ParamSpinBox::ModuleBase_ParamSpinBox(QWidget* theParent, int thePrec myPrecision(thePrecision), myIsEquation(false), myAcceptVariables(true), - myDecimals(3), mySingleStep(1), myMinimum(DBL_MIN), myMaximum(DBL_MAX) @@ -61,9 +60,12 @@ ModuleBase_ParamSpinBox::ModuleBase_ParamSpinBox(QWidget* theParent, int thePrec connect(lineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&))); + setLocale(QLocale::c()); + myValidator = new QDoubleValidator(this); myValidator->setLocale(locale()); myValidator->setRange(myMinimum, myMaximum); + myValidator->setDecimals(3); } void ModuleBase_ParamSpinBox::setCompletionList(QStringList& theList) @@ -80,6 +82,7 @@ ModuleBase_ParamSpinBox::~ModuleBase_ParamSpinBox() { } + /*! \brief Perform \a steps increment/decrement steps. @@ -107,38 +110,6 @@ void ModuleBase_ParamSpinBox::onTextChanged(const QString& theText) } -///*! -// \brief Connect signals and slots. -// */ -//void ModuleBase_ParamSpinBox::connectSignalsAndSlots() -//{ -// connect(this, SIGNAL(valueChanged(const QString&)), -// this, SLOT(onTextChanged(const QString&))); -//} -// -//void ModuleBase_ParamSpinBox::onTextChanged(const QString& text) -//{ -// myTextValue = text; -// emit textChanged(text); -//} -// -//double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const -//{ -// if (!hasVariable(theText)) -// return ModuleBase_DoubleSpinBox::valueFromText(theText); -// -// // small hack: return hash of the string to initiate valuesChanged signal -// return qHash(theText); -//} -// -//QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const -//{ -// if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){ -// return myTextValue; -// } -// return ModuleBase_DoubleSpinBox::textFromValue(theValue); -//} - /*! \brief This function is used to determine whether input is valid. \param str currently entered value @@ -148,8 +119,12 @@ void ModuleBase_ParamSpinBox::onTextChanged(const QString& theText) QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const { // Trying to interpret the current input text as a numeric value - if (!hasVariable(str)) + if (!hasVariable(str)) { + /// If decimals = 0 do not accept '.' (interpret as int) + if ((myValidator->decimals() == 0) && str.endsWith('.')) + return QValidator::Invalid; return myValidator->validate(str, pos); + } return isAcceptVariables() ? QValidator::Acceptable : QValidator::Invalid; } @@ -168,16 +143,13 @@ void ModuleBase_ParamSpinBox::setValue(double value) aVal = myMinimum; else if (aVal > myMaximum) aVal = myMaximum; - QString aText = QString::number(aVal, 'g', myDecimals); + QString aText = QString::number(aVal, 'g', decimals()); lineEdit()->setText(aText); emit textChanged(aText); } double ModuleBase_ParamSpinBox::value() const { - //if (myIsEquation) { - - //} return lineEdit()->text().toDouble(); } @@ -227,47 +199,6 @@ bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const return !isDouble; } -///*! -// \brief This function is used to determine whether input is valid. -// \return validating operation result -// */ -//ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText, -// double& theValue) const -//{ -// if (hasVariable() && !findVariable(theText, theValue)) { -// bool ok = false; -// theValue = locale().toDouble(theText, &ok); -// if (!ok) { -// return NoVariable; -// } -// } -// if (!checkRange(theValue)) { -// return Invalid; -// } -// -// return Acceptable; -//} -// -///*! -// \brief This function is used to check that string value lies within predefined range. -// \return check status -// */ -//bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const -//{ -// return theValue >= minimum() && theValue <= maximum(); -//} -// -///*! -// \brief This function is used to determine whether input is a variable name and to get its value. -// \return status of search operation -// */ -//bool ModuleBase_ParamSpinBox::findVariable(const QString& theName, -// double& outValue) const -//{ -// ResultParameterPtr aParam; -// return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdString(), outValue, aParam); -//} - void ModuleBase_ParamSpinBox::keyReleaseEvent(QKeyEvent* e) { switch (e->key()) { @@ -350,17 +281,6 @@ void ModuleBase_ParamSpinBox::insertCompletion(const QString& theText) } -///*! -// \brief This function is called when the spinbox receives show event. -// */ -//void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent) -//{ -// ModuleBase_DoubleSpinBox::showEvent(theEvent); -// if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) { -// setText(myTextValue); -// } -//} - void ModuleBase_ParamSpinBox::setValueEnabled(bool theEnable) { setReadOnly(!theEnable); diff --git a/src/ModuleBase/ModuleBase_ParamSpinBox.h b/src/ModuleBase/ModuleBase_ParamSpinBox.h index 4e12ffe1e..696bf0cd7 100644 --- a/src/ModuleBase/ModuleBase_ParamSpinBox.h +++ b/src/ModuleBase/ModuleBase_ParamSpinBox.h @@ -88,8 +88,8 @@ public: void setMinimum(double theMin) { myMinimum = theMin; myValidator->setBottom(theMin); } void setMaximum(double theMax) { myMaximum = theMax; myValidator->setTop(theMax); } - int decimals() const { return myDecimals; } - void setDecimals(int thePrecision) { myDecimals = thePrecision; } + int decimals() const { return myValidator->decimals(); } + void setDecimals(int thePrecision) { myValidator->setDecimals(thePrecision); } double singleStep() const { return mySingleStep; } void setSingleStep(double theStep) { mySingleStep = theStep; } @@ -150,7 +150,6 @@ private: double myMinimum; double myMaximum; - int myDecimals; int myCompletePos; double mySingleStep; diff --git a/src/ModuleBase/ModuleBase_Tools.cpp b/src/ModuleBase/ModuleBase_Tools.cpp index 10f191b27..8b09ef91a 100755 --- a/src/ModuleBase/ModuleBase_Tools.cpp +++ b/src/ModuleBase/ModuleBase_Tools.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include @@ -1169,6 +1171,104 @@ void setPointBallHighlighting(AIS_Shape* theAIS) } } +FeaturePtr createParameter(const QString& theText) +{ + FeaturePtr aParameter; + QStringList aList = theText.split("="); + if (aList.count() != 2) { + return aParameter; + } + QString aParamName = aList.at(0).trimmed(); + + if (isNameExist(aParamName, FeaturePtr())) { + return aParameter; + } + + if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) { + return aParameter; + } + + QString aExpression = aList.at(1).trimmed(); + if (aExpression.isEmpty()) { + return aParameter; + } + + SessionPtr aMgr = ModelAPI_Session::get(); + std::shared_ptr aDoc = aMgr->activeDocument(); + + aParameter = aDoc->addFeature("Parameter"); + if (aParameter.get()) { + AttributeStringPtr aNameAttr = aParameter->string("variable"); + aNameAttr->setValue(aParamName.toStdString()); + + AttributeStringPtr aExprAttr = aParameter->string("expression"); + aExprAttr->setValue(aExpression.toStdString()); + aParameter->execute(); + + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + } + return aParameter; +} + +void editParameter(FeaturePtr theParam, const QString& theText) +{ + QStringList aList = theText.split("="); + QString aParamName = aList.at(0).trimmed(); + + QString aExpression = aList.at(1).trimmed(); + if (aExpression.isEmpty()) { + return; + } + + if (isNameExist(aParamName, theParam)) { + return; + } + AttributeStringPtr aNameAttr = theParam->string("variable"); + aNameAttr->setValue(aParamName.toStdString()); + + AttributeStringPtr aExprAttr = theParam->string("expression"); + aExprAttr->setValue(aExpression.toStdString()); + theParam->execute(); + + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); +} + +bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter) +{ + SessionPtr aMgr = ModelAPI_Session::get(); + std::shared_ptr aDoc = aMgr->activeDocument(); + FeaturePtr aParamFeature; + int aNbFeatures = aDoc->numInternalFeatures(); + std::string aName = theName.toStdString(); + for (int i = 0; i < aNbFeatures; i++) { + aParamFeature = aDoc->internalFeature(i); + if (aParamFeature && aParamFeature->getKind() == "Parameter") { + if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName)) + return true; + } + } + return false; +} + +FeaturePtr findParameter(const QString& theName) +{ + SessionPtr aMgr = ModelAPI_Session::get(); + std::shared_ptr aDoc = aMgr->activeDocument(); + FeaturePtr aParamFeature; + int aNbFeatures = aDoc->numInternalFeatures(); + std::string aName = theName.toStdString(); + for (int i = 0; i < aNbFeatures; i++) { + aParamFeature = aDoc->internalFeature(i); + if (aParamFeature && aParamFeature->getKind() == "Parameter") { + if (aParamFeature->name() == aName) + return aParamFeature; + } + } + return FeaturePtr(); +} + + } // namespace ModuleBase_Tools diff --git a/src/ModuleBase/ModuleBase_Tools.h b/src/ModuleBase/ModuleBase_Tools.h index 0cd2ed2dc..4570f3fe6 100755 --- a/src/ModuleBase/ModuleBase_Tools.h +++ b/src/ModuleBase/ModuleBase_Tools.h @@ -364,6 +364,22 @@ QString MODULEBASE_EXPORT translate(const std::string& theContext, const std::st /// \param theAIS - the presentation void MODULEBASE_EXPORT setPointBallHighlighting(AIS_Shape* theAIS); +/// Creates a parameter from a given string +/// \theText a text wit equation +FeaturePtr MODULEBASE_EXPORT createParameter(const QString& theText); + +/// Edits parameter replacing its name and expression according to the given string +/// \theParam a editing parameter +/// \theText a text wit equation +void MODULEBASE_EXPORT editParameter(FeaturePtr theParam, const QString& theText); + +/// Returns True if a parameter with the given name already exists +/// \theName a name of parameter +bool MODULEBASE_EXPORT isNameExist(const QString& theName, FeaturePtr theIgnoreParameter); + +/// Find parameter by its name +/// \theName a name of parameter +FeaturePtr MODULEBASE_EXPORT findParameter(const QString& theName); } #endif diff --git a/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp b/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp index 62aa739f3..117cc8c08 100644 --- a/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp +++ b/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp @@ -25,14 +25,13 @@ #include #include #include -#include -#include #include #include #include #include #include #include +#include #include #include @@ -55,8 +54,6 @@ #include #endif -#define DEBUG_COMPLETE_WITH_PARAMETERS - ModuleBase_WidgetDoubleValue::ModuleBase_WidgetDoubleValue(QWidget* theParent, const Config_WidgetAPI* theData) : ModuleBase_ModelWidget(theParent, theData) @@ -126,11 +123,9 @@ ModuleBase_WidgetDoubleValue::~ModuleBase_WidgetDoubleValue() void ModuleBase_WidgetDoubleValue::activateCustom() { ModuleBase_ModelWidget::activateCustom(); -#ifdef DEBUG_COMPLETE_WITH_PARAMETERS QStringList aParameters; ModuleBase_Tools::getParameters(aParameters); mySpinBox->setCompletionList(aParameters); -#endif } bool ModuleBase_WidgetDoubleValue::resetCustom() @@ -161,18 +156,18 @@ bool ModuleBase_WidgetDoubleValue::storeValueCustom() QString aText = mySpinBox->text(); if (aText.contains('=')) { if (!myParameter.get()) { - myParameter = createParameter(aText); + myParameter = ModuleBase_Tools::createParameter(aText); if (!myParameter.get()) { aReal->setExpressionError("Parameter cannot be created"); aReal->setExpressionInvalid(true); - mySpinBox->setText(aReal->text().c_str()); + updateObject(myFeature); return false; } else if (aReal->expressionInvalid()) { aReal->setExpressionError(""); aReal->setExpressionInvalid(false); } } else { - editParameter(aText); + ModuleBase_Tools::editParameter(myParameter, aText); } aText = aText.split('=').at(0) + "="; } else if (myParameter.get()){ @@ -201,7 +196,7 @@ bool ModuleBase_WidgetDoubleValue::restoreValueCustom() if (aText.endsWith('=')) { if (!myParameter.get()) { QString aName = aText.left(aText.indexOf('=')).trimmed(); - myParameter = findParameter(aName); + myParameter = ModuleBase_Tools::findParameter(aName); } /// If myParameter is empty then it was not created because of an error if (!myParameter.get()) @@ -238,101 +233,3 @@ bool ModuleBase_WidgetDoubleValue::processEnter() } return isModified; } - - -FeaturePtr ModuleBase_WidgetDoubleValue::createParameter(const QString& theText) const -{ - FeaturePtr aParameter; - QStringList aList = theText.split("="); - if (aList.count() != 2) { - return aParameter; - } - QString aParamName = aList.at(0).trimmed(); - - if (isNameExist(aParamName)) { - return aParameter; - } - - if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) { - return aParameter; - } - - QString aExpression = aList.at(1).trimmed(); - if (aExpression.isEmpty()) { - return aParameter; - } - - SessionPtr aMgr = ModelAPI_Session::get(); - std::shared_ptr aDoc = aMgr->activeDocument(); - - aParameter = aDoc->addFeature("Parameter"); - if (aParameter.get()) { - AttributeStringPtr aNameAttr = aParameter->string("variable"); - aNameAttr->setValue(aParamName.toStdString()); - - AttributeStringPtr aExprAttr = aParameter->string("expression"); - aExprAttr->setValue(aExpression.toStdString()); - aParameter->execute(); - - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - } - return aParameter; -} - -bool ModuleBase_WidgetDoubleValue::isNameExist(const QString& theName) const -{ - SessionPtr aMgr = ModelAPI_Session::get(); - std::shared_ptr aDoc = aMgr->activeDocument(); - FeaturePtr aParamFeature; - int aNbFeatures = aDoc->numInternalFeatures(); - std::string aName = theName.toStdString(); - for (int i = 0; i < aNbFeatures; i++) { - aParamFeature = aDoc->internalFeature(i); - if (aParamFeature && aParamFeature->getKind() == "Parameter") { - if ((myParameter != aParamFeature) && (aParamFeature->name() == aName)) - return true; - } - } - return false; -} - -void ModuleBase_WidgetDoubleValue::editParameter(const QString& theText) -{ - QStringList aList = theText.split("="); - QString aParamName = aList.at(0).trimmed(); - - QString aExpression = aList.at(1).trimmed(); - if (aExpression.isEmpty()) { - return; - } - - if (isNameExist(aParamName)) { - return; - } - AttributeStringPtr aNameAttr = myParameter->string("variable"); - aNameAttr->setValue(aParamName.toStdString()); - - AttributeStringPtr aExprAttr = myParameter->string("expression"); - aExprAttr->setValue(aExpression.toStdString()); - myParameter->execute(); - - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); -} - -FeaturePtr ModuleBase_WidgetDoubleValue::findParameter(const QString& theName) const -{ - SessionPtr aMgr = ModelAPI_Session::get(); - std::shared_ptr aDoc = aMgr->activeDocument(); - FeaturePtr aParamFeature; - int aNbFeatures = aDoc->numInternalFeatures(); - std::string aName = theName.toStdString(); - for (int i = 0; i < aNbFeatures; i++) { - aParamFeature = aDoc->internalFeature(i); - if (aParamFeature && aParamFeature->getKind() == "Parameter") { - if (aParamFeature->name() == aName) - return aParamFeature; - } - } - return FeaturePtr(); -} diff --git a/src/ModuleBase/ModuleBase_WidgetDoubleValue.h b/src/ModuleBase/ModuleBase_WidgetDoubleValue.h index 28d7b4e2e..4cdae391d 100644 --- a/src/ModuleBase/ModuleBase_WidgetDoubleValue.h +++ b/src/ModuleBase/ModuleBase_WidgetDoubleValue.h @@ -80,15 +80,6 @@ protected: /// \return true if the widget current value is reset virtual bool resetCustom(); -private: - FeaturePtr createParameter(const QString& theText) const; - - void editParameter(const QString& theText); - - bool isNameExist(const QString& theName) const; - - FeaturePtr findParameter(const QString& theName) const; - protected: /// Label of the widget QLabel* myLabel; diff --git a/src/ModuleBase/ModuleBase_WidgetIntValue.cpp b/src/ModuleBase/ModuleBase_WidgetIntValue.cpp index abfead215..e694d35f5 100644 --- a/src/ModuleBase/ModuleBase_WidgetIntValue.cpp +++ b/src/ModuleBase/ModuleBase_WidgetIntValue.cpp @@ -21,11 +21,12 @@ #include #include #include -#include +#include #include #include #include +#include #include #include @@ -62,7 +63,8 @@ ModuleBase_WidgetIntValue::ModuleBase_WidgetIntValue(QWidget* theParent, if (!aLabelIcon.isEmpty()) myLabel->setPixmap(ModuleBase_IconFactory::loadPixmap(aLabelIcon)); - mySpinBox = new ModuleBase_ParamIntSpinBox(this); + mySpinBox = new ModuleBase_ParamSpinBox(this); + mySpinBox->setDecimals(0); QString anObjName = QString::fromStdString(attributeID()); mySpinBox->setObjectName(anObjName); @@ -106,6 +108,14 @@ ModuleBase_WidgetIntValue::~ModuleBase_WidgetIntValue() { } +void ModuleBase_WidgetIntValue::activateCustom() +{ + ModuleBase_ModelWidget::activateCustom(); + QStringList aParameters; + ModuleBase_Tools::getParameters(aParameters); + mySpinBox->setCompletionList(aParameters); +} + bool ModuleBase_WidgetIntValue::resetCustom() { bool aDone = false; @@ -131,8 +141,28 @@ bool ModuleBase_WidgetIntValue::storeValueCustom() AttributeIntegerPtr anAttribute = aData->integer(attributeID()); if (mySpinBox->hasVariable()) { // Here is a text of a real value or an expression. - std::string aText = mySpinBox->text().toStdString(); - anAttribute->setText(aText); + QString aText = mySpinBox->text(); + if (aText.contains('=')) { + if (!myParameter.get()) { + myParameter = ModuleBase_Tools::createParameter(aText); + if (!myParameter.get()) { + anAttribute->setExpressionError("Parameter cannot be created"); + anAttribute->setExpressionInvalid(true); + updateObject(myFeature); + return false; + } else if (anAttribute->expressionInvalid()) { + anAttribute->setExpressionError(""); + anAttribute->setExpressionInvalid(false); + } + } else { + ModuleBase_Tools::editParameter(myParameter, aText); + } + aText = aText.split('=').at(0) + "="; + } else if (myParameter.get()) { + // Nullyfy the parameter reference without deletion of the created + myParameter = FeaturePtr(); + } + anAttribute->setText(aText.toStdString()); } else { // it is important to set the empty text value to the attribute before set the value // because setValue tries to calculate the attribute value according to the @@ -150,7 +180,20 @@ bool ModuleBase_WidgetIntValue::restoreValueCustom() AttributeIntegerPtr anAttribute = aData->integer(attributeID()); std::string aTextRepr = anAttribute->text(); if (!aTextRepr.empty()) { - ModuleBase_Tools::setSpinText(mySpinBox, QString::fromStdString(aTextRepr)); + QString aText = QString::fromStdString(aTextRepr); + if (aText.endsWith('=')) { + if (!myParameter.get()) { + QString aName = aText.left(aText.indexOf('=')).trimmed(); + myParameter = ModuleBase_Tools::findParameter(aName); + } + /// If myParameter is empty then it was not created because of an error + if (!myParameter.get()) + return false; + + AttributeStringPtr aExprAttr = myParameter->string("expression"); + aText += aExprAttr->value().c_str(); + } + ModuleBase_Tools::setSpinText(mySpinBox, aText); } else { ModuleBase_Tools::setSpinValue(mySpinBox, anAttribute->value()); } diff --git a/src/ModuleBase/ModuleBase_WidgetIntValue.h b/src/ModuleBase/ModuleBase_WidgetIntValue.h index 0394458c9..bcd45d4b1 100644 --- a/src/ModuleBase/ModuleBase_WidgetIntValue.h +++ b/src/ModuleBase/ModuleBase_WidgetIntValue.h @@ -24,7 +24,7 @@ #include "ModuleBase.h" #include "ModuleBase_ModelWidget.h" -class ModuleBase_ParamIntSpinBox; +class ModuleBase_ParamSpinBox; class Config_WidgetAPI; class QWidget; class QLabel; @@ -49,6 +49,9 @@ Q_OBJECT virtual ~ModuleBase_WidgetIntValue(); + /// The methiod called when widget is activated + virtual void activateCustom(); + /// Select the internal content if it can be selected. It is empty in the default realization virtual void selectContent(); @@ -77,7 +80,9 @@ protected: QLabel* myLabel; /// Input value control - ModuleBase_ParamIntSpinBox* mySpinBox; + ModuleBase_ParamSpinBox* mySpinBox; + + FeaturePtr myParameter; }; #endif -- 2.39.2