Skip to content

Commit

Permalink
Fix erroneous HTML output after format of result with error/warning h…
Browse files Browse the repository at this point in the history
…as been updated; Do not show optional arguments when minimum number of arguments is two or more (affects gcd, lcm, and parallel) in insert function dialog; Add support "digits" and "autocalc" qalc set command options; Only insert text for one format of calculate-as-you-type result; Comments fixes/improvements; Complete preparations for version 5.4.0
  • Loading branch information
hanna-kn committed Nov 25, 2024
1 parent 01eba16 commit 962edac
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 45 deletions.
2 changes: 1 addition & 1 deletion data/io.github.Qalculate.qalculate-qt.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions data/io.github.Qalculate.qalculate-qt.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,28 @@
</provides>
<translation type="qt">qalculate-qt</translation>
<releases>
<release version="5.4.0" date="2024-11-25">
<description>
<p>Changes:</p>
<ul>
<li>Apply dual approximation/fraction to calculate as you type result, as regular result but with length restriction</li>
<li>Add option to add/edit comment to history context menu, and save comments in result on exit</li>
<li>Add "Search by Date" (also shows the date of the expression) to history context menu</li>
<li>Improve decision to automatically convert unchanged quantity with unit</li>
<li>Option to automatically group digits in input</li>
<li>Option, in menu, to open settings folder(s)</li>
<li>New functions: tripleProduct(), multilimit()</li>
<li>Updated French translation</li>
<li>Fix equals sign for calculate as you type result</li>
<li>Fix segfault with calculate as you type of "-(300K" and similar</li>
<li>Fix saving of two's complement input settings</li>
<li>Fix erroneous HTML output after format of result with error/warning has been updated</li>
<li>Fix case conversion of µ to M and similar</li>
<li>Fix segfault with very large integer raised by very large integer</li>
<li>Minor bug fixes and feature enhancements</li>
</ul>
</description>
</release>
<release version="5.3.0" date="2024-10-07">
<description>
<p>Changes:</p>
Expand Down
4 changes: 4 additions & 0 deletions snap/gui/qalculate.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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]=计算;算术;科学;金融;
8 changes: 4 additions & 4 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -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: |
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
89 changes: 57 additions & 32 deletions src/historyview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ int HistoryView::maxTemporaryCharacters() {
return (width() * 1.65 / fm.averageCharWidth()) - 7;
}

void HistoryView::addResult(std::vector<std::string> 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<std::string> 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;
}
Expand Down Expand Up @@ -487,7 +487,7 @@ void HistoryView::addResult(std::vector<std::string> 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);
Expand All @@ -503,9 +503,11 @@ void HistoryView::addResult(std::vector<std::string> values, std::string express
settings->v_result.push_back(values);
settings->v_exact.push_back(std::vector<int>());
settings->v_value.push_back(std::vector<size_t>());
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("</i>", "<img src=\"data://img1px.png\" width=\"1\"/></i>", parse);
Expand Down Expand Up @@ -580,22 +582,24 @@ void HistoryView::addResult(std::vector<std::string> 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 += "<tr><td colspan=\"2\" style=\"text-align:left";
if(!comment && initial_load) str += "; font-size:small";
if(!comment && (initial_load == 1 || (initial_load > 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("<a name=\"%1:%2\" style=\"text-decoration: none\">").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("<a name=\"%1:%2\" style=\"text-decoration: none\">").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("<a name=\"c%1:%2:%3\" style=\"text-decoration: none\">").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 += "</a></td></tr>";
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;
Expand All @@ -609,26 +613,26 @@ void HistoryView::addResult(std::vector<std::string> values, std::string express
}
QString sref;
if(settings->color == 2) {
sref = QStringLiteral("<a href=\"#%1:%2:%3\" style=\"text-decoration: none; text-align:left; color: #AAAAAA\">#%1</a>").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("<a href=\"#%1:%2:%3\" style=\"text-decoration: none; text-align:left; color: #AAAAAA\">#%1</a>").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("<a href=\"#%1:%2:%3\" style=\"text-decoration: none; text-align:left; color: #585858\">#%1</a>").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("<a href=\"#%1:%2:%3\" style=\"text-decoration: none; text-align:left; color: #585858\">#%1</a>").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 += "</td><td style=\"text-align:right";
if(initial_load == 1 || (initial_load > 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("</i>", "<img src=\"data://img1px.png\" width=\"1\"/></i>", values[i]);
} else if(w * 1.85 + w_number > width()) {
str += "; font-size:large";
Expand All @@ -650,7 +654,7 @@ void HistoryView::addResult(std::vector<std::string> values, std::string express
if(temporary && !values[i].empty()) {
str += "<a name=\"TR\" style=\"text-decoration: none\">";
} else if(!temporary) {
if(i_answer == 0) str += QStringLiteral("<a name=\"%1:%2\" style=\"text-decoration: none\">").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("<a name=\"%1:%2\" style=\"text-decoration: none\">").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("<a name=\"p%1:%2:%3\" style=\"text-decoration: none\">").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()) {
Expand Down Expand Up @@ -686,6 +690,7 @@ void HistoryView::addResult(std::vector<std::string> values, std::string express
if(!temporary || !values[i].empty()) str += "</a>";
str += "</td></tr>";
i_answer_pre = i_answer;
n++;
}
str.replace("\n", "<br>");
int i = 0;
Expand All @@ -697,7 +702,7 @@ void HistoryView::addResult(std::vector<std::string> 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\"");
}
Expand All @@ -706,7 +711,7 @@ void HistoryView::addResult(std::vector<std::string> 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);
Expand All @@ -715,7 +720,7 @@ void HistoryView::addResult(std::vector<std::string> 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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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]);
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1070,19 +1077,35 @@ void HistoryView::editComment() {
QString str = "#" + commentEdit->toPlainText().trimmed().toHtmlEscaped();
str.replace("\n", "<br>");
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<std::string> 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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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());
Expand Down
3 changes: 2 additions & 1 deletion src/historyview.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class HistoryView : public QTextEdit {
QAction *findAction;
QDialog *searchDialog;

void addResult(std::vector<std::string> 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<std::string> 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);
Expand Down Expand Up @@ -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:

Expand Down
Loading

0 comments on commit 962edac

Please sign in to comment.