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), | ||
36 | { | 38 | m_variableExpression(nullptr), | ||
37 | } | 39 | m_functionExpression(nullptr) | ||
38 | | ||||
39 | void MaximaVariableModel::clear() | | |||
40 | { | 40 | { | ||
41 | emit functionsRemoved(functionNames()); | | |||
42 | emit variablesRemoved(variableNames()); | | |||
43 | m_functions.clear(); | | |||
44 | m_variables.clear(); | | |||
45 | DefaultVariableModel::clearVariables(); | | |||
46 | } | 41 | } | ||
47 | 42 | | |||
48 | void MaximaVariableModel::update() | 43 | void MaximaVariableModel::update() | ||
49 | { | 44 | { | ||
45 | if (!m_variableExpression) | ||||
46 | { | ||||
50 | qDebug()<<"checking for new variables"; | 47 | qDebug()<<"checking for new variables"; | ||
51 | const QString& cmd1=variableInspectCommand.arg(QLatin1String("values")); | 48 | const QString& cmd1=variableInspectCommand.arg(QLatin1String("values")); | ||
52 | Cantor::Expression* expr1=session()->evaluateExpression(cmd1, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | 49 | m_variableExpression = session()->evaluateExpression(cmd1, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | ||
53 | connect(expr1, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewVariables); | 50 | connect(m_variableExpression, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewVariables); | ||
51 | } | ||||
54 | 52 | | |||
53 | if (!m_functionExpression) | ||||
54 | { | ||||
55 | qDebug()<<"checking for new functions"; | 55 | qDebug()<<"checking for new functions"; | ||
56 | const QString& cmd2=inspectCommand.arg(QLatin1String("functions")); | 56 | const QString& cmd2=inspectCommand.arg(QLatin1String("functions")); | ||
57 | Cantor::Expression* expr2=session()->evaluateExpression(cmd2, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | 57 | m_functionExpression = session()->evaluateExpression(cmd2, Cantor::Expression::FinishingBehavior::DoNotDelete, true); | ||
58 | connect(expr2, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewFunctions); | 58 | connect(m_functionExpression, &Cantor::Expression::statusChanged, this, &MaximaVariableModel::parseNewFunctions); | ||
59 | } | ||||
59 | } | 60 | } | ||
60 | 61 | | |||
61 | QList<Cantor::DefaultVariableModel::Variable> parse(MaximaExpression* expr) | 62 | QList<Cantor::DefaultVariableModel::Variable> parse(MaximaExpression* expr) | ||
62 | { | 63 | { | ||
63 | if(!expr || expr->status()!=Cantor::Expression::Done || expr->results().isEmpty()) { | 64 | if(!expr | ||
65 | || (expr->status()!=Cantor::Expression::Done && expr->errorMessage() != QLatin1String("$DONE")) | ||||
66 | || expr->results().isEmpty()) | ||||
67 | { | ||||
64 | return QList<Cantor::DefaultVariableModel::Variable>(); | 68 | return QList<Cantor::DefaultVariableModel::Variable>(); | ||
65 | } | 69 | } | ||
66 | 70 | | |||
67 | //for parsing of names and values below (old code) we need to combine multiple results back to one string | 71 | //for parsing of names and values below (old code) we need to combine multiple results back to one string | ||
68 | QString text; | 72 | QString text; | ||
69 | for (auto* result : expr->results()) | 73 | for (auto* result : expr->results()) | ||
70 | { | 74 | { | ||
71 | if(result->type()==Cantor::TextResult::Type) | 75 | if(result->type()==Cantor::TextResult::Type) | ||
Show All 26 Lines | |||||
98 | } | 102 | } | ||
99 | else | 103 | else | ||
100 | { | 104 | { | ||
101 | //variable definition(s): e.g. | 105 | //variable definition(s): e.g. | ||
102 | //text = "[a,b]\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | 106 | //text = "[a,b]\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | ||
103 | //nameString = "[a,b]" | 107 | //nameString = "[a,b]" | ||
104 | //variableString = "\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | 108 | //variableString = "\n1\n\"-cantor-value-separator-\"\n2\n\"-cantor-value-separator-\"\n($A $B)" | ||
105 | variableNames = namesString.split(QLatin1Char(',')); | 109 | variableNames = namesString.split(QLatin1Char(',')); | ||
110 | if (MaximaSettings::self()->variableManagement()) | ||||
111 | { | ||||
106 | valuesString = text.mid(nameIndex+1).trimmed(); | 112 | valuesString = text.mid(nameIndex+1).trimmed(); | ||
107 | valuesString = valuesString.remove(QLatin1String("\n")); //lists with many elements have line breaks, remove them | 113 | valuesString = valuesString.remove(QLatin1String("\n")); //lists with many elements have line breaks, remove them | ||
108 | variableValues = valuesString.split(QLatin1String("\"-cantor-value-separator-\"")); | 114 | variableValues = valuesString.split(QLatin1String("\"-cantor-value-separator-\"")); | ||
109 | hasValues = variableValues.isEmpty(); | 115 | hasValues = variableValues.isEmpty(); | ||
110 | } | 116 | } | ||
117 | } | ||||
111 | 118 | | |||
112 | qDebug()<<variableNames; | 119 | qDebug()<<variableNames; | ||
113 | qDebug()<<"string: "<<valuesString; | 120 | qDebug()<<"string: "<<valuesString; | ||
114 | qDebug()<<"values: "<<variableValues; | 121 | qDebug()<<"values: "<<variableValues; | ||
115 | qDebug()<<"has Values: "<<hasValues; | 122 | qDebug()<<"has Values: "<<hasValues; | ||
116 | 123 | | |||
117 | QList<Cantor::DefaultVariableModel::Variable> variables; | 124 | QList<Cantor::DefaultVariableModel::Variable> variables; | ||
118 | variables.reserve(variableNames.size()); | 125 | variables.reserve(variableNames.size()); | ||
Show All 16 Lines | |||||
135 | } | 142 | } | ||
136 | 143 | | |||
137 | void MaximaVariableModel::parseNewVariables(Cantor::Expression::Status status) | 144 | void MaximaVariableModel::parseNewVariables(Cantor::Expression::Status status) | ||
138 | { | 145 | { | ||
139 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | 146 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | ||
140 | return; | 147 | return; | ||
141 | 148 | | |||
142 | qDebug()<<"parsing variables"; | 149 | 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 | 150 | | |||
169 | for (const Variable& var : newVars) | 151 | QList<Variable> newVars=parse(static_cast<MaximaExpression*>(m_variableExpression)); | ||
170 | { | 152 | 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… | |||||
171 | addVariable(var); | | |||
172 | | ||||
173 | addedVars<<var.name; | | |||
174 | } | | |||
175 | | ||||
176 | m_variables=newVars; | | |||
177 | 153 | | |||
178 | //the expression is not needed anymore | 154 | //the expression is not needed anymore | ||
179 | expr->deleteLater(); | 155 | m_variableExpression->deleteLater(); | ||
180 | 156 | m_variableExpression = nullptr; | |||
181 | emit variablesAdded(addedVars); | | |||
182 | emit variablesRemoved(removedVars); | | |||
183 | } | 157 | } | ||
184 | 158 | | |||
185 | void MaximaVariableModel::parseNewFunctions(Cantor::Expression::Status status) | 159 | void MaximaVariableModel::parseNewFunctions(Cantor::Expression::Status status) | ||
186 | { | 160 | { | ||
187 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | 161 | if (status != Cantor::Expression::Done && status != Cantor::Expression::Error) | ||
188 | return; | 162 | return; | ||
189 | 163 | | |||
190 | qDebug()<<"parsing functions"; | 164 | qDebug()<<"parsing functions"; | ||
191 | MaximaExpression* expr=static_cast<MaximaExpression*>(sender()); | | |||
192 | | ||||
193 | QList<Variable> newVars=parse(expr); | | |||
194 | QStringList addedVars; | | |||
195 | QStringList removedVars; | | |||
196 | | ||||
197 | //remove the old variables | | |||
198 | for (const Variable& var : m_functions) | | |||
199 | { | | |||
200 | //check if this var is present in the new variables | | |||
201 | bool found=false; | | |||
202 | for (const Variable& var2 : newVars) | | |||
203 | { | | |||
204 | if(var.name==var2.name) | | |||
205 | { | | |||
206 | found=true; | | |||
207 | break; | | |||
208 | } | | |||
209 | } | | |||
210 | | ||||
211 | if(!found) | | |||
212 | { | | |||
213 | removeVariable(var); | | |||
214 | removedVars<<var.name; | | |||
215 | } | | |||
216 | } | | |||
217 | 165 | | |||
218 | for (Variable var : newVars) | 166 | // List of variables? | ||
219 | { | 167 | QList<Variable> newFuncs=parse(static_cast<MaximaExpression*>(m_functionExpression)); | ||
220 | var.value=i18n("function"); | 168 | QStringList functions; | ||
221 | addVariable(var); | 169 | for (Variable var : newFuncs) | ||
222 | //todo: check if the variable is actually new? | 170 | functions << var.name; | ||
223 | addedVars<<var.name; | 171 | setFunctions(functions); | ||
224 | } | | |||
225 | | ||||
226 | m_functions=newVars; | | |||
227 | 172 | | |||
228 | //the expression is not needed anymore | 173 | //the expression is not needed anymore | ||
229 | expr->deleteLater(); | 174 | m_functionExpression->deleteLater(); | ||
230 | 175 | m_functionExpression = nullptr; | |||
231 | emit functionsAdded(addedVars); | | |||
232 | emit functionsRemoved(removedVars); | | |||
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 | } | 176 | } | ||
240 | 177 | | |||
241 | MaximaSession* MaximaVariableModel::maximaSession() | 178 | MaximaSession* MaximaVariableModel::maximaSession() | ||
242 | { | 179 | { | ||
243 | return static_cast<MaximaSession*> (session()); | 180 | return static_cast<MaximaSession*> (session()); | ||
244 | } | 181 | } | ||
245 | 182 | | |||
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) | 183 | QStringList MaximaVariableModel::functionNames(bool stripParameters) | ||
266 | { | 184 | { | ||
267 | QStringList names; | 185 | QStringList names; | ||
268 | for (const Cantor::DefaultVariableModel::Variable& var : m_functions) | 186 | for (const QString func: m_functions) | ||
269 | { | 187 | { | ||
270 | QString name=var.name; | 188 | QString name=func; | ||
271 | if(stripParameters) | 189 | if(stripParameters) | ||
272 | { | 190 | { | ||
273 | name=name.left(name.lastIndexOf(QLatin1Char('('))); | 191 | name=name.left(name.lastIndexOf(QLatin1Char('('))); | ||
274 | } | 192 | } | ||
275 | names<<name; | 193 | names<<name; | ||
276 | } | 194 | } | ||
277 | 195 | | |||
278 | return names; | 196 | return names; | ||
279 | } | 197 | } |
m_variableExpression seems to exist in MaximaVariableModel only. Should we define it as MaximaExpression and avoid this cast?