From 223c1524a7693e2c0f2312dd738c6aeb484358a5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 11 Apr 2017 15:22:35 +0200 Subject: QQuickPlatformMenu::open(): Scale target rectangle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QPlatform* classes operate in native pixels. Task-number: QTBUG-55251 Change-Id: Ic9715bc062f7459054ed9735d133b1a5d05b60a2 Reviewed-by: Morten Johan Sørvig --- src/imports/platform/qquickplatformmenu.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 #include #include +#include #include #include #include @@ -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); } /*! -- cgit v1.2.3 From e693ad2c4ae22f8813befd5fe825c855537497ed Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Wed, 31 Jan 2018 08:36:07 +0200 Subject: Add changes file for Qt 5.10.1 Change-Id: I27b28095a9481b962fe450be9f67b31f36880dac Reviewed-by: J-P Nurmi --- dist/changes-5.10.1 | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 dist/changes-5.10.1 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 -- cgit v1.2.3 From 7eb5f8a54bdcf0520a7aa0a2874a059060866097 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 1 Feb 2018 11:48:45 +0100 Subject: QQuickControl: respect click focus policy for focus scopes If a focus scope explicitly requests click focus, make it gain active focus by clearing the sub-focus child. Pane { focusPolicy: Qt.ClickFocus TextField { } } [ChangeLog][Controls][Control] Fixed focus scope controls, such as Frame, GroupBox, Page, and Pane, to respect click focus policy by clearing a potential sub-focus child. This makes it possible to close the virtual keyboard by clicking the background of a Pane that has Qt.ClickFocus set as its focusPolicy, for example. Task-number: QTBUG-66133 Change-Id: I582f3c66aa6f11e229d89c4f610fae3c6259104d Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcontrol.cpp | 12 +++++- tests/auto/focus/tst_focus.cpp | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 8d571c34..020997b1 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -160,11 +160,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) @@ -181,7 +189,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; } diff --git a/tests/auto/focus/tst_focus.cpp b/tests/auto/focus/tst_focus.cpp index 3d4a8875..ad7578d0 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,75 @@ void tst_focus::visualFocus() QVERIFY(!button->property("showFocus").toBool()); } +void tst_focus::scope_data() +{ + QTest::addColumn("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 window(qobject_cast(component.create())); + QVERIFY2(window, qPrintable(component.errorString())); + + QQuickControl *control = qobject_cast(window->contentItem()->childItems().first()); + QVERIFY(control); + + control->setFocusPolicy(Qt::WheelFocus); + control->setAcceptedMouseButtons(Qt::LeftButton); + + QQuickItem *child = window->property("child").value(); + 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 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()); +} + QTEST_MAIN(tst_focus) #include "tst_focus.moc" -- cgit v1.2.3 From 3c0f3ed5d5819a927d259e0dda7b3245cf43b110 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 5 Feb 2018 13:31:28 +0100 Subject: Add missing meta revision 3 for Label, TextArea, TextField Fixes: ".palette" is not available due to component versioning. Change-Id: I3687a5879bcdf8f1af36c1b32b796ce2fa7e879e Reviewed-by: Mitch Curtis --- src/imports/templates/qtquicktemplates2plugin.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp index 15a5f338..813ace40 100644 --- a/src/imports/templates/qtquicktemplates2plugin.cpp +++ b/src/imports/templates/qtquicktemplates2plugin.cpp @@ -299,6 +299,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri) qmlRegisterType(uri, 2, 3, "Dialog"); qmlRegisterType(uri, 2, 3, "DialogButtonBox"); qRegisterMetaType(); + qmlRegisterType(uri, 2, 3, "Label"); qmlRegisterType(uri, 2, 3, "Menu"); qmlRegisterType(uri, 2, 3, "MenuBar"); qmlRegisterType(uri, 2, 3, "MenuBarItem"); @@ -311,6 +312,8 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri) qmlRegisterType(uri, 2, 3, "ScrollIndicator"); qmlRegisterType(uri, 2, 3, "Slider"); qmlRegisterType(uri, 2, 3, "SpinBox"); + qmlRegisterType(uri, 2, 3, "TextArea"); + qmlRegisterType(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) -- cgit v1.2.3 From b9584b13d53f36da5585051346d03a86650961bc Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 5 Feb 2018 14:39:43 +0100 Subject: Editors: tweak placeholder text color Instead of using 50% translucent palette.text, use 50% translucent TextField::color (which defaults to palette.text) to make the placeholder text color follow the text color when changed directly without changing the palette. In the future, the placeholder text color should be exposed as a separate property to give users full control. Task-number: QTBUG-66176 Change-Id: I57153ff676be6518f9b48cdbd7da4089daa36853 Reviewed-by: Mitch Curtis --- src/imports/controls/TextArea.qml | 2 +- src/imports/controls/TextField.qml | 2 +- src/imports/controls/fusion/TextArea.qml | 2 +- src/imports/controls/fusion/TextField.qml | 2 +- src/imports/controls/imagine/TextArea.qml | 2 +- src/imports/controls/imagine/TextField.qml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/imports/controls/TextArea.qml b/src/imports/controls/TextArea.qml index 9021d558..2bda4ca9 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 52125501..cbecd198 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/fusion/TextArea.qml b/src/imports/controls/fusion/TextArea.qml index 6d47e237..6fc74660 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 686690bb..aef8475b 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/imagine/TextArea.qml b/src/imports/controls/imagine/TextArea.qml index ac212b95..a0e60230 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 a6449884..024698f8 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 -- cgit v1.2.3 From a5aa09dfd7e42f38545fe4640b0fa251bdd32be9 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 31 Jan 2018 16:28:07 +0100 Subject: Make AbstractButton's icon properties win over Action's when both are set Task-number: QTBUG-65193 Change-Id: Idff23dcc35f3c3fe41406678613b022098149318 Reviewed-by: J-P Nurmi --- src/quicktemplates2/qquickabstractbutton.cpp | 50 +++--- src/quicktemplates2/qquickabstractbutton_p_p.h | 3 + src/quicktemplates2/qquickicon.cpp | 82 ++++++++- src/quicktemplates2/qquickicon_p.h | 14 +- tests/auto/controls/data/tst_abstractbutton.qml | 221 ++++++++++++++++++++++-- 5 files changed, 321 insertions(+), 49 deletions(-) diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index b1522995..768b923b 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -306,6 +306,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); @@ -687,17 +702,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(); } /*! @@ -759,7 +771,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); @@ -770,33 +782,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()); @@ -807,6 +797,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 3b2a87f2..c82f8cf7 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -93,6 +93,8 @@ public: void actionTextChange(); void setText(const QString &text, bool isExplicit); + void updateEffectiveIcon(); + void click(); void trigger(); void toggle(bool value); @@ -119,6 +121,7 @@ public: QKeySequence shortcut; #endif QQuickIcon icon; + QQuickIcon effectiveIcon; QPointF pressPoint; Qt::MouseButtons pressButtons; QQuickDeferredPointer indicator; 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..5eb18205 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 name FINAL) + Q_PROPERTY(QUrl source READ source WRITE setSource RESET source FINAL) + Q_PROPERTY(int width READ width WRITE setWidth RESET width FINAL) + Q_PROPERTY(int height READ height WRITE setHeight RESET height 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 d; }; diff --git a/tests/auto/controls/data/tst_abstractbutton.qml b/tests/auto/controls/data/tst_abstractbutton.qml index 7acf9882..a46a08df 100644 --- a/tests/auto/controls/data/tst_abstractbutton.qml +++ b/tests/auto/controls/data/tst_abstractbutton.qml @@ -285,6 +285,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 { @@ -305,8 +507,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) @@ -316,14 +516,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 @@ -331,31 +527,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" @@ -363,7 +554,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 -- cgit v1.2.3 From f301decbe39d253cc979774e2f32cde9c1212e4c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 5 Feb 2018 16:17:31 +0100 Subject: Popup: fix restoring focus for popups that did not request focus When a popup closes, if it has active focus, it should restore focus back to where it was regardless of whether the popup originally requested focus. Even if a popup does not request focus on open, it may gain focus programmatically or when a control with click-focus is clicked, for example. Task-number: QTBUG-66113 Change-Id: I9a7c467abe781bbef390d74898d13b9a30b2695b Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickpopup.cpp | 9 ++++----- tests/auto/qquickpopup/tst_qquickpopup.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index bb5ce660..0ef4bd64 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -443,12 +443,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; emit q->aboutToHide(); } diff --git a/tests/auto/qquickpopup/tst_qquickpopup.cpp b/tests/auto/qquickpopup/tst_qquickpopup.cpp index 3f4b2d13..b113e5ec 100644 --- a/tests/auto/qquickpopup/tst_qquickpopup.cpp +++ b/tests/auto/qquickpopup/tst_qquickpopup.cpp @@ -521,6 +521,16 @@ void tst_QQuickPopup::activeFocusOnClose1() nonFocusedPopup->close(); QVERIFY(!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()); + QVERIFY(nonFocusedPopup->hasActiveFocus()); + + nonFocusedPopup->close(); + QVERIFY(!nonFocusedPopup->isVisible()); + QVERIFY(focusedPopup->hasActiveFocus()); } void tst_QQuickPopup::activeFocusOnClose2() -- cgit v1.2.3 From b3b079f1578527859aa1f5137ee8f2ec163923fb Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 6 Feb 2018 11:43:20 +0100 Subject: QQuickIcon: fix reset methods Task-number: QTBUG-65193 Change-Id: I6393d39add5c3643812084ef4702e843bac14702 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickicon_p.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/quicktemplates2/qquickicon_p.h b/src/quicktemplates2/qquickicon_p.h index 5eb18205..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 RESET name FINAL) - Q_PROPERTY(QUrl source READ source WRITE setSource RESET source FINAL) - Q_PROPERTY(int width READ width WRITE setWidth RESET width FINAL) - Q_PROPERTY(int height READ height WRITE setHeight RESET height 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: -- cgit v1.2.3 From e052684db6e0814a6a3397eb21e3ce9f922563da Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 2 Feb 2018 09:46:48 +0100 Subject: Fix memory leak in QQC2 When repeatedly creating a QQuickView, loading a QML file that imports QQC2 and deleting the view again, we would leak memory that was allocated as a consequence of QML type registration in initializeEngine() callbacks that were called on every iteration. After the limitation of namespacing in the registerTypes() callback of QML module plugins has been lifted, we can move the type registrations into registerTypes() where they belong and which is called only once. Change-Id: I7e314663a69fd8c8529195b56c128b61392c0042 Reviewed-by: J-P Nurmi Reviewed-by: Mitch Curtis Reviewed-by: Michael Winkelmann --- .../fusion/qtquickcontrols2fusionstyleplugin.cpp | 6 ---- .../imagine/qtquickcontrols2imaginestyleplugin.cpp | 6 ---- .../qtquickcontrols2materialstyleplugin.cpp | 6 ---- src/imports/controls/qtquickcontrols2plugin.cpp | 32 +++++++--------------- .../qtquickcontrols2universalstyleplugin.cpp | 6 ---- 5 files changed, 10 insertions(+), 46 deletions(-) diff --git a/src/imports/controls/fusion/qtquickcontrols2fusionstyleplugin.cpp b/src/imports/controls/fusion/qtquickcontrols2fusionstyleplugin.cpp index 9a329d03..542f088c 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; QQuickProxyTheme *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/qtquickcontrols2imaginestyleplugin.cpp b/src/imports/controls/imagine/qtquickcontrols2imaginestyleplugin.cpp index 7aa78075..2a613f1c 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; QQuickProxyTheme *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(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/qtquickcontrols2materialstyleplugin.cpp b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp index 7eae0826..33c14d04 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; QQuickProxyTheme *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(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 464bbbdf..d04d3018 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; QQuickProxyTheme *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(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(import, 2, 1, "TumblerView"); #endif - qmlRegisterSingletonType(import, 2, 1, "Default", styleSingleton); + qmlRegisterSingletonType(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(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(import, 2, 3, "ColorImage"); qmlRegisterType(import, 2, 3, "IconImage"); - qmlRegisterSingletonType(import, 2, 3, "Color", colorSingleton); + qmlRegisterSingletonType(import, 2, 3, "Color", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { + Q_UNUSED(engine); + Q_UNUSED(scriptEngine); + return new QQuickColor; + }); qmlRegisterType(import, 2, 3, "IconLabel"); qmlRegisterType(import, 2, 3, "CheckLabel"); qmlRegisterType(import, 2, 3, "MnemonicLabel"); diff --git a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp index 55255181..8e5477ec 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; QQuickProxyTheme *createTheme() const override; @@ -76,11 +75,6 @@ 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(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... -- cgit v1.2.3 From cf719053689c32967084fdac54b118e44d0b7b67 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 2 Feb 2018 12:03:45 +0100 Subject: QQuickControl: respect wheel focus policy for focus scopes [ChangeLog][Controls][Control] Fixed focus scope controls to respect wheel focus policy. Task-number: QTBUG-66133 Change-Id: If963feba4b6e59b87ca54af5f6606805093eb0cc Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcontrol.cpp | 2 +- tests/auto/focus/tst_focus.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 020997b1..4bf0a867 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -1459,7 +1459,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/tests/auto/focus/tst_focus.cpp b/tests/auto/focus/tst_focus.cpp index ad7578d0..958b996b 100644 --- a/tests/auto/focus/tst_focus.cpp +++ b/tests/auto/focus/tst_focus.cpp @@ -396,6 +396,17 @@ void tst_focus::scope() 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) -- cgit v1.2.3 From 44d02e3f0cf4db7e6d426c75de459019c574500a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 7 Feb 2018 20:20:02 +0100 Subject: Bump version Change-Id: I441fd7bf775a5eb02037fb51bd49b2f8b9efde96 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 8dc3e6e2..4518dc99 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ DEFINES += QT_NO_FOREACH QQC2_SOURCE_TREE = $$PWD -MODULE_VERSION = 5.9.4 +MODULE_VERSION = 5.9.5 -- cgit v1.2.3 From 4ff95c1ffa016f4d4844b5b790e83da1e4999b7d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 12:14:47 +0100 Subject: QQuickCheckDelegate: don't force tristate when partially checked Same as 339ddd4 for QQuickCheckBox. It was noticed missing from the delegate counterpart while updating the "New Features in Qt 5.11" wiki page. This allows a parent node to present partially checked state of child nodes without being interactively a tri-state box. [ChangeLog][Important Behavior Changes] CheckDelegate no longer forces tristate to true when setting checkState to Qt.PartiallyChecked. This allows a delegate to present a partially checked state without being interactively a tri-state check delegate. Task-number: QTBUG-56295 Change-Id: If4aaa499b53b60de0a170d3d0adb662474eddaad Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcheckdelegate.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/quicktemplates2/qquickcheckdelegate.cpp b/src/quicktemplates2/qquickcheckdelegate.cpp index 9fd8c183..9b0a8064 100644 --- a/src/quicktemplates2/qquickcheckdelegate.cpp +++ b/src/quicktemplates2/qquickcheckdelegate.cpp @@ -166,9 +166,6 @@ 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->checkState = state; -- cgit v1.2.3 From e318a1690e30986026e8428442003dc9e1640371 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 12:25:10 +0100 Subject: QQuickCheckDelegate: don't consider partially checked as checked Same as fbcdccc for QQuickCheckBox. It was noticed missing from the delegate counterpart while updating the "New Features in Qt 5.11" wiki page. [ChangeLog][Important Behavior Changes] CheckDelegate no longer considers the partially checked state as a checked state. This fixes check state cycling for a non-tri-state check delegate so that it goes from partially checked to fully checked state. Task-number: QTBUG-56295 Change-Id: I1de29178c265e027fdb91ba0b4604b110ddba06a Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcheckdelegate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quicktemplates2/qquickcheckdelegate.cpp b/src/quicktemplates2/qquickcheckdelegate.cpp index 9b0a8064..b53877df 100644 --- a/src/quicktemplates2/qquickcheckdelegate.cpp +++ b/src/quicktemplates2/qquickcheckdelegate.cpp @@ -167,7 +167,7 @@ void QQuickCheckDelegate::setCheckState(Qt::CheckState state) return; bool wasChecked = isChecked(); - d->checked = state != Qt::Unchecked; + d->checked = state == Qt::Checked; d->checkState = state; emit checkStateChanged(); if (d->checked != wasChecked) -- cgit v1.2.3 From 92c85dc58c198796b1682b0e9fb3f14ad724abd0 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 13:48:54 +0100 Subject: QQuickUniversalStyle: init the globals from the plugin Change-Id: I9df13f980b565b4f846edc3bce8333b74f5366b9 Reviewed-by: Mitch Curtis --- .../controls/universal/qquickuniversalstyle.cpp | 103 ++++++++++----------- .../controls/universal/qquickuniversalstyle_p.h | 3 +- .../qtquickcontrols2universalstyleplugin.cpp | 1 + 3 files changed, 51 insertions(+), 56 deletions(-) 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 settings = QQuickStylePrivate::settings(QStringLiteral("Universal")); - - bool ok = false; - QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_THEME", settings, QStringLiteral("Theme")); - Theme themeEnum = toEnumValue(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(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 settings = QQuickStylePrivate::settings(QStringLiteral("Universal")); + + bool ok = false; + QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_THEME", settings, QStringLiteral("Theme")); + Theme themeEnum = toEnumValue(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(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(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(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(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(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 8e5477ec..139acab9 100644 --- a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp +++ b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp @@ -69,6 +69,7 @@ public: QtQuickControls2UniversalStylePlugin::QtQuickControls2UniversalStylePlugin(QObject *parent) : QQuickStylePlugin(parent) { initResources(); + QQuickUniversalStyle::initGlobals(); } void QtQuickControls2UniversalStylePlugin::registerTypes(const char *uri) -- cgit v1.2.3 From 497a59f0dc54be5b3530f1803d13dc3b28bacca8 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 17:04:40 +0100 Subject: tst_QQuickDrawer: run with all styles Change-Id: I3cbd5aa20f48051ab80cf7e83661f17010129450 Reviewed-by: Mitch Curtis --- tests/auto/qquickdrawer/tst_qquickdrawer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/qquickdrawer/tst_qquickdrawer.cpp b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp index 9f6a556f..c89ecb62 100644 --- a/tests/auto/qquickdrawer/tst_qquickdrawer.cpp +++ b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp @@ -38,6 +38,7 @@ #include #include "../shared/util.h" #include "../shared/visualtestutil.h" +#include "../shared/qtest_quickcontrols.h" #include #include @@ -1219,6 +1220,6 @@ void tst_QQuickDrawer::nonModal() QVERIFY(closedSpy.wait()); } -QTEST_MAIN(tst_QQuickDrawer) +QTEST_QUICKCONTROLS_MAIN(tst_QQuickDrawer) #include "tst_qquickdrawer.moc" -- cgit v1.2.3 From 0209651826762a684bcc7ce499ad8af1b206d2b1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 16:57:55 +0100 Subject: tst_QQuickPopup: run with all styles Change-Id: I0f48ef8bbf0cb7567796dc67f1030d274f684d67 Reviewed-by: Mitch Curtis --- tests/auto/qquickpopup/tst_qquickpopup.cpp | 88 +++++++++++++++++------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/tests/auto/qquickpopup/tst_qquickpopup.cpp b/tests/auto/qquickpopup/tst_qquickpopup.cpp index 550655ef..9230116b 100644 --- a/tests/auto/qquickpopup/tst_qquickpopup.cpp +++ b/tests/auto/qquickpopup/tst_qquickpopup.cpp @@ -38,6 +38,7 @@ #include #include "../shared/util.h" #include "../shared/visualtestutil.h" +#include "../shared/qtest_quickcontrols.h" #include #include @@ -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,24 +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(); - QVERIFY(!nonFocusedPopup->isVisible()); + QTRY_VERIFY(!nonFocusedPopup->isVisible()); QVERIFY(focusedPopup->hasActiveFocus()); } @@ -599,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()); } @@ -694,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()); @@ -844,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); } @@ -891,17 +904,18 @@ void tst_QQuickPopup::cursorShape() popup->open(); QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); QQuickItem *textField = helper.appWindow->property("textField").value(); 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()); @@ -1046,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" -- cgit v1.2.3 From a8ffdd80df848f22935c21a9b8cb8d08e06a0e61 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 13 Feb 2018 10:18:57 +0100 Subject: Material Dial: decrease handle size from 14 to 10 The handle is not interactive; the whole dial is. As it is now, the handle looks way too big. Before and after this patch: https://imgur.com/a/amhN3 Change-Id: I13c03085d25ee2eb01090825f6baa531409e02a0 Reviewed-by: J-P Nurmi --- src/imports/controls/material/Dial.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 -- cgit v1.2.3 From 4f9878ffba258674932a7b1611b940e35b72eb8a Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 13 Feb 2018 10:25:43 +0100 Subject: Universal Dial: decrease handle size from 20 to 14 The handle is not interactive; the whole dial is. As it is now, the handle looks way too big. Before and after this patch: https://imgur.com/a/HEbeh Change-Id: I5db93a3e792a2133f765f69566bdd871598ab3b0 Reviewed-by: J-P Nurmi --- src/imports/controls/universal/Dial.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 -- cgit v1.2.3 From 47a97af21fc80c301677a4498ccda7397283f2af Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 18:40:06 +0100 Subject: Docs: update the version table for Qt 5.11 Change-Id: Ib653224d7e30b08ec80b148420717e7e9fec5e7a Reviewed-by: Mitch Curtis --- src/imports/controls/doc/src/qtquickcontrols2-index.qdoc | 5 +++++ 1 file changed, 5 insertions(+) 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 @@ -101,6 +101,11 @@ \li 2.10 \li 2.3 \li 1.0 + \row + \li 5.11 + \li 2.11 + \li 2.4 + \li 1.0 \row \li ... \li ... -- cgit v1.2.3 From eddd9d24ff1528ed84619725b37b55c7c90efff5 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 19:33:01 +0100 Subject: Docs: fix qdoc (clang) warnings qtquickcontrols2-automotive.qdoc:28: (qdoc) warning: EXAMPLE PATH DOES NOT EXIST: automotive qtquickcontrols2-musicplayer.qdoc:28: (qdoc) warning: EXAMPLE PATH DOES NOT EXIST: musicplayer qquickspinbox.cpp:814: (qdoc) warning: Can't link to 'textFromValue()' Change-Id: Iec6fd398cca98b514a76fe9f2f30c79a59b81457 Reviewed-by: Mitch Curtis --- .../imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc | 2 +- .../imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc | 2 +- src/quicktemplates2/qquickspinbox.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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/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) -- cgit v1.2.3 From e8f29483a4415e17fa999b2234f142a3304b7a75 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 19:55:13 +0100 Subject: Merge tst_drawer.qml to tst_QQuickDrawer Change-Id: I837f6991f5a3b66e3ded9e1408656013a0803d8f Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_drawer.qml | 118 --------------------------- tests/auto/qquickdrawer/tst_qquickdrawer.cpp | 37 +++++++++ 2 files changed, 37 insertions(+), 118 deletions(-) delete mode 100644 tests/auto/controls/data/tst_drawer.qml 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/qquickdrawer/tst_qquickdrawer.cpp b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp index c89ecb62..60c5b189 100644 --- a/tests/auto/qquickdrawer/tst_qquickdrawer.cpp +++ b/tests/auto/qquickdrawer/tst_qquickdrawer.cpp @@ -62,6 +62,9 @@ class tst_QQuickDrawer : public QQmlDataTest private slots: void initTestCase(); + void defaults(); + void invalidEdge(); + void visible_data(); void visible(); @@ -127,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 root(component.create()); + QVERIFY2(!root.isNull(), qPrintable(component.errorString())); + + QQuickDrawer *drawer = root->property("drawer").value(); + 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 root(component.create()); + QVERIFY2(!root.isNull(), qPrintable(component.errorString())); + + QQuickDrawer *drawer = root->property("drawer").value(); + 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(QQuickDrawer::Right)); + QCOMPARE(drawer->edge(), Qt::LeftEdge); +} + void tst_QQuickDrawer::visible_data() { QTest::addColumn("source"); -- cgit v1.2.3 From f4700f0dd655ca5254ac67021ab9570c1b0cba7d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 12 Feb 2018 22:37:35 +0100 Subject: QQuickStackView: transfer focus to the current item Task-number: QTBUG-51321 Change-Id: I169491d3e04f3ce015f5a999935f45ec02b1b5ae Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickstackview_p.cpp | 2 ++ tests/auto/controls/data/tst_stackview.qml | 31 ++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) 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_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() { -- cgit v1.2.3 From 170d9aa423fbaa4b37889808bd6901df0badf1cf Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 14 Feb 2018 12:06:14 +0100 Subject: testbench: set checked on Button Change-Id: Ic63b9c17318b357f4f34a5c49ff3d27bb438856c Reviewed-by: J-P Nurmi --- tests/manual/testbench/controls/Button.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/manual/testbench/controls/Button.qml b/tests/manual/testbench/controls/Button.qml index 6d65b3ee..aa125b9d 100644 --- a/tests/manual/testbench/controls/Button.qml +++ b/tests/manual/testbench/controls/Button.qml @@ -87,6 +87,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") -- cgit v1.2.3 From d95e67c291d213cdbf41b23c535b47aa3a553ab5 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 14 Feb 2018 13:14:59 +0100 Subject: testbench: remove hovered states as the property is read-only Change-Id: Iebc19620b34d9a8a7cc954c9486b739eed1de4a4 Reviewed-by: J-P Nurmi --- tests/manual/testbench/controls/Button.qml | 7 +------ tests/manual/testbench/controls/RoundButton.qml | 6 ------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/manual/testbench/controls/Button.qml b/tests/manual/testbench/controls/Button.qml index aa125b9d..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"], 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"], -- cgit v1.2.3