Translation formula.

--HG--
branch : feature
This commit is contained in:
dismine 2014-05-23 21:11:13 +03:00
parent b94ab9bda6
commit 0f4cd08eed
21 changed files with 331 additions and 33 deletions

View file

@ -40,20 +40,7 @@ int Calculator::iVal = -1;
Calculator::Calculator(const VContainer *data)
:QmuParser(), vVarVal(nullptr)
{
//String with all unique symbols for supported alpabets.
// See script alphabets.py for generation and more information.
const QString symbols = QStringLiteral("ցЀĆЈVӧĎАғΕĖӅИқΝĞơРңњΥĦШҫ̆جگĮаҳѕεشԶиһνԾрυلՆӝшËՎҔPÓՖXӛӟŞӣզhëծpóӞնxßվāŁЃֆĉЋCŬđ"
"ҐГΒęҘЛΚŘġҠУGاհЫدԱҰгβطԹõлκKՁÀуςهՉÈыvیՑÐSOřӘћաőcӐթèkàѓżűðsķչøӥӔĀփїІĈЎґĐΗЖҙĘȚ"
"ΟОҡĠآΧЦتЮұİزηжԸغοоÁՀقχцÉՈيюÑՐђӋіәťӆўáŠĺѐfөըnñŰӤӨӹոľЁրăЉŭċБӸēłΔҖЙŤěΜӜDСձģΤӰ"
"ЩīņحҮбưԳصδHйԻŇμӲӴсՃمτƠщՋєLQŹՓŕÖYśÞaգĽæiŽիӓîqճöyջþĂօЄӦĊЌΑĒДҗјΙȘĚМΡéĵĢФūӚΩبĪ"
"ЬүќαذԲдҷιظԺмρՂфÇωوՊьÏՒTŚĻJբdçժlïӪղtպӫAւąЇčŃЏĕӯЗΖEțŮĝПΞأĥĹЧΦثÆӳЯIسŲԵзζԽпξكՅ"
"ÄчφNMՍӌяӢՕÔWÎŝÜџёźեägխoӒյôwĶBžսüЂĄև̈ЊČƏљΓВҕĔӮΛКĜΣТҥĤکЪƯخγвŅԴŪضλкԼĴσтÅՄنъÍՌR"
"ӕՔZÝŜbåդjíլļrӵմzýռپêЅքćچЍďӱҒЕůėژșΘØҚНğńءΠFҢХħΨҪЭųįҶرҲеԷňعθҺнԿفπÂхՇψÊэšՏÒU"
"əÚѝŻşҤӑâeէŐımկòuշÕúտŔ");
// Defining identifier character sets
DefineNameChars(QStringLiteral("0123456789_") + symbols);
DefineOprtChars(symbols + QStringLiteral("+-*^/?<>=#!$%&|~'_"));
InitCharacterSets();
// Add variables
InitVariables(data);
@ -62,8 +49,35 @@ Calculator::Calculator(const VContainer *data)
DefinePostfixOprt(cm_Oprt, CmUnit);
DefinePostfixOprt(mm_Oprt, MmUnit);
DefinePostfixOprt(in_Oprt, InchUnit);
}
//---------------------------------------------------------------------------------------------------------------------
Calculator::Calculator(const QString &formula, bool fromUser)
:QmuParser(), vVarVal(nullptr)
{
InitCharacterSets();
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);
QLocale loc = QLocale();
SetDecSep(loc.decimalPoint().toLatin1());
SetThousandsSep(loc.groupSeparator().toLatin1());
SetArgSep(';');
}
else
{
DefinePostfixOprt(cm_Oprt, CmUnit);
DefinePostfixOprt(mm_Oprt, MmUnit);
DefinePostfixOprt(in_Oprt, InchUnit);
}
SetExpr(formula);
}
Calculator::~Calculator()
@ -210,6 +224,24 @@ void Calculator::InitVariables(const VContainer *data)
}
}
void Calculator::InitCharacterSets()
{
//String with all unique symbols for supported alpabets.
// See script alphabets.py for generation and more information.
const QString symbols = QStringLiteral("ցЀĆЈVӧĎАғΕĖӅИқΝĞơРңњΥĦШҫ̆جگĮаҳѕεشԶиһνԾрυلՆӝшËՎҔPÓՖXӛӟŞӣզhëծpóӞնxßվāŁЃֆĉЋCŬđ"
"ҐГΒęҘЛΚŘġҠУGاհЫدԱҰгβطԹõлκKՁÀуςهՉÈыvیՑÐSOřӘћաőcӐթèkàѓżűðsķչøӥӔĀփїІĈЎґĐΗЖҙĘȚ"
"ΟОҡĠآΧЦتЮұİزηжԸغοоÁՀقχцÉՈيюÑՐђӋіәťӆўáŠĺѐfөըnñŰӤӨӹոľЁրăЉŭċБӸēłΔҖЙŤěΜӜDСձģΤӰ"
"ЩīņحҮбưԳصδHйԻŇμӲӴсՃمτƠщՋєLQŹՓŕÖYśÞaգĽæiŽիӓîqճöyջþĂօЄӦĊЌΑĒДҗјΙȘĚМΡéĵĢФūӚΩبĪ"
"ЬүќαذԲдҷιظԺмρՂфÇωوՊьÏՒTŚĻJբdçժlïӪղtպӫAւąЇčŃЏĕӯЗΖEțŮĝПΞأĥĹЧΦثÆӳЯIسŲԵзζԽпξكՅ"
"ÄчφNMՍӌяӢՕÔWÎŝÜџёźեägխoӒյôwĶBžսüЂĄև̈ЊČƏљΓВҕĔӮΛКĜΣТҥĤکЪƯخγвŅԴŪضλкԼĴσтÅՄنъÍՌR"
"ӕՔZÝŜbåդjíլļrӵմzýռپêЅքćچЍďӱҒЕůėژșΘØҚНğńءΠFҢХħΨҪЭųįҶرҲеԷňعθҺнԿفπÂхՇψÊэšՏÒU"
"əÚѝŻşҤӑâeէŐımկòuշÕúտŔ");
// Defining identifier character sets
DefineNameChars(QStringLiteral("0123456789_") + symbols);
DefineOprtChars(symbols + QStringLiteral("+-*^/?<>=#!$%&|~'_"));
}
//---------------------------------------------------------------------------------------------------------------------
qreal Calculator::CmUnit(qreal val)
{

View file

@ -37,7 +37,8 @@ using namespace qmu;
class Calculator:public QmuParser
{
public:
explicit Calculator(const VContainer *data);
Calculator(const VContainer *data);
Calculator(const QString &formula, bool fromUser = true);
~Calculator();
qreal EvalFormula(const QString &formula);
private:
@ -45,6 +46,7 @@ private:
qreal *vVarVal;
static int iVal;
void InitVariables(const VContainer *data);
void InitCharacterSets();
static qreal CmUnit(qreal val);
static qreal MmUnit(qreal val);
static qreal InchUnit(qreal val);

View file

@ -119,7 +119,7 @@ void DialogAlongLine::setFirstPointId(const quint32 &value, const quint32 &id)
//---------------------------------------------------------------------------------------------------------------------
void DialogAlongLine::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -157,7 +157,7 @@ inline QString DialogAlongLine::getTypeLine() const
inline QString DialogAlongLine::getFormula() const
{
return formula;
return qApp->FormulaFromUser(formula);
}
inline quint32 DialogAlongLine::getFirstPointId() const

View file

@ -128,7 +128,7 @@ void DialogBisector::setTypeLine(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
void DialogBisector::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -167,7 +167,7 @@ inline QString DialogBisector::getTypeLine() const
inline QString DialogBisector::getFormula() const
{
return formula;
return qApp->FormulaFromUser(formula);
}
inline quint32 DialogBisector::getFirstPointId() const

View file

@ -91,7 +91,7 @@ void DialogCutArc::setArcId(const quint32 &value, const quint32 &id)
//---------------------------------------------------------------------------------------------------------------------
void DialogCutArc::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -64,7 +64,7 @@ public:
* @brief getFormula return string with formula length
* @return formula
*/
QString getFormula() const {return formula;}
QString getFormula() const {return qApp->FormulaFromUser(formula);}
/**
* @brief setFormula set string with formula length
* @param value string with formula

View file

@ -70,7 +70,7 @@ void DialogCutSpline::setPointName(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
void DialogCutSpline::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -119,7 +119,7 @@ inline QString DialogCutSpline::getPointName() const
inline QString DialogCutSpline::getFormula() const
{
return formula;
return qApp->FormulaFromUser(formula);
}
inline quint32 DialogCutSpline::getSplineId() const

View file

@ -71,7 +71,7 @@ void DialogCutSplinePath::setPointName(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
void DialogCutSplinePath::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -119,7 +119,7 @@ inline QString DialogCutSplinePath::getPointName() const
inline QString DialogCutSplinePath::getFormula() const
{
return formula;
return qApp->FormulaFromUser(formula);
}
inline quint32 DialogCutSplinePath::getSplinePathId() const

View file

@ -89,7 +89,7 @@ void DialogEndLine::setTypeLine(const QString &value)
//---------------------------------------------------------------------------------------------------------------------
void DialogEndLine::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -152,7 +152,7 @@ inline QString DialogEndLine::getTypeLine() const
inline QString DialogEndLine::getFormula() const
{
return formula;
return qApp->FormulaFromUser(formula);
}
inline qreal DialogEndLine::getAngle() const

View file

@ -128,7 +128,7 @@ void DialogNormal::setAngle(const qreal &value)
//---------------------------------------------------------------------------------------------------------------------
void DialogNormal::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -171,7 +171,7 @@ inline QString DialogNormal::getTypeLine() const
inline QString DialogNormal::getFormula() const
{
return formula;
return qApp->FormulaFromUser(formula);
}
inline qreal DialogNormal::getAngle() const

View file

@ -145,7 +145,7 @@ void DialogShoulderPoint::setP1Line(const quint32 &value, const quint32 &id)
//---------------------------------------------------------------------------------------------------------------------
void DialogShoulderPoint::setFormula(const QString &value)
{
formula = value;
formula = qApp->FormulaToUser(value);
ui->lineEditFormula->setText(formula);
}

View file

@ -172,7 +172,7 @@ inline QString DialogShoulderPoint::getTypeLine() const
inline QString DialogShoulderPoint::getFormula() const
{
return formula;
return qApp->FormulaFromUser(formula);
}
inline quint32 DialogShoulderPoint::getP1Line() const

View file

@ -332,8 +332,9 @@ void DialogTool::Eval(QLineEdit *edit, bool &flag, QTimer *timer, QLabel *label)
{
try
{
const QString formula = qApp->FormulaFromUser(edit->text());
Calculator cal(data);
const qreal result = cal.EvalFormula(edit->text());
const qreal result = cal.EvalFormula(formula);
label->setText(QString().setNum(result));
flag = true;
@ -345,7 +346,7 @@ void DialogTool::Eval(QLineEdit *edit, bool &flag, QTimer *timer, QLabel *label)
label->setText(tr("Error"));
flag = false;
palette.setColor(labelEditFormula->foregroundRole(), Qt::red);
emit ToolTip(e.GetMsg());
emit ToolTip("Parser error: "+e.GetMsg());
qDebug() << "\nMath parser error:\n"
<< "--------------------------------------\n"
<< "Message: " << e.GetMsg() << "\n"

View file

@ -37,6 +37,8 @@
#include <QDebug>
#include <QDir>
#include <container/calculator.h>
const qreal VApplication::PrintDPI = 96.0;
#define DefWidth 1.2//mm
@ -632,6 +634,7 @@ void VApplication::InitFunctions()
functions.insert(avg_F, VTranslation::translate(context, avg_F, QStringLiteral("mean value of all arguments")));
}
//---------------------------------------------------------------------------------------------------------------------
void VApplication::InitPostfixOperators()
{
const QString context = QStringLiteral("PostfixOperators");
@ -641,6 +644,86 @@ void VApplication::InitPostfixOperators()
postfixOperators.insert(in_Oprt, VTranslation::translate(context, in_Oprt, QStringLiteral("inch")));
}
//---------------------------------------------------------------------------------------------------------------------
bool VApplication::Measurements(QString &newFormula, int position, const QString &token)
{
QMap<QString, VTranslation>::const_iterator i = measurements.constBegin();
while (i != measurements.constEnd())
{
if(token == i.value().translate())
{
newFormula.replace(position, token.length(), i.key());
return true;
}
++i;
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------
bool VApplication::VariablesFromUser(QString &newFormula, int position, const QString &token)
{
QMap<QString, VTranslation>::const_iterator i = variables.constBegin();
while (i != variables.constEnd())
{
if(token.indexOf( i.value().translate() ) == 0)
{
newFormula.replace(position, i.value().translate().length(), i.key());
return true;
}
++i;
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------
bool VApplication::PostfixOperators(QString &newFormula, int position, const QString &token)
{
QMap<QString, VTranslation>::const_iterator i = postfixOperators.constBegin();
while (i != postfixOperators.constEnd())
{
if(token == i.value().translate())
{
newFormula.replace(position, token.length(), i.key());
return true;
}
++i;
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------
bool VApplication::Functions(QString &newFormula, int position, const QString &token)
{
QMap<QString, VTranslation>::const_iterator i = functions.constBegin();
while (i != functions.constEnd())
{
if(token == i.value().translate())
{
newFormula.replace(position, token.length(), i.key());
return true;
}
++i;
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------
bool VApplication::VariablesToUser(QString &newFormula, int position, const QString &token)
{
QMap<QString, VTranslation>::const_iterator i = variables.constBegin();
while (i != variables.constEnd())
{
if(token.indexOf( i.key() ) == 0)
{
newFormula.replace(position, variables.value(i.key()).translate().length(), i.value().translate());
return true;
}
++i;
}
return false;
}
//---------------------------------------------------------------------------------------------------------------------
void VApplication::setPatternUnit(const Valentina::Units &patternUnit)
{
@ -677,3 +760,175 @@ QString VApplication::Function(const QString &name) const
{
return functions.value(name).translate();
}
//---------------------------------------------------------------------------------------------------------------------
QString VApplication::PostfixOperator(const QString &name) const
{
return postfixOperators.value(name).translate();
}
//---------------------------------------------------------------------------------------------------------------------
QString VApplication::FormulaFromUser(const QString &formula)
{
QString newFormula = formula;
QMap<int, QString> tokens;
QMap<int, QString> numbers;
try
{
Calculator cal(formula);
tokens = cal.GetTokens();
numbers = cal.GetNumbers();
}
catch(qmu::QmuParserError &e)
{
qDebug() << "\nMath parser error:\n"
<< "--------------------------------------\n"
<< "Message: " << e.GetMsg() << "\n"
<< "Expression: " << e.GetExpr() << "\n"
<< "--------------------------------------";
return newFormula;
}
QMap<int, QString>::const_iterator i = tokens.constBegin();
while (i != tokens.constEnd())
{
if(Measurements(newFormula, i.key(), i.value()))
{
++i;
continue;
}
if(VariablesFromUser(newFormula, i.key(), i.value()))
{
++i;
continue;
}
if(PostfixOperators(newFormula, i.key(), i.value()))
{
++i;
continue;
}
if(Functions(newFormula, i.key(), i.value()))
{
++i;
continue;
}
++i;
}
QLocale loc = QLocale();
if(loc != QLocale(QLocale::C))
{
QMap<int, QString>::const_iterator i = numbers.constBegin();
while (i != numbers.constEnd())
{
QLocale::setDefault(QLocale::C);
bool ok = false;
qreal d = QString(i.value()).toDouble(&ok);
if(ok == false)
{
qDebug()<<"Can't convert to double token"<<i.value();
++i;
continue;
}
if(qFloor (d) < d)
{
QLocale::setDefault(QLocale::system());
QLocale loc = QLocale();
QString dStr = loc.toString(d);
newFormula.replace(i.key(), i.value().length(), dStr);
}
++i;
}
}
return newFormula;
}
//---------------------------------------------------------------------------------------------------------------------
QString VApplication::FormulaToUser(const QString &formula)
{
QString newFormula = formula;
QMap<int, QString> tokens;
QMap<int, QString> numbers;
try
{
Calculator cal(formula);
tokens = cal.GetTokens();
numbers = cal.GetNumbers();
}
catch (qmu::QmuParserError &e)
{
qDebug() << "\nMath parser error:\n"
<< "--------------------------------------\n"
<< "Message: " << e.GetMsg() << "\n"
<< "Expression: " << e.GetExpr() << "\n"
<< "--------------------------------------";
return newFormula;
}
QMap<int, QString>::const_iterator i = tokens.constBegin();
while (i != tokens.constEnd())
{
if (measurements.contains(i.value()))
{
newFormula.replace(i.key(), i.value().length(), measurements.value(i.value()).translate());
++i;
continue;
}
if (functions.contains(i.value()))
{
newFormula.replace(i.key(), i.value().length(), functions.value(i.value()).translate());
++i;
continue;
}
if (postfixOperators.contains(i.value()))
{
newFormula.replace(i.key(), i.value().length(), postfixOperators.value(i.value()).translate());
++i;
continue;
}
if(VariablesToUser(newFormula, i.key(), i.value()))
{
++i;
continue;
}
}
QLocale loc = QLocale();
if(loc != QLocale::C)
{
QMap<int, QString>::const_iterator i = numbers.constBegin();
while (i != numbers.constEnd())
{
bool ok = false;
qreal d = QString(i.value()).toDouble(&ok);
if(ok == false)
{
qDebug()<<"Can't convert to double token"<<i.value();
++i;
continue;
}
if(qFloor (d) < d)
{
QLocale::setDefault(QLocale::C);
QLocale loc = QLocale();
QString dStr = loc.toString(d);
newFormula.replace(i.key(), i.value().length(), dStr);
QLocale::setDefault(QLocale::system());
}
++i;
}
}
return newFormula;
}

View file

@ -77,6 +77,9 @@ public:
QString Description(const QString &measurement) const;
QString Variable(const QString &name) const;
QString Function(const QString &name) const;
QString PostfixOperator(const QString &name) const;
QString FormulaFromUser(const QString &formula);
QString FormulaToUser(const QString &formula);
private:
Valentina::Units _patternUnit;
Pattern::Measurements _patternType;
@ -94,6 +97,11 @@ private:
void InitVariables();
void InitFunctions();
void InitPostfixOperators();
bool Measurements(QString &newFormula, int position, const QString &token);
bool VariablesFromUser(QString &newFormula, int position, const QString &token);
bool PostfixOperators(QString &newFormula, int position, const QString &token);
bool Functions(QString &newFormula, int position, const QString &token);
bool VariablesToUser(QString &newFormula, int position, const QString &token);
};
inline Valentina::Units VApplication::patternUnit() const