Merge lp:~ahayzen/music-app/refactor-move-delegates into lp:music-app
- refactor-move-delegates
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Victor Thompson |
Approved revision: | 845 |
Merged at revision: | 841 |
Proposed branch: | lp:~ahayzen/music-app/refactor-move-delegates |
Merge into: | lp:music-app |
Diff against target: |
1287 lines (+455/-480) 19 files modified
app/components/CMakeLists.txt (+1/-0) app/components/Delegates/CMakeLists.txt (+4/-0) app/components/Delegates/Card.qml (+1/-0) app/components/Delegates/ListItemWithActions.qml (+9/-239) app/components/Delegates/MusicListItem.qml (+151/-0) app/components/ListItemActions/AddToPlaylist.qml (+0/-2) app/components/ListItemActions/Remove.qml (+0/-2) app/components/ListItemReorderComponent.qml (+106/-0) app/ui/AddToPlaylist.qml (+1/-0) app/ui/Albums.qml (+1/-0) app/ui/ArtistView.qml (+1/-0) app/ui/Artists.qml (+1/-0) app/ui/Genres.qml (+1/-0) app/ui/NowPlaying.qml (+57/-90) app/ui/Playlists.qml (+1/-0) app/ui/Recent.qml (+1/-0) app/ui/Songs.qml (+38/-55) app/ui/SongsView.qml (+77/-88) tests/autopilot/music_app/__init__.py (+4/-4) |
To merge this branch: | bzr merge lp:~ahayzen/music-app/refactor-move-delegates |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Victor Thompson | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+249883@code.launchpad.net |
Commit message
* Move delegates into their own folder in components
* Split out multiselect/reorder code from ListItemWithAct
* Fix for ListItemWithAct
Description of the change
* Move delegates into their own folder in components
* Split out multiselect/reorder code from ListItemWithAct
* Fix for ListItemWithAct
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
- 842. By Andrew Hayzen
-
* Fix for autopilot
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:842
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
Is there any way more we could get more code reuse out of MusicListItem.qml? It's a pretty skinny component and we still have a lot of code for each usage of MusicListItem. I'm not seeing an easy way of doing so, however.
- 843. By Andrew Hayzen
-
* Split reorder code into a separate component and out of ListItemWithAct
ions.qml
* Split out some of the custom multiselect code - 844. By Andrew Hayzen
-
* Pull further multiselect code into MusicListItem.qml
* Remove use of primed as it is not used anymore - 845. By Andrew Hayzen
-
* Sort out autogenerated Component
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:845
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
This looks good. One issue I'm having is that deleting a playlist freezes the app. I'm not sure what your change would have done to cause this.
Victor Thompson (vthompson) wrote : | # |
The above issue also exists in the refactor series's trunk. I get the following in the console:
QQmlExpression: Attempted to evaluate an expression in an invalid context
qml: called LibraryListMode
Since this wasn't introduced by the code change here, this looks good to me. :)
Preview Diff
1 | === modified file 'app/components/CMakeLists.txt' |
2 | --- app/components/CMakeLists.txt 2015-02-08 04:06:28 +0000 |
3 | +++ app/components/CMakeLists.txt 2015-02-22 02:24:31 +0000 |
4 | @@ -1,3 +1,4 @@ |
5 | +add_subdirectory(Delegates) |
6 | add_subdirectory(Dialog) |
7 | add_subdirectory(HeadState) |
8 | add_subdirectory(Flickables) |
9 | |
10 | === added directory 'app/components/Delegates' |
11 | === added file 'app/components/Delegates/CMakeLists.txt' |
12 | --- app/components/Delegates/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
13 | +++ app/components/Delegates/CMakeLists.txt 2015-02-22 02:24:31 +0000 |
14 | @@ -0,0 +1,4 @@ |
15 | +# make the qml files visible on qtcreator |
16 | +file(GLOB DELEGATES_QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml) |
17 | + |
18 | +add_custom_target(com_ubuntu_music_DELEGATES_QMLFiles ALL SOURCES ${DELEGATES_QML_FILES}) |
19 | |
20 | === renamed file 'app/components/Card.qml' => 'app/components/Delegates/Card.qml' |
21 | --- app/components/Card.qml 2014-11-11 18:08:40 +0000 |
22 | +++ app/components/Delegates/Card.qml 2015-02-22 02:24:31 +0000 |
23 | @@ -17,6 +17,7 @@ |
24 | |
25 | import QtQuick 2.3 |
26 | import Ubuntu.Components 1.1 |
27 | +import "../" |
28 | |
29 | |
30 | Item { |
31 | |
32 | === renamed file 'app/components/ListItemWithActions.qml' => 'app/components/Delegates/ListItemWithActions.qml' |
33 | --- app/components/ListItemWithActions.qml 2015-01-18 00:06:06 +0000 |
34 | +++ app/components/Delegates/ListItemWithActions.qml 2015-02-22 02:24:31 +0000 |
35 | @@ -45,11 +45,8 @@ |
36 | readonly property alias swipping: mainItemMoving.running |
37 | readonly property bool _showActions: mouseArea.pressed || swipeState != "Normal" || swipping |
38 | |
39 | - property bool reorderable: false // CUSTOM |
40 | - property bool multiselectable: false // CUSTOM |
41 | - |
42 | - property int previousListItemIndex: -1 // CUSTOM |
43 | - property int listItemIndex: index // CUSTOM |
44 | + property alias _main: main // CUSTOM |
45 | + property alias pressed: mouseArea.pressed // CUSTOM |
46 | |
47 | /* internal */ |
48 | property var _visibleRightSideActions: filterVisibleActions(rightSideActions) |
49 | @@ -57,55 +54,6 @@ |
50 | signal itemClicked(var mouse) |
51 | signal itemPressAndHold(var mouse) |
52 | |
53 | - signal reorder(int from, int to) // CUSTOM |
54 | - |
55 | - onItemPressAndHold: { |
56 | - if (multiselectable) { |
57 | - selectionMode = true |
58 | - } |
59 | - } |
60 | - onListItemIndexChanged: { |
61 | - var i = parent.parent.selectedItems.lastIndexOf(previousListItemIndex) |
62 | - |
63 | - if (i !== -1) { |
64 | - parent.parent.selectedItems[i] = listItemIndex |
65 | - } |
66 | - |
67 | - previousListItemIndex = listItemIndex |
68 | - } |
69 | - |
70 | - onSelectedChanged: { |
71 | - if (selectionMode) { |
72 | - var tmp = parent.parent.selectedItems |
73 | - |
74 | - if (selected) { |
75 | - if (parent.parent.selectedItems.indexOf(listItemIndex) === -1) { |
76 | - tmp.push(listItemIndex) |
77 | - parent.parent.selectedItems = tmp |
78 | - } |
79 | - } else { |
80 | - tmp.splice(parent.parent.selectedItems.indexOf(listItemIndex), 1) |
81 | - parent.parent.selectedItems = tmp |
82 | - } |
83 | - } |
84 | - } |
85 | - |
86 | - onSelectionModeChanged: { // CUSTOM |
87 | - if (reorderable && selectionMode) { |
88 | - resetSwipe() |
89 | - } |
90 | - |
91 | - for (var j=0; j < main.children.length; j++) { |
92 | - main.children[j].anchors.rightMargin = reorderable && selectionMode ? actionReorderLoader.width + units.gu(2) : 0 |
93 | - } |
94 | - |
95 | - parent.parent.state = selectionMode ? "multiselectable" : "normal" |
96 | - |
97 | - if (!selectionMode) { |
98 | - selected = false |
99 | - } |
100 | - } |
101 | - |
102 | function returnToBoundsRTL(direction) |
103 | { |
104 | var actionFullWidth = actionWidth + units.gu(2) |
105 | @@ -122,20 +70,11 @@ |
106 | var xOffset = Math.abs(main.x) |
107 | var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length) |
108 | var newX = 0 |
109 | - var j // CUSTOM |
110 | |
111 | if (index === _visibleRightSideActions.length) { |
112 | newX = -(rightActionsView.width - units.gu(2)) |
113 | - |
114 | - for (j=0; j < rightSideActions.length; j++) { // CUSTOM |
115 | - rightActionsRepeater.itemAt(j).primed = true |
116 | - } |
117 | } else if (index >= 1) { |
118 | newX = -(actionFullWidth * index) |
119 | - |
120 | - for (j=0; j < rightSideActions.length; j++) { // CUSTOM |
121 | - rightActionsRepeater.itemAt(j).primed = j === index |
122 | - } |
123 | } |
124 | |
125 | updatePosition(newX) |
126 | @@ -147,10 +86,6 @@ |
127 | if ((direction === "RTL") || (main.x <= (finalX * root.threshold))) |
128 | finalX = 0 |
129 | updatePosition(finalX) |
130 | - |
131 | - if (leftSideAction !== null) { // CUSTOM |
132 | - leftActionViewLoader.item.primed = main.x > (finalX * root.threshold) |
133 | - } |
134 | } |
135 | |
136 | function returnToBounds(direction) |
137 | @@ -206,18 +141,6 @@ |
138 | } |
139 | } |
140 | |
141 | - function resetPrimed() // CUSTOM |
142 | - { |
143 | - if (leftSideAction !== null) { |
144 | - leftActionViewLoader.item.primed = false |
145 | - } |
146 | - |
147 | - for (var j=0; j < rightSideActions.length; j++) { |
148 | - console.debug(rightActionsRepeater.itemAt(j)); |
149 | - rightActionsRepeater.itemAt(j).primed = false |
150 | - } |
151 | - } |
152 | - |
153 | function resetSwipe() |
154 | { |
155 | updatePosition(0) |
156 | @@ -243,39 +166,6 @@ |
157 | mouseArea.state = "" |
158 | } |
159 | main.x = pos |
160 | - |
161 | - if (pos === 0) { // CUSTOM |
162 | - //resetPrimed() |
163 | - } |
164 | - } |
165 | - |
166 | - Connections { // CUSTOM |
167 | - target: mainView |
168 | - onListItemSwiping: { |
169 | - if (i !== index) { |
170 | - root.resetSwipe(); |
171 | - } |
172 | - } |
173 | - } |
174 | - |
175 | - Connections { // CUSTOM |
176 | - target: root.parent.parent |
177 | - onClearSelection: selected = false |
178 | - onFlickingChanged: { |
179 | - if (root.parent.parent.flicking) { |
180 | - root.resetSwipe() |
181 | - } |
182 | - } |
183 | - onSelectAll: selected = true |
184 | - onStateChanged: selectionMode = root.parent.parent.state === "multiselectable" |
185 | - } |
186 | - |
187 | - Component.onCompleted: { // CUSTOM |
188 | - if (parent.parent.selectedItems.indexOf(index) !== -1) { // FIXME: |
189 | - selected = true |
190 | - } |
191 | - |
192 | - selectionMode = root.parent.parent.state === "multiselectable" |
193 | } |
194 | |
195 | // CUSTOM remove animation |
196 | @@ -301,7 +191,7 @@ |
197 | when: selectionMode || selected |
198 | PropertyChanges { |
199 | target: selectionIcon |
200 | - source: Qt.resolvedUrl("ListItemActions/CheckBox.qml") |
201 | + source: Qt.resolvedUrl("../ListItemActions/CheckBox.qml") |
202 | anchors.leftMargin: units.gu(2) |
203 | } |
204 | PropertyChanges { |
205 | @@ -337,8 +227,6 @@ |
206 | width: root.leftActionWidth + actionThreshold |
207 | color: UbuntuColors.red |
208 | |
209 | - property alias primed: leftActionIcon.primed // CUSTOM |
210 | - |
211 | Icon { |
212 | id: leftActionIcon |
213 | anchors { |
214 | @@ -350,8 +238,6 @@ |
215 | color: Theme.palette.selected.field |
216 | height: units.gu(3) |
217 | width: units.gu(3) |
218 | - |
219 | - property bool primed: false // CUSTOM |
220 | } |
221 | } |
222 | } |
223 | @@ -400,8 +286,6 @@ |
224 | height: rightActionsView.height |
225 | width: root.actionWidth |
226 | |
227 | - property alias primed: img.primed // CUSTOM |
228 | - |
229 | Icon { |
230 | id: img |
231 | |
232 | @@ -411,8 +295,6 @@ |
233 | height: units.gu(3) |
234 | name: modelData.iconName |
235 | color: root.activeAction === modelData ? UbuntuColors.blue : styleMusic.common.white // CUSTOM |
236 | - |
237 | - property bool primed: false // CUSTOM |
238 | } |
239 | } |
240 | } |
241 | @@ -474,118 +356,6 @@ |
242 | } |
243 | } |
244 | |
245 | - /* CUSTOM Brighten Component */ |
246 | - Rectangle { |
247 | - id: listItemBrighten |
248 | - anchors { |
249 | - fill: main |
250 | - } |
251 | - |
252 | - color: mouseArea.pressed ? styleMusic.common.white : "transparent" |
253 | - opacity: 0.1 |
254 | - } |
255 | - |
256 | - /* CUSTOM Reorder Component */ |
257 | - Loader { |
258 | - id: actionReorderLoader |
259 | - anchors { |
260 | - bottom: parent.bottom |
261 | - right: main.right |
262 | - rightMargin: units.gu(1) |
263 | - top: parent.top |
264 | - } |
265 | - asynchronous: true |
266 | - sourceComponent: reorderable && selectionMode && root.parent.parent.selectedItems.length === 0 ? actionReorderComponent : undefined |
267 | - } |
268 | - |
269 | - Component { |
270 | - id: actionReorderComponent |
271 | - Item { |
272 | - id: actionReorder |
273 | - width: units.gu(4) |
274 | - visible: reorderable && selectionMode && root.parent.parent.selectedItems.length === 0 |
275 | - |
276 | - Icon { |
277 | - anchors { |
278 | - horizontalCenter: parent.horizontalCenter |
279 | - verticalCenter: parent.verticalCenter |
280 | - } |
281 | - name: "navigation-menu" // TODO: use proper image |
282 | - height: width |
283 | - width: units.gu(3) |
284 | - } |
285 | - |
286 | - MouseArea { |
287 | - id: actionReorderMouseArea |
288 | - anchors { |
289 | - fill: parent |
290 | - } |
291 | - property int startY: 0 |
292 | - property int startContentY: 0 |
293 | - |
294 | - onPressed: { |
295 | - root.parent.parent.interactive = false; // stop scrolling of listview |
296 | - startY = root.y; |
297 | - startContentY = root.parent.parent.contentY; |
298 | - root.z += 10; // force ontop of other elements |
299 | - |
300 | - console.debug("Reorder listitem pressed", root.y) |
301 | - } |
302 | - onMouseYChanged: root.y += mouse.y - (root.height / 2); |
303 | - onReleased: { |
304 | - console.debug("Reorder diff by position", getDiff()); |
305 | - |
306 | - var diff = getDiff(); |
307 | - |
308 | - // Remove the height of the actual item if moved down |
309 | - if (diff > 0) { |
310 | - diff -= 1; |
311 | - } |
312 | - |
313 | - root.parent.parent.interactive = true; // reenable scrolling |
314 | - |
315 | - if (diff === 0) { |
316 | - // Nothing has changed so reset the item |
317 | - // z index is restored after animation |
318 | - resetListItemYAnimation.start(); |
319 | - } |
320 | - else { |
321 | - var newIndex = index + diff; |
322 | - |
323 | - if (newIndex < 0) { |
324 | - newIndex = 0; |
325 | - } |
326 | - else if (newIndex > root.parent.parent.count - 1) { |
327 | - newIndex = root.parent.parent.count - 1; |
328 | - } |
329 | - |
330 | - root.z -= 10; // restore z index |
331 | - reorder(index, newIndex) |
332 | - } |
333 | - } |
334 | - |
335 | - function getDiff() { |
336 | - // Get the amount of items that have been passed over (by centre) |
337 | - return Math.round((((root.y - startY) + (root.parent.parent.contentY - startContentY)) / root.height) + 0.5); |
338 | - } |
339 | - } |
340 | - |
341 | - SequentialAnimation { |
342 | - id: resetListItemYAnimation |
343 | - UbuntuNumberAnimation { |
344 | - target: root; |
345 | - property: "y"; |
346 | - to: actionReorderMouseArea.startY |
347 | - } |
348 | - ScriptAction { |
349 | - script: { |
350 | - root.z -= 10; // restore z index |
351 | - } |
352 | - } |
353 | - } |
354 | - } |
355 | - } |
356 | - |
357 | SequentialAnimation { |
358 | id: triggerAction |
359 | |
360 | @@ -694,22 +464,22 @@ |
361 | direction = "None" |
362 | } |
363 | onClicked: { |
364 | - if (selectionMode) { // CUSTOM |
365 | + if (selectionMode) { // CUSTOM - selecting a listitem should toggle selection if in selectionMode |
366 | selected = !selected |
367 | return |
368 | - } |
369 | - else if (main.x === 0) { |
370 | + } else if (main.x === 0) { |
371 | root.itemClicked(mouse) |
372 | } else if (main.x > 0) { |
373 | var action = getActionAt(Qt.point(mouse.x, mouse.y)) |
374 | if (action && action !== -1) { |
375 | //action.triggered(root) |
376 | - removeAnimation.action = action // CUSTOM |
377 | + removeAnimation.action = action // CUSTOM - use our animation instead |
378 | removeAnimation.start() // CUSTOM |
379 | } |
380 | } else { |
381 | var actionIndex = getActionAt(Qt.point(mouse.x, mouse.y)) |
382 | - if (actionIndex !== -1) { |
383 | + |
384 | + if (actionIndex !== -1 && actionIndex !== leftSideAction) { // CUSTOM - can be leftAction |
385 | root.activeItem = rightActionsRepeater.itemAt(actionIndex) |
386 | root.activeAction = root.rightSideActions[actionIndex] |
387 | triggerAction.start() |
388 | @@ -723,7 +493,7 @@ |
389 | if (mouseArea.pressed) { |
390 | updateActiveAction() |
391 | |
392 | - listItemSwiping(index) // CUSTOM |
393 | + listItemSwiping(index) // CUSTOM - tells other listitems to dismiss any swipe |
394 | } |
395 | } |
396 | onPressAndHold: { |
397 | |
398 | === added file 'app/components/Delegates/MusicListItem.qml' |
399 | --- app/components/Delegates/MusicListItem.qml 1970-01-01 00:00:00 +0000 |
400 | +++ app/components/Delegates/MusicListItem.qml 2015-02-22 02:24:31 +0000 |
401 | @@ -0,0 +1,151 @@ |
402 | +/* |
403 | + * Copyright (C) 2013, 2014, 2015 |
404 | + * Andrew Hayzen <ahayzen@gmail.com> |
405 | + * Nekhelesh Ramananthan <krnekhelesh@gmail.com> |
406 | + * Victor Thompson <victor.thompson@gmail.com> |
407 | + * |
408 | + * This program is free software; you can redistribute it and/or modify |
409 | + * it under the terms of the GNU General Public License as published by |
410 | + * the Free Software Foundation; version 3. |
411 | + * |
412 | + * This program is distributed in the hope that it will be useful, |
413 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
414 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
415 | + * GNU General Public License for more details. |
416 | + * |
417 | + * You should have received a copy of the GNU General Public License |
418 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
419 | + */ |
420 | + |
421 | +import QtQuick 2.3 |
422 | +import Ubuntu.Components 1.1 |
423 | +import "../" |
424 | + |
425 | + |
426 | +ListItemWithActions { |
427 | + id: root |
428 | + |
429 | + property alias column: musicRow.column |
430 | + property alias imageSource: musicRow.imageSource |
431 | + |
432 | + property int listItemIndex: index |
433 | + property bool multiselectable: false |
434 | + property int previousListItemIndex: -1 |
435 | + property bool reorderable: false |
436 | + |
437 | + signal reorder(int from, int to) |
438 | + |
439 | + onItemPressAndHold: { |
440 | + if (multiselectable) { |
441 | + selectionMode = true |
442 | + } |
443 | + } |
444 | + |
445 | + onListItemIndexChanged: { |
446 | + var i = parent.parent.selectedItems.lastIndexOf(previousListItemIndex) |
447 | + |
448 | + if (i !== -1) { |
449 | + parent.parent.selectedItems[i] = listItemIndex |
450 | + } |
451 | + |
452 | + previousListItemIndex = listItemIndex |
453 | + } |
454 | + |
455 | + onSelectedChanged: { |
456 | + if (selectionMode) { |
457 | + var tmp = parent.parent.selectedItems |
458 | + |
459 | + if (selected) { |
460 | + if (parent.parent.selectedItems.indexOf(listItemIndex) === -1) { |
461 | + tmp.push(listItemIndex) |
462 | + parent.parent.selectedItems = tmp |
463 | + } |
464 | + } else { |
465 | + tmp.splice(parent.parent.selectedItems.indexOf(listItemIndex), 1) |
466 | + parent.parent.selectedItems = tmp |
467 | + } |
468 | + } |
469 | + } |
470 | + |
471 | + onSelectionModeChanged: { |
472 | + if (reorderable && selectionMode) { |
473 | + resetSwipe() |
474 | + } |
475 | + |
476 | + for (var j=0; j < _main.children.length; j++) { |
477 | + if (_main.children[j] !== actionReorderLoader) { |
478 | + _main.children[j].anchors.rightMargin = reorderable && selectionMode ? actionReorderLoader.width + units.gu(2) : 0 |
479 | + } |
480 | + } |
481 | + |
482 | + parent.parent.state = selectionMode ? "multiselectable" : "normal" |
483 | + |
484 | + if (!selectionMode) { |
485 | + selected = false |
486 | + } |
487 | + } |
488 | + |
489 | + /* Highlight the listitem on press */ |
490 | + Rectangle { |
491 | + id: listItemBrighten |
492 | + color: root.pressed ? styleMusic.common.white : "transparent" |
493 | + opacity: 0.1 |
494 | + height: root.height |
495 | + x: root.x - parent.x // -parent.x due to selectionIcon in ListItemWithActions |
496 | + width: root.width |
497 | + } |
498 | + |
499 | + /* Reorder Component */ |
500 | + Loader { |
501 | + id: actionReorderLoader |
502 | + active: reorderable && selectionMode && root.parent.parent.selectedItems.length === 0 |
503 | + anchors { |
504 | + bottom: parent.bottom |
505 | + right: parent.right |
506 | + rightMargin: units.gu(1) |
507 | + top: parent.top |
508 | + } |
509 | + asynchronous: true |
510 | + source: "../ListItemReorderComponent.qml" |
511 | + } |
512 | + |
513 | + Item { |
514 | + Connections { // Only allow one ListItem to be swiping at any time |
515 | + target: mainView |
516 | + onListItemSwiping: { |
517 | + if (i !== index) { |
518 | + root.resetSwipe(); |
519 | + } |
520 | + } |
521 | + } |
522 | + |
523 | + Connections { // Connections from signals in the ListView |
524 | + target: root.parent.parent |
525 | + onClearSelection: selected = false |
526 | + onFlickingChanged: { |
527 | + if (root.parent.parent.flicking) { |
528 | + root.resetSwipe() |
529 | + } |
530 | + } |
531 | + onSelectAll: selected = true |
532 | + onStateChanged: selectionMode = root.parent.parent.state === "multiselectable" |
533 | + } |
534 | + } |
535 | + |
536 | + |
537 | + MusicRow { |
538 | + id: musicRow |
539 | + anchors { |
540 | + verticalCenter: parent.verticalCenter |
541 | + } |
542 | + height: parent.height |
543 | + } |
544 | + |
545 | + Component.onCompleted: { // reload settings as delegates are destroyed |
546 | + if (parent.parent.selectedItems.indexOf(index) !== -1) { |
547 | + selected = true |
548 | + } |
549 | + |
550 | + selectionMode = root.parent.parent.state === "multiselectable" |
551 | + } |
552 | +} |
553 | |
554 | === modified file 'app/components/ListItemActions/AddToPlaylist.qml' |
555 | --- app/components/ListItemActions/AddToPlaylist.qml 2015-02-04 19:01:14 +0000 |
556 | +++ app/components/ListItemActions/AddToPlaylist.qml 2015-02-22 02:24:31 +0000 |
557 | @@ -25,8 +25,6 @@ |
558 | objectName: "addToPlaylistAction" |
559 | text: i18n.tr("Add to playlist") |
560 | |
561 | - property bool primed: false |
562 | - |
563 | onTriggered: { |
564 | console.debug("Debug: Add track to playlist"); |
565 | |
566 | |
567 | === modified file 'app/components/ListItemActions/Remove.qml' |
568 | --- app/components/ListItemActions/Remove.qml 2014-09-20 10:50:45 +0000 |
569 | +++ app/components/ListItemActions/Remove.qml 2015-02-22 02:24:31 +0000 |
570 | @@ -25,6 +25,4 @@ |
571 | iconName: "delete" |
572 | objectName: "swipeDeleteAction" |
573 | text: i18n.tr("Remove") |
574 | - |
575 | - property bool primed: false |
576 | } |
577 | |
578 | === added file 'app/components/ListItemReorderComponent.qml' |
579 | --- app/components/ListItemReorderComponent.qml 1970-01-01 00:00:00 +0000 |
580 | +++ app/components/ListItemReorderComponent.qml 2015-02-22 02:24:31 +0000 |
581 | @@ -0,0 +1,106 @@ |
582 | +/* |
583 | + * Copyright (C) 2013, 2014, 2015 |
584 | + * Andrew Hayzen <ahayzen@gmail.com> |
585 | + * Nekhelesh Ramananthan <krnekhelesh@gmail.com> |
586 | + * Victor Thompson <victor.thompson@gmail.com> |
587 | + * |
588 | + * This program is free software; you can redistribute it and/or modify |
589 | + * it under the terms of the GNU General Public License as published by |
590 | + * the Free Software Foundation; version 3. |
591 | + * |
592 | + * This program is distributed in the hope that it will be useful, |
593 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
594 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
595 | + * GNU General Public License for more details. |
596 | + * |
597 | + * You should have received a copy of the GNU General Public License |
598 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
599 | + */ |
600 | + |
601 | +import QtQuick 2.3 |
602 | +import Ubuntu.Components 1.1 |
603 | + |
604 | + |
605 | +Item { |
606 | + id: actionReorder |
607 | + width: units.gu(4) |
608 | + |
609 | + Icon { |
610 | + anchors { |
611 | + horizontalCenter: parent.horizontalCenter |
612 | + verticalCenter: parent.verticalCenter |
613 | + } |
614 | + name: "navigation-menu" // TODO: use proper image |
615 | + height: width |
616 | + width: units.gu(3) |
617 | + } |
618 | + |
619 | + MouseArea { |
620 | + id: actionReorderMouseArea |
621 | + anchors { |
622 | + fill: parent |
623 | + } |
624 | + property int startY: 0 |
625 | + property int startContentY: 0 |
626 | + |
627 | + onPressed: { |
628 | + root.parent.parent.interactive = false; // stop scrolling of listview |
629 | + startY = root.y; |
630 | + startContentY = root.parent.parent.contentY; |
631 | + root.z += 10; // force ontop of other elements |
632 | + |
633 | + console.debug("Reorder listitem pressed", root.y) |
634 | + } |
635 | + onMouseYChanged: root.y += mouse.y - (root.height / 2); |
636 | + onReleased: { |
637 | + console.debug("Reorder diff by position", getDiff()); |
638 | + |
639 | + var diff = getDiff(); |
640 | + |
641 | + // Remove the height of the actual item if moved down |
642 | + if (diff > 0) { |
643 | + diff -= 1; |
644 | + } |
645 | + |
646 | + root.parent.parent.interactive = true; // reenable scrolling |
647 | + |
648 | + if (diff === 0) { |
649 | + // Nothing has changed so reset the item |
650 | + // z index is restored after animation |
651 | + resetListItemYAnimation.start(); |
652 | + } |
653 | + else { |
654 | + var newIndex = index + diff; |
655 | + |
656 | + if (newIndex < 0) { |
657 | + newIndex = 0; |
658 | + } |
659 | + else if (newIndex > root.parent.parent.count - 1) { |
660 | + newIndex = root.parent.parent.count - 1; |
661 | + } |
662 | + |
663 | + root.z -= 10; // restore z index |
664 | + reorder(index, newIndex) |
665 | + } |
666 | + } |
667 | + |
668 | + function getDiff() { |
669 | + // Get the amount of items that have been passed over (by centre) |
670 | + return Math.round((((root.y - startY) + (root.parent.parent.contentY - startContentY)) / root.height) + 0.5); |
671 | + } |
672 | + } |
673 | + |
674 | + SequentialAnimation { |
675 | + id: resetListItemYAnimation |
676 | + UbuntuNumberAnimation { |
677 | + target: root; |
678 | + property: "y"; |
679 | + to: actionReorderMouseArea.startY |
680 | + } |
681 | + ScriptAction { |
682 | + script: { |
683 | + root.z -= 10; // restore z index |
684 | + } |
685 | + } |
686 | + } |
687 | +} |
688 | |
689 | === modified file 'app/ui/AddToPlaylist.qml' |
690 | --- app/ui/AddToPlaylist.qml 2015-02-08 04:06:28 +0000 |
691 | +++ app/ui/AddToPlaylist.qml 2015-02-22 02:24:31 +0000 |
692 | @@ -26,6 +26,7 @@ |
693 | import "../logic/meta-database.js" as Library |
694 | import "../logic/playlists.js" as Playlists |
695 | import "../components" |
696 | +import "../components/Delegates" |
697 | import "../components/Flickables" |
698 | import "../components/HeadState" |
699 | |
700 | |
701 | === modified file 'app/ui/Albums.qml' |
702 | --- app/ui/Albums.qml 2015-02-08 04:06:28 +0000 |
703 | +++ app/ui/Albums.qml 2015-02-22 02:24:31 +0000 |
704 | @@ -21,6 +21,7 @@ |
705 | import Ubuntu.Components 1.1 |
706 | import Ubuntu.MediaScanner 0.1 |
707 | import "../components" |
708 | +import "../components/Delegates" |
709 | import "../components/Flickables" |
710 | import "../components/HeadState" |
711 | |
712 | |
713 | === modified file 'app/ui/ArtistView.qml' |
714 | --- app/ui/ArtistView.qml 2015-02-08 04:06:28 +0000 |
715 | +++ app/ui/ArtistView.qml 2015-02-22 02:24:31 +0000 |
716 | @@ -26,6 +26,7 @@ |
717 | import QtQuick.LocalStorage 2.0 |
718 | import "../logic/meta-database.js" as Library |
719 | import "../components" |
720 | +import "../components/Delegates" |
721 | import "../components/Flickables" |
722 | import "../components/ViewButton" |
723 | |
724 | |
725 | === modified file 'app/ui/Artists.qml' |
726 | --- app/ui/Artists.qml 2015-02-08 04:06:28 +0000 |
727 | +++ app/ui/Artists.qml 2015-02-22 02:24:31 +0000 |
728 | @@ -27,6 +27,7 @@ |
729 | import "../logic/meta-database.js" as Library |
730 | import "../logic/playlists.js" as Playlists |
731 | import "../components" |
732 | +import "../components/Delegates" |
733 | import "../components/Flickables" |
734 | import "../components/HeadState" |
735 | |
736 | |
737 | === modified file 'app/ui/Genres.qml' |
738 | --- app/ui/Genres.qml 2015-02-08 04:06:28 +0000 |
739 | +++ app/ui/Genres.qml 2015-02-22 02:24:31 +0000 |
740 | @@ -21,6 +21,7 @@ |
741 | import Ubuntu.Components 1.1 |
742 | import Ubuntu.MediaScanner 0.1 |
743 | import "../components" |
744 | +import "../components/Delegates" |
745 | import "../components/Flickables" |
746 | import "../components/HeadState" |
747 | |
748 | |
749 | === modified file 'app/ui/NowPlaying.qml' |
750 | --- app/ui/NowPlaying.qml 2015-02-08 04:06:28 +0000 |
751 | +++ app/ui/NowPlaying.qml 2015-02-22 02:24:31 +0000 |
752 | @@ -23,6 +23,7 @@ |
753 | import Ubuntu.Components 1.1 |
754 | import Ubuntu.Thumbnailer 0.1 |
755 | import "../components" |
756 | +import "../components/Delegates" |
757 | import "../components/Flickables" |
758 | import "../components/HeadState" |
759 | import "../components/ListItemActions" |
760 | @@ -378,7 +379,6 @@ |
761 | fill: parent |
762 | topMargin: units.gu(2) |
763 | } |
764 | - delegate: queueDelegate |
765 | footer: Item { |
766 | height: mainView.height - (styleMusic.common.expandHeight + queueList.currentHeight) + units.gu(8) |
767 | } |
768 | @@ -390,95 +390,62 @@ |
769 | |
770 | onCountChanged: customdebug("Queue: Now has: " + queueList.count + " tracks") |
771 | |
772 | - Component { |
773 | - id: queueDelegate |
774 | - ListItemWithActions { |
775 | - id: queueListItem |
776 | - color: player.currentIndex === index ? "#2c2c34" : styleMusic.mainView.backgroundColor |
777 | - height: queueList.normalHeight |
778 | - objectName: "nowPlayingListItem" + index |
779 | - state: "" |
780 | - |
781 | - leftSideAction: Remove { |
782 | - onTriggered: trackQueue.removeQueueList([index]) |
783 | - } |
784 | - multiselectable: true |
785 | - reorderable: true |
786 | - rightSideActions: [ |
787 | - AddToPlaylist{ |
788 | - |
789 | - } |
790 | - ] |
791 | - |
792 | - onItemClicked: { |
793 | - customdebug("File: " + model.filename) // debugger |
794 | - trackQueueClick(index); // toggle track state |
795 | - } |
796 | - onReorder: { |
797 | - console.debug("Move: ", from, to); |
798 | - |
799 | - trackQueue.model.move(from, to, 1); |
800 | - Library.moveQueueItem(from, to); |
801 | - |
802 | - // Maintain currentIndex with current song |
803 | - if (from === player.currentIndex) { |
804 | - player.currentIndex = to; |
805 | - } |
806 | - else if (from < player.currentIndex && to >= player.currentIndex) { |
807 | - player.currentIndex -= 1; |
808 | - } |
809 | - else if (from > player.currentIndex && to <= player.currentIndex) { |
810 | - player.currentIndex += 1; |
811 | - } |
812 | - |
813 | - queueIndex = player.currentIndex |
814 | - } |
815 | - |
816 | - Item { |
817 | - id: trackContainer; |
818 | - anchors { |
819 | - fill: parent |
820 | - } |
821 | - |
822 | - NumberAnimation { |
823 | - id: trackContainerReorderAnimation |
824 | - target: trackContainer; |
825 | - property: "anchors.leftMargin"; |
826 | - duration: queueList.transitionDuration; |
827 | - to: units.gu(2) |
828 | - } |
829 | - |
830 | - NumberAnimation { |
831 | - id: trackContainerResetAnimation |
832 | - target: trackContainer; |
833 | - property: "anchors.leftMargin"; |
834 | - duration: queueList.transitionDuration; |
835 | - to: units.gu(0.5) |
836 | - } |
837 | - |
838 | - MusicRow { |
839 | - id: musicRow |
840 | - height: parent.height |
841 | - column: Column { |
842 | - Label { |
843 | - id: trackTitle |
844 | - color: player.currentIndex === index ? UbuntuColors.blue |
845 | - : styleMusic.common.music |
846 | - fontSize: "small" |
847 | - objectName: "titleLabel" |
848 | - text: model.title |
849 | - } |
850 | - |
851 | - Label { |
852 | - id: trackArtist |
853 | - color: styleMusic.common.subtitle |
854 | - fontSize: "x-small" |
855 | - objectName: "artistLabel" |
856 | - text: model.author |
857 | - } |
858 | - } |
859 | - } |
860 | - } |
861 | + delegate: MusicListItem { |
862 | + id: queueListItem |
863 | + color: player.currentIndex === index ? "#2c2c34" : styleMusic.mainView.backgroundColor |
864 | + column: Column { |
865 | + Label { |
866 | + id: trackTitle |
867 | + color: player.currentIndex === index ? UbuntuColors.blue : styleMusic.common.music |
868 | + fontSize: "small" |
869 | + objectName: "titleLabel" |
870 | + text: model.title |
871 | + } |
872 | + |
873 | + Label { |
874 | + id: trackArtist |
875 | + color: styleMusic.common.subtitle |
876 | + fontSize: "x-small" |
877 | + objectName: "artistLabel" |
878 | + text: model.author |
879 | + } |
880 | + } |
881 | + height: queueList.normalHeight |
882 | + objectName: "nowPlayingListItem" + index |
883 | + state: "" |
884 | + leftSideAction: Remove { |
885 | + onTriggered: trackQueue.removeQueueList([index]) |
886 | + } |
887 | + multiselectable: true |
888 | + reorderable: true |
889 | + rightSideActions: [ |
890 | + AddToPlaylist{ |
891 | + |
892 | + } |
893 | + ] |
894 | + |
895 | + onItemClicked: { |
896 | + customdebug("File: " + model.filename) // debugger |
897 | + trackQueueClick(index); // toggle track state |
898 | + } |
899 | + onReorder: { |
900 | + console.debug("Move: ", from, to); |
901 | + |
902 | + trackQueue.model.move(from, to, 1); |
903 | + Library.moveQueueItem(from, to); |
904 | + |
905 | + // Maintain currentIndex with current song |
906 | + if (from === player.currentIndex) { |
907 | + player.currentIndex = to; |
908 | + } |
909 | + else if (from < player.currentIndex && to >= player.currentIndex) { |
910 | + player.currentIndex -= 1; |
911 | + } |
912 | + else if (from > player.currentIndex && to <= player.currentIndex) { |
913 | + player.currentIndex += 1; |
914 | + } |
915 | + |
916 | + queueIndex = player.currentIndex |
917 | } |
918 | } |
919 | } |
920 | |
921 | === modified file 'app/ui/Playlists.qml' |
922 | --- app/ui/Playlists.qml 2015-02-08 04:06:28 +0000 |
923 | +++ app/ui/Playlists.qml 2015-02-22 02:24:31 +0000 |
924 | @@ -25,6 +25,7 @@ |
925 | import QtQuick.LocalStorage 2.0 |
926 | import "../logic/playlists.js" as Playlists |
927 | import "../components" |
928 | +import "../components/Delegates" |
929 | import "../components/Flickables" |
930 | import "../components/HeadState" |
931 | |
932 | |
933 | === modified file 'app/ui/Recent.qml' |
934 | --- app/ui/Recent.qml 2015-02-08 04:06:28 +0000 |
935 | +++ app/ui/Recent.qml 2015-02-22 02:24:31 +0000 |
936 | @@ -28,6 +28,7 @@ |
937 | import "../logic/meta-database.js" as Library |
938 | import "../logic/playlists.js" as Playlists |
939 | import "../components" |
940 | +import "../components/Delegates" |
941 | import "../components/Flickables" |
942 | |
943 | MusicPage { |
944 | |
945 | === modified file 'app/ui/Songs.qml' |
946 | --- app/ui/Songs.qml 2015-02-08 04:06:28 +0000 |
947 | +++ app/ui/Songs.qml 2015-02-22 02:24:31 +0000 |
948 | @@ -25,6 +25,7 @@ |
949 | import QtQuick.LocalStorage 2.0 |
950 | import "../logic/playlists.js" as Playlists |
951 | import "../components" |
952 | +import "../components/Delegates" |
953 | import "../components/Flickables" |
954 | import "../components/HeadState" |
955 | import "../components/ListItemActions" |
956 | @@ -90,61 +91,43 @@ |
957 | } |
958 | } |
959 | |
960 | - delegate: trackDelegate |
961 | - Component { |
962 | - id: trackDelegate |
963 | - |
964 | - ListItemWithActions { |
965 | - id: track |
966 | - objectName: "tracksPageListItem" + index |
967 | - height: units.gu(7) |
968 | - |
969 | - multiselectable: true |
970 | - rightSideActions: [ |
971 | - AddToQueue { |
972 | - }, |
973 | - AddToPlaylist { |
974 | - |
975 | - } |
976 | - ] |
977 | - |
978 | - onItemClicked: { |
979 | - if (songsPage.state === "search") { // only play single track when searching |
980 | - trackQueue.clear() |
981 | - trackQueue.append(songsModelFilter.get(index)) |
982 | - trackQueueClick(0) |
983 | - } else { |
984 | - trackClicked(songsModelFilter, index) // play track |
985 | - } |
986 | - } |
987 | - |
988 | - MusicRow { |
989 | - id: musicRow |
990 | - anchors { |
991 | - verticalCenter: parent.verticalCenter |
992 | - } |
993 | - imageSource: {"art": model.art} |
994 | - column: Column { |
995 | - Label { |
996 | - id: trackTitle |
997 | - color: styleMusic.common.music |
998 | - fontSize: "small" |
999 | - objectName: "tracktitle" |
1000 | - text: model.title |
1001 | - } |
1002 | - |
1003 | - Label { |
1004 | - id: trackArtist |
1005 | - color: styleMusic.common.subtitle |
1006 | - fontSize: "x-small" |
1007 | - text: model.author |
1008 | - } |
1009 | - } |
1010 | - } |
1011 | - |
1012 | - states: State { |
1013 | - name: "Current" |
1014 | - when: track.ListView.isCurrentItem |
1015 | + delegate: MusicListItem { |
1016 | + id: track |
1017 | + objectName: "tracksPageListItem" + index |
1018 | + column: Column { |
1019 | + Label { |
1020 | + id: trackTitle |
1021 | + color: styleMusic.common.music |
1022 | + fontSize: "small" |
1023 | + objectName: "tracktitle" |
1024 | + text: model.title |
1025 | + } |
1026 | + |
1027 | + Label { |
1028 | + id: trackArtist |
1029 | + color: styleMusic.common.subtitle |
1030 | + fontSize: "x-small" |
1031 | + text: model.author |
1032 | + } |
1033 | + } |
1034 | + height: units.gu(7) |
1035 | + imageSource: {"art": model.art} |
1036 | + multiselectable: true |
1037 | + rightSideActions: [ |
1038 | + AddToQueue { |
1039 | + }, |
1040 | + AddToPlaylist { |
1041 | + |
1042 | + } |
1043 | + ] |
1044 | + |
1045 | + onItemClicked: { |
1046 | + if (songsPage.state === "search") { // only play single track when searching |
1047 | + trackQueue.clear() |
1048 | + trackQueue.append(songsModelFilter.get(index)) |
1049 | + trackQueueClick(0) |
1050 | + } else { |
1051 | + trackClicked(songsModelFilter, index) // play track |
1052 | } |
1053 | } |
1054 | } |
1055 | |
1056 | === modified file 'app/ui/SongsView.qml' |
1057 | --- app/ui/SongsView.qml 2015-02-08 04:06:28 +0000 |
1058 | +++ app/ui/SongsView.qml 2015-02-22 02:24:31 +0000 |
1059 | @@ -27,6 +27,7 @@ |
1060 | import "../logic/meta-database.js" as Library |
1061 | import "../logic/playlists.js" as Playlists |
1062 | import "../components" |
1063 | +import "../components/Delegates" |
1064 | import "../components/Flickables" |
1065 | import "../components/HeadState" |
1066 | import "../components/ListItemActions" |
1067 | @@ -186,11 +187,9 @@ |
1068 | anchors { |
1069 | fill: parent |
1070 | } |
1071 | - delegate: albumTracksDelegate |
1072 | model: isAlbum ? songsModel : albumTracksModel.model |
1073 | objectName: "songspage-listview" |
1074 | width: parent.width |
1075 | - |
1076 | header: BlurredHeader { |
1077 | rightColumn: Column { |
1078 | spacing: units.gu(2) |
1079 | @@ -290,92 +289,82 @@ |
1080 | } |
1081 | } |
1082 | } |
1083 | - |
1084 | - Component { |
1085 | - id: albumTracksDelegate |
1086 | - |
1087 | - ListItemWithActions { |
1088 | - id: track |
1089 | - objectName: "songsPageListItem" + index |
1090 | - height: units.gu(6) |
1091 | - |
1092 | - leftSideAction: songStackPage.line1 === i18n.tr("Playlist") |
1093 | - ? playlistRemoveAction.item : null |
1094 | - multiselectable: true |
1095 | - reorderable: songStackPage.line1 === i18n.tr("Playlist") |
1096 | - rightSideActions: [ |
1097 | - AddToQueue { |
1098 | - |
1099 | - }, |
1100 | - AddToPlaylist { |
1101 | - |
1102 | - } |
1103 | - ] |
1104 | - |
1105 | - onItemClicked: { |
1106 | - trackClicked(albumtrackslist.model, index) // play track |
1107 | - |
1108 | - if (isAlbum && songStackPage.line1 !== i18n.tr("Genre")) { |
1109 | - Library.addRecent(albumtrackslist.model.get(0, albumtrackslist.model.RoleModelData).album, "album") |
1110 | - } else if (songStackPage.line1 === i18n.tr("Playlist")) { |
1111 | - Library.addRecent(songStackPage.line2, "playlist") |
1112 | - } else { |
1113 | - console.debug("Unknown type to add to recent") |
1114 | - } |
1115 | - |
1116 | - recentModel.filterRecent() |
1117 | - } |
1118 | - onReorder: { |
1119 | - console.debug("Move: ", from, to); |
1120 | - |
1121 | - Playlists.move(songStackPage.line2, from, to) |
1122 | - |
1123 | - albumTracksModel.filterPlaylistTracks(songStackPage.line2) |
1124 | - } |
1125 | - |
1126 | - Loader { |
1127 | - id: playlistRemoveAction |
1128 | - sourceComponent: Remove { |
1129 | - onTriggered: { |
1130 | - Playlists.removeFromPlaylist(songStackPage.line2, model.i) |
1131 | - |
1132 | - playlistChangedHelper() // update recent/playlist models |
1133 | - |
1134 | - albumTracksModel.filterPlaylistTracks(songStackPage.line2) |
1135 | - |
1136 | - // refresh cover art |
1137 | - songStackPage.covers = Playlists.getPlaylistCovers(songStackPage.line2) |
1138 | - } |
1139 | - } |
1140 | - } |
1141 | - |
1142 | - MusicRow { |
1143 | - id: musicRow |
1144 | - height: parent.height |
1145 | - column: Column { |
1146 | - Label { |
1147 | - id: trackTitle |
1148 | - color: styleMusic.common.music |
1149 | - fontSize: "small" |
1150 | - objectName: "songspage-tracktitle" |
1151 | - text: model.title |
1152 | - } |
1153 | - |
1154 | - Label { |
1155 | - id: trackArtist |
1156 | - color: styleMusic.common.subtitle |
1157 | - fontSize: "x-small" |
1158 | - text: model.author |
1159 | - } |
1160 | - } |
1161 | - } |
1162 | - |
1163 | - Component.onCompleted: { |
1164 | - if (model.date !== undefined) |
1165 | - { |
1166 | - songStackPage.file = model.filename; |
1167 | - songStackPage.year = new Date(model.date).toLocaleString(Qt.locale(),'yyyy'); |
1168 | - } |
1169 | + delegate: MusicListItem { |
1170 | + id: track |
1171 | + objectName: "songsPageListItem" + index |
1172 | + column: Column { |
1173 | + Label { |
1174 | + id: trackTitle |
1175 | + color: styleMusic.common.music |
1176 | + fontSize: "small" |
1177 | + objectName: "songspage-tracktitle" |
1178 | + text: model.title |
1179 | + } |
1180 | + |
1181 | + Label { |
1182 | + id: trackArtist |
1183 | + color: styleMusic.common.subtitle |
1184 | + fontSize: "x-small" |
1185 | + text: model.author |
1186 | + } |
1187 | + } |
1188 | + height: units.gu(6) |
1189 | + |
1190 | + leftSideAction: songStackPage.line1 === i18n.tr("Playlist") |
1191 | + ? playlistRemoveAction.item : null |
1192 | + multiselectable: true |
1193 | + reorderable: songStackPage.line1 === i18n.tr("Playlist") |
1194 | + rightSideActions: [ |
1195 | + AddToQueue { |
1196 | + |
1197 | + }, |
1198 | + AddToPlaylist { |
1199 | + |
1200 | + } |
1201 | + ] |
1202 | + |
1203 | + onItemClicked: { |
1204 | + trackClicked(albumtrackslist.model, index) // play track |
1205 | + |
1206 | + if (isAlbum && songStackPage.line1 !== i18n.tr("Genre")) { |
1207 | + Library.addRecent(albumtrackslist.model.get(0, albumtrackslist.model.RoleModelData).album, "album") |
1208 | + } else if (songStackPage.line1 === i18n.tr("Playlist")) { |
1209 | + Library.addRecent(songStackPage.line2, "playlist") |
1210 | + } else { |
1211 | + console.debug("Unknown type to add to recent") |
1212 | + } |
1213 | + |
1214 | + recentModel.filterRecent() |
1215 | + } |
1216 | + onReorder: { |
1217 | + console.debug("Move: ", from, to); |
1218 | + |
1219 | + Playlists.move(songStackPage.line2, from, to) |
1220 | + |
1221 | + albumTracksModel.filterPlaylistTracks(songStackPage.line2) |
1222 | + } |
1223 | + |
1224 | + Loader { |
1225 | + id: playlistRemoveAction |
1226 | + sourceComponent: Remove { |
1227 | + onTriggered: { |
1228 | + Playlists.removeFromPlaylist(songStackPage.line2, model.i) |
1229 | + |
1230 | + playlistChangedHelper() // update recent/playlist models |
1231 | + |
1232 | + albumTracksModel.filterPlaylistTracks(songStackPage.line2) |
1233 | + |
1234 | + // refresh cover art |
1235 | + songStackPage.covers = Playlists.getPlaylistCovers(songStackPage.line2) |
1236 | + } |
1237 | + } |
1238 | + } |
1239 | + |
1240 | + Component.onCompleted: { |
1241 | + if (model.date !== undefined) |
1242 | + { |
1243 | + songStackPage.file = model.filename; |
1244 | + songStackPage.year = new Date(model.date).toLocaleString(Qt.locale(),'yyyy'); |
1245 | } |
1246 | } |
1247 | } |
1248 | |
1249 | === modified file 'tests/autopilot/music_app/__init__.py' |
1250 | --- tests/autopilot/music_app/__init__.py 2015-02-04 04:20:07 +0000 |
1251 | +++ tests/autopilot/music_app/__init__.py 2015-02-22 02:24:31 +0000 |
1252 | @@ -187,7 +187,7 @@ |
1253 | self.visible.wait_for(True) |
1254 | |
1255 | def get_track(self, i): |
1256 | - return (self.wait_select_single(ListItemWithActions, |
1257 | + return (self.wait_select_single(MusicListItem, |
1258 | objectName="tracksPageListItem" + str(i))) |
1259 | |
1260 | |
1261 | @@ -270,7 +270,7 @@ |
1262 | |
1263 | @ensure_now_playing_list |
1264 | def get_track(self, i): |
1265 | - return (self.wait_select_single(ListItemWithActions, |
1266 | + return (self.wait_select_single(MusicListItem, |
1267 | objectName="nowPlayingListItem" + str(i))) |
1268 | |
1269 | @ensure_now_playing_full |
1270 | @@ -331,7 +331,7 @@ |
1271 | objectName="songsPageHeaderAlbumArtist") |
1272 | |
1273 | def get_track(self, i): |
1274 | - return (self.wait_select_single(ListItemWithActions, |
1275 | + return (self.wait_select_single(MusicListItem, |
1276 | objectName="songsPageListItem" + str(i))) |
1277 | |
1278 | |
1279 | @@ -358,7 +358,7 @@ |
1280 | now_playing_page.visible.wait_for(True) |
1281 | |
1282 | |
1283 | -class ListItemWithActions(UbuntuUIToolkitCustomProxyObjectBase): |
1284 | +class MusicListItem(UbuntuUIToolkitCustomProxyObjectBase): |
1285 | @click_object |
1286 | def click_add_to_playlist_action(self): |
1287 | return self.wait_select_single(objectName="addToPlaylistAction") |
FAILED: Continuous integration, rev:841 91.189. 93.70:8080/ job/music- app-refactor- ci/38/ 91.189. 93.70:8080/ job/generic- mediumtests- vivid/1080 91.189. 93.70:8080/ job/generic- mediumtests- vivid/1080/ artifact/ work/output/ *zip*/output. zip 91.189. 93.70:8080/ job/music- app-refactor- vivid-amd64- ci/38
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/music- app-refactor- ci/38/rebuild
http://