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:
parent
65c53c0739
commit
944f0ffe40
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user