Disable multiple subexpression mode. One expresiion per time.

--HG--
branch : feature
This commit is contained in:
dismine 2014-08-29 16:42:53 +03:00
parent 2b83e18773
commit 44d1465881
8 changed files with 48 additions and 95 deletions

View File

@ -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.

View File

@ -66,9 +66,6 @@ private:
const VContainer *data;
void InitVariables(const VContainer *data, const QMap<int, QString> &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);
};

View File

@ -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
{
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)
{
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

View File

@ -31,6 +31,8 @@
#include <QCoreApplication>
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;

View File

@ -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);

View File

@ -148,7 +148,7 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property)
VFormula formula = variant.value<VFormula>();
if (formula.error() == false)
{
i->setFormulaLength(variant.value<VFormula>().getFormula());
i->setFormulaLength(variant.value<VFormula>().getFormula(FormulaType::FromUser));
}
}
break;

View File

@ -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<int, QString>()), m_Numbers(QMap<int, QString>())
m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()), 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<int, QString>()), m_Numbers(QMap<int, QString>())
m_nFinalResultIdx(0), m_Tokens(QMap<int, QString>()), m_Numbers(QMap<int, QString>()), 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:

View File

@ -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<int, QString> m_Tokens;///< Keep all tokens that we can translate
mutable QMap<int, QString> m_Numbers;///< Keep all numbers what exist in formula
bool allowSubexpressions;
void Assign(const QmuParserBase &a_Parser);
void InitTokenReader();
void ReInit() const;