Fix segfault in action list with Qt 5; Add option to change the max number of history lines saved; Save timestamp of history item; Fix keyboard shortcuts with toolbar hidden; Improvements/fixes for preserved history height; Update translations

This commit is contained in:
Hanna K. 2024-06-20 12:08:33 +02:00
parent 0ea40a8f7c
commit 7f6335f6a5
17 changed files with 9468 additions and 8344 deletions

View File

@ -323,6 +323,7 @@ void HistoryView::loadInitial(bool reload) {
settings->v_parse.erase(settings->v_parse.begin() + i);
settings->v_result.erase(settings->v_result.begin() + i);
settings->v_protected.erase(settings->v_protected.begin() + i);
settings->v_time.erase(settings->v_time.begin() + i);
settings->v_exact.erase(settings->v_exact.begin() + i);
settings->v_pexact.erase(settings->v_pexact.begin() + i);
settings->v_value.erase(settings->v_value.begin() + i);
@ -470,6 +471,11 @@ void HistoryView::addResult(std::vector<std::string> values, std::string express
settings->v_parse.push_back(parse);
settings->v_pexact.push_back(pexact);
settings->v_protected.push_back(false);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
settings->v_time.push_back(QDateTime::currentSecsSinceEpoch());
#else
settings->v_time.push_back(QDateTime::currentMSecsSinceEpoch() / 1000);
#endif
settings->v_messages.push_back(serror);
settings->v_parseerror.push_back(b_parse_error);
settings->v_result.push_back(values);
@ -903,6 +909,7 @@ void HistoryView::editClear() {
settings->v_parse.erase(settings->v_parse.begin() + i1);
settings->v_result.erase(settings->v_result.begin() + i1);
settings->v_protected.erase(settings->v_protected.begin() + i1);
settings->v_time.erase(settings->v_time.begin() + i1);
settings->v_exact.erase(settings->v_exact.begin() + i1);
settings->v_pexact.erase(settings->v_pexact.begin() + i1);
settings->v_value.erase(settings->v_value.begin() + i1);
@ -924,6 +931,11 @@ void HistoryView::editMoveToTop() {
settings->v_parse.push_back(settings->v_parse[i1]);
settings->v_pexact.push_back(settings->v_pexact[i1]);
settings->v_protected.push_back(settings->v_protected[i1]);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
settings->v_time.push_back(QDateTime::currentSecsSinceEpoch());
#else
settings->v_time.push_back(QDateTime::currentMSecsSinceEpoch() / 1000);
#endif
settings->v_result.push_back(settings->v_result[i1]);
settings->v_exact.push_back(settings->v_exact[i1]);
settings->v_value.push_back(settings->v_value[i1]);
@ -933,6 +945,7 @@ void HistoryView::editMoveToTop() {
settings->v_parse.erase(settings->v_parse.begin() + i1);
settings->v_result.erase(settings->v_result.begin() + i1);
settings->v_protected.erase(settings->v_protected.begin() + i1);
settings->v_time.erase(settings->v_time.begin() + i1);
settings->v_exact.erase(settings->v_exact.begin() + i1);
settings->v_pexact.erase(settings->v_pexact.begin() + i1);
settings->v_value.erase(settings->v_value.begin() + i1);
@ -964,6 +977,7 @@ void HistoryView::editRemove() {
settings->v_parse.erase(settings->v_parse.begin() + i1);
settings->v_result.erase(settings->v_result.begin() + i1);
settings->v_protected.erase(settings->v_protected.begin() + i1);
settings->v_time.erase(settings->v_time.begin() + i1);
settings->v_exact.erase(settings->v_exact.begin() + i1);
settings->v_pexact.erase(settings->v_pexact.begin() + i1);
settings->v_value.erase(settings->v_value.begin() + i1);

View File

@ -1051,7 +1051,7 @@ void KeypadWidget::editCustomAction(KeypadButton *button, int i) {
actionList->setSelectionMode(QAbstractItemView::SingleSelection);
actionList->setRootIsDecorated(false);
actionList->header()->setVisible(true);
actionList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
actionList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
actionList->setSortingEnabled(true);
actionList->sortByColumn(-1, Qt::AscendingOrder);
grid->addWidget(actionList, i != 1 ? 0 : 1, 0, 1, 2);

View File

@ -103,6 +103,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) : QDialog(parent) {
#endif
BOX(tr("Allow multiple instances"), settings->allow_multiple_instances > 0, multipleInstancesToggled(bool));
BOX(tr("Clear history on exit"), settings->clear_history_on_exit, clearHistoryToggled(bool));
l->addWidget(new QLabel(tr("Max history lines saved:"), this), r, 0); QSpinBox *spin = new QSpinBox(this); spin->setRange(0, 100000); spin->setValue(settings->max_history_lines); connect(spin, SIGNAL(valueChanged(int)), this, SLOT(maxHistoryLinesChanged(int))); l->addWidget(spin, r, 1); r++;
BOX(tr("Close application with Escape key"), settings->close_with_esc, closeWithEscToggled(bool));
BOX(tr("Use keyboard keys for RPN"), settings->rpn_keys, rpnKeysToggled(bool));
BOX(tr("Use caret for bitwise XOR"), settings->caret_as_xor, caretAsXorToggled(bool));
@ -185,7 +186,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) : QDialog(parent) {
statusDelayWidget->setEnabled(settings->display_expression_status);
connect(statusDelayWidget, SIGNAL(valueChanged(int)), this, SLOT(statusDelayChanged(int)));
l->addWidget(statusDelayWidget, r, 1); r++;
l->addWidget(new QLabel(tr("Calculate-as-you-type delay:")), r, 0);
l->addWidget(new QLabel(tr("Calculate as you type delay:")), r, 0);
calculateDelayWidget = new QSpinBox(this);
calculateDelayWidget->setRange(0, 10000);
calculateDelayWidget->setSingleStep(250);
@ -373,7 +374,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) : QDialog(parent) {
connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(temperatureCalculationChanged(int)));
box = new QCheckBox(tr("Exchange rates updates:"), this); box->setChecked(settings->auto_update_exchange_rates > 0); connect(box, SIGNAL(toggled(bool)), this, SLOT(exratesToggled(bool))); l->addWidget(box, r, 0);
int days = settings->auto_update_exchange_rates <= 0 ? 7 : settings->auto_update_exchange_rates;
QSpinBox *spin = new QSpinBox(this); spin->setRange(1, 100); spin->setValue(days); spin->setEnabled(settings->auto_update_exchange_rates > 0); connect(spin, SIGNAL(valueChanged(int)), this, SLOT(exratesChanged(int))); l->addWidget(spin, r, 1); exratesSpin = spin; r++;
spin = new QSpinBox(this); spin->setRange(1, 100); spin->setValue(days); spin->setEnabled(settings->auto_update_exchange_rates > 0); connect(spin, SIGNAL(valueChanged(int)), this, SLOT(exratesChanged(int))); l->addWidget(spin, r, 1); exratesSpin = spin; r++;
QString str = tr("%n day(s)", "", days);
int index = str.indexOf(QString::number(days));
if(index == 0) {
@ -428,6 +429,9 @@ void PreferencesDialog::multipleInstancesToggled(bool b) {
void PreferencesDialog::clearHistoryToggled(bool b) {
settings->clear_history_on_exit = b;
}
void PreferencesDialog::maxHistoryLinesChanged(int i) {
settings->max_history_lines = i;
}
void PreferencesDialog::preserveHeightChanged(int state) {
preserveHeightBox->setTristate(false);
settings->preserve_history_height = (state == Qt::Checked);

View File

@ -102,6 +102,7 @@ class PreferencesDialog : public QDialog {
void autocopyResultToggled(bool);
void multipleInstancesToggled(bool);
void clearHistoryToggled(bool);
void maxHistoryLinesChanged(int);
void historyExpressionChanged(int);
void copyAsciiToggled(bool);
void copyAsciiWithoutUnitsToggled(bool);

View File

@ -156,6 +156,7 @@ int AnswerFunction::calculate(MathStructure &mstruct, const MathStructure &vargs
QalculateQtSettings::QalculateQtSettings() {
ignore_locale = false;
fetch_exchange_rates_at_startup = false;
current_history_time = 0;
allow_multiple_instances = -1;
std::string filename = buildPath(getLocalDir(), "qalculate-qt.cfg");
FILE *file = fopen(filename.c_str(), "r");
@ -210,11 +211,14 @@ void QalculateQtSettings::readPreferenceValue(const std::string &svar, const std
v_value.push_back(std::vector<size_t>());
v_messages.push_back("");
v_parseerror.push_back(false);
v_time.push_back(current_history_time);
} else if(svar == "history_parse") {
if(v_expression.size() > v_parse.size()) {
v_parse.push_back(svalue);
v_pexact.push_back(true);
}
} else if(svar == "history_time") {
current_history_time = (time_t) strtoll(svalue.c_str(), NULL, 10);
} else if(svar == "history_parse_approximate") {
if(v_expression.size() > v_parse.size()) {
v_parse.push_back(svalue);
@ -587,6 +591,8 @@ void QalculateQtSettings::readPreferenceValue(const std::string &svar, const std
save_defs_on_exit = v;
} else if(svar == "clear_history_on_exit") {
clear_history_on_exit = v;
} else if(svar == "max_history_lines") {
max_history_lines = v;
} else if(svar == "window_state") {
window_state = QByteArray::fromBase64(svalue.c_str());
} else if(svar == "preserve_history_height") {
@ -975,6 +981,7 @@ void QalculateQtSettings::loadPreferences() {
save_mode_on_exit = true;
save_defs_on_exit = true;
clear_history_on_exit = false;
max_history_lines = 300;
history_expression_type = 0;
keep_function_dialog_open = false;
#ifdef _WIN32
@ -990,6 +997,8 @@ void QalculateQtSettings::loadPreferences() {
v_parse.clear();
v_value.clear();
v_protected.clear();
current_history_time = 0;
v_time.clear();
v_result.clear();
v_exact.clear();
v_pexact.clear();
@ -1392,6 +1401,7 @@ bool QalculateQtSettings::savePreferences(const char *filename, bool is_workspac
fprintf(file, "save_mode_on_exit=%i\n", save_mode_on_exit);
fprintf(file, "save_definitions_on_exit=%i\n", save_defs_on_exit);
fprintf(file, "clear_history_on_exit=%i\n", clear_history_on_exit);
if(max_history_lines != 300) fprintf(file, "max_history_lines=%i\n", max_history_lines);
fprintf(file, "enable_input_method=%i\n", enable_input_method);
fprintf(file, "enable_tooltips=%i\n", enable_tooltips);
fprintf(file, "display_expression_status=%i\n", display_expression_status);
@ -1638,12 +1648,17 @@ bool QalculateQtSettings::savePreferences(const char *filename, bool is_workspac
}
n++;
}
if(n >= 300 || i == 0) break;
if(n >= max_history_lines || i == 0) break;
i--;
}
size_t i_first = i;
long long int history_time_prev = 0;
for(i = 0; i < v_expression.size(); i++) {
if(i >= i_first || v_protected[i]) {
if(v_time[i] != history_time_prev) {
history_time_prev = v_time[i];
fprintf(file, "history_time=%lli\n", (long long int) history_time_prev);
}
if(v_expression[i].empty()) {
if(v_protected[i]) fprintf(file, "history_expression*=%s\n", v_parse[i].c_str());
else fprintf(file, "history_expression=%s\n", v_parse[i].c_str());
@ -2217,6 +2232,8 @@ bool QalculateQtSettings::loadWorkspace(const char *filename) {
v_parse.clear();
v_value.clear();
v_protected.clear();
v_time.clear();
current_history_time = 0;
v_messages.clear();
v_parseerror.clear();
v_result.clear();

View File

@ -258,6 +258,7 @@ class QalculateQtSettings : QObject {
bool hide_numpad;
bool keep_function_dialog_open;
bool save_defs_on_exit, save_mode_on_exit, clear_history_on_exit;
int max_history_lines;
bool rpn_shown;
bool auto_calculate, status_in_history;
int history_expression_type;
@ -302,6 +303,7 @@ class QalculateQtSettings : QObject {
std::vector<std::string> v_parse;
std::vector<bool> v_pexact;
std::vector<bool> v_protected;
std::vector<long long int> v_time;
std::vector<std::vector<std::string> > v_result;
std::vector<std::vector<int> > v_exact;
std::vector<std::vector<size_t> > v_value;
@ -320,6 +322,7 @@ class QalculateQtSettings : QObject {
std::vector<custom_button> custom_buttons;
bool favourite_functions_changed, favourite_variables_changed, favourite_units_changed;
bool show_all_functions, show_all_variables, show_all_units, use_function_dialog;
long long int current_history_time;
};

View File

@ -1226,6 +1226,7 @@ void QalculateWindow::keyboardShortcutAdded(keyboard_shortcut *ks) {
ks->new_action = false;
QList<QKeySequence> shortcuts = action->shortcuts();
shortcuts << QKeySequence::fromString(ks->key);
addAction(action);
action->setShortcuts(shortcuts);
if(ks->type[0] == SHORTCUT_TYPE_PLOT) {
if(plotAction_t) plotAction_t->setToolTip(tr("Plot Functions/Data") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
@ -7813,7 +7814,15 @@ void QalculateWindow::onEMHTimeout() {
expressionEdit->updateMinimumHeight();
historyView->updateMinimumHeight();
}
void QalculateWindow::onResizeTimeout() {
if(DOCK_VISIBLE_IN_WINDOW(basesDock)) basesDock->setMaximumHeight(QWIDGETSIZE_MAX);
if(DOCK_VISIBLE_IN_WINDOW(keypadDock)) keypadDock->setMaximumHeight(QWIDGETSIZE_MAX);
setMinimumWidth(0);
setMaximumWidth(QWIDGETSIZE_MAX);
centralWidget()->setMaximumHeight(QWIDGETSIZE_MAX);
centralWidget()->setMinimumHeight(0);
}
// minimum width when dock is shown
void QalculateWindow::keypadTypeActivated() {
int v = qobject_cast<QAction*>(sender())->data().toInt();
beforeShowDock(keypadDock, v >= 0 || !keypadDock->isVisible());
@ -7821,18 +7830,20 @@ void QalculateWindow::keypadTypeActivated() {
bool b = !keypadDock->isVisible();
bool b_resize = (settings->preserve_history_height > 0 || (settings->preserve_history_height < 0 && settings->keypad_appended)) && !b && !init_in_progress && DOCK_IN_WINDOW(keypadDock);
if(b_resize) {
centralWidget()->setMaximumHeight(centralWidget()->height());
centralWidget()->setFixedHeight(centralWidget()->height());
if(DOCK_VISIBLE_IN_WINDOW(basesDock)) basesDock->setMaximumHeight(basesDock->height());
}
keypadDock->setVisible(b);
if(b) keypadDock->raise();
if(b_resize) {
setFixedWidth(width());
adjustSize();
if(!resizeTimer) {
resizeTimer = new QTimer();
resizeTimer->setSingleShot(true);
connect(resizeTimer, SIGNAL(timeout()), this, SLOT(onResizeTimeout()));
}
resizeTimer->start(10);
resizeTimer->start(100);
}
settings->show_keypad = b ? 1 : 0;
} else {
@ -7848,16 +7859,6 @@ void QalculateWindow::keypadTypeActivated() {
resetKeypadPositionAction->setEnabled(keypadDock->isVisible() && (keypadDock->isFloating() || dockWidgetArea(keypadDock) != Qt::BottomDockWidgetArea));
workspace_changed = true;
}
void QalculateWindow::onResizeTimeout() {
setMinimumWidth(width());
setMaximumWidth(width());
adjustSize();
if(DOCK_VISIBLE_IN_WINDOW(basesDock)) basesDock->setMaximumHeight(QWIDGETSIZE_MAX);
if(DOCK_VISIBLE_IN_WINDOW(keypadDock)) keypadDock->setMaximumHeight(QWIDGETSIZE_MAX);
setMinimumWidth(0);
setMaximumWidth(QWIDGETSIZE_MAX);
centralWidget()->setMaximumHeight(QWIDGETSIZE_MAX);
}
void QalculateWindow::onKeypadVisibilityChanged(bool b) {
beforeShowDockCleanUp(keypadDock);
QAction *action = find_child_data(this, "group_keypad", b ? settings->keypad_type : -1);
@ -7869,14 +7870,16 @@ void QalculateWindow::onKeypadVisibilityChanged(bool b) {
onBaseClicked(BASE_DECIMAL, true, false);
}
if((settings->preserve_history_height > 0 || (settings->preserve_history_height < 0 && settings->keypad_appended)) && !b && !init_in_progress && DOCK_IN_WINDOW(keypadDock)) {
centralWidget()->setMaximumHeight(centralWidget()->height());
centralWidget()->setFixedHeight(centralWidget()->height());
if(DOCK_VISIBLE_IN_WINDOW(basesDock)) basesDock->setMaximumHeight(basesDock->height());
setFixedWidth(width());
adjustSize();
if(!resizeTimer) {
resizeTimer = new QTimer();
resizeTimer->setSingleShot(true);
connect(resizeTimer, SIGNAL(timeout()), this, SLOT(onResizeTimeout()));
}
resizeTimer->start(10);
resizeTimer->start(100);
}
}
void QalculateWindow::onToolbarVisibilityChanged(bool b) {
@ -7889,18 +7892,20 @@ void QalculateWindow::onBasesActivated(bool b) {
beforeShowDock(basesDock, b);
bool b_resize = (settings->preserve_history_height > 0 || (settings->preserve_history_height < 0 && settings->bases_appended)) && !b && !init_in_progress && DOCK_IN_WINDOW(basesDock);
if(b_resize) {
centralWidget()->setMaximumHeight(centralWidget()->height());
centralWidget()->setFixedHeight(centralWidget()->height());
if(DOCK_VISIBLE_IN_WINDOW(keypadDock)) keypadDock->setMaximumHeight(keypadDock->height());
}
basesDock->setVisible(b);
if(b) basesDock->raise();
if(b_resize) {
setFixedWidth(width());
adjustSize();
if(!resizeTimer) {
resizeTimer = new QTimer();
resizeTimer->setSingleShot(true);
connect(resizeTimer, SIGNAL(timeout()), this, SLOT(onResizeTimeout()));
}
resizeTimer->start(10);
resizeTimer->start(100);
}
afterShowDock(basesDock);
}
@ -7908,14 +7913,16 @@ void QalculateWindow::onBasesVisibilityChanged(bool b) {
beforeShowDockCleanUp(basesDock);
basesAction->setChecked(b);
if((settings->preserve_history_height > 0 || (settings->preserve_history_height < 0 && settings->bases_appended)) && !b && !init_in_progress && DOCK_IN_WINDOW(basesDock)) {
centralWidget()->setMaximumHeight(centralWidget()->height());
centralWidget()->setFixedHeight(centralWidget()->height());
if(DOCK_VISIBLE_IN_WINDOW(keypadDock)) keypadDock->setMaximumHeight(keypadDock->height());
setFixedWidth(width());
adjustSize();
if(!resizeTimer) {
resizeTimer = new QTimer();
resizeTimer->setSingleShot(true);
connect(resizeTimer, SIGNAL(timeout()), this, SLOT(onResizeTimeout()));
}
resizeTimer->start(10);
resizeTimer->start(100);
}
if(b && expressionEdit->expressionHasChanged()) onExpressionChanged();
else if(b && !settings->history_answer.empty()) updateResultBases();
@ -8418,7 +8425,7 @@ bool QalculateWindow::editKeyboardShortcut(keyboard_shortcut *new_ks, keyboard_s
shortcutActionList->setSelectionMode(QAbstractItemView::SingleSelection);
shortcutActionList->setRootIsDecorated(false);
shortcutActionList->header()->setVisible(true);
shortcutActionList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
shortcutActionList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
shortcutActionList->setSortingEnabled(true);
shortcutActionList->sortByColumn(-1, Qt::AscendingOrder);
grid->addWidget(shortcutActionList, 0, 0, 1, 2);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1104,6 +1104,14 @@ Do you want to overwrite the function?</source>
<source>decimal fraction</source>
<translation>десятичная дробь</translation>
</message>
<message>
<source>In history list</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>In expression field</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FPConversionDialog</name>
@ -1720,7 +1728,7 @@ Do you want to overwrite the function?</source>
</message>
<message>
<source>Action:</source>
<translation>Действие:</translation>
<translation type="vanished">Действие:</translation>
</message>
<message>
<source>None</source>
@ -1908,6 +1916,10 @@ Do you want to overwrite the function?</source>
<translatorcomment>Стандартная кнопка калькулятора. Не используйте более трёх символов.</translatorcomment>
<translation>СХР</translation>
</message>
<message>
<source>Action</source>
<translation type="unfinished">Действие</translation>
</message>
</context>
<context>
<name>NamesEditDialog</name>
@ -2410,11 +2422,11 @@ Do you want to overwrite the function?</source>
</message>
<message>
<source>Display expression status</source>
<translation>Показывать статус выражения</translation>
<translation type="vanished">Показывать статус выражения</translation>
</message>
<message>
<source>Delay:</source>
<translation>Задержка:</translation>
<translation type="vanished">Задержка:</translation>
</message>
<message>
<source>Expression after calculation:</source>
@ -2873,6 +2885,42 @@ Do you want to overwrite the function?</source>
<source>Automatic</source>
<translation type="unfinished">Автоматическое</translation>
</message>
<message>
<source>Max history lines saved:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Preserve history height</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do not change the height of history list when keypad or number bases are show or hidden.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Expression status:</source>
<translation type="unfinished">Статус выражения:</translation>
</message>
<message>
<source>Off</source>
<translation type="unfinished">Выкл</translation>
</message>
<message>
<source>In history list</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>In expression field</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Status tooltip delay:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Calculate as you type delay:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QApplication</name>
@ -4191,7 +4239,7 @@ Please select interpretation of expressions with implicit multiplication
</message>
<message>
<source>Action:</source>
<translation>Действие:</translation>
<translation type="vanished">Действие:</translation>
</message>
<message>
<source>Value:</source>
@ -4496,6 +4544,18 @@ Do you wish to replace the current action (%1)?</source>
<source>Add percentage multiplied by 1/100</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show toolbar</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Action</source>
<translation type="unfinished">Действие</translation>
</message>
<message>
<source>Key combination</source>
<translation type="unfinished">Комбинация клавиш</translation>
</message>
</context>
<context>
<name>UnitEditDialog</name>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff