values, std::string express
}
QString sref;
if(settings->color == 2) {
- sref = QStringLiteral("#%1").arg(i_answer).arg(initial_load ? (int) index : settings->v_expression.size() - 1).arg(initial_load ? (int) i : settings->v_result[settings->v_result.size() - 1].size() - i - 1);
+ sref = QStringLiteral("#%1").arg(i_answer).arg(initial_load ? (int) index : settings->v_expression.size() - 1).arg(initial_load == 1 ? (int) i : settings->v_result[settings->v_result.size() - 1].size() - i - 1);
} else {
- sref = QStringLiteral("#%1").arg(i_answer).arg(initial_load ? (int) index : settings->v_expression.size() - 1).arg(initial_load ? (int) i : settings->v_result[settings->v_result.size() - 1].size() - i - 1);
+ sref = QStringLiteral("#%1").arg(i_answer).arg(initial_load ? (int) index : settings->v_expression.size() - 1).arg(initial_load == 1 ? (int) i : settings->v_result[settings->v_result.size() - 1].size() - i - 1);
}
bool b = true;
if(initial_load) {
for(size_t i2 = 0; i2 < i; i2++) {
- if(settings->v_value[index][i2] == i_answer) {
+ if(settings->v_value[index][i2] == i_answer && (values[i2].empty() || values[i2][0] != '#')) {
b = false;
}
}
}
if(b) str += sref;
- if((initial_load > 1 && i == 0) || (!initial_load && (!dual_approx || i == values.size() - 1))) {
+ if((initial_load > 1 && n == 0) || (!initial_load && (!dual_approx || i == values.size() - 1))) {
last_ans = i_answer;
last_ref = sref;
}
}
str += " 1 && i > 0 && i_answer <= i_answer_pre) || w * 1.5 + w_number > width() || !settings->format_result) {
+ if(initial_load == 1 || (initial_load > 1 && n > 0 && i_answer <= i_answer_pre) || w * 1.5 + w_number > width() || !settings->format_result) {
gsub("", "", values[i]);
} else if(w * 1.85 + w_number > width()) {
str += "; font-size:large";
@@ -650,7 +654,7 @@ void HistoryView::addResult(std::vector values, std::string express
if(temporary && !values[i].empty()) {
str += "";
} else if(!temporary) {
- if(i_answer == 0) str += QStringLiteral("").arg(initial_load ? index : settings->v_expression.size() - 1).arg(initial_load == 1 ? (int) i : settings->v_result[settings->v_result.size() - 1].size() - i - 1);
+ if(i_answer == 0) str += QStringLiteral("").arg(initial_load ? index : settings->v_expression.size() - 1).arg(initial_load ? (int) i : settings->v_result[settings->v_result.size() - 1].size() - i - 1);
else str += QStringLiteral("").arg(i_answer).arg(initial_load ? index : settings->v_expression.size() - 1).arg(initial_load == 1 ? (int) i : settings->v_result[settings->v_result.size() - 1].size() - i - 1);
}
if(!temporary || !values[i].empty()) {
@@ -686,6 +690,7 @@ void HistoryView::addResult(std::vector values, std::string express
if(!temporary || !values[i].empty()) str += "";
str += " | ";
i_answer_pre = i_answer;
+ n++;
}
str.replace("\n", "
");
int i = 0;
@@ -697,7 +702,7 @@ void HistoryView::addResult(std::vector values, std::string express
last_ref2 = last_ref;
}
if(!initial_load) {
- if(settings->format_result) {
+ if(settings->format_result && n > 0) {
previous_html.replace("font-size:normal", "font-size:small ");
previous_html.replace("width=\"2\"", "width=\"1\"");
}
@@ -706,7 +711,7 @@ void HistoryView::addResult(std::vector values, std::string express
if(i < 0) break;
int i2 = previous_html.indexOf(">", i);
previous_html.remove(i, i2 - i + 1);
- if(i < i_pos_p) i_pos_p -= (i2 - i + 1);
+ if(i < i_pos_p && expression.empty() && parse.empty()) i_pos_p -= (i2 - i + 1);
}
QTextCursor cur = textCursor();
cur.setPosition(previous_cursor);
@@ -715,7 +720,7 @@ void HistoryView::addResult(std::vector values, std::string express
cur.deleteChar();
}
if(expression.empty() && parse.empty()) {
- if(!initial_load && settings->format_result) {
+ if(!initial_load && settings->format_result && n > 0) {
i = 0;
while(true) {
i = previous_html.indexOf("; font-size:x-large", i);
@@ -843,7 +848,9 @@ void HistoryView::mouseDoubleClickEvent(QMouseEvent *e) {
int i1 = -1, i2 = -1;
indexAtPos(e->pos(), &i1, &i2, NULL, &str);
if(i1 >= 0 && str.length() > 0) {
- if(str[0] == 'p') {
+ if(str[0] == 'c') {
+ editComment(i1, i2);
+ } else if(str[0] == 'p') {
int index = str.indexOf(":");
if(index < 0) return;
str = str.mid(index + 1);
@@ -874,7 +881,7 @@ void HistoryView::mouseDoubleClickEvent(QMouseEvent *e) {
int i1 = str.left(index).toInt();
int i2 = str.mid(index + 1).toInt();
if(i1 >= 0 && (size_t) i1 < settings->v_result.size() && i2 >= 0 && (size_t) i2 < settings->v_result[i1].size()) {
- if(!settings->v_result[i1][i2].empty() && settings->v_result[i1][i2][0] == '#') emit insertTextRequested(settings->v_result[i1][i2].substr(1));
+ if(!settings->v_result[i1][i2].empty() && settings->v_result[i1][i2][0] == '#') editComment(i1, i2);
else emit insertTextRequested(settings->v_result[i1][i2]);
}
}
@@ -1037,12 +1044,12 @@ void HistoryView::editRemove() {
reloadHistory();
verticalScrollBar()->setValue(vpos);
}
-void HistoryView::editComment() {
- int i1 = -1, i2 = -1;
- indexAtPos(context_pos, &i1, &i2);
- if(i1 < 0 || i1 >= (int) settings->v_expression.size()) return;
- bool b_edit = i2 >= 0 && i2 < (int) settings->v_result[i1].size() && !settings->v_result[i1][i2].empty() && settings->v_result[i1][i2][0] == '#';
- if(i2 < 0 || i2 >= (int) settings->v_result[i1].size()) i2 = 0;
+void HistoryView::editComment(int i1, int i2) {
+ bool b_edit = !settings->v_result[i1][i2].empty() && settings->v_result[i1][i2][0] == '#';
+ if(i2 > 0 && !settings->v_result[i1][i2 - 1].empty() && settings->v_result[i1][i2 - 1][0] == '#') {
+ i2--;
+ b_edit = true;
+ }
QDialog *dialog = new QDialog(this);
QVBoxLayout *box = new QVBoxLayout(dialog);
if(settings->always_on_top) dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
@@ -1070,19 +1077,35 @@ void HistoryView::editComment() {
QString str = "#" + commentEdit->toPlainText().trimmed().toHtmlEscaped();
str.replace("\n", "
");
if(b_edit) {
- settings->v_result[i1][i2] = str.toStdString();
+ if(settings->v_result[i1][i2] != str.toStdString()) {
+ settings->v_result[i1][i2] = str.toStdString();
+ int vpos = verticalScrollBar()->value();
+ reloadHistory();
+ verticalScrollBar()->setValue(vpos);
+ }
+ } else if(!settings->history_answer.empty() && i1 == (int) settings->v_result.size() - 1 && i2 == 0) {
+ std::vector values;
+ values.push_back(str.toStdString());
+ addResult(values, "", true, "", settings->v_exact[i1][i2]);
} else {
settings->v_result[i1].insert(settings->v_result[i1].begin() + i2, str.toStdString());
settings->v_exact[i1].insert(settings->v_exact[i1].begin() + i2, settings->v_exact[i1][i2]);
settings->v_value[i1].insert(settings->v_value[i1].begin() + i2, settings->v_value[i1][i2]);
+ int vpos = verticalScrollBar()->value();
+ reloadHistory();
+ verticalScrollBar()->setValue(vpos);
}
- int vpos = verticalScrollBar()->value();
- reloadHistory();
- verticalScrollBar()->setValue(vpos);
}
}
dialog->deleteLater();
}
+void HistoryView::editComment() {
+ int i1 = -1, i2 = -1;
+ indexAtPos(context_pos, &i1, &i2);
+ if(i1 < 0 || i1 >= (int) settings->v_expression.size()) return;
+ if(i2 < 0 || i2 >= (int) settings->v_result[i1].size()) i2 = 0;
+ editComment(i1, i2);
+}
void HistoryView::editProtect() {
int i1 = -1, i2 = -1;
indexAtPos(context_pos, &i1, &i2);
@@ -1124,7 +1147,7 @@ void HistoryView::indexAtPos(const QPoint &pos, int *expression_index, int *resu
if(anchorstr) *anchorstr = sref;
if(sref.isEmpty() || sref == "TR" || sref == "TP") return;
int i = sref.indexOf(":");
- if(sref[0] == '#' || sref[0] == 'p') {
+ if(sref[0] == '#' || sref[0] == 'p' || sref[0] == 'c') {
if(i < 0) return;
int i2 = sref.indexOf(":", i + 1);
if(i2 >= 0) {
@@ -1193,7 +1216,9 @@ void HistoryView::contextMenuEvent(QContextMenuEvent *e) {
selectAllAction->setEnabled(!document()->isEmpty());
protectAction->setChecked(i1 >= 0 && i1 < (int) settings->v_protected.size() && settings->v_protected[i1]);
if((i1 >= 0 || b_tmp) && e->reason() == QContextMenuEvent::Mouse && !textCursor().hasSelection()) {
- insertValueAction->setEnabled(i3 >= 0);
+ if(i2 < 0) i2 = 0;
+ bool b_edit = (!astr.isEmpty() && astr[0] == 'c') || (!b_tmp && i2 < (int) settings->v_result[i1].size() && ((!settings->v_result[i1][i2].empty() && settings->v_result[i1][i2][0] == '#') || (i2 > 0 && !settings->v_result[i1][i2 - 1].empty() && settings->v_result[i1][i2 - 1][0] == '#')));
+ insertValueAction->setEnabled(i3 >= 0 && !b_edit);
insertTextAction->setEnabled(true);
copyAction->setEnabled(true);
copyFormattedAction->setEnabled(true);
@@ -1208,7 +1233,7 @@ void HistoryView::contextMenuEvent(QContextMenuEvent *e) {
#endif
else findDateAction->setText(tr("Search by Date…"));
commentAction->setEnabled(i1 >= 0);
- if(i1 >= 0 && i2 >= 0 && i2 < (int) settings->v_result[i1].size() && !settings->v_result[i1][i2].empty() && settings->v_result[i1][i2][0] == '#') commentAction->setText(tr("Edit Comment…"));
+ if(b_edit) commentAction->setText(tr("Edit Comment…"));
else commentAction->setText(tr("Add Comment…"));
} else {
copyAction->setEnabled(textCursor().hasSelection());
diff --git a/src/historyview.h b/src/historyview.h
index fecb155..d250f58 100644
--- a/src/historyview.h
+++ b/src/historyview.h
@@ -35,7 +35,7 @@ class HistoryView : public QTextEdit {
QAction *findAction;
QDialog *searchDialog;
- void addResult(std::vector values, std::string expression = "", bool pexact = true, std::string parse = "", int exact = 1, bool dual_approx = false, const QString &image = QString(), bool *implicit_warning = NULL, int initial_load = 0, size_t index = 0, bool temporary = false);
+ void addResult(std::vector values, std::string expression = "", bool pexact = true, std::string parse = "", int exact = 1, bool dual_approx = false, const QString &image = QString(), bool *implicit_warning = NULL, int initial_load = 0, size_t index = 0, bool temporary = false, const std::string &tmp_value = "");
void clearTemporary();
void addMessages();
void loadInitial(bool reload = false);
@@ -69,6 +69,7 @@ class HistoryView : public QTextEdit {
void keyPressEvent(QKeyEvent *e) override;
void inputMethodEvent(QInputMethodEvent*) override;
void changeEvent(QEvent*) override;
+ void editComment(int, int);
protected slots:
diff --git a/src/qalculatewindow.cpp b/src/qalculatewindow.cpp
index a224ce4..44d94df 100644
--- a/src/qalculatewindow.cpp
+++ b/src/qalculatewindow.cpp
@@ -3398,7 +3398,7 @@ void QalculateWindow::setPreviousExpression() {
void QalculateWindow::resultFormatUpdated(int delay) {
if(rfTimer) rfTimer->stop();
- if(block_result_update) return;
+ if(block_result_update || (!expressionEdit->expressionHasChanged() && auto_expression.empty() && parsed_mstruct && parsed_mstruct->isFunction() && parsed_mstruct->function()->id() == FUNCTION_ID_MESSAGE)) return;
if(delay > 0) {
if(!rfTimer) {
rfTimer = new QTimer();
@@ -3412,7 +3412,7 @@ void QalculateWindow::resultFormatUpdated(int delay) {
workspace_changed = true;
setResult(NULL, true, false, false);
auto_format_updated = true;
- if(!QToolTip::text().isEmpty() || (settings->status_in_history && expressionEdit->expressionHasChanged())) expressionEdit->displayParseStatus(true);
+ if((!settings->status_in_history && !QToolTip::text().isEmpty()) || (settings->status_in_history && expressionEdit->expressionHasChanged())) expressionEdit->displayParseStatus(true);
}
void QalculateWindow::resultDisplayUpdated() {
resultFormatUpdated();
@@ -3431,7 +3431,7 @@ void QalculateWindow::expressionFormatUpdated(bool recalculate) {
}
}
workspace_changed = true;
- if(!settings->rpn_mode && recalculate) {
+ if(!settings->rpn_mode && recalculate && (expressionEdit->expressionHasChanged() || !parsed_mstruct || !parsed_mstruct->isFunction() || parsed_mstruct->function()->id() != FUNCTION_ID_MESSAGE)) {
calculateExpression(false);
}
if(expressionEdit->expressionHasChanged()) expressionEdit->displayParseStatus(true, !QToolTip::text().isEmpty());
@@ -3450,7 +3450,7 @@ void QalculateWindow::expressionCalculationUpdated(int delay) {
workspace_changed = true;
auto_calculation_updated = true;
settings->updateMessagePrintOptions();
- if(!settings->rpn_mode) {
+ if(!settings->rpn_mode && (expressionEdit->expressionHasChanged() || !parsed_mstruct || !parsed_mstruct->isFunction() || parsed_mstruct->function()->id() != FUNCTION_ID_MESSAGE)) {
if(parsed_mstruct) {
for(size_t i = 0; i < 5; i++) {
if(parsed_mstruct->contains(settings->vans[i])) return;
@@ -4223,6 +4223,13 @@ void QalculateWindow::setOption(std::string str) {
} else {
settings->colorize_result = v;
}
+ } else if(equalsIgnoreCase(svar, "calculate as you type") || svar == "autocalc") {
+ bool b = settings->display_expression_status;
+ SET_BOOL(b)
+ if(b != settings->display_expression_status) {
+ settings->display_expression_status = b;
+ onExpressionStatusModeChanged(true);
+ }
} else if(equalsIgnoreCase(svar, "max decimals") || svar == "maxdeci") {
int v = -1;
if(equalsIgnoreCase(svalue, "off")) v = -1;
@@ -4249,6 +4256,29 @@ void QalculateWindow::setOption(std::string str) {
settings->printops.use_min_decimals = (v > 0);
settings->printops.min_decimals = v;
resultFormatUpdated();
+ } else if(equalsIgnoreCase(svar, "digits")) {
+ int v = -1;
+ if(equalsIgnoreCase(svalue, "off") || equalsIgnoreCase(svalue, "auto") || equalsIgnoreCase(svalue, "precision")) v = -1;
+ else if(!empty_value && svalue.find_first_not_of(SPACES NUMBERS) == std::string::npos) v = s2i(svalue);
+ if(v < PRECISION) {
+ QSpinBox *w = findChild("spinbox_maxdecimals");
+ if(w) {
+ w->blockSignals(true);
+ w->setValue(-1);
+ w->blockSignals(false);
+ }
+ }
+ if(v <= 0 || v == PRECISION) {
+ settings->printops.max_decimals = -1;
+ settings->printops.use_max_decimals = false;
+ resultFormatUpdated();
+ } else if(v >= 2 && v < PRECISION) {
+ settings->printops.max_decimals = -v;
+ settings->printops.use_max_decimals = true;
+ resultFormatUpdated();
+ } else {
+ CALCULATOR->error(true, "Illegal value: %s.", svalue.c_str(), NULL);
+ }
} else if(equalsIgnoreCase(svar, "fractions") || svar == "fr") {
int v = -1;
if(equalsIgnoreCase(svalue, "off")) v = FRACTION_DECIMAL;
@@ -6289,7 +6319,7 @@ void QalculateWindow::autoCalculateTimeout() {
bool is_approximate = false;
PrintOptions po = settings->printops;
po.is_approximate = &is_approximate;
- std::string str = current_status_expression, result;
+ std::string str = current_status_expression, result, single_result;
CALCULATOR->beginTemporaryStopMessages();
@@ -6696,6 +6726,7 @@ void QalculateWindow::autoCalculateTimeout() {
int max_length = -1;
if(!mauto.isNumber() || !mauto.number().isRational() || mauto.number().denominator() >= 20 || mauto.number() >= 100 || mauto.number() <= -100) max_length = historyView->maxTemporaryCharacters();
print_dual(mauto, str, mparsed, mexact, result, values, po, settings->evalops, settings->dual_fraction < 0 ? AUTOMATIC_FRACTION_AUTO : (settings->dual_fraction > 0 ? AUTOMATIC_FRACTION_DUAL : AUTOMATIC_FRACTION_OFF), settings->dual_approximation < 0 ? AUTOMATIC_APPROXIMATION_AUTO : (settings->dual_fraction > 0 ? AUTOMATIC_APPROXIMATION_DUAL : AUTOMATIC_APPROXIMATION_OFF), settings->complex_angle_form, &exact_comparison, true, settings->format_result, settings->color, TAG_TYPE_HTML, max_length, had_to_expression);
+ single_result = result;
if(max_length >= 0) {
size_t l = unformatted_length(result);
for(size_t i = 0; i < values.size(); i++) {
@@ -6785,7 +6816,7 @@ void QalculateWindow::autoCalculateTimeout() {
CALCULATOR->addMessages(&messages);
int b_exact = (exact_comparison || (!is_approximate && !mauto.isApproximate()));
if(!values.empty() && (mauto.isComparison() || ((mauto.isLogicalAnd() || mauto.isLogicalOr()) && mauto.containsType(STRUCT_COMPARISON, true, false, false))) && (exact_comparison || b_exact || values[0].find(SIGN_ALMOST_EQUAL) != std::string::npos)) b_exact = -1;
- historyView->addResult(values, "", true, auto_expression, b_exact, false, flag, NULL, 0, 0, true);
+ historyView->addResult(values, "", true, auto_expression, b_exact, false, flag, NULL, 0, 0, true, values.empty() ? "" : single_result);
updateWindowTitle(QString::fromStdString(unhtmlize(auto_result)), true);
}
@@ -9212,7 +9243,7 @@ void QalculateWindow::insertFunction(MathFunction *f, QWidget *parent) {
} else if(f->minargs() > 0) {
args = f->minargs();
while(!f->getDefaultValue(args + 1).empty()) args++;
- args++;
+ if(args == 1 || f->id() == FUNCTION_ID_PLOT) args++;
} else {
args = 1;
has_vector = true;