Add as multiple functions if plot expression results in matrix (e.g. root(x, [3,4,5])); Fix plot expression with localized decimal separator; Update category list when new category has been introduced by new/edited object; Move favorites and user objects to top of category list; Preserve selection after update of variable, units, and functions dialogs; Clear search entry when category selection reset; Do not generally set keyboard shortcuts as application wide (fixes search shortcut in dialogs); Fix unlocalization of expressions after editing of object; Fix set current result as value if value text has not changed in variable edit dialog; Disable (temporarily) conversion button after switching to RPN mode; Avoid line breaks in result index; Update qalculate-qt.appdata.xml; Update translations

This commit is contained in:
Hanna K 2021-12-01 14:10:34 +01:00
parent 65c53c0739
commit 944f0ffe40
20 changed files with 5101 additions and 4901 deletions

View File

@ -68,7 +68,7 @@
</provides>
<translation type="qt">qalculate-qt</translation>
<releases>
<release version="3.22.0" date="2021-11-29">
<release version="3.22.0" date="2021-12-01">
<description>
<p>Changes:</p>
<ul>
@ -82,13 +82,12 @@
<li>Ctrl+Enter shortcut for approximation of current result</li>
<li>New functions: linearfit(), quadraticfit(), cubicfit(), ramlatency(), parallel()</li>
<li>Improved and extended parallel operator (|| is interpreted as parallel if units are used)</li>
<li>Merged inv() and inverse() functions</li>
<li>Allow nested subfunctions</li>
<li>Solve x^(x^(-a))=b</li>
<li>Improved simplification: Im(-x)=-Im(x), Re(-x)=-Re(x)</li>
<li>Fix pearson() and spearman()</li>
<li>Fix a*sin(x)+b*cos(x)=c</li>
<li>Fix display of incompletely solved equation with dual approximation in some cases</li>
<li>Fix genvector() when step size requires evaluation</li>
<li>Fix a%%-b (interpret %% as mod, not percent)</li>
<li>Many minor feature enhancements and bug fixes</li>
</ul>
</description>

View File

@ -64,7 +64,7 @@ TRANSLATIONS = translations/qalculate-qt_ca.ts \
translations/qalculate-qt_sv.ts \
translations/qalculate-qt_zh_CN.ts
!win32: {
!win32:!macx {
TRANSLATIONS = $$prependAll(LANGUAGES, $$PWD/translations/qalculate-qt_, .ts)
TRANSLATIONS_FILES =
qtPrepareTool(LRELEASE, lrelease) for(tsfile, TRANSLATIONS) {

View File

@ -100,13 +100,11 @@ FunctionsDialog::FunctionsDialog(QWidget *parent) : QDialog(parent, Qt::Window)
selected_category = "All";
updateFunctions();
functionsView->setFocus();
functionsModel->setFilter("All");
connect(searchEdit, SIGNAL(textChanged(const QString&)), this, SLOT(searchChanged(const QString&)));
connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject()));
connect(categoriesView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(selectedCategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(functionsView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(selectedFunctionChanged(const QModelIndex&, const QModelIndex&)));
connect(functionsView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(calculateClicked()));
selectedFunctionChanged(QModelIndex(), QModelIndex());
if(!settings->functions_geometry.isEmpty()) restoreGeometry(settings->functions_geometry);
else resize(900, 800);
if(!settings->functions_vsplitter_state.isEmpty()) vsplitter->restoreState(settings->functions_vsplitter_state);
@ -181,16 +179,24 @@ void FunctionsDialog::newClicked() {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Inactive", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Inactive"); l << "Inactive"; new QTreeWidgetItem(categoriesView, l);}
}
selected_item = f;
if(f->category().empty()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Uncategorized", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Uncategorized"); l << "Uncategorized"; new QTreeWidgetItem(categoriesView->topLevelItem(2), l);}
} else if(f->category() != CALCULATOR->temporaryCategory()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems(QString("/") + QString::fromStdString(f->category()), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {
if(selected_category != "All") selected_category = "User items";
updateFunctions();
emit itemsChanged();
return;
}
}
selected_item = f;
QStandardItem *item = new QStandardItem(QString::fromStdString(f->title(true, settings->printops.use_unicode_signs, &can_display_unicode_string_function, (void*) functionsView)));
item->setEditable(false);
item->setData(QVariant::fromValue((void*) f), Qt::UserRole);
sourceModel->appendRow(item);
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + f->category()) {
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + f->category() && (selected_category != "Uncategorized" || !f->category().empty())) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(!list.isEmpty()) {
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
@ -222,16 +228,24 @@ void FunctionsDialog::editClicked() {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Inactive", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Inactive"); l << "Inactive"; new QTreeWidgetItem(categoriesView, l);}
}
selected_item = f;
if(f->category().empty()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Uncategorized", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Uncategorized"); l << "Uncategorized"; new QTreeWidgetItem(categoriesView->topLevelItem(2), l);}
} else if(f->category() != CALCULATOR->temporaryCategory()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems(QString("/") + QString::fromStdString(f->category()), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {
if(selected_category != "All") selected_category = "User items";
updateFunctions();
emit itemsChanged();
return;
}
}
QStandardItem *item = new QStandardItem(QString::fromStdString(f->title(true, settings->printops.use_unicode_signs, &can_display_unicode_string_function, (void*) functionsView)));
item->setEditable(false);
item->setData(QVariant::fromValue((void*) f), Qt::UserRole);
sourceModel->appendRow(item);
selected_item = f;
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + f->category()) {
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + f->category() && (selected_category != "Uncategorized" || !f->category().empty())) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(!list.isEmpty()) {
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
@ -549,7 +563,9 @@ void FunctionsDialog::updateFunctions() {
function_cats.parent = NULL;
bool has_inactive = false, has_uncat = false;
std::list<tree_struct>::iterator it;
QStandardItem *item_sel = NULL;
functionsView->selectionModel()->blockSignals(true);
sourceModel->clear();
sourceModel->setColumnCount(1);
sourceModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Function")));
@ -601,12 +617,15 @@ void FunctionsDialog::updateFunctions() {
item->setEditable(false);
item->setData(QVariant::fromValue((void*) f), Qt::UserRole);
sourceModel->appendRow(item);
if(f == selected_item) functionsView->selectionModel()->setCurrentIndex(functionsModel->mapFromSource(item->index()), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
if(f == selected_item) item_sel = item;
}
functionsView->selectionModel()->blockSignals(false);
sourceModel->sort(0);
function_cats.sort();
categoriesView->blockSignals(true);
categoriesView->clear();
categoriesView->blockSignals(false);
QTreeWidgetItem *iter, *iter2, *iter3;
QStringList l;
l.clear(); l << tr("Favorites"); l << "Favorites";
@ -676,12 +695,24 @@ void FunctionsDialog::updateFunctions() {
iter->setSelected(true);
}
}
iter3->setExpanded(true);
if(categoriesView->selectedItems().isEmpty()) {
//if no category has been selected (previously selected has been renamed/deleted), select "All"
selected_category = "All";
iter3->setExpanded(true);
iter3->setSelected(true);
}
searchEdit->blockSignals(true);
searchEdit->clear();
searchEdit->blockSignals(false);
functionsModel->setFilter(selected_category);
QModelIndex index;
if(item_sel) index = functionsModel->mapFromSource(item_sel->index());
if(!index.isValid()) index = functionsModel->index(0, 0);
if(index.isValid()) {
functionsView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
functionsView->scrollTo(index);
}
selectedFunctionChanged(index, QModelIndex());
}
void FunctionsDialog::setSearch(const QString &str) {
searchEdit->setText(str);

View File

@ -286,8 +286,9 @@ void HistoryView::addResult(std::vector<std::string> values, std::string express
size_t i_answer = -1;
if(!initial_load) i_answer = dual_approx && i == 0 ? settings->history_answer.size() - 1 : settings->history_answer.size();
QFontMetrics fm(font());
int w = fm.boundingRect("#9999" + unhtmlize(QString::fromStdString(values[i]))).width();
str += "<tr><td valign=\"center\">";
int w = fm.boundingRect("#9999").width();
str += "<tr><td valign=\"center\" width=\""; str += QString::number(w); str += "\">";
w = fm.boundingRect("#9999" + unhtmlize(QString::fromStdString(values[i]))).width();
if(!initial_load && (dual_approx || i == 0)) {
if(expression.empty() && last_ans == i_answer && !last_ref.isEmpty()) s_text.remove(last_ref);
QString sref;

View File

@ -303,10 +303,10 @@ class PlotThread : public Thread {
if(plot_rate < 0) {
MathStructure m_step = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(plot_step, eo.parse_options), eo);
if(!CALCULATOR->aborted()) {
y_vector->set(CALCULATOR->expressionToPlotVector(plot_str, min, max, m_step, x_vector, plot_x, eo.parse_options, 0));
y_vector->set(CALCULATOR->expressionToPlotVector(CALCULATOR->unlocalizeExpression(plot_str, eo.parse_options), min, max, m_step, x_vector, plot_x, eo.parse_options, 0));
}
} else if(!CALCULATOR->aborted()) {
y_vector->set(CALCULATOR->expressionToPlotVector(plot_str, min, max, plot_rate, x_vector, plot_x, eo.parse_options, 0));
y_vector->set(CALCULATOR->expressionToPlotVector(CALCULATOR->unlocalizeExpression(plot_str, eo.parse_options), min, max, plot_rate, x_vector, plot_x, eo.parse_options, 0));
}
}
CALCULATOR->stopControl();
@ -532,17 +532,59 @@ void PlotDialog::updateItem(QTreeWidgetItem *item) {
}
MathStructure *x_vector, *y_vector;
generatePlotSeries(&x_vector, &y_vector, type, expression, str_x);
item->setData(0, TYPE_ROLE, type);
item->setData(0, YAXIS2_ROLE, secondaryButton->isChecked());
item->setData(0, ROWS_ROLE, rowsBox->isChecked());
item->setData(0, SMOOTHING_ROLE, smoothingCombo->currentData());
item->setData(0, STYLE_ROLE, styleCombo->currentData());
item->setData(0, YVECTOR_ROLE, QVariant::fromValue((void*) y_vector));
item->setData(0, XVECTOR_ROLE, QVariant::fromValue((void*) x_vector));
item->setData(0, X_ROLE, str_x);
item->setText(0, title);
item->setText(1, expression);
item->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter);
bool b_multiple = (type != 1 && type != 2 && y_vector->isMatrix() && expression != item->text(1));
MathStructure mfunc;
if(b_multiple) {
EvaluationOptions eo;
eo.approximation = APPROXIMATION_APPROXIMATE;
eo.parse_options = settings->evalops.parse_options;
eo.parse_options.base = 10;
eo.parse_options.read_precision = DONT_READ_PRECISION;
eo.interval_calculation = INTERVAL_CALCULATION_NONE;
mfunc = CALCULATOR->parse(expression.toStdString(), eo.parse_options);
if(!mfunc.isVector()) {
CALCULATOR->beginTemporaryStopIntervalArithmetic();
CALCULATOR->beginTemporaryStopMessages();
mfunc.eval(eo);
CALCULATOR->endTemporaryStopMessages();
CALCULATOR->endTemporaryStopIntervalArithmetic();
if(!mfunc.isVector() || mfunc.size() != y_vector->columns()) b_multiple = false;
}
}
PrintOptions po = settings->printops;
po.can_display_unicode_string_arg = (void*) expressionEdit;
po.base = 10;
po.is_approximate = NULL;
po.allow_non_usable = false;
for(size_t i = 0; ; i++) {
if(b_multiple) {
MathStructure *m = new MathStructure();
y_vector->columnToVector(i + 1, *m);
item->setData(0, YVECTOR_ROLE, QVariant::fromValue((void*) m));
item->setData(0, XVECTOR_ROLE, QVariant::fromValue((void*) new MathStructure(*x_vector)));
QString str = QString::fromStdString(mfunc[i].print(po));
item->setText(1, str);
if(i == 0) expressionEdit->setText(str);
} else {
item->setData(0, YVECTOR_ROLE, QVariant::fromValue((void*) y_vector));
item->setData(0, XVECTOR_ROLE, QVariant::fromValue((void*) x_vector));
item->setText(1, expression);
}
item->setData(0, TYPE_ROLE, type);
item->setData(0, YAXIS2_ROLE, secondaryButton->isChecked());
item->setData(0, ROWS_ROLE, rowsBox->isChecked());
item->setData(0, SMOOTHING_ROLE, smoothingCombo->currentData());
item->setData(0, STYLE_ROLE, styleCombo->currentData());
item->setData(0, X_ROLE, str_x);
item->setText(0, title);
item->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter);
if(!b_multiple || i + 1 >= y_vector->columns()) break;
item = new QTreeWidgetItem(graphsTable);
}
if(b_multiple) {
delete y_vector;
delete x_vector;
}
}
void PlotDialog::onApplyClicked() {
QList<QTreeWidgetItem *> list = graphsTable->selectedItems();

View File

@ -1111,13 +1111,14 @@ std::string QalculateQtSettings::localizeExpression(std::string str, bool unit_e
std::string QalculateQtSettings::unlocalizeExpression(std::string str) {
ParseOptions pa = evalops.parse_options; pa.base = 10;
str = CALCULATOR->localizeExpression(str, pa);
str = CALCULATOR->unlocalizeExpression(str, pa);
CALCULATOR->parseSigns(str);
return str;
}
void QalculateQtSettings::updateMessagePrintOptions() {
PrintOptions message_printoptions = printops;
message_printoptions.is_approximate = NULL;
message_printoptions.interval_display = INTERVAL_DISPLAY_PLUSMINUS;
message_printoptions.show_ending_zeroes = false;
message_printoptions.base = 10;

View File

@ -303,12 +303,12 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
if(settings->use_custom_app_font) appfont.fromString(QString::fromStdString(settings->custom_app_font));
action = new QAction("Negate", this);
action->setShortcut(Qt::CTRL | Qt::Key_Minus); action->setShortcutContext(Qt::ApplicationShortcut);
action->setShortcut(Qt::CTRL | Qt::Key_Minus);
addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(negate()));
action = new QAction("Approximate", this);
action->setShortcuts({Qt::CTRL | Qt::Key_Return, Qt::CTRL | Qt::Key_Enter}); action->setShortcutContext(Qt::ApplicationShortcut);
action->setShortcuts({Qt::CTRL | Qt::Key_Return, Qt::CTRL | Qt::Key_Enter});
addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(approximateResult()));
@ -329,13 +329,12 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
menu->addAction(tr("Import CSV File…"), this, SLOT(importCSV()));
menu->addAction(tr("Export CSV File…"), this, SLOT(exportCSV()));
menu->addSeparator();
menu->addAction(tr("Functions"), this, SLOT(openFunctions()), Qt::CTRL | Qt::Key_F)->setShortcutContext(Qt::ApplicationShortcut);
menu->addAction(tr("Functions"), this, SLOT(openFunctions()), Qt::CTRL | Qt::Key_F);
variablesAction = menu->addAction(tr("Variables and Constants"), this, SLOT(openVariables()), Qt::CTRL | Qt::Key_M);
variablesAction->setShortcutContext(Qt::ApplicationShortcut);
menu->addAction(tr("Units"), this, SLOT(openUnits()), Qt::CTRL | Qt::Key_U)->setShortcutContext(Qt::ApplicationShortcut);
menu->addAction(tr("Units"), this, SLOT(openUnits()), Qt::CTRL | Qt::Key_U);
menu->addAction(tr("Data Sets"), this, SLOT(openDatasets()));
menu->addSeparator();
menu->addAction(tr("Plot Functions/Data"), this, SLOT(openPlot()), Qt::CTRL | Qt::Key_P)->setShortcutContext(Qt::ApplicationShortcut);
menu->addAction(tr("Plot Functions/Data"), this, SLOT(openPlot()), Qt::CTRL | Qt::Key_P);
menu->addAction(tr("Floating Point Conversion (IEEE 754)"), this, SLOT(openFPConversion()));
menu->addAction(tr("Calendar Conversion"), this, SLOT(openCalendarConversion()));
menu->addAction(tr("Percentage Calculation Tool"), this, SLOT(openPercentageCalculation()));
@ -345,7 +344,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
menu->addSeparator();
group = new QActionGroup(this);
action = menu->addAction(tr("Normal Mode"), this, SLOT(normalModeActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_normalmode"); if(!settings->rpn_mode && !settings->chain_mode) action->setChecked(true);
action = menu->addAction(tr("RPN Mode"), this, SLOT(rpnModeActivated()), Qt::CTRL | Qt::Key_R); action->setShortcutContext(Qt::ApplicationShortcut); action->setCheckable(true); group->addAction(action); action->setObjectName("action_rpnmode"); if(settings->rpn_mode) action->setChecked(true);
action = menu->addAction(tr("RPN Mode"), this, SLOT(rpnModeActivated()), Qt::CTRL | Qt::Key_R); action->setCheckable(true); group->addAction(action); action->setObjectName("action_rpnmode"); if(settings->rpn_mode) action->setChecked(true);
action = menu->addAction(tr("Chain Mode"), this, SLOT(chainModeActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_chainmode"); if(settings->chain_mode) action->setChecked(true);
menu->addSeparator();
menu->addAction(tr("Preferences"), this, SLOT(editPreferences()));
@ -571,10 +570,10 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
toAction = new QAction(LOAD_ICON("convert"), tr("Convert"), this);
toAction->setEnabled(false);
toAction->setShortcut(Qt::CTRL | Qt::Key_T); toAction->setShortcutContext(Qt::ApplicationShortcut); toAction->setToolTip(tr("Convert (%1)").arg(toAction->shortcut().toString(QKeySequence::NativeText)));
toAction->setShortcut(Qt::CTRL | Qt::Key_T); toAction->setToolTip(tr("Convert (%1)").arg(toAction->shortcut().toString(QKeySequence::NativeText)));
connect(toAction, SIGNAL(triggered(bool)), this, SLOT(onToActivated()));
tb->addAction(toAction);
storeAction = new QAction(LOAD_ICON("document-save"), tr("Store"), this); storeAction->setShortcut(QKeySequence::Save); storeAction->setShortcutContext(Qt::ApplicationShortcut); storeAction->setToolTip(tr("Store (%1)").arg(storeAction->shortcut().toString(QKeySequence::NativeText)));
storeAction = new QAction(LOAD_ICON("document-save"), tr("Store"), this); storeAction->setShortcut(QKeySequence::Save); storeAction->setToolTip(tr("Store (%1)").arg(storeAction->shortcut().toString(QKeySequence::NativeText)));
connect(storeAction, SIGNAL(triggered(bool)), this, SLOT(onStoreActivated()));
variablesMenu = new QMenu(this);
updateVariablesMenu();
@ -609,12 +608,12 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
connect(percentageAction, SIGNAL(triggered(bool)), this, SLOT(openPercentageCalculation()));
tb->addAction(percentageAction);*/
basesAction = new QAction(LOAD_ICON("number-bases"), tr("Number bases"), this);
basesAction->setShortcut(Qt::CTRL | Qt::Key_B); basesAction->setShortcutContext(Qt::ApplicationShortcut); basesAction->setToolTip(tr("Number Bases (%1)").arg(basesAction->shortcut().toString(QKeySequence::NativeText)));
basesAction->setShortcut(Qt::CTRL | Qt::Key_B); basesAction->setToolTip(tr("Number Bases (%1)").arg(basesAction->shortcut().toString(QKeySequence::NativeText)));
connect(basesAction, SIGNAL(triggered(bool)), this, SLOT(onBasesActivated(bool)));
basesAction->setCheckable(true);
tb->addAction(basesAction);
keypadAction = new QAction(LOAD_ICON("keypad"), tr("Keypad"), this);
keypadAction->setShortcut(Qt::CTRL | Qt::Key_K); keypadAction->setShortcutContext(Qt::ApplicationShortcut); keypadAction->setToolTip(tr("Keypad (%1)").arg(keypadAction->shortcut().toString(QKeySequence::NativeText)));
keypadAction->setShortcut(Qt::CTRL | Qt::Key_K); keypadAction->setToolTip(tr("Keypad (%1)").arg(keypadAction->shortcut().toString(QKeySequence::NativeText)));
connect(keypadAction, SIGNAL(triggered(bool)), this, SLOT(onKeypadActivated(bool)));
keypadAction->setCheckable(true);
tb->addAction(keypadAction);
@ -6042,6 +6041,7 @@ void QalculateWindow::onRPNVisibilityChanged(bool b) {
}
QAction *w = findChild<QAction*>("action_rpnmode");
if(w) w->setChecked(true);
toAction->setEnabled(false);
} else {
normalModeActivated();
QAction *w = findChild<QAction*>("action_normalmode");
@ -6060,6 +6060,7 @@ void QalculateWindow::rpnModeActivated() {
if(!settings->rpn_shown) {rpnDock->setFloating(true); settings->rpn_shown = true;}
rpnDock->show();
rpnDock->raise();
toAction->setEnabled(false);
}
}
void QalculateWindow::chainModeActivated() {

View File

@ -127,8 +127,6 @@ UnitsDialog::UnitsDialog(QWidget *parent) : QDialog(parent, Qt::Window) {
selected_category = "All";
updateUnits();
unitsView->setFocus();
unitsModel->setFilter("All");
toModel->setFilter("All");
connect(searchEdit, SIGNAL(textChanged(const QString&)), this, SLOT(searchChanged(const QString&)));
connect(fromEdit, SIGNAL(textEdited(const QString&)), this, SLOT(fromChanged()));
connect(toEdit, SIGNAL(textEdited(const QString&)), this, SLOT(toChanged()));
@ -137,7 +135,6 @@ UnitsDialog::UnitsDialog(QWidget *parent) : QDialog(parent, Qt::Window) {
connect(categoriesView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(selectedCategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(unitsView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(selectedUnitChanged(const QModelIndex&, const QModelIndex&)));
connect(unitsView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onUnitActivated(const QModelIndex&)));
selectedUnitChanged(QModelIndex(), QModelIndex());
if(!settings->units_geometry.isEmpty()) restoreGeometry(settings->units_geometry);
else resize(900, 800);
if(!settings->units_vsplitter_state.isEmpty()) vsplitter->restoreState(settings->units_vsplitter_state);
@ -315,11 +312,19 @@ void UnitsDialog::newClicked() {
if(list.isEmpty()) {QStringList l; l << tr("Inactive"); l << "Inactive"; new QTreeWidgetItem(categoriesView, l);}
}
}
selected_item = u;
if(u->category().empty()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Uncategorized", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Uncategorized"); l << "Uncategorized"; new QTreeWidgetItem(categoriesView->topLevelItem(2), l);}
} else if(u->category() != CALCULATOR->temporaryCategory()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems(QString("/") + QString::fromStdString(u->category()), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {
if(selected_category != "All") selected_category = "User items";
updateUnits();
emit itemsChanged();
return;
}
}
selected_item = u;
QString qstr;
SET_TO_STR
QStandardItem *item = new QStandardItem(qstr);
@ -330,7 +335,7 @@ void UnitsDialog::newClicked() {
item->setEditable(false);
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
sourceModel->appendRow(item);
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + u->category()) {
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + u->category() && (selected_category != "Uncategorized" || !u->category().empty())) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(!list.isEmpty()) {
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
@ -388,9 +393,18 @@ void UnitsDialog::editClicked() {
if(list.isEmpty()) {QStringList l; l << tr("Inactive"); l << "Inactive"; new QTreeWidgetItem(categoriesView, l);}
}
}
selected_item = u;
if(u->category().empty()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Uncategorized", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Uncategorized"); l << "Uncategorized"; new QTreeWidgetItem(categoriesView->topLevelItem(2), l);}
} else if(u->category() != CALCULATOR->temporaryCategory()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems(QString("/") + QString::fromStdString(u->category()), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {
if(selected_category != "All") selected_category = "User items";
updateUnits();
emit itemsChanged();
return;
}
}
QString qstr;
SET_TO_STR
@ -402,8 +416,7 @@ void UnitsDialog::editClicked() {
item->setEditable(false);
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
sourceModel->appendRow(item);
selected_item = u;
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + u->category()) {
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + u->category() && (selected_category != "Uncategorized" || !u->category().empty())) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(!list.isEmpty()) {
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
@ -692,7 +705,9 @@ void UnitsDialog::updateUnits() {
unit_cats.parent = NULL;
bool has_inactive = false, has_uncat = false;
std::list<tree_struct>::iterator it;
QStandardItem *item_sel = NULL;
unitsView->selectionModel()->blockSignals(true);
sourceModel->clear();
sourceModel->setColumnCount(1);
sourceModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Unit")));
@ -747,19 +762,22 @@ void UnitsDialog::updateUnits() {
item->setEditable(false);
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
sourceModel->appendRow(item);
if(u == selected_item) unitsView->selectionModel()->setCurrentIndex(unitsModel->mapFromSource(item->index()), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
if(u == selected_item) item_sel = item;
SET_TO_STR
item = new QStandardItem(qstr);
item->setEditable(false);
item->setData(QVariant::fromValue((void*) u), Qt::UserRole);
toSourceModel->appendRow(item);
}
unitsView->selectionModel()->blockSignals(false);
sourceModel->sort(0);
toSourceModel->sort(0);
unit_cats.sort();
categoriesView->blockSignals(true);
categoriesView->clear();
categoriesView->blockSignals(false);
QTreeWidgetItem *iter, *iter2, *iter3;
QStringList l;
l.clear(); l << tr("Favorites"); l << "Favorites";
@ -772,7 +790,7 @@ void UnitsDialog::updateUnits() {
if(selected_category == "User items") {
iter->setSelected(true);
}
l.clear(); l << tr("All", "All functions"); l << "All";
l.clear(); l << tr("All", "All units"); l << "All";
iter3 = new QTreeWidgetItem(categoriesView, l);
tree_struct *item, *item2;
unit_cats.it = unit_cats.items.begin();
@ -829,12 +847,24 @@ void UnitsDialog::updateUnits() {
iter->setSelected(true);
}
}
iter3->setExpanded(true);
if(categoriesView->selectedItems().isEmpty()) {
//if no category has been selected (previously selected has been renamed/deleted), select "All"
selected_category = "All";
iter3->setExpanded(true);
iter3->setSelected(true);
}
searchEdit->blockSignals(true);
searchEdit->clear();
searchEdit->blockSignals(false);
unitsModel->setFilter(selected_category);
QModelIndex index;
if(item_sel) index = unitsModel->mapFromSource(item_sel->index());
if(!index.isValid()) index = unitsModel->index(0, 0);
if(index.isValid()) {
unitsView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
unitsView->scrollTo(index);
}
selectedUnitChanged(index, QModelIndex());
}
void UnitsDialog::setSearch(const QString &str) {
searchEdit->setText(str);
@ -846,4 +876,3 @@ void UnitsDialog::selectCategory(std::string str) {
}
}

View File

@ -307,6 +307,7 @@ void VariableEditDialog::onValueEdited() {
void VariableEditDialog::setValue(const QString &str) {
valueEdit->setPlainText(str);
if(!b_empty) onValueEdited();
b_changed = false;
}
void VariableEditDialog::disableValue() {
valueEdit->setReadOnly(true);

View File

@ -106,13 +106,11 @@ VariablesDialog::VariablesDialog(QWidget *parent) : QDialog(parent, Qt::Window)
selected_category = "All";
updateVariables();
variablesView->setFocus();
variablesModel->setFilter("All");
connect(searchEdit, SIGNAL(textChanged(const QString&)), this, SLOT(searchChanged(const QString&)));
connect(buttonBox->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(reject()));
connect(categoriesView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(selectedCategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(variablesView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(selectedVariableChanged(const QModelIndex&, const QModelIndex&)));
connect(variablesView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(insertClicked()));
selectedVariableChanged(QModelIndex(), QModelIndex());
if(!settings->variables_geometry.isEmpty()) restoreGeometry(settings->variables_geometry);
else resize(900, 700);
if(!settings->variables_vsplitter_state.isEmpty()) vsplitter->restoreState(settings->variables_vsplitter_state);
@ -199,16 +197,24 @@ void VariablesDialog::newVariable(int type) {
if(list.isEmpty()) {QStringList l; l << tr("Inactive"); l << "Inactive"; new QTreeWidgetItem(categoriesView, l);}
}
}
selected_item = v;
if(v->category().empty()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Uncategorized", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Uncategorized"); l << "Uncategorized"; new QTreeWidgetItem(categoriesView->topLevelItem(2), l);}
} else if(v->category() != CALCULATOR->temporaryCategory()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems(QString("/") + QString::fromStdString(v->category()), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {
if(selected_category != "All") selected_category = "User items";
updateVariables();
emit itemsChanged();
return;
}
}
selected_item = v;
QStandardItem *item = new QStandardItem(QString::fromStdString(v->title(true, settings->printops.use_unicode_signs, &can_display_unicode_string_function, (void*) variablesView)));
item->setEditable(false);
item->setData(QVariant::fromValue((void*) v), Qt::UserRole);
sourceModel->appendRow(item);
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + v->category()) {
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + v->category() && (selected_category != "Uncategorized" || !v->category().empty())) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(!list.isEmpty()) {
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
@ -264,16 +270,24 @@ void VariablesDialog::editClicked() {
if(list.isEmpty()) {QStringList l; l << tr("Inactive"); l << "Inactive"; new QTreeWidgetItem(categoriesView, l);}
}
}
selected_item = v;
if(v->category().empty()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("Uncategorized", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {QStringList l; l << tr("Uncategorized"); l << "Uncategorized"; new QTreeWidgetItem(categoriesView->topLevelItem(2), l);}
} else if(v->category() != CALCULATOR->temporaryCategory()) {
QList<QTreeWidgetItem*> list = categoriesView->findItems(QString("/") + QString::fromStdString(v->category()), Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(list.isEmpty()) {
if(selected_category != "All") selected_category = "User items";
updateVariables();
emit itemsChanged();
return;
}
}
QStandardItem *item = new QStandardItem(QString::fromStdString(v->title(true, settings->printops.use_unicode_signs, &can_display_unicode_string_function, (void*) variablesView)));
item->setEditable(false);
item->setData(QVariant::fromValue((void*) v), Qt::UserRole);
sourceModel->appendRow(item);
selected_item = v;
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + v->category()) {
if(selected_category != "All" && selected_category != "User items" && selected_category != std::string("/") + v->category() && (selected_category != "Uncategorized" || !v->category().empty())) {
QList<QTreeWidgetItem*> list = categoriesView->findItems("User items", Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap, 1);
if(!list.isEmpty()) {
categoriesView->setCurrentItem(list[0], 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
@ -501,7 +515,9 @@ void VariablesDialog::updateVariables() {
variable_cats.parent = NULL;
bool has_inactive = false, has_uncat = false;
std::list<tree_struct>::iterator it;
QStandardItem *item_sel = NULL;
variablesView->selectionModel()->blockSignals(true);
sourceModel->clear();
sourceModel->setColumnCount(1);
sourceModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Variable")));
@ -553,12 +569,15 @@ void VariablesDialog::updateVariables() {
item->setEditable(false);
item->setData(QVariant::fromValue((void*) v), Qt::UserRole);
sourceModel->appendRow(item);
if(v == selected_item) variablesView->selectionModel()->setCurrentIndex(variablesModel->mapFromSource(item->index()), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
if(v == selected_item) item_sel = item;
}
variablesView->selectionModel()->blockSignals(false);
sourceModel->sort(0);
variable_cats.sort();
categoriesView->blockSignals(true);
categoriesView->clear();
categoriesView->blockSignals(false);
QTreeWidgetItem *iter, *iter2, *iter3;
QStringList l;
l.clear(); l << tr("Favorites"); l << "Favorites";
@ -571,7 +590,7 @@ void VariablesDialog::updateVariables() {
if(selected_category == "User items") {
iter->setSelected(true);
}
l.clear(); l << tr("All", "All functions"); l << "All";
l.clear(); l << tr("All", "All variables"); l << "All";
iter3 = new QTreeWidgetItem(categoriesView, l);
tree_struct *item, *item2;
variable_cats.it = variable_cats.items.begin();
@ -628,12 +647,24 @@ void VariablesDialog::updateVariables() {
iter->setSelected(true);
}
}
iter3->setExpanded(true);
if(categoriesView->selectedItems().isEmpty()) {
//if no category has been selected (previously selected has been renamed/deleted), select "All"
selected_category = "All";
iter3->setExpanded(true);
iter3->setSelected(true);
}
searchEdit->blockSignals(true);
searchEdit->clear();
searchEdit->blockSignals(false);
variablesModel->setFilter(selected_category);
QModelIndex index;
if(item_sel) index = variablesModel->mapFromSource(item_sel->index());
if(!index.isValid()) index = variablesModel->index(0, 0);
if(index.isValid()) {
variablesView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear);
variablesView->scrollTo(index);
}
selectedVariableChanged(index, QModelIndex());
}
void VariablesDialog::setSearch(const QString &str) {
searchEdit->setText(str);

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

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