Skip to content

Commit

Permalink
Add result to history even if both expression and result are identica…
Browse files Browse the repository at this point in the history
…l if expression contains a function generating a random number; Allow omission of 1 in 1/n for output using fixed denominator; Do not update result when number base changes after closing programming keypad; Fixes/improvements for fractions with fixed denominator; Improvements/fixes for conversion menu; Increment version number
  • Loading branch information
hanna-kn committed Nov 26, 2023
1 parent 97a6fd0 commit 1faf1aa
Show file tree
Hide file tree
Showing 23 changed files with 5,929 additions and 5,867 deletions.
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Qt, and CLI).
1. Requirements

* Qt5 (>= 5.6) or Qt6
* libqalculate (>= 4.8.0)
* libqalculate (>= 4.9.0)

2. Installation

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Qalculate! is a multi-purpose cross-platform desktop calculator. It is simple to

## Requirements
* Qt5 (>= 5.6) or Qt6
* libqalculate (>= 4.8.0)
* libqalculate (>= 4.9.0)

## Installation
Instructions and download links for installers, binaries packages, and the source code of released versions of Qalculate! are available at https://qalculate.github.io/downloads.html.
Expand Down
25 changes: 24 additions & 1 deletion data/io.github.Qalculate.qalculate-qt.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
</description>
<screenshots>
<screenshot type="default">
<image>https://raw.githubusercontent.com/Qalculate/qalculate.github.io/master/images/qalculate-qt.png</image>
<image>https://raw.githubusercontent.com/Qalculate/qalculate-qt/master/data/io.github.Qalculate.qalculate-qt.png</image>
<caption>The main window with keypad visible</caption>
</screenshot>
</screenshots>
Expand All @@ -70,6 +70,29 @@
</provides>
<translation type="qt">qalculate-qt</translation>
<releases>
<release version="4.9.0" date="2023-11-27">
<description>
<p>Changes:</p>
<ul>
<li>Support for specifying a fixed denominator for display of fractions (e.g. "0.3 ft ➞ 1/8 ≈ (3 + 5/8) in")</li>
<li>Restore decimal number base after closing programming keypad</li>
<li>Improve appearance of conversion menu</li>
<li>Save position of main window even if size has not changed from the default</li>
<li>Always add result to history (even if identical to previous) if expression contains a function generating a random number</li>
<li>Prefer capitalized function name (over name with underscore), when completing function name</li>
<li>Return gcd of numerators divided by lcm of denominators in gcd() with non-integer rational numbers, and vice versa for lcm()</li>
<li>Add units for mean Gregorian and tropical years</li>
<li>Ignore underscore in number</li>
<li>Replace defunct exchange rates source and fix bitcoin exchange rate</li>
<li>Fix custom middle click button action</li>
<li>Fix immediate calculation after selecting to-conversion completion</li>
<li>Fix asin(x)=a, acos(x)=a, and atan(x)=a, when a contains an angle unit and default angle unit is set</li>
<li>Fix output of value converted to unit expression with numerical multiplier in denominator, e.g. "➞ L/(100 km)"</li>
<li>Fix segfault when trying to solve "(x*sqrt(x)-y*sqrt(y))/(sqrt(x)-sqrt(y))=x+sqrt(x*y)+y"</li>
<li>Fix parsing of case insensitive object name ending with Unicode character when followed by another Unicode character in expression, e.g. "микрометр"</li>
</ul>
</description>
</release>
<release version="4.8.1" date="2023-09-18">
<description>
<p>Changes:</p>
Expand Down
Binary file added data/io.github.Qalculate.qalculate-qt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion qalculate-qt.pro
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION = 4.8.1
VERSION = 4.9.0
isEmpty(PREFIX) {
PREFIX = /usr/local
}
Expand Down
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: '4.8.1'
version: '4.9.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: v4.8.1
source-tag: v4.9.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/v4.8.1/qalculate-qt-4.8.1.tar.gz
source-checksum: sha512/b1776b57ec268648a2375b3b5f94b7b3c01cccc3deb68ab57c0471200d7cfd1f94df7263d1be400d8af7e1f030aae34b828749a8f8b73cb51850d572c6d018e3
source: https://github.com/Qalculate/qalculate-qt/releases/download/v4.9.0/qalculate-qt-4.9.0.tar.gz
source-checksum: sha512/088e0768a65d88d641e1d45700774a9a6d7179c365fcee14194ec9a231f896823592092251b7355543c9ab627a4040e73aba95b2865420f20105ba82273b028a
plugin: qmake
build-snaps:
- kde-frameworks-5-core18-sdk
Expand Down
5 changes: 3 additions & 2 deletions src/expressionedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1200,13 +1200,14 @@ void ExpressionEdit::updateCompletion() {
} else {
title2 = QString::fromStdString(u->title(false));
ename = &u->preferredInputName(true, settings->printops.use_unicode_signs, false, u->isCurrency(), &can_display_unicode_string_function, completionView);
if(ename->abbreviation) {
if(ename->abbreviation && (!ename->suffix || (ename->name.length() > 5 && ename->name.find("_unit", ename->name.length() - 5) != std::string::npos))) {
bool tp = title2[title2.length() - 1] == ')';
title2 += " ";
if(!tp) title2 += "(";
if(name_has_formatting(ename)) title2 += QString::fromStdString(ename->formattedName(TYPE_UNIT, true, false, -1, true));
else title2 += QString::fromStdString(ename->name);
if(!tp) title2 += ")";
if(title2.contains("_")) title2 = QString::fromStdString(u->title(false));
}
}
title = QString::fromStdString(u->title(true, settings->printops.use_unicode_signs, &can_display_unicode_string_function, completionView));
Expand Down Expand Up @@ -1262,7 +1263,7 @@ void ExpressionEdit::updateCompletion() {
if(str.find("<") == std::string::npos) {
title2 += QString::fromStdString(str);
} else {
title2 += QString::fromStdString(cu->print(po, false, TAG_TYPE_HTML, false, false));
title2 += QString::fromStdString(cu->print(po, true, TAG_TYPE_TERMINAL, false, false));
}
}
if(!tp) title2 += ")";
Expand Down
2 changes: 1 addition & 1 deletion src/historyview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ void HistoryView::loadInitial() {
last_ref = "";
if(!settings->v_expression.empty()) {
for(size_t i = 0; i < settings->v_expression.size();) {
if(settings->v_delexpression[i] || (i > 0 && !settings->v_protected[i] && settings->v_expression[i] == settings->v_expression[i - 1] && settings->v_parse[i] == settings->v_parse[i - 1] && settings->v_result[i] == settings->v_result[i - 1] && settings->v_pexact[i] == settings->v_pexact[i] && settings->v_exact[i] == settings->v_exact[i - 1] && settings->v_delresult[i] == settings->v_delresult[i - 1] && settings->v_value[i] == settings->v_value[i - 1])) {
if(settings->v_delexpression[i] || (i > 0 && !settings->v_protected[i] && settings->v_expression[i] == settings->v_expression[i - 1] && settings->v_parse[i] == settings->v_parse[i - 1] && settings->v_result[i] == settings->v_result[i - 1] && settings->v_pexact[i] == settings->v_pexact[i] && settings->v_exact[i] == settings->v_exact[i - 1] && settings->v_delresult[i] == settings->v_delresult[i - 1] && settings->v_value[i] == settings->v_value[i - 1] && settings->v_parse[i].find("rand") == std::string::npos && settings->v_expression[i].find("rand") == std::string::npos)) {
settings->v_delexpression.erase(settings->v_delexpression.begin() + i);
settings->v_expression.erase(settings->v_expression.begin() + i);
settings->v_parse.erase(settings->v_parse.begin() + i);
Expand Down
6 changes: 3 additions & 3 deletions src/keypadwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,7 @@ void KeypadWidget::setKeypadType(int i) {
if(i < 0 || i > KEYPAD_CUSTOM) i = 0;
if(leftStack->currentIndex() == KEYPAD_PROGRAMMING && settings->programming_base_changed) {
settings->programming_base_changed = false;
emit baseClicked(BASE_DECIMAL, true);
emit baseClicked(BASE_DECIMAL, true, false);
}
leftStack->setCurrentIndex(i);
}
Expand Down Expand Up @@ -1519,11 +1519,11 @@ void KeypadWidget::onOperatorButtonClicked3() {
}
void KeypadWidget::onBaseButtonClicked() {
settings->programming_base_changed = settings->programming_base_changed || (settings->printops.base == BASE_DECIMAL && settings->evalops.parse_options.base == BASE_DECIMAL);
emit baseClicked(sender()->property(BUTTON_DATA).toInt(), true);
emit baseClicked(sender()->property(BUTTON_DATA).toInt(), true, true);
}
void KeypadWidget::onBaseButtonClicked2() {
settings->programming_base_changed = settings->programming_base_changed || (settings->printops.base == BASE_DECIMAL && settings->evalops.parse_options.base == BASE_DECIMAL);
emit baseClicked(sender()->property(BUTTON_DATA).toInt(), false);
emit baseClicked(sender()->property(BUTTON_DATA).toInt(), false, true);
}
void KeypadWidget::onItemButtonClicked() {
ExpressionItem *item = (ExpressionItem*) sender()->property(BUTTON_DATA).value<void*>();
Expand Down
2 changes: 1 addition & 1 deletion src/keypadwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ class KeypadWidget : public QWidget {
void newFunctionClicked();
void backspaceClicked();
void answerClicked();
void baseClicked(int, bool);
void baseClicked(int, bool, bool);
void factorizeClicked();
void expandClicked();
void expandPartialFractionsClicked();
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int main(int argc, char **argv) {
app.setApplicationName("qalculate-qt");
app.setApplicationDisplayName("Qalculate!");
app.setOrganizationName("qalculate");
app.setApplicationVersion("4.8.1");
app.setApplicationVersion("4.9.0");
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
Expand Down
10 changes: 6 additions & 4 deletions src/qalculateqtsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ long int get_fixed_denominator_qt2(const std::string &str, int &to_fraction, cha
} else {
if(str.length() > 2 && str[0] == '1' && str[1] == '/' && str.find_first_not_of(NUMBERS SPACES, 2) == std::string::npos) {
fden = s2i(str.substr(2, str.length() - 2));
} else if(str.length() > 1 && str[0] == '/' && str.find_first_not_of(NUMBERS SPACES, 1) == std::string::npos) {
fden = s2i(str.substr(1, str.length() - 1));
} else if(str == "3rds") {
fden = 3;
} else if(str == "halves") {
Expand Down Expand Up @@ -376,11 +378,11 @@ void QalculateQtSettings::readPreferenceValue(const std::string &svar, const std
} else if(svar == "number_fraction_format") {
if(v >= FRACTION_DECIMAL && v <= FRACTION_COMBINED) {
printops.number_fraction_format = (NumberFractionFormat) v;
printops.restrict_fraction_length = (v >= FRACTION_FRACTIONAL);
printops.restrict_fraction_length = (v == FRACTION_FRACTIONAL || v == FRACTION_COMBINED);
dual_fraction = 0;
} else if(v == FRACTION_COMBINED + 1) {
printops.number_fraction_format = FRACTION_FRACTIONAL;
printops.restrict_fraction_length = false;
printops.restrict_fraction_length = PREFERENCES_VERSION_AFTER(4, 8, 1);
dual_fraction = 0;
} else if(v == FRACTION_COMBINED + 2) {
printops.number_fraction_format = FRACTION_DECIMAL;
Expand Down Expand Up @@ -995,8 +997,8 @@ void QalculateQtSettings::loadPreferences() {
max_plot_time = 5;

preferences_version[0] = 4;
preferences_version[1] = 8;
preferences_version[2] = 1;
preferences_version[1] = 9;
preferences_version[2] = 0;

if(file) {
char line[1000000L];
Expand Down
36 changes: 27 additions & 9 deletions src/qalculatewindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
connect(keypad, SIGNAL(storeClicked()), this, SLOT(onStoreActivated()));
connect(keypad, SIGNAL(newFunctionClicked()), this, SLOT(newFunction()));
connect(keypad, SIGNAL(answerClicked()), this, SLOT(onAnswerClicked()));
connect(keypad, SIGNAL(baseClicked(int, bool)), this, SLOT(onBaseClicked(int, bool)));
connect(keypad, SIGNAL(baseClicked(int, bool, bool)), this, SLOT(onBaseClicked(int, bool, bool)));
connect(keypad, SIGNAL(factorizeClicked()), this, SLOT(onFactorizeClicked()));
connect(keypad, SIGNAL(expandClicked()), this, SLOT(onExpandClicked()));
connect(keypad, SIGNAL(expandPartialFractionsClicked()), this, SLOT(onExpandPartialFractionsClicked()));
Expand Down Expand Up @@ -3079,7 +3079,7 @@ void QalculateWindow::onAnswerClicked() {
onInsertValueRequested(settings->history_answer.size());
}
}
void QalculateWindow::onBaseClicked(int v, bool b) {
void QalculateWindow::onBaseClicked(int v, bool b, bool b_update) {
if(b && v != settings->evalops.parse_options.base) {
settings->evalops.parse_options.base = v;
QAction *action = find_child_data(this, "group_inbase", v);
Expand All @@ -3092,7 +3092,7 @@ void QalculateWindow::onBaseClicked(int v, bool b) {
to_bits = 0;
QAction *action = find_child_data(this, "group_outbase", v);
if(action) action->setChecked(true);
resultFormatUpdated();
if(b_update) resultFormatUpdated();
}
keypad->updateBase();
}
Expand Down Expand Up @@ -4025,6 +4025,10 @@ void QalculateWindow::setOption(std::string str) {
else if(equalsIgnoreCase(svalue, "auto")) v = -1;
else if(svalue.find_first_not_of(SPACES NUMBERS) == std::string::npos) {
v = s2i(svalue);
if(v == FRACTION_COMBINED + 1) v = FRACTION_COMBINED_FIXED_DENOMINATOR + 1;
else if(v == FRACTION_COMBINED + 2) v = FRACTION_COMBINED_FIXED_DENOMINATOR + 2;
else if(v == FRACTION_COMBINED_FIXED_DENOMINATOR + 1) v = FRACTION_FRACTIONAL_FIXED_DENOMINATOR;
else if(v == FRACTION_COMBINED_FIXED_DENOMINATOR + 2) v = FRACTION_COMBINED_FIXED_DENOMINATOR;
} else {
int tofr = 0;
long int fden = get_fixed_denominator_qt(settings->unlocalizeExpression(svalue), tofr, QString(), true);
Expand All @@ -4037,7 +4041,7 @@ void QalculateWindow::setOption(std::string str) {
if(v > FRACTION_COMBINED_FIXED_DENOMINATOR + 2) {
CALCULATOR->error(true, "Illegal value: %s.", svalue.c_str(), NULL);
} else {
settings->printops.restrict_fraction_length = (v >= FRACTION_FRACTIONAL && v <= FRACTION_COMBINED_FIXED_DENOMINATOR);
settings->printops.restrict_fraction_length = (v == FRACTION_FRACTIONAL || v == FRACTION_COMBINED);
if(v < 0) settings->dual_fraction = -1;
else if(v == FRACTION_COMBINED_FIXED_DENOMINATOR + 2) settings->dual_fraction = 1;
else settings->dual_fraction = 0;
Expand Down Expand Up @@ -6046,6 +6050,14 @@ int intervals_are_relative(MathStructure &m) {
return ret;
}

bool contains_rand_function(const MathStructure &m) {
if(m.isFunction() && m.function()->category() == CALCULATOR->getFunctionById(FUNCTION_ID_RAND)->category()) return true;
for(size_t i = 0; i < m.size(); i++) {
if(contains_rand_function(m[i])) return true;
}
return false;
}

void QalculateWindow::setResult(Prefix *prefix, bool update_history, bool update_parse, bool force, std::string transformation, bool do_stack, size_t stack_index, bool register_moved, bool supress_dialog) {

if(block_result_update) return;
Expand Down Expand Up @@ -6163,7 +6175,7 @@ void QalculateWindow::setResult(Prefix *prefix, bool update_history, bool update
CALCULATOR->setFixedDenominator(to_fixed_fraction);
settings->dual_fraction = 0;
do_to = true;
} else if(to_fraction > 0 && (settings->printops.restrict_fraction_length || settings->printops.number_fraction_format != FRACTION_COMBINED)) {
} else if(to_fraction > 0 && (settings->dual_fraction != 0 || settings->printops.restrict_fraction_length || (to_fraction != 2 && settings->printops.number_fraction_format != FRACTION_COMBINED) || (to_fraction == 2 && settings->printops.number_fraction_format != FRACTION_FRACTIONAL))) {
settings->printops.restrict_fraction_length = false;
if(to_fraction == 2) settings->printops.number_fraction_format = FRACTION_FRACTIONAL;
else settings->printops.number_fraction_format = FRACTION_COMBINED;
Expand Down Expand Up @@ -6331,7 +6343,7 @@ void QalculateWindow::setResult(Prefix *prefix, bool update_history, bool update
size_t index = settings->v_expression.size();
while(index > 0 && settings->v_delexpression[index - 1]) index--;
bool b_add = true;
if(index > 0 && !CALCULATOR->message() && (!update_parse || (settings->history_answer.size() > (mstruct_exact.isUndefined() ? 1 : 2) && !settings->rpn_mode && mstruct->equals(*settings->history_answer[settings->history_answer.size() - 1], true, true) && (mstruct_exact.isUndefined() || (settings->history_answer.size() > 1 && mstruct_exact.equals(*settings->history_answer[settings->history_answer.size() - 2], true, true))) && parsed_text == settings->v_parse[index - 1] && prev_result_text == settings->v_expression[index - 1] && parsed_approx != settings->v_pexact[index - 1])) && alt_results.size() <= settings->v_result[index - 1].size()) {
if(index > 0 && !CALCULATOR->message() && (!update_parse || (settings->history_answer.size() > (mstruct_exact.isUndefined() ? 1 : 2) && !settings->rpn_mode && mstruct->equals(*settings->history_answer[settings->history_answer.size() - 1], true, true) && (mstruct_exact.isUndefined() || (settings->history_answer.size() > 1 && mstruct_exact.equals(*settings->history_answer[settings->history_answer.size() - 2], true, true))) && parsed_text == settings->v_parse[index - 1] && prev_result_text == settings->v_expression[index - 1] && parsed_approx != settings->v_pexact[index - 1] && !contains_rand_function(*parsed_mstruct))) && alt_results.size() <= settings->v_result[index - 1].size()) {
b_add = false;
for(size_t i = 0; i < alt_results.size(); i++) {
if(settings->v_delresult[index - 1][i] || settings->v_exact[index - 1][i] != (b_exact || i < alt_results.size() - 1) || settings->v_result[index - 1][i] != alt_results[i]) {
Expand Down Expand Up @@ -6710,8 +6722,14 @@ void QalculateWindow::closeEvent(QCloseEvent *e) {
void QalculateWindow::onToActivated(bool button) {
QTextCursor cur = expressionEdit->textCursor();
bool b_result = !expressionEdit->expressionHasChanged() && settings->current_result;
if(!b_result) {
expressionEdit->blockCompletion(true, button);
bool b_addto = !b_result;
if(b_addto && button && CALCULATOR->hasToExpression(expressionEdit->toPlainText().toStdString(), true, settings->evalops)) {
std::string str = expressionEdit->toPlainText().toStdString(), to_str;
CALCULATOR->separateToExpression(str, to_str, settings->evalops, true, true);
if(to_str.empty()) b_addto = false;
}
if(!b_result) expressionEdit->blockCompletion(true, button);
if(b_addto) {
expressionEdit->blockParseStatus();
expressionEdit->moveCursor(QTextCursor::End);
expressionEdit->insertPlainText("➞");
Expand Down Expand Up @@ -6862,7 +6880,7 @@ void QalculateWindow::onKeypadVisibilityChanged(bool b) {
resetKeypadPositionAction->setEnabled(keypadDock->isVisible() && (keypadDock->isFloating() || dockWidgetArea(keypadDock) != Qt::BottomDockWidgetArea));
if(!b && settings->keypad_type == KEYPAD_PROGRAMMING && settings->programming_base_changed) {
settings->programming_base_changed = false;
onBaseClicked(BASE_DECIMAL, true);
onBaseClicked(BASE_DECIMAL, true, false);
}
}
void QalculateWindow::onBasesActivated(bool b) {
Expand Down
2 changes: 1 addition & 1 deletion src/qalculatewindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class QalculateWindow : public QMainWindow {
void onMPlusClicked();
void onMMinusClicked();
void onAnswerClicked();
void onBaseClicked(int, bool);
void onBaseClicked(int, bool, bool);
void onFactorizeClicked();
void onExpandClicked();
void onExpandPartialFractionsClicked();
Expand Down
Loading

0 comments on commit 1faf1aa

Please sign in to comment.