diff options
author | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-10-26 16:36:32 +0100 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-10-29 07:35:26 +0000 |
commit | cf67efa1ea63fe11504799b9bb2329f70d99c525 (patch) | |
tree | 024fbb692210f044da403dfc8554d0b5f216766c /src/templates | |
parent | e4721fa68c5426d71e957dc6997753ec85f312af (diff) |
SpinBox: add validator, textFromValue and valueFromText
Change-Id: I45e01199453ac5fd64b7f98c165cc12eeb0ce8c3
Task-number: QTBUG-48989
Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
Reviewed-by: Nikita Krupenko <krnekit@gmail.com>
Diffstat (limited to 'src/templates')
-rw-r--r-- | src/templates/qquickspinbox.cpp | 138 | ||||
-rw-r--r-- | src/templates/qquickspinbox_p.h | 18 |
2 files changed, 153 insertions, 3 deletions
diff --git a/src/templates/qquickspinbox.cpp b/src/templates/qquickspinbox.cpp index e1596e3a..9bb908e9 100644 --- a/src/templates/qquickspinbox.cpp +++ b/src/templates/qquickspinbox.cpp @@ -40,6 +40,10 @@ #include <QtGui/qguiapplication.h> #include <QtGui/qstylehints.h> +#include <QtQml/qqmlinfo.h> +#include <QtQml/private/qqmllocale_p.h> +#include <QtQml/private/qqmlengine_p.h> + QT_BEGIN_NAMESPACE // copied from qabstractbutton.cpp @@ -65,6 +69,17 @@ static const int AUTO_REPEAT_INTERVAL = 100; \snippet qtlabscontrols-spinbox.qml 1 + \section2 Custom Values + + \image qtlabscontrols-spinbox-textual.png + + Even though SpinBox works on integer values, it can be customized to + accept arbitrary input values. The following snippet demonstrates how + \l validator, \l textFromValue and \l valueFromText can be used to + customize the default behavior. + + \snippet qtlabscontrols-spinbox-textual.qml 1 + \sa Tumbler, {Customizing SpinBox} */ @@ -74,7 +89,7 @@ class QQuickSpinBoxPrivate : public QQuickControlPrivate public: QQuickSpinBoxPrivate() : from(0), to(99), value(0), stepSize(1), - delayTimer(0), repeatTimer(0), up(Q_NULLPTR), down(Q_NULLPTR) { } + delayTimer(0), repeatTimer(0), up(Q_NULLPTR), down(Q_NULLPTR), validator(Q_NULLPTR) { } int boundValue(int value) const; void updateValue(); @@ -99,6 +114,9 @@ public: QQuickSpinner *up; QQuickSpinner *down; QLocale locale; + QValidator *validator; + QJSValue textFromValue; + QJSValue valueFromText; }; int QQuickSpinBoxPrivate::boundValue(int value) const @@ -111,8 +129,12 @@ void QQuickSpinBoxPrivate::updateValue() Q_Q(QQuickSpinBox); if (contentItem) { QVariant text = contentItem->property("text"); - if (text.isValid()) - q->setValue(locale.toInt(text.toString())); + if (text.isValid()) { + QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(q)); + QJSValue loc(v4, QQmlLocale::wrap(v4, locale)); + QJSValue val = valueFromText.call(QJSValueList() << text.toString() << loc); + q->setValue(val.toInt()); + } } } @@ -335,6 +357,103 @@ void QQuickSpinBox::setLocale(const QLocale &locale) } /*! + \qmlproperty Validator Qt.labs.controls::SpinBox::validator + + This property holds the input text validator. By default, SpinBox uses + \l IntValidator to accept input of integer numbers. + + \snippet SpinBox.qml validator + + \sa textFromValue, valueFromText, locale +*/ +QValidator *QQuickSpinBox::validator() const +{ + Q_D(const QQuickSpinBox); + return d->validator; +} + +void QQuickSpinBox::setValidator(QValidator *validator) +{ + Q_D(QQuickSpinBox); + if (d->validator != validator) { + d->validator = validator; + emit validatorChanged(); + } +} + +/*! + \qmlproperty function Qt.labs.controls::SpinBox::textFromValue + + This property holds a callback function that is called whenever + an integer value needs to be converted to display text. + + The callback function signature is \c {string function(value, locale)}. + The function can have one or two arguments, where the first argument + is the value to be converted, and the optional second argument is the + locale that should be used for the conversion, if applicable. + + The default implementation does the conversion using \l {QtQml::Locale}{Number.toLocaleString()}: + + \code + textFromValue: function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); } + \endcode + + \sa valueFromText, validator, locale +*/ +QJSValue QQuickSpinBox::textFromValue() const +{ + Q_D(const QQuickSpinBox); + return d->textFromValue; +} + +void QQuickSpinBox::setTextFromValue(const QJSValue &callback) +{ + Q_D(QQuickSpinBox); + if (!callback.isCallable()) { + qmlInfo(this) << "textFromValue must be a callable function"; + return; + } + d->textFromValue = callback; + emit textFromValueChanged(); +} + +/*! + \qmlproperty function Qt.labs.controls::SpinBox::valueFromText + + This property holds a callback function that is called whenever + input text needs to be converted to an integer value. + + The callback function signature is \c {int function(text, locale)}. + The function can have one or two arguments, where the first argument + is the text to be converted, and the optional second argument is the + locale that should be used for the conversion, if applicable. + + The default implementation does the conversion using \l {QtQml::Locale}{Number.fromLocaleString()}: + + \code + valueFromText: function(text, locale) { return Number.fromLocaleString(locale, text); } + \endcode + + \sa textFromValue, validator, locale +*/ +QJSValue QQuickSpinBox::valueFromText() const +{ + Q_D(const QQuickSpinBox); + return d->valueFromText; +} + +void QQuickSpinBox::setValueFromText(const QJSValue &callback) +{ + Q_D(QQuickSpinBox); + if (!callback.isCallable()) { + qmlInfo(this) << "valueFromText must be a callable function"; + return; + } + d->valueFromText = callback; + emit valueFromTextChanged(); +} + +/*! \qmlpropertygroup Qt.labs.controls::SpinBox::up \qmlproperty bool Qt.labs.controls::SpinBox::up.pressed \qmlproperty Item Qt.labs.controls::SpinBox::up.indicator @@ -459,6 +578,19 @@ void QQuickSpinBox::timerEvent(QTimerEvent *event) } } +void QQuickSpinBox::componentComplete() +{ + Q_D(QQuickSpinBox); + QQuickControl::componentComplete(); + QQmlEngine *engine = qmlEngine(this); + if (engine) { + if (!d->textFromValue.isCallable()) + setTextFromValue(engine->evaluate(QStringLiteral("function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }"))); + if (!d->valueFromText.isCallable()) + setValueFromText(engine->evaluate(QStringLiteral("function(text, locale) { return Number.fromLocaleString(locale, text); }"))); + } +} + void QQuickSpinBox::itemChange(ItemChange change, const ItemChangeData &value) { Q_D(QQuickSpinBox); diff --git a/src/templates/qquickspinbox_p.h b/src/templates/qquickspinbox_p.h index e78979f9..047364a2 100644 --- a/src/templates/qquickspinbox_p.h +++ b/src/templates/qquickspinbox_p.h @@ -49,9 +49,11 @@ // #include <QtLabsTemplates/private/qquickcontrol_p.h> +#include <QtQml/qjsvalue.h> QT_BEGIN_NAMESPACE +class QValidator; class QQuickSpinner; class QQuickSpinnerPrivate; class QQuickSpinBoxPrivate; @@ -64,6 +66,9 @@ class Q_LABSTEMPLATES_EXPORT QQuickSpinBox : public QQuickControl Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged FINAL) Q_PROPERTY(int stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL) Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged FINAL) + Q_PROPERTY(QValidator *validator READ validator WRITE setValidator NOTIFY validatorChanged FINAL) + Q_PROPERTY(QJSValue textFromValue READ textFromValue WRITE setTextFromValue NOTIFY textFromValueChanged FINAL) + Q_PROPERTY(QJSValue valueFromText READ valueFromText WRITE setValueFromText NOTIFY valueFromTextChanged FINAL) Q_PROPERTY(QQuickSpinner *up READ up CONSTANT FINAL) Q_PROPERTY(QQuickSpinner *down READ down CONSTANT FINAL) @@ -85,6 +90,15 @@ public: QLocale locale() const; void setLocale(const QLocale &locale); + QValidator *validator() const; + void setValidator(QValidator *validator); + + QJSValue textFromValue() const; + void setTextFromValue(const QJSValue &callback); + + QJSValue valueFromText() const; + void setValueFromText(const QJSValue &callback); + QQuickSpinner *up() const; QQuickSpinner *down() const; @@ -98,6 +112,9 @@ Q_SIGNALS: void valueChanged(); void stepSizeChanged(); void localeChanged(); + void validatorChanged(); + void textFromValueChanged(); + void valueFromTextChanged(); protected: bool childMouseEventFilter(QQuickItem *child, QEvent *event) Q_DECL_OVERRIDE; @@ -105,6 +122,7 @@ protected: void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + void componentComplete() Q_DECL_OVERRIDE; void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) Q_DECL_OVERRIDE; |