diff options
-rw-r--r-- | src/quickcontrols2impl/qquickiconlabel.cpp | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickabstractbutton.cpp | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickaction.cpp | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickicon.cpp | 36 | ||||
-rw-r--r-- | src/quicktemplates2/qquickicon_p.h | 5 | ||||
-rw-r--r-- | tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml | 13 | ||||
-rw-r--r-- | tests/auto/quickcontrols2/qquickiconlabel/data/sub/Actions.qml | 6 | ||||
-rw-r--r-- | tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp | 9 |
8 files changed, 51 insertions, 24 deletions
diff --git a/src/quickcontrols2impl/qquickiconlabel.cpp b/src/quickcontrols2impl/qquickiconlabel.cpp index 111c68cc98..b18d483675 100644 --- a/src/quickcontrols2impl/qquickiconlabel.cpp +++ b/src/quickcontrols2impl/qquickiconlabel.cpp @@ -399,7 +399,7 @@ void QQuickIconLabel::setIcon(const QQuickIcon &icon) return; d->icon = icon; - d->icon.setOwner(this); + d->icon.ensureRelativeSourceResolved(this); d->updateOrSyncImage(); } diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 11a6fb7152..a6a94b0ba7 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -790,7 +790,7 @@ void QQuickAbstractButton::setIcon(const QQuickIcon &icon) { Q_D(QQuickAbstractButton); d->icon = icon; - d->icon.setOwner(this); + d->icon.ensureRelativeSourceResolved(this); d->updateEffectiveIcon(); } diff --git a/src/quicktemplates2/qquickaction.cpp b/src/quicktemplates2/qquickaction.cpp index d8e49add90..193169162d 100644 --- a/src/quicktemplates2/qquickaction.cpp +++ b/src/quicktemplates2/qquickaction.cpp @@ -403,7 +403,7 @@ void QQuickAction::setIcon(const QQuickIcon &icon) return; d->icon = icon; - d->icon.setOwner(this); + d->icon.ensureRelativeSourceResolved(this); emit iconChanged(icon); } diff --git a/src/quicktemplates2/qquickicon.cpp b/src/quicktemplates2/qquickicon.cpp index 2b58529ec1..5cc1f793c0 100644 --- a/src/quicktemplates2/qquickicon.cpp +++ b/src/quicktemplates2/qquickicon.cpp @@ -59,6 +59,7 @@ public: QString name; QUrl source; + QUrl resolvedSource; int width = 0; int height = 0; QColor color = Qt::transparent; @@ -104,6 +105,7 @@ bool QQuickIcon::operator==(const QQuickIcon &other) const { return d == other.d || (d->name == other.d->name && d->source == other.d->source + && d->resolvedSource == other.d->resolvedSource && d->width == other.d->width && d->height == other.d->height && d->color == other.d->color @@ -154,6 +156,7 @@ void QQuickIcon::setSource(const QUrl &source) d.detach(); d->source = source; + d->resolvedSource.clear(); d->resolveMask |= QQuickIconPrivate::SourceResolved; } @@ -161,18 +164,27 @@ void QQuickIcon::resetSource() { d.detach(); d->source = QString(); + d->resolvedSource.clear(); d->resolveMask &= ~QQuickIconPrivate::SourceResolved; } QUrl QQuickIcon::resolvedSource() const { - if (QObject *owner = d->ownerAndCache.data()) { - QQmlData *data = QQmlData::get(owner); - if (data && data->outerContext) - return data->outerContext->resolvedUrl(d->source); - } + return d->resolvedSource.isEmpty() ? d->source : d->resolvedSource; +} - return d->source; +// must be called by the property owner (e.g. Button) prior to emitting changed signal. +void QQuickIcon::ensureRelativeSourceResolved(const QObject *owner) +{ + if (d->source.isEmpty()) + return; + if (!d->resolvedSource.isEmpty()) + return; // already resolved relative to (possibly) different owner + const QQmlData *data = QQmlData::get(owner); + if (!data || !data->outerContext) + return; + d.detach(); + d->resolvedSource = data->outerContext->resolvedUrl(d->source); } int QQuickIcon::width() const @@ -264,14 +276,6 @@ void QQuickIcon::resetCache() d->resolveMask &= ~QQuickIconPrivate::CacheResolved; } -void QQuickIcon::setOwner(QObject *owner) -{ - if (d->ownerAndCache.data() == owner) - return; - d.detach(); - d->ownerAndCache = owner; -} - QQuickIcon QQuickIcon::resolve(const QQuickIcon &other) const { QQuickIcon resolved = *this; @@ -280,8 +284,10 @@ QQuickIcon QQuickIcon::resolve(const QQuickIcon &other) const if (!(d->resolveMask & QQuickIconPrivate::NameResolved)) resolved.d->name = other.d->name; - if (!(d->resolveMask & QQuickIconPrivate::SourceResolved)) + if (!(d->resolveMask & QQuickIconPrivate::SourceResolved)) { resolved.d->source = other.d->source; + resolved.d->resolvedSource = other.d->resolvedSource; + } if (!(d->resolveMask & QQuickIconPrivate::WidthResolved)) resolved.d->width = other.d->width; diff --git a/src/quicktemplates2/qquickicon_p.h b/src/quicktemplates2/qquickicon_p.h index aa05055e5f..0312812429 100644 --- a/src/quicktemplates2/qquickicon_p.h +++ b/src/quicktemplates2/qquickicon_p.h @@ -91,6 +91,7 @@ public: void setSource(const QUrl &source); void resetSource(); QUrl resolvedSource() const; + void ensureRelativeSourceResolved(const QObject *owner); int width() const; void setWidth(int width); @@ -108,10 +109,6 @@ public: void setCache(bool cache); void resetCache(); - // owner is not a property - it is set internally by classes using icon - // so that we can resolve relative URL's correctly - void setOwner(QObject *owner); - QQuickIcon resolve(const QQuickIcon &other) const; private: diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml index 0d562d1500..8cf09666d0 100644 --- a/tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml @@ -1,7 +1,18 @@ -import QtQuick.Controls import QtQuick +import QtQuick.Controls.Basic +import QtQuick.Controls.impl +import "sub" as Sub Item { Image { source: "a.png" } IconLabel { icon.source: "a.png" } + Button { + icon.color: "transparent" + icon.source: "a.png" + } + Button { + action: actions.action + icon.color: "transparent" + Sub.Actions { id: actions } + } } diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/sub/Actions.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/sub/Actions.qml new file mode 100644 index 0000000000..20bd6a5e6b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/sub/Actions.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls.Basic + +QtObject { + readonly property Action action: Action { icon.source: "../a.png" } +} diff --git a/tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp b/tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp index 2ee0bf4c9f..13aad8b465 100644 --- a/tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp +++ b/tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp @@ -37,6 +37,7 @@ #include <QtQuick/private/qquickimage_p_p.h> #include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> #include <QtQuickTemplates2/private/qquickicon_p.h> #include <QtQuickControls2Impl/private/qquickiconimage_p.h> #include <QtQuickControls2Impl/private/qquickiconlabel_p.h> @@ -345,7 +346,13 @@ void tst_qquickiconlabel::iconSourceContext() for (QQuickItem *child : root->childItems()) { QQuickImage *image = qobject_cast<QQuickImage *>(child); if (!image) { - if (QQuickIconLabel *label = qobject_cast<QQuickIconLabel *>(child)) { + QQuickIconLabel *label = nullptr; + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(child)) { + label = qobject_cast<QQuickIconLabel *>(button->contentItem()); + } else { + label = qobject_cast<QQuickIconLabel *>(child); + } + if (label) { QQuickIconLabelPrivate *labelPrivate = static_cast<QQuickIconLabelPrivate *>( QQuickItemPrivate::get(label)); image = labelPrivate->image; |