Changeset View
Changeset View
Standalone View
Standalone View
src/backends/qalculate/qalculateexpression.cpp
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | |||||
61 | QalculateExpression::~QalculateExpression() | 61 | QalculateExpression::~QalculateExpression() | ||
62 | { | 62 | { | ||
63 | if (m_tempFile) | 63 | if (m_tempFile) | ||
64 | delete m_tempFile; | 64 | delete m_tempFile; | ||
65 | } | 65 | } | ||
66 | 66 | | |||
67 | void QalculateExpression::evaluate() | 67 | void QalculateExpression::evaluate() | ||
68 | { | 68 | { | ||
69 | /* | ||||
70 | Use Api for: | ||||
71 | * help | ||||
72 | * plot | ||||
73 | Use qalc for any other command | ||||
74 | */ | ||||
69 | setStatus(Cantor::Expression::Computing); | 75 | setStatus(Cantor::Expression::Computing); | ||
70 | m_message = QLatin1String(""); | | |||
71 | | ||||
72 | if (command().isEmpty()) { | 76 | if (command().isEmpty()) { | ||
77 | setStatus(Cantor::Expression::Done); | ||||
73 | return; | 78 | return; | ||
74 | } | 79 | } | ||
75 | 80 | | |||
76 | QStringList commands=command().split(QLatin1Char('\n')); | | |||
77 | QString resultString; | | |||
78 | 81 | | |||
82 | QStringList commands = command().split(QLatin1Char('\n')); | ||||
79 | foreach(const QString& command, commands) | 83 | foreach(const QString& command, commands) | ||
80 | { | 84 | { | ||
81 | if (command.contains(QLatin1String("help"))) { | 85 | if (command.contains(QLatin1String("help"))) { | ||
82 | QalculateSyntaxHelpObject* helper = new QalculateSyntaxHelpObject(command, (QalculateSession*) session()); | 86 | QalculateSyntaxHelpObject* helper = new QalculateSyntaxHelpObject(command, (QalculateSession*) session()); | ||
83 | setResult(new Cantor::HelpResult(helper->answer())); | 87 | setResult(new Cantor::HelpResult(helper->answer())); | ||
84 | setStatus(Cantor::Expression::Done); | 88 | setStatus(Cantor::Expression::Done); | ||
85 | return; | 89 | return; | ||
86 | } | 90 | } | ||
87 | else if (command.trimmed().startsWith(QLatin1String("plot")) && | 91 | else if (command.trimmed().startsWith(QLatin1String("plot")) && | ||
88 | (command.indexOf(QLatin1String("plot"))+4 == command.size() || | 92 | (command.indexOf(QLatin1String("plot"))+4 == command.size() || | ||
89 | command[command.indexOf(QLatin1String("plot"))+4].isSpace())) { | 93 | command[command.indexOf(QLatin1String("plot"))+4].isSpace())) { | ||
90 | evaluatePlotCommand(); | 94 | evaluatePlotCommand(); | ||
91 | return; | 95 | return; | ||
92 | } | 96 | } | ||
93 | else if (command.trimmed().startsWith(QLatin1String("saveVariables")) && | | |||
94 | (command.indexOf(QLatin1String("saveVariables"))+13 == command.size() || | | |||
95 | command[command.indexOf(QLatin1String("saveVariables"))+13].isSpace())) { | | |||
96 | evaluateSaveVariablesCommand(); | | |||
97 | return; | | |||
98 | } | 97 | } | ||
99 | else if (command.trimmed().startsWith(QLatin1String("loadVariables")) && | 98 | // we are here because the commands entered by user are regular commands. We would have returned by now otherwise | ||
100 | (command.indexOf(QLatin1String("loadVariables"))+13 == command.size() || | 99 | QalculateSession* currentSession = dynamic_cast<QalculateSession*>(session()); | ||
101 | command[command.indexOf(QLatin1String("loadVariables"))+13].isSpace())) { | 100 | currentSession->runExpression(); | ||
102 | evaluateLoadVariablesCommand(); | | |||
103 | return; | | |||
104 | } | | |||
105 | | ||||
106 | string expression = unlocalizeExpression(command); | | |||
107 | | ||||
108 | qDebug() << "EXPR: " << QLatin1String(expression.c_str()); | | |||
109 | | ||||
110 | EvaluationOptions eo = evaluationOptions(); | | |||
111 | | ||||
112 | MathStructure result = CALCULATOR->calculate(expression, eo); | | |||
113 | | ||||
114 | // update the answer variables | | |||
115 | static_cast<QalculateSession*>(session())->setLastResult(result); | | |||
116 | | ||||
117 | // error handling | | |||
118 | if (checkForCalculatorMessages() & (MSG_WARN | MSG_WARN)) | | |||
119 | return; | | |||
120 | | ||||
121 | updateVariables(CALCULATOR->parse(expression, eo.parse_options)); | | |||
122 | | ||||
123 | QSharedPointer<PrintOptions> po = printOptions(); | | |||
124 | 101 | | |||
125 | result.format(*po); | | |||
126 | | ||||
127 | resultString+=QLatin1String(result.print(*po).c_str()) + QLatin1Char('\n'); | | |||
128 | | ||||
129 | } | | |||
130 | | ||||
131 | setResult(new Cantor::TextResult(resultString)); | | |||
132 | setStatus(Done); | | |||
133 | } | 102 | } | ||
134 | 103 | | |||
135 | void QalculateExpression::evaluateSaveVariablesCommand() | 104 | void QalculateExpression::parseOutput(QString& output) | ||
136 | { | 105 | { | ||
137 | QString argString = command().mid(command().indexOf(QLatin1String("saveVariables"))+13); | 106 | output.remove(QLatin1String(">")); | ||
138 | argString = argString.trimmed(); | 107 | output = output.trimmed(); | ||
139 | | ||||
140 | QString usage = i18n("Usage: saveVariables file"); | | |||
141 | | ||||
142 | QString fileName = parseForFilename(argString, usage); | | |||
143 | if (fileName.isNull()) | | |||
144 | return; | | |||
145 | 108 | | |||
146 | // We want to save Temporary variables, but Qalculate does not. | 109 | qDebug() << "output from qalc for command: " << command() << " " << output << endl; | ||
chinmoyr: You should comment out this line. It's only for testing isn't it? | |||||
I am keeping the debug statements for now. rishabhg: I am keeping the debug statements for now.
They will be removed at some point later | |||||
147 | std::vector<Variable*> variables = CALCULATOR->variables; | 110 | setResult(new Cantor::TextResult(output)); | ||
148 | // If somebody saves his variables in Cantor_Internal_Temporary | 111 | // update the variable model | ||
149 | // he deserves unexpected behavior. | 112 | updateVariables(); | ||
150 | std::string tmpCategory = "Temporary"; | 113 | setStatus(Cantor::Expression::Done); | ||
151 | std::string newCategory = "Cantor_Internal_Temporary"; | | |||
152 | for (size_t i = 0; i < variables.size(); ++i) { | | |||
153 | if (variables[i]->category() == tmpCategory) | | |||
154 | variables[i]->setCategory(newCategory); | | |||
155 | } | | |||
156 | | ||||
157 | int res = CALCULATOR->saveVariables(fileName.toLatin1().data()); | | |||
158 | | ||||
159 | for (size_t i = 0; i < variables.size(); ++i) { | | |||
160 | if (variables[i]->category() == newCategory) | | |||
161 | variables[i]->setCategory(tmpCategory); | | |||
162 | } | | |||
163 | | ||||
164 | | ||||
165 | if (checkForCalculatorMessages() & (MSG_WARN|MSG_ERR)) { | | |||
166 | return; | | |||
167 | } | | |||
168 | if (res < 0) { | | |||
169 | showMessage(i18n("Saving failed."), MESSAGE_ERROR); | | |||
170 | return; | | |||
171 | } | 114 | } | ||
172 | 115 | | |||
173 | setStatus(Done); | | |||
174 | } | | |||
175 | 116 | | |||
176 | void QalculateExpression::evaluateLoadVariablesCommand() | 117 | void QalculateExpression::updateVariables() | ||
177 | { | 118 | { | ||
178 | QString argString = command().mid(command().indexOf(QLatin1String("loadVariables"))+13); | 119 | QalculateSession* currentSession = dynamic_cast<QalculateSession*>(session()); | ||
179 | argString = argString.trimmed(); | 120 | QMap<QString,QString> &variables = currentSession->variables; | ||
180 | 121 | Cantor::DefaultVariableModel* model = static_cast<Cantor::DefaultVariableModel*>(currentSession->variableModel()); | |||
181 | QString usage = i18n("Usage: loadVariables file"); | 122 | QMap<QString, QString>::const_iterator it = variables.constBegin(); | ||
182 | 123 | while (it != variables.constEnd()) { | |||
183 | QString fileName = parseForFilename(argString, usage); | 124 | model->addVariable(it.key(), it.value()); | ||
184 | if (fileName.isNull()) | 125 | ++it; | ||
185 | return; | | |||
186 | | ||||
187 | int res = CALCULATOR->loadDefinitions(fileName.toLatin1().data()); | | |||
188 | if (checkForCalculatorMessages() & (MSG_WARN|MSG_ERR)) { | | |||
189 | return; | | |||
190 | } | | |||
191 | if (res < 0) { | | |||
192 | showMessage(i18n("Loading failed."), MESSAGE_ERROR); | | |||
193 | return; | | |||
194 | } | | |||
195 | | ||||
196 | // We have to store temporary variables in a different category | | |||
197 | // (see parseSaveVariablesCommand()) | | |||
198 | std::vector<Variable*> variables = CALCULATOR->variables; | | |||
199 | std::string tmpCategory = "Temporary"; | | |||
200 | std::string newCategory = "Cantor_Internal_Temporary"; | | |||
201 | | ||||
202 | for (size_t i = 0; i < variables.size(); ++i) { | | |||
203 | if (variables[i]->category() == newCategory) | | |||
204 | variables[i]->setCategory(tmpCategory); | | |||
205 | } | 126 | } | ||
206 | | ||||
207 | setStatus(Done); | | |||
208 | } | 127 | } | ||
209 | 128 | | |||
210 | QString QalculateExpression::parseForFilename(QString argument, QString usage) | 129 | void QalculateExpression::parseError(QString& error) | ||
211 | { | 130 | { | ||
212 | if (argument.isEmpty()) { | 131 | error.remove(QLatin1String(">")); | ||
213 | showMessage(usage, MESSAGE_ERROR); | 132 | error = error.trimmed(); | ||
214 | return QString(); | 133 | qDebug() << "Error from qalc for command: " << command() << " " << error << endl; | ||
chinmoyr: same here. | |||||
215 | } | 134 | setErrorMessage(error); | ||
216 | 135 | setStatus(Cantor::Expression::Error); | |||
217 | QString fileName = QLatin1String(""); | | |||
218 | QChar sep = QLatin1Char('\0'); | | |||
219 | int i = 0; | | |||
220 | if (argument[0] == QLatin1Char('\'') || argument[0] == QLatin1Char('"')) { | | |||
221 | sep = argument[0]; | | |||
222 | i = 1; | | |||
223 | } | | |||
224 | while (i < argument.size() && !argument[i].isSpace() && | | |||
225 | argument[i] != sep) { | | |||
226 | if (argument[i] == QLatin1Char('\\') && i < argument.size()-1) | | |||
227 | ++i; | | |||
228 | fileName += argument[i]; | | |||
229 | ++i; | | |||
230 | } | | |||
231 | | ||||
232 | if (sep != QLatin1Char('\0') && i == argument.size()) { | | |||
233 | showMessage(i18n("missing %1", sep), MESSAGE_ERROR); | | |||
234 | return QString(); | | |||
235 | } | | |||
236 | | ||||
237 | if (i < argument.size() - 1) { | | |||
238 | showMessage(usage, MESSAGE_ERROR); | | |||
239 | return QString(); | | |||
240 | } | 136 | } | ||
241 | 137 | | |||
242 | return fileName; | 138 | void QalculateExpression::interrupt() | ||
139 | { | ||||
140 | setStatus(Cantor::Expression::Interrupted); | ||||
243 | } | 141 | } | ||
244 | 142 | | |||
245 | void QalculateExpression::evaluatePlotCommand() | 143 | void QalculateExpression::evaluatePlotCommand() | ||
246 | { | 144 | { | ||
247 | QString argString = command().mid(command().indexOf(QLatin1String("plot"))+4); | 145 | QString argString = command().mid(command().indexOf(QLatin1String("plot"))+4); | ||
248 | argString = QLatin1String(unlocalizeExpression(argString).c_str()); | 146 | argString = QLatin1String(unlocalizeExpression(argString).c_str()); | ||
249 | argString = argString.trimmed(); | 147 | argString = argString.trimmed(); | ||
250 | 148 | | |||
▲ Show 20 Lines • Show All 681 Lines • ▼ Show 20 Line(s) | 829 | return CALCULATOR->unlocalizeExpression( | |||
932 | expr.replace(QChar(0xA3), QLatin1String("GBP")) | 830 | expr.replace(QChar(0xA3), QLatin1String("GBP")) | ||
933 | .replace(QChar(0xA5), QLatin1String("JPY")) | 831 | .replace(QChar(0xA5), QLatin1String("JPY")) | ||
934 | .replace(QLatin1String("$"), QLatin1String("USD")) | 832 | .replace(QLatin1String("$"), QLatin1String("USD")) | ||
935 | .replace(QChar(0x20AC), QLatin1String("EUR")) | 833 | .replace(QChar(0x20AC), QLatin1String("EUR")) | ||
936 | .toLatin1().data() | 834 | .toLatin1().data() | ||
937 | ); | 835 | ); | ||
938 | } | 836 | } | ||
939 | 837 | | |||
940 | void QalculateExpression::updateVariables(MathStructure command) | 838 | | ||
941 | { | | |||
942 | Cantor::DefaultVariableModel* model = | | |||
943 | static_cast<Cantor::DefaultVariableModel*>(session()->variableModel()); | | |||
944 | QStack<MathStructure*> stack; | | |||
945 | stack.push(&command); | | |||
946 | QSharedPointer<PrintOptions> po = printOptions(); | | |||
947 | while (!stack.isEmpty()) { | | |||
948 | MathStructure* current = stack.pop(); | | |||
949 | if (current->isFunction() && current->function()->name() == "save" && | | |||
950 | current->countChildren() >= 2 && current->getChild(2)->isSymbolic()) | | |||
951 | { | | |||
952 | // I'd like to use CALCULATOR->getVariable and KnownVariable::get, | | |||
953 | // but that doesn't work for built in variables, as it keeps | | |||
954 | // returning the old value | | |||
955 | std::string name = current->getChild(2)->symbol(); | | |||
956 | MathStructure m = CALCULATOR->calculate(name, evaluationOptions()); | | |||
957 | m.format(*po); | | |||
958 | model->addVariable(QLatin1String(name.c_str()), QLatin1String(m.print(*po).c_str())); | | |||
959 | } | | |||
960 | for (size_t i = 0; i < current->countChildren(); ++i) { | | |||
961 | stack.push(current->getChild(i+1)); | | |||
962 | } | | |||
963 | } | | |||
964 | } | | |||
965 | 839 | | |||
966 | QSharedPointer<PrintOptions> QalculateExpression::printOptions() | 840 | QSharedPointer<PrintOptions> QalculateExpression::printOptions() | ||
967 | { | 841 | { | ||
968 | QSharedPointer<PrintOptions> po(new PrintOptions); | 842 | QSharedPointer<PrintOptions> po(new PrintOptions); | ||
969 | 843 | | |||
970 | switch (QalculateSettings::fractionFormat()) { | 844 | switch (QalculateSettings::fractionFormat()) { | ||
971 | case 0: | 845 | case 0: | ||
972 | po->number_fraction_format = FRACTION_DECIMAL; | 846 | po->number_fraction_format = FRACTION_DECIMAL; | ||
Show All 38 Lines |
You should comment out this line. It's only for testing isn't it?