File indexing completed on 2023-10-01 07:35:56
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2018 Nikita Sirgienko <warquark@gmail.com> 0004 */ 0005 0006 #include "rvariablemodel.h" 0007 #include "rkeywords.h" 0008 #include "rsession.h" 0009 0010 #include <result.h> 0011 0012 using namespace Cantor; 0013 0014 RVariableModel::RVariableModel(RSession* session) : DefaultVariableModel(session) 0015 { 0016 } 0017 0018 RVariableModel::~RVariableModel() 0019 { 0020 if (m_expression) 0021 m_expression->setFinishingBehavior(Expression::FinishingBehavior::DeleteOnFinish); 0022 } 0023 0024 void RVariableModel::update() 0025 { 0026 if (m_expression) 0027 return; 0028 0029 m_expression = session()->evaluateExpression(QLatin1String("%model update"), Expression::FinishingBehavior::DoNotDelete, true); 0030 connect(m_expression, &Expression::statusChanged, this, &RVariableModel::parseResult); 0031 } 0032 0033 void RVariableModel::parseResult(Cantor::Expression::Status status) 0034 { 0035 switch(status) 0036 { 0037 case Expression::Status::Done: 0038 { 0039 if (!m_expression->result()) 0040 break; 0041 0042 const QChar recordSep(30); 0043 const QChar unitSep(31); 0044 0045 const QString output = m_expression->result()->data().toString(); 0046 0047 const QStringList& names = output.section(unitSep, 0, 0).split(recordSep, QString::SkipEmptyParts); 0048 const QStringList& values = output.section(unitSep, 1, 1).split(recordSep, QString::SkipEmptyParts); 0049 QStringList funcs = output.section(unitSep, 2, 2).split(recordSep, QString::SkipEmptyParts); 0050 const QStringList& constants = output.section(unitSep, 3, 3).split(recordSep, QString::SkipEmptyParts); 0051 0052 QList<Variable> vars; 0053 if (!values.isEmpty()) // Variables management disabled 0054 for (int i = 0; i < names.size(); i++) 0055 { 0056 if (i < values.size()) 0057 vars.append(Variable{names.at(i), values.at(i)}); 0058 else 0059 vars.append(Variable{names.at(i), QString()}); 0060 } 0061 else 0062 for (int i = 0; i < names.size(); i++) 0063 vars.append(Variable{names.at(i), QString()}); 0064 0065 setVariables(vars); 0066 0067 // Remove primitive function "(" because it not function for user calling (i guess) 0068 // And the function with name like this make highlighting worse actually 0069 funcs.removeOne(QLatin1String("(")); 0070 0071 // Also removes syntax keywords from functions list, like "function" 0072 for (const QString& keyword: RKeywords::instance()->keywords()) 0073 funcs.removeOne(keyword); 0074 0075 setFunctions(funcs); 0076 setConstants(constants); 0077 break; 0078 } 0079 case Expression::Status::Error: 0080 qWarning() << "R code for update variable model finishs with error message: " << m_expression->errorMessage(); 0081 break; 0082 0083 case Expression::Status::Interrupted: 0084 break; 0085 0086 default: 0087 return; 0088 } 0089 0090 m_expression->deleteLater(); 0091 m_expression = nullptr; 0092 } 0093 0094 void RVariableModel::setConstants(QStringList newConstants) 0095 { 0096 QStringList addedConstants; 0097 QStringList removedConstants; 0098 0099 //remove the old variables 0100 int i = 0; 0101 while (i < m_constants.size()) 0102 { 0103 //check if this var is present in the new variables 0104 bool found = false; 0105 for (const QString& constant : newConstants) 0106 if(m_constants[i] == constant) 0107 { 0108 found=true; 0109 break; 0110 } 0111 0112 if(!found) 0113 { 0114 removedConstants << m_constants[i]; 0115 m_constants.removeAt(i); 0116 } 0117 else 0118 i++; 0119 } 0120 0121 for (const QString& constant : newConstants) 0122 { 0123 if (!m_constants.contains(constant)) 0124 { 0125 addedConstants << constant; 0126 m_constants.append(constant); 0127 } 0128 } 0129 0130 emit constantsAdded(addedConstants); 0131 emit constantsRemoved(removedConstants); 0132 }