Customizable keypad; More work on customizable keyboard shortcuts

This commit is contained in:
Hanna K 2022-01-10 10:48:30 +01:00
parent 7d404aeab4
commit 720161ed3a
12 changed files with 1197 additions and 227 deletions

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="m22.27 4l-18.27 18.27v5.73h5.73c0 0 18.269-18.269 18.27-18.27zm-2.865 4.299l4.297 4.297-11.701 11.703v-2.299h-4v-2.299zm-12.404 12.402v2.299h4v2.299l-1.701 1.701h-2l-2.297-2.297v-2z"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 523 B

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="m22.27 4l-18.27 18.27v5.73h5.73c0 0 18.269-18.269 18.27-18.27zm-2.865 4.299l4.297 4.297-11.701 11.703v-2.299h-4v-2.299zm-12.404 12.402v2.299h4v2.299l-1.701 1.701h-2l-2.297-2.297v-2z"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 523 B

View File

@ -4,8 +4,9 @@
<file alias="actions/scalable/calendars.svg">data/scalable/calendars.svg</file>
<file alias="actions/scalable/configure.svg">data/scalable/configure.svg</file>
<file alias="actions/scalable/convert.svg">data/scalable/convert.svg</file>
<file alias="actions/scalable/document-save.svg">data/scalable/document-save.svg</file>
<file alias="actions/scalable/document-edit.svg">data/scalable/document-edit.svg</file>
<file alias="actions/scalable/document-open.svg">data/scalable/document-open.svg</file>
<file alias="actions/scalable/document-save.svg">data/scalable/document-save.svg</file>
<file alias="actions/scalable/edit-clear.svg">data/scalable/edit-clear.svg</file>
<file alias="actions/scalable/edit-copy.svg">data/scalable/edit-copy.svg</file>
<file alias="actions/scalable/edit-delete.svg">data/scalable/edit-delete.svg</file>
@ -28,6 +29,7 @@
<file alias="dark/actions/scalable/calendars.svg">data/scalable/calendars-dark.svg</file>
<file alias="dark/actions/scalable/configure.svg">data/scalable/configure-dark.svg</file>
<file alias="dark/actions/scalable/convert.svg">data/scalable/convert-dark.svg</file>
<file alias="dark/actions/scalable/document-edit.svg">data/scalable/document-edit-dark.svg</file>
<file alias="dark/actions/scalable/document-open.svg">data/scalable/document-open-dark.svg</file>
<file alias="dark/actions/scalable/document-save.svg">data/scalable/document-save-dark.svg</file>
<file alias="dark/actions/scalable/edit-clear.svg">data/scalable/edit-clear-dark.svg</file>

View File

@ -351,6 +351,7 @@ bool title_matches(ExpressionItem *item, const std::string &str, size_t minlengt
big_A = (str[0] == 'A');
}
const std::string &title = item->title(true);
if(title.empty()) return false;
size_t i = 0;
while(true) {
while(true) {
@ -1363,6 +1364,13 @@ void ExpressionEdit::keyReleaseEvent(QKeyEvent *event) {
if(!event->isAutoRepeat()) disable_history_arrow_keys = false;
QPlainTextEdit::keyReleaseEvent(event);
}
void ExpressionEdit::completeOrActivateFirst() {
if(completionView->isVisible()) {
onCompletionActivated(completionView->currentIndex().isValid() ? completionView->currentIndex() : completionModel->index(0, 0));
} else {
complete();
}
}
void ExpressionEdit::keyPressEvent(QKeyEvent *event) {
if(event->matches(QKeySequence::Undo)) {
editUndo();
@ -1392,8 +1400,8 @@ void ExpressionEdit::keyPressEvent(QKeyEvent *event) {
emit calculateRPNRequest(OPERATION_SUBTRACT);
return;
}
if(doChainMode(SIGN_MINUS)) return;
wrapSelection(SIGN_MINUS);
if(doChainMode(settings->printops.use_unicode_signs ? SIGN_MINUS : "-")) return;
wrapSelection(settings->printops.use_unicode_signs ? SIGN_MINUS : "-");
return;
}
case Qt::Key_Dead_Circumflex: {

View File

@ -145,6 +145,7 @@ class ExpressionEdit : public QPlainTextEdit {
void editDelete();
void insertDate();
void insertMatrix();
void completeOrActivateFirst();
bool complete(MathStructure* = NULL, const QPoint& = QPoint(), bool = false);
signals:

View File

@ -68,7 +68,7 @@ bool ItemProxyModel::filterAcceptsRow(int source_row, const QModelIndex&) const
if(item->type() == TYPE_UNIT) {
return name_matches(item, filter) || title_matches(item, filter) || country_matches((Unit*) item, filter);
}
std::string title = item->title(true);
std::string title = item->title(true, settings->printops.use_unicode_signs);
remove_blank_ends(title);
while(title.length() >= filter.length()) {
if(equalsIgnoreCase(filter, title.substr(0, filter.length()))) {

View File

@ -14,6 +14,8 @@
#include <QPaintEvent>
#include <QLabel>
#include <QTimer>
#include <QLineEdit>
#include <QListWidget>
#include <QTextDocument>
#include <QStackedLayout>
#include <QHBoxLayout>
@ -21,6 +23,8 @@
#include <QAction>
#include <QActionGroup>
#include <QToolButton>
#include <QDialog>
#include <QDialogButtonBox>
#include <QDebug>
#include "keypadwidget.h"
@ -29,6 +33,9 @@
#define BUTTON_DATA "QALCULATE DATA1"
#define BUTTON_DATA2 "QALCULATE DATA2"
#define BUTTON_DATA3 "QALCULATE DATA3"
#define BUTTON_VALUE "QALCULATE VALUE1"
#define BUTTON_VALUE2 "QALCULATE VALUE2"
#define BUTTON_VALUE3 "QALCULATE VALUE3"
#define SYMBOL_BUTTON_BOX(x) button = new KeypadButton(x, this); \
button->setProperty(BUTTON_DATA, x); \
@ -130,7 +137,7 @@
button->setProperty(BUTTON_DATA, QVariant::fromValue((void*) o1)); \
button->setProperty(BUTTON_DATA2, QVariant::fromValue((void*) o2)); \
button->setProperty(BUTTON_DATA3, QVariant::fromValue((void*) o3)); \
button->setToolTip(QString::fromStdString(o1->title(true)), (void*) o1 == (void*) o2 ? QString() : QString::fromStdString(o2->title(true)), (void*) o2 == (void*) o3 ? QString() : QString::fromStdString(o3->title(true))); \
button->setToolTip(QString::fromStdString(o1->title(true, settings->printops.use_unicode_signs)), (void*) o1 == (void*) o2 ? QString() : QString::fromStdString(o2->title(true, settings->printops.use_unicode_signs)), (void*) o2 == (void*) o3 ? QString() : QString::fromStdString(o3->title(true, settings->printops.use_unicode_signs))); \
connect(button, SIGNAL(clicked()), this, SLOT(onItemButtonClicked())); \
connect(button, SIGNAL(clicked2()), this, SLOT(onItemButtonClicked2())); \
connect(button, SIGNAL(clicked3()), this, SLOT(onItemButtonClicked3())); \
@ -140,7 +147,7 @@
button->setProperty(BUTTON_DATA, QVariant::fromValue((void*) o1)); \
button->setProperty(BUTTON_DATA2, o2); \
button->setProperty(BUTTON_DATA3, QVariant::fromValue((void*) o3)); \
button->setToolTip(QString::fromStdString(o1->title(true)), o2, QString::fromStdString(o3->title(true))); \
button->setToolTip(QString::fromStdString(o1->title(true, settings->printops.use_unicode_signs)), o2, QString::fromStdString(o3->title(true, settings->printops.use_unicode_signs))); \
connect(button, SIGNAL(clicked()), this, SLOT(onItemButtonClicked())); \
connect(button, SIGNAL(clicked2()), this, SLOT(onOperatorButtonClicked2())); \
connect(button, SIGNAL(clicked3()), this, SLOT(onItemButtonClicked3())); \
@ -149,7 +156,7 @@
#define SET_ITEM_BUTTON2(button, o1, o2) button->setProperty(BUTTON_DATA, QVariant::fromValue((void*) o1)); \
button->setProperty(BUTTON_DATA2, QVariant::fromValue((void*) o2)); \
button->setProperty(BUTTON_DATA3, QVariant::fromValue((void*) o2)); \
button->setToolTip(QString::fromStdString(o1->title(true)), QString::fromStdString(o2->title(true)));
button->setToolTip(QString::fromStdString(o1->title(true, settings->printops.use_unicode_signs)), QString::fromStdString(o2->title(true, settings->printops.use_unicode_signs)));
#define ITEM_BUTTON(o, x, r, c) ITEM_BUTTON3(o, o, o, x, r, c)
#define ITEM_BUTTON2(o1, o2, x, r, c) ITEM_BUTTON3(o1, o2, o2, x, r, c)
@ -165,10 +172,13 @@
KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
QHBoxLayout *box = new QHBoxLayout(this);
leftStack = new QStackedLayout();
box->addLayout(leftStack, 2);
box->addLayout(leftStack, 4 + (settings->custom_button_columns <= 4 ? 0 : (settings->custom_button_columns - 4) * 1.5));
box->addSpacing(box->spacing());
QGridLayout *grid2 = new QGridLayout();
box->addLayout(grid2, 3);
numpad = new QWidget(this);
if(settings->hide_numpad) numpad->hide();
QGridLayout *grid2 = new QGridLayout(numpad);
grid2->setContentsMargins(0, 0, 0, 0);
box->addWidget(numpad, 6);
QWidget *keypadG = new QWidget(this);
leftStack->addWidget(keypadG);
QGridLayout *grid = new QGridLayout(keypadG);
@ -214,7 +224,7 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
c++;
OPERATOR_ITEM2_BUTTON("^", CALCULATOR->getFunctionById(FUNCTION_ID_SQUARE), CALCULATOR->getFunctionById(FUNCTION_ID_EXP), c, 3);
button->setRichText("x<sup>y</sup>");
button->setToolTip(tr("Exponentiation"), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_SQUARE)->title(true)), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_EXP)->title(true)));
button->setToolTip(tr("Exponentiation"), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_SQUARE)->title(true, settings->printops.use_unicode_signs)), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_EXP)->title(true, settings->printops.use_unicode_signs)));
ITEM_BUTTON3(CALCULATOR->getFunctionById(FUNCTION_ID_SQRT), CALCULATOR->getFunctionById(FUNCTION_ID_CBRT), CALCULATOR->getFunctionById(FUNCTION_ID_ROOT), SIGN_SQRT, c, 2);
f = CALCULATOR->getActiveFunction("log10"); f2 = CALCULATOR->getActiveFunction("log2");
if(f && f2) {
@ -225,7 +235,7 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
f = CALCULATOR->getActiveFunction("perm"); f2 = CALCULATOR->getActiveFunction("comb");
if(f && f2) {
OPERATOR_ITEM2_BUTTON("!", f, f2, c, 0);
button->setToolTip(QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_FACTORIAL)->title(true)), QString::fromStdString(f->title(true)), QString::fromStdString(f2->title(true)));
button->setToolTip(QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_FACTORIAL)->title(true, settings->printops.use_unicode_signs)), QString::fromStdString(f->title(true, settings->printops.use_unicode_signs)), QString::fromStdString(f2->title(true, settings->printops.use_unicode_signs)));
} else {
OPERATOR_BUTTON("!", c, 0);
}
@ -244,7 +254,7 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
button->setRichText("<i>x</i> =");
c++;
SYMBOL_BUTTON2("%", "", c, 1);
button->setToolTip(tr("Percent or remainder"), QString::fromStdString(CALCULATOR->getVariableById(VARIABLE_ID_PERMILLE)->title(true)));
button->setToolTip(tr("Percent or remainder"), QString::fromStdString(CALCULATOR->getVariableById(VARIABLE_ID_PERMILLE)->title(true, settings->printops.use_unicode_signs)));
SYMBOL_ITEM2_BUTTON("±", CALCULATOR->getFunctionById(FUNCTION_ID_UNCERTAINTY), CALCULATOR->getFunctionById(FUNCTION_ID_INTERVAL), c, 0);
button->setToolTip(tr("Uncertainty/interval"), tr("Relative error"), tr("Interval"));
backButton = new KeypadButton(LOAD_ICON("go-back"), this, true);
@ -259,16 +269,8 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
connect(forwardButton, SIGNAL(clicked2()), this, SIGNAL(endClicked()));
connect(forwardButton, SIGNAL(clicked3()), this, SIGNAL(endClicked()));
grid->addWidget(forwardButton, c, 3, 1, 1);
grid->setRowStretch(0, 1);
grid->setRowStretch(1, 1);
grid->setRowStretch(2, 1);
grid->setRowStretch(3, 1);
grid->setRowStretch(4, 1);
grid->setRowStretch(0, 1);
grid->setColumnStretch(0, 1);
grid->setColumnStretch(1, 1);
grid->setColumnStretch(2, 1);
grid->setColumnStretch(3, 1);
for(c = 0; c < 4; c++) grid->setColumnStretch(c, 1);
for(int r = 0; r < 5; r++) grid->setRowStretch(r, 1);
QWidget *keypadP = new QWidget(this);
leftStack->addWidget(keypadP);
@ -307,11 +309,11 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
ITEM_BUTTON(CALCULATOR->getFunctionById(FUNCTION_ID_CIRCULAR_SHIFT), tr("rot"), 3, 3);
OPERATOR_BUTTON2(" mod ", " rem ", 4, 0);
button->setText("mod");
button->setToolTip(QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_MOD)->title(true)), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_REM)->title(true)));
button->setToolTip(QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_MOD)->title(true, settings->printops.use_unicode_signs)), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_REM)->title(true, settings->printops.use_unicode_signs)));
OPERATOR_BUTTON("//", 4, 1);
button->setText("div");
f = CALCULATOR->getActiveFunction("div");
if(f) button->setToolTip(QString::fromStdString(f->title(true)));
if(f) button->setToolTip(QString::fromStdString(f->title(true, settings->printops.use_unicode_signs)));
f = CALCULATOR->getActiveFunction("log10"); f2 = CALCULATOR->getActiveFunction("log2");
if(f && f2) {
ITEM_BUTTON2(f2, f, "log<sub>2</sub>", 4, 2);
@ -319,16 +321,8 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
ITEM_BUTTON(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), "ln", 4, 2);
}
ITEM_BUTTON2(CALCULATOR->getFunctionById(FUNCTION_ID_ASCII), CALCULATOR->getFunctionById(FUNCTION_ID_CHAR), tr("a→1"), 4, 3);
grid->setRowStretch(0, 1);
grid->setRowStretch(1, 1);
grid->setRowStretch(2, 1);
grid->setRowStretch(3, 1);
grid->setRowStretch(4, 1);
grid->setRowStretch(0, 1);
grid->setColumnStretch(0, 1);
grid->setColumnStretch(1, 1);
grid->setColumnStretch(2, 1);
grid->setColumnStretch(3, 1);
for(c = 0; c < 4; c++) grid->setColumnStretch(c, 1);
for(int r = 0; r < 5; r++) grid->setRowStretch(r, 1);
QWidget *keypadX = new QWidget(this);
leftStack->addWidget(keypadX);
@ -386,11 +380,11 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
SYMBOL_BUTTON("n", 0, 3);
SYMBOL_BUTTON2("=", SIGN_NOT_EQUAL, 1, 2);
SYMBOL_BUTTON("/.", 1, 3);
button->setToolTip(QString::fromStdString(CALCULATOR->localWhereString()));
SYMBOL_BUTTON("<", 2, 0);
SYMBOL_BUTTON(SIGN_LESS_OR_EQUAL, 2, 1);
SYMBOL_BUTTON(">", 2, 2);
SYMBOL_BUTTON(SIGN_GREATER_OR_EQUAL, 2, 3);
button->setToolTip(tr("where"));
ITEM_BUTTON2(CALCULATOR->getFunctionById(FUNCTION_ID_SUM), CALCULATOR->getFunctionById(FUNCTION_ID_PRODUCT), "", 3, 0);
ITEM_BUTTON2(CALCULATOR->getFunctionById(FUNCTION_ID_DIFFERENTIATE), CALCULATOR->getFunctionById(FUNCTION_ID_D_SOLVE), "<font size=\"-1\"><i>d/dx</i></font>", 3, 1);
ITEM_BUTTON(CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE), "", 3, 2);
@ -406,16 +400,71 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
ITEM_BUTTON2(CALCULATOR->getFunctionById(FUNCTION_ID_CBRT), CALCULATOR->getFunctionById(FUNCTION_ID_ROOT), "", 4, 1);
ITEM_BUTTON2(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), CALCULATOR->getFunctionById(FUNCTION_ID_LOGN), "ln", 4, 2);
ITEM_BUTTON(CALCULATOR->getFunctionById(FUNCTION_ID_ABS), "|x|", 4, 3);
grid->setRowStretch(0, 1);
grid->setRowStretch(1, 1);
grid->setRowStretch(2, 1);
grid->setRowStretch(3, 1);
grid->setRowStretch(4, 1);
grid->setRowStretch(0, 1);
grid->setColumnStretch(0, 1);
grid->setColumnStretch(1, 1);
grid->setColumnStretch(2, 1);
grid->setColumnStretch(3, 1);
for(c = 0; c < 4; c++) grid->setColumnStretch(c, 1);
for(int r = 0; r < 5; r++) grid->setRowStretch(r, 1);
QWidget *keypadC = new QWidget(this);
leftStack->addWidget(keypadC);
grid = new QGridLayout(keypadC);
grid->setContentsMargins(0, 0, 0, 0);
customGrid = grid;
customEditButton = new QToolButton(this);
customEditButton->setIcon(LOAD_ICON("document-edit"));
customEditButton->setFocusPolicy(Qt::TabFocus);
customEditButton->setCheckable(true);
QFontMetrics fm(customEditButton->font());
QSize size = fm.boundingRect("DEL").size();
size.setWidth(size.width() + 10); size.setHeight(size.height() + 10);
customEditButton->setMinimumSize(size);
customEditButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
QMenu *menu = new QMenu(this);
addColumnAction = menu->addAction(tr("Add column"), this, SLOT(addCustomColumn())); addColumnAction->setEnabled(settings->custom_button_columns < 100);
addRowAction = menu->addAction(tr("Add row"), this, SLOT(addCustomRow())); addRowAction->setEnabled(settings->custom_button_rows < 100);
removeColumnAction = menu->addAction(tr("Remove column"), this, SLOT(removeCustomColumn())); removeColumnAction->setEnabled(settings->custom_button_columns > 1);
removeRowAction = menu->addAction(tr("Remove row"), this, SLOT(removeCustomRow())); removeRowAction->setEnabled(settings->custom_button_rows > 1);
customEditButton->setMenu(menu);
customEditButton->setPopupMode(QToolButton::MenuButtonPopup);
connect(customEditButton, SIGNAL(toggled(bool)), this, SLOT(onCustomEditClicked(bool)));
grid->addWidget(customEditButton, 0, 0);
customButtons.resize(settings->custom_button_columns);
for(c = 0; c < settings->custom_button_columns; c++) {
customButtons[c].resize(settings->custom_button_rows);
for(int r = 0; r < settings->custom_button_rows; r++) {
if(c == 0 && r == 0) {
customButtons[c][r] = NULL;
} else {
button = new KeypadButton(QString(), this);
connect(button, SIGNAL(clicked()), this, SLOT(onCustomButtonClicked()));
connect(button, SIGNAL(clicked2()), this, SLOT(onCustomButtonClicked2()));
connect(button, SIGNAL(clicked3()), this, SLOT(onCustomButtonClicked3()));
grid->addWidget(button, r, c);
customButtons[c][r] = button;
}
grid->setRowStretch(r, 1);
}
grid->setColumnStretch(c, 1);
}
for(size_t i = 0; i < settings->custom_buttons.size();) {
custom_button *cb = &settings->custom_buttons[i];
if(cb->c > 0 && cb->r > 0 && (cb->c != 1 || cb->r != 1) && cb->c <= customButtons.size() && cb->r <= customButtons[cb->c - 1].size()) {
button = customButtons[cb->c - 1][cb->r - 1];
if(button) {
if(cb->label.contains("</")) button->setRichText(cb->label);
else button->setText(cb->label);
button->setProperty(BUTTON_DATA, cb->type[0]);
button->setProperty(BUTTON_VALUE, QString::fromStdString(cb->value[0]));
button->setProperty(BUTTON_DATA2, cb->type[1]);
button->setProperty(BUTTON_VALUE2, QString::fromStdString(cb->value[1]));
button->setProperty(BUTTON_DATA3, cb->type[2]);
button->setProperty(BUTTON_VALUE3, QString::fromStdString(cb->value[2]));
button->setToolTip(settings->shortcutText(cb->type[0], cb->value[0]), settings->shortcutText(cb->type[1], cb->value[1]), settings->shortcutText(cb->type[2], cb->value[2]));
}
i++;
} else {
settings->custom_buttons.erase(settings->custom_buttons.begin() + i);
}
}
b_edit = false;
grid = grid2;
c = 0;
@ -434,7 +483,7 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
commaButton = button;
c++;
SYMBOL_OPERATOR_SYMBOL_BUTTON("0", "", "°", 3, c)
button->setToolTip(QString(), "x<sup>0</sup>", QString::fromStdString(CALCULATOR->getDegUnit()->title(true)));
button->setToolTip(QString(), "x<sup>0</sup>", QString::fromStdString(CALCULATOR->getDegUnit()->title(true, settings->printops.use_unicode_signs)));
f = CALCULATOR->getActiveFunction("inv");
if(f) {
SYMBOL_OPERATOR_ITEM_BUTTON("1", "¹", f, 2, c)
@ -467,7 +516,7 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
f = CALCULATOR->getActiveFunction("exp10"); f2 = CALCULATOR->getActiveFunction("exp2");
if(f && f2) {
OPERATOR_ITEM2_BUTTON("E", f, f2, 3, c);
button->setToolTip("10<sup>x</sup>", QString::fromStdString(f->title(true)), QString::fromStdString(f2->title(true)));
button->setToolTip("10<sup>x</sup>", QString::fromStdString(f->title(true, settings->printops.use_unicode_signs)), QString::fromStdString(f2->title(true, settings->printops.use_unicode_signs)));
} else {
OPERATOR_BUTTON("E", 3, c);
button->setToolTip("10<sup>x</sup>");
@ -477,7 +526,7 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
ITEM_BUTTON(settings->vans[0], "ANS", 3, c);
button = new KeypadButton("ANS", this);
button->setProperty(BUTTON_DATA, QVariant::fromValue((void*) settings->vans[0])); \
button->setToolTip(QString::fromStdString(settings->vans[0]->title(true)), tr("Previous result (static)"));
button->setToolTip(QString::fromStdString(settings->vans[0]->title(true, settings->printops.use_unicode_signs)), tr("Previous result (static)"));
connect(button, SIGNAL(clicked()), this, SLOT(onItemButtonClicked()));
connect(button, SIGNAL(clicked2()), this, SIGNAL(answerClicked()));
connect(button, SIGNAL(clicked3()), this, SIGNAL(answerClicked()));
@ -497,7 +546,7 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
f = CALCULATOR->getActiveFunction("neg");
if(f) {
OPERATOR_ITEM_SYMBOL_BUTTON(SIGN_MINUS, f, SIGN_MINUS, 2, c);
button->setToolTip(tr("Subtraction"), QString::fromStdString(f->title(true)) + " (" + QKeySequence(Qt::CTRL | Qt::Key_Minus).toString(QKeySequence::NativeText) + ")", tr("Minus"));
button->setToolTip(tr("Subtraction"), QString::fromStdString(f->title(true, settings->printops.use_unicode_signs)) + " (" + QKeySequence(Qt::CTRL | Qt::Key_Minus).toString(QKeySequence::NativeText) + ")", tr("Minus"));
} else {
OPERATOR_SYMBOL_BUTTON(SIGN_MINUS, SIGN_MINUS, 2, c);
button->setToolTip(tr("Subtraction"), tr("Minus"));
@ -513,26 +562,216 @@ KeypadWidget::KeypadWidget(QWidget *parent) : QWidget(parent) {
connect(acButton, SIGNAL(clicked3()), this, SIGNAL(clearClicked()));
grid->addWidget(acButton, 0, c, 1, 1);
button = new KeypadButton("=", this);
button->setToolTip(tr("Calculate expression"), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_SOLVE)->title(true)));
button->setToolTip(tr("Calculate expression"), QString::fromStdString(CALCULATOR->getFunctionById(FUNCTION_ID_SOLVE)->title(true, settings->printops.use_unicode_signs)));
button->setProperty(BUTTON_DATA, QVariant::fromValue((void*) CALCULATOR->getFunctionById(FUNCTION_ID_SOLVE))); \
connect(button, SIGNAL(clicked()), this, SIGNAL(equalsClicked()));
connect(button, SIGNAL(clicked2()), this, SLOT(onItemButtonClicked()));
connect(button, SIGNAL(clicked3()), this, SLOT(onItemButtonClicked()));
grid->addWidget(button, 3, c, 1, 1);
grid->setRowStretch(0, 1);
grid->setRowStretch(1, 1);
grid->setRowStretch(2, 1);
grid->setRowStretch(3, 1);
grid->setColumnStretch(0, 1);
grid->setColumnStretch(1, 1);
grid->setColumnStretch(2, 1);
grid->setColumnStretch(3, 1);
grid->setColumnStretch(4, 1);
grid->setColumnStretch(5, 1);
for(c = 0; c < 6; c++) grid->setColumnStretch(c, 1);
for(int r = 0; r < 4; r++) grid->setRowStretch(r, 1);
setKeypadType(settings->keypad_type);
}
KeypadWidget::~KeypadWidget() {}
void KeypadWidget::updateCustomActionOK() {
int i = actionList->currentRow();
customOKButton->setEnabled(i == 0 || (i > 0 && (!labelEdit || !labelEdit->text().trimmed().isEmpty()) && (!SHORTCUT_REQUIRES_VALUE(i - 1) || !valueEdit->text().trimmed().isEmpty())));
}
void KeypadWidget::customActionOKClicked() {
QString value = valueEdit->text().trimmed();
if(settings->testShortcutValue(actionList->currentRow() - 1, value, customActionDialog)) {
customActionDialog->accept();
} else {
valueEdit->setFocus();
}
valueEdit->setText(value);
}
void KeypadWidget::currentCustomActionChanged(int i) {
valueEdit->setEnabled(SHORTCUT_REQUIRES_VALUE(i));
if(!valueEdit->isEnabled()) valueEdit->clear();
}
void KeypadWidget::editCustomAction(KeypadButton *button, int i) {
if(i < 1 || i > 3) return;
QDialog *dialog = new QDialog(this);
customActionDialog = dialog;
if(settings->always_on_top) dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
dialog->setWindowTitle(tr("Button Action"));
QVBoxLayout *box = new QVBoxLayout(dialog);
QGridLayout *grid = new QGridLayout();
box->addLayout(grid);
if(i == 1) {
grid->addWidget(new QLabel(tr("Label:"), dialog), 0, 0);
labelEdit = new QLineEdit(dialog);
labelEdit->setText(button->richText().isEmpty() ? button->text() : button->richText());
grid->addWidget(labelEdit, 0, 1);
} else {
labelEdit = NULL;
}
grid->addWidget(new QLabel(tr("Action:"), dialog), i == 2 ? 0 : 1, 0);
actionList = new QListWidget(dialog);
grid->addWidget(actionList, i == 2 ? 1 : 2, 0, 1, 2);
int type = -1;
if(button->property(i == 2 ? BUTTON_DATA2 : (i == 3 ? BUTTON_DATA3 : BUTTON_DATA)).isValid()) type = button->property(i == 2 ? BUTTON_DATA2 : (i == 3 ? BUTTON_DATA3 : BUTTON_DATA)).toInt();
actionList->addItem(tr("None"));
actionList->setCurrentRow(0);
for(int i = SHORTCUT_TYPE_FUNCTION; i <= LAST_SHORTCUT_TYPE; i++) {
actionList->addItem(settings->shortcutTypeText((shortcut_type) i));
if(i == type) actionList->setCurrentRow(i + 1);
}
grid->addWidget(new QLabel(tr("Value:"), dialog), i == 2 ? 2 : 3, 0);
valueEdit = new MathLineEdit(dialog);
if(button->property(i == 2 ? BUTTON_VALUE2 : (i == 3 ? BUTTON_VALUE3 : BUTTON_VALUE)).isValid()) valueEdit->setText(button->property(i == 2 ? BUTTON_VALUE2 : (i == 3 ? BUTTON_VALUE3 : BUTTON_VALUE)).toString());
grid->addWidget(valueEdit, i == 2 ? 2 : 3, 1);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, dialog);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false);
box->addWidget(buttonBox);
connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(customActionOKClicked()));
connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), dialog, SLOT(reject()));
if(labelEdit) connect(labelEdit, SIGNAL(textEdited(const QString&)), this, SLOT(updateCustomActionOK()));
connect(actionList, SIGNAL(currentRowChanged(int)), this, SLOT(updateCustomActionOK()));
connect(actionList, SIGNAL(currentRowChanged(int)), this, SLOT(currentCustomActionChanged(int)));
connect(valueEdit, SIGNAL(textEdited(const QString&)), this, SLOT(updateCustomActionOK()));
customOKButton = buttonBox->button(QDialogButtonBox::Ok);
customOKButton->setEnabled(false);
if(labelEdit) labelEdit->setFocus();
else actionList->setFocus();
if(dialog->exec() == QDialog::Accepted) {
int grid_i = customGrid->indexOf(button);
int c = 0, r = 0, cs = 0, rs = 0;
customGrid->getItemPosition(grid_i, &r, &c, &rs, &cs);
c++; r++;
size_t index = 0;
for(size_t i = settings->custom_buttons.size(); i > 0; i--) {
if(settings->custom_buttons[i - 1].r == r && settings->custom_buttons[i - 1].c == c) {
index = i;
break;
}
}
if(index == 0) {
custom_button cb;
cb.c = c; cb.r = r; cb.type[0] = -1; cb.type[1] = -1; cb.type[2] = -1;
settings->custom_buttons.push_back(cb);
index = settings->custom_buttons.size();
}
index--;
custom_button *cb = &settings->custom_buttons[index];
cb->type[i - 1] = actionList->currentRow() - 1;
cb->value[i - 1] = valueEdit->text().trimmed().toStdString();
button->setProperty(i == 2 ? BUTTON_DATA2 : (i == 3 ? BUTTON_DATA3 : BUTTON_DATA), actionList->currentRow() - 1);
button->setProperty(i == 2 ? BUTTON_VALUE2 : (i == 3 ? BUTTON_VALUE3 : BUTTON_VALUE), valueEdit->text().trimmed());
button->setToolTip(settings->shortcutText(cb->type[0], cb->value[0]), settings->shortcutText(cb->type[1], cb->value[1]), settings->shortcutText(cb->type[2], cb->value[2]));
if(labelEdit) {
settings->custom_buttons[index].label = labelEdit->text().trimmed();
if(labelEdit->text().contains("</")) button->setRichText(labelEdit->text().trimmed());
else button->setText(labelEdit->text());
}
}
dialog->deleteLater();
}
void KeypadWidget::onCustomEditClicked(bool b) {
b_edit = b;
}
void KeypadWidget::addCustomRow() {
settings->custom_button_rows++;
int r = settings->custom_button_rows - 1;
for(int c = 0; c < settings->custom_button_columns; c++) {
customButtons[c].resize(settings->custom_button_rows);
KeypadButton *button = new KeypadButton(QString(), this);
connect(button, SIGNAL(clicked()), this, SLOT(onCustomButtonClicked()));
connect(button, SIGNAL(clicked2()), this, SLOT(onCustomButtonClicked2()));
connect(button, SIGNAL(clicked3()), this, SLOT(onCustomButtonClicked3()));
customGrid->addWidget(button, r, c);
customButtons[c][r] = button;
customGrid->setRowStretch(r, 1);
}
addRowAction->setEnabled(settings->custom_button_rows < 100);
removeRowAction->setEnabled(true);
}
void KeypadWidget::addCustomColumn() {
settings->custom_button_columns++;
customButtons.resize(settings->custom_button_columns);
int c = settings->custom_button_columns - 1;
customButtons[c].resize(settings->custom_button_rows);
for(int r = 0; r < settings->custom_button_rows; r++) {
KeypadButton *button = new KeypadButton(QString(), this);
connect(button, SIGNAL(clicked()), this, SLOT(onCustomButtonClicked()));
connect(button, SIGNAL(clicked2()), this, SLOT(onCustomButtonClicked2()));
connect(button, SIGNAL(clicked3()), this, SLOT(onCustomButtonClicked3()));
customGrid->addWidget(button, r, c);
customButtons[c][r] = button;
customGrid->setRowStretch(r, 1);
}
customGrid->setColumnStretch(c, 1);
((QBoxLayout*) layout())->setStretchFactor(leftStack, 4 + (settings->custom_button_columns <= 4 ? 0 : (settings->custom_button_columns - 4) * 1.5));
addColumnAction->setEnabled(settings->custom_button_columns < 100);
removeColumnAction->setEnabled(true);
}
void KeypadWidget::removeCustomRow() {
if(settings->custom_button_rows <= 1) return;
settings->custom_button_rows--;
int r = settings->custom_button_rows;
customGrid->setRowStretch(r, 0);
for(int c = 0; c < settings->custom_button_columns; c++) {
for(size_t i = settings->custom_buttons.size(); i > 0; i--) {
if(settings->custom_buttons[i - 1].r == r + 1 && settings->custom_buttons[i - 1].c == c + 1) {
settings->custom_buttons.erase(settings->custom_buttons.begin() + i);
break;
}
}
customGrid->removeWidget(customButtons[c][r]);
customButtons[c][r]->deleteLater();
customButtons[c].pop_back();
}
addRowAction->setEnabled(true);
removeRowAction->setEnabled(settings->custom_button_rows > 1);
}
void KeypadWidget::removeCustomColumn() {
if(settings->custom_button_columns <= 1) return;
settings->custom_button_columns--;
int c = settings->custom_button_columns;
customGrid->setColumnStretch(c, 0);
for(int r = 0; r < settings->custom_button_rows; r++) {
for(size_t i = settings->custom_buttons.size(); i > 0; i--) {
if(settings->custom_buttons[i - 1].r == r + 1 && settings->custom_buttons[i - 1].c == c + 1) {
settings->custom_buttons.erase(settings->custom_buttons.begin() + i);
break;
}
}
customGrid->removeWidget(customButtons[c][r]);
customButtons[c][r]->deleteLater();
}
customButtons.pop_back();
((QBoxLayout*) layout())->setStretchFactor(leftStack, 4 + (settings->custom_button_columns <= 4 ? 0 : (settings->custom_button_columns - 4) * 1.5));
addColumnAction->setEnabled(true);
removeColumnAction->setEnabled(settings->custom_button_columns > 1);
}
void KeypadWidget::onCustomButtonClicked() {
KeypadButton *button = qobject_cast<KeypadButton*>(sender());
if(b_edit || !button->property(BUTTON_DATA).isValid() || button->property(BUTTON_DATA).toInt() < 0) {
editCustomAction(button, 1);
} else {
emit shortcutClicked(button->property(BUTTON_DATA).toInt(), button->property(BUTTON_VALUE).toString());
}
}
void KeypadWidget::onCustomButtonClicked2() {
KeypadButton *button = qobject_cast<KeypadButton*>(sender());
if(b_edit || !button->property(BUTTON_DATA2).isValid() || button->property(BUTTON_DATA2).toInt() < 0) {
editCustomAction(button, 2);
} else {
emit shortcutClicked(button->property(BUTTON_DATA2).toInt(), button->property(BUTTON_VALUE2).toString());
}
}
void KeypadWidget::onCustomButtonClicked3() {
KeypadButton *button = qobject_cast<KeypadButton*>(sender());
if(b_edit || !button->property(BUTTON_DATA3).isValid() || button->property(BUTTON_DATA3).toInt() < 0) {
editCustomAction(button, 3);
} else {
emit shortcutClicked(button->property(BUTTON_DATA2).toInt(), button->property(BUTTON_VALUE3).toString());
}
}
void KeypadWidget::updateAssumptions() {
QMenu *menu = qobject_cast<QMenu*>(sender());
int id = menu->property(BUTTON_DATA).toInt();
@ -596,6 +835,9 @@ void KeypadWidget::setKeypadType(int i) {
if(i < 0 || i > KEYPAD_CUSTOM) i = 0;
leftStack->setCurrentIndex(i);
}
void KeypadWidget::hideNumpad(bool b) {
numpad->setVisible(!b);
}
void KeypadWidget::updateBase() {
binButton->setChecked(settings->printops.base == 2 && settings->evalops.parse_options.base == 2);
octButton->setChecked(settings->printops.base == 8 && settings->evalops.parse_options.base == 8);
@ -629,6 +871,7 @@ void KeypadWidget::changeEvent(QEvent *e) {
delButton->setIcon(LOAD_ICON("edit-delete"));
backButton->setIcon(LOAD_ICON("go-back"));
forwardButton->setIcon(LOAD_ICON("go-forward"));
customEditButton->setIcon(LOAD_ICON("document-edit"));
}
QWidget::changeEvent(e);
}
@ -723,6 +966,9 @@ void KeypadButton::setRichText(const QString &text) {
richtext = text;
setText(QString());
}
const QString &KeypadButton::richText() const {
return richtext;
}
void KeypadButton::paintEvent(QPaintEvent *p) {
QPushButton::paintEvent(p);
if(!richtext.isEmpty()) {

View File

@ -14,11 +14,18 @@
#include <QWidget>
#include <QPushButton>
#include <QVector>
#include <libqalculate/qalculate.h>
class QTimer;
class QStackedLayout;
class QToolButton;
class QLineEdit;
class QListWidget;
class QDialog;
class QGridLayout;
class QAction;
class KeypadButton : public QPushButton {
@ -32,6 +39,7 @@ class KeypadButton : public QPushButton {
void setToolTip(const QString &s1, const QString &s2 = QString(), const QString &s3 = QString());
void setRichText(const QString &text);
const QString &richText() const;
protected:
@ -74,8 +82,19 @@ class KeypadWidget : public QWidget {
protected:
KeypadButton *sinButton, *cosButton, *tanButton, *delButton, *acButton, *backButton, *forwardButton, *dotButton, *commaButton, *multiplicationButton, *divisionButton, *imaginaryButton, *binButton, *octButton, *decButton, *hexButton, *aButton, *bButton, *cButton, *dButton, *eButton, *fButton;
QPushButton *customOKButton;
QToolButton *customEditButton;
QVector<QVector<KeypadButton*> > customButtons;
QStackedLayout *leftStack;
QGridLayout *customGrid;
QLineEdit *labelEdit, *valueEdit;
QListWidget *actionList;
QWidget *numpad;
QDialog *customActionDialog;
QAction *addRowAction, *addColumnAction, *removeRowAction, *removeColumnAction;
bool b_edit;
void changeEvent(QEvent *e);
void editCustomAction(KeypadButton*, int);
protected slots:
@ -91,17 +110,29 @@ class KeypadWidget : public QWidget {
void onItemButtonClicked3();
void onBaseButtonClicked();
void onBaseButtonClicked2();
void onCustomButtonClicked();
void onCustomButtonClicked2();
void onCustomButtonClicked3();
void onHypToggled(bool);
void assumptionsTypeActivated();
void assumptionsSignActivated();
void defaultAssumptionsActivated();
void updateAssumptions();
void onCustomEditClicked(bool);
void removeCustomRow();
void addCustomRow();
void removeCustomColumn();
void addCustomColumn();
void updateCustomActionOK();
void customActionOKClicked();
void currentCustomActionChanged(int);
public slots:
void updateBase();
void updateSymbols();
void setKeypadType(int);
void hideNumpad(bool);
signals:
@ -130,6 +161,7 @@ class KeypadWidget : public QWidget {
void factorizeClicked();
void expandClicked();
void expressionCalculationUpdated(int);
void shortcutClicked(int, const QString&);
};

View File

@ -233,6 +233,7 @@ void QalculateQtSettings::loadPreferences() {
expression_status_delay = 1000;
prefixes_default = true;
keypad_type = 0;
hide_numpad = false;
use_custom_result_font = false;
use_custom_expression_font = false;
use_custom_keypad_font = false;
@ -263,6 +264,9 @@ void QalculateQtSettings::loadPreferences() {
default_shortcuts = true;
keyboard_shortcuts.clear();
custom_buttons.clear();
custom_button_rows = 5;
custom_button_columns = 4;
default_signed = -1;
default_bits = -1;
@ -344,12 +348,67 @@ void QalculateQtSettings::loadPreferences() {
char str1[svalue.length()];
char str2[svalue.length()];
keyboard_shortcut ks;
int n = sscanf(svalue.c_str(), "%s:%i:%s", str1, &ks.type, str2);
if(n >= 2 && ks.type >= SHORTCUT_TYPE_FUNCTION && ks.type <= LAST_SHORTCUT_TYPE) {
int ks_type = 0;
int n = sscanf(svalue.c_str(), "%s:%i:%s", str1, &ks_type, str2);
if(n >= 2 && ks_type >= SHORTCUT_TYPE_FUNCTION && ks_type <= LAST_SHORTCUT_TYPE) {
if(n == 3) ks.value = str1;
remove_blank_ends(ks.value);
ks.type = (shortcut_type) ks_type;
ks.key = str1;
ks.new_action = false;
ks.action = NULL;
keyboard_shortcuts.push_back(ks);
}
} else if(svar == "custom_button_label") {
int c = 0, r = 0;
char str[svalue.length()];
int n = sscanf(svalue.c_str(), "%i:%i:%s", &r, &c, str);
if(n == 3 && c > 0 && r > 0) {
size_t index = 0;
for(size_t i = custom_buttons.size(); i > 0; i--) {
if(custom_buttons[i - 1].r == r && custom_buttons[i - 1].c == c) {
index = i;
break;
}
}
if(index == 0) {
custom_button cb;
cb.c = c; cb.r = r; cb.type[0] = -1; cb.type[1] = -1; cb.type[2] = -1;
custom_buttons.push_back(cb);
index = custom_buttons.size();
}
index--;
custom_buttons[index].label = QString::fromUtf8(str).trimmed();
}
} else if(svar == "custom_button") {
int c = 0, r = 0;
unsigned int bi = 0;
char str[svalue.length()];
int cb_type = -1;
int n = sscanf(svalue.c_str(), "%i:%i:%u:%i:%s", &c, &r, &bi, &cb_type, str);
if((n == 4 || n == 5) && bi <= 2 && c > 0 && r > 0) {
size_t index = 0;
for(size_t i = custom_buttons.size(); i > 0; i--) {
if(custom_buttons[i - 1].r == r && custom_buttons[i - 1].c == c) {
index = i;
break;
}
}
if(index == 0) {
custom_button cb;
cb.c = c; cb.r = r; cb.type[0] = -1; cb.type[1] = -1; cb.type[2] = -1;
custom_buttons.push_back(cb);
index = custom_buttons.size();
}
index--;
custom_buttons[index].type[bi] = cb_type;
if(n == 5) {custom_buttons[index].value[bi] = str; remove_blank_ends(custom_buttons[index].value[bi]);}
else custom_buttons[index].value[bi] = "";
}
} else if(svar == "custom_button_rows") {
if(v > 0 && v <= 100) custom_button_rows = v;
} else if(svar == "custom_button_columns") {
if(v > 0 && v <= 100) custom_button_columns = v;
} else if(svar == "version") {
parse_qalculate_version(svalue, preferences_version);
} else if(svar == "always_on_top") {
@ -366,6 +425,8 @@ void QalculateQtSettings::loadPreferences() {
window_state = QByteArray::fromBase64(svalue.c_str());
} else if(svar == "keypad_type") {
if(v >= 0 && v <= 3) keypad_type = v;
} else if(svar == "hide_numpad") {
hide_numpad = v;
} else if(svar == "replace_expression") {
replace_expression = v;
} else if(svar == "window_geometry") {
@ -752,10 +813,10 @@ void QalculateQtSettings::loadPreferences() {
if(default_shortcuts) {
keyboard_shortcut ks;
#define ADD_SHORTCUT(k, t, v) ks.key = k; ks.type = t; ks.value = v; keyboard_shortcuts.push_back(ks);
#define ADD_SHORTCUT(k, t, v) ks.key = k; ks.type = t; ks.value = v; ks.action = NULL; ks.new_action = false; keyboard_shortcuts.push_back(ks);
ADD_SHORTCUT(QKeySequence(QKeySequence::Quit).toString(), SHORTCUT_TYPE_QUIT, "")
ADD_SHORTCUT(QKeySequence(QKeySequence::HelpContents).toString(), SHORTCUT_TYPE_HELP, "")
//ADD_SHORTCUT(GDK_KEY_c, GDK_CONTROL_MASK | GDK_MOD1_MASK, SHORTCUT_TYPE_COPY_RESULT, "")
ADD_SHORTCUT("Ctrl+Alt+C", SHORTCUT_TYPE_COPY_RESULT, "")
ADD_SHORTCUT(QKeySequence(QKeySequence::Save).toString(), SHORTCUT_TYPE_STORE, "")
ADD_SHORTCUT("Ctrl+M", SHORTCUT_TYPE_MANAGE_VARIABLES, "")
ADD_SHORTCUT("Ctrl+F", SHORTCUT_TYPE_MANAGE_FUNCTIONS, "")
@ -766,16 +827,20 @@ void QalculateQtSettings::loadPreferences() {
ADD_SHORTCUT("Alt+K", SHORTCUT_TYPE_KEYPAD, "")
ADD_SHORTCUT("Ctrl+T", SHORTCUT_TYPE_CONVERT, "")
ADD_SHORTCUT("Ctrl+B", SHORTCUT_TYPE_NUMBER_BASES, "")
/*ADD_SHORTCUT(GDK_KEY_parenright, GDK_CONTROL_MASK | GDK_SHIFT_MASK, SHORTCUT_TYPE_SMART_PARENTHESES, "")
ADD_SHORTCUT(GDK_KEY_parenleft, GDK_CONTROL_MASK | GDK_SHIFT_MASK, SHORTCUT_TYPE_SMART_PARENTHESES, "")
ADD_SHORTCUT(GDK_KEY_Up, GDK_CONTROL_MASK, SHORTCUT_TYPE_RPN_UP, "")
ADD_SHORTCUT(GDK_KEY_Down, GDK_CONTROL_MASK, SHORTCUT_TYPE_RPN_DOWN, "")
ADD_SHORTCUT(GDK_KEY_Right, GDK_CONTROL_MASK, SHORTCUT_TYPE_RPN_SWAP, "")
ADD_SHORTCUT(GDK_KEY_Left, GDK_CONTROL_MASK, SHORTCUT_TYPE_RPN_LASTX, "")
ADD_SHORTCUT(GDK_KEY_c, GDK_CONTROL_MASK | GDK_SHIFT_MASK, SHORTCUT_TYPE_RPN_COPY, "")
ADD_SHORTCUT(GDK_KEY_Delete, GDK_CONTROL_MASK, SHORTCUT_TYPE_RPN_DELETE, "")
ADD_SHORTCUT(GDK_KEY_Delete, GDK_CONTROL_MASK | GDK_SHIFT_MASK, SHORTCUT_TYPE_RPN_CLEAR, "")
ADD_SHORTCUT(GDK_KEY_Tab, 0, SHORTCUT_TYPE_ACTIVATE_FIRST_COMPLETION, "")*/
ADD_SHORTCUT("Ctrl+-", SHORTCUT_TYPE_NEGATE, "")
ADD_SHORTCUT("Ctrl+Enter", SHORTCUT_TYPE_APPROXIMATE, "")
ADD_SHORTCUT("Ctrl+Return", SHORTCUT_TYPE_APPROXIMATE, "")
ADD_SHORTCUT("Alt+M", SHORTCUT_TYPE_MODE, "")
ADD_SHORTCUT("F10", SHORTCUT_TYPE_MENU, "")
ADD_SHORTCUT("Ctrl+)", SHORTCUT_TYPE_SMART_PARENTHESES, "")
ADD_SHORTCUT("Ctrl+(", SHORTCUT_TYPE_SMART_PARENTHESES, "")
ADD_SHORTCUT("Ctrl+Up", SHORTCUT_TYPE_RPN_UP, "")
ADD_SHORTCUT("Ctrl+Down", SHORTCUT_TYPE_RPN_DOWN, "")
ADD_SHORTCUT("Ctrl+Right", SHORTCUT_TYPE_RPN_SWAP, "")
ADD_SHORTCUT("Ctrl+Left", SHORTCUT_TYPE_RPN_LASTX, "")
ADD_SHORTCUT("Ctrl+Shift+C", SHORTCUT_TYPE_RPN_COPY, "")
ADD_SHORTCUT("Ctrl+Delete", SHORTCUT_TYPE_RPN_DELETE, "")
ADD_SHORTCUT("Ctrl+Shift+Delete", SHORTCUT_TYPE_RPN_CLEAR, "")
}
updateMessagePrintOptions();
@ -976,7 +1041,27 @@ void QalculateQtSettings::savePreferences(bool) {
if(implicit_question_asked) fprintf(file, "implicit_question_asked=%i\n", implicit_question_asked);
fprintf(file, "replace_expression=%i\n", replace_expression);
fprintf(file, "keypad_type=%i\n", keypad_type);
fprintf(file, "hide_numpad=%i\n", hide_numpad);
fprintf(file, "rpn_keys=%i\n", rpn_keys);
if(!custom_buttons.empty()) {
fprintf(file, "custom_button_columns=%i\n", custom_button_columns);
fprintf(file, "custom_button_rows=%i\n", custom_button_rows);
for(unsigned int i = 0; i < custom_buttons.size(); i++) {
if(!custom_buttons[i].label.isEmpty()) fprintf(file, "custom_button_label=%i:%i:%s\n", custom_buttons[i].r, custom_buttons[i].c, custom_buttons[i].label.toUtf8().data());
for(unsigned int bi = 0; bi <= 2; bi++) {
if(custom_buttons[i].type[bi] != -1) {
if(custom_buttons[i].value[bi].empty()) fprintf(file, "custom_button=%i:%i:%u:%i\n", custom_buttons[i].c, custom_buttons[i].r, bi, custom_buttons[i].type[bi]);
else fprintf(file, "custom_button=%i:%i:%u:%i:%s\n", custom_buttons[i].c, custom_buttons[i].r, bi, custom_buttons[i].type[bi], custom_buttons[i].value[bi].c_str());
}
}
}
}
if(!default_shortcuts) {
for(size_t i = 0; i < keyboard_shortcuts.size(); i++) {
if(keyboard_shortcuts[i].value.empty()) fprintf(file, "keyboard_shortcut=%s:%i\n", keyboard_shortcuts[i].key.toUtf8().data(), keyboard_shortcuts[i].type);
else fprintf(file, "keyboard_shortcut=%s:%i:%s\n", keyboard_shortcuts[i].key.toUtf8().data(), keyboard_shortcuts[i].type, keyboard_shortcuts[i].value.c_str());
}
}
if(default_bits >= 0) fprintf(file, "bit_width=%i\n", default_bits);
if(default_signed >= 0) fprintf(file, "signed_integer=%i\n", default_signed);
fprintf(file, "spell_out_logical_operators=%i\n", printops.spell_out_logical_operators);
@ -1209,6 +1294,10 @@ void MathLineEdit::keyPressEvent(QKeyEvent *event) {
insert(settings->multiplicationSign(b_unit));
return;
}
case Qt::Key_Slash: {
insert(settings->divisionSign(false));
return;
}
case Qt::Key_Minus: {
insert(SIGN_MINUS);
return;
@ -1429,3 +1518,158 @@ void QalculateQtSettings::checkVersion(bool force, QWidget *parent) {
last_version_check_date.setToCurrentDate();
}
QString QalculateQtSettings::shortcutText(int type, const std::string &value) {
if(type < 0) return QString();
switch(type) {
case SHORTCUT_TYPE_FUNCTION: {
MathFunction *f = CALCULATOR->getActiveFunction(value);
return QString::fromStdString(f->title(true, printops.use_unicode_signs));
}
case SHORTCUT_TYPE_FUNCTION_WITH_DIALOG: {
MathFunction *f = CALCULATOR->getActiveFunction(value);
return QString::fromStdString(f->title(true, printops.use_unicode_signs));
}
case SHORTCUT_TYPE_VARIABLE: {
Variable *v = CALCULATOR->getActiveVariable(value);
return QString::fromStdString(v->title(true, printops.use_unicode_signs));
}
case SHORTCUT_TYPE_UNIT: {
Unit *u = CALCULATOR->getActiveUnit(value);
return QString::fromStdString(u->title(true, printops.use_unicode_signs));
}
default: {}
}
if(value.empty()) return shortcutTypeText((shortcut_type) type);
return tr("%1: %2").arg(shortcutTypeText((shortcut_type) type)).arg(QString::fromStdString(value));
}
QString QalculateQtSettings::shortcutTypeText(shortcut_type type) {
switch(type) {
case SHORTCUT_TYPE_FUNCTION: {return tr("Insert function");}
case SHORTCUT_TYPE_FUNCTION_WITH_DIALOG: {return tr("Insert function (dialog)");}
case SHORTCUT_TYPE_VARIABLE: {return tr("Insert variable");}
case SHORTCUT_TYPE_APPROXIMATE: {return tr("Approximate result");}
case SHORTCUT_TYPE_NEGATE: {return tr("Negate");}
case SHORTCUT_TYPE_INVERT: {return tr("Invert");}
case SHORTCUT_TYPE_UNIT: {return tr("Insert unit");}
case SHORTCUT_TYPE_TEXT: {return tr("Insert text");}
case SHORTCUT_TYPE_OPERATOR: {return tr("Insert operator");}
case SHORTCUT_TYPE_DATE: {return tr("Insert date");}
case SHORTCUT_TYPE_MATRIX: {return tr("Insert matrix");}
case SHORTCUT_TYPE_SMART_PARENTHESES: {return tr("Insert smart parentheses");}
case SHORTCUT_TYPE_CONVERT_TO: {return tr("Convert to unit");}
case SHORTCUT_TYPE_CONVERT: {return tr("Convert");}
case SHORTCUT_TYPE_OPTIMAL_UNIT: {return tr("Convert to optimal unit");}
case SHORTCUT_TYPE_BASE_UNITS: {return tr("Convert to base units");}
case SHORTCUT_TYPE_OPTIMAL_PREFIX: {return tr("Convert to optimal prefix");}
case SHORTCUT_TYPE_TO_NUMBER_BASE: {return tr("Convert to number base");}
case SHORTCUT_TYPE_FACTORIZE: {return tr("Factorize result");}
case SHORTCUT_TYPE_EXPAND: {return tr("Expand result");}
case SHORTCUT_TYPE_PARTIAL_FRACTIONS: {return tr("Expand partial fractions");}
case SHORTCUT_TYPE_RPN_DOWN: {return tr("RPN: down");}
case SHORTCUT_TYPE_RPN_UP: {return tr("RPN: up");}
case SHORTCUT_TYPE_RPN_SWAP: {return tr("RPN: swap");}
case SHORTCUT_TYPE_RPN_COPY: {return tr("RPN: copy");}
case SHORTCUT_TYPE_RPN_LASTX: {return tr("RPN: lastx");}
case SHORTCUT_TYPE_RPN_DELETE: {return tr("RPN: delete register");}
case SHORTCUT_TYPE_RPN_CLEAR: {return tr("RPN: clear stack");}
case SHORTCUT_TYPE_INPUT_BASE: {return tr("Set expression base");}
case SHORTCUT_TYPE_OUTPUT_BASE: {return tr("Set result base");}
case SHORTCUT_TYPE_DEGREES: {return tr("Set angle unit to degrees");}
case SHORTCUT_TYPE_RADIANS: {return tr("Set angle unit to radians");}
case SHORTCUT_TYPE_GRADIANS: {return tr("Set angle unit to gradians");}
case SHORTCUT_TYPE_NORMAL_NOTATION: {return tr("Active normal notation");}
case SHORTCUT_TYPE_SCIENTIFIC_NOTATION: {return tr("Activate scientific notation");}
case SHORTCUT_TYPE_ENGINEERING_NOTATION: {return tr("Activate engineering notation");}
case SHORTCUT_TYPE_SIMPLE_NOTATION: {return tr("Activate simple notation");}
case SHORTCUT_TYPE_RPN_MODE: {return tr("Toggle RPN mode");}
case SHORTCUT_TYPE_GENERAL_KEYPAD: {return tr("Show general keypad");}
case SHORTCUT_TYPE_PROGRAMMING_KEYPAD: {return tr("Toggle programming keypad");}
case SHORTCUT_TYPE_ALGEBRA_KEYPAD: {return tr("Toggle algebra keypad");}
case SHORTCUT_TYPE_CUSTOM_KEYPAD: {return tr("Toggle custom keypad");}
case SHORTCUT_TYPE_KEYPAD: {return tr("Show/hide keypad");}
case SHORTCUT_TYPE_HISTORY_SEARCH: {return tr("Search history");}
case SHORTCUT_TYPE_MANAGE_VARIABLES: {return tr("Show variables");}
case SHORTCUT_TYPE_MANAGE_FUNCTIONS: {return tr("Show functions");}
case SHORTCUT_TYPE_MANAGE_UNITS: {return tr("Show units");}
case SHORTCUT_TYPE_MANAGE_DATA_SETS: {return tr("Show data sets");}
case SHORTCUT_TYPE_STORE: {return tr("Store result");}
case SHORTCUT_TYPE_MEMORY_CLEAR: {return tr("MC (memory clear)");}
case SHORTCUT_TYPE_MEMORY_RECALL: {return tr("MR (memory recall)");}
case SHORTCUT_TYPE_MEMORY_STORE: {return tr("MS (memory store)");}
case SHORTCUT_TYPE_MEMORY_ADD: {return tr("M+ (memory plus)");}
case SHORTCUT_TYPE_MEMORY_SUBTRACT: {return tr("M (memory minus)");}
case SHORTCUT_TYPE_NEW_VARIABLE: {return tr("New variable");}
case SHORTCUT_TYPE_NEW_FUNCTION: {return tr("New function");}
case SHORTCUT_TYPE_PLOT: {return tr("Open plot functions/data");}
case SHORTCUT_TYPE_NUMBER_BASES: {return tr("Open convert number bases");}
case SHORTCUT_TYPE_FLOATING_POINT: {return tr("Open floating point conversion");}
case SHORTCUT_TYPE_CALENDARS: {return tr("Open calender conversion");}
case SHORTCUT_TYPE_PERCENTAGE_TOOL: {return tr("Open percentage calculation tool");}
case SHORTCUT_TYPE_PERIODIC_TABLE: {return tr("Open periodic table");}
case SHORTCUT_TYPE_UPDATE_EXRATES: {return tr("Update exchange rates");}
case SHORTCUT_TYPE_COPY_RESULT: {return tr("Copy result");}
case SHORTCUT_TYPE_INSERT_RESULT: {return tr("Insert result");}
case SHORTCUT_TYPE_MODE: {return tr("Open mode menu");}
case SHORTCUT_TYPE_MENU: {return tr("Open menu");}
case SHORTCUT_TYPE_HELP: {return tr("Help");}
case SHORTCUT_TYPE_QUIT: {return tr("Quit");}
case SHORTCUT_TYPE_CHAIN_MODE: {return tr("Toggle chain mode");}
case SHORTCUT_TYPE_ALWAYS_ON_TOP: {return tr("Toggle keep above");}
case SHORTCUT_TYPE_COMPLETE: {return tr("Show completion (activate first item)");}
case SHORTCUT_TYPE_EXPRESSION_CLEAR: {return tr("Clear expression");}
case SHORTCUT_TYPE_EXPRESSION_DELETE: {return tr("Delete");}
case SHORTCUT_TYPE_EXPRESSION_BACKSPACE: {return tr("Backspace");}
case SHORTCUT_TYPE_EXPRESSION_START: {return tr("Home");}
case SHORTCUT_TYPE_EXPRESSION_END: {return tr("End");}
case SHORTCUT_TYPE_EXPRESSION_RIGHT: {return tr("Right");}
case SHORTCUT_TYPE_EXPRESSION_LEFT: {return tr("Left");}
case SHORTCUT_TYPE_EXPRESSION_UP: {return tr("Up");}
case SHORTCUT_TYPE_EXPRESSION_DOWN: {return tr("Down");}
case SHORTCUT_TYPE_EXPRESSION_UNDO: {return tr("Undo");}
case SHORTCUT_TYPE_EXPRESSION_REDO: {return tr("Redo");}
case SHORTCUT_TYPE_EXPRESSION_HISTORY_NEXT: {return tr("Expression history next");}
case SHORTCUT_TYPE_EXPRESSION_HISTORY_PREVIOUS: {return tr("Expression history previous");}
}
return "-";
}
bool QalculateQtSettings::testShortcutValue(int type, QString &value, QWidget *w) {
switch(type) {
case SHORTCUT_TYPE_FUNCTION: {}
case SHORTCUT_TYPE_FUNCTION_WITH_DIALOG: {
if(value.length() > 2 && value.right(2) == "()") value.chop(2);
if(!CALCULATOR->getActiveFunction(value.toStdString())) {
QMessageBox::critical(w, QApplication::tr("Error"), QApplication::tr("Function not found."), QMessageBox::Ok);
return false;
}
break;
}
case SHORTCUT_TYPE_VARIABLE: {
if(!CALCULATOR->getActiveVariable(value.toStdString())) {
QMessageBox::critical(w, QApplication::tr("Error"), QApplication::tr("Variable not found."), QMessageBox::Ok);
return false;
}
break;
}
case SHORTCUT_TYPE_UNIT: {
if(!CALCULATOR->getActiveUnit(value.toStdString())) {
QMessageBox::critical(w, QApplication::tr("Error"), QApplication::tr("Unit not found."), QMessageBox::Ok);
return false;
}
break;
}
case SHORTCUT_TYPE_TO_NUMBER_BASE: {}
case SHORTCUT_TYPE_INPUT_BASE: {}
case SHORTCUT_TYPE_OUTPUT_BASE: {
Number nbase; int base;
base_from_string(value.toStdString(), base, nbase, type == SHORTCUT_TYPE_INPUT_BASE);
if(base == BASE_CUSTOM && nbase.isZero()) {
QMessageBox::critical(w, QApplication::tr("Error"), QApplication::tr("Unsupported base."), QMessageBox::Ok);
return false;
}
break;
}
}
return true;
}

View File

@ -19,6 +19,7 @@
class QWidget;
class QByteArray;
class QAction;
bool can_display_unicode_string_function(const char *str, void *w);
@ -38,6 +39,7 @@ bool name_matches(ExpressionItem *item, const std::string &str);
bool country_matches(Unit *u, const std::string &str, size_t minlength = 0);
bool title_matches(ExpressionItem *item, const std::string &str, size_t minlength = 0);
bool contains_plot_or_save(const std::string &str);
void base_from_string(std::string str, int &base, Number &nbase, bool input_base = false);
enum {
TITLE_APP,
@ -52,14 +54,14 @@ enum {
CLEAR_EXPRESSION
};
enum {
typedef enum {
SHORTCUT_TYPE_FUNCTION,
SHORTCUT_TYPE_FUNCTION_WITH_DIALOG,
SHORTCUT_TYPE_VARIABLE,
SHORTCUT_TYPE_UNIT,
SHORTCUT_TYPE_OPERATOR,
SHORTCUT_TYPE_TEXT,
SHORTCUT_TYPE_DATE,
SHORTCUT_TYPE_VECTOR,
SHORTCUT_TYPE_MATRIX,
SHORTCUT_TYPE_SMART_PARENTHESES,
SHORTCUT_TYPE_CONVERT_TO,
@ -72,6 +74,8 @@ enum {
SHORTCUT_TYPE_EXPAND,
SHORTCUT_TYPE_PARTIAL_FRACTIONS,
SHORTCUT_TYPE_APPROXIMATE,
SHORTCUT_TYPE_NEGATE,
SHORTCUT_TYPE_INVERT,
SHORTCUT_TYPE_RPN_UP,
SHORTCUT_TYPE_RPN_DOWN,
SHORTCUT_TYPE_RPN_SWAP,
@ -79,13 +83,14 @@ enum {
SHORTCUT_TYPE_RPN_LASTX,
SHORTCUT_TYPE_RPN_DELETE,
SHORTCUT_TYPE_RPN_CLEAR,
SHORTCUT_TYPE_META_MODE,
SHORTCUT_TYPE_OUTPUT_BASE,
SHORTCUT_TYPE_INPUT_BASE,
SHORTCUT_TYPE_DEGREES,
SHORTCUT_TYPE_RADIANS,
SHORTCUT_TYPE_GRADIANS,
SHORTCUT_TYPE_NORMAL_NOTATION,
SHORTCUT_TYPE_SCIENTIFIC_NOTATION,
SHORTCUT_TYPE_ENGINEERING_NOTATION,
SHORTCUT_TYPE_SIMPLE_NOTATION,
SHORTCUT_TYPE_COPY_RESULT,
SHORTCUT_TYPE_INSERT_RESULT,
@ -98,8 +103,7 @@ enum {
SHORTCUT_TYPE_KEYPAD,
SHORTCUT_TYPE_HISTORY_SEARCH,
SHORTCUT_TYPE_ALWAYS_ON_TOP,
SHORTCUT_TYPE_DO_COMPLETION,
SHORTCUT_TYPE_ACTIVATE_FIRST_COMPLETION,
SHORTCUT_TYPE_COMPLETE,
SHORTCUT_TYPE_MANAGE_VARIABLES,
SHORTCUT_TYPE_MANAGE_FUNCTIONS,
SHORTCUT_TYPE_MANAGE_UNITS,
@ -110,6 +114,19 @@ enum {
SHORTCUT_TYPE_MEMORY_STORE,
SHORTCUT_TYPE_MEMORY_ADD,
SHORTCUT_TYPE_MEMORY_SUBTRACT,
SHORTCUT_TYPE_EXPRESSION_CLEAR,
SHORTCUT_TYPE_EXPRESSION_DELETE,
SHORTCUT_TYPE_EXPRESSION_BACKSPACE,
SHORTCUT_TYPE_EXPRESSION_START,
SHORTCUT_TYPE_EXPRESSION_END,
SHORTCUT_TYPE_EXPRESSION_RIGHT,
SHORTCUT_TYPE_EXPRESSION_LEFT,
SHORTCUT_TYPE_EXPRESSION_UP,
SHORTCUT_TYPE_EXPRESSION_DOWN,
SHORTCUT_TYPE_EXPRESSION_HISTORY_NEXT,
SHORTCUT_TYPE_EXPRESSION_HISTORY_PREVIOUS,
SHORTCUT_TYPE_EXPRESSION_UNDO,
SHORTCUT_TYPE_EXPRESSION_REDO,
SHORTCUT_TYPE_NEW_VARIABLE,
SHORTCUT_TYPE_NEW_FUNCTION,
SHORTCUT_TYPE_PLOT,
@ -123,14 +140,25 @@ enum {
SHORTCUT_TYPE_MENU,
SHORTCUT_TYPE_HELP,
SHORTCUT_TYPE_QUIT
};
} shortcut_type;
#define LAST_SHORTCUT_TYPE SHORTCUT_TYPE_QUIT
#define SHORTCUT_REQUIRES_VALUE(x) (x == SHORTCUT_TYPE_FUNCTION || x == SHORTCUT_TYPE_FUNCTION_WITH_DIALOG || x == SHORTCUT_TYPE_UNIT || x == SHORTCUT_TYPE_VARIABLE || x == SHORTCUT_TYPE_TEXT || x == SHORTCUT_TYPE_OPERATOR || x == SHORTCUT_TYPE_CONVERT_TO || x == SHORTCUT_TYPE_TO_NUMBER_BASE || x == SHORTCUT_TYPE_INPUT_BASE || x == SHORTCUT_TYPE_OUTPUT_BASE)
struct keyboard_shortcut {
QString key;
int type;
shortcut_type type;
std::string value;
QAction *action;
bool new_action;
};
struct custom_button {
int c, r;
int type[3];
std::string value[3];
QString label;
};
DECLARE_BUILTIN_FUNCTION(AnswerFunction, 0)
@ -154,6 +182,9 @@ class QalculateQtSettings : QObject {
void fetchExchangeRates(int timeout, int n = -1, QWidget *parent = NULL);
bool displayMessages(QWidget *parent);
bool isAnswerVariable(Variable *v);
QString shortcutTypeText(shortcut_type type);
QString shortcutText(int type, const std::string &value);
bool testShortcutValue(int type, QString &value, QWidget *parent = NULL);
void checkVersion(bool force, QWidget *parent);
void autoUpdate(std::string new_version, QWidget *parent);
const char *multiplicationSign(bool units = false);
@ -180,6 +211,7 @@ class QalculateQtSettings : QObject {
int replace_expression;
int default_signed = -1, default_bits = -1;
int keypad_type;
bool hide_numpad;
bool keep_function_dialog_open;
bool save_defs_on_exit, save_mode_on_exit, clear_history_on_exit;
bool rpn_shown;
@ -222,6 +254,8 @@ class QalculateQtSettings : QObject {
std::vector<std::string> favourite_units_pre;
bool default_shortcuts;
std::vector<keyboard_shortcut> keyboard_shortcuts;
int custom_button_columns, custom_button_rows;
std::vector<custom_button> custom_buttons;
bool favourite_functions_changed, favourite_variables_changed, favourite_units_changed;
};

View File

@ -44,6 +44,7 @@
#include <QTableWidget>
#include <QHeaderView>
#include <QDesktopServices>
#include <QClipboard>
#include <QDebug>
#include "qalculatewindow.h"
@ -222,6 +223,35 @@ std::string unhtmlize(std::string str) {
return str;
}
void base_from_string(std::string str, int &base, Number &nbase, bool input_base) {
if(equalsIgnoreCase(str, "golden") || equalsIgnoreCase(str, "golden ratio") || str == "φ") base = BASE_GOLDEN_RATIO;
else if(equalsIgnoreCase(str, "roman") || equalsIgnoreCase(str, "roman")) base = BASE_ROMAN_NUMERALS;
else if(!input_base && (equalsIgnoreCase(str, "time") || equalsIgnoreCase(str, "time"))) base = BASE_TIME;
else if(str == "b26" || str == "B26") base = BASE_BIJECTIVE_26;
else if(equalsIgnoreCase(str, "unicode")) base = BASE_UNICODE;
else if(equalsIgnoreCase(str, "supergolden") || equalsIgnoreCase(str, "supergolden ratio") || str == "ψ") base = BASE_SUPER_GOLDEN_RATIO;
else if(equalsIgnoreCase(str, "pi") || str == "π") base = BASE_PI;
else if(str == "e") base = BASE_E;
else if(str == "sqrt(2)" || str == "sqrt 2" || str == "sqrt2" || str == "2") base = BASE_SQRT2;
else {
EvaluationOptions eo = settings->evalops;
eo.parse_options.base = 10;
MathStructure m;
eo.approximation = APPROXIMATION_TRY_EXACT;
CALCULATOR->beginTemporaryStopMessages();
CALCULATOR->calculate(&m, CALCULATOR->unlocalizeExpression(str, eo.parse_options), 350, eo);
if(CALCULATOR->endTemporaryStopMessages()) {
base = BASE_CUSTOM;
nbase.clear();
} else if(m.isInteger() && m.number() >= 2 && m.number() <= 36) {
base = m.number().intValue();
} else {
base = BASE_CUSTOM;
nbase = m.number();
}
}
}
class QalculateDockWidget : public QDockWidget {
public:
@ -313,21 +343,10 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
QFont appfont;
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);
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});
addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(approximateResult()));
menuAction = new QToolButton(this); menuAction->setIcon(LOAD_ICON("menu")); menuAction->setText(tr("Menu"));
menuAction->setShortcut(Qt::Key_F10); menuAction->setToolTip(tr("Menu (%1)").arg(menuAction->shortcut().toString(QKeySequence::NativeText)));
menuAction->setPopupMode(QToolButton::InstantPopup);
menuAction_t = new QToolButton(this); menuAction_t->setIcon(LOAD_ICON("menu")); menuAction_t->setText(tr("Menu"));
menuAction_t->setPopupMode(QToolButton::InstantPopup);
menu = new QMenu(this);
menuAction->setMenu(menu);
menuAction_t->setMenu(menu);
menu2 = menu;
menu = menu2->addMenu(tr("New"));
newFunctionAction = menu->addAction(tr("Function…"), this, SLOT(newFunction()));
@ -368,11 +387,10 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
menu->addSeparator();
quitAction = menu->addAction(tr("Quit"), qApp, SLOT(closeAllWindows()));
modeAction = new QToolButton(this); modeAction->setIcon(LOAD_ICON("configure")); modeAction->setText(tr("Mode"));
modeAction->setShortcut(Qt::ALT | Qt::Key_M); modeAction->setToolTip(tr("Mode (%1)").arg(modeAction->shortcut().toString(QKeySequence::NativeText)));
modeAction->setPopupMode(QToolButton::InstantPopup);
modeAction_t = new QToolButton(this); modeAction_t->setIcon(LOAD_ICON("configure")); modeAction_t->setText(tr("Mode"));
modeAction_t->setPopupMode(QToolButton::InstantPopup);
menu = new QMenu(this);
modeAction->setMenu(menu);
modeAction_t->setMenu(menu);
ADD_SECTION(tr("General Display Mode"));
QFontMetrics fm1(settings->use_custom_app_font ? appfont : menu->font());
@ -380,26 +398,26 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
w = fm1.boundingRect(tr("General Display Mode")).width() * 1.5;
group = new QActionGroup(this); group->setObjectName("group_general");
action = menu->addAction(tr("Normal"), this, SLOT(normalActivated())); action->setCheckable(true); group->addAction(action);
action->setToolTip("500 000<br>5 × 10<sup>14</sup><br>50 km/s<br>y x<br>erf(10) ≈ 1.000 000 000");
action->setToolTip("500 000<br>5 × 10<sup>14</sup><br>50 km/s<br>y x<br>erf(10) ≈ 1.000 000 000"); normalAction = action;
if(settings->printops.min_exp == EXP_PRECISION) action->setChecked(true);
action = menu->addAction(tr("Scientific"), this, SLOT(scientificActivated())); action->setCheckable(true); group->addAction(action);
action->setToolTip("5 × 10<sup>5</sup><br>5 × 10<sup>4</sup> m·s<sup>1</sup><br>y + x<br>erf(10) ≈ 1.000 000 000");
action->setToolTip("5 × 10<sup>5</sup><br>5 × 10<sup>4</sup> m·s<sup>1</sup><br>y + x<br>erf(10) ≈ 1.000 000 000"); sciAction = action;
if(settings->printops.min_exp == EXP_SCIENTIFIC) action->setChecked(true);
action = menu->addAction(tr("Engineering"), this, SLOT(engineeringActivated())); action->setCheckable(true); group->addAction(action);
action->setToolTip("500 × 10<sup>3</sup><br>50 × 10<sup>3</sup> m/s<br>y + x<br>erf(10) ≈ 1.000 000 000");
action->setToolTip("500 × 10<sup>3</sup><br>50 × 10<sup>3</sup> m/s<br>y + x<br>erf(10) ≈ 1.000 000 000"); engAction = action;
if(settings->printops.min_exp == EXP_BASE_3) action->setChecked(true);
action = menu->addAction(tr("Simple"), this, SLOT(simpleActivated())); action->setCheckable(true); group->addAction(action);
action->setToolTip("500 000 000 000 000<br>50 km/s<br>y x<br>erf(10) ≈ 1");
action->setToolTip("500 000 000 000 000<br>50 km/s<br>y x<br>erf(10) ≈ 1"); simpleAction = action;
if(settings->printops.min_exp == EXP_NONE) action->setChecked(true);
ADD_SECTION(tr("Angle Unit"));
w2 = fm1.boundingRect(tr("Angle Unit")).width() * 1.5; if(w2 > w) w = w2;
group = new QActionGroup(this);
action = menu->addAction(tr("Radians"), this, SLOT(radiansActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_radians");
action = menu->addAction(tr("Radians"), this, SLOT(radiansActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_radians"); radAction = action;
if(settings->evalops.parse_options.angle_unit == ANGLE_UNIT_RADIANS) action->setChecked(true);
action = menu->addAction(tr("Degrees"), this, SLOT(degreesActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_degrees");
action = menu->addAction(tr("Degrees"), this, SLOT(degreesActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_degrees"); degAction = action;
if(settings->evalops.parse_options.angle_unit == ANGLE_UNIT_DEGREES) action->setChecked(true);
action = menu->addAction(tr("Gradians"), this, SLOT(gradiansActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_gradians");
action = menu->addAction(tr("Gradians"), this, SLOT(gradiansActivated())); action->setCheckable(true); group->addAction(action); action->setObjectName("action_gradians"); graAction = action;
if(settings->evalops.parse_options.angle_unit == ANGLE_UNIT_GRADIANS) action->setChecked(true);
ADD_SECTION(tr("Approximation"));
@ -491,7 +509,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
aww = new QWidget(this);
aw->setDefaultWidget(aww);
awl = new QHBoxLayout(aww);
QSpinBox *customOutputBaseEdit = new QSpinBox(this);
customOutputBaseEdit = new QSpinBox(this);
customOutputBaseEdit->setRange(INT_MIN, INT_MAX);
customOutputBaseEdit->setValue(settings->printops.base == BASE_CUSTOM ? (CALCULATOR->customOutputBase().isZero() ? 10 : CALCULATOR->customOutputBase().intValue()) : ((settings->printops.base >= 2 && settings->printops.base <= 36) ? settings->printops.base : 10)); customOutputBaseEdit->setObjectName("spinbox_outbase");
customOutputBaseEdit->setAlignment(Qt::AlignRight);
@ -538,7 +556,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
aww = new QWidget(this);
aw->setDefaultWidget(aww);
awl = new QHBoxLayout(aww);
QSpinBox *customInputBaseEdit = new QSpinBox(this);
customInputBaseEdit = new QSpinBox(this);
customInputBaseEdit->setRange(INT_MIN, INT_MAX);
customInputBaseEdit->setValue(settings->evalops.parse_options.base == BASE_CUSTOM ? (CALCULATOR->customInputBase().isZero() ? 10 : CALCULATOR->customInputBase().intValue()) : ((settings->evalops.parse_options.base >= 2 && settings->evalops.parse_options.base <= 36) ? settings->evalops.parse_options.base : 10)); customInputBaseEdit->setObjectName("spinbox_inbase");
customInputBaseEdit->setAlignment(Qt::AlignRight);
@ -577,7 +595,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
menu->addAction(aw);
menu->setMinimumWidth(w);
tb->addWidget(modeAction);
tb->addWidget(modeAction_t);
toAction = new QAction(LOAD_ICON("convert"), tr("Convert"), this);
toAction->setEnabled(false);
@ -614,27 +632,26 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
tb->addAction(basesAction);
keypadAction_t = new QToolButton(this); keypadAction_t->setIcon(LOAD_ICON("keypad")); keypadAction_t->setText(tr("Keypad"));
keypadAction_t->setPopupMode(QToolButton::InstantPopup);
keypadAction = new QAction("Keypad", this);
addAction(keypadAction);
connect(keypadAction, SIGNAL(triggered()), this, SLOT(onKeypadActivated()));
menu = new QMenu(this);
keypadAction_t->setMenu(menu);
group = new QActionGroup(this); group->setObjectName("group_keypad");
action = menu->addAction(tr("General"), this, SLOT(keypadTypeActivated())); action->setCheckable(true); group->addAction(action);
action->setData(KEYPAD_GENERAL);
action->setData(KEYPAD_GENERAL); gKeypadAction = action;
action = menu->addAction(tr("Programming"), this, SLOT(keypadTypeActivated())); action->setCheckable(true); group->addAction(action);
action->setData(KEYPAD_PROGRAMMING);
action->setData(KEYPAD_PROGRAMMING); pKeypadAction = action;
action = menu->addAction(tr("Algebra"), this, SLOT(keypadTypeActivated())); action->setCheckable(true); group->addAction(action);
action->setData(KEYPAD_ALGEBRA);
action->setData(KEYPAD_ALGEBRA); xKeypadAction = action;
action = menu->addAction(tr("Custom"), this, SLOT(keypadTypeActivated())); action->setCheckable(true); group->addAction(action);
action->setData(KEYPAD_CUSTOM);
action->setData(KEYPAD_CUSTOM); cKeypadAction = action;
action = menu->addAction(tr("None"), this, SLOT(keypadTypeActivated())); action->setCheckable(true); group->addAction(action);
action->setData(-1); action->setChecked(true);
action->setData(-1); action->setChecked(true); keypadAction = action;
menu->addSeparator();
action = menu->addAction(tr("Hide Number Pad"), this, SLOT(hideNumpad(bool))); action->setCheckable(true); action->setChecked(settings->hide_numpad);
tb->addWidget(keypadAction_t);
QWidget *spacer = new QWidget();
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
tb->addWidget(spacer);
tb->addWidget(menuAction);
tb->addWidget(menuAction_t);
expressionEdit = new ExpressionEdit(this, tb);
QFont font = expressionEdit->font();
@ -731,25 +748,25 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
rpnTB->setToolButtonStyle(Qt::ToolButtonIconOnly);
rpnTB->setOrientation(Qt::Vertical);
rpnBox->addWidget(rpnTB);
rpnUpAction = new QAction(LOAD_ICON("go-up"), "RPN Up", this); rpnUpAction->setShortcut(Qt::CTRL | Qt::Key_Up); rpnUpAction->setEnabled(false); rpnUpAction->setToolTip(tr("Rotate the stack or move the selected register up (%1)").arg(rpnUpAction->shortcut().toString(QKeySequence::NativeText)));
connect(rpnUpAction, SIGNAL(triggered(bool)), this, SLOT(registerUp())); rpnUpAction->setShortcutContext(Qt::ApplicationShortcut);
rpnUpAction = new QAction(LOAD_ICON("go-up"), "RPN Up", this); rpnUpAction->setEnabled(false);
connect(rpnUpAction, SIGNAL(triggered(bool)), this, SLOT(registerUp()));
rpnTB->addAction(rpnUpAction);
rpnDownAction = new QAction(LOAD_ICON("go-down"), "RPN Down", this); rpnDownAction->setShortcut(Qt::CTRL | Qt::Key_Down); rpnDownAction->setEnabled(false); rpnDownAction->setToolTip(tr("Rotate the stack or move the selected register down (%1)").arg(rpnDownAction->shortcut().toString(QKeySequence::NativeText))); rpnDownAction->setShortcutContext(Qt::ApplicationShortcut);
rpnDownAction = new QAction(LOAD_ICON("go-down"), "RPN Down", this); rpnDownAction->setEnabled(false);
connect(rpnDownAction, SIGNAL(triggered(bool)), this, SLOT(registerDown()));
rpnTB->addAction(rpnDownAction);
rpnSwapAction = new QAction(LOAD_ICON("rpn-swap"), "RPN Swap", this); rpnSwapAction->setShortcut(Qt::CTRL | Qt::Key_Right); rpnSwapAction->setEnabled(false); rpnSwapAction->setToolTip(tr("Swap the top two values or move the selected value to the top of the stack (%1)").arg(rpnSwapAction->shortcut().toString(QKeySequence::NativeText))); rpnSwapAction->setShortcutContext(Qt::ApplicationShortcut);
rpnSwapAction = new QAction(LOAD_ICON("rpn-swap"), "RPN Swap", this); rpnSwapAction->setEnabled(false);
connect(rpnSwapAction, SIGNAL(triggered(bool)), this, SLOT(registerSwap()));
rpnTB->addAction(rpnSwapAction);
rpnCopyAction = new QAction(LOAD_ICON("edit-copy"), "RPN Copy", this); rpnCopyAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_C); rpnCopyAction->setEnabled(false); rpnCopyAction->setToolTip(tr("Copy the selected or top value to the top of the stack (%1)").arg(rpnCopyAction->shortcut().toString(QKeySequence::NativeText))); rpnCopyAction->setShortcutContext(Qt::ApplicationShortcut);
rpnCopyAction = new QAction(LOAD_ICON("edit-copy"), "RPN Copy", this); rpnCopyAction->setEnabled(false);
connect(rpnCopyAction, SIGNAL(triggered(bool)), this, SLOT(copyRegister()));
rpnTB->addAction(rpnCopyAction);
rpnLastxAction = new QAction(LOAD_ICON("edit-undo"), "RPN LastX", this); rpnLastxAction->setShortcut(Qt::CTRL | Qt::Key_Left); rpnLastxAction->setEnabled(false); rpnLastxAction->setToolTip(tr("Enter the top value from before the last numeric operation (%1)").arg(rpnLastxAction->shortcut().toString(QKeySequence::NativeText))); rpnLastxAction->setShortcutContext(Qt::ApplicationShortcut);
rpnLastxAction = new QAction(LOAD_ICON("edit-undo"), "RPN LastX", this); rpnLastxAction->setEnabled(false);
connect(rpnLastxAction, SIGNAL(triggered(bool)), this, SLOT(rpnLastX()));
rpnTB->addAction(rpnLastxAction);
rpnDeleteAction = new QAction(LOAD_ICON("edit-delete"), "RPN Delete", this); rpnDeleteAction->setShortcut(Qt::CTRL | Qt::Key_Delete); rpnDeleteAction->setEnabled(false); rpnDeleteAction->setToolTip(tr("Delete the top or selected value (%1)").arg(rpnDeleteAction->shortcut().toString(QKeySequence::NativeText))); rpnDeleteAction->setShortcutContext(Qt::ApplicationShortcut);
rpnDeleteAction = new QAction(LOAD_ICON("edit-delete"), "RPN Delete", this); rpnDeleteAction->setEnabled(false);
connect(rpnDeleteAction, SIGNAL(triggered(bool)), this, SLOT(deleteRegister()));
rpnTB->addAction(rpnDeleteAction);
rpnClearAction = new QAction(LOAD_ICON("edit-clear"), "RPN Clear", this); rpnClearAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Delete); rpnClearAction->setEnabled(false); rpnClearAction->setToolTip(tr("Clear the RPN stack (%1)").arg(rpnClearAction->shortcut().toString(QKeySequence::NativeText))); rpnClearAction->setShortcutContext(Qt::ApplicationShortcut);
rpnClearAction = new QAction(LOAD_ICON("edit-clear"), "RPN Clear", this); rpnClearAction->setEnabled(false);
connect(rpnClearAction, SIGNAL(triggered(bool)), this, SLOT(clearStack()));
rpnTB->addAction(rpnClearAction);
rpnDock->setWidget(rpnWidget);
@ -785,7 +802,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
if(settings->use_custom_expression_font) {QFont font; font.fromString(QString::fromStdString(settings->custom_expression_font)); expressionEdit->setFont(font);}
if(settings->use_custom_result_font) {QFont font; font.fromString(QString::fromStdString(settings->custom_result_font)); historyView->setFont(font);}
updateShortcuts(true);
loadShortcuts();
connect(historyView, SIGNAL(insertTextRequested(std::string)), this, SLOT(onInsertTextRequested(std::string)));
connect(historyView, SIGNAL(insertValueRequested(int)), this, SLOT(onInsertValueRequested(int)));
@ -798,6 +815,7 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
connect(basesDock, SIGNAL(visibilityChanged(bool)), this, SLOT(onBasesVisibilityChanged(bool)));
connect(rpnDock, SIGNAL(visibilityChanged(bool)), this, SLOT(onRPNVisibilityChanged(bool)));
connect(keypad, SIGNAL(expressionCalculationUpdated(int)), this, SLOT(expressionCalculationUpdated(int)));
connect(keypad, SIGNAL(shortcutClicked(int, const QString&)), this, SLOT(shortcutClicked(int, const QString&)));
connect(keypad, SIGNAL(symbolClicked(const QString&)), this, SLOT(onSymbolClicked(const QString&)));
connect(keypad, SIGNAL(operatorClicked(const QString&)), this, SLOT(onOperatorClicked(const QString&)));
connect(keypad, SIGNAL(functionClicked(MathFunction*)), this, SLOT(onFunctionClicked(MathFunction*)));
@ -842,71 +860,448 @@ QalculateWindow::QalculateWindow() : QMainWindow() {
}
QalculateWindow::~QalculateWindow() {}
void QalculateWindow::updateShortcuts(bool initial) {
QList<QKeySequence> shortcuts;
if(!initial) {
functionsAction->setShortcut(QKeySequence());
unitsAction->setShortcut(QKeySequence());
variablesAction->setShortcut(QKeySequence());
datasetsAction->setShortcut(QKeySequence());
plotAction->setShortcut(QKeySequence());
fpAction->setShortcut(QKeySequence());
calendarsAction->setShortcut(QKeySequence());
periodicTableAction->setShortcut(QKeySequence());
percentageAction->setShortcut(QKeySequence());
helpAction->setShortcut(QKeySequence());
quitAction->setShortcut(QKeySequence());
toAction->setShortcut(QKeySequence());
basesAction->setShortcut(QKeySequence());
keypadAction->setShortcut(QKeySequence());
}
void QalculateWindow::loadShortcuts() {
if(plotAction_t) plotAction_t->setToolTip(tr("Plot Functions/Data"));
storeAction->setToolTip(tr("Store"));
unitsAction_t->setToolTip(tr("Units"));
functionsAction_t->setToolTip(tr("Functions"));
basesAction->setToolTip(tr("Number Bases"));
toAction->setToolTip(tr("Convert"));
menuAction_t->setToolTip(tr("Menu"));
modeAction_t->setToolTip(tr("Mode"));
rpnUpAction->setToolTip(tr("Rotate the stack or move the selected register up"));
rpnDownAction->setToolTip(tr("Rotate the stack or move the selected register down"));
rpnSwapAction->setToolTip(tr("Swap the top two values or move the selected value to the top of the stack"));
rpnDeleteAction->setToolTip(tr("Delete the top or selected value"));
rpnLastxAction->setToolTip(tr("Enter the top value from before the last numeric operation"));
rpnCopyAction->setToolTip(tr("Copy the selected or top value to the top of the stack"));
rpnClearAction->setToolTip(tr("Clear the RPN stack"));
for(size_t i = 0; i < settings->keyboard_shortcuts.size(); i++) {
keyboard_shortcut ks = settings->keyboard_shortcuts[i];
QAction *action = NULL;
switch(ks.type) {
case SHORTCUT_TYPE_MANAGE_FUNCTIONS: {action = functionsAction; break;}
case SHORTCUT_TYPE_MANAGE_VARIABLES: {action = variablesAction; break;}
case SHORTCUT_TYPE_MANAGE_UNITS: {action = unitsAction; break;}
case SHORTCUT_TYPE_MANAGE_DATA_SETS: {action = datasetsAction; break;}
case SHORTCUT_TYPE_FLOATING_POINT: {action = fpAction; break;}
case SHORTCUT_TYPE_CALENDARS: {action = calendarsAction; break;}
case SHORTCUT_TYPE_PERIODIC_TABLE: {action = periodicTableAction; break;}
case SHORTCUT_TYPE_PERCENTAGE_TOOL: {action = percentageAction; break;}
case SHORTCUT_TYPE_NUMBER_BASES: {action = basesAction; break;}
case SHORTCUT_TYPE_CONVERT: {action = toAction; break;}
case SHORTCUT_TYPE_RPN_MODE: {action = rpnAction; break;}
case SHORTCUT_TYPE_CHAIN_MODE: {action = chainAction; break;}
case SHORTCUT_TYPE_KEYPAD: {action = keypadAction; break;}
case SHORTCUT_TYPE_STORE: {action = storeAction; break;}
case SHORTCUT_TYPE_PLOT: {action = plotAction; break;}
case SHORTCUT_TYPE_HELP: {action = helpAction; break;}
case SHORTCUT_TYPE_QUIT: {action = quitAction; break;}
default: {}
keyboardShortcutAdded(&settings->keyboard_shortcuts[i]);
}
}
void QalculateWindow::keyboardShortcutRemoved(keyboard_shortcut *ks) {
if(!ks->action) return;
if(ks->new_action) {
removeAction(ks->action);
ks->action->deleteLater();
return;
}
QList<QKeySequence> shortcuts = ks->action->shortcuts();
shortcuts.removeAll(QKeySequence(ks->key));
ks->action->setShortcuts(shortcuts);
if(ks->type == SHORTCUT_TYPE_PLOT && plotAction_t) {
plotAction_t->setToolTip(tr("Plot Functions/Data") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_STORE) {
storeAction->setToolTip(tr("Store") + QString("(%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_MANAGE_UNITS) {
unitsAction_t->setToolTip(tr("Units") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_MANAGE_FUNCTIONS) {
functionsAction_t->setToolTip(tr("Functions") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_NUMBER_BASES) {
basesAction->setToolTip(tr("Number Bases") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_CONVERT) {
toAction->setToolTip(tr("Convert") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_MODE) {
modeAction_t->setToolTip(tr("Mode") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_MENU) {
menuAction_t->setToolTip(tr("Menu") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_RPN_UP) {
rpnUpAction->setToolTip(tr("Rotate the stack or move the selected register up") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_RPN_DOWN) {
rpnDownAction->setToolTip(tr("Rotate the stack or move the selected register down") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_RPN_SWAP) {
rpnSwapAction->setToolTip(tr("Swap the top two values or move the selected value to the top of the stack") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_RPN_DELETE) {
rpnDeleteAction->setToolTip(tr("Delete the top or selected value") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_RPN_LASTX) {
rpnLastxAction->setToolTip(tr("Enter the top value from before the last numeric operation") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_RPN_COPY) {
rpnCopyAction->setToolTip(tr("Copy the selected or top value to the top of the stack") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
} else if(ks->type == SHORTCUT_TYPE_RPN_CLEAR) {
rpnClearAction->setToolTip(tr("Clear the RPN stack") + (shortcuts.isEmpty() ? QString() : QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText))));
}
}
void QalculateWindow::keyboardShortcutAdded(keyboard_shortcut *ks) {
QAction *action = NULL;
switch(ks->type) {
case SHORTCUT_TYPE_MANAGE_FUNCTIONS: {action = functionsAction; break;}
case SHORTCUT_TYPE_MANAGE_VARIABLES: {action = variablesAction; break;}
case SHORTCUT_TYPE_MANAGE_UNITS: {action = unitsAction; break;}
case SHORTCUT_TYPE_MANAGE_DATA_SETS: {action = datasetsAction; break;}
case SHORTCUT_TYPE_FLOATING_POINT: {action = fpAction; break;}
case SHORTCUT_TYPE_CALENDARS: {action = calendarsAction; break;}
case SHORTCUT_TYPE_PERIODIC_TABLE: {action = periodicTableAction; break;}
case SHORTCUT_TYPE_PERCENTAGE_TOOL: {action = percentageAction; break;}
case SHORTCUT_TYPE_NUMBER_BASES: {action = basesAction; break;}
case SHORTCUT_TYPE_CONVERT: {action = toAction; break;}
case SHORTCUT_TYPE_RPN_MODE: {action = rpnAction; break;}
case SHORTCUT_TYPE_DEGREES: {action = degAction; break;}
case SHORTCUT_TYPE_RADIANS: {action = radAction; break;}
case SHORTCUT_TYPE_GRADIANS: {action = graAction; break;}
case SHORTCUT_TYPE_NORMAL_NOTATION: {action = normalAction; break;}
case SHORTCUT_TYPE_SCIENTIFIC_NOTATION: {action = sciAction; break;}
case SHORTCUT_TYPE_ENGINEERING_NOTATION: {action = engAction; break;}
case SHORTCUT_TYPE_SIMPLE_NOTATION: {action = simpleAction; break;}
case SHORTCUT_TYPE_CHAIN_MODE: {action = chainAction; break;}
case SHORTCUT_TYPE_KEYPAD: {action = keypadAction; break;}
case SHORTCUT_TYPE_GENERAL_KEYPAD: {action = gKeypadAction; break;}
case SHORTCUT_TYPE_PROGRAMMING_KEYPAD: {action = pKeypadAction; break;}
case SHORTCUT_TYPE_ALGEBRA_KEYPAD: {action = xKeypadAction; break;}
case SHORTCUT_TYPE_CUSTOM_KEYPAD: {action = cKeypadAction; break;}
case SHORTCUT_TYPE_STORE: {action = storeAction; break;}
case SHORTCUT_TYPE_NEW_VARIABLE: {action = newVariableAction; break;}
case SHORTCUT_TYPE_NEW_FUNCTION: {action = newFunctionAction; break;}
case SHORTCUT_TYPE_PLOT: {action = plotAction; break;}
case SHORTCUT_TYPE_UPDATE_EXRATES: {action = exratesAction; break;}
case SHORTCUT_TYPE_HELP: {action = helpAction; break;}
case SHORTCUT_TYPE_QUIT: {action = quitAction; break;}
case SHORTCUT_TYPE_RPN_UP: {action = rpnUpAction; break;}
case SHORTCUT_TYPE_RPN_DOWN: {action = rpnDownAction; break;}
case SHORTCUT_TYPE_RPN_SWAP: {action = rpnSwapAction; break;}
case SHORTCUT_TYPE_RPN_LASTX: {action = rpnLastxAction; break;}
case SHORTCUT_TYPE_RPN_COPY: {action = rpnCopyAction; break;}
case SHORTCUT_TYPE_RPN_DELETE: {action = rpnDeleteAction; break;}
case SHORTCUT_TYPE_RPN_CLEAR: {action = rpnClearAction; break;}
default: {}
}
if(action) {
ks->new_action = false;
QList<QKeySequence> shortcuts = action->shortcuts();
shortcuts << QKeySequence(ks->key);
action->setShortcuts(shortcuts);
if(ks->type == SHORTCUT_TYPE_PLOT) {
if(plotAction_t) plotAction_t->setToolTip(tr("Plot Functions/Data") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_STORE) {
storeAction->setToolTip(tr("Store") + QString("(%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_MANAGE_UNITS) {
unitsAction_t->setToolTip(tr("Units") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_MANAGE_FUNCTIONS) {
functionsAction_t->setToolTip(tr("Functions") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_NUMBER_BASES) {
basesAction->setToolTip(tr("Number Bases") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_CONVERT) {
toAction->setToolTip(tr("Convert") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_MODE) {
modeAction_t->setToolTip(tr("Mode") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_MENU) {
menuAction_t->setToolTip(tr("Menu") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_RPN_UP) {
rpnUpAction->setToolTip(tr("Rotate the stack or move the selected register up") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_RPN_DOWN) {
rpnDownAction->setToolTip(tr("Rotate the stack or move the selected register down") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_RPN_SWAP) {
rpnSwapAction->setToolTip(tr("Swap the top two values or move the selected value to the top of the stack") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_RPN_DELETE) {
rpnDeleteAction->setToolTip(tr("Delete the top or selected value") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_RPN_LASTX) {
rpnLastxAction->setToolTip(tr("Enter the top value from before the last numeric operation") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_RPN_COPY) {
rpnCopyAction->setToolTip(tr("Copy the selected or top value to the top of the stack") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks->type == SHORTCUT_TYPE_RPN_CLEAR) {
rpnClearAction->setToolTip(tr("Clear the RPN stack") + QString(" (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
}
if(action) {
shortcuts = action->shortcuts();
shortcuts << QKeySequence(ks.key);
action->setShortcuts(shortcuts);
if(ks.type == SHORTCUT_TYPE_PLOT) {
if(plotAction_t) plotAction_t->setToolTip(tr("Plot Functions/Data (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks.type == SHORTCUT_TYPE_STORE) {
storeAction->setToolTip(tr("Store (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks.type == SHORTCUT_TYPE_MANAGE_UNITS) {
unitsAction_t->setToolTip(tr("Units (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks.type == SHORTCUT_TYPE_MANAGE_FUNCTIONS) {
functionsAction_t->setToolTip(tr("Functions (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks.type == SHORTCUT_TYPE_NUMBER_BASES) {
basesAction->setToolTip(tr("Number Bases (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else if(ks.type == SHORTCUT_TYPE_CONVERT) {
toAction->setToolTip(tr("Convert (%1)").arg(shortcuts[0].toString(QKeySequence::NativeText)));
} else {
ks->new_action = true;
action = new QAction();
action->setShortcut(ks->key);
action->setData(QVariant::fromValue((void*) ks));
addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(shortcutActivated()));
}
ks->action = action;
}
void QalculateWindow::shortcutActivated() {
keyboard_shortcut *ks = (keyboard_shortcut*) qobject_cast<QAction*>(sender())->data().value<void*>();
triggerShortcut(ks->type, ks->value);
}
void QalculateWindow::shortcutClicked(int type, const QString &value) {
triggerShortcut((shortcut_type) type, value.toStdString());
}
bool contains_prefix(const MathStructure &m) {
if(m.isUnit() && (m.prefix() || m.unit()->subtype() == SUBTYPE_COMPOSITE_UNIT)) return true;
for(size_t i = 0; i < m.size(); i++) {
if(contains_prefix(m[i])) return true;
}
return false;
}
void QalculateWindow::triggerShortcut(int type, const std::string &value) {
switch(type) {
case SHORTCUT_TYPE_NEGATE: {
negate();
break;
}
case SHORTCUT_TYPE_INVERT: {
onFunctionClicked(CALCULATOR->getActiveFunction("inv"));
break;
}
case SHORTCUT_TYPE_APPROXIMATE: {
approximateResult();
break;
}
case SHORTCUT_TYPE_MODE: {
modeAction_t->showMenu();
break;
}
case SHORTCUT_TYPE_MENU: {
menuAction_t->showMenu();
break;
}
case SHORTCUT_TYPE_FUNCTION: {
onFunctionClicked(CALCULATOR->getActiveFunction(value));
break;
}
case SHORTCUT_TYPE_FUNCTION_WITH_DIALOG: {
insertFunction(CALCULATOR->getActiveFunction(value), this);
break;
}
case SHORTCUT_TYPE_VARIABLE: {
onVariableClicked(CALCULATOR->getActiveVariable(value));
break;
}
case SHORTCUT_TYPE_UNIT: {
onUnitClicked(CALCULATOR->getActiveUnit(value));
break;
}
case SHORTCUT_TYPE_OPERATOR: {
onOperatorClicked(QString::fromStdString(value));
break;
}
case SHORTCUT_TYPE_TEXT: {
onSymbolClicked(QString::fromStdString(value));
break;
}
case SHORTCUT_TYPE_DATE: {
expressionEdit->insertDate();
break;
}
case SHORTCUT_TYPE_MATRIX: {
expressionEdit->insertMatrix();
break;
}
case SHORTCUT_TYPE_SMART_PARENTHESES: {
expressionEdit->smartParentheses();
break;
}
case SHORTCUT_TYPE_CONVERT_TO: {
ParseOptions pa = settings->evalops.parse_options; pa.base = 10;
executeCommand(COMMAND_CONVERT_STRING, true, CALCULATOR->unlocalizeExpression(value, pa));
break;
}
case SHORTCUT_TYPE_OPTIMAL_UNIT: {
executeCommand(COMMAND_CONVERT_OPTIMAL);
break;
}
case SHORTCUT_TYPE_BASE_UNITS: {
executeCommand(COMMAND_CONVERT_BASE);
break;
}
case SHORTCUT_TYPE_OPTIMAL_PREFIX: {
to_prefix = 0;
bool b_use_unit_prefixes = settings->printops.use_unit_prefixes;
bool b_use_prefixes_for_all_units = settings->printops.use_prefixes_for_all_units;
if(contains_prefix(*mstruct)) {
mstruct->unformat(settings->evalops);
executeCommand(COMMAND_CALCULATE, false);
}
settings->printops.use_unit_prefixes = true;
settings->printops.use_prefixes_for_all_units = true;
setResult(NULL, true, false, true);
settings->printops.use_unit_prefixes = b_use_unit_prefixes;
settings->printops.use_prefixes_for_all_units = b_use_prefixes_for_all_units;
break;
}
case SHORTCUT_TYPE_TO_NUMBER_BASE: {
int save_base = settings->printops.base;
Number save_nbase = CALCULATOR->customOutputBase();
to_base = 0;
to_bits = 0;
Number nbase;
base_from_string(value, settings->printops.base, nbase);
CALCULATOR->setCustomOutputBase(nbase);
resultFormatUpdated();
settings->printops.base = save_base;
CALCULATOR->setCustomOutputBase(save_nbase);
break;
}
case SHORTCUT_TYPE_FACTORIZE: {
executeCommand(COMMAND_FACTORIZE);
break;
}
case SHORTCUT_TYPE_EXPAND: {
executeCommand(COMMAND_EXPAND);
break;
}
case SHORTCUT_TYPE_PARTIAL_FRACTIONS: {
executeCommand(COMMAND_EXPAND_PARTIAL_FRACTIONS);
break;
}
case SHORTCUT_TYPE_INPUT_BASE: {
Number nbase;
base_from_string(value, settings->evalops.parse_options.base, nbase, true);
QAction *action = find_child_data(this, "group_inbase", settings->evalops.parse_options.base);
if(!action) action = customInputBaseAction;
if(action) action->setChecked(true);
if(settings->printops.base == BASE_CUSTOM) CALCULATOR->setCustomInputBase(nbase);
if(action == customInputBaseAction) customInputBaseEdit->setValue(settings->evalops.parse_options.base == BASE_CUSTOM ? CALCULATOR->customInputBase().intValue() : settings->evalops.parse_options.base);
expressionFormatUpdated(false);
keypad->updateBase();
break;
}
case SHORTCUT_TYPE_OUTPUT_BASE: {
Number nbase;
base_from_string(value, settings->printops.base, nbase, false);
to_base = 0;
to_bits = 0;
QAction *action = find_child_data(this, "group_outbase", settings->printops.base);
if(!action) action = customOutputBaseAction;
if(action) action->setChecked(true);
if(settings->printops.base == BASE_CUSTOM) CALCULATOR->setCustomOutputBase(nbase);
if(action == customOutputBaseAction) customOutputBaseEdit->setValue(settings->printops.base == BASE_CUSTOM ? CALCULATOR->customOutputBase().intValue() : settings->printops.base);
resultFormatUpdated();
keypad->updateBase();
break;
}
case SHORTCUT_TYPE_HISTORY_SEARCH: {
historyView->editFind();
break;
}
case SHORTCUT_TYPE_MEMORY_CLEAR: {
onMCClicked();
break;
}
case SHORTCUT_TYPE_MEMORY_RECALL: {
onMRClicked();
break;
}
case SHORTCUT_TYPE_MEMORY_STORE: {
onMSClicked();
break;
}
case SHORTCUT_TYPE_MEMORY_ADD: {
onMPlusClicked();
break;
}
case SHORTCUT_TYPE_MEMORY_SUBTRACT: {
onMMinusClicked();
break;
}
case SHORTCUT_TYPE_COPY_RESULT: {
if(!settings->v_result.empty()) {
QApplication::clipboard()->setText(QString::fromStdString(unhtmlize(settings->v_result[settings->v_result.size() - 1][0])));
}
break;
}
case SHORTCUT_TYPE_INSERT_RESULT: {
if(!settings->v_result.empty()) {
expressionEdit->blockCompletion();
expressionEdit->insertPlainText(QString::fromStdString(unhtmlize(settings->v_result[settings->v_result.size() - 1][0])));
if(!expressionEdit->hasFocus()) expressionEdit->setFocus();
expressionEdit->blockCompletion(false);
}
break;
}
case SHORTCUT_TYPE_ALWAYS_ON_TOP: {
settings->always_on_top = !settings->always_on_top;
onAlwaysOnTopChanged();
break;
}
case SHORTCUT_TYPE_COMPLETE: {
expressionEdit->completeOrActivateFirst();
break;
}
case SHORTCUT_TYPE_EXPRESSION_CLEAR: {
expressionEdit->clear();
break;
}
case SHORTCUT_TYPE_EXPRESSION_DELETE: {
expressionEdit->textCursor().deleteChar();
break;
}
case SHORTCUT_TYPE_EXPRESSION_BACKSPACE: {
expressionEdit->textCursor().deletePreviousChar();
break;
}
case SHORTCUT_TYPE_EXPRESSION_START: {
expressionEdit->moveCursor(QTextCursor::Start);
break;
}
case SHORTCUT_TYPE_EXPRESSION_END: {
expressionEdit->moveCursor(QTextCursor::End);
break;
}
case SHORTCUT_TYPE_EXPRESSION_RIGHT: {
expressionEdit->moveCursor(QTextCursor::NextCharacter);
break;
}
case SHORTCUT_TYPE_EXPRESSION_LEFT: {
expressionEdit->moveCursor(QTextCursor::PreviousCharacter);
break;
}
case SHORTCUT_TYPE_EXPRESSION_UP: {
expressionEdit->moveCursor(QTextCursor::PreviousRow);
break;
}
case SHORTCUT_TYPE_EXPRESSION_DOWN: {
expressionEdit->moveCursor(QTextCursor::NextRow);
break;
}
case SHORTCUT_TYPE_EXPRESSION_UNDO: {
expressionEdit->editUndo();
break;
}
case SHORTCUT_TYPE_EXPRESSION_REDO: {
expressionEdit->editRedo();
break;
}
case SHORTCUT_TYPE_EXPRESSION_HISTORY_NEXT: {
QKeyEvent e(QEvent::KeyPress, Qt::Key_PageDown, Qt::NoModifier);
expressionEdit->keyPressEvent(&e);
break;
}
case SHORTCUT_TYPE_EXPRESSION_HISTORY_PREVIOUS: {
QKeyEvent e(QEvent::KeyPress, Qt::Key_PageUp, Qt::NoModifier);
expressionEdit->keyPressEvent(&e);
break;
}
case SHORTCUT_TYPE_MANAGE_FUNCTIONS: {functionsAction->trigger(); break;}
case SHORTCUT_TYPE_MANAGE_VARIABLES: {variablesAction->trigger(); break;}
case SHORTCUT_TYPE_MANAGE_UNITS: {unitsAction->trigger(); break;}
case SHORTCUT_TYPE_MANAGE_DATA_SETS: {datasetsAction->trigger(); break;}
case SHORTCUT_TYPE_FLOATING_POINT: {fpAction->trigger(); break;}
case SHORTCUT_TYPE_CALENDARS: {calendarsAction->trigger(); break;}
case SHORTCUT_TYPE_PERIODIC_TABLE: {periodicTableAction->trigger(); break;}
case SHORTCUT_TYPE_PERCENTAGE_TOOL: {percentageAction->trigger(); break;}
case SHORTCUT_TYPE_NUMBER_BASES: {basesAction->trigger(); break;}
case SHORTCUT_TYPE_CONVERT: {toAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_MODE: {rpnAction->trigger(); break;}
case SHORTCUT_TYPE_DEGREES: {degAction->trigger(); break;}
case SHORTCUT_TYPE_RADIANS: {radAction->trigger(); break;}
case SHORTCUT_TYPE_GRADIANS: {graAction->trigger(); break;}
case SHORTCUT_TYPE_NORMAL_NOTATION: {normalAction->trigger(); break;}
case SHORTCUT_TYPE_SCIENTIFIC_NOTATION: {sciAction->trigger(); break;}
case SHORTCUT_TYPE_ENGINEERING_NOTATION: {engAction->trigger(); break;}
case SHORTCUT_TYPE_SIMPLE_NOTATION: {simpleAction->trigger(); break;}
case SHORTCUT_TYPE_CHAIN_MODE: {chainAction->trigger(); break;}
case SHORTCUT_TYPE_KEYPAD: {keypadAction->trigger(); break;}
case SHORTCUT_TYPE_GENERAL_KEYPAD: {gKeypadAction->trigger(); break;}
case SHORTCUT_TYPE_PROGRAMMING_KEYPAD: {pKeypadAction->trigger(); break;}
case SHORTCUT_TYPE_ALGEBRA_KEYPAD: {xKeypadAction->trigger(); break;}
case SHORTCUT_TYPE_CUSTOM_KEYPAD: {cKeypadAction->trigger(); break;}
case SHORTCUT_TYPE_STORE: {storeAction->trigger(); break;}
case SHORTCUT_TYPE_NEW_VARIABLE: {newVariableAction->trigger(); break;}
case SHORTCUT_TYPE_NEW_FUNCTION: {newFunctionAction->trigger(); break;}
case SHORTCUT_TYPE_PLOT: {plotAction->trigger(); break;}
case SHORTCUT_TYPE_UPDATE_EXRATES: {exratesAction->trigger(); break;}
case SHORTCUT_TYPE_HELP: {helpAction->trigger(); break;}
case SHORTCUT_TYPE_QUIT: {quitAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_UP: {rpnUpAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_DOWN: {rpnDownAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_SWAP: {rpnSwapAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_LASTX: {rpnLastxAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_COPY: {rpnCopyAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_DELETE: {rpnDeleteAction->trigger(); break;}
case SHORTCUT_TYPE_RPN_CLEAR: {rpnClearAction->trigger(); break;}
}
}
bool sort_compare_item(ExpressionItem *o1, ExpressionItem *o2) {
@ -1184,7 +1579,7 @@ void QalculateWindow::onFunctionClicked(MathFunction *f) {
if(arg_bits && arg_signed && (f->id() != FUNCTION_ID_CIRCULAR_SHIFT || arg_steps)) {
QDialog *dialog = new QDialog(this);
if(settings->always_on_top) dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
dialog->setWindowTitle(QString::fromStdString(f->title(true)));
dialog->setWindowTitle(QString::fromStdString(f->title(true, settings->printops.use_unicode_signs)));
QVBoxLayout *box = new QVBoxLayout(dialog);
QGridLayout *grid = new QGridLayout();
box->addLayout(grid);
@ -1275,7 +1670,7 @@ void QalculateWindow::onFunctionClicked(MathFunction *f) {
if(arg_n) {
QDialog *dialog = new QDialog(this);
if(settings->always_on_top) dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
dialog->setWindowTitle(QString::fromStdString(f->title(true)));
dialog->setWindowTitle(QString::fromStdString(f->title(true, settings->printops.use_unicode_signs)));
QVBoxLayout *box = new QVBoxLayout(dialog);
QGridLayout *grid = new QGridLayout();
box->addLayout(grid);
@ -1355,12 +1750,14 @@ void QalculateWindow::negate() {
onFunctionClicked(CALCULATOR->getActiveFunction("neg"));
}
void QalculateWindow::onVariableClicked(Variable *v) {
if(!v) return;
expressionEdit->blockCompletion();
expressionEdit->insertPlainText(QString::fromStdString(v->preferredInputName(settings->printops.abbreviate_names, settings->printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name));
if(!expressionEdit->hasFocus()) expressionEdit->setFocus();
expressionEdit->blockCompletion(false);
}
void QalculateWindow::onUnitClicked(Unit *u) {
if(!u) return;
expressionEdit->blockCompletion();
if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
expressionEdit->insertPlainText(QString::fromStdString(((CompositeUnit*) u)->print(true, settings->printops.abbreviate_names, settings->printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit)));
@ -1651,34 +2048,6 @@ int s2b(const std::string &str) {
if(i > 0) return 1;
return 0;
}
void base_from_string(std::string str, int &base, Number &nbase, bool input_base = false) {
if(equalsIgnoreCase(str, "golden") || equalsIgnoreCase(str, "golden ratio") || str == "φ") base = BASE_GOLDEN_RATIO;
else if(equalsIgnoreCase(str, "roman") || equalsIgnoreCase(str, "roman")) base = BASE_ROMAN_NUMERALS;
else if(!input_base && (equalsIgnoreCase(str, "time") || equalsIgnoreCase(str, "time"))) base = BASE_TIME;
else if(str == "b26" || str == "B26") base = BASE_BIJECTIVE_26;
else if(equalsIgnoreCase(str, "unicode")) base = BASE_UNICODE;
else if(equalsIgnoreCase(str, "supergolden") || equalsIgnoreCase(str, "supergolden ratio") || str == "ψ") base = BASE_SUPER_GOLDEN_RATIO;
else if(equalsIgnoreCase(str, "pi") || str == "π") base = BASE_PI;
else if(str == "e") base = BASE_E;
else if(str == "sqrt(2)" || str == "sqrt 2" || str == "sqrt2" || str == "2") base = BASE_SQRT2;
else {
EvaluationOptions eo = settings->evalops;
eo.parse_options.base = 10;
MathStructure m;
eo.approximation = APPROXIMATION_TRY_EXACT;
CALCULATOR->beginTemporaryStopMessages();
CALCULATOR->calculate(&m, CALCULATOR->unlocalizeExpression(str, eo.parse_options), 350, eo);
if(CALCULATOR->endTemporaryStopMessages()) {
base = BASE_CUSTOM;
nbase.clear();
} else if(m.isInteger() && m.number() >= 2 && m.number() <= 36) {
base = m.number().intValue();
} else {
base = BASE_CUSTOM;
nbase = m.number();
}
}
}
void set_assumption(const std::string &str, AssumptionType &at, AssumptionSign &as, bool last_of_two = false) {
if(equalsIgnoreCase(str, "none") || str == "0") {
as = ASSUMPTION_SIGN_UNKNOWN;
@ -4669,7 +5038,7 @@ void QalculateWindow::changeEvent(QEvent *e) {
QColor c = QApplication::palette().base().color();
if(c.red() + c.green() + c.blue() < 255) settings->color = 2;
else settings->color = 1;
menuAction->setIcon(LOAD_ICON("menu"));
menuAction_t->setIcon(LOAD_ICON("menu"));
toAction->setIcon(LOAD_ICON("convert"));
storeAction->setIcon(LOAD_ICON("document-save"));
functionsAction_t->setIcon(LOAD_ICON("function"));
@ -4677,7 +5046,7 @@ void QalculateWindow::changeEvent(QEvent *e) {
if(plotAction_t) plotAction_t->setIcon(LOAD_ICON("plot"));
keypadAction_t->setIcon(LOAD_ICON("keypad"));
basesAction->setIcon(LOAD_ICON("number-bases"));
modeAction->setIcon(LOAD_ICON("configure"));
modeAction_t->setIcon(LOAD_ICON("configure"));
rpnUpAction->setIcon(LOAD_ICON("go-up"));
rpnDownAction->setIcon(LOAD_ICON("go-down"));
rpnSwapAction->setIcon(LOAD_ICON("rpn-swap"));
@ -5013,22 +5382,23 @@ void QalculateWindow::newFunction() {
updateFunctionsMenu();
}
}
void QalculateWindow::hideNumpad(bool b) {
keypad->hideNumpad(b);
}
void QalculateWindow::keypadTypeActivated() {
int v = qobject_cast<QAction*>(sender())->data().toInt();
if(v < 0) {
keypadDock->setVisible(false);
bool b = !keypadDock->isVisible();
keypadDock->setVisible(b);
if(b) keypadDock->raise();
} else {
if(settings->keypad_type == v && keypadDock->isVisible()) v = KEYPAD_GENERAL;
settings->keypad_type = v;
keypad->setKeypadType(v);
keypadDock->setVisible(true);
keypadDock->raise();
}
}
void QalculateWindow::onKeypadActivated() {
bool b = !keypadDock->isVisible();
keypadDock->setVisible(b);
if(b) keypadDock->raise();
}
void QalculateWindow::onKeypadVisibilityChanged(bool b) {
QAction *action = find_child_data(this, "group_keypad", b ? settings->keypad_type : -1);
if(action) action->setChecked(true);

View File

@ -45,6 +45,7 @@ class CalendarConversionDialog;
class QTableWidget;
class QMenu;
struct FunctionDialog;
struct keyboard_shortcut;
class QalculateWindow : public QMainWindow {
@ -89,9 +90,8 @@ class QalculateWindow : public QMainWindow {
QLabel *binEdit, *octEdit, *decEdit, *hexEdit;
QLabel *binLabel, *octLabel, *decLabel, *hexLabel;
QToolBar *tb;
QToolButton *menuAction, *modeAction, *keypadAction_t;
QAction *toAction, *storeAction, *functionsAction_t, *unitsAction_t, *plotAction_t, *basesAction, *customOutputBaseAction, *customInputBaseAction;
QAction *newVariableAction, *newFunctionAction, *variablesAction, *functionsAction, *unitsAction, *datasetsAction, *plotAction, *fpAction, *calendarsAction, *percentageAction, *periodicTableAction, *exratesAction, *quitAction, *helpAction, *keypadAction, *rpnAction, *chainAction;
QToolButton *menuAction_t, *modeAction_t, *keypadAction_t;
QAction *toAction, *storeAction, *functionsAction_t, *unitsAction_t, *plotAction_t, *basesAction, *customOutputBaseAction, *customInputBaseAction, *newVariableAction, *newFunctionAction, *variablesAction, *functionsAction, *unitsAction, *datasetsAction, *plotAction, *fpAction, *calendarsAction, *percentageAction, *periodicTableAction, *exratesAction, *quitAction, *helpAction, *keypadAction, *rpnAction, *chainAction, *gKeypadAction, *pKeypadAction, *xKeypadAction, *cKeypadAction, *radAction, *degAction, *graAction, *normalAction, *sciAction, *engAction, *simpleAction;
QMenu *variablesMenu, *functionsMenu, *unitsMenu;
QAction *assumptionTypeActions[5], *assumptionSignActions[6];
QSpinBox *customOutputBaseEdit, *customInputBaseEdit;
@ -99,7 +99,7 @@ class QalculateWindow : public QMainWindow {
QFont saved_app_font;
QTableWidget *rpnView;
QAction *rpnUpAction, *rpnDownAction, *rpnSwapAction, *rpnCopyAction, *rpnLastxAction, *rpnDeleteAction, *rpnEditAction, *rpnClearAction;
QAction *rpnUpAction, *rpnDownAction, *rpnSwapAction, *rpnCopyAction, *rpnLastxAction, *rpnDeleteAction, *rpnClearAction;
bool send_event;
@ -119,6 +119,8 @@ class QalculateWindow : public QMainWindow {
void RPNRegisterAdded(std::string, int = 0);
void RPNRegisterRemoved(int);
void RPNRegisterChanged(std::string, int);
void triggerShortcut(int, const std::string&);
void loadShortcuts();
protected slots:
@ -149,7 +151,7 @@ class QalculateWindow : public QMainWindow {
void onToActivated();
void onStoreActivated();
void keypadTypeActivated();
void onKeypadActivated();
void hideNumpad(bool);
void onKeypadVisibilityChanged(bool);
void onBasesActivated(bool);
void onBasesVisibilityChanged(bool);
@ -220,6 +222,10 @@ class QalculateWindow : public QMainWindow {
void updateFunctionsMenu();
void updateUnitsMenu();
void updateVariablesMenu();
void shortcutActivated();
void shortcutClicked(int, const QString&);
void keyboardShortcutAdded(keyboard_shortcut *ks);
void keyboardShortcutRemoved(keyboard_shortcut *ks);
public slots:
@ -262,7 +268,6 @@ class QalculateWindow : public QMainWindow {
void checkVersion();
void reportBug();
void help();
void updateShortcuts(bool initial = false);
signals: