Warning, file /education/cantor/src/backends/maxima/maximavariablemodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2012 Alexander Rieder <alexanderrieder@gmail.com> 0004 */ 0005 0006 #include "maximavariablemodel.h" 0007 0008 #include "maximasession.h" 0009 #include "maximaexpression.h" 0010 #include "textresult.h" 0011 #include "latexresult.h" 0012 0013 #include <QDebug> 0014 #include <KLocalizedString> 0015 0016 #include "settings.h" 0017 0018 //command used to inspect a maxima variable. %1 is the name of that variable 0019 const QString MaximaVariableModel::inspectCommand=QLatin1String(":lisp($disp $%1)"); 0020 const QString MaximaVariableModel::variableInspectCommand=QLatin1String(":lisp(cantor-inspect $%1)"); 0021 0022 MaximaVariableModel::MaximaVariableModel(MaximaSession* session) : Cantor::DefaultVariableModel(session) 0023 { 0024 } 0025 0026 void MaximaVariableModel::update() 0027 { 0028 if (static_cast<MaximaSession*>(session())->mode() != MaximaSession::Maxima) 0029 return; 0030 0031 if (!m_variableExpression) 0032 { 0033 qDebug()<<"checking for new variables"; 0034 const QString& cmd1 = variableInspectCommand.arg(QLatin1String("values")); 0035 m_variableExpression = static_cast<MaximaExpression*>(session()->evaluateExpression(cmd1, Cantor::Expression::FinishingBehavior::DoNotDelete, true)); 0036 connect(m_variableExpression, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewVariables); 0037 } 0038 0039 if (!m_functionExpression) 0040 { 0041 qDebug()<<"checking for new functions"; 0042 const QString& cmd2 = inspectCommand.arg(QLatin1String("functions")); 0043 m_functionExpression = static_cast<MaximaExpression*>(session()->evaluateExpression(cmd2, Cantor::Expression::FinishingBehavior::DoNotDelete, true)); 0044 connect(m_functionExpression, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewFunctions); 0045 } 0046 } 0047 0048 QList<Cantor::DefaultVariableModel::Variable> parse(MaximaExpression* expr) 0049 { 0050 if(!expr 0051 || (expr->status()!=Cantor::Expression::Done && expr->errorMessage() != QLatin1String("$DONE")) 0052 || expr->results().isEmpty()) 0053 { 0054 return QList<Cantor::DefaultVariableModel::Variable>(); 0055 } 0056 0057 //for parsing of names and values below (old code) we need to combine multiple results back to one string 0058 QString text; 0059 for (auto* result : expr->results()) 0060 { 0061 if(result->type()==Cantor::TextResult::Type) 0062 text += static_cast<Cantor::TextResult*>(result)->plain(); 0063 else if(expr->result()->type()==Cantor::LatexResult::Type) 0064 text += static_cast<Cantor::LatexResult*>(result)->plain(); 0065 } 0066 0067 const int nameIndex = text.indexOf(QLatin1Char(']')); 0068 QString namesString = text.left(nameIndex); 0069 //namesString.chop(1); 0070 namesString=namesString.mid(1); 0071 namesString=namesString.trimmed(); 0072 0073 qDebug()<<"variable names: "<<namesString; 0074 if(namesString.isEmpty()) 0075 return QList<Cantor::DefaultVariableModel::Variable>(); 0076 0077 QStringList variableNames; 0078 QString valuesString; 0079 bool hasValues = false; 0080 QStringList variableValues; 0081 if ( namesString.contains(QLatin1Char(')')) ) 0082 { 0083 //function definition(s): e.g 0084 //text = "[f1(x),f2(x,y),f3(x,y,z)]\n$DONE" 0085 //nameString = f1(x),f2(x,y),f3(x,y,z) 0086 //variableString = "\n$DONE" 0087 variableNames = namesString.split(QLatin1String("),")); 0088 } 0089 else 0090 { 0091 //variable definition(s): e.g. 0092 //text = "[a,b]\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" 0093 //nameString = "[a,b]" 0094 //variableString = "\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" 0095 variableNames = namesString.split(QLatin1Char(',')); 0096 if (MaximaSettings::self()->variableManagement()) 0097 { 0098 valuesString = text.mid(nameIndex+1).trimmed(); 0099 valuesString = valuesString.remove(QLatin1String("\n")); //lists with many elements have line breaks, remove them 0100 variableValues = valuesString.split(QLatin1String("\"-cantor-value-separator-\"")); 0101 hasValues = variableValues.isEmpty(); 0102 } 0103 } 0104 0105 qDebug()<<variableNames; 0106 qDebug()<<"string: "<<valuesString; 0107 qDebug()<<"values: "<<variableValues; 0108 qDebug()<<"has Values: "<<hasValues; 0109 0110 QList<Cantor::DefaultVariableModel::Variable> variables; 0111 variables.reserve(variableNames.size()); 0112 for(int i=0;i<variableNames.size();i++) 0113 { 0114 Cantor::DefaultVariableModel::Variable var; 0115 var.name=variableNames.at(i);; 0116 if(variableValues.size()>i) 0117 { 0118 var.value=variableValues.at(i).trimmed(); 0119 var.value=var.value.remove(QLatin1String("\n")); //lists with many elements have line breaks, remove them 0120 0121 // text output is quoted by Maxima, remove the quotes 0122 if (var.value.startsWith(QLatin1String("\""))) 0123 { 0124 var.value.remove(0, 1); 0125 var.value.chop(1); 0126 var.value.replace(QLatin1String("\\\""), QLatin1String("\"")); 0127 } 0128 } 0129 else 0130 var.value=QLatin1String("unknown"); 0131 0132 variables<<var; 0133 } 0134 0135 return variables; 0136 } 0137 0138 void MaximaVariableModel::parseNewVariables(Cantor::Expression::Status status) 0139 { 0140 if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) 0141 return; 0142 0143 qDebug()<<"parsing variables"; 0144 0145 QList<Variable> newVars=parse(m_variableExpression); 0146 setVariables(newVars); 0147 0148 //the expression is not needed anymore 0149 m_variableExpression->deleteLater(); 0150 m_variableExpression = nullptr; 0151 } 0152 0153 void MaximaVariableModel::parseNewFunctions(Cantor::Expression::Status status) 0154 { 0155 if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) 0156 return; 0157 0158 qDebug()<<"parsing functions"; 0159 0160 // List of variables? 0161 QList<Variable> newFuncs=parse(m_functionExpression); 0162 QStringList functions; 0163 for (Variable var : newFuncs) 0164 functions << var.name.left(var.name.indexOf(QLatin1Char('('))); 0165 qDebug() << functions; 0166 setFunctions(functions); 0167 0168 //the expression is not needed anymore 0169 m_functionExpression->deleteLater(); 0170 m_functionExpression = nullptr; 0171 } 0172 0173 MaximaSession* MaximaVariableModel::maximaSession() 0174 { 0175 return static_cast<MaximaSession*> (session()); 0176 }