=== modified file 'components.api'
--- components.api	2015-08-04 20:07:41 +0000
+++ components.api	2015-08-06 18:06:52 +0000
@@ -878,7 +878,7 @@
 Ubuntu.Components.StateSaver 1.0 0.1: QtObject
 Ubuntu.Components.StyleHints 1.3: QtObject
     property bool ignoreUnknownProperties
-Ubuntu.Components.StyledItem 1.3 1.3 1.1 1.0 0.1: Item
+Ubuntu.Components.StyledItem 1.3 1.1 1.0 0.1: Item
     property bool activeFocusOnPress 1.3
     function bool requestFocus(Qt.FocusReason reason) 1.3
     function bool requestFocus() 1.3
@@ -1238,6 +1238,7 @@
 UCStateSaverAttached: QtObject
     property bool enabled
     property string properties
+UCThemingAttached: QtObject
 Ubuntu.Components.UCUnits 1.0 0.1: QtObject
     property float gridUnit
     function float dp(float value)

=== modified file 'src/Ubuntu/Components/plugin/plugin.cpp'
--- src/Ubuntu/Components/plugin/plugin.cpp	2015-07-23 11:49:38 +0000
+++ src/Ubuntu/Components/plugin/plugin.cpp	2015-08-06 18:06:52 +0000
@@ -22,6 +22,7 @@
 
 #include "plugin.h"
 #include "uctheme.h"
+#include "ucthemingattached.h"
 #include "ucdeprecatedtheme.h"
 
 #include <QtQml/QQmlContext>
@@ -208,11 +209,11 @@
     qmlRegisterType<UCUbuntuShapeOverlay>(uri, 1, 2, "UbuntuShapeOverlay");
 
     // register 1.3 API
+    qmlRegisterType<UCThemingAttached>();
     qmlRegisterType<UCListItem13>(uri, 1, 3, "ListItem");
     qmlRegisterType<UCTheme>(uri, 1, 3, "ThemeSettings");
     qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem");
     qmlRegisterSingletonType<UCNamespaceV13>(uri, 1, 3, "Ubuntu", registerUbuntuNamespace13);
-    qmlRegisterType<UCStyledItemBase, 2>(uri, 1, 3, "StyledItem");
     qmlRegisterCustomType<UCStyleHints>(uri, 1, 3, "StyleHints", new UCStyleHintsParser);
     qmlRegisterType<UCAction, 1>(uri, 1, 3, "Action");
     qmlRegisterType<UCUbuntuShape, 2>(uri, 1, 3, "UbuntuShape");

=== modified file 'src/Ubuntu/Components/plugin/plugin.pri'
--- src/Ubuntu/Components/plugin/plugin.pri	2015-07-30 09:57:45 +0000
+++ src/Ubuntu/Components/plugin/plugin.pri	2015-08-06 18:06:52 +0000
@@ -76,7 +76,8 @@
     $$PWD/ucnamespace.h \
     $$PWD/ucdeprecatedtheme.h \
     $$PWD/ucdefaulttheme.h \
-    $$PWD/ucstylehints.h
+    $$PWD/ucstylehints.h \
+    $$PWD/ucthemingattached.h
 
 SOURCES += $$PWD/plugin.cpp \
     $$PWD/uctheme.cpp \
@@ -125,7 +126,8 @@
     $$PWD/ucnamespace.cpp \
     $$PWD/ucdeprecatedtheme.cpp \
     $$PWD/ucdefaulttheme.cpp \
-    $$PWD/ucstylehints.cpp
+    $$PWD/ucstylehints.cpp \
+    $$PWD/ucthemingattached.cpp
 
 # adapters
 SOURCES += $$PWD/adapters/alarmsadapter_organizer.cpp

=== modified file 'src/Ubuntu/Components/plugin/ucstyleditembase.cpp'
--- src/Ubuntu/Components/plugin/ucstyleditembase.cpp	2015-07-29 11:41:16 +0000
+++ src/Ubuntu/Components/plugin/ucstyleditembase.cpp	2015-08-06 18:06:52 +0000
@@ -18,18 +18,16 @@
 
 #include "ucstyleditembase.h"
 #include "ucstyleditembase_p.h"
+#include "ucthemingattached.h"
 #include "uctheme.h"
 #include "ucstylehints.h"
 #include <QtQml/QQmlEngine>
 #include <QtQuick/private/qquickanchors_p.h>
 
 UCStyledItemBasePrivate::UCStyledItemBasePrivate()
-    : activeFocusOnPress(false)
-    , styleComponent(0)
-    , styleItemContext(0)
+    : styleComponent(0)
     , styleItem(0)
-    , theme(0)
-    , parentStyledItem(0)
+    , activeFocusOnPress(false)
 {
 }
 
@@ -41,10 +39,6 @@
 {
     Q_Q(UCStyledItemBase);
     q->setFlag(QQuickItem::ItemIsFocusScope);
-    QObject::connect(&UCTheme::defaultTheme(), SIGNAL(nameChanged()),
-                     q, SLOT(_q_reloadStyle()));
-    QObject::connect(&UCTheme::defaultTheme(), SIGNAL(versionChanged()),
-                     q, SLOT(_q_reloadStyle()));
 }
 
 
@@ -455,75 +449,14 @@
  */
 UCTheme *UCStyledItemBasePrivate::getTheme() const
 {
-    if (theme) {
-        return theme;
-    } else if (!parentStyledItem.isNull()) {
-        return UCStyledItemBasePrivate::get(parentStyledItem)->getTheme();
-    }
-    return &UCTheme::defaultTheme();
+    return theming ? theming->getTheme() : &UCTheme::defaultTheme();
 }
 void UCStyledItemBasePrivate::setTheme(UCTheme *newTheme)
 {
-    Q_Q(UCStyledItemBase);
-    if (theme == newTheme) {
+    if (theming && !theming->setTheme(newTheme)) {
         return;
     }
 
-    // preform pre-theme change tasks
-    preThemeChanged();
-
-    // disconnect from the previous set
-    UCTheme *connectedSet = theme ?
-                                theme :
-                                (!parentStyledItem ? &UCTheme::defaultTheme() : NULL);
-    if (connectedSet) {
-        QObject::disconnect(connectedSet, SIGNAL(nameChanged()),
-                            q, SLOT(_q_reloadStyle()));
-        QObject::disconnect(connectedSet, SIGNAL(versionChanged()),
-                            q, SLOT(_q_reloadStyle()));
-    }
-
-    UCTheme *prevSet = theme;
-
-    // resolve new theme
-    if (theme && newTheme) {
-        // no need to redo the parentStack, simply set the theme and leave
-        theme = newTheme;
-    } else {
-        theme = newTheme;
-        if (!newTheme) {
-            // redo the parent chanin
-            disconnectTillItem(0);
-            connectParents(0);
-        }
-    }
-
-    // connect to the new set
-    connectedSet = theme ?
-                    theme :
-                    (!parentStyledItem ? &UCTheme::defaultTheme() : NULL);
-    if (connectedSet) {
-        QObject::connect(connectedSet, SIGNAL(nameChanged()),
-                         q, SLOT(_q_reloadStyle()));
-        QObject::connect(connectedSet, SIGNAL(versionChanged()),
-                         q, SLOT(_q_reloadStyle()));
-    }
-    // detach previous set and attach the new one
-    if (prevSet) {
-        Q_EMIT prevSet->parentThemeChanged();
-    }
-    if (theme) {
-        // re-parent theme to make sure we have it
-        // for the entire lifetime of the styled item
-        theme->setParent(q);
-        Q_EMIT theme->parentThemeChanged();
-    }
-
-    // perform post-theme changes, update internal styling
-    postThemeChanged();
-
-    Q_EMIT q->themeChanged();
-
     // perform style reload
     if (!styleComponent) {
         preStyleChanged();
@@ -533,102 +466,22 @@
 }
 void UCStyledItemBasePrivate::resetTheme()
 {
-    setTheme(NULL);
-}
-
-// link/unlink all ascendant items until we reach a StyledItem, returns true if the
-// theme change signal emission is justified
-bool UCStyledItemBasePrivate::connectParents(QQuickItem *fromItem)
-{
-    Q_Q(UCStyledItemBase);
-    QQuickItem *item = fromItem ? fromItem : parentItem;
-    while (item) {
-        // push the item onto the stack
-        parentStack.push(QPointer<QQuickItem>(item));
-        UCStyledItemBase *styledItem = qobject_cast<UCStyledItemBase*>(item);
-        if (styledItem) {
-            // this is the closest StyledItem, connect its themeChanged() signal
-            QObject::connect(styledItem, SIGNAL(themeChanged()),
-                             q, SLOT(_q_parentStyleChanged()), Qt::DirectConnection);
-            // set the current style set to the one in the parent's one if differs
-            return setParentStyled(styledItem);
-        } else {
-            // connect to the item's parentChanged() signal so we can detect when the parent changes
-            QObject::connect(item, SIGNAL(parentChanged(QQuickItem*)),
-                             q, SLOT(_q_ascendantChanged(QQuickItem*)), Qt::DirectConnection);
-        }
-        item = item->parentItem();
-    }
-    return false;
-}
-
-// set the used parent styled item's style; returns true if the parent styled got changed
-bool UCStyledItemBasePrivate::setParentStyled(UCStyledItemBase *styledItem)
-{
-    if (parentStyledItem == styledItem) {
-        return false;
-    }
-    parentStyledItem = styledItem;
-    if (theme) {
-        Q_EMIT theme->parentThemeChanged();
-    }
-    return (theme == NULL);
-}
-
-// disconnect parent stack till item is reached; all the stack if item == 0
-void UCStyledItemBasePrivate::disconnectTillItem(QQuickItem *item)
-{
-    Q_Q(UCStyledItemBase);
-    while (!parentStack.isEmpty() && item != parentStack.top()) {
-        QPointer<QQuickItem> stackItem = parentStack.pop();
-        // the topmost item can be the only one which is a StyledItem
-        UCStyledItemBase *styledItem = qobject_cast<UCStyledItemBase*>(stackItem.data());
-        if (styledItem) {
-            QObject::disconnect(styledItem, SIGNAL(themeChanged()),
-                                q, SLOT(_q_parentStyleChanged()));
-        } else if (!stackItem.isNull()) {
-            QObject::disconnect(stackItem.data(), SIGNAL(parentChanged(QQuickItem*)),
-                                q, SLOT(_q_ascendantChanged(QQuickItem*)));
-        }
-    }
-}
-
-// captures ascendant change signal, the sender is the one which counts!
-void UCStyledItemBasePrivate::_q_ascendantChanged(QQuickItem *ascendant)
-{
-    Q_Q(UCStyledItemBase);
-    QQuickItem *sender = static_cast<QQuickItem*>(q->sender());
-    if (!sender) {
-        // cannot detect the sender, leave!
-        return;
-    }
-    if (ascendant) {
-        // disconnect from the previous ones
-        disconnectTillItem(sender);
-        parentStyledItem.clear();
-        // traverse ascendants till we reach a StyledItem or root and push them into the stack
-        if (connectParents(ascendant)) {
-            Q_EMIT q->themeChanged();
-        }
-    }
-}
-
-// syncs the ascendant StyledItem's style
-void UCStyledItemBasePrivate::_q_parentStyleChanged()
-{
-    // do not trigger themeChanged() on this item if we have a
-    // custom one, but resolve its eventual parent change!
-    if (theme) {
-        Q_EMIT theme->parentThemeChanged();
-        return;
-    }
-    Q_Q(UCStyledItemBase);
-    UCStyledItemBase *styledItem = static_cast<UCStyledItemBase*>(q->sender());
-    if (!styledItem) {
-        return;
-    }
-    setParentStyled(styledItem);
-    Q_EMIT q->themeChanged();
+    theming->setTheme(Q_NULLPTR);
+}
+
+
+void UCStyledItemBase::classBegin()
+{
+    QQuickItem::classBegin();
+
+    Q_D(UCStyledItemBase);
+    // attach theming
+    d->theming = UCThemingAttached::attachTheming(this);
+    if (d->theming) {
+        d->theming->setListener(d);
+        connect(d->theming.data(), SIGNAL(themeChanged()),
+                         this, SLOT(_q_reloadStyle()));
+    }
 }
 
 void UCStyledItemBase::componentComplete()
@@ -667,20 +520,4 @@
     return QQuickItem::childMouseEventFilter(child, event);
 }
 
-// catch parent change event so we can lookup for the parent chain theme
-void UCStyledItemBase::itemChange(ItemChange change, const ItemChangeData &data)
-{
-    QQuickItem::itemChange(change, data);
-    if (change == ItemParentHasChanged) {
-        Q_D(UCStyledItemBase);
-        // clean stack
-        d->disconnectTillItem(0);
-        // make sure we reset parent StyledItem
-        d->parentStyledItem.clear();
-        // build the stack - if possible
-        d->connectParents(0);
-        Q_EMIT themeChanged();
-    }
-}
-
 #include "moc_ucstyleditembase.cpp"

=== modified file 'src/Ubuntu/Components/plugin/ucstyleditembase.h'
--- src/Ubuntu/Components/plugin/ucstyleditembase.h	2015-06-02 12:37:41 +0000
+++ src/Ubuntu/Components/plugin/ucstyleditembase.h	2015-08-06 18:06:52 +0000
@@ -53,16 +53,14 @@
 protected:
     UCStyledItemBase(UCStyledItemBasePrivate &, QQuickItem *parent);
 
+    void classBegin();
     void componentComplete();
     void mousePressEvent(QMouseEvent *event);
     bool childMouseEventFilter(QQuickItem *child, QEvent *event);
-    void itemChange(ItemChange, const ItemChangeData &);
 
 private:
     Q_DECLARE_PRIVATE(UCStyledItemBase)
     Q_PRIVATE_SLOT(d_func(), void _q_styleResized())
-    Q_PRIVATE_SLOT(d_func(), void _q_ascendantChanged(QQuickItem*))
-    Q_PRIVATE_SLOT(d_func(), void _q_parentStyleChanged())
     Q_PRIVATE_SLOT(d_func(), void _q_reloadStyle())
 };
 

=== modified file 'src/Ubuntu/Components/plugin/ucstyleditembase_p.h'
--- src/Ubuntu/Components/plugin/ucstyleditembase_p.h	2015-06-02 12:37:41 +0000
+++ src/Ubuntu/Components/plugin/ucstyleditembase_p.h	2015-08-06 18:06:52 +0000
@@ -21,10 +21,11 @@
 
 #include <QtQuick/private/qquickitem_p.h>
 #include "ucstyleditembase.h"
+#include "ucthemingattached.h"
 
 class QQuickMouseArea;
 class UCStyledItemBase;
-class UCStyledItemBasePrivate : public QQuickItemPrivate
+class UCStyledItemBasePrivate : public QQuickItemPrivate, public UCThemeChangeListener
 {
     Q_DECLARE_PUBLIC(UCStyledItemBase)
 public:
@@ -35,8 +36,6 @@
 
     void _q_reloadStyle();
     void _q_styleResized();
-    void _q_ascendantChanged(QQuickItem *ascendant);
-    void _q_parentStyleChanged();
 
     UCStyledItemBasePrivate();
     virtual ~UCStyledItemBasePrivate();
@@ -61,25 +60,19 @@
     void setTheme(UCTheme *theme);
     void resetTheme();
 
-    virtual void preThemeChanged(){}
-    virtual void postThemeChanged(){}
+    void preThemeChanged(){}
+    void postThemeChanged(){}
 
 public:
-    bool activeFocusOnPress:1;
     QString styleDocument;
+    QPointer<UCThemingAttached> theming;
+    QPointer<QQmlContext> styleItemContext;
     QQmlComponent *styleComponent;
-    QPointer<QQmlContext> styleItemContext;
     QQuickItem *styleItem;
-    UCTheme *theme;
-    QPointer<UCStyledItemBase> parentStyledItem;
+    bool activeFocusOnPress:1;
 
 protected:
-    QStack< QPointer<QQuickItem> > parentStack;
-
     void connectStyleSizeChanges(bool attach);
-    bool connectParents(QQuickItem *fromItem);
-    bool setParentStyled(UCStyledItemBase *styledItem);
-    void disconnectTillItem(QQuickItem *item);
 };
 
 #endif // UCSTYLEDITEMBASE_P_H

=== modified file 'src/Ubuntu/Components/plugin/uctheme.cpp'
--- src/Ubuntu/Components/plugin/uctheme.cpp	2015-07-20 12:56:17 +0000
+++ src/Ubuntu/Components/plugin/uctheme.cpp	2015-08-06 18:06:52 +0000
@@ -24,6 +24,7 @@
 #include "i18n.h"
 #include "ucfontutils.h"
 #include "ucstyleditembase_p.h"
+#include "ucthemingattached.h"
 
 #include <QtQml/qqml.h>
 #include <QtQml/qqmlinfo.h>
@@ -422,10 +423,9 @@
  */
 UCTheme *UCTheme::parentTheme()
 {
-    UCStyledItemBase *owner = qobject_cast<UCStyledItemBase*>(parent());
-    UCStyledItemBasePrivate *pOwner = owner ? UCStyledItemBasePrivate::get(owner) : NULL;
-    if (pOwner && pOwner->theme == this && pOwner->parentStyledItem) {
-        return UCStyledItemBasePrivate::get(pOwner->parentStyledItem)->getTheme();
+    UCThemingAttached *theming = itemTheming(static_cast<QQuickItem*>(parent()));
+    if (theming && theming->m_theme == this && theming->m_parentTheming) {
+        return theming->m_parentTheming->getTheme();
     }
     return NULL;
 }

=== added file 'src/Ubuntu/Components/plugin/ucthemingattached.cpp'
--- src/Ubuntu/Components/plugin/ucthemingattached.cpp	1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucthemingattached.cpp	2015-08-06 18:06:52 +0000
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Zsombor Egri <zsombor.egri@canonical.com>
+ */
+
+#include "ucthemingattached.h"
+#include <QtQuick/QQuickItem>
+#include "uctheme.h"
+
+/*
+ * UCThemingAttached is an attached object to all themable components. It is used
+ * internally by those components which need theme access thru the theme property.
+ * Components which want to use this should do the following:
+ * - attach the object in classBegin() function
+ * - expose a theme property
+ * - getter should use the getTheme() attached function
+ * - setter/reset should use the setTheme() attached function
+ * - themeChanged() signal must be connected to the property change signal
+ *
+ * The theme change is notified through listener callbacks. Registering listener
+ * is not mandatory.
+ */
+
+UCThemingAttached *itemTheming(QQuickItem *item)
+{
+    return qobject_cast<UCThemingAttached*>(
+                qmlAttachedPropertiesObject<UCThemingAttached>(item, false));
+}
+
+UCThemingAttached::UCThemingAttached(QObject *parent)
+    : QObject(parent)
+    , m_theme(Q_NULLPTR)
+    , m_listener(Q_NULLPTR)
+    , m_ownerItem(static_cast<QQuickItem*>(parent))
+{
+}
+
+UCThemingAttached *UCThemingAttached::qmlAttachedProperties(QObject *owner)
+{
+    UCThemingAttached *theming = new UCThemingAttached(owner);
+    // the theme is the default one at this stage, so connect all the necessary signals
+    // owner must have theme signal
+    theming->connectThemeSignals(theming->getTheme(), true);
+    // connect parentChanged of owner to know when its parent is changed
+    connect(theming->m_ownerItem, &QQuickItem::parentChanged,
+            theming, &UCThemingAttached::itemParentChanged, Qt::DirectConnection);
+    return theming;
+}
+
+UCThemingAttached *UCThemingAttached::attachTheming(QObject *owner)
+{
+    return qobject_cast<UCThemingAttached*>(
+                qmlAttachedPropertiesObject<UCThemingAttached>(owner, true));
+}
+
+void UCThemingAttached::connectThemeSignals(UCTheme *theme, bool connect)
+{
+    if (connect) {
+        QObject::connect(theme, SIGNAL(nameChanged()), this, SIGNAL(themeChanged()), Qt::DirectConnection);
+        QObject::connect(theme, SIGNAL(versionChanged()), this, SIGNAL(themeChanged()), Qt::DirectConnection);
+    } else {
+        QObject::disconnect(theme, SIGNAL(nameChanged()), this, SIGNAL(themeChanged()));
+        QObject::disconnect(theme, SIGNAL(versionChanged()), this, SIGNAL(themeChanged()));
+    }
+}
+
+// link/unlink all ascendant items until we reach a StyledItem, returns true if the
+// theme change signal emission is justified
+bool UCThemingAttached::connectParents(QQuickItem *fromItem)
+{
+    QQuickItem *item = fromItem ? fromItem : m_ownerItem->parentItem();
+    while (item) {
+        // push the item onto the stack
+        m_parentStack.push(QPointer<QQuickItem>(item));
+        UCThemingAttached *styling = itemTheming(item);
+        if (styling) {
+            // this is the closest StyledItem, connect its themeChanged() signal
+            QObject::connect(styling, SIGNAL(themeChanged()),
+                             this, SLOT(parentStyleChanged()), Qt::DirectConnection);
+            // set the current style set to the one in the parent's one if differs
+            return setParentStyled(styling);
+        } else {
+            // connect to the item's parentChanged() signal so we can detect when the parent changes
+            QObject::connect(item, SIGNAL(parentChanged(QQuickItem*)),
+                             this, SLOT(ascendantChanged(QQuickItem*)), Qt::DirectConnection);
+        }
+        item = item->parentItem();
+    }
+    return false;
+}
+
+// disconnect parent stack till item is reached; all the stack if item == 0
+void UCThemingAttached::disconnectTillItem(QQuickItem *item)
+{
+    while (!m_parentStack.isEmpty() && item != m_parentStack.top()) {
+        QPointer<QQuickItem> stackItem = m_parentStack.pop();
+        // the topmost item can be the only one which is a StyledItem
+        UCThemingAttached *styling = itemTheming(stackItem.data());
+        if (styling) {
+            QObject::disconnect(styling, SIGNAL(themeChanged()),
+                                this, SLOT(parentStyleChanged()));
+            // clear parent styling as well
+            if (styling == m_parentTheming) {
+                m_parentTheming.clear();
+            }
+        } else if (!stackItem.isNull()) {
+            QObject::disconnect(stackItem.data(), SIGNAL(parentChanged(QQuickItem*)),
+                                this, SLOT(ascendantChanged(QQuickItem*)));
+        }
+    }
+}
+
+// set the used parent styled item's style; returns true if the parent styled got changed
+bool UCThemingAttached::setParentStyled(UCThemingAttached *newStyling)
+{
+    if (m_parentTheming == newStyling) {
+        return false;
+    }
+    m_parentTheming = newStyling;
+    if (m_theme) {
+        Q_EMIT themeChanged();
+    }
+    return (m_theme == NULL);
+}
+
+UCTheme *UCThemingAttached::getTheme()
+{
+    if (m_theme) {
+        return m_theme;
+    } else if (!m_parentTheming.isNull()) {
+        return m_parentTheming->getTheme();
+    }
+    return &UCTheme::defaultTheme();
+}
+
+bool UCThemingAttached::setTheme(UCTheme *newTheme)
+{
+    if (m_theme == newTheme) {
+        return false;
+    }
+
+    // preform pre-theme change tasks
+    if (m_listener) {
+        m_listener->preThemeChanged();
+    }
+
+    // disconnect from the previous set
+    UCTheme *connectedSet = m_theme ?
+                                m_theme :
+                                (!m_parentTheming ? &UCTheme::defaultTheme() : NULL);
+    if (connectedSet) {
+        connectThemeSignals(connectedSet, false);
+    }
+
+    UCTheme *prevSet = m_theme;
+
+    // resolve new theme
+    if (m_theme && newTheme) {
+        // no need to redo the parentStack, simply set the theme and leave
+        m_theme = newTheme;
+    } else {
+        m_theme = newTheme;
+        if (!newTheme) {
+            // redo the parent chanin
+            disconnectTillItem(0);
+            connectParents(0);
+        }
+    }
+
+    // connect to the new set
+    connectedSet = m_theme ?
+                    m_theme :
+                    (!m_parentTheming ? &UCTheme::defaultTheme() : NULL);
+    if (connectedSet) {
+        connectThemeSignals(connectedSet, true);
+    }
+    // detach previous set and attach the new one
+    if (prevSet) {
+        Q_EMIT prevSet->parentThemeChanged();
+    }
+    if (m_theme) {
+        // re-parent theme to make sure we have it
+        // for the entire lifetime of the styled item
+        m_theme->setParent(parent());
+        Q_EMIT m_theme->parentThemeChanged();
+    }
+
+    // perform post-theme changes, update internal styling
+    if (m_listener) {
+        m_listener->postThemeChanged();
+    }
+
+    Q_EMIT themeChanged();
+    return true;
+}
+
+// lookup for the parent chain theme
+void UCThemingAttached::itemParentChanged()
+{
+    // clean stack
+    disconnectTillItem(0);
+    // make sure we reset parent StyledItem
+    m_parentTheming.clear();
+    // build the stack - if possible
+    connectParents(0);
+    Q_EMIT themeChanged();
+}
+
+// captures ascendant change signal, the sender is the one which counts!
+void UCThemingAttached::ascendantChanged(QQuickItem *ascendant)
+{
+    QQuickItem *sender = static_cast<QQuickItem*>(this->sender());
+    if (!sender) {
+        // cannot detect the sender, leave!
+        return;
+    }
+    if (ascendant) {
+        // disconnect from the previous ones
+        disconnectTillItem(sender);
+        m_parentTheming.clear();
+        // traverse ascendants till we reach a StyledItem or root and push them into the stack
+        if (connectParents(ascendant)) {
+            Q_EMIT themeChanged();
+        }
+    }
+}
+
+// syncs the ascendant styled item's styles
+void UCThemingAttached::parentStyleChanged()
+{
+    // do not trigger themeChanged() on this item if we have a
+    // custom one, but resolve its eventual parent change!
+    if (m_theme) {
+        Q_EMIT m_theme->parentThemeChanged();
+        return;
+    }
+
+    UCThemingAttached *styling = static_cast<UCThemingAttached*>(sender());
+    if (!styling) {
+        return;
+    }
+    setParentStyled(styling);
+    Q_EMIT themeChanged();
+}

=== added file 'src/Ubuntu/Components/plugin/ucthemingattached.h'
--- src/Ubuntu/Components/plugin/ucthemingattached.h	1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucthemingattached.h	2015-08-06 18:06:52 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Zsombor Egri <zsombor.egri@canonical.com>
+ */
+
+#ifndef UCTHEMINGATTACHED_H
+#define UCTHEMINGATTACHED_H
+
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtQml>
+
+class UCTheme;
+class QQuickItem;
+
+class UCThemeChangeListener {
+public:
+    virtual void preThemeChanged() = 0;
+    virtual void postThemeChanged() = 0;
+};
+
+class UCThemingAttached : public QObject
+{
+    Q_OBJECT
+public:
+    explicit UCThemingAttached(QObject *parent = 0);
+
+    static UCThemingAttached *qmlAttachedProperties(QObject *owner);
+    static UCThemingAttached *attachTheming(QObject *owner);
+
+    void setListener(UCThemeChangeListener *listener)
+    {
+        m_listener = listener;
+    }
+    UCTheme *getTheme();
+    bool setTheme(UCTheme *theme);
+
+Q_SIGNALS:
+    void themeChanged();
+
+public Q_SLOTS:
+
+    void ascendantChanged(QQuickItem *ascendant);
+    void parentStyleChanged();
+    void itemParentChanged();
+
+protected:
+    friend class UCTheme;
+
+    QStack< QPointer<QQuickItem> > m_parentStack;
+    QPointer<UCThemingAttached> m_parentTheming;
+    UCTheme *m_theme;
+    UCThemeChangeListener *m_listener;
+    QQuickItem *m_ownerItem;
+
+    void connectThemeSignals(UCTheme *theme, bool connect);
+
+    bool connectParents(QQuickItem *fromItem);
+    void disconnectTillItem(QQuickItem *item);
+    bool setParentStyled(UCThemingAttached *newStyling);
+
+};
+QML_DECLARE_TYPEINFO(UCThemingAttached, QML_HAS_ATTACHED_PROPERTIES)
+
+UCThemingAttached *itemTheming(QQuickItem *item);
+
+
+#endif // UCTHEMINGATTACHED_H

