Changeset View
Changeset View
Standalone View
Standalone View
src/backends/maxima/maximavariablemodel.cpp
Show All 22 Lines | |||||
23 | #include "maximasession.h" | 23 | #include "maximasession.h" | ||
24 | #include "maximaexpression.h" | 24 | #include "maximaexpression.h" | ||
25 | #include "textresult.h" | 25 | #include "textresult.h" | ||
26 | #include "latexresult.h" | 26 | #include "latexresult.h" | ||
27 | 27 | | |||
28 | #include <QDebug> | 28 | #include <QDebug> | ||
29 | #include <KLocalizedString> | 29 | #include <KLocalizedString> | ||
30 | 30 | | |||
31 | #include "settings.h" | ||||
32 | | ||||
31 | //command used to inspect a maxima variable. %1 is the name of that variable | 33 | //command used to inspect a maxima variable. %1 is the name of that variable | ||
32 | const QString MaximaVariableModel::inspectCommand=QLatin1String(":lisp($disp $%1)"); | 34 | const QString MaximaVariableModel::inspectCommand=QLatin1String(":lisp($disp $%1)"); | ||
33 | const QString MaximaVariableModel::variableInspectCommand=QLatin1String(":lisp(cantor-inspect $%1)"); | 35 | const QString MaximaVariableModel::variableInspectCommand=QLatin1String(":lisp(cantor-inspect $%1)"); | ||
34 | 36 | | |||
35 | MaximaVariableModel::MaximaVariableModel( MaximaSession* session) : Cantor::DefaultVariableModel(session) | 37 | MaximaVariableModel::MaximaVariableModel( MaximaSession* session) : Cantor::DefaultVariableModel(session), | ||
38 | m_variableExpression(nullptr), | ||||
39 | m_functionExpression(nullptr) | ||||
36 | { | 40 | { | ||
37 | } | 41 | } | ||
38 | 42 | | |||
39 | void MaximaVariableModel::clear() | 43 | void MaximaVariableModel::clearFunctions() | ||
40 | { | 44 | { | ||
41 | emit functionsRemoved(functionNames()); | 45 | emit functionsRemoved(functionNames()); | ||
42 | emit variablesRemoved(variableNames()); | | |||
43 | m_functions.clear(); | 46 | m_functions.clear(); | ||
44 | m_variables.clear(); | | |||
45 | DefaultVariableModel::clearVariables(); | | |||
46 | } | 47 | } | ||
47 | 48 | | |||
48 | void MaximaVariableModel::update() | 49 | void MaximaVariableModel::update() | ||
49 | { | 50 | { | ||
51 | if (!m_variableExpression) | ||||
52 | { | ||||
50 | qDebug()<<"checking for new variables"; | 53 | qDebug()<<"checking for new variables"; | ||
51 | const QString& cmd1=variableInspectCommand.arg(QLatin1String("values")); | 54 | const QString& cmd1=variableInspectCommand.arg(QLatin1String("values")); | ||
52 | Cantor::Expression* expr1=session()->evaluateExpression(cmd1, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | 55 | m_variableExpression = session()->evaluateExpression(cmd1, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | ||
53 | connect(expr1, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewVariables); | 56 | connect(m_variableExpression, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewVariables); | ||
57 | } | ||||
54 | 58 | | |||
59 | if (!m_functionExpression) | ||||
60 | { | ||||
55 | qDebug()<<"checking for new functions"; | 61 | qDebug()<<"checking for new functions"; | ||
56 | const QString& cmd2=inspectCommand.arg(QLatin1String("functions")); | 62 | const QString& cmd2=inspectCommand.arg(QLatin1String("functions")); | ||
57 | Cantor::Expression* expr2=session()->evaluateExpression(cmd2, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | 63 | m_functionExpression = session()->evaluateExpression(cmd2, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | ||
58 | connect(expr2, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewFunctions); | 64 | connect(m_functionExpression, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewFunctions); | ||
65 | } | ||||
59 | } | 66 | } | ||
60 | 67 | | |||
61 | QList<Cantor::DefaultVariableModel::Variable> parse(MaximaExpression* expr) | 68 | QList<Cantor::DefaultVariableModel::Variable> parse(MaximaExpression* expr) | ||
62 | { | 69 | { | ||
63 | if(!expr || expr->status()!=Cantor::Expression::Done || expr->results().isEmpty()) { | 70 | if(!expr | ||
71 | || (expr->status()!=Cantor::Expression::Done && expr->errorMessage() != QLatin1String("$DONE")) | ||||
72 | || expr->results().isEmpty()) | ||||
73 | { | ||||
64 | return QList<Cantor::DefaultVariableModel::Variable>(); | 74 | return QList<Cantor::DefaultVariableModel::Variable>(); | ||
65 | } | 75 | } | ||
66 | 76 | | |||
67 | //for parsing of names and values below (old code) we need to combine multiple results back to one string | 77 | //for parsing of names and values below (old code) we need to combine multiple results back to one string | ||
68 | QString text; | 78 | QString text; | ||
69 | for (auto* result : expr->results()) | 79 | for (auto* result : expr->results()) | ||
70 | { | 80 | { | ||
71 | if(result->type()==Cantor::TextResult::Type) | 81 | if(result->type()==Cantor::TextResult::Type) | ||
Show All 26 Lines | |||||
98 | } | 108 | } | ||
99 | else | 109 | else | ||
100 | { | 110 | { | ||
101 | //variable definition(s): e.g. | 111 | //variable definition(s): e.g. | ||
102 | //text = "[a,b]\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | 112 | //text = "[a,b]\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | ||
103 | //nameString = "[a,b]" | 113 | //nameString = "[a,b]" | ||
104 | //variableString = "\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | 114 | //variableString = "\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | ||
105 | variableNames = namesString.split(QLatin1Char(',')); | 115 | variableNames = namesString.split(QLatin1Char(',')); | ||
116 | if (MaximaSettings::self()->variableManagement()) | ||||
117 | { | ||||
106 | valuesString = text.mid(nameIndex+1).trimmed(); | 118 | valuesString = text.mid(nameIndex+1).trimmed(); | ||
107 | valuesString = valuesString.remove(QLatin1String("\n")); //lists with many elements have line breaks, remove them | 119 | valuesString = valuesString.remove(QLatin1String("\n")); //lists with many elements have line breaks, remove them | ||
108 | variableValues = valuesString.split(QLatin1String("\"-cantor-value-separator-\"")); | 120 | variableValues = valuesString.split(QLatin1String("\"-cantor-value-separator-\"")); | ||
109 | hasValues = variableValues.isEmpty(); | 121 | hasValues = variableValues.isEmpty(); | ||
110 | } | 122 | } | ||
123 | } | ||||
111 | 124 | | |||
112 | qDebug()<<variableNames; | 125 | qDebug()<<variableNames; | ||
113 | qDebug()<<"string: "<<valuesString; | 126 | qDebug()<<"string: "<<valuesString; | ||
114 | qDebug()<<"values: "<<variableValues; | 127 | qDebug()<<"values: "<<variableValues; | ||
115 | qDebug()<<"has Values: "<<hasValues; | 128 | qDebug()<<"has Values: "<<hasValues; | ||
116 | 129 | | |||
117 | QList<Cantor::DefaultVariableModel::Variable> variables; | 130 | QList<Cantor::DefaultVariableModel::Variable> variables; | ||
118 | variables.reserve(variableNames.size()); | 131 | variables.reserve(variableNames.size()); | ||
Show All 16 Lines | |||||
135 | } | 148 | } | ||
136 | 149 | | |||
137 | void MaximaVariableModel::parseNewVariables(Cantor::Expression::Status status) | 150 | void MaximaVariableModel::parseNewVariables(Cantor::Expression::Status status) | ||
138 | { | 151 | { | ||
139 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | 152 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | ||
140 | return; | 153 | return; | ||
141 | 154 | | |||
142 | qDebug()<<"parsing variables"; | 155 | qDebug()<<"parsing variables"; | ||
143 | MaximaExpression* expr=static_cast<MaximaExpression*>(sender()); | | |||
144 | | ||||
145 | QList<Variable> newVars=parse(expr); | | |||
146 | QStringList addedVars; | | |||
147 | QStringList removedVars; | | |||
148 | //remove the old variables | | |||
149 | for (const Variable& var : m_variables) | | |||
150 | { | | |||
151 | //check if this var is present in the new variables | | |||
152 | bool found=false; | | |||
153 | for (const Variable& var2 : newVars) | | |||
154 | { | | |||
155 | if(var.name==var2.name) | | |||
156 | { | | |||
157 | found=true; | | |||
158 | break; | | |||
159 | } | | |||
160 | } | | |||
161 | | ||||
162 | if(!found) | | |||
163 | { | | |||
164 | removeVariable(var); | | |||
165 | removedVars<<var.name; | | |||
166 | } | | |||
167 | } | | |||
168 | | ||||
169 | for (const Variable& var : newVars) | | |||
170 | { | | |||
171 | addVariable(var); | | |||
172 | | ||||
173 | addedVars<<var.name; | | |||
174 | } | | |||
175 | 156 | | |||
176 | m_variables=newVars; | 157 | QList<Variable> newVars=parse(static_cast<MaximaExpression*>(m_variableExpression)); | ||
158 | setVariables(newVars); | ||||
asemke: m_variableExpression seems to exist in MaximaVariableModel only. Should we define it as… | |||||
I have done it. But it doesn't bring big difference, because we still need casting for Cantor::Expression from evaluateExpression to MaximaExpression. sirgienko: I have done it. But it doesn't bring big difference, because we still need casting for `Cantor… | |||||
177 | 159 | | |||
178 | //the expression is not needed anymore | 160 | //the expression is not needed anymore | ||
179 | expr->deleteLater(); | 161 | m_variableExpression->deleteLater(); | ||
180 | 162 | m_variableExpression = nullptr; | |||
181 | emit variablesAdded(addedVars); | | |||
182 | emit variablesRemoved(removedVars); | | |||
183 | } | 163 | } | ||
184 | 164 | | |||
185 | void MaximaVariableModel::parseNewFunctions(Cantor::Expression::Status status) | 165 | void MaximaVariableModel::parseNewFunctions(Cantor::Expression::Status status) | ||
186 | { | 166 | { | ||
187 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | 167 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | ||
188 | return; | 168 | return; | ||
189 | 169 | | |||
190 | qDebug()<<"parsing functions"; | 170 | qDebug()<<"parsing functions"; | ||
191 | MaximaExpression* expr=static_cast<MaximaExpression*>(sender()); | | |||
192 | 171 | | |||
193 | QList<Variable> newVars=parse(expr); | 172 | // List of variables? | ||
194 | QStringList addedVars; | 173 | QList<Variable> newFuncs=parse(static_cast<MaximaExpression*>(m_functionExpression)); | ||
195 | QStringList removedVars; | 174 | QStringList addedFuncs; | ||
175 | QStringList removedFuncs; | ||||
196 | 176 | | |||
197 | //remove the old variables | 177 | //remove the old variables | ||
198 | for (const Variable& var : m_functions) | 178 | int i = 0; | ||
179 | while (i < m_functions.size()) | ||||
199 | { | 180 | { | ||
200 | //check if this var is present in the new variables | 181 | //check if this var is present in the new variables | ||
201 | bool found=false; | 182 | bool found=false; | ||
202 | for (const Variable& var2 : newVars) | 183 | for (const Variable& func : newFuncs) | ||
203 | { | 184 | if(m_functions[i] == func.name) | ||
204 | if(var.name==var2.name) | | |||
205 | { | 185 | { | ||
206 | found=true; | 186 | found=true; | ||
207 | break; | 187 | break; | ||
208 | } | 188 | } | ||
209 | } | | |||
210 | 189 | | |||
211 | if(!found) | 190 | if(!found) | ||
212 | { | 191 | { | ||
213 | removeVariable(var); | 192 | removedFuncs<<m_functions[i]; | ||
214 | removedVars<<var.name; | 193 | m_functions.removeAt(i); | ||
215 | } | 194 | } | ||
195 | else | ||||
196 | i++; | ||||
216 | } | 197 | } | ||
217 | 198 | | |||
218 | for (Variable var : newVars) | 199 | for (Variable func : newFuncs) | ||
219 | { | 200 | { | ||
220 | var.value=i18n("function"); | 201 | if (!m_functions.contains(func.name)) | ||
221 | addVariable(var); | 202 | { | ||
222 | //todo: check if the variable is actually new? | 203 | addedFuncs<<func.name; | ||
223 | addedVars<<var.name; | 204 | m_functions.append(func.name); | ||
205 | } | ||||
224 | } | 206 | } | ||
225 | | ||||
226 | m_functions=newVars; | | |||
227 | 207 | | |||
228 | //the expression is not needed anymore | 208 | //the expression is not needed anymore | ||
229 | expr->deleteLater(); | 209 | m_functionExpression->deleteLater(); | ||
210 | m_functionExpression = nullptr; | ||||
230 | 211 | | |||
231 | emit functionsAdded(addedVars); | 212 | emit functionsAdded(addedFuncs); | ||
232 | emit functionsRemoved(removedVars); | 213 | emit functionsRemoved(removedFuncs); | ||
233 | } | | |||
234 | | ||||
235 | bool MaximaVariableModel::isUpdateCommand(const QString& cmd) const | | |||
236 | { | | |||
237 | return cmd == variableInspectCommand.arg(QLatin1String("values")) | | |||
238 | || cmd == inspectCommand.arg(QLatin1String("functions")); | | |||
239 | } | 214 | } | ||
240 | 215 | | |||
241 | MaximaSession* MaximaVariableModel::maximaSession() | 216 | MaximaSession* MaximaVariableModel::maximaSession() | ||
242 | { | 217 | { | ||
243 | return static_cast<MaximaSession*> (session()); | 218 | return static_cast<MaximaSession*> (session()); | ||
244 | } | 219 | } | ||
245 | 220 | | |||
246 | QList<Cantor::DefaultVariableModel::Variable> MaximaVariableModel::variables() | | |||
247 | { | | |||
248 | return m_variables; | | |||
249 | } | | |||
250 | | ||||
251 | QList<Cantor::DefaultVariableModel::Variable> MaximaVariableModel::functions() | | |||
252 | { | | |||
253 | return m_functions; | | |||
254 | } | | |||
255 | | ||||
256 | QStringList MaximaVariableModel::variableNames() | | |||
257 | { | | |||
258 | QStringList names; | | |||
259 | for (const Cantor::DefaultVariableModel::Variable& var : m_variables) | | |||
260 | names<<var.name; | | |||
261 | | ||||
262 | return names; | | |||
263 | } | | |||
264 | | ||||
265 | QStringList MaximaVariableModel::functionNames(bool stripParameters) | 221 | QStringList MaximaVariableModel::functionNames(bool stripParameters) | ||
266 | { | 222 | { | ||
267 | QStringList names; | 223 | QStringList names; | ||
268 | for (const Cantor::DefaultVariableModel::Variable& var : m_functions) | 224 | for (const QString func: m_functions) | ||
269 | { | 225 | { | ||
270 | QString name=var.name; | 226 | QString name=func; | ||
271 | if(stripParameters) | 227 | if(stripParameters) | ||
272 | { | 228 | { | ||
273 | name=name.left(name.lastIndexOf(QLatin1Char('('))); | 229 | name=name.left(name.lastIndexOf(QLatin1Char('('))); | ||
274 | } | 230 | } | ||
275 | names<<name; | 231 | names<<name; | ||
276 | } | 232 | } | ||
277 | 233 | | |||
278 | return names; | 234 | return names; | ||
279 | } | 235 | } |
m_variableExpression seems to exist in MaximaVariableModel only. Should we define it as MaximaExpression and avoid this cast?