1 /*************************************************************************************
2  *  Copyright (C) 2010 by Aleix Pol <aleixpol@kde.org>                               *
3  *                                                                                   *
4  *  This program is free software; you can redistribute it and/or                    *
5  *  modify it under the terms of the GNU General Public License                      *
6  *  as published by the Free Software Foundation; either version 2                   *
7  *  of the License, or (at your option) any later version.                           *
8  *                                                                                   *
9  *  This program is distributed in the hope that it will be useful,                  *
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
12  *  GNU General Public License for more details.                                     *
13  *                                                                                   *
14  *  You should have received a copy of the GNU General Public License                *
15  *  along with this program; if not, write to the Free Software                      *
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
17  *************************************************************************************/
18 
19 #include "analitzawrapper.h"
20 #include <analitza/analyzer.h>
21 #include <analitza/value.h>
22 #include <analitza/variables.h>
23 #include <analitza/analitzautils.h>
24 #include <analitzagui/variablesmodel.h>
25 
26 
Q_DECLARE_METATYPE(ExpressionWrapper *)27 Q_DECLARE_METATYPE(ExpressionWrapper*)
28 
29 ExpressionWrapper::ExpressionWrapper(QObject* parent)
30     : QObject(parent)
31 {}
32 
33 
ExpressionWrapper(const Analitza::Expression & e,QObject * parent)34 ExpressionWrapper::ExpressionWrapper(const Analitza::Expression& e, QObject* parent)
35     : QObject(parent)
36     , m_exp(e)
37 {}
38 
isCorrect() const39 bool ExpressionWrapper::isCorrect() const { return m_exp.isCorrect(); }
toString() const40 QString ExpressionWrapper::toString() const { return m_exp.toString(); }
value() const41 QVariant ExpressionWrapper::value() const { return AnalitzaUtils::expressionToVariant(m_exp); }
errors() const42 QStringList ExpressionWrapper::errors() const { return m_exp.error(); }
43 
44 //////////////////////////
45 
AnalitzaWrapper(QObject * parent)46 AnalitzaWrapper::AnalitzaWrapper(QObject* parent)
47     : QObject(parent)
48     , m_wrapped(nullptr), m_vars(new Analitza::Variables), m_calc(false)
49 {
50     initWrapped();
51 }
52 
~AnalitzaWrapper()53 AnalitzaWrapper::~AnalitzaWrapper()
54 {}
55 
initWrapped()56 void AnalitzaWrapper::initWrapped()
57 {
58     if(!m_wrapped) {
59         m_wrapped.reset(new Analitza::Analyzer(m_vars));
60     }
61 }
62 
setVariables(const QSharedPointer<Analitza::Variables> & v)63 void AnalitzaWrapper::setVariables(const QSharedPointer<Analitza::Variables> &v)
64 {
65     m_wrapped->setVariables(v);
66     m_vars = v;
67     initWrapped();
68 }
69 
simplify(const QString & expression)70 QVariant AnalitzaWrapper::simplify(const QString& expression)
71 {
72     initWrapped();
73     Analitza::Expression e(expression, false);
74     if(!e.isCorrect()) {
75         return e.error();
76     }
77     m_wrapped->setExpression(e);
78     m_wrapped->simplify();
79 
80     return QVariant::fromValue(new ExpressionWrapper(m_wrapped->expression()));
81 }
82 
execute(const QString & expression)83 QVariant AnalitzaWrapper::execute(const QString& expression)
84 {
85     initWrapped();
86     Analitza::Expression e(expression, false);
87     if(!e.isCorrect()) {
88         return e.error();
89     }
90     m_wrapped->setExpression(e);
91 
92     Analitza::Expression res;
93     if(m_calc)
94         res = m_wrapped->calculate();
95     else
96         res = m_wrapped->evaluate();
97 
98     if(!m_wrapped->isCorrect())
99         return QVariant();
100 
101     return QVariant::fromValue(new ExpressionWrapper(res));
102 }
103 
executeFunc(const QString & name,const QVariantList & args)104 QVariant AnalitzaWrapper::executeFunc(const QString& name, const QVariantList& args)
105 {
106     if(m_vars && !m_vars->contains(name))
107         return QVariant();
108 
109     QStack<Analitza::Object*> stack;
110     QList<Analitza::Expression> exps;
111     foreach(const QVariant& v, args) {
112         exps += AnalitzaUtils::variantToExpression(v);
113         stack << exps.last().tree();
114     }
115 
116     m_wrapped->setExpression(Analitza::Expression(name, false));
117     m_wrapped->setExpression(m_wrapped->calculate());
118     m_wrapped->setStack(stack);
119     Analitza::Expression expr = m_wrapped->calculateLambda();
120 
121     if(!m_wrapped->isCorrect())
122         return QVariant();
123     else
124         return QVariant::fromValue(new ExpressionWrapper(expr));
125 }
126 
dependenciesToLambda(const QString & expression) const127 QString AnalitzaWrapper::dependenciesToLambda(const QString& expression) const
128 {
129     m_wrapped->setExpression(Analitza::Expression(expression, false));
130     return m_wrapped->dependenciesToLambda().toString();
131 }
132 
insertVariable(const QString & name,const QString & expression) const133 void AnalitzaWrapper::insertVariable(const QString& name, const QString& expression) const
134 {
135     m_wrapped->insertVariable(name, Analitza::Expression(expression, false));
136 }
137 
unusedVariableName() const138 QString AnalitzaWrapper::unusedVariableName() const
139 {
140     QString candidate;
141     char curr='a';
142 
143     for(candidate=curr; m_vars->contains(candidate); ) {
144         curr+=1;
145         if(curr>'z')
146             curr='a';
147         else
148             candidate.chop(1);
149 
150         candidate += curr;
151     }
152 
153     return candidate;
154 }
155 
removeVariable(const QString & name)156 void AnalitzaWrapper::removeVariable(const QString& name)
157 {
158     m_vars->remove(name);
159 }
160 
isCorrect() const161 bool AnalitzaWrapper::isCorrect() const { return m_wrapped->isCorrect(); }
162 
errors() const163 QStringList AnalitzaWrapper::errors() const { return m_wrapped->errors(); }
164 
setCalculate(bool calc)165 void AnalitzaWrapper::setCalculate(bool calc)
166 {
167     if (m_calc != calc) {
168         m_calc = calc;
169         Q_EMIT isCalculateChanged(calc);
170     }
171 }
172