aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2018-02-15 11:22:14 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2018-02-15 11:22:23 +0100
commitf6fec74d4238e304643b99880bdfd8ee32c8578e (patch)
treef3880de9e9890cb6b140ba5722d91819b800616f
parent72d5d88afe64a76f2026e4a45a4858a13917d4f0 (diff)
parentd95e67c291d213cdbf41b23c535b47aa3a553ab5 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
-rw-r--r--dist/changes-5.10.149
-rw-r--r--examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc2
-rw-r--r--examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc2
-rw-r--r--src/imports/controls/TextArea.qml2
-rw-r--r--src/imports/controls/TextField.qml2
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-index.qdoc5
-rw-r--r--src/imports/controls/fusion/TextArea.qml2
-rw-r--r--src/imports/controls/fusion/TextField.qml2
-rw-r--r--src/imports/controls/fusion/qtquickcontrols2fusionstyleplugin.cpp6
-rw-r--r--src/imports/controls/imagine/TextArea.qml2
-rw-r--r--src/imports/controls/imagine/TextField.qml2
-rw-r--r--src/imports/controls/imagine/qtquickcontrols2imaginestyleplugin.cpp6
-rw-r--r--src/imports/controls/material/Dial.qml4
-rw-r--r--src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp6
-rw-r--r--src/imports/controls/qtquickcontrols2plugin.cpp32
-rw-r--r--src/imports/controls/universal/Dial.qml4
-rw-r--r--src/imports/controls/universal/qquickuniversalstyle.cpp103
-rw-r--r--src/imports/controls/universal/qquickuniversalstyle_p.h3
-rw-r--r--src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp7
-rw-r--r--src/imports/platform/qquickplatformmenu.cpp6
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp3
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp50
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h3
-rw-r--r--src/quicktemplates2/qquickcheckdelegate.cpp5
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp14
-rw-r--r--src/quicktemplates2/qquickicon.cpp82
-rw-r--r--src/quicktemplates2/qquickicon_p.h14
-rw-r--r--src/quicktemplates2/qquickpopup.cpp9
-rw-r--r--src/quicktemplates2/qquickspinbox.cpp2
-rw-r--r--src/quicktemplates2/qquickstackview_p.cpp2
-rw-r--r--tests/auto/controls/data/tst_abstractbutton.qml221
-rw-r--r--tests/auto/controls/data/tst_drawer.qml118
-rw-r--r--tests/auto/controls/data/tst_stackview.qml31
-rw-r--r--tests/auto/focus/tst_focus.cpp83
-rw-r--r--tests/auto/qquickdrawer/tst_qquickdrawer.cpp40
-rw-r--r--tests/auto/qquickpopup/tst_qquickpopup.cpp96
-rw-r--r--tests/manual/testbench/controls/Button.qml8
-rw-r--r--tests/manual/testbench/controls/RoundButton.qml6
38 files changed, 679 insertions, 355 deletions
diff --git a/dist/changes-5.10.1 b/dist/changes-5.10.1
new file mode 100644
index 00000000..c94cb75d
--- /dev/null
+++ b/dist/changes-5.10.1
@@ -0,0 +1,49 @@
+Qt 5.10.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.10.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.10 series is binary compatible with the 5.9.x series.
+Applications compiled for 5.9 will continue to run with 5.10.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+This release contains all fixes included in the Qt 5.9.4 release.
+
+****************************************************************************
+* Qt 5.10.1 Changes *
+****************************************************************************
+
+Controls
+--------
+
+ - AbstractButton:
+ * [QTBUG-65193] Made button's text win over action's when both are
+ specified.
+
+ - Action:
+ * [QTBUG-65108] Fixed an issue where a checkable action would toggle
+ twice when toggling an associated checkable button.
+ * [QTBUG-65889] Fixed shortcuts in Repeater.
+
+Styles
+------
+
+ - Imagine:
+ * [QTBUG-65500] Fixed to respect user font settings from
+ qtquickcontrols2.conf.
+
+Third-Party Code
+----------------
+
+ - [QTBUG-65409] Document constants from AngularJS in
+ src/imports/controls/material/ElevationEffect.qml
diff --git a/examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc b/examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc
index 2107e6ab..9a8c1883 100644
--- a/examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc
+++ b/examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
- \example automotive
+ \example imagine/automotive
\title Qt Quick Controls 2 - Imagine Style Example: Automotive
\ingroup qtquickcontrols2-examples
\brief An automotive user interface using custom Imagine style assets.
diff --git a/examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc b/examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc
index cca44e83..960c683d 100644
--- a/examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc
+++ b/examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
- \example musicplayer
+ \example imagine/musicplayer
\title Qt Quick Controls 2 - Imagine Style Example: Music Player
\ingroup qtquickcontrols2-examples
\brief An audio player user interface using custom Imagine style assets.
diff --git a/src/imports/controls/TextArea.qml b/src/imports/controls/TextArea.qml
index 00a97957..04a44eae 100644
--- a/src/imports/controls/TextArea.qml
+++ b/src/imports/controls/TextArea.qml
@@ -66,7 +66,7 @@ T.TextArea {
text: control.placeholderText
font: control.font
opacity: 0.5
- color: control.palette.text
+ color: control.color
verticalAlignment: control.verticalAlignment
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
elide: Text.ElideRight
diff --git a/src/imports/controls/TextField.qml b/src/imports/controls/TextField.qml
index 333c5bba..4b80d8be 100644
--- a/src/imports/controls/TextField.qml
+++ b/src/imports/controls/TextField.qml
@@ -67,7 +67,7 @@ T.TextField {
text: control.placeholderText
font: control.font
opacity: 0.5
- color: control.palette.text
+ color: control.color
verticalAlignment: control.verticalAlignment
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
elide: Text.ElideRight
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc
index 2ce0eb92..cbe21282 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-index.qdoc
@@ -102,6 +102,11 @@
\li 2.3
\li 1.0
\row
+ \li 5.11
+ \li 2.11
+ \li 2.4
+ \li 1.0
+ \row
\li ...
\li ...
\li ...
diff --git a/src/imports/controls/fusion/TextArea.qml b/src/imports/controls/fusion/TextArea.qml
index 56541d89..36d9db04 100644
--- a/src/imports/controls/fusion/TextArea.qml
+++ b/src/imports/controls/fusion/TextArea.qml
@@ -68,7 +68,7 @@ T.TextArea {
opacity: 0.5
text: control.placeholderText
font: control.font
- color: control.palette.text
+ color: control.color
verticalAlignment: control.verticalAlignment
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
elide: Text.ElideRight
diff --git a/src/imports/controls/fusion/TextField.qml b/src/imports/controls/fusion/TextField.qml
index e66857cd..2ea5c967 100644
--- a/src/imports/controls/fusion/TextField.qml
+++ b/src/imports/controls/fusion/TextField.qml
@@ -68,7 +68,7 @@ T.TextField {
opacity: 0.5
text: control.placeholderText
font: control.font
- color: control.palette.text
+ color: control.color
verticalAlignment: control.verticalAlignment
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
elide: Text.ElideRight
diff --git a/src/imports/controls/fusion/qtquickcontrols2fusionstyleplugin.cpp b/src/imports/controls/fusion/qtquickcontrols2fusionstyleplugin.cpp
index 2d1a6e28..5bb1d062 100644
--- a/src/imports/controls/fusion/qtquickcontrols2fusionstyleplugin.cpp
+++ b/src/imports/controls/fusion/qtquickcontrols2fusionstyleplugin.cpp
@@ -69,7 +69,6 @@ public:
QtQuickControls2FusionStylePlugin(QObject *parent = nullptr);
void registerTypes(const char *uri) override;
- void initializeEngine(QQmlEngine *engine, const char *uri) override;
QString name() const override;
QQuickTheme *createTheme() const override;
@@ -84,11 +83,6 @@ void QtQuickControls2FusionStylePlugin::registerTypes(const char *uri)
{
qmlRegisterModule(uri, 2, 3); // Qt 5.10->2.3
qmlRegisterModule(uri, 2, QT_VERSION_MINOR - 7); // Qt 5.11->2.4, 5.12->2.5...
-}
-
-void QtQuickControls2FusionStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
-{
- QQuickStylePlugin::initializeEngine(engine, uri);
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterModule(import, 2, QT_VERSION_MINOR - 7); // Qt 5.11->2.4, 5.12->2.5...
diff --git a/src/imports/controls/imagine/TextArea.qml b/src/imports/controls/imagine/TextArea.qml
index 49153b5d..9867a0bd 100644
--- a/src/imports/controls/imagine/TextArea.qml
+++ b/src/imports/controls/imagine/TextArea.qml
@@ -70,7 +70,7 @@ T.TextArea {
text: control.placeholderText
font: control.font
- color: control.palette.text
+ color: control.color
verticalAlignment: control.verticalAlignment
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
elide: Text.ElideRight
diff --git a/src/imports/controls/imagine/TextField.qml b/src/imports/controls/imagine/TextField.qml
index 09ef5bcb..17827b95 100644
--- a/src/imports/controls/imagine/TextField.qml
+++ b/src/imports/controls/imagine/TextField.qml
@@ -70,7 +70,7 @@ T.TextField {
text: control.placeholderText
font: control.font
- color: control.palette.text
+ color: control.color
verticalAlignment: control.verticalAlignment
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
elide: Text.ElideRight
diff --git a/src/imports/controls/imagine/qtquickcontrols2imaginestyleplugin.cpp b/src/imports/controls/imagine/qtquickcontrols2imaginestyleplugin.cpp
index 3ab8a472..292b8719 100644
--- a/src/imports/controls/imagine/qtquickcontrols2imaginestyleplugin.cpp
+++ b/src/imports/controls/imagine/qtquickcontrols2imaginestyleplugin.cpp
@@ -64,7 +64,6 @@ public:
QtQuickControls2ImagineStylePlugin(QObject *parent = nullptr);
void registerTypes(const char *uri) override;
- void initializeEngine(QQmlEngine *engine, const char *uri) override;
QString name() const override;
QQuickTheme *createTheme() const override;
@@ -79,11 +78,6 @@ void QtQuickControls2ImagineStylePlugin::registerTypes(const char *uri)
{
qmlRegisterModule(uri, 2, QT_VERSION_MINOR - 7); // Qt 5.10 -> 2.3, 5.11 -> 2.4, ...
qmlRegisterUncreatableType<QQuickImagineStyle>(uri, 2, 3, "Imagine", tr("Imagine is an attached property"));
-}
-
-void QtQuickControls2ImagineStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
-{
- QQuickStylePlugin::initializeEngine(engine, uri);
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterModule(import, 2, QT_VERSION_MINOR - 7); // Qt 5.10 -> 2.3, 5.11 -> 2.4, ...
diff --git a/src/imports/controls/material/Dial.qml b/src/imports/controls/material/Dial.qml
index 3d94df18..54469c92 100644
--- a/src/imports/controls/material/Dial.qml
+++ b/src/imports/controls/material/Dial.qml
@@ -69,8 +69,8 @@ T.Dial {
origin.y: handle.height / 2
}
]
- implicitWidth: 14
- implicitHeight: 14
+ implicitWidth: 10
+ implicitHeight: 10
value: control.value
handleHasFocus: control.visualFocus
diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
index 4ea1f426..5e0494d5 100644
--- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
+++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
@@ -64,7 +64,6 @@ public:
QtQuickControls2MaterialStylePlugin(QObject *parent = nullptr);
void registerTypes(const char *uri) override;
- void initializeEngine(QQmlEngine *engine, const char *uri) override;
QString name() const override;
QQuickTheme *createTheme() const override;
@@ -79,11 +78,6 @@ void QtQuickControls2MaterialStylePlugin::registerTypes(const char *uri)
{
qmlRegisterModule(uri, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2...
qmlRegisterUncreatableType<QQuickMaterialStyle>(uri, 2, 0, "Material", tr("Material is an attached property"));
-}
-
-void QtQuickControls2MaterialStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
-{
- QQuickStylePlugin::initializeEngine(engine, uri);
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterModule(import, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2...
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp
index dba18fc8..443f0cb8 100644
--- a/src/imports/controls/qtquickcontrols2plugin.cpp
+++ b/src/imports/controls/qtquickcontrols2plugin.cpp
@@ -78,7 +78,6 @@ class QtQuickControls2Plugin: public QQuickStylePlugin
public:
QtQuickControls2Plugin(QObject *parent = nullptr);
void registerTypes(const char *uri) override;
- void initializeEngine(QQmlEngine *engine, const char *uri) override;
QString name() const override;
QQuickTheme *createTheme() const override;
@@ -165,25 +164,6 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
qmlRegisterType(selector.select(QStringLiteral("MenuBar.qml")), uri, 2, 3, "MenuBar");
qmlRegisterType(selector.select(QStringLiteral("MenuBarItem.qml")), uri, 2, 3, "MenuBarItem");
qmlRegisterUncreatableType<QQuickOverlay>(uri, 2, 3, "Overlay", QStringLiteral("Overlay is only available as an attached property."));
-}
-
-static QObject *styleSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
-{
- Q_UNUSED(engine);
- Q_UNUSED(scriptEngine);
- return new QQuickDefaultStyle;
-}
-
-static QObject *colorSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
-{
- Q_UNUSED(engine);
- Q_UNUSED(scriptEngine);
- return new QQuickColor;
-}
-
-void QtQuickControls2Plugin::initializeEngine(QQmlEngine *engine, const char *uri)
-{
- QQuickStylePlugin::initializeEngine(engine, uri);
const QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterModule(import, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2...
@@ -198,7 +178,11 @@ void QtQuickControls2Plugin::initializeEngine(QQmlEngine *engine, const char *ur
#if QT_CONFIG(quick_listview) && QT_CONFIG(quick_pathview)
qmlRegisterType<QQuickTumblerView>(import, 2, 1, "TumblerView");
#endif
- qmlRegisterSingletonType<QQuickDefaultStyle>(import, 2, 1, "Default", styleSingleton);
+ qmlRegisterSingletonType<QQuickDefaultStyle>(import, 2, 1, "Default", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* {
+ Q_UNUSED(engine);
+ Q_UNUSED(scriptEngine);
+ return new QQuickDefaultStyle;
+ });
// QtQuick.Controls.impl 2.2 (Qt 5.9)
qmlRegisterType<QQuickClippedText>(import, 2, 2, "ClippedText");
@@ -208,7 +192,11 @@ void QtQuickControls2Plugin::initializeEngine(QQmlEngine *engine, const char *ur
// QtQuick.Controls.impl 2.3 (Qt 5.10)
qmlRegisterType<QQuickColorImage>(import, 2, 3, "ColorImage");
qmlRegisterType<QQuickIconImage>(import, 2, 3, "IconImage");
- qmlRegisterSingletonType<QQuickColor>(import, 2, 3, "Color", colorSingleton);
+ qmlRegisterSingletonType<QQuickColor>(import, 2, 3, "Color", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* {
+ Q_UNUSED(engine);
+ Q_UNUSED(scriptEngine);
+ return new QQuickColor;
+ });
qmlRegisterType<QQuickIconLabel>(import, 2, 3, "IconLabel");
qmlRegisterType<QQuickCheckLabel>(import, 2, 3, "CheckLabel");
qmlRegisterType<QQuickMnemonicLabel>(import, 2, 3, "MnemonicLabel");
diff --git a/src/imports/controls/universal/Dial.qml b/src/imports/controls/universal/Dial.qml
index 539400cd..d2634713 100644
--- a/src/imports/controls/universal/Dial.qml
+++ b/src/imports/controls/universal/Dial.qml
@@ -56,8 +56,8 @@ T.Dial {
}
handle: Rectangle {
- implicitWidth: 20
- implicitHeight: 20
+ implicitWidth: 14
+ implicitHeight: 14
x: background.x + background.width / 2 - handle.width / 2
y: background.y + background.height / 2 - handle.height / 2
diff --git a/src/imports/controls/universal/qquickuniversalstyle.cpp b/src/imports/controls/universal/qquickuniversalstyle.cpp
index 157d5ddb..dbc409fd 100644
--- a/src/imports/controls/universal/qquickuniversalstyle.cpp
+++ b/src/imports/controls/universal/qquickuniversalstyle.cpp
@@ -536,66 +536,59 @@ static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSe
return value;
}
-void QQuickUniversalStyle::init()
-{
- static bool globalsInitialized = false;
- if (!globalsInitialized) {
- QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Universal"));
-
- bool ok = false;
- QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_THEME", settings, QStringLiteral("Theme"));
- Theme themeEnum = toEnumValue<Theme>(themeValue, &ok);
- if (ok)
- GlobalTheme = m_theme = qquickuniversal_effective_theme(themeEnum);
- else if (!themeValue.isEmpty())
- qWarning().nospace().noquote() << "Universal: unknown theme value: " << themeValue;
-
- QByteArray accentValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_ACCENT", settings, QStringLiteral("Accent"));
- Color accentEnum = toEnumValue<Color>(accentValue, &ok);
- if (ok) {
- GlobalAccent = m_accent = qquickuniversal_accent_color(accentEnum);
- } else if (!accentValue.isEmpty()) {
- QColor color(accentValue.constData());
- if (color.isValid())
- GlobalAccent = m_accent = color.rgba();
- else
- qWarning().nospace().noquote() << "Universal: unknown accent value: " << accentValue;
- }
+void QQuickUniversalStyle::initGlobals()
+{
+ QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Universal"));
+
+ bool ok = false;
+ QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_THEME", settings, QStringLiteral("Theme"));
+ Theme themeEnum = toEnumValue<Theme>(themeValue, &ok);
+ if (ok)
+ GlobalTheme = qquickuniversal_effective_theme(themeEnum);
+ else if (!themeValue.isEmpty())
+ qWarning().nospace().noquote() << "Universal: unknown theme value: " << themeValue;
+
+ QByteArray accentValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_ACCENT", settings, QStringLiteral("Accent"));
+ Color accentEnum = toEnumValue<Color>(accentValue, &ok);
+ if (ok) {
+ GlobalAccent = qquickuniversal_accent_color(accentEnum);
+ } else if (!accentValue.isEmpty()) {
+ QColor color(accentValue.constData());
+ if (color.isValid())
+ GlobalAccent = color.rgba();
+ else
+ qWarning().nospace().noquote() << "Universal: unknown accent value: " << accentValue;
+ }
- QByteArray foregroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_FOREGROUND", settings, QStringLiteral("Foreground"));
- Color foregroundEnum = toEnumValue<Color>(foregroundValue, &ok);
- if (ok) {
- GlobalForeground = m_foreground = qquickuniversal_accent_color(foregroundEnum);
- HasGlobalForeground = m_hasForeground = true;
- } else if (!foregroundValue.isEmpty()) {
- QColor color(foregroundValue.constData());
- if (color.isValid()) {
- GlobalForeground = m_foreground = color.rgba();
- HasGlobalForeground = m_hasForeground = true;
- } else {
- qWarning().nospace().noquote() << "Universal: unknown foreground value: " << foregroundValue;
- }
+ QByteArray foregroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_FOREGROUND", settings, QStringLiteral("Foreground"));
+ Color foregroundEnum = toEnumValue<Color>(foregroundValue, &ok);
+ if (ok) {
+ GlobalForeground = qquickuniversal_accent_color(foregroundEnum);
+ HasGlobalForeground = true;
+ } else if (!foregroundValue.isEmpty()) {
+ QColor color(foregroundValue.constData());
+ if (color.isValid()) {
+ GlobalForeground = color.rgba();
+ HasGlobalForeground = true;
+ } else {
+ qWarning().nospace().noquote() << "Universal: unknown foreground value: " << foregroundValue;
}
+ }
- QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_BACKGROUND", settings, QStringLiteral("Background"));
- Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok);
- if (ok) {
- GlobalBackground = m_background = qquickuniversal_accent_color(backgroundEnum);
- HasGlobalBackground = m_hasBackground = true;
- } else if (!backgroundValue.isEmpty()) {
- QColor color(backgroundValue.constData());
- if (color.isValid()) {
- GlobalBackground = m_background = color.rgba();
- HasGlobalBackground = m_hasBackground = true;
- } else {
- qWarning().nospace().noquote() << "Universal: unknown background value: " << backgroundValue;
- }
+ QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_BACKGROUND", settings, QStringLiteral("Background"));
+ Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok);
+ if (ok) {
+ GlobalBackground = qquickuniversal_accent_color(backgroundEnum);
+ HasGlobalBackground = true;
+ } else if (!backgroundValue.isEmpty()) {
+ QColor color(backgroundValue.constData());
+ if (color.isValid()) {
+ GlobalBackground = color.rgba();
+ HasGlobalBackground = true;
+ } else {
+ qWarning().nospace().noquote() << "Universal: unknown background value: " << backgroundValue;
}
-
- globalsInitialized = true;
}
-
- QQuickAttachedObject::init(); // TODO: lazy init?
}
bool QQuickUniversalStyle::variantToRgba(const QVariant &var, const char *name, QRgb *rgba) const
diff --git a/src/imports/controls/universal/qquickuniversalstyle_p.h b/src/imports/controls/universal/qquickuniversalstyle_p.h
index 196048ef..eb9f6d83 100644
--- a/src/imports/controls/universal/qquickuniversalstyle_p.h
+++ b/src/imports/controls/universal/qquickuniversalstyle_p.h
@@ -200,6 +200,8 @@ public:
QColor systemColor(SystemColor role) const;
+ static void initGlobals();
+
Q_SIGNALS:
void themeChanged();
void accentChanged();
@@ -211,7 +213,6 @@ protected:
void attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) override;
private:
- void init();
bool variantToRgba(const QVariant &var, const char *name, QRgb *rgba) const;
// These reflect whether a color value was explicitly set on the specific
diff --git a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
index b9934c73..fa55e18a 100644
--- a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
+++ b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
@@ -61,7 +61,6 @@ public:
QtQuickControls2UniversalStylePlugin(QObject *parent = nullptr);
void registerTypes(const char *uri) override;
- void initializeEngine(QQmlEngine *engine, const char *uri) override;
QString name() const override;
QQuickTheme *createTheme() const override;
@@ -70,17 +69,13 @@ public:
QtQuickControls2UniversalStylePlugin::QtQuickControls2UniversalStylePlugin(QObject *parent) : QQuickStylePlugin(parent)
{
initResources();
+ QQuickUniversalStyle::initGlobals();
}
void QtQuickControls2UniversalStylePlugin::registerTypes(const char *uri)
{
qmlRegisterModule(uri, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2...
qmlRegisterUncreatableType<QQuickUniversalStyle>(uri, 2, 0, "Universal", tr("Universal is an attached property"));
-}
-
-void QtQuickControls2UniversalStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
-{
- QQuickStylePlugin::initializeEngine(engine, uri);
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterModule(import, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2...
diff --git a/src/imports/platform/qquickplatformmenu.cpp b/src/imports/platform/qquickplatformmenu.cpp
index 82adb6c3..ec5c4804 100644
--- a/src/imports/platform/qquickplatformmenu.cpp
+++ b/src/imports/platform/qquickplatformmenu.cpp
@@ -44,6 +44,7 @@
#include <QtGui/qcursor.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtQml/private/qqmlengine_p.h>
#include <QtQml/private/qv4scopedvalue_p.h>
#include <QtQml/private/qv4qobjectwrapper_p.h>
@@ -705,8 +706,9 @@ void QQuickPlatformMenu::open(QQmlV4Function *args)
targetRect.moveTo(pos);
#endif
}
-
- m_handle->showPopup(window, targetRect, menuItem ? menuItem->handle() : nullptr);
+ m_handle->showPopup(window,
+ QHighDpi::toNativePixels(targetRect, window),
+ menuItem ? menuItem->handle() : nullptr);
}
/*!
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index a67fca2c..d775a019 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -299,6 +299,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickDialog, 3>(uri, 2, 3, "Dialog");
qmlRegisterType<QQuickDialogButtonBox, 3>(uri, 2, 3, "DialogButtonBox");
qRegisterMetaType<QQuickIcon>();
+ qmlRegisterType<QQuickLabel, 3>(uri, 2, 3, "Label");
qmlRegisterType<QQuickMenu, 3>(uri, 2, 3, "Menu");
qmlRegisterType<QQuickMenuBar>(uri, 2, 3, "MenuBar");
qmlRegisterType<QQuickMenuBarItem>(uri, 2, 3, "MenuBarItem");
@@ -311,6 +312,8 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickScrollIndicator, 3>(uri, 2, 3, "ScrollIndicator");
qmlRegisterType<QQuickSlider, 3>(uri, 2, 3, "Slider");
qmlRegisterType<QQuickSpinBox, 3>(uri, 2, 3, "SpinBox");
+ qmlRegisterType<QQuickTextArea, 3>(uri, 2, 3, "TextArea");
+ qmlRegisterType<QQuickTextField, 3>(uri, 2, 3, "TextField");
// NOTE: register the latest revisions of all template/control base classes to
// make revisioned properties available to their subclasses (synced with Qt 5.10)
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 238669c6..0a8b8ddf 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -328,6 +328,21 @@ void QQuickAbstractButtonPrivate::setText(const QString &newText, bool isExplici
q->buttonChange(QQuickAbstractButton::ButtonTextChange);
}
+void QQuickAbstractButtonPrivate::updateEffectiveIcon()
+{
+ Q_Q(QQuickAbstractButton);
+ // We store effectiveIcon because we need to be able to tell if the icon has actually changed.
+ // If we only stored our icon and the action's icon, and resolved in the getter, we'd have
+ // no way of knowing what the old value was here. As an added benefit, we only resolve when
+ // something has changed, as opposed to doing it unconditionally in the icon() getter.
+ const QQuickIcon newEffectiveIcon = action ? icon.resolve(action->icon()) : icon;
+ if (newEffectiveIcon == effectiveIcon)
+ return;
+
+ effectiveIcon = newEffectiveIcon;
+ emit q->iconChanged();
+}
+
void QQuickAbstractButtonPrivate::click()
{
Q_Q(QQuickAbstractButton);
@@ -720,17 +735,14 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator)
QQuickIcon QQuickAbstractButton::icon() const
{
Q_D(const QQuickAbstractButton);
- return d->icon;
+ return d->effectiveIcon;
}
void QQuickAbstractButton::setIcon(const QQuickIcon &icon)
{
Q_D(QQuickAbstractButton);
- if (d->icon == icon)
- return;
-
d->icon = icon;
- emit iconChanged();
+ d->updateEffectiveIcon();
}
/*!
@@ -792,7 +804,7 @@ void QQuickAbstractButton::setAction(QQuickAction *action)
QObjectPrivate::disconnect(oldAction, &QQuickAction::triggered, d, &QQuickAbstractButtonPrivate::click);
QObjectPrivate::disconnect(oldAction, &QQuickAction::textChanged, d, &QQuickAbstractButtonPrivate::actionTextChange);
- disconnect(oldAction, &QQuickAction::iconChanged, this, &QQuickAbstractButton::setIcon);
+ QObjectPrivate::disconnect(oldAction, &QQuickAction::iconChanged, d, &QQuickAbstractButtonPrivate::updateEffectiveIcon);
disconnect(oldAction, &QQuickAction::checkedChanged, this, &QQuickAbstractButton::setChecked);
disconnect(oldAction, &QQuickAction::checkableChanged, this, &QQuickAbstractButton::setCheckable);
disconnect(oldAction, &QQuickAction::enabledChanged, this, &QQuickItem::setEnabled);
@@ -803,33 +815,11 @@ void QQuickAbstractButton::setAction(QQuickAction *action)
QObjectPrivate::connect(action, &QQuickAction::triggered, d, &QQuickAbstractButtonPrivate::click);
QObjectPrivate::connect(action, &QQuickAction::textChanged, d, &QQuickAbstractButtonPrivate::actionTextChange);
- connect(action, &QQuickAction::iconChanged, this, &QQuickAbstractButton::setIcon);
+ QObjectPrivate::connect(action, &QQuickAction::iconChanged, d, &QQuickAbstractButtonPrivate::updateEffectiveIcon);
connect(action, &QQuickAction::checkedChanged, this, &QQuickAbstractButton::setChecked);
connect(action, &QQuickAction::checkableChanged, this, &QQuickAbstractButton::setCheckable);
connect(action, &QQuickAction::enabledChanged, this, &QQuickItem::setEnabled);
- QQuickIcon actionIcon = action->icon();
-
- QString name = actionIcon.name();
- if (!name.isEmpty())
- d->icon.setName(name);
-
- QUrl source = actionIcon.source();
- if (!source.isEmpty())
- d->icon.setSource(source);
-
- int width = actionIcon.width();
- if (width > 0)
- d->icon.setWidth(width);
-
- int height = actionIcon.height();
- if (height)
- d->icon.setHeight(height);
-
- QColor color = actionIcon.color();
- if (color != Qt::transparent)
- d->icon.setColor(color);
-
setChecked(action->isChecked());
setCheckable(action->isCheckable());
setEnabled(action->isEnabled());
@@ -840,6 +830,8 @@ void QQuickAbstractButton::setAction(QQuickAction *action)
if (oldText != text())
buttonChange(ButtonTextChange);
+ d->updateEffectiveIcon();
+
emit actionChanged();
}
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index 1c493cd8..bb74e143 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -96,6 +96,8 @@ public:
void actionTextChange();
void setText(const QString &text, bool isExplicit);
+ void updateEffectiveIcon();
+
void click();
void trigger();
void toggle(bool value);
@@ -124,6 +126,7 @@ public:
QKeySequence shortcut;
#endif
QQuickIcon icon;
+ QQuickIcon effectiveIcon;
QPointF pressPoint;
QPointF movePoint;
Qt::MouseButtons pressButtons;
diff --git a/src/quicktemplates2/qquickcheckdelegate.cpp b/src/quicktemplates2/qquickcheckdelegate.cpp
index 9fd8c183..b53877df 100644
--- a/src/quicktemplates2/qquickcheckdelegate.cpp
+++ b/src/quicktemplates2/qquickcheckdelegate.cpp
@@ -166,11 +166,8 @@ void QQuickCheckDelegate::setCheckState(Qt::CheckState state)
if (d->checkState == state)
return;
- if (!d->tristate && state == Qt::PartiallyChecked)
- setTristate(true);
-
bool wasChecked = isChecked();
- d->checked = state != Qt::Unchecked;
+ d->checked = state == Qt::Checked;
d->checkState = state;
emit checkStateChanged();
if (d->checked != wasChecked)
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 3c3b67f8..c2d63f02 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -163,11 +163,19 @@ bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point)
}
#endif
+static void setActiveFocus(QQuickControl *control, Qt::FocusReason reason)
+{
+ QQuickControlPrivate *d = QQuickControlPrivate::get(control);
+ if (d->subFocusItem && d->window && d->flags & QQuickItem::ItemIsFocusScope)
+ QQuickWindowPrivate::get(d->window)->clearFocusInScope(control, d->subFocusItem, reason);
+ control->forceActiveFocus(reason);
+}
+
void QQuickControlPrivate::handlePress(const QPointF &)
{
Q_Q(QQuickControl);
if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
+ setActiveFocus(q, Qt::MouseFocusReason);
}
void QQuickControlPrivate::handleMove(const QPointF &point)
@@ -184,7 +192,7 @@ void QQuickControlPrivate::handleRelease(const QPointF &)
{
Q_Q(QQuickControl);
if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
+ setActiveFocus(q, Qt::MouseFocusReason);
touchId = -1;
}
@@ -1683,7 +1691,7 @@ void QQuickControl::wheelEvent(QWheelEvent *event)
{
Q_D(QQuickControl);
if ((d->focusPolicy & Qt::WheelFocus) == Qt::WheelFocus)
- forceActiveFocus(Qt::MouseFocusReason);
+ setActiveFocus(this, Qt::MouseFocusReason);
event->setAccepted(d->wheelEnabled);
}
diff --git a/src/quicktemplates2/qquickicon.cpp b/src/quicktemplates2/qquickicon.cpp
index 0b0127d3..79af62b1 100644
--- a/src/quicktemplates2/qquickicon.cpp
+++ b/src/quicktemplates2/qquickicon.cpp
@@ -44,7 +44,8 @@ public:
QQuickIconPrivate()
: width(0),
height(0),
- color(Qt::transparent)
+ color(Qt::transparent),
+ resolveMask(0)
{
}
@@ -53,6 +54,18 @@ public:
int width;
int height;
QColor color;
+
+ enum ResolveProperties {
+ NameResolved = 0x0001,
+ SourceResolved = 0x0002,
+ WidthResolved = 0x0004,
+ HeightResolved = 0x0008,
+ ColorResolved = 0x0010,
+ AllPropertiesResolved = 0x1ffff
+ };
+
+ // This is based on QFont's resolve_mask.
+ int resolveMask;
};
QQuickIcon::QQuickIcon()
@@ -101,7 +114,17 @@ QString QQuickIcon::name() const
void QQuickIcon::setName(const QString &name)
{
+ if ((d->resolveMask & QQuickIconPrivate::NameResolved) && d->name == name)
+ return;
+
d->name = name;
+ d->resolveMask |= QQuickIconPrivate::NameResolved;
+}
+
+void QQuickIcon::resetName()
+{
+ d->name = QString();
+ d->resolveMask &= ~QQuickIconPrivate::NameResolved;
}
QUrl QQuickIcon::source() const
@@ -111,7 +134,17 @@ QUrl QQuickIcon::source() const
void QQuickIcon::setSource(const QUrl &source)
{
+ if ((d->resolveMask & QQuickIconPrivate::SourceResolved) && d->source == source)
+ return;
+
d->source = source;
+ d->resolveMask |= QQuickIconPrivate::SourceResolved;
+}
+
+void QQuickIcon::resetSource()
+{
+ d->source = QString();
+ d->resolveMask &= ~QQuickIconPrivate::SourceResolved;
}
int QQuickIcon::width() const
@@ -121,7 +154,17 @@ int QQuickIcon::width() const
void QQuickIcon::setWidth(int width)
{
+ if ((d->resolveMask & QQuickIconPrivate::WidthResolved) && d->width == width)
+ return;
+
d->width = width;
+ d->resolveMask |= QQuickIconPrivate::WidthResolved;
+}
+
+void QQuickIcon::resetWidth()
+{
+ d->width = 0;
+ d->resolveMask &= ~QQuickIconPrivate::WidthResolved;
}
int QQuickIcon::height() const
@@ -131,7 +174,17 @@ int QQuickIcon::height() const
void QQuickIcon::setHeight(int height)
{
+ if ((d->resolveMask & QQuickIconPrivate::HeightResolved) && d->height == height)
+ return;
+
d->height = height;
+ d->resolveMask |= QQuickIconPrivate::HeightResolved;
+}
+
+void QQuickIcon::resetHeight()
+{
+ d->height = 0;
+ d->resolveMask &= ~QQuickIconPrivate::HeightResolved;
}
QColor QQuickIcon::color() const
@@ -141,12 +194,39 @@ QColor QQuickIcon::color() const
void QQuickIcon::setColor(const QColor &color)
{
+ if ((d->resolveMask & QQuickIconPrivate::ColorResolved) && d->color == color)
+ return;
+
d->color = color;
+ d->resolveMask |= QQuickIconPrivate::ColorResolved;
}
void QQuickIcon::resetColor()
{
d->color = Qt::transparent;
+ d->resolveMask &= ~QQuickIconPrivate::ColorResolved;
+}
+
+QQuickIcon QQuickIcon::resolve(const QQuickIcon &other) const
+{
+ QQuickIcon resolved = *this;
+
+ if (!(d->resolveMask & QQuickIconPrivate::NameResolved))
+ resolved.setName(other.name());
+
+ if (!(d->resolveMask & QQuickIconPrivate::SourceResolved))
+ resolved.setSource(other.source());
+
+ if (!(d->resolveMask & QQuickIconPrivate::WidthResolved))
+ resolved.setWidth(other.width());
+
+ if (!(d->resolveMask & QQuickIconPrivate::HeightResolved))
+ resolved.setHeight(other.height());
+
+ if (!(d->resolveMask & QQuickIconPrivate::ColorResolved))
+ resolved.setColor(other.color());
+
+ return resolved;
}
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickicon_p.h b/src/quicktemplates2/qquickicon_p.h
index 6e28f2a9..2c95bc9d 100644
--- a/src/quicktemplates2/qquickicon_p.h
+++ b/src/quicktemplates2/qquickicon_p.h
@@ -62,10 +62,10 @@ class QQuickIconPrivate;
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickIcon
{
Q_GADGET
- Q_PROPERTY(QString name READ name WRITE setName FINAL)
- Q_PROPERTY(QUrl source READ source WRITE setSource FINAL)
- Q_PROPERTY(int width READ width WRITE setWidth FINAL)
- Q_PROPERTY(int height READ height WRITE setHeight FINAL)
+ Q_PROPERTY(QString name READ name WRITE setName RESET resetName FINAL)
+ Q_PROPERTY(QUrl source READ source WRITE setSource RESET resetSource FINAL)
+ Q_PROPERTY(int width READ width WRITE setWidth RESET resetWidth FINAL)
+ Q_PROPERTY(int height READ height WRITE setHeight RESET resetHeight FINAL)
Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor FINAL)
public:
@@ -81,20 +81,26 @@ public:
QString name() const;
void setName(const QString &name);
+ void resetName();
QUrl source() const;
void setSource(const QUrl &source);
+ void resetSource();
int width() const;
void setWidth(int width);
+ void resetWidth();
int height() const;
void setHeight(int height);
+ void resetHeight();
QColor color() const;
void setColor(const QColor &color);
void resetColor();
+ QQuickIcon resolve(const QQuickIcon &other) const;
+
private:
QSharedDataPointer<QQuickIconPrivate> d;
};
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 0524c688..97e347d7 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -450,12 +450,11 @@ bool QQuickPopupPrivate::prepareExitTransition()
return false;
if (transitionState != ExitTransition) {
- if (focus) {
- // The setFocus(false) call below removes any active focus before we're
- // able to check it in finalizeExitTransition.
- hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus();
+ // The setFocus(false) call below removes any active focus before we're
+ // able to check it in finalizeExitTransition.
+ hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus();
+ if (focus)
popupItem->setFocus(false);
- }
transitionState = ExitTransition;
hideOverlay();
emit q->aboutToHide();
diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp
index 5e74f6ef..525de945 100644
--- a/src/quicktemplates2/qquickspinbox.cpp
+++ b/src/quicktemplates2/qquickspinbox.cpp
@@ -818,7 +818,7 @@ void QQuickSpinBox::setWrap(bool wrap)
This property holds the textual value of the spinbox.
- The value of the property is based on \l textFromValue() and \l {Control::}
+ The value of the property is based on \l textFromValue and \l {Control::}
{locale}, and equal to:
\badcode
var text = spinBox.textFromValue(spinBox.value, spinBox.locale)
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp
index 0167ad97..606d259a 100644
--- a/src/quicktemplates2/qquickstackview_p.cpp
+++ b/src/quicktemplates2/qquickstackview_p.cpp
@@ -73,6 +73,8 @@ void QQuickStackViewPrivate::setCurrentItem(QQuickStackElement *element)
currentItem = item;
if (element)
element->setVisible(true);
+ if (item)
+ item->setFocus(true);
emit q->currentItemChanged();
}
diff --git a/tests/auto/controls/data/tst_abstractbutton.qml b/tests/auto/controls/data/tst_abstractbutton.qml
index b266b183..d611a45a 100644
--- a/tests/auto/controls/data/tst_abstractbutton.qml
+++ b/tests/auto/controls/data/tst_abstractbutton.qml
@@ -392,6 +392,208 @@ TestCase {
compare(spy.count, data.resetChanged ? 1 : 0)
}
+ function test_actionIcon_data() {
+ var data = []
+
+ // Save duplicating the rows by reusing them with different properties of the same type.
+ // This means that the first loop will test icon.name and the second one will test icon.source.
+ var stringPropertyValueSuffixes = [
+ { propertyName: "name", valueSuffix: "IconName" },
+ { propertyName: "source", valueSuffix: "IconSource" }
+ ]
+
+ for (var i = 0; i < stringPropertyValueSuffixes.length; ++i) {
+ var propertyName = stringPropertyValueSuffixes[i].propertyName
+ var valueSuffix = stringPropertyValueSuffixes[i].valueSuffix
+
+ var buttonPropertyValue = "Button" + valueSuffix
+ var buttonPropertyValue2 = "Button" + valueSuffix + "2"
+ var actionPropertyValue = "Action" + valueSuffix
+ var actionPropertyValue2 = "Action" + valueSuffix + "2"
+
+ data.push({ tag: "implicit " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ resetExpected: "", resetChanged: true })
+ data.push({ tag: "explicit " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: actionPropertyValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ data.push({ tag: "empty button " + propertyName, property: propertyName,
+ initButton: "", initAction: actionPropertyValue,
+ assignExpected: "", assignChanged: false,
+ resetExpected: "", resetChanged: false })
+ data.push({ tag: "empty action " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: "",
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ data.push({ tag: "empty both " + propertyName, property: propertyName,
+ initButton: undefined, initAction: "",
+ assignExpected: "", assignChanged: false,
+ resetExpected: "", resetChanged: false })
+ data.push({ tag: "modify button " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ modifyButton: buttonPropertyValue2,
+ modifyButtonExpected: buttonPropertyValue2, modifyButtonChanged: true,
+ resetExpected: buttonPropertyValue2, resetChanged: false })
+ data.push({ tag: "modify implicit action " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ modifyAction: actionPropertyValue2,
+ modifyActionExpected: actionPropertyValue2, modifyActionChanged: true,
+ resetExpected: "", resetChanged: true })
+ data.push({ tag: "modify explicit action " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: actionPropertyValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ modifyAction: actionPropertyValue2,
+ modifyActionExpected: buttonPropertyValue, modifyActionChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ }
+
+ var intPropertyNames = [
+ "width",
+ "height",
+ ]
+
+ for (i = 0; i < intPropertyNames.length; ++i) {
+ propertyName = intPropertyNames[i]
+
+ buttonPropertyValue = 20
+ buttonPropertyValue2 = 21
+ actionPropertyValue = 40
+ actionPropertyValue2 = 41
+ var defaultValue = 0
+
+ data.push({ tag: "implicit " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ resetExpected: defaultValue, resetChanged: true })
+ data.push({ tag: "explicit " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: actionPropertyValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ data.push({ tag: "default button " + propertyName, property: propertyName,
+ initButton: defaultValue, initAction: actionPropertyValue,
+ assignExpected: defaultValue, assignChanged: false,
+ resetExpected: defaultValue, resetChanged: false })
+ data.push({ tag: "default action " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: defaultValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ data.push({ tag: "default both " + propertyName, property: propertyName,
+ initButton: undefined, initAction: defaultValue,
+ assignExpected: defaultValue, assignChanged: false,
+ resetExpected: defaultValue, resetChanged: false })
+ data.push({ tag: "modify button " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ modifyButton: buttonPropertyValue2,
+ modifyButtonExpected: buttonPropertyValue2, modifyButtonChanged: true,
+ resetExpected: buttonPropertyValue2, resetChanged: false })
+ data.push({ tag: "modify implicit action " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ modifyAction: actionPropertyValue2,
+ modifyActionExpected: actionPropertyValue2, modifyActionChanged: true,
+ resetExpected: defaultValue, resetChanged: true })
+ data.push({ tag: "modify explicit action " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: actionPropertyValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ modifyAction: actionPropertyValue2,
+ modifyActionExpected: buttonPropertyValue, modifyActionChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ }
+
+ propertyName = "color"
+ buttonPropertyValue = "#aa0000"
+ buttonPropertyValue2 = "#ff0000"
+ actionPropertyValue = "#0000aa"
+ actionPropertyValue2 = "#0000ff"
+ defaultValue = "#00000000"
+
+ data.push({ tag: "implicit " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ resetExpected: defaultValue, resetChanged: true })
+ data.push({ tag: "explicit " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: actionPropertyValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ data.push({ tag: "default button " + propertyName, property: propertyName,
+ initButton: defaultValue, initAction: actionPropertyValue,
+ assignExpected: defaultValue, assignChanged: false,
+ resetExpected: defaultValue, resetChanged: false })
+ data.push({ tag: "default action " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: defaultValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+ data.push({ tag: "default both " + propertyName, property: propertyName,
+ initButton: undefined, initAction: defaultValue,
+ assignExpected: defaultValue, assignChanged: false,
+ resetExpected: defaultValue, resetChanged: false })
+ data.push({ tag: "modify button " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ modifyButton: buttonPropertyValue2,
+ modifyButtonExpected: buttonPropertyValue2, modifyButtonChanged: true,
+ resetExpected: buttonPropertyValue2, resetChanged: false })
+ data.push({ tag: "modify implicit action " + propertyName, property: propertyName,
+ initButton: undefined, initAction: actionPropertyValue,
+ assignExpected: actionPropertyValue, assignChanged: true,
+ modifyAction: actionPropertyValue2,
+ modifyActionExpected: actionPropertyValue2, modifyActionChanged: true,
+ resetExpected: defaultValue, resetChanged: true })
+ data.push({ tag: "modify explicit action " + propertyName, property: propertyName,
+ initButton: buttonPropertyValue, initAction: actionPropertyValue,
+ assignExpected: buttonPropertyValue, assignChanged: false,
+ modifyAction: actionPropertyValue2,
+ modifyActionExpected: buttonPropertyValue, modifyActionChanged: false,
+ resetExpected: buttonPropertyValue, resetChanged: false })
+
+ return data;
+ }
+
+ function test_actionIcon(data) {
+ var control = createTemporaryObject(button, testCase)
+ verify(control)
+ control.icon[data.property] = data.initButton
+
+ var act = action.createObject(control)
+ act.icon[data.property] = data.initAction
+
+ var spy = signalSpy.createObject(control, {target: control, signalName: "iconChanged"})
+ verify(spy.valid)
+
+ // assign action
+ spy.clear()
+ control.action = act
+ compare(control.icon[data.property], data.assignExpected)
+ compare(spy.count, data.assignChanged ? 1 : 0)
+
+ // modify button
+ if (data.hasOwnProperty("modifyButton")) {
+ spy.clear()
+ control.icon[data.property] = data.modifyButton
+ compare(control.icon[data.property], data.modifyButtonExpected)
+ compare(spy.count, data.modifyButtonChanged ? 1 : 0)
+ }
+
+ // modify action
+ if (data.hasOwnProperty("modifyAction")) {
+ spy.clear()
+ act.icon[data.property] = data.modifyAction
+ compare(control.icon[data.property], data.modifyActionExpected)
+ compare(spy.count, data.modifyActionChanged ? 1 : 0)
+ }
+
+ // reset action
+ spy.clear()
+ control.action = null
+ compare(control.icon[data.property], data.resetExpected)
+ compare(spy.count, data.resetChanged ? 1 : 0)
+ }
+
Component {
id: actionButton
AbstractButton {
@@ -412,8 +614,6 @@ TestCase {
// initial values
compare(control.text, "Default")
- compare(control.icon.name, "default")
- compare(control.icon.source, "qrc:/icons/default.png")
compare(control.checkable, true)
compare(control.checked, true)
compare(control.enabled, false)
@@ -423,14 +623,10 @@ TestCase {
// changes via action
control.action.text = "Action"
- control.action.icon.name = "action"
- control.action.icon.source = "qrc:/icons/action.png"
control.action.checkable = false
control.action.checked = false
control.action.enabled = true
compare(control.text, "Action") // propagates
- compare(control.icon.name, "action") // propagates
- compare(control.icon.source, "qrc:/icons/action.png") // propagates
compare(control.checkable, false) // propagates
compare(control.checked, false) // propagates
compare(control.enabled, true) // propagates
@@ -438,31 +634,26 @@ TestCase {
// changes via button
control.text = "Button"
- control.icon.name = "button"
- control.icon.source = "qrc:/icons/button.png"
control.checkable = true
control.checked = true
control.enabled = false
compare(control.text, "Button")
- compare(control.icon.name, "button")
- compare(control.icon.source, "qrc:/icons/button.png")
compare(control.checkable, true)
compare(control.checked, true)
compare(control.enabled, false)
compare(control.action.text, "Action") // does NOT propagate
- compare(control.action.icon.name, "action") // does NOT propagate
- compare(control.action.icon.source, "qrc:/icons/action.png") // does NOT propagate
compare(control.action.checkable, true) // propagates
compare(control.action.checked, true) // propagates
compare(control.action.enabled, true) // does NOT propagate
compare(textSpy.count, 2)
- // remove the action so that only the button's text is left
+ // remove the action so that only the button's properties are left
control.action = null
compare(control.text, "Button")
compare(textSpy.count, 2)
- // setting an action while button has text shouldn't cause a change in the button's effective text
+ // setting an action while button has a particular property set
+ // shouldn't cause a change in the button's effective property value
var secondAction = createTemporaryObject(action, testCase)
verify(secondAction)
secondAction.text = "SecondAction"
@@ -470,7 +661,7 @@ TestCase {
compare(control.text, "Button")
compare(textSpy.count, 2)
- // test setting an action with empty text
+ // test setting an action whose properties aren't set
var thirdAction = createTemporaryObject(action, testCase)
verify(thirdAction)
control.action = thirdAction
diff --git a/tests/auto/controls/data/tst_drawer.qml b/tests/auto/controls/data/tst_drawer.qml
deleted file mode 100644
index 5446b969..00000000
--- a/tests/auto/controls/data/tst_drawer.qml
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.2
-import QtTest 1.0
-import QtQuick.Controls 2.3
-
-TestCase {
- id: testCase
- width: 400
- height: 400
- visible: true
- when: windowShown
- name: "Drawer"
-
- Component {
- id: drawer
- Drawer { }
- }
-
- function test_defaults() {
- var control = createTemporaryObject(drawer, testCase)
- compare(control.edge, Qt.LeftEdge)
- compare(control.position, 0.0)
- compare(control.dragMargin, Qt.styleHints.startDragDistance)
- compare(control.parent, Overlay.overlay)
- }
-
- function test_invalidEdge() {
- var control = createTemporaryObject(drawer, testCase)
- compare(control.edge, Qt.LeftEdge)
-
- // Test an invalid value - it should warn and ignore it.
- ignoreWarning(Qt.resolvedUrl("tst_drawer.qml") + ":65:9: QML Drawer: invalid edge value - valid values are: Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge")
- control.edge = Drawer.Right
- compare(control.edge, Qt.LeftEdge)
- }
-
- Component {
- id: rectDrawer
-
- Drawer {
- Rectangle {
- width: 200
- height: 400
- color: "steelblue"
- }
- }
- }
-
- function test_swipeVelocity() {
- skip("QTBUG-52003");
-
- var control = createTemporaryObject(rectDrawer, testCase)
- verify(control.contentItem)
- compare(control.edge, Qt.LeftEdge)
- compare(control.position, 0.0)
-
- var dragDistance = Math.max(20, Qt.styleHints.startDragDistance + 5)
- var distance = dragDistance * 1.1
- if (distance >= control.width * 0.7)
- skip("This test requires a startDragDistance that is less than the opening threshold of the drawer")
-
- mousePress(control, 0, 0, Qt.LeftButton)
- mouseMove(control, distance, 0)
- verify(control.position > 0)
- tryCompare(control, "position", distance / control.contentItem.width)
- mouseRelease(control, distance, 0, Qt.LeftButton)
- tryCompare(control, "position", 1.0)
- }
-}
diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml
index 6f6497c5..3c0f0273 100644
--- a/tests/auto/controls/data/tst_stackview.qml
+++ b/tests/auto/controls/data/tst_stackview.qml
@@ -61,7 +61,7 @@ TestCase {
name: "StackView"
Item { id: item }
- TextField { id: textField }
+ Component { id: textField; TextField { } }
Component { id: component; Item { } }
Component {
@@ -323,22 +323,33 @@ TestCase {
compare(item.height, control.height)
}
- function test_focus() {
+ function test_focus_data() {
+ return [
+ { tag: "true", focus: true, forceActiveFocus: false },
+ { tag: "false", focus: false, forceActiveFocus: false },
+ { tag: "forceActiveFocus()", focus: false, forceActiveFocus: true },
+ ]
+ }
+
+ function test_focus(data) {
var control = createTemporaryObject(stackView, testCase, {initialItem: item, width: 200, height: 200})
verify(control)
- control.forceActiveFocus()
- verify(control.activeFocus)
+ if (data.focus)
+ control.focus = true
+ if (data.forceActiveFocus)
+ control.forceActiveFocus()
+ compare(control.activeFocus, data.focus || data.forceActiveFocus)
- control.push(textField, StackView.Immediate)
- compare(control.currentItem, textField)
- textField.forceActiveFocus()
- verify(textField.activeFocus)
+ var page = control.push(textField, StackView.Immediate)
+ verify(page)
+ compare(control.currentItem, page)
+ compare(page.activeFocus, control.activeFocus)
control.pop(StackView.Immediate)
compare(control.currentItem, item)
- verify(control.activeFocus)
- verify(!textField.activeFocus)
+ compare(item.activeFocus, data.focus || data.forceActiveFocus)
+ verify(!page.activeFocus)
}
function test_find() {
diff --git a/tests/auto/focus/tst_focus.cpp b/tests/auto/focus/tst_focus.cpp
index 3d4a8875..958b996b 100644
--- a/tests/auto/focus/tst_focus.cpp
+++ b/tests/auto/focus/tst_focus.cpp
@@ -67,6 +67,9 @@ private slots:
void reason();
void visualFocus();
+
+ void scope_data();
+ void scope();
};
void tst_focus::initTestCase()
@@ -326,6 +329,86 @@ void tst_focus::visualFocus()
QVERIFY(!button->property("showFocus").toBool());
}
+void tst_focus::scope_data()
+{
+ QTest::addColumn<QString>("name");
+
+ QTest::newRow("Frame") << "Frame";
+ QTest::newRow("GroupBox") << "Frame";
+ QTest::newRow("Page") << "Page";
+ QTest::newRow("Pane") << "Pane";
+ QTest::newRow("StackView") << "StackView";
+}
+
+void tst_focus::scope()
+{
+ QFETCH(QString, name);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(QString("import QtQuick 2.9; import QtQuick.Controls 2.2; ApplicationWindow { property alias child: child; width: 100; height: 100; %1 { anchors.fill: parent; Item { id: child; width: 10; height: 10 } } }").arg(name).toUtf8(), QUrl());
+
+ QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create()));
+ QVERIFY2(window, qPrintable(component.errorString()));
+
+ QQuickControl *control = qobject_cast<QQuickControl *>(window->contentItem()->childItems().first());
+ QVERIFY(control);
+
+ control->setFocusPolicy(Qt::WheelFocus);
+ control->setAcceptedMouseButtons(Qt::LeftButton);
+
+ QQuickItem *child = window->property("child").value<QQuickItem *>();
+ QVERIFY(child);
+
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
+ struct TouchDeviceDeleter
+ {
+ static inline void cleanup(QTouchDevice *device)
+ {
+ QWindowSystemInterface::unregisterTouchDevice(device);
+ delete device;
+ }
+ };
+
+ QScopedPointer<QTouchDevice, TouchDeviceDeleter> device(new QTouchDevice);
+ device->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(device.data());
+
+ child->forceActiveFocus();
+ QVERIFY(child->hasActiveFocus());
+ QVERIFY(control->hasActiveFocus());
+
+ // Qt::ClickFocus (mouse)
+ QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2));
+ QVERIFY(!child->hasActiveFocus());
+ QVERIFY(control->hasActiveFocus());
+
+ // reset
+ child->forceActiveFocus();
+ QVERIFY(child->hasActiveFocus());
+ QVERIFY(control->hasActiveFocus());
+
+ // Qt::ClickFocus (touch)
+ QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2));
+ QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2));
+ QVERIFY(!child->hasActiveFocus());
+ QVERIFY(control->hasActiveFocus());
+
+ // reset
+ child->forceActiveFocus();
+ QVERIFY(child->hasActiveFocus());
+ QVERIFY(control->hasActiveFocus());
+
+ // Qt::WheelFocus
+ QWheelEvent wheelEvent(QPoint(control->width() / 2, control->height() / 2), 10, Qt::NoButton, Qt::NoModifier);
+ QGuiApplication::sendEvent(control, &wheelEvent);
+ QVERIFY(!child->hasActiveFocus());
+ QVERIFY(control->hasActiveFocus());
+}
+
QTEST_MAIN(tst_focus)
#include "tst_focus.moc"
diff --git a/tests/auto/qquickdrawer/tst_qquickdrawer.cpp b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp
index 9f6a556f..60c5b189 100644
--- a/tests/auto/qquickdrawer/tst_qquickdrawer.cpp
+++ b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp
@@ -38,6 +38,7 @@
#include <QtTest/qsignalspy.h>
#include "../shared/util.h"
#include "../shared/visualtestutil.h"
+#include "../shared/qtest_quickcontrols.h"
#include <QtGui/qstylehints.h>
#include <QtGui/qtouchdevice.h>
@@ -61,6 +62,9 @@ class tst_QQuickDrawer : public QQmlDataTest
private slots:
void initTestCase();
+ void defaults();
+ void invalidEdge();
+
void visible_data();
void visible();
@@ -126,6 +130,40 @@ void tst_QQuickDrawer::initTestCase()
QWindowSystemInterface::registerTouchDevice(touchDevice.data());
}
+void tst_QQuickDrawer::defaults()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("window.qml"));
+
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY2(!root.isNull(), qPrintable(component.errorString()));
+
+ QQuickDrawer *drawer = root->property("drawer").value<QQuickDrawer *>();
+ QVERIFY(drawer);
+ QCOMPARE(drawer->edge(), Qt::LeftEdge);
+ QCOMPARE(drawer->position(), 0.0);
+ QCOMPARE(drawer->dragMargin(), qGuiApp->styleHints()->startDragDistance());
+}
+
+void tst_QQuickDrawer::invalidEdge()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("window.qml"));
+
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY2(!root.isNull(), qPrintable(component.errorString()));
+
+ QQuickDrawer *drawer = root->property("drawer").value<QQuickDrawer *>();
+ QVERIFY(drawer);
+
+ // Test an invalid value - it should warn and ignore it.
+ QTest::ignoreMessage(QtWarningMsg, qUtf8Printable(testFileUrl("window.qml").toString() + ":61:5: QML Drawer: invalid edge value - valid values are: Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge"));
+ drawer->setEdge(static_cast<Qt::Edge>(QQuickDrawer::Right));
+ QCOMPARE(drawer->edge(), Qt::LeftEdge);
+}
+
void tst_QQuickDrawer::visible_data()
{
QTest::addColumn<QString>("source");
@@ -1219,6 +1257,6 @@ void tst_QQuickDrawer::nonModal()
QVERIFY(closedSpy.wait());
}
-QTEST_MAIN(tst_QQuickDrawer)
+QTEST_QUICKCONTROLS_MAIN(tst_QQuickDrawer)
#include "tst_qquickdrawer.moc"
diff --git a/tests/auto/qquickpopup/tst_qquickpopup.cpp b/tests/auto/qquickpopup/tst_qquickpopup.cpp
index a1e5e246..9230116b 100644
--- a/tests/auto/qquickpopup/tst_qquickpopup.cpp
+++ b/tests/auto/qquickpopup/tst_qquickpopup.cpp
@@ -38,6 +38,7 @@
#include <QtTest/qsignalspy.h>
#include "../shared/util.h"
#include "../shared/visualtestutil.h"
+#include "../shared/qtest_quickcontrols.h"
#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
@@ -119,7 +120,7 @@ void tst_QQuickPopup::visible()
QVERIFY(overlay->childItems().contains(popupItem));
popup->close();
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
QVERIFY(!overlay->childItems().contains(popupItem));
popup->setVisible(true);
@@ -127,7 +128,7 @@ void tst_QQuickPopup::visible()
QVERIFY(overlay->childItems().contains(popupItem));
popup->setVisible(false);
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
QVERIFY(!overlay->childItems().contains(popupItem));
}
@@ -164,7 +165,7 @@ void tst_QQuickPopup::state()
QCOMPARE(closedSpy.count(), 0);
popup->close();
- QCOMPARE(visibleChangedSpy.count(), 2);
+ QTRY_COMPARE(visibleChangedSpy.count(), 2);
QCOMPARE(aboutToShowSpy.count(), 1);
QCOMPARE(aboutToHideSpy.count(), 1);
QCOMPARE(openedSpy.count(), 1);
@@ -236,6 +237,7 @@ void tst_QQuickPopup::overlay()
popup->open();
QVERIFY(popup->isVisible());
QVERIFY(overlay->isVisible());
+ QTRY_VERIFY(popup->isOpened());
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
@@ -243,16 +245,15 @@ void tst_QQuickPopup::overlay()
QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
+ QTRY_VERIFY(!popup->isVisible());
+ QVERIFY(!overlay->isVisible());
+
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); // no modal-popups open
QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
- popup->close();
- QVERIFY(!popup->isVisible());
- QVERIFY(!overlay->isVisible());
-
popup->setDim(dim);
popup->setModal(modal);
popup->setClosePolicy(QQuickPopup::CloseOnReleaseOutside);
@@ -261,6 +262,7 @@ void tst_QQuickPopup::overlay()
popup->open();
QVERIFY(popup->isVisible());
QVERIFY(overlay->isVisible());
+ QTRY_VERIFY(popup->isOpened());
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount);
@@ -274,8 +276,8 @@ void tst_QQuickPopup::overlay()
QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
- QVERIFY(!popup->isVisible());
- QCOMPARE(overlay->isVisible(), popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
+ QVERIFY(!overlay->isVisible());
// touch
popup->open();
@@ -307,8 +309,8 @@ void tst_QQuickPopup::overlay()
QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount);
QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount);
- QVERIFY(!popup->isVisible());
- QCOMPARE(overlay->isVisible(), popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
+ QVERIFY(!overlay->isVisible());
// multi-touch
popup->open();
@@ -331,7 +333,7 @@ void tst_QQuickPopup::overlay()
QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount);
QTest::touchEvent(window, device.data()).release(0, button->mapToScene(QPointF(1, 1)).toPoint()).stationary(1);
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
QVERIFY(!overlay->isVisible());
QVERIFY(!button->isPressed());
QCOMPARE(overlayPressedSignal.count(), overlayPressCount);
@@ -378,12 +380,12 @@ void tst_QQuickPopup::zOrder()
QVERIFY(popup->isVisible());
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
- QVERIFY(!popup2->isVisible());
+ QTRY_VERIFY(!popup2->isVisible());
QVERIFY(popup->isVisible());
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QVERIFY(!popup2->isVisible());
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
}
void tst_QQuickPopup::windowChange()
@@ -483,49 +485,55 @@ void tst_QQuickPopup::closePolicy()
popup->open();
QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
// press outside popup and its parent
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) || closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent))
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
else
QVERIFY(popup->isVisible());
popup->open();
QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
// release outside popup and its parent
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside))
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
else
QVERIFY(popup->isVisible());
popup->open();
QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
// press outside popup but inside its parent
- QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x(), button->y()));
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + 1, button->y() + 1));
if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent))
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
else
QVERIFY(popup->isVisible());
popup->open();
QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
// release outside popup but inside its parent
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x(), button->y()));
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + 1, button->y() + 1));
if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutsideParent))
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
else
QVERIFY(popup->isVisible());
popup->open();
QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
// press inside and release outside
- QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + popup->x(), button->y() + popup->y()));
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + popup->x() + 1,
+ button->y() + popup->y() + 1));
QVERIFY(popup->isVisible());
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QVERIFY(popup->isVisible());
@@ -533,7 +541,7 @@ void tst_QQuickPopup::closePolicy()
// escape
QTest::keyClick(window, Qt::Key_Escape);
if (closePolicy.testFlag(QQuickPopup::CloseOnEscape))
- QVERIFY(!popup->isVisible());
+ QTRY_VERIFY(!popup->isVisible());
else
QVERIFY(popup->isVisible());
}
@@ -556,14 +564,27 @@ void tst_QQuickPopup::activeFocusOnClose1()
focusedPopup->open();
QVERIFY(focusedPopup->isVisible());
+ QTRY_VERIFY(focusedPopup->isOpened());
QVERIFY(focusedPopup->hasActiveFocus());
nonFocusedPopup->open();
QVERIFY(nonFocusedPopup->isVisible());
+ QTRY_VERIFY(nonFocusedPopup->isOpened());
QVERIFY(focusedPopup->hasActiveFocus());
nonFocusedPopup->close();
- QVERIFY(!nonFocusedPopup->isVisible());
+ QTRY_VERIFY(!nonFocusedPopup->isVisible());
+ QVERIFY(focusedPopup->hasActiveFocus());
+
+ // QTBUG-66113: force active focus on a popup that did not request focus
+ nonFocusedPopup->open();
+ nonFocusedPopup->forceActiveFocus();
+ QVERIFY(nonFocusedPopup->isVisible());
+ QTRY_VERIFY(nonFocusedPopup->isOpened());
+ QVERIFY(nonFocusedPopup->hasActiveFocus());
+
+ nonFocusedPopup->close();
+ QTRY_VERIFY(!nonFocusedPopup->isVisible());
QVERIFY(focusedPopup->hasActiveFocus());
}
@@ -589,16 +610,18 @@ void tst_QQuickPopup::activeFocusOnClose2()
popup1->open();
QVERIFY(popup1->isVisible());
+ QTRY_VERIFY(popup1->isOpened());
QVERIFY(popup1->hasActiveFocus());
popup2->open();
QVERIFY(popup2->isVisible());
+ QTRY_VERIFY(popup2->isOpened());
QVERIFY(popup2->hasActiveFocus());
// Causes popup1.contentItem.forceActiveFocus() to be called, then closes popup2.
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier,
closePopup2Button->mapToScene(QPointF(closePopup2Button->width() / 2, closePopup2Button->height() / 2)).toPoint());
- QVERIFY(!popup2->isVisible());
+ QTRY_VERIFY(!popup2->isVisible());
QVERIFY(popup1->hasActiveFocus());
}
@@ -684,7 +707,7 @@ void tst_QQuickPopup::hover()
QVERIFY(!childButton->isHovered());
// hover the child button in a popup
- QTest::mouseMove(window, QPoint(2, 2));
+ QTest::mouseMove(window, QPoint(popup->x() + popup->width() / 2, popup->y() + popup->height() / 2));
QVERIFY(!parentButton->isHovered());
QVERIFY(childButton->isHovered());
@@ -834,35 +857,35 @@ void tst_QQuickPopup::grabber()
QVERIFY(combo);
menu->open();
- QCOMPARE(menu->isVisible(), true);
+ QTRY_COMPARE(menu->isOpened(), true);
QCOMPARE(popup->isVisible(), false);
QCOMPARE(combo->isVisible(), false);
// click a menu item to open the popup
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(menu->width() / 2, menu->height() / 2));
- QCOMPARE(menu->isVisible(), false);
- QCOMPARE(popup->isVisible(), true);
+ QTRY_COMPARE(menu->isVisible(), false);
+ QTRY_COMPARE(popup->isOpened(), true);
QCOMPARE(combo->isVisible(), false);
combo->open();
QCOMPARE(menu->isVisible(), false);
QCOMPARE(popup->isVisible(), true);
- QCOMPARE(combo->isVisible(), true);
+ QTRY_COMPARE(combo->isOpened(), true);
// click outside to close both the combo popup and the parent popup
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() - 1));
QCOMPARE(menu->isVisible(), false);
- QCOMPARE(popup->isVisible(), false);
- QCOMPARE(combo->isVisible(), false);
+ QTRY_COMPARE(popup->isVisible(), false);
+ QTRY_COMPARE(combo->isVisible(), false);
menu->open();
- QCOMPARE(menu->isVisible(), true);
+ QTRY_COMPARE(menu->isOpened(), true);
QCOMPARE(popup->isVisible(), false);
QCOMPARE(combo->isVisible(), false);
// click outside the menu to close it (QTBUG-56697)
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() - 1));
- QCOMPARE(menu->isVisible(), false);
+ QTRY_COMPARE(menu->isVisible(), false);
QCOMPARE(popup->isVisible(), false);
QCOMPARE(combo->isVisible(), false);
}
@@ -881,17 +904,18 @@ void tst_QQuickPopup::cursorShape()
popup->open();
QVERIFY(popup->isVisible());
+ QTRY_VERIFY(popup->isOpened());
QQuickItem *textField = helper.appWindow->property("textField").value<QQuickItem*>();
QVERIFY(textField);
// Move the mouse over the text field.
- const QPoint textFieldPos(popup->x() - 10, popup->y() + popup->height() / 2);
+ const QPoint textFieldPos(popup->x() - 10, textField->height() / 2);
QTest::mouseMove(window, textFieldPos);
QCOMPARE(window->cursor().shape(), textField->cursor().shape());
// Move the mouse over the popup where it overlaps with the text field.
- const QPoint textFieldOverlapPos(popup->x() + 10, popup->y() + popup->height() / 2);
+ const QPoint textFieldOverlapPos(popup->x() + 10, textField->height() / 2);
QTest::mouseMove(window, textFieldOverlapPos);
QCOMPARE(window->cursor().shape(), popup->popupItem()->cursor().shape());
@@ -1036,6 +1060,6 @@ void tst_QQuickPopup::orientation()
QCOMPARE(popup->popupItem()->position(), position);
}
-QTEST_MAIN(tst_QQuickPopup)
+QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
#include "tst_qquickpopup.moc"
diff --git a/tests/manual/testbench/controls/Button.qml b/tests/manual/testbench/controls/Button.qml
index 6d65b3ee..b1152481 100644
--- a/tests/manual/testbench/controls/Button.qml
+++ b/tests/manual/testbench/controls/Button.qml
@@ -58,23 +58,18 @@ QtObject {
["pressed"],
["checked"],
["checked", "disabled"],
- ["checked", "hovered"],
+ ["checked"],
["highlighted"],
["highlighted", "disabled"],
- ["highlighted", "hovered"],
["highlighted", "pressed"],
["highlighted", "checked"],
- ["highlighted", "checkable", "hovered"],
["highlighted", "checkable", "pressed"],
["highlighted", "checkable", "checked"],
- ["hovered"],
["flat"],
["flat", "disabled"],
- ["flat", "hovered"],
["flat", "pressed"],
["flat", "checked"],
["flat", "checkable"],
- ["flat", "checkable", "hovered"],
["flat", "checkable", "pressed"],
["flat", "checkable", "checked", "pressed"],
["flat", "checkable", "highlighted"],
@@ -87,6 +82,7 @@ QtObject {
enabled: !is("disabled")
flat: is("flat")
checkable: is("checkable")
+ checked: is("checked")
// Only set it if it's pressed, or the non-pressed examples will have no press effects
down: is("pressed") ? true : undefined
highlighted: is("highlighted")
diff --git a/tests/manual/testbench/controls/RoundButton.qml b/tests/manual/testbench/controls/RoundButton.qml
index 75eedf38..6a2bb5c2 100644
--- a/tests/manual/testbench/controls/RoundButton.qml
+++ b/tests/manual/testbench/controls/RoundButton.qml
@@ -58,23 +58,17 @@ QtObject {
["pressed"],
["checked"],
["checked", "disabled"],
- ["checked", "hovered"],
["highlighted"],
["highlighted", "disabled"],
- ["highlighted", "hovered"],
["highlighted", "pressed"],
["highlighted", "checked"],
- ["highlighted", "checkable", "hovered"],
["highlighted", "checkable", "pressed"],
["highlighted", "checkable", "checked"],
- ["hovered"],
["flat"],
["flat", "disabled"],
- ["flat", "hovered"],
["flat", "pressed"],
["flat", "checked"],
["flat", "checkable"],
- ["flat", "checkable", "hovered"],
["flat", "checkable", "pressed"],
["flat", "checkable", "checked", "pressed"],
["flat", "checkable", "highlighted"],