File indexing completed on 2022-09-27 12:21:23

0001 /*************************************************************************************
0002  *  Copyright (C) 2010 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #include "analitzawrapper.h"
0020 #include <analitza/analyzer.h>
0021 #include <analitza/value.h>
0022 #include <analitza/analitzautils.h>
0023 #include <analitzagui/variablesmodel.h>
0024 
0025 
0026 Q_DECLARE_METATYPE(ExpressionWrapper*)
0027 
0028 ExpressionWrapper::ExpressionWrapper(QObject* parent)
0029     : QObject(parent)
0030 {}
0031 
0032 
0033 ExpressionWrapper::ExpressionWrapper(const Analitza::Expression& e, QObject* parent)
0034     : QObject(parent)
0035     , m_exp(e)
0036 {}
0037 
0038 bool ExpressionWrapper::isCorrect() const { return m_exp.isCorrect(); }
0039 QString ExpressionWrapper::toString() const { return m_exp.toString(); }
0040 QVariant ExpressionWrapper::value() const { return AnalitzaUtils::expressionToVariant(m_exp); }
0041 QStringList ExpressionWrapper::errors() const { return m_exp.error(); }
0042 
0043 //////////////////////////
0044 
0045 AnalitzaWrapper::AnalitzaWrapper(QObject* parent)
0046     : QObject(parent)
0047     , m_wrapped(nullptr), m_vars(new Analitza::Variables), m_calc(false)
0048 {
0049     initWrapped();
0050 }
0051 
0052 AnalitzaWrapper::~AnalitzaWrapper()
0053 {}
0054 
0055 void AnalitzaWrapper::initWrapped()
0056 {
0057     if(!m_wrapped) {
0058         m_wrapped.reset(new Analitza::Analyzer(m_vars));
0059     }
0060 }
0061 
0062 void AnalitzaWrapper::setVariables(const QSharedPointer<Analitza::Variables> &v)
0063 {
0064     m_wrapped->setVariables(v);
0065     m_vars = v;
0066     initWrapped();
0067 }
0068 
0069 QVariant AnalitzaWrapper::simplify(const QString& expression)
0070 {
0071     initWrapped();
0072     Analitza::Expression e(expression, false);
0073     if(!e.isCorrect()) {
0074         return e.error();
0075     }
0076     m_wrapped->setExpression(e);
0077     m_wrapped->simplify();
0078 
0079     return QVariant::fromValue(new ExpressionWrapper(m_wrapped->expression()));
0080 }
0081 
0082 QVariant AnalitzaWrapper::execute(const QString& expression)
0083 {
0084     initWrapped();
0085     Analitza::Expression e(expression, false);
0086     if(!e.isCorrect()) {
0087         return e.error();
0088     }
0089     m_wrapped->setExpression(e);
0090     
0091     Analitza::Expression res;
0092     if(m_calc)
0093         res = m_wrapped->calculate();
0094     else
0095         res = m_wrapped->evaluate();
0096     
0097     if(!m_wrapped->isCorrect())
0098         return QVariant();
0099     
0100     return QVariant::fromValue(new ExpressionWrapper(res));
0101 }
0102 
0103 QVariant AnalitzaWrapper::executeFunc(const QString& name, const QVariantList& args)
0104 {
0105     if(m_vars && !m_vars->contains(name))
0106         return QVariant();
0107     
0108     QStack<Analitza::Object*> stack;
0109     QList<Analitza::Expression> exps;
0110     foreach(const QVariant& v, args) {
0111         exps += AnalitzaUtils::variantToExpression(v);
0112         stack << exps.last().tree();
0113     }
0114     
0115     m_wrapped->setExpression(Analitza::Expression(name, false));
0116     m_wrapped->setExpression(m_wrapped->calculate());
0117     m_wrapped->setStack(stack);
0118     Analitza::Expression expr = m_wrapped->calculateLambda();
0119     
0120     if(!m_wrapped->isCorrect())
0121         return QVariant();
0122     else
0123         return QVariant::fromValue(new ExpressionWrapper(expr));
0124 }
0125 
0126 QString AnalitzaWrapper::dependenciesToLambda(const QString& expression) const
0127 {
0128     m_wrapped->setExpression(Analitza::Expression(expression, false));
0129     return m_wrapped->dependenciesToLambda().toString();
0130 }
0131 
0132 void AnalitzaWrapper::insertVariable(const QString& name, const QString& expression) const
0133 {
0134     m_wrapped->insertVariable(name, Analitza::Expression(expression, false));
0135 }
0136 
0137 QString AnalitzaWrapper::unusedVariableName() const
0138 {
0139     QString candidate;
0140     char curr='a';
0141     
0142     for(candidate=curr; m_vars->contains(candidate); ) {
0143         curr+=1;
0144         if(curr>'z')
0145             curr='a';
0146         else
0147             candidate.chop(1);
0148         
0149         candidate += curr;
0150     }
0151     
0152     return candidate;
0153 }
0154 
0155 void AnalitzaWrapper::removeVariable(const QString& name)
0156 {
0157     m_vars->remove(name);
0158 }
0159 
0160 bool AnalitzaWrapper::isCorrect() const { return m_wrapped->isCorrect(); }
0161 
0162 QStringList AnalitzaWrapper::errors() const { return m_wrapped->errors(); }
0163 
0164 void AnalitzaWrapper::setCalculate(bool calc)
0165 {
0166     if (m_calc != calc) {
0167         m_calc = calc;
0168         Q_EMIT isCalculateChanged(calc);
0169     }
0170 }