diff --git a/data/io.github.Qalculate.qalculate-qt.desktop b/data/io.github.Qalculate.qalculate-qt.desktop index e155b75..fb88db0 100644 --- a/data/io.github.Qalculate.qalculate-qt.desktop +++ b/data/io.github.Qalculate.qalculate-qt.desktop @@ -34,7 +34,7 @@ StartupWMClass=qalculate-qt Categories=Qt;Utility;Calculator;Education;Science;Math; Keywords=calculation;arithmetic;scientific;financial; Keywords[ca]=calculation;arithmetic;scientific;financial; -Keywords[de]=Berechnung;Arithmetik; Wissenschaft;Finanzen; +Keywords[de]=Berechnung;Arithmetik;Wissenschaft;Finanzen; Keywords[es]=calculadora;aritmética;científica;financiera; Keywords[fr]=calcul;arithmétique;scientifique;financier; Keywords[pt_BR]=calculadora;aritmética;científica;financeira; diff --git a/data/io.github.Qalculate.qalculate-qt.metainfo.xml b/data/io.github.Qalculate.qalculate-qt.metainfo.xml index c0b41fd..147f47a 100644 --- a/data/io.github.Qalculate.qalculate-qt.metainfo.xml +++ b/data/io.github.Qalculate.qalculate-qt.metainfo.xml @@ -70,6 +70,28 @@ qalculate-qt + + +

Changes:

+
    +
  • Apply dual approximation/fraction to calculate as you type result, as regular result but with length restriction
  • +
  • Add option to add/edit comment to history context menu, and save comments in result on exit
  • +
  • Add "Search by Date" (also shows the date of the expression) to history context menu
  • +
  • Improve decision to automatically convert unchanged quantity with unit
  • +
  • Option to automatically group digits in input
  • +
  • Option, in menu, to open settings folder(s)
  • +
  • New functions: tripleProduct(), multilimit()
  • +
  • Updated French translation
  • +
  • Fix equals sign for calculate as you type result
  • +
  • Fix segfault with calculate as you type of "-(300K" and similar
  • +
  • Fix saving of two's complement input settings
  • +
  • Fix erroneous HTML output after format of result with error/warning has been updated
  • +
  • Fix case conversion of µ to M and similar
  • +
  • Fix segfault with very large integer raised by very large integer
  • +
  • Minor bug fixes and feature enhancements
  • +
+
+

Changes:

diff --git a/snap/gui/qalculate.desktop b/snap/gui/qalculate.desktop index 80cf69a..ed78fd6 100644 --- a/snap/gui/qalculate.desktop +++ b/snap/gui/qalculate.desktop @@ -6,6 +6,7 @@ GenericName[de]=Taschenrechner GenericName[es]=Calculadora GenericName[fr]=Calculatrice GenericName[pt_BR]=Calculadora +GenericName[pt_PT]=Calculadora GenericName[ru]=Калькулятор GenericName[sl]=Računalo GenericName[sv]=Kalkylator @@ -17,9 +18,11 @@ Comment[es]=Calculadora poderosa y fácil de usar Comment[fr]=Une calculatrice puissante et facile d'utilisation Comment[nl]=Gemakkelijk te gebruiken rekenmachine met veel mogelijkheden Comment[pt_BR]=Calculadora potente e fácil de usar +Comment[pt_PT]=Calculadora poderosa e fácil de usar Comment[ru]=Мощный и простой в использовании калькулятор Comment[sl]=Zmogljivo računalo, preprosto za uporabo Comment[sv]=Kraftfull och användarvänlig miniräknare +Comment[zh_CN]=强大而易用的计算器 Exec=qalculate-qt Icon=${SNAP}/meta/gui/qalculate.svg Terminal=false @@ -33,6 +36,7 @@ Keywords[de]=Berechnung;Arithmetik;Wissenschaft;Finanzen; Keywords[es]=calculadora;aritmética;científica;financiera; Keywords[fr]=calcul;arithmétique;scientifique;financier; Keywords[pt_BR]=calculadora;aritmética;científica;financeira; +Keywords[pt_PT]=calculadora;aritmética;científica;financeira; Keywords[ru]=расчёт;расчет;арифметика;научный;финансовый Keywords[sl]=izračun;aritmetika;znanstveno;finančno;računalo;kalkulator; Keywords[zh_CN]=计算;算术;科学;金融; diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index ebff5f2..0c6a1c6 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: qalculate-qt title: Qalculate! (Qt) -version: '5.3.0' +version: '5.4.0' license: GPL-2.0+ summary: The ultimate desktop calculator description: | @@ -42,7 +42,7 @@ apps: parts: libqalculate: source: https://github.com/Qalculate/libqalculate.git - source-tag: v5.3.0 + source-tag: v5.4.0 source-depth: 1 plugin: autotools build-environment: @@ -77,8 +77,8 @@ parts: - -usr/share/lintian qalculate-qt: - source: https://github.com/Qalculate/qalculate-qt/releases/download/v5.3.0/qalculate-qt-5.3.0.tar.gz - source-checksum: sha512/841461dca4fa97d9dc3cff57de050b5c0d1dabe06c151149484a85b66540b038f6d3270ca96a34a65fbd9e71da26ce1068f2df76adc365e74a0e4d2220ccc909 + source: https://github.com/Qalculate/qalculate-qt/releases/download/v5.4.0/qalculate-qt-5.4.0.tar.gz + source-checksum: sha512/30f30d904211ebf3ac57d1d5ddb1235763731bc93ced86507b94accfd1b320d7dcfe5c3a030bd2ae41e94bea53b4b68412faa5cc9a8ff54b52dd18b602011985 plugin: qmake build-snaps: - kde-frameworks-5-core18-sdk diff --git a/src/historyview.cpp b/src/historyview.cpp index fd29c66..465a0d5 100644 --- a/src/historyview.cpp +++ b/src/historyview.cpp @@ -421,7 +421,7 @@ int HistoryView::maxTemporaryCharacters() { return (width() * 1.65 / fm.averageCharWidth()) - 7; } -void HistoryView::addResult(std::vector values, std::string expression, bool pexact, std::string parse, int exact, bool dual_approx, const QString &image, bool *implicit_warning, int initial_load, size_t index, bool temporary) { +void HistoryView::addResult(std::vector values, std::string expression, bool pexact, std::string parse, int exact, bool dual_approx, const QString &image, bool *implicit_warning, int initial_load, size_t index, bool temporary, const std::string &tmp_value) { if(temporary && !previous_temporary) { previous_cursor2 = previous_cursor; } @@ -487,7 +487,7 @@ void HistoryView::addResult(std::vector values, std::string express str += "\">"; if(temporary) { parse_tmp = parse; - result_tmp = (values.empty() ? "" : values[0]); + result_tmp = tmp_value; } else if(!initial_load) { settings->v_expression.push_back(expression); settings->v_parse.push_back(parse); @@ -503,9 +503,11 @@ void HistoryView::addResult(std::vector values, std::string express settings->v_result.push_back(values); settings->v_exact.push_back(std::vector()); settings->v_value.push_back(std::vector()); + size_t n = 0; for(size_t i = 0; i < values.size(); i++) { settings->v_exact[settings->v_exact.size() - 1].push_back(exact || i < values.size() - 1); - settings->v_value[settings->v_value.size() - 1].push_back(dual_approx && i == 0 ? settings->history_answer.size() - 1 : settings->history_answer.size()); + settings->v_value[settings->v_value.size() - 1].push_back(dual_approx && n == 0 ? settings->history_answer.size() - 1 : settings->history_answer.size()); + if(values[i].empty() || values[i][0] != '#') n++; } } gsub("", "", parse); @@ -580,22 +582,24 @@ void HistoryView::addResult(std::vector values, std::string express if(temporary && values.empty()) { values.push_back(""); } + size_t n = 0; for(size_t i = 0; i < values.size(); i++) { + size_t i_answer = 0; + if(initial_load) i_answer = settings->v_value[index][i]; + else if(!temporary) i_answer = dual_approx && n == 0 ? settings->history_answer.size() - 1 : settings->history_answer.size(); if(!values[i].empty() && values[i][0] == '#') { str += " 1 && n > 0))) str += "; font-size:small"; else if(!comment) str += "; font-size:normal"; if((!expression.empty() || !parse.empty()) && i == values.size() - 1) str += QStringLiteral("; padding-bottom: %1 px").arg(paste_h / 4); str += "\">"; - 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(values[i].size() == 1 || values[i][1] != '-') str += "- "; str += QString::fromStdString(values[i]).mid(1); str += ""; continue; } - size_t i_answer = 0; - if(initial_load) i_answer = settings->v_value[index][i]; - else if(!temporary) i_answer = dual_approx && i == 0 ? settings->history_answer.size() - 1 : settings->history_answer.size(); QFontMetrics fm(font()); int w_number = fm.boundingRect("#9999").width(); int w = 0; @@ -609,26 +613,26 @@ void HistoryView::addResult(std::vector 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;