aboutsummaryrefslogtreecommitdiffstats
path: root/src/templates
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-10-26 16:36:32 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-10-29 07:35:26 +0000
commitcf67efa1ea63fe11504799b9bb2329f70d99c525 (patch)
tree024fbb692210f044da403dfc8554d0b5f216766c /src/templates
parente4721fa68c5426d71e957dc6997753ec85f312af (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.cpp138
-rw-r--r--src/templates/qquickspinbox_p.h18
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;