From 15c9644008bb56e5e21c97ae61115caca46718ba Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 1 Jun 2020 18:47:54 +0200 Subject: [PATCH] Gui: [skip ci] make QuantitySpinBox to handle disabled keyboard tracking --- src/Gui/QuantitySpinBox.cpp | 111 ++++++++++++++++++++++++++---------- src/Gui/QuantitySpinBox.h | 5 +- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/Gui/QuantitySpinBox.cpp b/src/Gui/QuantitySpinBox.cpp index 2410ed4b6ff0..222f3bfe0b87 100644 --- a/src/Gui/QuantitySpinBox.cpp +++ b/src/Gui/QuantitySpinBox.cpp @@ -63,6 +63,7 @@ class QuantitySpinBoxPrivate public: QuantitySpinBoxPrivate() : validInput(true), + pendingEmit(false), unitValue(0), maximum(DOUBLE_MAX), minimum(-DOUBLE_MAX), @@ -83,6 +84,34 @@ class QuantitySpinBoxPrivate return text; } + bool validate(QString& input, Base::Quantity& result) const + { + bool success = false; + QString tmp = input; + int pos = 0; + QValidator::State state; + Base::Quantity res = validateAndInterpret(tmp, pos, state); + res.setFormat(quantity.getFormat()); + if (state == QValidator::Acceptable) { + success = true; + result = res; + input = tmp; + } + else if (state == QValidator::Intermediate) { + tmp = tmp.trimmed(); + tmp += QLatin1Char(' '); + tmp += unitStr; + Base::Quantity res2 = validateAndInterpret(tmp, pos, state); + res2.setFormat(quantity.getFormat()); + if (state == QValidator::Acceptable) { + success = true; + result = res2; + input = tmp; + } + } + + return success; + } Base::Quantity validateAndInterpret(QString& input, int& pos, QValidator::State& state) const { Base::Quantity res; @@ -224,8 +253,10 @@ class QuantitySpinBoxPrivate QLocale locale; bool validInput; + bool pendingEmit; QString validStr; Base::Quantity quantity; + Base::Quantity cached; Base::Unit unit; double unitValue; QString unitStr; @@ -245,6 +276,8 @@ QuantitySpinBox::QuantitySpinBox(QWidget *parent) this->setContextMenuPolicy(Qt::DefaultContextMenu); QObject::connect(lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(userInput(QString))); + QObject::connect(this, SIGNAL(editingFinished()), + this, SLOT(handlePendingEmit())); defaultPalette = lineEdit()->palette(); @@ -378,6 +411,8 @@ void Gui::QuantitySpinBox::onChange() s << value->getValue(); lineEdit()->setText(getUserString(value->getQuantity())); + handlePendingEmit(); + setReadOnly(true); QPixmap pixmap = getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight)); iconLabel->setPixmap(pixmap); @@ -490,6 +525,7 @@ void QuantitySpinBox::updateText(const Quantity &quant) QString txt = getUserString(quant, dFactor, d->unitStr); d->unitValue = quant.getValue()/dFactor; lineEdit()->setText(txt); + handlePendingEmit(); } Base::Quantity QuantitySpinBox::value() const @@ -536,44 +572,26 @@ void QuantitySpinBox::userInput(const QString & text) { Q_D(QuantitySpinBox); + d->pendingEmit = true; + QString tmp = text; - int pos = 0; - QValidator::State state; - Base::Quantity res = d->validateAndInterpret(tmp, pos, state); - res.setFormat(d->quantity.getFormat()); - if (state == QValidator::Acceptable) { + Base::Quantity res; + if (d->validate(tmp, res)) { + d->validStr = tmp; d->validInput = true; - d->validStr = text; - } - else if (state == QValidator::Intermediate) { - tmp = tmp.trimmed(); - tmp += QLatin1Char(' '); - tmp += d->unitStr; - Base::Quantity res2 = d->validateAndInterpret(tmp, pos, state); - res2.setFormat(d->quantity.getFormat()); - if (state == QValidator::Acceptable) { - d->validInput = true; - d->validStr = tmp; - res = res2; - } - else { - d->validInput = false; - return; - } } else { d->validInput = false; return; } - double factor; - getUserString(res, factor, d->unitStr); - d->unitValue = res.getValue()/factor; - d->quantity = res; - - // signaling - valueChanged(res); - valueChanged(res.getValue()); + if (keyboardTracking()) { + d->cached = res; + handlePendingEmit(); + } + else { + d->cached = res; + } } void QuantitySpinBox::openFormulaDialog() @@ -610,6 +628,23 @@ void QuantitySpinBox::finishFormulaDialog() Q_EMIT showFormulaDialog(false); } +void QuantitySpinBox::handlePendingEmit() +{ + Q_D(QuantitySpinBox); + if (d->pendingEmit) { + double factor; + const Base::Quantity& res = d->cached; + getUserString(res, factor, d->unitStr); + d->unitValue = res.getValue() / factor; + d->quantity = res; + + // signaling + valueChanged(res); + valueChanged(res.getValue()); + d->pendingEmit = false; + } +} + Base::Unit QuantitySpinBox::unit() const { Q_D(const QuantitySpinBox); @@ -765,6 +800,7 @@ void QuantitySpinBox::stepBy(int steps) val = d->minimum; lineEdit()->setText(QString::fromUtf8("%L1 %2").arg(val).arg(d->unitStr)); + handlePendingEmit(); update(); selectNumber(); } @@ -842,6 +878,18 @@ void QuantitySpinBox::showEvent(QShowEvent * event) selectNumber(); } +void QuantitySpinBox::hideEvent(QHideEvent * event) +{ + handlePendingEmit(); + QAbstractSpinBox::hideEvent(event); +} + +void QuantitySpinBox::closeEvent(QCloseEvent * event) +{ + handlePendingEmit(); + QAbstractSpinBox::closeEvent(event); +} + bool QuantitySpinBox::event(QEvent * event) { // issue #0004059: Tooltips for Gui::QuantitySpinBox not showing @@ -900,6 +948,9 @@ void QuantitySpinBox::focusOutEvent(QFocusEvent * event) if (state != QValidator::Acceptable) { lineEdit()->setText(d->validStr); } + + handlePendingEmit(); + QToolTip::hideText(); QAbstractSpinBox::focusOutEvent(event); } diff --git a/src/Gui/QuantitySpinBox.h b/src/Gui/QuantitySpinBox.h index cc9c9ddaeafd..7e8f77e7e686 100644 --- a/src/Gui/QuantitySpinBox.h +++ b/src/Gui/QuantitySpinBox.h @@ -142,13 +142,16 @@ protected Q_SLOTS: void userInput(const QString & text); void openFormulaDialog(); void finishFormulaDialog(); - + void handlePendingEmit(); + //get notified on expression change virtual void onChange(); protected: virtual StepEnabled stepEnabled() const; virtual void showEvent(QShowEvent * event); + virtual void hideEvent(QHideEvent * event); + virtual void closeEvent(QCloseEvent * event); virtual void focusInEvent(QFocusEvent * event); virtual void focusOutEvent(QFocusEvent * event); virtual void keyPressEvent(QKeyEvent *event);