diff --git a/src/Gui/SpinBox.cpp b/src/Gui/SpinBox.cpp index 44c38818a5..974959a3b3 100644 --- a/src/Gui/SpinBox.cpp +++ b/src/Gui/SpinBox.cpp @@ -47,6 +47,167 @@ using namespace Gui; using namespace App; using namespace Base; +ExpressionSpinBox::ExpressionSpinBox(QAbstractSpinBox* sb) + : spinbox(sb) +{ + lineedit = spinbox->findChild(); + makeLabel(lineedit); + QObject::connect(iconLabel, &ExpressionLabel::clicked, [=]() { + this->openFormulaDialog(); + }); +} + +ExpressionSpinBox::~ExpressionSpinBox() +{ +} + +void ExpressionSpinBox::bind(const App::ObjectIdentifier &_path) +{ + ExpressionBinding::bind(_path); + + int frameWidth = spinbox->style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth); + lineedit->setStyleSheet(QString::fromLatin1("QLineEdit { padding-right: %1px } ").arg(iconLabel->sizeHint().width() + frameWidth + 1)); + + iconLabel->show(); +} + +void ExpressionSpinBox::setExpression(std::shared_ptr expr) +{ + Q_ASSERT(isBound()); + + try { + ExpressionBinding::setExpression(expr); + } + catch (const Base::Exception & e) { + spinbox->setReadOnly(true); + QPalette p(lineedit->palette()); + p.setColor(QPalette::Active, QPalette::Text, Qt::red); + lineedit->setPalette(p); + iconLabel->setToolTip(QString::fromLatin1(e.what())); + } +} + +void ExpressionSpinBox::onChange() +{ + if (getExpression()) { + std::unique_ptr result(getExpression()->eval()); + NumberExpression * value = freecad_dynamic_cast(result.get()); + + if (value) { + setNumberExpression(value); + spinbox->setReadOnly(true); + iconLabel->setPixmap(getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight))); + + QPalette p(lineedit->palette()); + p.setColor(QPalette::Text, Qt::lightGray); + lineedit->setPalette(p); + } + iconLabel->setExpressionText(Base::Tools::fromStdString(getExpression()->toString())); + } + else { + spinbox->setReadOnly(false); + iconLabel->setPixmap(getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight))); + QPalette p(lineedit->palette()); + p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text)); + lineedit->setPalette(p); + iconLabel->setExpressionText(QString()); + } +} + +void ExpressionSpinBox::resizeWidget() +{ + int frameWidth = spinbox->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) { + spinbox->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 { + spinbox->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) { + spinbox->setReadOnly(true); + QPalette p(lineedit->palette()); + p.setColor(QPalette::Active, QPalette::Text, Qt::red); + lineedit->setPalette(p); + iconLabel->setToolTip(QString::fromLatin1(e.what())); + } +} + +void ExpressionSpinBox::openFormulaDialog() +{ + Q_ASSERT(isBound()); + + PropertyQuantity * qprop = freecad_dynamic_cast(getPath().getProperty()); + Unit unit; + + if (qprop != 0) + unit = qprop->getUnit(); + + Gui::Dialog::DlgExpressionInput* box = new Gui::Dialog::DlgExpressionInput(getPath(), getExpression(), unit, spinbox); + 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(); + }); + box->show(); + + QPoint pos = spinbox->mapToGlobal(QPoint(0,0)); + box->move(pos-box->expressionPosition()); + box->setExpressionInputSize(spinbox->width(), spinbox->height()); +} + +bool ExpressionSpinBox::handleKeyEvent(const QString& text) +{ + if (text == QString::fromUtf8("=") && isBound()) { + openFormulaDialog(); + return true; + } + + return false; +} + +void ExpressionSpinBox::drawControl(QStyleOptionSpinBox& opt) +{ + if (hasExpression()) { + opt.activeSubControls &= ~QStyle::SC_SpinBoxUp; + opt.activeSubControls &= ~QStyle::SC_SpinBoxDown; + opt.state &= ~QStyle::State_Active; + opt.stepEnabled = QAbstractSpinBox::StepNone; + } + + QStylePainter p(spinbox); + p.drawComplexControl(QStyle::CC_SpinBox, opt); +} + +// ---------------------------------------------------------------------------- + UnsignedValidator::UnsignedValidator( QObject * parent ) : QValidator( parent ) { @@ -142,6 +303,7 @@ public: UIntSpinBox::UIntSpinBox (QWidget* parent) : QSpinBox (parent) + , ExpressionSpinBox(this) { d = new UIntSpinBoxPrivate; d->mValidator = new UnsignedValidator(this->minimum(), this->maximum(), this); @@ -150,10 +312,6 @@ UIntSpinBox::UIntSpinBox (QWidget* parent) setRange(0, 99); setValue(0); updateValidator(); - - makeLabel(lineEdit()); - - QObject::connect(iconLabel, SIGNAL(clicked()), this, SLOT(openFormulaDialog())); } UIntSpinBox::~UIntSpinBox() @@ -242,60 +400,6 @@ void UIntSpinBox::updateValidator() d->mValidator->setRange(this->minimum(), this->maximum()); } -void UIntSpinBox::bind(const App::ObjectIdentifier &_path) -{ - ExpressionBinding::bind(_path); - - int frameWidth = style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth); - lineEdit()->setStyleSheet(QString::fromLatin1("QLineEdit { padding-right: %1px } ").arg(iconLabel->sizeHint().width() + frameWidth + 1)); - - iconLabel->show(); -} - -void UIntSpinBox::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())); - } -} - -void UIntSpinBox::onChange() { - - if (getExpression()) { - std::unique_ptr result(getExpression()->eval()); - NumberExpression * value = freecad_dynamic_cast(result.get()); - - if (value) { - setValue(boost::math::round(value->getValue())); - setReadOnly(true); - iconLabel->setPixmap(getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight))); - - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Text, Qt::lightGray); - lineEdit()->setPalette(p); - } - iconLabel->setExpressionText(Base::Tools::fromStdString(getExpression()->toString())); - } - else { - setReadOnly(false); - iconLabel->setPixmap(getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight))); - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text)); - lineEdit()->setPalette(p); - iconLabel->setExpressionText(QString()); - } -} - - bool UIntSpinBox::apply(const std::string & propName) { if (!ExpressionBinding::apply(propName)) { @@ -306,97 +410,20 @@ bool UIntSpinBox::apply(const std::string & propName) return false; } -bool UIntSpinBox::apply() +void UIntSpinBox::setNumberExpression(App::NumberExpression* expr) { - return ExpressionBinding::apply(); + setValue(boost::math::round(expr->getValue())); } void UIntSpinBox::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())); - } - -} - -void UIntSpinBox::openFormulaDialog() -{ - Q_ASSERT(isBound()); - - PropertyQuantity * qprop = freecad_dynamic_cast(getPath().getProperty()); - Unit unit; - - if (qprop != 0) - unit = qprop->getUnit(); - - Gui::Dialog::DlgExpressionInput* box = new Gui::Dialog::DlgExpressionInput(getPath(), getExpression(), unit, this); - connect(box, SIGNAL(finished(int)), this, SLOT(finishFormulaDialog())); - box->show(); - - QPoint pos = mapToGlobal(QPoint(0,0)); - box->move(pos-box->expressionPosition()); - box->setExpressionInputSize(width(), height()); -} - -void UIntSpinBox::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(); + resizeWidget(); } void UIntSpinBox::keyPressEvent(QKeyEvent *event) { - if (event->text() == QString::fromUtf8("=") && isBound()) - openFormulaDialog(); - else + if (!handleKeyEvent(event->text())) QAbstractSpinBox::keyPressEvent(event); } @@ -404,32 +431,24 @@ void UIntSpinBox::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); } // ---------------------------------------------------------------------------- -IntSpinBox::IntSpinBox(QWidget* parent) : QSpinBox(parent) +IntSpinBox::IntSpinBox(QWidget* parent) + : QSpinBox(parent) + , ExpressionSpinBox(this) { - makeLabel(lineEdit()); - QObject::connect(iconLabel, SIGNAL(clicked()), this, SLOT(openFormulaDialog())); } -IntSpinBox::~IntSpinBox() { +IntSpinBox::~IntSpinBox() +{ } - -bool IntSpinBox::apply(const std::string& propName) { - +bool IntSpinBox::apply(const std::string& propName) +{ if (!ExpressionBinding::apply(propName)) { Gui::Command::doCommand(Gui::Command::Doc, "%s = %d", propName.c_str(), value()); return true; @@ -438,145 +457,20 @@ bool IntSpinBox::apply(const std::string& propName) { return false; } -void IntSpinBox::bind(const ObjectIdentifier& _path) { - - ExpressionBinding::bind(_path); - - int frameWidth = style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth); - lineEdit()->setStyleSheet(QString::fromLatin1("QLineEdit { padding-right: %1px } ").arg(iconLabel->sizeHint().width() + frameWidth + 1)); - - iconLabel->show(); -} - -void IntSpinBox::setExpression(std::shared_ptr expr) +void IntSpinBox::setNumberExpression(App::NumberExpression* 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())); - } -} - -void IntSpinBox::onChange() { - - if (getExpression()) { - std::unique_ptr result(getExpression()->eval()); - NumberExpression * value = freecad_dynamic_cast(result.get()); - - if (value) { - setValue(boost::math::round(value->getValue())); - setReadOnly(true); - iconLabel->setPixmap(getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight))); - - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Text, Qt::lightGray); - lineEdit()->setPalette(p); - } - iconLabel->setExpressionText(Base::Tools::fromStdString(getExpression()->toString())); - } - else { - setReadOnly(false); - iconLabel->setPixmap(getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight))); - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text)); - lineEdit()->setPalette(p); - iconLabel->setExpressionText(QString()); - } + setValue(boost::math::round(expr->getValue())); } void IntSpinBox::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())); - } - -} - -void IntSpinBox::openFormulaDialog() -{ - Q_ASSERT(isBound()); - - PropertyQuantity * qprop = freecad_dynamic_cast(getPath().getProperty()); - Unit unit; - - if (qprop != 0) - unit = qprop->getUnit(); - - Gui::Dialog::DlgExpressionInput* box = new Gui::Dialog::DlgExpressionInput(getPath(), getExpression(),unit, this); - connect(box, SIGNAL(finished(int)), this, SLOT(finishFormulaDialog())); - box->show(); - - QPoint pos = mapToGlobal(QPoint(0,0)); - box->move(pos-box->expressionPosition()); - box->setExpressionInputSize(width(), height()); -} - -void IntSpinBox::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(); + resizeWidget(); } void IntSpinBox::keyPressEvent(QKeyEvent *event) { - if (event->text() == QString::fromUtf8("=") && isBound()) - openFormulaDialog(); - else + if (!handleKeyEvent(event->text())) QAbstractSpinBox::keyPressEvent(event); } @@ -584,32 +478,24 @@ void IntSpinBox::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); } // ---------------------------------------------------------------------------- -DoubleSpinBox::DoubleSpinBox(QWidget* parent): QDoubleSpinBox(parent) +DoubleSpinBox::DoubleSpinBox(QWidget* parent) + : QDoubleSpinBox(parent) + , ExpressionSpinBox(this) { - makeLabel(lineEdit()); - QObject::connect(iconLabel, SIGNAL(clicked()), this, SLOT(openFormulaDialog())); } -DoubleSpinBox::~DoubleSpinBox() { +DoubleSpinBox::~DoubleSpinBox() +{ } - -bool DoubleSpinBox::apply(const std::string& propName) { - +bool DoubleSpinBox::apply(const std::string& propName) +{ if (!ExpressionBinding::apply(propName)) { Gui::Command::doCommand(Gui::Command::Doc, "%s = %f", propName.c_str(), value()); return true; @@ -618,160 +504,28 @@ bool DoubleSpinBox::apply(const std::string& propName) { return false; } -void DoubleSpinBox::bind(const ObjectIdentifier& _path) { - - ExpressionBinding::bind(_path); - - int frameWidth = style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth); - lineEdit()->setStyleSheet(QString::fromLatin1("QLineEdit { padding-right: %1px } ").arg(iconLabel->sizeHint().width() + frameWidth + 1)); - - iconLabel->show(); -} - -void DoubleSpinBox::setExpression(std::shared_ptr expr) +void DoubleSpinBox::setNumberExpression(App::NumberExpression* 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())); - } -} - -void DoubleSpinBox::onChange() { - - if (getExpression()) { - std::unique_ptr result(getExpression()->eval()); - NumberExpression * value = freecad_dynamic_cast(result.get()); - - if (value) { - setValue(value->getValue()); - setReadOnly(true); - iconLabel->setPixmap(getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight))); - - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Text, Qt::lightGray); - lineEdit()->setPalette(p); - } - iconLabel->setExpressionText(Base::Tools::fromStdString(getExpression()->toString())); - } - else { - setReadOnly(false); - iconLabel->setPixmap(getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight))); - QPalette p(lineEdit()->palette()); - p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text)); - lineEdit()->setPalette(p); - iconLabel->setExpressionText(QString()); - } + setValue(expr->getValue()); } void DoubleSpinBox::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())); - } -} - -void DoubleSpinBox::openFormulaDialog() -{ - Q_ASSERT(isBound()); - - PropertyQuantity * qprop = freecad_dynamic_cast(getPath().getProperty()); - Unit unit; - - if (qprop != 0) - unit = qprop->getUnit(); - - Gui::Dialog::DlgExpressionInput* box = new Gui::Dialog::DlgExpressionInput(getPath(), getExpression(), unit, this); - connect(box, SIGNAL(finished(int)), this, SLOT(finishFormulaDialog())); - box->show(); - - QPoint pos = mapToGlobal(QPoint(0,0)); - box->move(pos-box->expressionPosition()); - box->setExpressionInputSize(width(), height()); -} - -void DoubleSpinBox::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(); + resizeWidget(); } void DoubleSpinBox::keyPressEvent(QKeyEvent *event) { - if (event->text() == QString::fromUtf8("=") && isBound()) - openFormulaDialog(); - else - QAbstractSpinBox::keyPressEvent(event); + if (!handleKeyEvent(event->text())) + QDoubleSpinBox::keyPressEvent(event); } void DoubleSpinBox::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); } #include "moc_SpinBox.cpp" diff --git a/src/Gui/SpinBox.h b/src/Gui/SpinBox.h index 0ae1f7ee4e..09e88e8fd7 100644 --- a/src/Gui/SpinBox.h +++ b/src/Gui/SpinBox.h @@ -28,8 +28,38 @@ #include #include "ExpressionBinding.h" +class QStyleOptionSpinBox; + +namespace App { +class NumberExpression; +} + namespace Gui { +class GuiExport ExpressionSpinBox : public ExpressionBinding +{ +public: + ExpressionSpinBox(QAbstractSpinBox*); + virtual ~ExpressionSpinBox(); + + void bind(const App::ObjectIdentifier &_path); + void setExpression(std::shared_ptr expr); + +protected: + void onChange(); + virtual void setNumberExpression(App::NumberExpression*) = 0; + void resizeWidget(); + + bool handleKeyEvent(const QString&); + void openFormulaDialog(); + + void drawControl(QStyleOptionSpinBox&); + +protected: + QLineEdit* lineedit; + QAbstractSpinBox* spinbox; +}; + /** * A validator that allows only input of unsigned int values in the range * from 0 to UINT_MAX. @@ -65,7 +95,7 @@ class UIntSpinBoxPrivate; * This allows to use numbers in the range of [0, UINT_MAX] * @author Werner Mayer */ -class GuiExport UIntSpinBox : public QSpinBox, public ExpressionBinding +class GuiExport UIntSpinBox : public QSpinBox, public ExpressionSpinBox { Q_OBJECT Q_OVERRIDE( uint maximum READ maximum WRITE setMaximum ) @@ -84,10 +114,8 @@ public: uint maximum() const; void setMaximum( uint value ); - void setExpression(std::shared_ptr expr); - void bind(const App::ObjectIdentifier &_path); bool apply(const std::string &propName); - bool apply(); + using ExpressionSpinBox::apply; void keyPressEvent(QKeyEvent *event); void resizeEvent(QResizeEvent *event); @@ -101,13 +129,11 @@ public Q_SLOTS: private Q_SLOTS: void valueChange( int value ); - void finishFormulaDialog(); - void openFormulaDialog(); protected: virtual QString textFromValue ( int v ) const; virtual int valueFromText ( const QString & text ) const; - virtual void onChange(); + virtual void setNumberExpression(App::NumberExpression*); private: void updateValidator(); @@ -119,7 +145,7 @@ private: * The IntSpinBox class does exactly the same as Qt's QSpinBox but has expression support * @author Stefan Tröger */ -class GuiExport IntSpinBox : public QSpinBox, public ExpressionBinding +class GuiExport IntSpinBox : public QSpinBox, public ExpressionSpinBox { Q_OBJECT @@ -127,18 +153,13 @@ public: IntSpinBox ( QWidget* parent=0 ); virtual ~IntSpinBox(); - void setExpression(std::shared_ptr expr); - void bind(const App::ObjectIdentifier &_path); bool apply(const std::string &propName); + using ExpressionSpinBox::apply; + void setNumberExpression(App::NumberExpression*); void keyPressEvent(QKeyEvent *event); void resizeEvent(QResizeEvent *event); void paintEvent(QPaintEvent *event); - -private Q_SLOTS: - void finishFormulaDialog(); - void openFormulaDialog(); - virtual void onChange(); }; /** @@ -146,7 +167,7 @@ private Q_SLOTS: * support * @author Stefan Tröger */ -class GuiExport DoubleSpinBox : public QDoubleSpinBox, public ExpressionBinding +class GuiExport DoubleSpinBox : public QDoubleSpinBox, public ExpressionSpinBox { Q_OBJECT @@ -154,18 +175,13 @@ public: DoubleSpinBox ( QWidget* parent=0 ); virtual ~DoubleSpinBox(); - void setExpression(std::shared_ptr expr); - void bind(const App::ObjectIdentifier &_path); bool apply(const std::string &propName); + using ExpressionSpinBox::apply; + void setNumberExpression(App::NumberExpression*); void keyPressEvent(QKeyEvent *event); void resizeEvent(QResizeEvent *event); void paintEvent(QPaintEvent *event); - -private Q_SLOTS: - void finishFormulaDialog(); - void openFormulaDialog(); - virtual void onChange(); }; } // namespace Gui