From 44d1465881d498b42548b80b26030cfea2277040 Mon Sep 17 00:00:00 2001 From: dismine Date: Fri, 29 Aug 2014 16:42:53 +0300 Subject: [PATCH] Disable multiple subexpression mode. One expresiion per time. --HG-- branch : feature --- src/app/container/calculator.cpp | 82 +------------------ src/app/container/calculator.h | 3 - src/app/container/vformula.cpp | 28 +++++-- src/app/container/vformula.h | 6 +- src/app/widgets/vformulapropertyeditor.cpp | 4 +- .../widgets/vtooloptionspropertybrowser.cpp | 2 +- src/libs/qmuparser/qmuparserbase.cpp | 14 +++- src/libs/qmuparser/qmuparserbase.h | 4 + 8 files changed, 48 insertions(+), 95 deletions(-) diff --git a/src/app/container/calculator.cpp b/src/app/container/calculator.cpp index 3ea4cb7f1..87bdd1f8d 100644 --- a/src/app/container/calculator.cpp +++ b/src/app/container/calculator.cpp @@ -55,14 +55,7 @@ Calculator::Calculator(const VContainer *data) :QmuParser(), vVarVal(nullptr), data(data) { InitCharacterSets(); - - // Add unary operators - DefinePostfixOprt(cm_Oprt, CmUnit); - DefinePostfixOprt(mm_Oprt, MmUnit); - DefinePostfixOprt(in_Oprt, InchUnit); - - SetArgSep(','); - SetDecSep('.'); + setAllowSubexpressions(false);//Only one expression per time } //--------------------------------------------------------------------------------------------------------------------- @@ -85,15 +78,12 @@ Calculator::Calculator(const QString &formula, bool fromUser) :QmuParser(), vVarVal(nullptr), data(nullptr) { InitCharacterSets(); + setAllowSubexpressions(false);//Only one expression per time SetVarFactory(AddVariable, this); // Add unary operators if (fromUser) { - DefinePostfixOprt(qApp->PostfixOperator(cm_Oprt), CmUnit); - DefinePostfixOprt(qApp->PostfixOperator(mm_Oprt), MmUnit); - DefinePostfixOprt(qApp->PostfixOperator(in_Oprt), InchUnit); - bool osSeparatorValue = qApp->getSettings()->value("configuration/osSeparator", 1).toBool(); if (osSeparatorValue) @@ -111,16 +101,13 @@ Calculator::Calculator(const QString &formula, bool fromUser) } else { - DefinePostfixOprt(cm_Oprt, CmUnit); - DefinePostfixOprt(mm_Oprt, MmUnit); - DefinePostfixOprt(in_Oprt, InchUnit); SetArgSep(','); SetDecSep('.'); } SetExpr(formula); - //Need run for making tokens. Don't catch exception here, because because we want know if formula has error. + //Need run for making tokens. Don't catch exception here, because we want know if formula has error. Eval(); } @@ -221,69 +208,6 @@ void Calculator::InitCharacterSets() DefineOprtChars(symbols + QStringLiteral("+-*^/?<>=#!$%&|~'_")); } -//--------------------------------------------------------------------------------------------------------------------- -qreal Calculator::CmUnit(qreal val) -{ - qreal unit = val; - switch (qApp->patternUnit()) - { - case Unit::Mm: - unit = val * 10.0; - break; - case Unit::Cm: - break; - case Unit::Inch: - unit = val / 2.54; - break; - default: - break; - } - - return unit; -} - -//--------------------------------------------------------------------------------------------------------------------- -qreal Calculator::MmUnit(qreal val) -{ - qreal unit = val; - switch (qApp->patternUnit()) - { - case Unit::Mm: - break; - case Unit::Cm: - unit = val / 10.0; - break; - case Unit::Inch: - unit = val / 25.4; - break; - default: - break; - } - - return unit; -} - -//--------------------------------------------------------------------------------------------------------------------- -qreal Calculator::InchUnit(qreal val) -{ - qreal unit = val; - switch (qApp->patternUnit()) - { - case Unit::Mm: - unit = val * 25.4; - break; - case Unit::Cm: - unit = val * 2.54; - break; - case Unit::Inch: - break; - default: - break; - } - - return unit; -} - //--------------------------------------------------------------------------- // Factory function for creating new parser variables // This could as well be a function performing database queries. diff --git a/src/app/container/calculator.h b/src/app/container/calculator.h index 9ec6c303d..22ec079f3 100644 --- a/src/app/container/calculator.h +++ b/src/app/container/calculator.h @@ -66,9 +66,6 @@ private: const VContainer *data; void InitVariables(const VContainer *data, const QMap &tokens); void InitCharacterSets(); - static qreal CmUnit(qreal val); - static qreal MmUnit(qreal val); - static qreal InchUnit(qreal val); static qreal* AddVariable(const QString &a_szName, void *a_pUserData); }; diff --git a/src/app/container/vformula.cpp b/src/app/container/vformula.cpp index eb3cf4d0d..412934508 100644 --- a/src/app/container/vformula.cpp +++ b/src/app/container/vformula.cpp @@ -40,7 +40,7 @@ VFormula::VFormula() //--------------------------------------------------------------------------------------------------------------------- VFormula::VFormula(const QString &formula, const VContainer *container) - :formula(formula), value(QString(tr("Error"))), checkZero(true), data(container), toolId(NULL_ID), + :formula(qApp->FormulaToUser(formula)), value(QString(tr("Error"))), checkZero(true), data(container), toolId(NULL_ID), postfix(QStringLiteral("")), _error(true) { this->formula.replace("\n", " ");// Replace line return with spaces for calc if exist @@ -90,17 +90,32 @@ bool VFormula::operator!=(const VFormula &formula) const } //--------------------------------------------------------------------------------------------------------------------- -QString VFormula::getFormula() const +QString VFormula::getFormula(FormulaType type) const { - return formula; + if (type == FormulaType::ToUser) + { + return formula; + } + else + { + return qApp->FormulaFromUser(formula); + } } //--------------------------------------------------------------------------------------------------------------------- -void VFormula::setFormula(const QString &value) +void VFormula::setFormula(const QString &value, FormulaType type) { if (formula != value) { - formula = value; + if (type == FormulaType::ToUser) + { + formula = value; + } + else + { + formula = qApp->FormulaToUser(value); + } + formula.replace("\n", " ");// Replace line return with spaces for calc if exist Eval(); } } @@ -200,7 +215,8 @@ void VFormula::Eval() try { Calculator *cal = new Calculator(data); - const qreal result = cal->EvalFormula(formula); + QString expression = qApp->FormulaFromUser(formula); + const qreal result = cal->EvalFormula(expression); delete cal; //if result equal 0 diff --git a/src/app/container/vformula.h b/src/app/container/vformula.h index c624ed829..c60453de7 100644 --- a/src/app/container/vformula.h +++ b/src/app/container/vformula.h @@ -31,6 +31,8 @@ #include +enum class FormulaType : char{ToUser, FromUser}; + class VContainer; class VFormula @@ -44,8 +46,8 @@ public: bool operator==(const VFormula &formula) const; bool operator!=(const VFormula &formula) const; - QString getFormula() const; - void setFormula(const QString &value); + QString getFormula(FormulaType type = FormulaType::ToUser) const; + void setFormula(const QString &value, FormulaType type = FormulaType::ToUser); QString getValue() const; diff --git a/src/app/widgets/vformulapropertyeditor.cpp b/src/app/widgets/vformulapropertyeditor.cpp index baa7de4b6..3118979aa 100644 --- a/src/app/widgets/vformulapropertyeditor.cpp +++ b/src/app/widgets/vformulapropertyeditor.cpp @@ -88,11 +88,11 @@ void VFormulaPropertyEditor::onToolButtonClicked() DialogEditWrongFormula* tmpWidget = new DialogEditWrongFormula(formula.getData(), formula.getToolId()); tmpWidget->setCheckZero(formula.getCheckZero()); tmpWidget->setPostfix(formula.getPostfix()); - tmpWidget->setFormula(formula.getFormula()); + tmpWidget->setFormula(formula.getFormula(FormulaType::FromUser)); if (tmpWidget->exec() == QDialog::Accepted) { - formula.setFormula(tmpWidget->getFormula()); + formula.setFormula(tmpWidget->getFormula(), FormulaType::ToUser); TextLabel->setText(formula.getValue()); delete tmpWidget; emit dataChangedByUser(formula, this); diff --git a/src/app/widgets/vtooloptionspropertybrowser.cpp b/src/app/widgets/vtooloptionspropertybrowser.cpp index 5fdae5e54..a085a493f 100644 --- a/src/app/widgets/vtooloptionspropertybrowser.cpp +++ b/src/app/widgets/vtooloptionspropertybrowser.cpp @@ -148,7 +148,7 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property) VFormula formula = variant.value(); if (formula.error() == false) { - i->setFormulaLength(variant.value().getFormula()); + i->setFormulaLength(variant.value().getFormula(FormulaType::FromUser)); } } break; diff --git a/src/libs/qmuparser/qmuparserbase.cpp b/src/libs/qmuparser/qmuparserbase.cpp index 3bf001f68..c4c30f0ee 100644 --- a/src/libs/qmuparser/qmuparserbase.cpp +++ b/src/libs/qmuparser/qmuparserbase.cpp @@ -65,7 +65,7 @@ QmuParserBase::QmuParserBase() :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), - m_nFinalResultIdx(0), m_Tokens(QMap()), m_Numbers(QMap()) + m_nFinalResultIdx(0), m_Tokens(QMap()), m_Numbers(QMap()), allowSubexpressions(true) { InitTokenReader(); } @@ -80,7 +80,7 @@ QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser) :m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(), m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(), - m_nFinalResultIdx(0), m_Tokens(QMap()), m_Numbers(QMap()) + m_nFinalResultIdx(0), m_Tokens(QMap()), m_Numbers(QMap()), allowSubexpressions(true) { m_pTokenReader.reset(new token_reader_type(this)); Assign(a_Parser); @@ -219,6 +219,12 @@ void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd) Q_UNUSED(nEnd); } +//--------------------------------------------------------------------------------------------------------------------- +void QmuParserBase::setAllowSubexpressions(bool value) +{ + allowSubexpressions = value; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief Returns the version of muparser. @@ -1323,6 +1329,10 @@ void QmuParserBase::CreateRPN() const { Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); } + if (stOpt.empty() && allowSubexpressions == false) + { + Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos()); + } ++stArgCount.top(); // fallthrough intentional (no break!) case cmEND: diff --git a/src/libs/qmuparser/qmuparserbase.h b/src/libs/qmuparser/qmuparserbase.h index d7d92c090..59d8b7c59 100644 --- a/src/libs/qmuparser/qmuparserbase.h +++ b/src/libs/qmuparser/qmuparserbase.h @@ -120,6 +120,8 @@ public: { AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() ); } + void setAllowSubexpressions(bool value); + protected: static const QStringList c_DefaultOprt; static std::locale s_locale; ///< The locale used by the parser @@ -235,6 +237,8 @@ private: mutable QMap m_Tokens;///< Keep all tokens that we can translate mutable QMap m_Numbers;///< Keep all numbers what exist in formula + bool allowSubexpressions; + void Assign(const QmuParserBase &a_Parser); void InitTokenReader(); void ReInit() const;