From 5d49bf78de785a536f941f1a6d06d432582a95d3 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 2 Apr 2021 22:22:16 +0200 Subject: [PATCH] Gui: QuantitySpinBox inherits from ExpressionSpinBox to reduce code duplication --- src/Gui/QuantitySpinBox.cpp | 144 ++++-------------------------------- src/Gui/QuantitySpinBox.h | 16 ++-- src/Gui/SpinBox.cpp | 2 + src/Gui/SpinBox.h | 2 +- 4 files changed, 24 insertions(+), 140 deletions(-) diff --git a/src/Gui/QuantitySpinBox.cpp b/src/Gui/QuantitySpinBox.cpp index 52e3eb69ba..1e8d60fd89 100644 --- a/src/Gui/QuantitySpinBox.cpp +++ b/src/Gui/QuantitySpinBox.cpp @@ -290,7 +290,7 @@ end: QuantitySpinBox::QuantitySpinBox(QWidget *parent) : QAbstractSpinBox(parent), - ExpressionBinding(), + ExpressionSpinBox(this), d_ptr(new QuantitySpinBoxPrivate()) { d_ptr->locale = locale(); @@ -300,8 +300,6 @@ QuantitySpinBox::QuantitySpinBox(QWidget *parent) QObject::connect(this, SIGNAL(editingFinished()), this, SLOT(handlePendingEmit())); - makeLabel(lineEdit()); - // When a style sheet is set the text margins for top/bottom must be set to avoid to squash the widget #ifndef Q_OS_MAC lineEdit()->setTextMargins(0, 2, 0, 2); @@ -309,8 +307,6 @@ QuantitySpinBox::QuantitySpinBox(QWidget *parent) // https://forum.freecadweb.org/viewtopic.php?f=8&t=50615 lineEdit()->setTextMargins(0, 2, 0, 0); #endif - - QObject::connect(iconLabel, SIGNAL(clicked()), this, SLOT(openFormulaDialog())); } QuantitySpinBox::~QuantitySpinBox() @@ -324,22 +320,6 @@ void QuantitySpinBox::bind(const App::ObjectIdentifier &_path) iconLabel->show(); } -void Gui::QuantitySpinBox::setExpression(std::shared_ptr expr) -{ - Q_ASSERT(isBound()); - - try { - ExpressionBinding::setExpression(expr); - } - catch (const Base::Exception & e) { - setReadOnly(true); - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Active, QPalette::Text, Qt::red); - lineEdit()->setPalette(p); - iconLabel->setToolTip(QString::fromLatin1(e.what())); - } -} - QString QuantitySpinBox::boundToName() const { if (isBound()) { @@ -412,44 +392,12 @@ QString Gui::QuantitySpinBox::expressionText() const return QString(); } - -void Gui::QuantitySpinBox::onChange() +void Gui::QuantitySpinBox::setNumberExpression(App::NumberExpression* expr) { - Q_ASSERT(isBound()); - - if (getExpression()) { - std::unique_ptr result(getExpression()->eval()); - NumberExpression * value = freecad_dynamic_cast(result.get()); - - if (value) { - std::stringstream s; - s << value->getValue(); - - lineEdit()->setText(getUserString(value->getQuantity())); - handlePendingEmit(); - - setReadOnly(true); - QPixmap pixmap = getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight)); - iconLabel->setPixmap(pixmap); - - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Text, Qt::lightGray); - lineEdit()->setPalette(p); - } - iconLabel->setExpressionText(Base::Tools::fromStdString(getExpression()->toString())); - } - else { - setReadOnly(false); - QPixmap pixmap = getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight)); - iconLabel->setPixmap(pixmap); - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text)); - lineEdit()->setPalette(p); - iconLabel->setExpressionText(QString()); - } + lineEdit()->setText(getUserString(expr->getQuantity())); + handlePendingEmit(); } - bool QuantitySpinBox::apply(const std::string & propName) { if (!ExpressionBinding::apply(propName)) { @@ -480,54 +428,12 @@ bool QuantitySpinBox::apply(const std::string & propName) void QuantitySpinBox::resizeEvent(QResizeEvent * event) { QAbstractSpinBox::resizeEvent(event); - - int frameWidth = style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth); - - QSize sz = iconLabel->sizeHint(); - iconLabel->move(lineEdit()->rect().right() - frameWidth - sz.width(), 0); - - try { - if (isBound() && getExpression()) { - std::unique_ptr result(getExpression()->eval()); - NumberExpression * value = freecad_dynamic_cast(result.get()); - - if (value) { - setReadOnly(true); - QPixmap pixmap = getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight)); - iconLabel->setPixmap(pixmap); - - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Text, Qt::lightGray); - lineEdit()->setPalette(p); - } - iconLabel->setExpressionText(Base::Tools::fromStdString(getExpression()->toString())); - } - else { - setReadOnly(false); - QPixmap pixmap = getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight)); - iconLabel->setPixmap(pixmap); - - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text)); - lineEdit()->setPalette(p); - iconLabel->setExpressionText(QString()); - } - } - catch (const Base::Exception & e) { - setReadOnly(true); - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Active, QPalette::Text, Qt::red); - lineEdit()->setPalette(p); - iconLabel->setToolTip(QString::fromLatin1(e.what())); - } - + resizeWidget(); } void Gui::QuantitySpinBox::keyPressEvent(QKeyEvent *event) { - if (event->text() == QString::fromUtf8("=") && isBound()) - openFormulaDialog(); - else + if (!handleKeyEvent(event->text())) QAbstractSpinBox::keyPressEvent(event); } @@ -535,15 +441,7 @@ void Gui::QuantitySpinBox::paintEvent(QPaintEvent*) { QStyleOptionSpinBox opt; initStyleOption(&opt); - if (hasExpression()) { - opt.activeSubControls &= ~QStyle::SC_SpinBoxUp; - opt.activeSubControls &= ~QStyle::SC_SpinBoxDown; - opt.state &= ~QStyle::State_Active; - opt.stepEnabled = StepNone; - } - - QStylePainter p(this); - p.drawComplexControl(QStyle::CC_SpinBox, opt); + drawControl(opt); } void QuantitySpinBox::updateText(const Quantity &quant) @@ -629,7 +527,15 @@ void QuantitySpinBox::openFormulaDialog() Q_D(const QuantitySpinBox); Gui::Dialog::DlgExpressionInput* box = new Gui::Dialog::DlgExpressionInput(getPath(), getExpression(), d->unit, this); - connect(box, SIGNAL(finished(int)), this, SLOT(finishFormulaDialog())); + QObject::connect(box, &Gui::Dialog::DlgExpressionInput::finished, [=]() { + if (box->result() == QDialog::Accepted) + setExpression(box->getExpression()); + else if (box->discardedFormula()) + setExpression(std::shared_ptr()); + + box->deleteLater(); + Q_EMIT showFormulaDialog(false); + }); box->show(); QPoint pos = mapToGlobal(QPoint(0,0)); @@ -639,24 +545,6 @@ void QuantitySpinBox::openFormulaDialog() Q_EMIT showFormulaDialog(true); } -void QuantitySpinBox::finishFormulaDialog() -{ - Gui::Dialog::DlgExpressionInput* box = qobject_cast(sender()); - if (!box) { - qWarning() << "Sender is not a Gui::Dialog::DlgExpressionInput"; - return; - } - - if (box->result() == QDialog::Accepted) - setExpression(box->getExpression()); - else if (box->discardedFormula()) - setExpression(std::shared_ptr()); - - box->deleteLater(); - - Q_EMIT showFormulaDialog(false); -} - void QuantitySpinBox::handlePendingEmit() { updateFromCache(true); diff --git a/src/Gui/QuantitySpinBox.h b/src/Gui/QuantitySpinBox.h index 6a3da7b765..d0f34fa11c 100644 --- a/src/Gui/QuantitySpinBox.h +++ b/src/Gui/QuantitySpinBox.h @@ -24,10 +24,9 @@ #ifndef GUI_QUANTITYSPINBOX_H #define GUI_QUANTITYSPINBOX_H -#include #include #include -#include "ExpressionBinding.h" +#include #ifdef Q_MOC_RUN Q_DECLARE_METATYPE(Base::Quantity) @@ -36,7 +35,7 @@ Q_DECLARE_METATYPE(Base::Quantity) namespace Gui { class QuantitySpinBoxPrivate; -class GuiExport QuantitySpinBox : public QAbstractSpinBox, public ExpressionBinding +class GuiExport QuantitySpinBox : public QAbstractSpinBox, public ExpressionSpinBox { Q_OBJECT @@ -50,8 +49,6 @@ class GuiExport QuantitySpinBox : public QAbstractSpinBox, public ExpressionBind Q_PROPERTY(QString expression READ expressionText) public: - using ExpressionBinding::apply; - explicit QuantitySpinBox(QWidget *parent = 0); virtual ~QuantitySpinBox(); @@ -128,9 +125,10 @@ public: QSize minimumSizeHint() const; bool event(QEvent *event); - void setExpression(std::shared_ptr expr); + void setNumberExpression(App::NumberExpression*); void bind(const App::ObjectIdentifier &_path); bool apply(const std::string &propName); + using ExpressionSpinBox::apply; public Q_SLOTS: /// Sets the field with a quantity @@ -140,14 +138,10 @@ public Q_SLOTS: protected Q_SLOTS: void userInput(const QString & text); - void openFormulaDialog(); - void finishFormulaDialog(); void handlePendingEmit(); - //get notified on expression change - virtual void onChange(); - protected: + virtual void openFormulaDialog(); virtual StepEnabled stepEnabled() const; virtual void showEvent(QShowEvent * event); virtual void hideEvent(QHideEvent * event); diff --git a/src/Gui/SpinBox.cpp b/src/Gui/SpinBox.cpp index 974959a3b3..9866abf11d 100644 --- a/src/Gui/SpinBox.cpp +++ b/src/Gui/SpinBox.cpp @@ -89,6 +89,8 @@ void ExpressionSpinBox::setExpression(std::shared_ptr expr) void ExpressionSpinBox::onChange() { + Q_ASSERT(isBound()); + if (getExpression()) { std::unique_ptr result(getExpression()->eval()); NumberExpression * value = freecad_dynamic_cast(result.get()); diff --git a/src/Gui/SpinBox.h b/src/Gui/SpinBox.h index 09e88e8fd7..c8ca9ec3c4 100644 --- a/src/Gui/SpinBox.h +++ b/src/Gui/SpinBox.h @@ -51,7 +51,7 @@ protected: void resizeWidget(); bool handleKeyEvent(const QString&); - void openFormulaDialog(); + virtual void openFormulaDialog(); void drawControl(QStyleOptionSpinBox&);