Merge lp:~zsombi/ubuntu-ui-toolkit/listitemSelectModeBugs into lp:ubuntu-ui-toolkit/staging
- listitemSelectModeBugs
- Merge into staging
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Tim Peeters | ||||||||||||
Approved revision: | 1673 | ||||||||||||
Merged at revision: | 1743 | ||||||||||||
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/listitemSelectModeBugs | ||||||||||||
Merge into: | lp:ubuntu-ui-toolkit/staging | ||||||||||||
Diff against target: |
783 lines (+391/-48) 12 files modified
components.api (+2/-0) src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml (+2/-3) src/Ubuntu/Components/plugin/plugin.pri (+2/-0) src/Ubuntu/Components/plugin/privates/listitemselection.cpp (+141/-0) src/Ubuntu/Components/plugin/privates/listitemselection.h (+56/-0) src/Ubuntu/Components/plugin/uclistitem.cpp (+38/-26) src/Ubuntu/Components/plugin/uclistitem.h (+4/-2) src/Ubuntu/Components/plugin/uclistitem_p.h (+2/-1) src/Ubuntu/Components/plugin/ucviewitemsattached.cpp (+6/-6) tests/resources/listitems/ListItemDragging.qml (+7/-2) tests/unit_x11/tst_components/tst_listitem_selectmode.qml (+69/-4) tests/unit_x11/tst_components/tst_listitem_selectmode13.qml (+62/-4) |
||||||||||||
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/listitemSelectModeBugs | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tim Peeters | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email:
|
Commit message
Fixing ListItem.selected and ListItem.selectMode bugs.
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1669. By Zsombor Egri
-
staging sync
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1669
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1670. By Zsombor Egri
-
staging sync
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1670
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Tim Peeters (tpeeters) wrote : | # |
+ function test_togle_
Some typos here. Everything else looks good.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Tim Peeters (tpeeters) wrote : | # |
+ function test_select_
I don't know how to read this function name as a sentence. Can you make it more clear?
- 1671. By Zsombor Egri
-
typo and test name renamed
- 1672. By Zsombor Egri
-
staging sync
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1672
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Tim Peeters (tpeeters) wrote : | # |
function test_togle_
*togle
*selecded
- 1673. By Zsombor Egri
-
more typo fixes
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2015-12-03 15:45:33 +0000 |
3 | +++ components.api 2015-12-08 14:59:12 +0000 |
4 | @@ -564,6 +564,7 @@ |
5 | property bool selectMode |
6 | property bool selected |
7 | property bool swipeEnabled 1.3 |
8 | + readonly property bool swiped 1.3 |
9 | property ListItemActions trailingActions |
10 | Ubuntu.Components.ListItemActions 1.2: QtObject |
11 | property list<Action> actions |
12 | @@ -1619,6 +1620,7 @@ |
13 | property bool dragMode |
14 | property list<int> expandedIndices |
15 | property int expansionFlags |
16 | + signal selectedIndicesChanged(list<int> indices) |
17 | signal dragUpdated(ListItemDrag event) |
18 | signal expandedIndicesChanged(list<int> indices) |
19 | property bool selectMode |
20 | |
21 | === modified file 'src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml' |
22 | --- src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-09-18 11:31:26 +0000 |
23 | +++ src/Ubuntu/Components/Themes/Ambiance/1.3/ListItemStyle.qml 2015-12-08 14:59:12 +0000 |
24 | @@ -234,7 +234,7 @@ |
25 | right: parent.left |
26 | } |
27 | width: styledItem.width |
28 | - sourceComponent: internals.swiped && styledItem.leadingActions && styledItem.leadingActions.actions.length > 0 ? |
29 | + sourceComponent: styledItem.swiped && styledItem.leadingActions && styledItem.leadingActions.actions.length > 0 ? |
30 | panelComponent : null |
31 | // context properties used in delegates |
32 | readonly property bool leading: true |
33 | @@ -283,7 +283,7 @@ |
34 | left: parent.right |
35 | } |
36 | width: styledItem.width |
37 | - sourceComponent: internals.swiped && styledItem.trailingActions && styledItem.trailingActions.actions.length > 0 ? |
38 | + sourceComponent: styledItem.swiped && styledItem.trailingActions && styledItem.trailingActions.actions.length > 0 ? |
39 | panelComponent : null |
40 | // context properties used in delegates |
41 | readonly property bool leading: false |
42 | @@ -327,7 +327,6 @@ |
43 | // action triggered |
44 | property Action selectedAction |
45 | // swipe handling |
46 | - readonly property bool swiped: listItemStyle.x != styledItem.x && !styledItem.selectMode && !styledItem.dragMode |
47 | readonly property Item swipedPanel: leadingPanel ? leadingLoader.item : trailingLoader.item |
48 | readonly property bool leadingPanel: listItemStyle.LayoutMirroring.enabled ? (listItemStyle.x < 0) : (listItemStyle.x > 0) |
49 | readonly property real swipedOffset: (leadingPanel ? listItemStyle.x : -listItemStyle.x) * |
50 | |
51 | === modified file 'src/Ubuntu/Components/plugin/plugin.pri' |
52 | --- src/Ubuntu/Components/plugin/plugin.pri 2015-11-23 15:14:16 +0000 |
53 | +++ src/Ubuntu/Components/plugin/plugin.pri 2015-12-08 14:59:12 +0000 |
54 | @@ -75,6 +75,7 @@ |
55 | $$PWD/ucserviceproperties_p.h \ |
56 | $$PWD/privates/listitemdragarea.h \ |
57 | $$PWD/privates/listitemdraghandler.h \ |
58 | + $$PWD/privates/listitemselection.h \ |
59 | $$PWD/ucnamespace.h \ |
60 | $$PWD/ucdeprecatedtheme.h \ |
61 | $$PWD/ucdefaulttheme.h \ |
62 | @@ -150,6 +151,7 @@ |
63 | $$PWD/privates/listitemdragarea.cpp \ |
64 | $$PWD/privates/listitemdraghandler.cpp \ |
65 | $$PWD/privates/listitemexpansion.cpp \ |
66 | + $$PWD/privates/listitemselection.cpp \ |
67 | $$PWD/ucnamespace.cpp \ |
68 | $$PWD/ucdeprecatedtheme.cpp \ |
69 | $$PWD/ucdefaulttheme.cpp \ |
70 | |
71 | === added file 'src/Ubuntu/Components/plugin/privates/listitemselection.cpp' |
72 | --- src/Ubuntu/Components/plugin/privates/listitemselection.cpp 1970-01-01 00:00:00 +0000 |
73 | +++ src/Ubuntu/Components/plugin/privates/listitemselection.cpp 2015-12-08 14:59:12 +0000 |
74 | @@ -0,0 +1,141 @@ |
75 | +/* |
76 | + * Copyright 2015 Canonical Ltd. |
77 | + * |
78 | + * This program is free software; you can redistribute it and/or modify |
79 | + * it under the terms of the GNU Lesser General Public License as published by |
80 | + * the Free Software Foundation; version 3. |
81 | + * |
82 | + * This program is distributed in the hope that it will be useful, |
83 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
84 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
85 | + * GNU Lesser General Public License for more details. |
86 | + * |
87 | + * You should have received a copy of the GNU Lesser General Public License |
88 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
89 | + */ |
90 | + |
91 | +#include "listitemselection.h" |
92 | +#include "uclistitem_p.h" |
93 | + |
94 | +ListItemSelection::ListItemSelection(UCListItem *parent) |
95 | + : QObject(parent) |
96 | + , hostItem(parent) |
97 | + , dirtyFlags(0) |
98 | + , selectMode(false) |
99 | + , selected(false) |
100 | +{ |
101 | +} |
102 | + |
103 | +// initialize connections between ViewItems and selection handler |
104 | +void ListItemSelection::attachToViewItems(UCViewItemsAttached *newViewItems) |
105 | +{ |
106 | + if (viewItems.data() == newViewItems) { |
107 | + return; |
108 | + } |
109 | + if (viewItems) { |
110 | + disconnect(viewItems.data(), &UCViewItemsAttached::selectModeChanged, |
111 | + this, &ListItemSelection::onSelectModeChanged); |
112 | + disconnect(viewItems.data(), &UCViewItemsAttached::selectedIndicesChanged, |
113 | + this, &ListItemSelection::onSelectedIndicesChanged); |
114 | + viewItems.clear(); |
115 | + } |
116 | + if (newViewItems) { |
117 | + viewItems = newViewItems; |
118 | + connect(viewItems.data(), &UCViewItemsAttached::selectModeChanged, |
119 | + this, &ListItemSelection::onSelectModeChanged); |
120 | + connect(viewItems.data(), &UCViewItemsAttached::selectedIndicesChanged, |
121 | + this, &ListItemSelection::onSelectedIndicesChanged); |
122 | + syncWithViewItems(); |
123 | + } |
124 | +} |
125 | + |
126 | +// synchronize selection handler data to the ViewItems |
127 | +void ListItemSelection::syncWithViewItems() |
128 | +{ |
129 | + if (viewItems) { |
130 | + QSignalBlocker blocker(viewItems.data()); |
131 | + |
132 | + // sync selectMode |
133 | + if (dirtyFlags & SelectModeDirty) { |
134 | + viewItems->setSelectMode(selectMode); |
135 | + } else if (viewItems->selectMode() != selectMode) { |
136 | + selectMode = inSelectMode(); |
137 | + Q_EMIT hostItem->selectModeChanged(); |
138 | + } |
139 | + |
140 | + // sync selected |
141 | + if (dirtyFlags & SelectedDirty) { |
142 | + if (selected) { |
143 | + UCViewItemsAttachedPrivate::get(viewItems.data())->addSelectedItem(hostItem); |
144 | + } else { |
145 | + UCViewItemsAttachedPrivate::get(viewItems.data())->removeSelectedItem(hostItem); |
146 | + } |
147 | + } else if (selected != isSelected()) { |
148 | + selected = isSelected(); |
149 | + Q_EMIT hostItem->selectedChanged(); |
150 | + } |
151 | + dirtyFlags = 0; |
152 | + } |
153 | +} |
154 | + |
155 | +bool ListItemSelection::inSelectMode() const |
156 | +{ |
157 | + return viewItems ? viewItems->selectMode() : selectMode; |
158 | +} |
159 | +void ListItemSelection::setSelectMode(bool mode) |
160 | +{ |
161 | + if (mode == inSelectMode()) { |
162 | + return; |
163 | + } |
164 | + if (viewItems) { |
165 | + // selectMode is updated through the updateSelectMode() |
166 | + viewItems->setSelectMode(mode); |
167 | + } else { |
168 | + selectMode = mode; |
169 | + dirtyFlags |= SelectModeDirty; |
170 | + Q_EMIT hostItem->selectModeChanged(); |
171 | + } |
172 | +} |
173 | + |
174 | +bool ListItemSelection::isSelected() const |
175 | +{ |
176 | + if (viewItems) { |
177 | + return UCViewItemsAttachedPrivate::get(viewItems.data())->isItemSelected(hostItem); |
178 | + } |
179 | + return selected; |
180 | +} |
181 | +void ListItemSelection::setSelected(bool selected) |
182 | +{ |
183 | + if (selected == isSelected()) { |
184 | + return; |
185 | + } |
186 | + if (viewItems) { |
187 | + // this->selected is updated through updateSelected() |
188 | + if (selected) { |
189 | + UCViewItemsAttachedPrivate::get(viewItems.data())->addSelectedItem(hostItem); |
190 | + } else { |
191 | + UCViewItemsAttachedPrivate::get(viewItems.data())->removeSelectedItem(hostItem); |
192 | + } |
193 | + } else { |
194 | + this->selected = selected; |
195 | + dirtyFlags |= SelectedDirty; |
196 | + Q_EMIT hostItem->selectedChanged(); |
197 | + } |
198 | +} |
199 | + |
200 | +void ListItemSelection::onSelectModeChanged() |
201 | +{ |
202 | + UCListItemPrivate *d = UCListItemPrivate::get(hostItem); |
203 | + selectMode = d->parentAttached->selectMode(); |
204 | + d->loadStyleItem(); |
205 | + Q_EMIT hostItem->selectModeChanged(); |
206 | +} |
207 | + |
208 | +void ListItemSelection::onSelectedIndicesChanged(const QList<int> &indices) |
209 | +{ |
210 | + UCListItemPrivate *d = UCListItemPrivate::get(hostItem); |
211 | + if (selected != indices.contains(d->index())) { |
212 | + selected = indices.contains(d->index()); |
213 | + Q_EMIT hostItem->selectedChanged(); |
214 | + } |
215 | +} |
216 | |
217 | === added file 'src/Ubuntu/Components/plugin/privates/listitemselection.h' |
218 | --- src/Ubuntu/Components/plugin/privates/listitemselection.h 1970-01-01 00:00:00 +0000 |
219 | +++ src/Ubuntu/Components/plugin/privates/listitemselection.h 2015-12-08 14:59:12 +0000 |
220 | @@ -0,0 +1,56 @@ |
221 | +/* |
222 | + * Copyright 2015 Canonical Ltd. |
223 | + * |
224 | + * This program is free software; you can redistribute it and/or modify |
225 | + * it under the terms of the GNU Lesser General Public License as published by |
226 | + * the Free Software Foundation; version 3. |
227 | + * |
228 | + * This program is distributed in the hope that it will be useful, |
229 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
230 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
231 | + * GNU Lesser General Public License for more details. |
232 | + * |
233 | + * You should have received a copy of the GNU Lesser General Public License |
234 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
235 | + */ |
236 | + |
237 | +#ifndef LISTITEMSELECTION_H |
238 | +#define LISTITEMSELECTION_H |
239 | + |
240 | +#include <QtCore/QObject> |
241 | +#include <QtCore/QPointer> |
242 | + |
243 | +class UCViewItemsAttached; |
244 | +class UCListItem; |
245 | +class ListItemSelection : public QObject |
246 | +{ |
247 | + Q_OBJECT |
248 | +public: |
249 | + explicit ListItemSelection(UCListItem *parent = 0); |
250 | + |
251 | + void attachToViewItems(UCViewItemsAttached * newViewItems); |
252 | + |
253 | + bool inSelectMode() const; |
254 | + void setSelectMode(bool mode); |
255 | + |
256 | + bool isSelected() const; |
257 | + void setSelected(bool selected); |
258 | + |
259 | + void onSelectModeChanged(); |
260 | + void onSelectedIndicesChanged(const QList<int> &indices); |
261 | + |
262 | +private: |
263 | + QPointer<UCViewItemsAttached> viewItems; |
264 | + UCListItem *hostItem; |
265 | + enum { |
266 | + SelectModeDirty = 0x01, |
267 | + SelectedDirty = 0x02 |
268 | + }; |
269 | + quint8 dirtyFlags; |
270 | + bool selectMode:1; |
271 | + bool selected:1; |
272 | + |
273 | + void syncWithViewItems(); |
274 | +}; |
275 | + |
276 | +#endif // LISTITEMSELECTION_H |
277 | |
278 | === modified file 'src/Ubuntu/Components/plugin/uclistitem.cpp' |
279 | --- src/Ubuntu/Components/plugin/uclistitem.cpp 2015-10-26 11:48:44 +0000 |
280 | +++ src/Ubuntu/Components/plugin/uclistitem.cpp 2015-12-08 14:59:12 +0000 |
281 | @@ -21,6 +21,7 @@ |
282 | #include "uclistitem_p.h" |
283 | #include "uclistitemactions.h" |
284 | #include "uclistitemactions_p.h" |
285 | +#include "privates/listitemselection.h" |
286 | #include "ucubuntuanimation.h" |
287 | #include "propertychange_p.h" |
288 | #include "i18n.h" |
289 | @@ -195,6 +196,7 @@ |
290 | , trailingActions(Q_NULLPTR) |
291 | , mainAction(Q_NULLPTR) |
292 | , expansion(Q_NULLPTR) |
293 | + , selection(Q_NULLPTR) |
294 | , xAxisMoveThresholdGU(DEFAULT_SWIPE_THRESHOLD_GU) |
295 | , button(Qt::NoButton) |
296 | , highlighted(false) |
297 | @@ -237,7 +239,10 @@ |
298 | // watch grid unit size change and set implicit size |
299 | QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), q, SLOT(_q_updateSize())); |
300 | _q_updateSize(); |
301 | - setStyleName("ListItemStyle"); |
302 | + styleDocument = "ListItemStyle"; |
303 | + |
304 | + // create selection object |
305 | + selection = new ListItemSelection(q); |
306 | } |
307 | |
308 | void UCListItemPrivate::_q_themeChanged() |
309 | @@ -303,13 +308,6 @@ |
310 | |
311 | // synchronizes selection mode, initializes the style if has not been done yet, |
312 | // which in turn reveals the selection panels |
313 | -void UCListItemPrivate::_q_syncSelectMode() |
314 | -{ |
315 | - loadStyleItem(); |
316 | - Q_Q(UCListItem); |
317 | - Q_EMIT q->selectModeChanged(); |
318 | -} |
319 | - |
320 | // same for the dragMode |
321 | void UCListItemPrivate::_q_syncDragMode() |
322 | { |
323 | @@ -329,7 +327,9 @@ |
324 | bool UCListItemPrivate::loadStyleItem(bool animated) |
325 | { |
326 | // the style should be loaded only if one of the condition is satisfied |
327 | - if (!swiped && !selectMode() && !dragMode() && !(expansion && expansion->expanded())) { |
328 | + // do not use selectMode() as that will create the selection handler, which may not even be needed at this phase. |
329 | + bool inSelectMode = (selection && selection->inSelectMode()); |
330 | + if (!swiped && !inSelectMode && !dragMode() && !(expansion && expansion->expanded())) { |
331 | return false; |
332 | } |
333 | |
334 | @@ -427,6 +427,7 @@ |
335 | // lock contentItem left/right edges |
336 | lockContentItem(true); |
337 | } |
338 | + Q_EMIT q->swipedChanged(); |
339 | } |
340 | |
341 | // connects/disconnects from the Flickable anchestor to get notified when to do rebound |
342 | @@ -1014,13 +1015,7 @@ |
343 | } |
344 | |
345 | if (d->parentAttached) { |
346 | - // connect selectedIndicesChanged |
347 | - connect(d->parentAttached.data(), &UCViewItemsAttached::selectedIndicesChanged, |
348 | - this, &UCListItem::selectedChanged); |
349 | - // sync selectModeChanged() |
350 | - connect(d->parentAttached, SIGNAL(selectModeChanged()), |
351 | - this, SLOT(_q_syncSelectMode())); |
352 | - // also draggable |
353 | + // update draggable |
354 | connect(d->parentAttached, SIGNAL(dragModeChanged()), |
355 | this, SLOT(_q_syncDragMode())); |
356 | |
357 | @@ -1072,6 +1067,7 @@ |
358 | } |
359 | |
360 | if (d->parentAttached) { |
361 | + d->selection->attachToViewItems(d->parentAttached.data()); |
362 | connect(d->parentAttached.data(), SIGNAL(expandedIndicesChanged(QList<int>)), |
363 | this, SLOT(_q_updateExpansion(QList<int>)), Qt::DirectConnection); |
364 | } |
365 | @@ -1693,16 +1689,14 @@ |
366 | bool UCListItemPrivate::isSelected() |
367 | { |
368 | Q_Q(UCListItem); |
369 | - return UCViewItemsAttachedPrivate::get(parentAttached)->isItemSelected(q); |
370 | + Q_ASSERT(selection); |
371 | + return selection->isSelected(); |
372 | } |
373 | void UCListItemPrivate::setSelected(bool value) |
374 | { |
375 | Q_Q(UCListItem); |
376 | - if (value) { |
377 | - UCViewItemsAttachedPrivate::get(parentAttached)->addSelectedItem(q); |
378 | - } else { |
379 | - UCViewItemsAttachedPrivate::get(parentAttached)->removeSelectedItem(q); |
380 | - } |
381 | + Q_ASSERT(selection); |
382 | + selection->setSelected(value); |
383 | } |
384 | |
385 | /*! |
386 | @@ -1715,14 +1709,19 @@ |
387 | */ |
388 | bool UCListItemPrivate::selectMode() |
389 | { |
390 | - UCViewItemsAttachedPrivate *attached = UCViewItemsAttachedPrivate::get(parentAttached); |
391 | - return attached ? attached->selectable : false; |
392 | + Q_Q(UCListItem); |
393 | + if (!selection) { |
394 | + selection = new ListItemSelection(q); |
395 | + } |
396 | + return selection->inSelectMode(); |
397 | } |
398 | void UCListItemPrivate::setSelectMode(bool selectable) |
399 | { |
400 | - if (parentAttached) { |
401 | - parentAttached->setSelectMode(selectable); |
402 | + Q_Q(UCListItem); |
403 | + if (!selection) { |
404 | + selection = new ListItemSelection(q); |
405 | } |
406 | + selection->setSelectMode(selectable); |
407 | } |
408 | |
409 | /*! |
410 | @@ -1848,4 +1847,17 @@ |
411 | Q_EMIT swipeEnabledChanged(); |
412 | } |
413 | |
414 | +/*! |
415 | + * \qmlproperty bool ListItem::swiped |
416 | + * \readonly |
417 | + * \since Ubuntu.Components 1.3 |
418 | + * The property notifies about the content being swiped so leading or trailing |
419 | + * actions are visible. |
420 | + */ |
421 | +bool UCListItem::isSwiped() |
422 | +{ |
423 | + Q_D(UCListItem); |
424 | + return d->swiped; |
425 | +} |
426 | + |
427 | #include "moc_uclistitem.cpp" |
428 | |
429 | === modified file 'src/Ubuntu/Components/plugin/uclistitem.h' |
430 | --- src/Ubuntu/Components/plugin/uclistitem.h 2015-10-26 11:48:44 +0000 |
431 | +++ src/Ubuntu/Components/plugin/uclistitem.h 2015-12-08 14:59:12 +0000 |
432 | @@ -48,6 +48,7 @@ |
433 | // 1.3 |
434 | Q_PROPERTY(UCListItemExpansion* expansion READ expansion CONSTANT REVISION 1) |
435 | Q_PROPERTY(bool swipeEnabled READ isSwipeEnabled WRITE setSwipeEnabled NOTIFY swipeEnabledChanged FINAL REVISION 1) |
436 | + Q_PROPERTY(bool swiped READ isSwiped NOTIFY swipedChanged FINAL REVISION 1) |
437 | public: |
438 | explicit UCListItem(QQuickItem *parent = 0); |
439 | ~UCListItem(); |
440 | @@ -68,6 +69,7 @@ |
441 | UCListItemExpansion *expansion(); |
442 | bool isSwipeEnabled() const; |
443 | void setSwipeEnabled(bool swipeEnabled); |
444 | + bool isSwiped(); |
445 | |
446 | protected: |
447 | virtual QObject *attachedViewItems(QObject *object, bool create); |
448 | @@ -96,6 +98,7 @@ |
449 | void actionChanged(); |
450 | void listItemChildrenChanged(); |
451 | Q_REVISION(1) void swipeEnabledChanged(); |
452 | + Q_REVISION(1) void swipedChanged(); |
453 | |
454 | void clicked(); |
455 | void pressAndHold(); |
456 | @@ -115,7 +118,6 @@ |
457 | Q_PRIVATE_SLOT(d_func(), void _q_updateSize()) |
458 | Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) |
459 | Q_PRIVATE_SLOT(d_func(), void _q_contentMoving()) |
460 | - Q_PRIVATE_SLOT(d_func(), void _q_syncSelectMode()) |
461 | Q_PRIVATE_SLOT(d_func(), void _q_syncDragMode()) |
462 | Q_PRIVATE_SLOT(d_func(), void _q_updateExpansion(const QList<int> &indices)) |
463 | Q_PRIVATE_SLOT(d_func(), void _q_popoverClosed()) |
464 | @@ -198,7 +200,7 @@ |
465 | |
466 | Q_SIGNALS: |
467 | void selectModeChanged(); |
468 | - void selectedIndicesChanged(); |
469 | + void selectedIndicesChanged(const QList<int> &indices); |
470 | void dragModeChanged(); |
471 | |
472 | void dragUpdated(UCDragEvent *event); |
473 | |
474 | === modified file 'src/Ubuntu/Components/plugin/uclistitem_p.h' |
475 | --- src/Ubuntu/Components/plugin/uclistitem_p.h 2015-10-26 11:48:44 +0000 |
476 | +++ src/Ubuntu/Components/plugin/uclistitem_p.h 2015-12-08 14:59:12 +0000 |
477 | @@ -34,6 +34,7 @@ |
478 | class UCListItemActions; |
479 | class UCListItemStyle; |
480 | class ListItemDragHandler; |
481 | +class ListItemSelection; |
482 | class UCListItemPrivate : public UCStyledItemBasePrivate |
483 | { |
484 | Q_DECLARE_PUBLIC(UCListItem) |
485 | @@ -57,7 +58,6 @@ |
486 | void _q_updateSize(); |
487 | void _q_updateIndex(); |
488 | void _q_contentMoving(); |
489 | - void _q_syncSelectMode(); |
490 | void _q_syncDragMode(); |
491 | void _q_updateExpansion(const QList<int> &indices); |
492 | int index(); |
493 | @@ -92,6 +92,7 @@ |
494 | UCListItemActions *trailingActions; |
495 | UCAction *mainAction; |
496 | UCListItemExpansion *expansion; |
497 | + ListItemSelection *selection; |
498 | qreal xAxisMoveThresholdGU; |
499 | Qt::MouseButton button; |
500 | bool highlighted:1; |
501 | |
502 | === modified file 'src/Ubuntu/Components/plugin/ucviewitemsattached.cpp' |
503 | --- src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-09-23 14:31:26 +0000 |
504 | +++ src/Ubuntu/Components/plugin/ucviewitemsattached.cpp 2015-12-08 14:59:12 +0000 |
505 | @@ -291,7 +291,7 @@ |
506 | return; |
507 | } |
508 | d->selectedList = QSet<int>::fromList(list); |
509 | - Q_EMIT selectedIndicesChanged(); |
510 | + Q_EMIT selectedIndicesChanged(list); |
511 | } |
512 | |
513 | bool UCViewItemsAttachedPrivate::addSelectedItem(UCListItem *item) |
514 | @@ -299,7 +299,7 @@ |
515 | int index = UCListItemPrivate::get(item)->index(); |
516 | if (!selectedList.contains(index)) { |
517 | selectedList.insert(index); |
518 | - Q_EMIT q_func()->selectedIndicesChanged(); |
519 | + Q_EMIT q_func()->selectedIndicesChanged(selectedList.toList()); |
520 | return true; |
521 | } |
522 | return false; |
523 | @@ -307,7 +307,7 @@ |
524 | bool UCViewItemsAttachedPrivate::removeSelectedItem(UCListItem *item) |
525 | { |
526 | if (selectedList.remove(UCListItemPrivate::get(item)->index()) > 0) { |
527 | - Q_EMIT q_func()->selectedIndicesChanged(); |
528 | + Q_EMIT q_func()->selectedIndicesChanged(selectedList.toList()); |
529 | return true; |
530 | } |
531 | return false; |
532 | @@ -524,7 +524,7 @@ |
533 | bool isFromSelected = selectedList.contains(fromIndex); |
534 | if (isFromSelected) { |
535 | selectedList.remove(fromIndex); |
536 | - Q_EMIT q->selectedIndicesChanged(); |
537 | + Q_EMIT q->selectedIndicesChanged(selectedList.toList()); |
538 | } |
539 | // direction is -1 (forwards) or 1 (backwards) |
540 | int direction = (fromIndex < toIndex) ? -1 : 1; |
541 | @@ -539,13 +539,13 @@ |
542 | if (selectedList.contains(i)) { |
543 | selectedList.remove(i); |
544 | selectedList.insert(i + direction); |
545 | - Q_EMIT q->selectedIndicesChanged(); |
546 | + Q_EMIT q->selectedIndicesChanged(selectedList.toList()); |
547 | } |
548 | i -= direction; |
549 | } |
550 | if (isFromSelected) { |
551 | selectedList.insert(toIndex); |
552 | - Q_EMIT q->selectedIndicesChanged(); |
553 | + Q_EMIT q->selectedIndicesChanged(selectedList.toList()); |
554 | } |
555 | } |
556 | |
557 | |
558 | === modified file 'tests/resources/listitems/ListItemDragging.qml' |
559 | --- tests/resources/listitems/ListItemDragging.qml 2015-08-31 10:15:27 +0000 |
560 | +++ tests/resources/listitems/ListItemDragging.qml 2015-12-08 14:59:12 +0000 |
561 | @@ -15,9 +15,9 @@ |
562 | */ |
563 | |
564 | import QtQuick 2.4 |
565 | -import Ubuntu.Components 1.2 |
566 | +import Ubuntu.Components 1.3 |
567 | import QtQuick.Layouts 1.1 |
568 | -import Ubuntu.Components.ListItems 1.0 |
569 | +import Ubuntu.Components.ListItems 1.3 |
570 | import QtQml.Models 2.1 |
571 | |
572 | MainView { |
573 | @@ -133,6 +133,7 @@ |
574 | trailingActions: ListItemActions { |
575 | actions: contextualActions |
576 | } |
577 | + onSelectedChanged: print(selected) |
578 | |
579 | RowLayout { |
580 | anchors { |
581 | @@ -150,6 +151,10 @@ |
582 | captionStyle: Ubuntu.SummaryCaptionStyle |
583 | title.text: "LTR" |
584 | subtitle.text: "RTL" |
585 | + MouseArea { |
586 | + anchors.fill: parent |
587 | + onClicked: item.selected = !item.selected |
588 | + } |
589 | } |
590 | } |
591 | |
592 | |
593 | === modified file 'tests/unit_x11/tst_components/tst_listitem_selectmode.qml' |
594 | --- tests/unit_x11/tst_components/tst_listitem_selectmode.qml 2015-07-13 19:49:29 +0000 |
595 | +++ tests/unit_x11/tst_components/tst_listitem_selectmode.qml 2015-12-08 14:59:12 +0000 |
596 | @@ -41,7 +41,11 @@ |
597 | ListElement { text: "Also notice how when pressing on the listitem in step 3, the selected indice still changes!" } |
598 | } |
599 | |
600 | - anchors.fill: parent |
601 | + anchors { |
602 | + fill: parent |
603 | + bottomMargin: parent.height / 2 |
604 | + } |
605 | + clip: true |
606 | model: instructionModel |
607 | |
608 | delegate: ListItem { |
609 | @@ -74,11 +78,48 @@ |
610 | text: "Selected Indices: " + listView.ViewItems.selectedIndices |
611 | } |
612 | } |
613 | - } |
614 | - |
615 | - UbuntuTestCase { |
616 | + |
617 | + UbuntuListView { |
618 | + id: testView |
619 | + anchors { |
620 | + fill: parent |
621 | + topMargin: parent.height / 2 |
622 | + bottomMargin: notInView.height |
623 | + } |
624 | + clip: true |
625 | + } |
626 | + |
627 | + // for bug1514928 |
628 | + ListItem { |
629 | + id: notInView |
630 | + selected: true |
631 | + } |
632 | + } |
633 | + |
634 | + Component { |
635 | + id: selectModePreset |
636 | + ListItem { |
637 | + id: litem |
638 | + objectName: "listItem" + index |
639 | + selectMode: true |
640 | + property SignalSpy selectedChangedSpy: SignalSpy { |
641 | + target: litem |
642 | + signalName: "selectedChanged" |
643 | + } |
644 | + } |
645 | + } |
646 | + |
647 | + ListItemTestCase { |
648 | + name: "ListItem.selectMode" |
649 | when: windowShown |
650 | |
651 | + function cleanup() { |
652 | + listView.ViewItems.selectMode = false; |
653 | + testView.model = null; |
654 | + testView.delegate = null; |
655 | + wait(200); |
656 | + } |
657 | + |
658 | function test_select_toggle_breaks_property_binding_bug1469471() { |
659 | listView.ViewItems.selectMode = true; |
660 | wait(400); |
661 | @@ -99,6 +140,30 @@ |
662 | listItem.selected = !listItem.selected; |
663 | compare(checkBox.checked, false); |
664 | } |
665 | + |
666 | + function test_select_mode_set_in_listview_delegate_bug1493882() { |
667 | + testView.delegate = selectModePreset; |
668 | + testView.model = 10; |
669 | + waitForRendering(testView, 500); |
670 | + var item = findChild(testView, "listItem0"); |
671 | + verify(item); |
672 | + var selectPanel = findChild(item, "selection_panel0"); |
673 | + verify(selectPanel, "selection panel not found"); |
674 | + } |
675 | + |
676 | + function test_toggle_selected_triggers_one_selectedChanged_bug1493880() { |
677 | + testView.delegate = selectModePreset; |
678 | + testView.model = 10; |
679 | + waitForRendering(testView, 500); |
680 | + var item0 = findChild(testView, "listItem0"); |
681 | + var item1 = findChild(testView, "listItem1"); |
682 | + verify(item0 && item1); |
683 | + |
684 | + // select #0 |
685 | + item0.selected = true; |
686 | + item0.selectedChangedSpy.wait(); |
687 | + compare(item1.selectedChangedSpy.count, 0, "Only the selected item should emit the change signal!"); |
688 | + } |
689 | } |
690 | } |
691 | |
692 | |
693 | === modified file 'tests/unit_x11/tst_components/tst_listitem_selectmode13.qml' |
694 | --- tests/unit_x11/tst_components/tst_listitem_selectmode13.qml 2015-07-13 19:49:29 +0000 |
695 | +++ tests/unit_x11/tst_components/tst_listitem_selectmode13.qml 2015-12-08 14:59:12 +0000 |
696 | @@ -41,7 +41,11 @@ |
697 | ListElement { text: "Also notice how when pressing on the listitem in step 3, the selected indice still changes!" } |
698 | } |
699 | |
700 | - anchors.fill: parent |
701 | + anchors { |
702 | + fill: parent |
703 | + bottomMargin: parent.height / 2 |
704 | + } |
705 | + clip: true |
706 | model: instructionModel |
707 | |
708 | delegate: ListItem { |
709 | @@ -74,11 +78,41 @@ |
710 | text: "Selected Indices: " + listView.ViewItems.selectedIndices |
711 | } |
712 | } |
713 | - } |
714 | - |
715 | - UbuntuTestCase { |
716 | + |
717 | + UbuntuListView { |
718 | + id: testView |
719 | + anchors { |
720 | + fill: parent |
721 | + topMargin: parent.height / 2 |
722 | + } |
723 | + clip: true |
724 | + } |
725 | + } |
726 | + |
727 | + Component { |
728 | + id: selectModePreset |
729 | + ListItem { |
730 | + id: litem |
731 | + objectName: "listItem" + index |
732 | + selectMode: true |
733 | + property SignalSpy selectedChangedSpy: SignalSpy { |
734 | + target: litem |
735 | + signalName: "selectedChanged" |
736 | + } |
737 | + } |
738 | + } |
739 | + |
740 | + ListItemTestCase13 { |
741 | + name: "ListItem13.selectMode" |
742 | when: windowShown |
743 | |
744 | + function cleanup() { |
745 | + listView.ViewItems.selectMode = false; |
746 | + testView.model = null; |
747 | + testView.delegate = null; |
748 | + wait(200); |
749 | + } |
750 | + |
751 | function test_select_toggle_breaks_property_binding_bug1469471() { |
752 | listView.ViewItems.selectMode = true; |
753 | wait(400); |
754 | @@ -99,6 +133,30 @@ |
755 | listItem.selected = !listItem.selected; |
756 | compare(checkBox.checked, false); |
757 | } |
758 | + |
759 | + function test_select_mode_turned_on_delegate_on_creation_bug1493882() { |
760 | + testView.delegate = selectModePreset; |
761 | + testView.model = 10; |
762 | + waitForRendering(testView, 500); |
763 | + var item = findChild(testView, "listItem0"); |
764 | + verify(item); |
765 | + var selectPanel = findChild(item, "selection_panel0"); |
766 | + verify(selectPanel, "selection panel not found"); |
767 | + } |
768 | + |
769 | + function test_togle_selded_triggers_one_selectedChanged_bug1493880() { |
770 | + testView.delegate = selectModePreset; |
771 | + testView.model = 10; |
772 | + waitForRendering(testView, 500); |
773 | + var item0 = findChild(testView, "listItem0"); |
774 | + var item1 = findChild(testView, "listItem1"); |
775 | + verify(item0 && item1); |
776 | + |
777 | + // select #0 |
778 | + item0.selected = true; |
779 | + item0.selectedChangedSpy.wait(); |
780 | + compare(item1.selectedChangedSpy.count, 0, "Only the selected item should emit the change signal!"); |
781 | + } |
782 | } |
783 | } |
784 |
FAILED: Continuous integration, rev:1668 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/2487/ jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/1215 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/1217 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/1217/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/1214
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/2487/ rebuild
http://