Merge lp:~zsombi/ubuntu-ui-toolkit/layouts-visibility into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Cris Dywan
Approved revision: 1055
Merged at revision: 1065
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/layouts-visibility
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 1516 lines (+595/-227)
12 files modified
components.api (+2/-0)
modules/Ubuntu/Layouts/plugin/plugin.pro (+1/-1)
modules/Ubuntu/Layouts/plugin/propertychanges.cpp (+18/-33)
modules/Ubuntu/Layouts/plugin/propertychanges_p.h (+3/-16)
modules/Ubuntu/Layouts/plugin/ulitemlayout.h (+4/-1)
modules/Ubuntu/Layouts/plugin/ullayouts.cpp (+92/-81)
modules/Ubuntu/Layouts/plugin/ullayouts.h (+8/-3)
modules/Ubuntu/Layouts/plugin/ullayouts_p.h (+3/-5)
tests/unit_x11/tst_layouts/NestedVisibility.qml (+163/-0)
tests/unit_x11/tst_layouts/Visibility.qml (+84/-0)
tests/unit_x11/tst_layouts/tst_layouts.cpp (+214/-86)
tests/unit_x11/tst_layouts/tst_layouts.pro (+3/-1)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/layouts-visibility
Reviewer Review Type Date Requested Status
Cris Dywan Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+218916@code.launchpad.net

Commit message

Ubuntu Layouts reparents those default layout components which are not subject of layout instead of altering their visible and enabled properties.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1041
http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/192/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/106
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/94
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-amd64-ci/24
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/24
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/24/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-i386-ci/24
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/618
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/264
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/264/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/6988
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/87
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/137
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/137/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/192/rebuild

review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

The test case should
 - check that visible is not changed, ie. bug 1300668
 - verify ordering of the components

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1043
http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/219/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/175
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/165
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-amd64-ci/51
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/51
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/51/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-i386-ci/51
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/675
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/389
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/389/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/7103
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/150
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/211
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/211/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/219/rebuild

review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1052
http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/239/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/273
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/248
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-amd64-ci/71
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/71
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/71/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-i386-ci/71
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/760
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/554
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/554/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/7257
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/224
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/312
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/312/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/239/rebuild

review: Approve (continuous-integration)
1053. By Zsombor Egri

test cases merged

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:1053
http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/241/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/278
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/252
    FAILURE: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-amd64-ci/73/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/73
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/73/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-i386-ci/73
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/764
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/563
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/563/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/7265
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/228
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/316
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/316/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/241/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

Thanks for the change to data!

992 QTest::newRow("portrait") << "tabletLandscapeLayout" << "tabletLandscape";

This should probably be "landscape"

Aside from that it's looking good.

review: Needs Fixing
1054. By Zsombor Egri

test tag fixed

1055. By Zsombor Egri

staging merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1055
http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/260/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/360
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/313
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-amd64-ci/92
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/92
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-armhf-ci/92/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-utopic-i386-ci/92
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/832
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/707
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/707/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/7416
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/278
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/401
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/401/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-sdk-team-ubuntu-ui-toolkit-staging-ci/260/rebuild

review: Approve (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'components.api'
2--- components.api 2014-05-15 09:41:46 +0000
3+++ components.api 2014-05-20 19:37:09 +0000
4@@ -868,6 +868,8 @@
5 exports: ["Layouts 0.1", "Layouts 1.0"]
6 Property { name: "currentLayout"; type: "string"; isReadonly: true }
7 Property { name: "layouts"; type: "ULConditionalLayout"; isList: true; isReadonly: true }
8+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
9+ Property { name: "children"; type: "QQuickItem"; isList: true; isReadonly: true }
10 name: "ULLayoutsAttached"
11 prototype: "QObject"
12 Property { name: "item"; type: "string" }
13
14=== modified file 'modules/Ubuntu/Layouts/plugin/plugin.pro'
15--- modules/Ubuntu/Layouts/plugin/plugin.pro 2013-11-22 11:15:48 +0000
16+++ modules/Ubuntu/Layouts/plugin/plugin.pro 2014-05-20 19:37:09 +0000
17@@ -5,7 +5,7 @@
18
19 QMAKE_CXXFLAGS += -Werror
20
21-QT += quick-private
22+QT += quick-private gui-private
23 QT += qml-private core-private
24
25 equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) {
26
27=== modified file 'modules/Ubuntu/Layouts/plugin/propertychanges.cpp'
28--- modules/Ubuntu/Layouts/plugin/propertychanges.cpp 2013-06-26 09:58:41 +0000
29+++ modules/Ubuntu/Layouts/plugin/propertychanges.cpp 2014-05-20 19:37:09 +0000
30@@ -145,7 +145,7 @@
31 }
32 if (fromBinding) {
33 QQmlAbstractBinding *revertedBinding = QQmlPropertyPrivate::setBinding(property, fromBinding);
34- if (revertedBinding && ((revertedBinding != toBinding.data()) || (revertedBinding == toBinding.data() && deleteToBinding))) {
35+ if (revertedBinding && (revertedBinding != fromBinding) && ((revertedBinding != toBinding.data()) || (revertedBinding == toBinding.data() && deleteToBinding))) {
36 revertedBinding->destroy();
37 }
38 } else if (!toBinding.isNull() && QQmlPropertyPrivate::binding(property) == toBinding.data()) {
39@@ -222,24 +222,6 @@
40 {
41 }
42
43-/******************************************************************************
44- * ReparentChange
45- */
46-ReparentChange::ReparentChange(QQuickItem *target, const QString &property, QQuickItem *source)
47- : PropertyChange(target, property, QVariant(), Normal)
48- , sourceProperty(source, property, qmlContext(source))
49-{
50- action.type = PropertyAction::Binding;
51-}
52-
53-void ReparentChange::saveState()
54-{
55- action.toValue = sourceProperty.read();
56- PropertyChange::saveState();
57- if (sourceProperty.isValid()) {
58- action.setTargetBinding(QQmlPropertyPrivate::binding(sourceProperty), false);
59- }
60-}
61
62 /******************************************************************************
63 * ParentChange
64@@ -304,35 +286,31 @@
65 * ItemStackBackup
66 * High priority change backing up the item's stack position.
67 */
68-ItemStackBackup::ItemStackBackup(QQuickItem *item, QQuickItem *currentLayoutItem, QQuickItem *previousLayoutItem)
69+ItemStackBackup::ItemStackBackup(QQuickItem *item)
70 : PropertyChange(High)
71 , target(item)
72- , currentLayout(currentLayoutItem)
73- , previousLayout(previousLayoutItem)
74- , originalStackBefore(0)
75+ , prevItem(0)
76 {
77 }
78
79 void ItemStackBackup::saveState()
80 {
81 QQuickItem *rewindParent = target->parentItem();
82+ if (!rewindParent) {
83+ return;
84+ }
85 // save original stack position, but detect layout objects!
86 QList<QQuickItem*> children = rewindParent->childItems();
87- for (int ii = 0; ii < children.count() - 1; ++ii) {
88- if (children.at(ii) == target) {
89- originalStackBefore = children.at(ii + 1);
90- if (originalStackBefore == currentLayout || originalStackBefore == previousLayout) {
91- originalStackBefore = 0;
92- }
93- break;
94- }
95+ int index = children.indexOf(target);
96+ if (index > 0) {
97+ prevItem = children.at(index - 1);
98 }
99 }
100
101 void ItemStackBackup::revert()
102 {
103- if (originalStackBefore) {
104- target->stackBefore(originalStackBefore);
105+ if (prevItem) {
106+ target->stackAfter(prevItem);
107 }
108 }
109
110@@ -459,6 +437,13 @@
111 return *this;
112 }
113
114+// creates two changes, one for reparenting and one for itemstack backup
115+ChangeList &ChangeList::addParentChange(QQuickItem *item, QQuickItem *newParent, bool topmostItem)
116+{
117+ return addChange(new ParentChange(item, newParent, topmostItem))
118+ .addChange(new ItemStackBackup(item));
119+}
120+
121 QList<PropertyChange*> ChangeList::unifiedChanges()
122 {
123 QList<PropertyChange*> list;
124
125=== modified file 'modules/Ubuntu/Layouts/plugin/propertychanges_p.h'
126--- modules/Ubuntu/Layouts/plugin/propertychanges_p.h 2013-06-26 09:58:41 +0000
127+++ modules/Ubuntu/Layouts/plugin/propertychanges_p.h 2014-05-20 19:37:09 +0000
128@@ -104,18 +104,6 @@
129 };
130
131
132-class ReparentChange : public PropertyChange
133-{
134-public:
135- ReparentChange(QQuickItem *item, const QString &property, QQuickItem *source);
136-
137-protected:
138- virtual void saveState();
139-
140- QQmlProperty sourceProperty;
141-};
142-
143-
144 class ParentChange : public PropertyChange
145 {
146 public:
147@@ -143,16 +131,14 @@
148 class ItemStackBackup : public PropertyChange
149 {
150 public:
151- ItemStackBackup(QQuickItem *item, QQuickItem *currentLayoutItem, QQuickItem *previousLayoutItem);
152+ ItemStackBackup(QQuickItem *item);
153 void apply() {}
154 void revert();
155
156 protected:
157 virtual void saveState();
158 QQuickItem *target;
159- QQuickItem *currentLayout;
160- QQuickItem *previousLayout;
161- QQuickItem *originalStackBefore;
162+ QQuickItem *prevItem;
163 private:
164 friend class ULLayouts;
165 };
166@@ -214,6 +200,7 @@
167 void clear();
168
169 ChangeList &addChange(PropertyChange *change);
170+ ChangeList &addParentChange(QQuickItem *item, QQuickItem *newParent, bool topmostItem);
171
172 private:
173 QList<PropertyChange*> changes[PropertyChange::MaxPriority];
174
175=== modified file 'modules/Ubuntu/Layouts/plugin/ulitemlayout.h'
176--- modules/Ubuntu/Layouts/plugin/ulitemlayout.h 2013-06-06 16:00:10 +0000
177+++ modules/Ubuntu/Layouts/plugin/ulitemlayout.h 2014-05-20 19:37:09 +0000
178@@ -26,7 +26,7 @@
179 Q_OBJECT
180 Q_DISABLE_COPY(ULItemLayout)
181
182- Q_PROPERTY(QString item READ item WRITE setItem)
183+ Q_PROPERTY(QString item READ item WRITE setItem NOTIFY itemChanged)
184
185 public:
186 explicit ULItemLayout(QQuickItem *parent = 0);
187@@ -35,6 +35,9 @@
188 QString item() const;
189 void setItem(const QString &value);
190
191+Q_SIGNALS:
192+ void itemChanged();
193+
194 private:
195 QString m_itemName;
196 };
197
198=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts.cpp'
199--- modules/Ubuntu/Layouts/plugin/ullayouts.cpp 2014-04-20 19:25:12 +0000
200+++ modules/Ubuntu/Layouts/plugin/ullayouts.cpp 2014-05-20 19:37:09 +0000
201@@ -22,15 +22,21 @@
202 #include "ulconditionallayout.h"
203 #include "propertychanges_p.h"
204 #include <QtQml/QQmlInfo>
205+#include <QtQuick/private/qquickitem_p.h>
206
207 ULLayoutsPrivate::ULLayoutsPrivate(ULLayouts *qq)
208 : QQmlIncubator(Asynchronous)
209 , q_ptr(qq)
210 , currentLayoutItem(0)
211 , previousLayoutItem(0)
212+ , contentItem(new QQuickItem)
213 , currentLayoutIndex(-1)
214 , ready(false)
215 {
216+ // hidden container for the components that are not laid out
217+ // any component not subject of layout is reparented into this component
218+ contentItem->setParent(qq);
219+ contentItem->setParentItem(qq);
220 }
221
222
223@@ -80,7 +86,6 @@
224 QQuickItem *item = static_cast<QQuickItem*>(object);
225 // set disabled and invisible, and set its parent as last action
226 item->setVisible(false);
227- item->setEnabled(false);
228 }
229
230 /*
231@@ -98,14 +103,16 @@
232 currentLayoutItem = qobject_cast<QQuickItem*>(object());
233 Q_ASSERT(currentLayoutItem);
234
235- // hide all non-laid out items first
236- hideExcludedItems();
237-
238 //reparent components to be laid out
239 reparentItems();
240 // set parent item, then enable and show layout
241 changes.addChange(new ParentChange(currentLayoutItem, q, false));
242- itemActivate(currentLayoutItem, true);
243+
244+ // hide default layout, then show the new one
245+ // there's no need to queue these property changes as we do not need
246+ // to back up their previosus states
247+ contentItem->setVisible(false);
248+ currentLayoutItem->setVisible(true);
249 // apply changes
250 changes.apply();
251 // clear previous layout
252@@ -114,18 +121,10 @@
253
254 Q_EMIT q->currentLayoutChanged();
255 } else if (status == Error) {
256- Q_Q(ULLayouts);
257 error(q, errors());
258 }
259 }
260
261-void ULLayoutsPrivate::hideExcludedItems()
262-{
263- for (int i = 0; i < excludedFromLayout.count(); i++) {
264- itemActivate(excludedFromLayout[i], false);
265- }
266-}
267-
268 /*
269 * Re-parent items to the new layout.
270 */
271@@ -134,26 +133,32 @@
272 // create copy of items list, to keep track of which ones we change
273 LaidOutItemsMap unusedItems = itemsToLayout;
274
275- // iterate through the Layout definition to find containers - those Items with
276- // ConditionalLayout.items set
277- QList<QQuickItem*> items = currentLayoutItem->findChildren<QQuickItem*>();
278- // add the root item as that also can be the container
279- items.prepend(currentLayoutItem);
280-
281- Q_FOREACH(QQuickItem *container, items) {
282- // check whether we have ItemLayout declared
283- ULItemLayout *itemLayout = qobject_cast<ULItemLayout*>(container);
284- if (itemLayout) {
285- reparentToItemLayout(unusedItems, itemLayout);
286+ // iterate through the Layout definition to find containers - ItemLayout items
287+ QList<ULItemLayout*> containers = collectContainers(currentLayoutItem);
288+
289+ Q_FOREACH(ULItemLayout *container, containers) {
290+ reparentToItemLayout(unusedItems, container);
291+ }
292+}
293+
294+QList<ULItemLayout*> ULLayoutsPrivate::collectContainers(QQuickItem *fromItem)
295+{
296+ QList<ULItemLayout*> result;
297+ // check first if the fromItem is also a container
298+ ULItemLayout *container = qobject_cast<ULItemLayout*>(fromItem);
299+ if (container) {
300+ result.append(container);
301+ }
302+
303+ // loop through children but exclude nested Layouts
304+ QList<QQuickItem*> children = fromItem->childItems();
305+ Q_FOREACH(QQuickItem *child, children) {
306+ if (qobject_cast<ULLayouts*>(child)) {
307+ continue;
308 }
309- }
310-
311- // hide the rest of the unused ones
312- LaidOutItemsMapIterator i(unusedItems);
313- while (i.hasNext()) {
314- i.next();
315- itemActivate(i.value(), false);
316- }
317+ result.append(collectContainers(child));
318+ }
319+ return result;
320 }
321
322 /*
323@@ -176,8 +181,7 @@
324 }
325
326 // the component fills the parent
327- changes.addChange(new ParentChange(item, fragment, true));
328- changes.addChange(new ItemStackBackup(item, currentLayoutItem, previousLayoutItem));
329+ changes.addParentChange(item, fragment, true);
330 changes.addChange(new AnchorChange(item, "fill", fragment));
331 changes.addChange(new PropertyChange(item, "anchors.margins", 0));
332 changes.addChange(new PropertyChange(item, "anchors.leftMargin", 0));
333@@ -194,18 +198,6 @@
334 map.remove(itemName);
335 }
336
337-void ULLayoutsPrivate::itemActivate(QQuickItem *item, bool activate)
338-{
339- changes.addChange(new PropertyChange(item, "visible", activate))
340- .addChange(new PropertyChange(item, "enabled", activate));
341-}
342-
343-// remove the deleted item from the excluded ones
344-void ULLayoutsPrivate::_q_removeExcludedItem(QObject *excludedItem)
345-{
346- excludedFromLayout.removeAll(static_cast<QQuickItem*>(excludedItem));
347-}
348-
349 /*
350 * Validates the declared conditional layouts by checking whether they have name
351 * property set and whether the value set is unique, and whether the conditional
352@@ -244,44 +236,20 @@
353 /*
354 * Collect items to be laid out.
355 */
356-void ULLayoutsPrivate::getLaidOutItems()
357+void ULLayoutsPrivate::getLaidOutItems(QQuickItem *container)
358 {
359- Q_Q(ULLayouts);
360-
361- QList<QQuickItem*> items = q->findChildren<QQuickItem*>();
362- for (int i = 0; i < items.count(); i++) {
363- QQuickItem *item = items[i];
364+ Q_FOREACH(QQuickItem *child, container->childItems()) {
365+ // skip nested layouts
366+ if (qobject_cast<ULLayouts*>(child)) {
367+ continue;
368+ }
369 ULLayoutsAttached *marker = qobject_cast<ULLayoutsAttached*>(
370- qmlAttachedPropertiesObject<ULLayouts>(item, false));
371+ qmlAttachedPropertiesObject<ULLayouts>(child, false));
372 if (marker && !marker->item().isEmpty()) {
373- itemsToLayout.insert(marker->item(), item);
374+ itemsToLayout.insert(marker->item(), child);
375 } else {
376- // the item is not marked to be laid out but one of its parents
377- // can be, therefore check
378- // check if the item's parent is included in the layout
379- QQuickItem *pl = item->parentItem();
380- marker = 0;
381- if (!pl && item->parent()) {
382- // this may be an item instance assigned to a property
383- // like "property var anItem: Item {}"
384- // in which case we must get the parent object of it, not the parent item
385- pl = qobject_cast<QQuickItem*>(item->parent());
386- }
387- while (pl) {
388- marker = qobject_cast<ULLayoutsAttached*>(
389- qmlAttachedPropertiesObject<ULLayouts>(pl, false));
390- if (marker && !marker->item().isEmpty()) {
391- break;
392- }
393- pl = pl->parentItem();
394- }
395- if (!marker || (marker && marker->item().isEmpty())) {
396- // remember theese so we hide them once we switch away from default layout
397- excludedFromLayout << item;
398- // and make sure we remove the item from excluded ones in case the item is destroyed
399- QObject::connect(item, SIGNAL(destroyed(QObject*)),
400- q, SLOT(_q_removeExcludedItem(QObject*)));
401- }
402+ // continue to search in between the child's children
403+ getLaidOutItems(child);
404 }
405 }
406 }
407@@ -344,6 +312,9 @@
408 // revert and clear changes
409 changes.revert();
410 changes.clear();
411+ // make contentItem visible
412+
413+ contentItem->setVisible(true);
414 delete currentLayoutItem;
415 currentLayoutItem = 0;
416 currentLayoutIndex = -1;
417@@ -606,10 +577,18 @@
418 Q_D(ULLayouts);
419 d->ready = true;
420 d->validateConditionalLayouts();
421- d->getLaidOutItems();
422+ d->getLaidOutItems(d->contentItem);
423 d->updateLayout();
424 }
425
426+void ULLayouts::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
427+{
428+ Q_D(ULLayouts);
429+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
430+ // simply update the container's width/height to the new width/height
431+ d->contentItem->setSize(newGeometry.size());
432+}
433+
434 /*!
435 * \qmlproperty string Layouts::currentLayout
436 * The property holds the active layout name. The default layout is identified
437@@ -634,6 +613,17 @@
438 }
439
440 /*!
441+ * \internal
442+ * Returns the contentItem for internal use.
443+ */
444+QQuickItem *ULLayouts::contentItem() const
445+{
446+ Q_D(const ULLayouts);
447+ return d->contentItem;
448+}
449+
450+
451+/*!
452 * \qmlproperty list<ConditionalLayout> Layouts::layouts
453 * The property holds the list of different ConditionalLayout elements.
454 */
455@@ -647,4 +637,25 @@
456 &ULLayoutsPrivate::clear_layouts);
457 }
458
459+/*!
460+ * \internal
461+ * Overrides the default data property.
462+ */
463+QQmlListProperty<QObject> ULLayouts::data()
464+{
465+ Q_D(ULLayouts);
466+ return QQuickItemPrivate::get(d->contentItem)->data();
467+}
468+
469+/*!
470+ * \internal
471+ * Overrides the default children property.
472+ */
473+QQmlListProperty<QQuickItem> ULLayouts::children()
474+{
475+ Q_D(ULLayouts);
476+ return QQuickItemPrivate::get(d->contentItem)->children();
477+}
478+
479+
480 #include "moc_ullayouts.cpp"
481
482=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts.h'
483--- modules/Ubuntu/Layouts/plugin/ullayouts.h 2014-02-18 13:27:23 +0000
484+++ modules/Ubuntu/Layouts/plugin/ullayouts.h 2014-05-20 19:37:09 +0000
485@@ -55,7 +55,10 @@
486
487 Q_PROPERTY(QString currentLayout READ currentLayout NOTIFY currentLayoutChanged DESIGNABLE false)
488 Q_PROPERTY(QQmlListProperty<ULConditionalLayout> layouts READ layouts DESIGNABLE false)
489-
490+
491+ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
492+ Q_PROPERTY(QQmlListProperty<QQuickItem> children READ children DESIGNABLE false)
493+ Q_CLASSINFO("DefaultProperty", "data")
494 public:
495 explicit ULLayouts(QQuickItem *parent = 0);
496 ~ULLayouts();
497@@ -64,21 +67,23 @@
498
499 QString currentLayout() const;
500 QList<ULConditionalLayout*> layoutList();
501+ QQuickItem *contentItem() const;
502
503 Q_SIGNALS:
504 void currentLayoutChanged();
505
506 protected:
507 void componentComplete();
508+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
509
510 private:
511 QQmlListProperty<ULConditionalLayout> layouts();
512+ QQmlListProperty<QObject> data();
513+ QQmlListProperty<QQuickItem> children();
514
515 friend class ULConditionalLayout;
516 Q_DECLARE_PRIVATE(ULLayouts)
517 QScopedPointer<ULLayoutsPrivate> d_ptr;
518-
519- Q_PRIVATE_SLOT(d_func(), void _q_removeExcludedItem(QObject*))
520 };
521
522 QML_DECLARE_TYPE(ULLayouts)
523
524=== modified file 'modules/Ubuntu/Layouts/plugin/ullayouts_p.h'
525--- modules/Ubuntu/Layouts/plugin/ullayouts_p.h 2014-02-18 13:27:23 +0000
526+++ modules/Ubuntu/Layouts/plugin/ullayouts_p.h 2014-05-20 19:37:09 +0000
527@@ -33,9 +33,8 @@
528
529 ULLayoutsPrivate(ULLayouts *qq);
530
531- void _q_removeExcludedItem(QObject *excludedItem);
532 void validateConditionalLayouts();
533- void getLaidOutItems();
534+ void getLaidOutItems(QQuickItem *item);
535 void updateLayout();
536
537 static void error(QObject *item, const QString &message);
538@@ -51,9 +50,9 @@
539 QList<ULConditionalLayout*> layouts;
540 ChangeList changes;
541 LaidOutItemsMap itemsToLayout;
542- QList<QQuickItem*> excludedFromLayout;
543 QQuickItem* currentLayoutItem;
544 QQuickItem* previousLayoutItem;
545+ QQuickItem* contentItem;
546 int currentLayoutIndex;
547 bool ready:1;
548
549@@ -64,10 +63,9 @@
550 static void clear_layouts(QQmlListProperty<ULConditionalLayout>*);
551
552 void reLayout();
553- void hideExcludedItems();
554 void reparentItems();
555+ QList<ULItemLayout*> collectContainers(QQuickItem *fromItem);
556 void reparentToItemLayout(LaidOutItemsMap &map, ULItemLayout *fragment);
557- void itemActivate(QQuickItem *item, bool activate);
558 };
559
560 #endif // ULLAYOUTS_P_H
561
562=== added file 'tests/unit_x11/tst_layouts/NestedVisibility.qml'
563--- tests/unit_x11/tst_layouts/NestedVisibility.qml 1970-01-01 00:00:00 +0000
564+++ tests/unit_x11/tst_layouts/NestedVisibility.qml 2014-05-20 19:37:09 +0000
565@@ -0,0 +1,163 @@
566+/*
567+ * Copyright 2014 Canonical Ltd.
568+ *
569+ * This program is free software; you can redistribute it and/or modify
570+ * it under the terms of the GNU Lesser General Public License as published by
571+ * the Free Software Foundation; version 3.
572+ *
573+ * This program is distributed in the hope that it will be useful,
574+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
575+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
576+ * GNU Lesser General Public License for more details.
577+ *
578+ * You should have received a copy of the GNU Lesser General Public License
579+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
580+ */
581+
582+import QtQuick 2.0
583+import Ubuntu.Components 1.1
584+import Ubuntu.Layouts 1.0
585+
586+MainView {
587+ id: main
588+ objectName: "mainView"
589+ applicationName: "test-app"
590+
591+ /*
592+ This property enables the application to change orientation
593+ when the device is rotated. The default is false.
594+ */
595+ automaticOrientation: true // TODO: support wide aspect ratios, esp. on prepareGamePage
596+
597+ width: units.gu(40)
598+ height: units.gu(75)
599+
600+ function phoneLayout() {
601+ width = units.gu(50);
602+ }
603+ function tabletPortraitLayout() {
604+ width = units.gu(70);
605+ }
606+ function tabletLandscapeLayout() {
607+ width = units.gu(100);
608+ }
609+
610+ PageStack {
611+ Component.onCompleted: push(testPage)
612+
613+ Page {
614+ title: i18n.tr("Conditional Layouts with PageStack")
615+ id: testPage
616+ visible: false
617+
618+ Layouts {
619+ id: layouts
620+ objectName: "mainLayout"
621+ width: parent.width
622+ height: parent.height
623+ layouts: [
624+ ConditionalLayout {
625+ name: "tabletPortrait"
626+ when: main.width > units.gu(50)
627+ Layouts {
628+ anchors.fill: parent
629+ objectName: "nestedLayout"
630+ layouts: [
631+ ConditionalLayout {
632+ name: "tabletLandscape"
633+ when: main.width > units.gu(70)
634+ Row {
635+ objectName: "tabletLandscape"
636+ anchors.fill: parent
637+ Rectangle {
638+ height: parent.height
639+ color: "white"
640+ width: parent.width / 5
641+ }
642+ Flow {
643+ spacing: units.gu(2)
644+ ItemLayout {
645+ objectName: "nestedMagentaContainer"
646+ item: "mainMagenta"
647+ width: units.gu(20)
648+ height: width
649+ }
650+ ItemLayout {
651+ objectName: "nestedGreenContainer"
652+ item: "mainGreen"
653+ width: units.gu(60)
654+ height: width
655+ }
656+ }
657+ }
658+ }
659+ ]
660+ // Default layout, but can have ItemLayouts
661+ // as those will belong to the previous Layouts
662+ // and attaching Layouts.item we can layout it further
663+ Flow {
664+ objectName: "tabletPortrait"
665+ anchors.fill: parent
666+ ItemLayout {
667+ objectName: "greenContainer"
668+ item: "mainGreen"
669+ width: units.gu(40)
670+ height: width
671+ Layouts.item: item
672+ }
673+ ItemLayout {
674+ objectName: "magentaContainer"
675+ item: "mainMagenta"
676+ width: units.gu(60)
677+ height: width
678+ Layouts.item: item
679+ }
680+ }
681+ }
682+ }
683+ ]
684+
685+ // default layout for mainLayout
686+ Flow {
687+ objectName: "mainDefaultLayout"
688+ anchors.fill: parent
689+ Rectangle {
690+ objectName: "mainRed"
691+ width: units.gu(15)
692+ height: width
693+ color: "red"
694+ Layouts.item: "mainRed"
695+ }
696+ Rectangle {
697+ objectName: "mainGreen"
698+ width: units.gu(15)
699+ height: width
700+ color: "green"
701+ Layouts.item: "mainGreen"
702+ }
703+ Rectangle {
704+ objectName: "mainBlue"
705+ width: units.gu(15)
706+ height: width
707+ color: "blue"
708+ Layouts.item: "mainBlue"
709+ }
710+ Rectangle {
711+ objectName: "mainMagenta"
712+ width: units.gu(15)
713+ height: width
714+ color: "magenta"
715+ Layouts.item: "mainMagenta"
716+ }
717+ Rectangle {
718+ objectName: "mainHidden"
719+ width: units.gu(15)
720+ height: width
721+ color: "yellow"
722+ visible: false
723+ }
724+ }
725+ }
726+ }
727+ }
728+}
729
730=== added file 'tests/unit_x11/tst_layouts/Visibility.qml'
731--- tests/unit_x11/tst_layouts/Visibility.qml 1970-01-01 00:00:00 +0000
732+++ tests/unit_x11/tst_layouts/Visibility.qml 2014-05-20 19:37:09 +0000
733@@ -0,0 +1,84 @@
734+/*
735+ * Copyright 2014 Canonical Ltd.
736+ *
737+ * This program is free software; you can redistribute it and/or modify
738+ * it under the terms of the GNU Lesser General Public License as published by
739+ * the Free Software Foundation; version 3.
740+ *
741+ * This program is distributed in the hope that it will be useful,
742+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
743+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
744+ * GNU Lesser General Public License for more details.
745+ *
746+ * You should have received a copy of the GNU Lesser General Public License
747+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
748+ */
749+
750+import QtQuick 2.0
751+import Ubuntu.Components 1.1
752+import Ubuntu.Layouts 1.0
753+
754+MainView {
755+ id: main
756+ objectName: "mainView"
757+ applicationName: "test-app"
758+
759+ /*
760+ This property enables the application to change orientation
761+ when the device is rotated. The default is false.
762+ */
763+ automaticOrientation: true // TODO: support wide aspect ratios, esp. on prepareGamePage
764+
765+ property bool boundValue: true
766+
767+ width: units.gu(100)
768+ height: units.gu(75)
769+
770+ function portraitLayout() {
771+ width = units.gu(50);
772+ }
773+ function landscapeLayout() {
774+ width = units.gu(100);
775+ }
776+
777+ PageStack {
778+ Component.onCompleted: push(testPage)
779+
780+ Page {
781+ title: i18n.tr("Conditional Layouts with PageStack")
782+ id: testPage
783+ visible: false
784+
785+ Layouts {
786+ id: layouts
787+ objectName: "layoutManager"
788+ width: parent.width
789+ height: parent.height
790+ layouts: [
791+ ConditionalLayout {
792+ name: "wide"
793+ when: layouts.width < units.gu(60)
794+ UbuntuShape {
795+ width: units.gu(20)
796+ height: units.gu(20)
797+ color: "red"
798+ Label { text: "wide" }
799+ }
800+ }
801+ ]
802+
803+ // This is a default layout.
804+ // When using a PageStack and layouts is not empty, it won't display or switch to the default layout.
805+ // However it only works when putting it into the layouts list with an inversed condition.
806+ UbuntuShape {
807+ objectName: "DefaultLayout"
808+ width: units.gu(20)
809+ height: units.gu(20)
810+ color: "green"
811+ visible: main.boundValue
812+ Label { text: "default" }
813+ }
814+ }
815+ }
816+ }
817+}
818
819=== modified file 'tests/unit_x11/tst_layouts/tst_layouts.cpp'
820--- tests/unit_x11/tst_layouts/tst_layouts.cpp 2014-03-19 12:48:33 +0000
821+++ tests/unit_x11/tst_layouts/tst_layouts.cpp 2014-05-20 19:37:09 +0000
822@@ -72,6 +72,25 @@
823 return (children.count() > 0) ? children[0] : 0;
824 }
825
826+ bool hasChildItem(QQuickItem *child, QQuickItem *parent)
827+ {
828+ QQuickItem *pl = child->parentItem();
829+ while (pl) {
830+ if (pl == parent) {
831+ return true;
832+ }
833+ pl = pl->parentItem();
834+ }
835+ return false;
836+ }
837+
838+ QQuickItem *prevSibling(QQuickItem *item)
839+ {
840+ QList<QQuickItem*> children = item->parentItem()->childItems();
841+ int index = children.indexOf(item);
842+ return (index > 0) ? children.at(index - 1) : 0;
843+ }
844+
845
846 private Q_SLOTS:
847 void initTestCase()
848@@ -419,16 +438,16 @@
849
850 void testCase_AnchorFilledReparenting()
851 {
852- QScopedPointer<QQuickView> view(loadTest("AnchorFilledReparenting.qml"));
853+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorFilledReparenting.qml"));
854 QVERIFY(view);
855 QQuickItem *root = view->rootObject();
856 QVERIFY(root);
857
858- QQuickItem *layout = testItem(root, "layoutManager");
859+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
860 QVERIFY(layout);
861 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
862
863- QQuickItem *item = testItem(root, "testItem");
864+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
865 QVERIFY(item);
866
867 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
868@@ -436,27 +455,27 @@
869
870 root->setWidth(root->width() + 100);
871 layoutChangeSpy.wait(100);
872- QQuickItem *testLayout = testItem(root, "testLayout");
873+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
874 QVERIFY(testLayout);
875 QCOMPARE(anchors->fill(), testLayout);
876
877 root->setWidth(root->width() - 100);
878 layoutChangeSpy.wait(100);
879- QCOMPARE(anchors->fill(), layout);
880+ QCOMPARE(anchors->fill(), layout->contentItem());
881 }
882
883 void testCase_AnchorFilledMargins()
884 {
885- QScopedPointer<QQuickView> view(loadTest("AnchorFilledMargins.qml"));
886+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorFilledMargins.qml"));
887 QVERIFY(view);
888 QQuickItem *root = view->rootObject();
889 QVERIFY(root);
890
891- QQuickItem *layout = testItem(root, "layoutManager");
892+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
893 QVERIFY(layout);
894 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
895
896- QQuickItem *item = testItem(root, "testItem");
897+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
898 QVERIFY(item);
899
900 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
901@@ -465,29 +484,29 @@
902 root->setWidth(root->width() + 100);
903 layoutChangeSpy.wait(100);
904
905- QQuickItem *testLayout = testItem(root, "testLayout");
906+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
907 QVERIFY(testLayout);
908 QCOMPARE(anchors->fill(), testLayout);
909 QCOMPARE(anchors->margins(), 0.0);
910
911 root->setWidth(root->width() - 100);
912 layoutChangeSpy.wait(100);
913- QCOMPARE(anchors->fill(), layout);
914+ QCOMPARE(anchors->fill(), layout->contentItem());
915 QCOMPARE(anchors->margins(), 10.0);
916 }
917
918 void testCase_AnchorFilledSeparateMargins()
919 {
920- QScopedPointer<QQuickView> view(loadTest("AnchorFilledSeparateMargins.qml"));
921+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorFilledSeparateMargins.qml"));
922 QVERIFY(view);
923 QQuickItem *root = view->rootObject();
924 QVERIFY(root);
925
926- QQuickItem *layout = testItem(root, "layoutManager");
927+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
928 QVERIFY(layout);
929 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
930
931- QQuickItem *item = testItem(root, "testItem");
932+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
933 QVERIFY(item);
934
935 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
936@@ -496,7 +515,7 @@
937 root->setWidth(root->width() + 100);
938 layoutChangeSpy.wait(100);
939
940- QQuickItem *testLayout = testItem(root, "testLayout");
941+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
942 QVERIFY(testLayout);
943 QCOMPARE(anchors->fill(), testLayout);
944 QCOMPARE(anchors->margins(), 0.0);
945@@ -507,7 +526,7 @@
946
947 root->setWidth(root->width() - 100);
948 layoutChangeSpy.wait(100);
949- QCOMPARE(anchors->fill(), layout);
950+ QCOMPARE(anchors->fill(), layout->contentItem());
951 QCOMPARE(anchors->leftMargin(), 10.0);
952 QCOMPARE(anchors->topMargin(), 20.0);
953 QCOMPARE(anchors->rightMargin(), 30.0);
954@@ -516,16 +535,16 @@
955
956 void testCase_AnchorCenteredInDefault()
957 {
958- QScopedPointer<QQuickView> view(loadTest("AnchorCenteredInDefault.qml"));
959+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorCenteredInDefault.qml"));
960 QVERIFY(view);
961 QQuickItem *root = view->rootObject();
962 QVERIFY(root);
963
964- QQuickItem *layout = testItem(root, "layoutManager");
965+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
966 QVERIFY(layout);
967 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
968
969- QQuickItem *item = testItem(root, "testItem");
970+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
971 QVERIFY(item);
972
973 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
974@@ -533,335 +552,335 @@
975
976 root->setWidth(root->width() + 100);
977 layoutChangeSpy.wait(100);
978- QQuickItem *testLayout = testItem(root, "testLayout");
979+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
980 QVERIFY(testLayout);
981 QCOMPARE(anchors->fill(), testLayout);
982
983 root->setWidth(root->width() - 100);
984 layoutChangeSpy.wait(100);
985- QCOMPARE(anchors->centerIn(), layout);
986+ QCOMPARE(anchors->centerIn(), layout->contentItem());
987 }
988
989 void testCase_AnchorVerticalCenter()
990 {
991- QScopedPointer<QQuickView> view(loadTest("AnchorVerticalCenter.qml"));
992+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorVerticalCenter.qml"));
993 QVERIFY(view);
994 QQuickItem *root = view->rootObject();
995 QVERIFY(root);
996
997- QQuickItem *layout = testItem(root, "layoutManager");
998+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
999 QVERIFY(layout);
1000 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1001
1002- QQuickItem *item = testItem(root, "testItem");
1003+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1004 QVERIFY(item);
1005
1006 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1007 QVERIFY(anchors);
1008
1009- QCOMPARE(anchors->verticalCenter().item, layout);
1010+ QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
1011
1012 root->setWidth(root->width() + 100);
1013 layoutChangeSpy.wait(100);
1014- QQuickItem *testLayout = testItem(root, "testLayout");
1015+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1016 QVERIFY(testLayout);
1017 QCOMPARE(anchors->fill(), testLayout);
1018
1019 root->setWidth(root->width() - 100);
1020 layoutChangeSpy.wait(100);
1021- QCOMPARE(anchors->verticalCenter().item, layout);
1022+ QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
1023 }
1024
1025 void testCase_AnchorVerticalCenterOffset()
1026 {
1027- QScopedPointer<QQuickView> view(loadTest("AnchorVerticalCenterOffset.qml"));
1028+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorVerticalCenterOffset.qml"));
1029 QVERIFY(view);
1030 QQuickItem *root = view->rootObject();
1031 QVERIFY(root);
1032
1033- QQuickItem *layout = testItem(root, "layoutManager");
1034+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1035 QVERIFY(layout);
1036 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1037
1038- QQuickItem *item = testItem(root, "testItem");
1039+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1040 QVERIFY(item);
1041
1042 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1043 QVERIFY(anchors);
1044
1045- QCOMPARE(anchors->verticalCenter().item, layout);
1046+ QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
1047 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
1048
1049 root->setWidth(root->width() + 100);
1050 layoutChangeSpy.wait(100);
1051- QQuickItem *testLayout = qobject_cast<QQuickItem*>(testItem(root, "testLayout"));
1052+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1053 QVERIFY(testLayout);
1054 QCOMPARE(anchors->fill(), testLayout);
1055 // no need to check offset as it does not affect the fill
1056
1057 root->setWidth(root->width() - 100);
1058 layoutChangeSpy.wait(100);
1059- QCOMPARE(anchors->verticalCenter().item, layout);
1060+ QCOMPARE(anchors->verticalCenter().item, layout->contentItem());
1061 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
1062 }
1063
1064 void testCase_AnchorHorizontalCenter()
1065 {
1066- QScopedPointer<QQuickView> view(loadTest("AnchorHorizontalCenter.qml"));
1067+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorHorizontalCenter.qml"));
1068 QVERIFY(view);
1069 QQuickItem *root = view->rootObject();
1070 QVERIFY(root);
1071
1072- QQuickItem *layout = testItem(root, "layoutManager");
1073+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1074 QVERIFY(layout);
1075 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1076
1077- QQuickItem *item = testItem(root, "testItem");
1078+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1079 QVERIFY(item);
1080
1081 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1082 QVERIFY(anchors);
1083
1084- QCOMPARE(anchors->horizontalCenter().item, layout);
1085+ QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
1086
1087 root->setWidth(root->width() + 100);
1088 layoutChangeSpy.wait(100);
1089- QQuickItem *testLayout = testItem(root, "testLayout");
1090+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1091 QVERIFY(testLayout);
1092 QCOMPARE(anchors->fill(), testLayout);
1093
1094 root->setWidth(root->width() - 100);
1095 layoutChangeSpy.wait(100);
1096- QCOMPARE(anchors->horizontalCenter().item, layout);
1097+ QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
1098 }
1099
1100 void testCase_AnchorHorizontalCenterOffset()
1101 {
1102- QScopedPointer<QQuickView> view(loadTest("AnchorHorizontalCenterOffset.qml"));
1103+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorHorizontalCenterOffset.qml"));
1104 QVERIFY(view);
1105 QQuickItem *root = view->rootObject();
1106 QVERIFY(root);
1107
1108- QQuickItem *layout = testItem(root, "layoutManager");
1109+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1110 QVERIFY(layout);
1111 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1112
1113- QQuickItem *item = testItem(root, "testItem");
1114+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1115 QVERIFY(item);
1116
1117 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1118 QVERIFY(anchors);
1119
1120- QCOMPARE(anchors->horizontalCenter().item, layout);
1121+ QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
1122 QCOMPARE(anchors->horizontalCenterOffset(), 50.0);
1123
1124 root->setWidth(root->width() + 100);
1125 layoutChangeSpy.wait(100);
1126- QQuickItem *testLayout = testItem(root, "testLayout");
1127+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1128 QVERIFY(testLayout);
1129 QCOMPARE(anchors->fill(), testLayout);
1130 // no need to check offset as it does not affect the fill
1131
1132 root->setWidth(root->width() - 100);
1133 layoutChangeSpy.wait(100);
1134- QCOMPARE(anchors->horizontalCenter().item, layout);
1135+ QCOMPARE(anchors->horizontalCenter().item, layout->contentItem());
1136 QCOMPARE(anchors->horizontalCenterOffset(), 50.0);
1137 }
1138
1139 void testCase_AnchorCenterWithOffset()
1140 {
1141- QScopedPointer<QQuickView> view(loadTest("AnchorCenterWithOffset.qml"));
1142+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorCenterWithOffset.qml"));
1143 QVERIFY(view);
1144 QQuickItem *root = view->rootObject();
1145 QVERIFY(root);
1146
1147- QQuickItem *layout = testItem(root, "layoutManager");
1148+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1149 QVERIFY(layout);
1150 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1151
1152- QQuickItem *item = testItem(root, "testItem");
1153+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1154 QVERIFY(item);
1155
1156 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1157 QVERIFY(anchors);
1158
1159- QCOMPARE(anchors->centerIn(), layout);
1160+ QCOMPARE(anchors->centerIn(), layout->contentItem());
1161 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
1162 QCOMPARE(anchors->horizontalCenterOffset(), 40.0);
1163
1164 root->setWidth(root->width() + 100);
1165 layoutChangeSpy.wait(100);
1166- QQuickItem *testLayout = testItem(root, "testLayout");
1167+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1168 QVERIFY(testLayout);
1169 QCOMPARE(anchors->fill(), testLayout);
1170 // no need to check offsets as it does not affect the fill
1171
1172 root->setWidth(root->width() - 100);
1173 layoutChangeSpy.wait(100);
1174- QCOMPARE(anchors->centerIn(), layout);
1175+ QCOMPARE(anchors->centerIn(), layout->contentItem());
1176 QCOMPARE(anchors->verticalCenterOffset(), 50.0);
1177 QCOMPARE(anchors->horizontalCenterOffset(), 40.0);
1178 }
1179
1180 void testCase_AnchorLeft()
1181 {
1182- QScopedPointer<QQuickView> view(loadTest("AnchorLeft.qml"));
1183+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorLeft.qml"));
1184 QVERIFY(view);
1185 QQuickItem *root = view->rootObject();
1186 QVERIFY(root);
1187
1188- QQuickItem *layout = testItem(root, "layoutManager");
1189+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1190 QVERIFY(layout);
1191 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1192
1193- QQuickItem *item = testItem(root, "testItem");
1194+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1195 QVERIFY(item);
1196
1197 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1198 QVERIFY(anchors);
1199
1200- QCOMPARE(anchors->left().item, layout);
1201+ QCOMPARE(anchors->left().item, layout->contentItem());
1202 QCOMPARE(anchors->leftMargin(), 10.0);
1203
1204 root->setWidth(root->width() + 100);
1205 layoutChangeSpy.wait(100);
1206- QQuickItem *testLayout = testItem(root, "testLayout");
1207+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1208 QVERIFY(testLayout);
1209 QCOMPARE(anchors->fill(), testLayout);
1210 QCOMPARE(anchors->leftMargin(), 0.0);
1211
1212 root->setWidth(root->width() - 100);
1213 layoutChangeSpy.wait(100);
1214- QCOMPARE(anchors->left().item, layout);
1215+ QCOMPARE(anchors->left().item, layout->contentItem());
1216 QCOMPARE(anchors->leftMargin(), 10.0);
1217 }
1218
1219 void testCase_AnchorTop()
1220 {
1221- QScopedPointer<QQuickView> view(loadTest("AnchorTop.qml"));
1222+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorTop.qml"));
1223 QVERIFY(view);
1224 QQuickItem *root = view->rootObject();
1225 QVERIFY(root);
1226
1227- QQuickItem *layout = testItem(root, "layoutManager");
1228+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1229 QVERIFY(layout);
1230 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1231
1232- QQuickItem *item = testItem(root, "testItem");
1233+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1234 QVERIFY(item);
1235
1236 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1237 QVERIFY(anchors);
1238
1239- QCOMPARE(anchors->top().item, layout);
1240+ QCOMPARE(anchors->top().item, layout->contentItem());
1241 QCOMPARE(anchors->topMargin(), 10.0);
1242
1243 root->setWidth(root->width() + 100);
1244 layoutChangeSpy.wait(100);
1245- QQuickItem *testLayout = testItem(root, "testLayout");
1246+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1247 QVERIFY(testLayout);
1248 QCOMPARE(anchors->fill(), testLayout);
1249 QCOMPARE(anchors->topMargin(), 0.0);
1250
1251 root->setWidth(root->width() - 100);
1252 layoutChangeSpy.wait(100);
1253- QCOMPARE(anchors->top().item, layout);
1254+ QCOMPARE(anchors->top().item, layout->contentItem());
1255 QCOMPARE(anchors->topMargin(), 10.0);
1256 }
1257
1258 void testCase_AnchorRight()
1259 {
1260- QScopedPointer<QQuickView> view(loadTest("AnchorRight.qml"));
1261+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorRight.qml"));
1262 QVERIFY(view);
1263 QQuickItem *root = view->rootObject();
1264 QVERIFY(root);
1265
1266- QQuickItem *layout = testItem(root, "layoutManager");
1267+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1268 QVERIFY(layout);
1269 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1270
1271- QQuickItem *item = testItem(root, "testItem");
1272+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1273 QVERIFY(item);
1274
1275 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1276 QVERIFY(anchors);
1277
1278- QCOMPARE(anchors->right().item, layout);
1279+ QCOMPARE(anchors->right().item, layout->contentItem());
1280 QCOMPARE(anchors->rightMargin(), 10.0);
1281
1282 root->setWidth(root->width() + 100);
1283 layoutChangeSpy.wait(100);
1284- QQuickItem *testLayout = testItem(root, "testLayout");
1285+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1286 QVERIFY(testLayout);
1287 QCOMPARE(anchors->fill(), testLayout);
1288 QCOMPARE(anchors->rightMargin(), 0.0);
1289
1290 root->setWidth(root->width() - 100);
1291 layoutChangeSpy.wait(100);
1292- QCOMPARE(anchors->right().item, layout);
1293+ QCOMPARE(anchors->right().item, layout->contentItem());
1294 QCOMPARE(anchors->rightMargin(), 10.0);
1295 }
1296
1297 void testCase_AnchorBottom()
1298 {
1299- QScopedPointer<QQuickView> view(loadTest("AnchorBottom.qml"));
1300+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorBottom.qml"));
1301 QVERIFY(view);
1302 QQuickItem *root = view->rootObject();
1303 QVERIFY(root);
1304
1305- QQuickItem *layout = testItem(root, "layoutManager");
1306+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1307 QVERIFY(layout);
1308 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1309
1310- QQuickItem *item = testItem(root, "testItem");
1311+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1312 QVERIFY(item);
1313
1314 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1315 QVERIFY(anchors);
1316
1317- QCOMPARE(anchors->bottom().item, layout);
1318+ QCOMPARE(anchors->bottom().item, layout->contentItem());
1319 QCOMPARE(anchors->bottomMargin(), 10.0);
1320
1321 root->setWidth(root->width() + 100);
1322 layoutChangeSpy.wait(100);
1323- QQuickItem *testLayout = testItem(root, "testLayout");
1324+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1325 QVERIFY(testLayout);
1326 QCOMPARE(anchors->fill(), testLayout);
1327 QCOMPARE(anchors->bottomMargin(), 0.0);
1328
1329 root->setWidth(root->width() - 100);
1330 layoutChangeSpy.wait(100);
1331- QCOMPARE(anchors->bottom().item, layout);
1332+ QCOMPARE(anchors->bottom().item, layout->contentItem());
1333 QCOMPARE(anchors->bottomMargin(), 10.0);
1334 }
1335
1336 void testCase_AnchorAll()
1337 {
1338- QScopedPointer<QQuickView> view(loadTest("AnchorAll.qml"));
1339+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("AnchorAll.qml"));
1340 QVERIFY(view);
1341 QQuickItem *root = view->rootObject();
1342 QVERIFY(root);
1343
1344- QQuickItem *layout = testItem(root, "layoutManager");
1345+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1346 QVERIFY(layout);
1347 QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1348
1349- QQuickItem *item = testItem(root, "testItem");
1350+ QQuickItem *item = view->findItem<QQuickItem*>("testItem");
1351 QVERIFY(item);
1352
1353 QQuickAnchors *anchors = item->property("anchors").value<QQuickAnchors*>();
1354 QVERIFY(anchors);
1355
1356- QCOMPARE(anchors->left().item, layout);
1357- QCOMPARE(anchors->top().item, layout);
1358- QCOMPARE(anchors->right().item, layout);
1359- QCOMPARE(anchors->bottom().item, layout);
1360+ QCOMPARE(anchors->left().item, layout->contentItem());
1361+ QCOMPARE(anchors->top().item, layout->contentItem());
1362+ QCOMPARE(anchors->right().item, layout->contentItem());
1363+ QCOMPARE(anchors->bottom().item, layout->contentItem());
1364 QVERIFY(!anchors->fill());
1365 QCOMPARE(anchors->margins(), 20.0);
1366
1367 root->setWidth(root->width() + 100);
1368 layoutChangeSpy.wait(100);
1369- QQuickItem *testLayout = testItem(root, "testLayout");
1370+ QQuickItem *testLayout = view->findItem<QQuickItem*>("testLayout");
1371 QVERIFY(testLayout);
1372 QCOMPARE(anchors->fill(), testLayout);
1373 QVERIFY(!anchors->left().item);
1374@@ -872,10 +891,10 @@
1375
1376 root->setWidth(root->width() - 100);
1377 layoutChangeSpy.wait(100);
1378- QCOMPARE(anchors->left().item, layout);
1379- QCOMPARE(anchors->top().item, layout);
1380- QCOMPARE(anchors->right().item, layout);
1381- QCOMPARE(anchors->bottom().item, layout);
1382+ QCOMPARE(anchors->left().item, layout->contentItem());
1383+ QCOMPARE(anchors->top().item, layout->contentItem());
1384+ QCOMPARE(anchors->right().item, layout->contentItem());
1385+ QCOMPARE(anchors->bottom().item, layout->contentItem());
1386 QVERIFY(!anchors->fill());
1387 QCOMPARE(anchors->margins(), 20.0);
1388 }
1389@@ -932,6 +951,115 @@
1390 QCOMPARE(layoutChangeSpy.count(), 1);
1391 }
1392
1393+ // guard bug #1204834 and #1300668
1394+ void testCase_Visibility()
1395+ {
1396+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("Visibility.qml"));
1397+ QVERIFY(view);
1398+ QQuickItem *root = view->rootObject();
1399+ QVERIFY(root);
1400+
1401+ ULLayouts *layout = view->findItem<ULLayouts*>("layoutManager");
1402+ QVERIFY(layout);
1403+ QSignalSpy layoutChangeSpy(layout, SIGNAL(currentLayoutChanged()));
1404+
1405+ QQuickItem *defaultLayout = testItem(root, "DefaultLayout");
1406+ QVERIFY(defaultLayout);
1407+
1408+ // invoke layout change
1409+ view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "portraitLayout");
1410+ layoutChangeSpy.wait(1000);
1411+ QCOMPARE(defaultLayout->parentItem(), layout->contentItem());
1412+ // despite of visible property binding, the visibility of the component is false
1413+ // while its parent is set to invisible
1414+ QCOMPARE(defaultLayout->isVisible(), false);
1415+ QCOMPARE(layout->contentItem()->isVisible(), false);
1416+
1417+ // change layout back
1418+ layoutChangeSpy.clear();
1419+ view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "landscapeLayout");
1420+ layoutChangeSpy.wait(1000);
1421+ QCOMPARE(defaultLayout->parentItem(), layout->contentItem());
1422+ QCOMPARE(defaultLayout->isVisible(), true);
1423+ QCOMPARE(layout->contentItem()->isVisible(), true);
1424+ }
1425+
1426+ void testCase_NestedVisibility_data() {
1427+ QTest::addColumn<QString>("layoutFunction");
1428+ QTest::addColumn<QString>("layoutName");
1429+
1430+ QTest::newRow("portrait") << "tabletPortraitLayout" << "tabletPortrait";
1431+ QTest::newRow("landscape") << "tabletLandscapeLayout" << "tabletLandscape";
1432+ }
1433+
1434+ void testCase_NestedVisibility()
1435+ {
1436+ QFETCH(QString, layoutFunction);
1437+ QFETCH(QString, layoutName);
1438+
1439+ QScopedPointer<UbuntuTestCase> view(new UbuntuTestCase("NestedVisibility.qml"));
1440+ QVERIFY(view);
1441+ QQuickItem *root = view->rootObject();
1442+ QVERIFY(root);
1443+
1444+ ULLayouts *mainLayout = view->findItem<ULLayouts*>("mainLayout");
1445+ QVERIFY(mainLayout);
1446+ QQuickItem *red = testItem(mainLayout, "mainRed");
1447+ QVERIFY(red);
1448+ QQuickItem *green = testItem(mainLayout, "mainGreen");
1449+ QVERIFY(green);
1450+ QQuickItem *blue = testItem(mainLayout, "mainBlue");
1451+ QVERIFY(blue);
1452+ QQuickItem *magenta = testItem(mainLayout, "mainMagenta");
1453+ QVERIFY(magenta);
1454+ QQuickItem *hidden = testItem(mainLayout, "mainHidden");
1455+ QVERIFY(hidden);
1456+ QCOMPARE(hidden->isVisible(), false);
1457+ // default is phone layout, get layd out items' neighbors
1458+ QQuickItem *greenPrev = prevSibling(green);
1459+ QQuickItem *magentaPrev = prevSibling(magenta);
1460+ QSizeF greenSize(green->width(), green->height());
1461+ QSizeF magentaSize(magenta->width(), magenta->height());
1462+
1463+ // invoke tablet layout change
1464+ QSignalSpy mainLayoutChangeSpy(mainLayout, SIGNAL(currentLayoutChanged()));
1465+ view->rootObject()->metaObject()->invokeMethod(view->rootObject(), layoutFunction.toLocal8Bit().data());
1466+ mainLayoutChangeSpy.wait(1000);
1467+ // get the nested layout
1468+ ULLayouts *nestedLayout = qobject_cast<ULLayouts*>(testItem(mainLayout, "nestedLayout"));
1469+ QVERIFY(nestedLayout);
1470+ QQuickItem *nestedActiveLayout = testItem(nestedLayout, layoutName);
1471+ QVERIFY(nestedActiveLayout);
1472+ QCOMPARE(red->isVisible(), false);
1473+ QCOMPARE(green->isVisible(), true);
1474+ QCOMPARE(blue->isVisible(), false);
1475+ QCOMPARE(magenta->isVisible(), true);
1476+ QCOMPARE(hidden->isVisible(), false);
1477+ // we cannot use findChild() to locate green and magenta boxes, as reparenting only
1478+ // changes the parentItem, not the parent object itself; therefore we only check if
1479+ // their container is in the layout
1480+ QVERIFY(hasChildItem(green, nestedActiveLayout));
1481+ QVERIFY(hasChildItem(magenta, nestedActiveLayout));
1482+
1483+ // go back to default layout of main
1484+ mainLayoutChangeSpy.clear();
1485+ view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "phoneLayout");
1486+ mainLayoutChangeSpy.wait(1000);
1487+ QCOMPARE(red->isVisible(), true);
1488+ QCOMPARE(green->isVisible(), true);
1489+ QCOMPARE(blue->isVisible(), true);
1490+ QCOMPARE(magenta->isVisible(), true);
1491+ QCOMPARE(hidden->isVisible(), false);
1492+ QCOMPARE(prevSibling(green), greenPrev);
1493+ QCOMPARE(prevSibling(magenta), magentaPrev);
1494+ QCOMPARE(green->width(), greenSize.width());
1495+ QCOMPARE(green->height(), greenSize.height());
1496+ QCOMPARE(magenta->width(), magentaSize.width());
1497+ QCOMPARE(magenta->height(), magentaSize.height());
1498+ QVERIFY(hasChildItem(green, mainLayout->contentItem()));
1499+ QVERIFY(hasChildItem(magenta, mainLayout->contentItem()));
1500+ }
1501+
1502 };
1503
1504 QTEST_MAIN(tst_Layouts)
1505
1506=== modified file 'tests/unit_x11/tst_layouts/tst_layouts.pro'
1507--- tests/unit_x11/tst_layouts/tst_layouts.pro 2014-02-18 13:27:23 +0000
1508+++ tests/unit_x11/tst_layouts/tst_layouts.pro 2014-05-20 19:37:09 +0000
1509@@ -37,4 +37,6 @@
1510 AnchorAll.qml \
1511 ItemInstanceAsProperty.qml \
1512 DialerCrash.qml \
1513- ExcludedItemDeleted.qml
1514+ ExcludedItemDeleted.qml \
1515+ Visibility.qml \
1516+ NestedVisibility.qml

Subscribers

People subscribed via source and target branches