Merge lp:~ahayzen/music-app/listitem-actions-take-2 into lp:music-app/trusty

Proposed by Andrew Hayzen
Status: Merged
Approved by: Victor Thompson
Approved revision: 562
Merged at revision: 561
Proposed branch: lp:~ahayzen/music-app/listitem-actions-take-2
Merge into: lp:music-app/trusty
Diff against target: 2712 lines (+1031/-1103)
25 files modified
MusicNowPlaying.qml (+47/-396)
MusicPlaylists.qml (+30/-62)
MusicSearch.qml (+13/-20)
MusicTracks.qml (+13/-29)
MusicaddtoPlaylist.qml (+1/-0)
common/CMakeLists.txt (+1/-1)
common/Expander.qml (+0/-165)
common/ExpanderItems/AddToPlaylist.qml (+0/-60)
common/ExpanderItems/AddToQueue.qml (+0/-58)
common/ExpanderItems/CMakeLists.txt (+0/-4)
common/ExpanderItems/DeletePlaylist.qml (+0/-59)
common/ExpanderItems/EditPlaylist.qml (+0/-59)
common/ListItemActions/AddToPlaylist.qml (+34/-0)
common/ListItemActions/AddToQueue.qml (+31/-0)
common/ListItemActions/CMakeLists.txt (+4/-0)
common/ListItemActions/DeletePlaylist.qml (+29/-0)
common/ListItemActions/EditPlaylist.qml (+35/-0)
common/ListItemActions/Remove.qml (+30/-0)
common/ListItemWithActions.qml (+547/-0)
common/MusicRow.qml (+1/-2)
common/SongsPage.qml (+47/-38)
music-app.qml (+2/-4)
po/com.ubuntu.music.pot (+73/-67)
tests/autopilot/music_app/emulators.py (+39/-55)
tests/autopilot/music_app/tests/test_music.py (+54/-24)
To merge this branch: bzr merge lp:~ahayzen/music-app/listitem-actions-take-2
Reviewer Review Type Date Requested Status
Victor Thompson Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+229536@code.launchpad.net

Commit message

* Remove expander, reorder, swipedelete code
* Use ListItemWithActions from other apps
* Implement actions for add to playlist, add to queue, edit playlist, delete playlist
* Implement reordering

Description of the change

* Remove expander, reorder, swipedelete code
* Use ListItemWithActions from other apps
* Implement actions for add to playlist, add to queue, edit playlist, delete playlist
* Implement reordering

This makes use of a mod'd version ListItemWithActions.qml used in other apps such as address-book and clock-app-reboot and therefore should be preferred over [0].

0 - https://code.launchpad.net/~andrew-hayzen/music-app/listitem-actions/+merge/220290

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
550. By Andrew Hayzen

* Fixes for autopilot

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
551. By Andrew Hayzen

* Add primed var to actions so autopilot can tell which actions are visible

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
552. By Andrew Hayzen

* Correct objectNames for autopilot

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
553. By Andrew Hayzen

* Merge of trunk

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
554. By Andrew Hayzen

* Fixes for ap tests and swipeDelete not functioning

555. By Andrew Hayzen

* Switch colour of rightactions to Orange

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
556. By Andrew Hayzen

* Merge of trunk

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
557. By Andrew Hayzen

* Fix for ap so that it waits for the action animation to complete before accessing the playlist page

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Victor Thompson (vthompson) wrote :

I've noticed three things, functionally, that need fixing:

1. Currently when you delete a playlist, it is removed before the action is confirmed.
2. The reorder functionality hasn't been applied to playlists.
3. The list item actions on the right appear to be a bit too close to the edge closest to the item.

Things that we should consider changing:

4. I think the list item actions when 'inactive' should be white in color, rather than grey.
5. We should consider using a different color rather than orange for the 'active' action. It looks OK, but there might be a better option
6. I'm still not a huge fan of the red background color for the delete action.

review: Needs Fixing
558. By Andrew Hayzen

* Enable reordering for playlists
* Remove extra remove dialogue when removing a playlist
* Increase rightAction margin

Revision history for this message
Andrew Hayzen (ahayzen) wrote :

1) Fixed, it was incorrectly showing the dialogue after you had already confirmed removal.
2) Fixed, reordering wasn't enabled on that page :) and fixed another bug in the transition of the code from v1->v2 which meant you could attempt to move beyond the model bounds.
3) Fixed, put a left margin on the rightActions to match the spacing

4) & 5) Maybe we should have grey for inactive and white for active?
6) I'm not a huge fan either but it is growing on me.

For 4), 5) & 6) we need to ensure that we remain as consistent as possible with the other apps (clock-app-reboot and address-book) using this component (hence keeping the red and grey colours). But I'm open to suggestions.

559. By Andrew Hayzen

* Fix margins of now playing so item is centred

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
560. By Andrew Hayzen

* Switch rightSideAction to be white/orange

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Victor Thompson (vthompson) wrote :

Things to fix:

1. Could you update the .pot file since there are translatable items changing? (mostly some are being removed)
2. Deleting a song from a playlist is not working. I see the following in the log when I remove a song:

file:///opt/click.ubuntu.com/com.ubuntu.music/1.3.560/common/SongsPage.qml:216: ReferenceError: model is not defined

So for the code looks pretty good though.

review: Needs Fixing
Revision history for this message
Victor Thompson (vthompson) wrote :

Additional things:

3. The elide needs to be fixed so text doesn't collide with the reorder icon.
4. Currently any view that has a reorder active will stay in reorder mode when you change views. I do not think we should be done this. One bad thing this causes is that if you put a playlist into reorder mode and then view an album or genre it will appear as though it's in reorder mode as well. Items can then be dragged around--with no affect. It also seems like it might break the model until the app is restarted.

review: Needs Fixing
561. By Andrew Hayzen

* Fix removing track from playlist
* Fix elide of text when reordering
* Rebuild .pot
* Cancel reordering if focus is lost

Revision history for this message
Andrew Hayzen (ahayzen) wrote :

1) Rebuilt
2) Fixed, the Loader was outside of the ListItem so couldn't access the model
3) Fixed, margin now exists so labels are then elide'd
4) Fixed, reordering is now cancelled if the visibility is lost on the listview

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
562. By Andrew Hayzen

* Refresh playlist model count when child track is removed

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Victor Thompson (vthompson) wrote :

This looks good! Great work!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'MusicNowPlaying.qml'
2--- MusicNowPlaying.qml 2014-06-24 19:35:57 +0000
3+++ MusicNowPlaying.qml 2014-08-11 00:34:14 +0000
4@@ -22,10 +22,9 @@
5 import QtQuick 2.0
6 import QtQuick.LocalStorage 2.0
7 import Ubuntu.Components 0.1
8-import Ubuntu.Components.ListItems 0.1 as ListItem
9 import Ubuntu.Thumbnailer 0.1
10 import "common"
11-import "common/ExpanderItems"
12+import "common/ListItemActions"
13 import "settings.js" as Settings
14
15 MusicPage {
16@@ -56,7 +55,6 @@
17 return;
18 }
19
20- collapseExpand(); // Collapse expanded tracks
21 queuelist.currentIndex = player.currentIndex;
22
23 customdebug("MusicQueue update currentIndex: " + player.source);
24@@ -87,7 +85,6 @@
25 objectName: "queuelist"
26 anchors.fill: parent
27 anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
28- spacing: units.gu(1)
29 delegate: queueDelegate
30 model: trackQueue.model
31 highlightFollowsCurrentItem: false
32@@ -126,369 +123,53 @@
33
34 Component {
35 id: queueDelegate
36- ListItem.Standard {
37+ ListItemWithActions {
38 id: queueListItem
39+ color: "transparent"
40 height: queuelist.normalHeight
41- state: queuelist.currentIndex == index ? "current" : ""
42-
43- // cached height used to restore the height after expansion
44- property int cachedHeight: -1
45-
46- SwipeDelete {
47- id: swipeBackground
48- duration: queuelist.transitionDuration
49-
50- onDeleteStateChanged: {
51- if (deleteState === true)
52- {
53- queueListItemRemoveAnimation.start();
54- }
55- }
56- }
57-
58- function onCollapseSwipeDelete(indexCol)
59- {
60- if ((indexCol !== index || indexCol === -1) && swipeBackground !== undefined && swipeBackground.direction !== "")
61- {
62- customdebug("auto collapse swipeDelete")
63- queueListItemResetStartAnimation.start();
64- }
65- }
66-
67- Component.onCompleted: {
68- collapseSwipeDelete.connect(onCollapseSwipeDelete);
69- }
70-
71- MouseArea {
72- id: queueArea
73- anchors.fill: parent
74-
75- property int startX: queueListItem.x
76- property int startY: queueListItem.y
77- property int startMouseY: -1
78-
79- // Allow dragging on the X axis for swipeDelete if not reordering
80- drag.target: queueListItem
81- drag.axis: Drag.XAxis
82- drag.minimumX: queuelist.state == "reorder" ? 0 : -queueListItem.width
83- drag.maximumX: queuelist.state == "reorder" ? 0 : queueListItem.width
84-
85- /* Get the mouse and item difference from the starting positions */
86- function getDiff(mouseY)
87- {
88- return (mouseY - startMouseY) + (queueListItem.y - startY);
89- }
90-
91- /*
92- * Has the mouse crossed the current item
93- * True - it has crossed
94- * NULL - it is on the current
95- * False - it has not crossed
96- */
97- function hasCrossedCurrent(diff, currentOffset)
98- {
99- // Only crossed if in same direction
100- if ((diff > 0 || currentOffset > 0) && (diff <= 0 || currentOffset <= 0))
101- {
102- return false;
103- }
104-
105- if (Math.abs(diff) > (Math.abs(currentOffset) * queuelist.normalHeight) + queuelist.currentHeight)
106- {
107- return true;
108- }
109- else if (Math.abs(diff) > (Math.abs(currentOffset) * queuelist.normalHeight))
110- {
111- return null;
112- }
113- else
114- {
115- return false;
116- }
117- }
118-
119- function getNewIndex(mouseY, index)
120- {
121- var diff = getDiff(mouseY);
122- var negPos = diff < 0 ? -1 : 1;
123- var currentOffset = queuelist.currentIndex - index; // get the current offset
124-
125- if (currentOffset < 0) // when current is less the offset is actually +1
126- {
127- currentOffset += 1;
128- }
129-
130- var hasCrossed = hasCrossedCurrent(diff, currentOffset);
131-
132- if (hasCrossed === true)
133- {
134- /* Take off difference so it just appears like a normalheight
135- * minus when after and add when before */
136- diff -= negPos * (queuelist.currentHeight - queuelist.normalHeight);
137- }
138- else if (hasCrossed === null)
139- {
140- // Work out how far into the current item it is
141- var tmpDiff = Math.abs(diff) - (Math.abs(currentOffset) * queuelist.normalHeight);
142-
143- // Scale difference so is the same as a normalHeight
144- tmpDiff *= (queuelist.normalHeight / queuelist.currentHeight);
145-
146- // rebuild Diff with new values
147- diff = (currentOffset * queuelist.normalHeight) + (negPos * tmpDiff);
148- }
149-
150- return index + (Math.round(diff / queuelist.normalHeight));
151- }
152-
153- onClicked: {
154- collapseSwipeDelete(-1); // collapse all expands
155- customdebug("File: " + model.filename) // debugger
156- trackQueueClick(index); // toggle track state
157- }
158-
159- onMouseXChanged: {
160- // Only allow XChange if not in reorder state
161- if (queuelist.state == "reorder")
162- {
163- return;
164- }
165-
166- // New X is less than start so swiping left
167- if (queueListItem.x < startX)
168- {
169- collapseExpand();
170- swipeBackground.state = "swipingLeft";
171- startY = queueListItem.y;
172- }
173- // New X is greater sow swiping right
174- else if (queueListItem.x > startX)
175- {
176- collapseExpand();
177- swipeBackground.state = "swipingRight";
178- startY = queueListItem.y;
179- }
180- // Same so reset state back to normal
181- else
182- {
183- swipeBackground.state = "normal";
184- queuelist.state = "normal";
185- }
186- }
187-
188- onMouseYChanged: {
189- // Y change only affects when in reorder mode
190- if (queuelist.state == "reorder")
191- {
192- /* update the listitem y position so that the
193- * listitem horizontalCenter is under the mouse.y */
194- queueListItem.y += mouse.y - (queueListItem.height / 2);
195- }
196- }
197-
198- onPressed: {
199- startX = queueListItem.x;
200- startY = queueListItem.y;
201- startMouseY = mouse.y;
202- }
203-
204- onPressAndHold: {
205- // Must be in a normal state to change to reorder state
206- if (queuelist.state == "normal" && swipeBackground.state == "normal" && queuelist.currentIndex != index)
207- {
208- collapseSwipeDelete(-1); // collapse all swipedeletes
209- collapseExpand(); // collapse all
210- customdebug("Pressed and held queued track "+model.filename)
211- queuelist.state = "reorder"; // enable reordering state
212- trackContainerReorderAnimation.start();
213- }
214- }
215-
216- onReleased: {
217- // Get current state to determine what to do
218- if (queuelist.state == "reorder")
219- {
220- var newIndex = getNewIndex(mouse.y + (queueListItem.height / 2), index); // get new index
221-
222- // Indexes larger than current need -1 because when it is moved the current is removed
223- if (newIndex > index)
224- {
225- newIndex -= 1;
226- }
227-
228- if (newIndex === index)
229- {
230- queueListItemResetAnimation.start(); // reset item position
231- trackContainerResetAnimation.start(); // reset the trackContainer
232- }
233- else
234- {
235- queueListItem.x = startX; // ensure X position is correct
236- trackContainerResetAnimation.start(); // reset the trackContainer
237-
238- // Check that the newIndex is within the range
239- if (newIndex < 0)
240- {
241- newIndex = 0;
242- }
243- else if (newIndex > queuelist.count - 1)
244- {
245- newIndex = queuelist.count - 1;
246- }
247-
248- console.debug("Move: " + index + " To: " + newIndex);
249- queuelist.model.move(index, newIndex, 1); // update the model
250- }
251- }
252- else if (swipeBackground.state == "swipingLeft" || swipeBackground.state == "swipingRight")
253- {
254- var moved = Math.abs(queueListItem.x - startX);
255-
256- // Make sure that item has been dragged far enough
257- if (moved > queueListItem.width / 2 || (swipeBackground.primed === true && moved > units.gu(5)))
258- {
259- if (swipeBackground.primed === false)
260- {
261- collapseSwipeDelete(index); // collapse other swipeDeletes
262-
263- // Move the listitem half way across to reveal the delete button
264- queueListItemPrepareRemoveAnimation.start();
265- }
266- else
267- {
268- // Check that actually swiping to cancel
269- if (swipeBackground.direction !== "" &&
270- swipeBackground.direction !== swipeBackground.state)
271- {
272- // Reset the listitem to the centre
273- queueListItemResetStartAnimation.start();
274- }
275- else
276- {
277- // Reset the listitem to the centre
278- queueListItemResetAnimation.start();
279- }
280- }
281- }
282- else
283- {
284- // Reset the listitem to the centre
285- queueListItemResetAnimation.start();
286- }
287- }
288-
289- // ensure states are normal
290- swipeBackground.state = "normal";
291- queuelist.state = "normal";
292- }
293-
294- // Animation to reset the x, y of the queueitem
295- ParallelAnimation {
296- id: queueListItemResetAnimation
297- running: false
298- NumberAnimation { // reset X
299- target: queueListItem
300- property: "x"
301- to: queueArea.startX
302- duration: queuelist.transitionDuration
303- }
304- NumberAnimation { // reset Y
305- target: queueListItem
306- property: "y"
307- to: queueArea.startY
308- duration: queuelist.transitionDuration
309- }
310- }
311-
312- // Animation to reset the x, y of the item
313- ParallelAnimation {
314- id: queueListItemResetStartAnimation
315- running: false
316- NumberAnimation { // reset X
317- target: queueListItem
318- property: "x"
319- to: 0
320- duration: queuelist.transitionDuration
321- }
322- NumberAnimation { // reset Y
323- target: queueListItem
324- property: "y"
325- to: queueArea.startY
326- duration: queuelist.transitionDuration
327- }
328- onRunningChanged: {
329- if (running === true)
330- {
331- swipeBackground.direction = "";
332- swipeBackground.primed = false;
333- }
334- }
335- }
336-
337- // Move the listitem half way across to reveal the delete button
338- NumberAnimation {
339- id: queueListItemPrepareRemoveAnimation
340- target: queueListItem
341- property: "x"
342- to: swipeBackground.state == "swipingRight" ? queueListItem.width / 2 : 0 - (queueListItem.width / 2)
343- duration: queuelist.transitionDuration
344- onRunningChanged: {
345- if (running === true)
346- {
347- swipeBackground.direction = swipeBackground.state;
348- swipeBackground.primed = true;
349- }
350- }
351- }
352-
353- ParallelAnimation {
354- id: queueListItemRemoveAnimation
355- running: false
356- NumberAnimation { // 'slide' up
357- target: queueListItem
358- property: "height"
359- to: 0
360- duration: queuelist.transitionDuration
361- }
362- NumberAnimation { // 'slide' in direction of removal
363- target: queueListItem
364- property: "x"
365- to: swipeBackground.direction === "swipingLeft" ? 0 - queueListItem.width : queueListItem.width
366- duration: queuelist.transitionDuration
367- }
368- onRunningChanged: {
369- if (running === false)
370- {
371- // Remove the item
372- if (index == queuelist.currentIndex)
373- {
374- if (queuelist.count > 1)
375- {
376- // Next song and only play if currently playing
377- player.nextSong(player.isPlaying);
378- }
379- else
380- {
381- player.stop();
382- }
383- }
384-
385- if (index < player.currentIndex) {
386- player.currentIndex -= 1;
387- }
388-
389- // Remove item from queue and clear caches
390- trackQueue.model.remove(index);
391- }
392- }
393- }
394- }
395-
396- onFocusChanged: {
397- if (focus == false) {
398- selected = false
399- } else {
400- selected = false
401+ state: queuelist.currentIndex == index && !reordering ? "current" : ""
402+
403+ leftSideAction: Remove {
404+ onTriggered: {
405+ if (index === player.currentIndex) {
406+ player.nextSong(player.isPlaying);
407+ }
408+
409+ if (index < player.currentIndex) {
410+ // update index as the old has been removed
411+ player.currentIndex -= 1;
412+ }
413+
414+ queuelist.model.remove(index);
415+ }
416+ }
417+ reorderable: true
418+ rightSideActions: [
419+ AddToPlaylist{
420+
421+ }
422+ ]
423+ triggerActionOnMouseRelease: true
424+
425+ onItemClicked: {
426+ customdebug("File: " + model.filename) // debugger
427+ trackQueueClick(index); // toggle track state
428+ }
429+ onReorder: {
430+ console.debug("Move: ", from, to);
431+
432+ queuelist.model.move(from, to, 1);
433+
434+
435+ // Maintain currentIndex with current song
436+ if (from === player.currentIndex) {
437+ player.currentIndex = to;
438+ }
439+ else if (from < player.currentIndex && to >= player.currentIndex) {
440+ player.currentIndex -= 1;
441+ }
442+ else if (from > player.currentIndex && to <= player.currentIndex) {
443+ player.currentIndex += 1;
444 }
445 }
446
447@@ -496,8 +177,7 @@
448 id: trackContainer;
449 anchors {
450 fill: parent
451- margins: units.gu(0.5)
452- rightMargin: expandable.expanderButtonWidth
453+ margins: units.gu(1)
454 }
455 color: "transparent"
456
457@@ -599,31 +279,6 @@
458 }
459 }
460
461- Expander {
462- id: expandable
463- anchors {
464- fill: parent
465- }
466- actualListItemHeight: queueListItem.state === "current" ?
467- queuelist.currentHeight :
468- queuelist.normalHeight
469- buttonEnabled: !swipeBackground.primed
470- expanderButtonCentreFromBottom: queuelist.normalHeight - (trackContainer.anchors.margins * 2) - nowPlayingTitle.y - (nowPlayingTitle.height / 2)
471- listItem: queueListItem
472- model: trackQueue.model.get(index)
473- row: Row {
474- AddToPlaylist {
475- }
476- }
477- Behavior on actualListItemHeight {
478- NumberAnimation {
479- target: expandable;
480- property: "actualListItemHeight";
481- duration: queuelist.transitionDuration;
482- }
483- }
484- }
485-
486 states: State {
487 name: "current"
488 PropertyChanges {
489@@ -648,10 +303,6 @@
490 x: trackImage.x
491 y: nowPlayingTitle.y + nowPlayingTitle.height + units.gu(1.25)
492 }
493- PropertyChanges {
494- target: expandable
495- expanderButtonCentreFromBottom: queuelist.currentHeight - (trackContainer.anchors.margins * 2) - nowPlayingTitle.y - (nowPlayingTitle.height / 2)
496- }
497 }
498 transitions: Transition {
499 from: ",current"
500
501=== modified file 'MusicPlaylists.qml'
502--- MusicPlaylists.qml 2014-08-06 02:26:18 +0000
503+++ MusicPlaylists.qml 2014-08-11 00:34:14 +0000
504@@ -20,16 +20,14 @@
505
506 import QtQuick 2.0
507 import Ubuntu.Components 0.1
508-import Ubuntu.Components.ListItems 0.1
509 import Ubuntu.Components.Popups 0.1
510-import Ubuntu.Components.ListItems 0.1 as ListItem
511 import QtMultimedia 5.0
512 import QtQuick.LocalStorage 2.0
513 import "settings.js" as Settings
514 import "scrobble.js" as Scrobble
515 import "playlists.js" as Playlists
516 import "common"
517-import "common/ExpanderItems"
518+import "common/ListItemActions"
519
520 // page for the playlists
521 MusicPage {
522@@ -110,35 +108,6 @@
523 }
524 }
525
526- // Remove playlist dialog
527- Component {
528- id: removePlaylistDialog
529- Dialog {
530- id: dialogueRemovePlaylist
531- // TRANSLATORS: this is a title of a dialog with a prompt to delete a playlist
532- title: i18n.tr("Are you sure?")
533- text: i18n.tr("This will delete your playlist.")
534-
535- Button {
536- text: i18n.tr("Remove")
537- color: styleMusic.dialog.confirmButtonColor
538- onClicked: {
539- // removing playlist
540- Playlists.removePlaylist(oldPlaylistName)
541-
542- playlistModel.filterPlaylists();
543-
544- PopupUtils.close(dialogueRemovePlaylist)
545- }
546- }
547- Button {
548- text: i18n.tr("Cancel")
549- color: styleMusic.dialog.cancelButtonColor
550- onClicked: PopupUtils.close(dialogueRemovePlaylist)
551- }
552- }
553- }
554-
555 MusicSettings {
556 id: musicSettings
557 }
558@@ -159,13 +128,40 @@
559
560 Component {
561 id: playlistDelegate
562- ListItem.Standard {
563+ ListItemWithActions {
564 id: playlist
565 property string name: model.name
566 property string count: model.count
567 property var covers: Playlists.getPlaylistCovers(name)
568+
569+ color: "transparent"
570 height: styleMusic.common.itemHeight
571- iconFrame: false
572+ width: parent.width
573+
574+ leftSideAction: DeletePlaylist {
575+ onTriggered: {
576+ Playlists.removePlaylist(model.name)
577+
578+ playlistModel.filterPlaylists();
579+ }
580+ }
581+
582+ rightSideActions: [
583+ EditPlaylist {
584+ }
585+ ]
586+ triggerActionOnMouseRelease: true
587+
588+ onItemClicked: {
589+ albumTracksModel.filterPlaylistTracks(name)
590+ songsPage.isAlbum = false
591+ songsPage.line1 = "Playlist"
592+ songsPage.line2 = model.name
593+ songsPage.covers = playlist.covers
594+ songsPage.title = i18n.tr("Playlist")
595+
596+ mainPageStack.push(songsPage)
597+ }
598
599 MusicRow {
600 covers: playlist.covers
601@@ -185,34 +181,6 @@
602 }
603 }
604 }
605-
606- Expander {
607- id: expandable
608- anchors {
609- fill: parent
610- }
611- listItem: playlist
612- model: {"name": name, "index": index}
613- row: Row {
614- EditPlaylist {
615-
616- }
617- DeletePlaylist {
618-
619- }
620- }
621- }
622-
623- onClicked: {
624- albumTracksModel.filterPlaylistTracks(name)
625- songsPage.isAlbum = false
626- songsPage.line1 = "Playlist"
627- songsPage.line2 = model.name
628- songsPage.covers = playlist.covers
629- songsPage.title = i18n.tr("Playlist")
630-
631- mainPageStack.push(songsPage)
632- }
633 }
634 }
635 }
636
637=== modified file 'MusicSearch.qml'
638--- MusicSearch.qml 2014-07-11 22:29:21 +0000
639+++ MusicSearch.qml 2014-08-11 00:34:14 +0000
640@@ -27,7 +27,7 @@
641 import QtQuick.LocalStorage 2.0
642 import "playlists.js" as Playlists
643 import "common"
644-import "common/ExpanderItems"
645+import "common/ListItemActions"
646
647 Item {
648 id: sheetItem
649@@ -154,13 +154,23 @@
650 searchTrackView.forceActiveFocus()
651 }
652
653- delegate: ListItem.Standard {
654+ delegate: ListItemWithActions {
655 id: search
656+ color: "transparent"
657 objectName: "playlist"
658 width: parent.width
659 height: styleMusic.common.itemHeight
660
661- onClicked: {
662+ rightSideActions: [
663+ AddToQueue {
664+
665+ },
666+ AddToPlaylist {
667+
668+ }
669+ ]
670+
671+ onItemClicked: {
672 console.debug("Debug: "+title+" added to queue")
673 // now play this track, but keep current queue
674 trackQueue.append(model)
675@@ -193,23 +203,6 @@
676 }
677 }
678 }
679-
680- Expander {
681- id: expandable
682- anchors {
683- fill: parent
684- }
685- listItem: search
686- model: songsSearchModel.get(index, songsSearchModel.RoleModelData)
687- row: Row {
688- AddToPlaylist {
689-
690- }
691- AddToQueue {
692-
693- }
694- }
695- }
696 }
697 }
698 }
699
700=== modified file 'MusicTracks.qml'
701--- MusicTracks.qml 2014-07-11 22:29:21 +0000
702+++ MusicTracks.qml 2014-08-11 00:34:14 +0000
703@@ -20,8 +20,6 @@
704 import QtQuick 2.0
705 import Ubuntu.Components 0.1
706 import Ubuntu.Components 1.1 as Toolkit
707-import Ubuntu.Components.ListItems 0.1
708-import Ubuntu.Components.ListItems 0.1 as ListItem
709 import Ubuntu.MediaScanner 0.1
710 import Ubuntu.Thumbnailer 0.1
711 import QtMultimedia 5.0
712@@ -29,7 +27,7 @@
713 import "settings.js" as Settings
714 import "playlists.js" as Playlists
715 import "common"
716-import "common/ExpanderItems"
717+import "common/ListItemActions"
718
719
720 MusicPage {
721@@ -41,6 +39,7 @@
722 anchors.fill: parent
723 anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
724 highlightFollowsCurrentItem: false
725+ objectName: "trackstab-listview"
726 model: Toolkit.SortFilterModel {
727 id: songsModelFilter
728 property alias rowCount: songsModel.rowCount
729@@ -54,21 +53,23 @@
730 delegate: trackDelegate
731 Component {
732 id: trackDelegate
733- ListItem.Standard {
734+
735+ ListItemWithActions {
736 id: track
737+ color: "transparent"
738 width: parent.width
739 height: styleMusic.common.itemHeight
740
741- MouseArea {
742- anchors.fill: parent
743- onClicked: {
744- if (focus == false) {
745- focus = true
746- }
747+ rightSideActions: [
748+ AddToQueue {
749+ },
750+ AddToPlaylist {
751
752- trackClicked(tracklist.model, index) // play track
753 }
754- }
755+ ]
756+ triggerActionOnMouseRelease: true
757+
758+ onItemClicked: trackClicked(tracklist.model, index) // play track
759
760 MusicRow {
761 covers: [{author: model.author, album: model.album}]
762@@ -98,23 +99,6 @@
763 }
764 }
765
766- Expander {
767- id: expandable
768- anchors {
769- fill: parent
770- }
771- listItem: track
772- model: songsModelFilter.get(index, songsModelFilter.RoleModelData)
773- row: Row {
774- AddToPlaylist {
775-
776- }
777- AddToQueue {
778-
779- }
780- }
781- }
782-
783 states: State {
784 name: "Current"
785 when: track.ListView.isCurrentItem
786
787=== modified file 'MusicaddtoPlaylist.qml'
788--- MusicaddtoPlaylist.qml 2014-07-28 00:00:45 +0000
789+++ MusicaddtoPlaylist.qml 2014-08-11 00:34:14 +0000
790@@ -37,6 +37,7 @@
791 // Page that will be used when adding tracks to playlists
792 MusicPage {
793 id: addtoPlaylist
794+ objectName: "addToPlaylistPage"
795 title: i18n.tr("Select playlist")
796 visible: false
797
798
799=== modified file 'common/CMakeLists.txt'
800--- common/CMakeLists.txt 2014-06-13 12:29:43 +0000
801+++ common/CMakeLists.txt 2014-08-11 00:34:14 +0000
802@@ -1,4 +1,4 @@
803-add_subdirectory(ExpanderItems)
804+add_subdirectory(ListItemActions)
805
806 # make the qml files visible on qtcreator
807 file(GLOB COMMON_QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml)
808
809=== removed file 'common/Expander.qml'
810--- common/Expander.qml 2014-05-23 15:00:21 +0000
811+++ common/Expander.qml 1970-01-01 00:00:00 +0000
812@@ -1,165 +0,0 @@
813-/*
814- * Copyright (C) 2013, 2014
815- * Andrew Hayzen <ahayzen@gmail.com>
816- * Daniel Holm <d.holmen@gmail.com>
817- * Victor Thompson <victor.thompson@gmail.com>
818- *
819- * This program is free software; you can redistribute it and/or modify
820- * it under the terms of the GNU General Public License as published by
821- * the Free Software Foundation; version 3.
822- *
823- * This program is distributed in the hope that it will be useful,
824- * but WITHOUT ANY WARRANTY; without even the implied warranty of
825- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
826- * GNU General Public License for more details.
827- *
828- * You should have received a copy of the GNU General Public License
829- * along with this program. If not, see <http://www.gnu.org/licenses/>.
830- */
831-
832-import QtQuick 2.0
833-import Ubuntu.Components 0.1
834-import Ubuntu.Components.Popups 0.1
835-
836-Item {
837- id: expander
838- property int actualListItemHeight: -1
839- property alias backgroundOpacity: expandedBackground.opacity
840- property bool buttonEnabled: true
841- property int expanderButtonCentreFromBottom: -1
842- property alias expanderButtonWidth: expandableButton.width
843- property var listItem: null
844- property var model: null
845- property alias row: expanderRowLoader.sourceComponent
846- property bool expanderVisible: false
847- property bool _heightChangeLock: false
848-
849- Component.onCompleted: {
850- if (listItem !== null && actualListItemHeight === -1) {
851- actualListItemHeight = listItem.height;
852- }
853- if (listItem !== null && expanderButtonCentreFromBottom === -1) {
854- expanderButtonCentreFromBottom = listItem.height / 2;
855- }
856-
857- collapseExpand.connect(onCollapseExpand);
858- }
859-
860- function onCollapseExpand(indexCol)
861- {
862- if (expander !== undefined && expander.expanderVisible) {
863- customdebug("auto collapse")
864- expander.expanderVisible = false;
865- }
866- }
867-
868- Connections {
869- target: listItem
870- onHeightChanged: {
871- if (!expander._heightChangeLock && expander.expanderVisible) {
872- expander._heightChangeLock = true;
873- listItem.height += styleMusic.common.expandHeight;
874- expander._heightChangeLock = false;
875- }
876- }
877- }
878-
879- onExpanderVisibleChanged: {
880- expander._heightChangeLock = true;
881- if (expanderVisible) {
882- listItem.height += styleMusic.common.expandHeight;
883- }
884- else {
885- listItem.height -= styleMusic.common.expandHeight;
886- }
887- expander._heightChangeLock = false;
888- }
889-
890- Rectangle {
891- id: expandableButton
892- anchors {
893- bottom: parent.bottom
894- bottomMargin: expanderVisible ? expandedContainer.height : undefined
895- right: parent.right
896- }
897- color: "transparent"
898- height: expanderButtonCentreFromBottom * 2
899- width: expandableButtonImage.width * 2
900-
901- Image {
902- id: expandableButtonImage
903- anchors {
904- left: parent.left
905- verticalCenter: parent.verticalCenter
906- }
907- source: "../images/dropdown-menu.svg"
908- height: styleMusic.common.expandedItem
909- objectName: "expanditem"
910- rotation: expander.expanderVisible? 180 : 0
911- width: styleMusic.common.expandedItem
912- }
913-
914- MouseArea {
915- anchors {
916- horizontalCenter: parent.horizontalCenter
917- top: parent.top
918- }
919- height: parent.height
920- width: parent.width + units.gu(1)
921- onClicked: {
922- if (!expander.buttonEnabled) {
923- return;
924- }
925-
926- var expanderState = expander.expanderVisible;
927-
928- collapseExpand();
929- expander.expanderVisible = !expanderState;
930- }
931- }
932- }
933-
934- Rectangle {
935- id: expandedContainer
936- anchors {
937- top: parent.top
938- topMargin: actualListItemHeight
939- }
940- color: "transparent"
941- height: styleMusic.common.expandHeight
942- visible: expander.expanderVisible
943- width: parent.width
944-
945- Rectangle {
946- id: expandedBackground
947- anchors {
948- fill: parent
949- }
950- color: styleMusic.common.black
951- opacity: 0.4
952- }
953-
954- MouseArea {
955- anchors {
956- fill: parent
957- }
958- onClicked: mouse.accepted = true
959- }
960-
961- Rectangle {
962- anchors {
963- fill: parent
964- leftMargin: styleMusic.common.expandedLeftMargin
965- }
966- color: "transparent"
967- Loader {
968- id: expanderRowLoader
969- anchors {
970- verticalCenter: parent.verticalCenter
971- }
972- property alias expanderLink: expander
973- }
974- }
975-
976- }
977-}
978
979=== removed directory 'common/ExpanderItems'
980=== removed file 'common/ExpanderItems/AddToPlaylist.qml'
981--- common/ExpanderItems/AddToPlaylist.qml 2014-07-28 00:00:45 +0000
982+++ common/ExpanderItems/AddToPlaylist.qml 1970-01-01 00:00:00 +0000
983@@ -1,60 +0,0 @@
984-/*
985- * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
986- * Daniel Holm <d.holmen@gmail.com>
987- * Victor Thompson <victor.thompson@gmail.com>
988- *
989- * This program is free software; you can redistribute it and/or modify
990- * it under the terms of the GNU General Public License as published by
991- * the Free Software Foundation; version 3.
992- *
993- * This program is distributed in the hope that it will be useful,
994- * but WITHOUT ANY WARRANTY; without even the implied warranty of
995- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
996- * GNU General Public License for more details.
997- *
998- * You should have received a copy of the GNU General Public License
999- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1000- */
1001-
1002-import QtQuick 2.0
1003-import Ubuntu.Components 0.1
1004-import Ubuntu.Components.Popups 0.1
1005-
1006-// add to playlist
1007-Rectangle {
1008- id: playlistRow
1009- color: "transparent"
1010- height: styleMusic.common.expandHeight
1011- width: units.gu(15)
1012- Icon {
1013- id: playlistTrack
1014- anchors.verticalCenter: parent.verticalCenter
1015- color: styleMusic.common.white
1016- name: "add-to-playlist"
1017- height: styleMusic.common.expandedItem
1018- width: styleMusic.common.expandedItem
1019- }
1020- Label {
1021- anchors {
1022- left: playlistTrack.right
1023- leftMargin: units.gu(0.5)
1024- verticalCenter: parent.verticalCenter
1025- }
1026- color: styleMusic.common.white
1027- fontSize: "small"
1028- maximumLineCount: 3
1029- objectName: "addtoplaylist"
1030- text: i18n.tr("Add to playlist")
1031- width: parent.width - playlistTrack.width - units.gu(1)
1032- wrapMode: Text.WordWrap
1033- }
1034- MouseArea {
1035- anchors.fill: parent
1036- onClicked: {
1037- parent.parent.parent.expanderLink.expanderVisible = false;
1038- chosenElement = makeDict(parent.parent.parent.expanderLink.model);
1039- console.debug("Debug: Add track to playlist");
1040- mainPageStack.push(addtoPlaylist)
1041- }
1042- }
1043-}
1044
1045=== removed file 'common/ExpanderItems/AddToQueue.qml'
1046--- common/ExpanderItems/AddToQueue.qml 2014-07-13 00:16:14 +0000
1047+++ common/ExpanderItems/AddToQueue.qml 1970-01-01 00:00:00 +0000
1048@@ -1,58 +0,0 @@
1049-/*
1050- * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1051- * Daniel Holm <d.holmen@gmail.com>
1052- * Victor Thompson <victor.thompson@gmail.com>
1053- *
1054- * This program is free software; you can redistribute it and/or modify
1055- * it under the terms of the GNU General Public License as published by
1056- * the Free Software Foundation; version 3.
1057- *
1058- * This program is distributed in the hope that it will be useful,
1059- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1060- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1061- * GNU General Public License for more details.
1062- *
1063- * You should have received a copy of the GNU General Public License
1064- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1065- */
1066-
1067-import QtQuick 2.0
1068-import Ubuntu.Components 0.1
1069-import Ubuntu.Components.Popups 0.1
1070-
1071-Rectangle {
1072- id: queueRow
1073- color: "transparent"
1074- height: styleMusic.common.expandHeight
1075- width: units.gu(15)
1076- Icon {
1077- id: queueTrack
1078- anchors.verticalCenter: parent.verticalCenter
1079- color: styleMusic.common.white
1080- name: "add"
1081- height: styleMusic.common.expandedItem
1082- width: styleMusic.common.expandedItem
1083- }
1084- Label {
1085- anchors {
1086- left: queueTrack.right
1087- leftMargin: units.gu(0.5)
1088- verticalCenter: parent.verticalCenter
1089- }
1090- color: styleMusic.common.white
1091- fontSize: "small"
1092- maximumLineCount: 3
1093- objectName: "queuetrack"
1094- text: i18n.tr("Add to queue")
1095- wrapMode: Text.WordWrap
1096- width: parent.width - queueTrack.width - units.gu(1)
1097- }
1098- MouseArea {
1099- anchors.fill: parent
1100- onClicked: {
1101- parent.parent.parent.expanderLink.expanderVisible = false
1102- console.debug("Debug: Add track to queue: " + parent.parent.parent.expanderLink.model)
1103- trackQueue.append(parent.parent.parent.expanderLink.model)
1104- }
1105- }
1106-}
1107
1108=== removed file 'common/ExpanderItems/CMakeLists.txt'
1109--- common/ExpanderItems/CMakeLists.txt 2014-06-13 12:29:43 +0000
1110+++ common/ExpanderItems/CMakeLists.txt 1970-01-01 00:00:00 +0000
1111@@ -1,4 +0,0 @@
1112-# make the qml files visible on qtcreator
1113-file(GLOB EXPANDERITEMS_QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml)
1114-
1115-add_custom_target(com_ubuntu_music_EXPANDERITEMS_QMLFiles ALL SOURCES ${EXPANDERITEMS_QML_FILES})
1116
1117=== removed file 'common/ExpanderItems/DeletePlaylist.qml'
1118--- common/ExpanderItems/DeletePlaylist.qml 2014-07-28 00:00:45 +0000
1119+++ common/ExpanderItems/DeletePlaylist.qml 1970-01-01 00:00:00 +0000
1120@@ -1,59 +0,0 @@
1121-/*
1122- * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1123- * Daniel Holm <d.holmen@gmail.com>
1124- * Victor Thompson <victor.thompson@gmail.com>
1125- *
1126- * This program is free software; you can redistribute it and/or modify
1127- * it under the terms of the GNU General Public License as published by
1128- * the Free Software Foundation; version 3.
1129- *
1130- * This program is distributed in the hope that it will be useful,
1131- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1132- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1133- * GNU General Public License for more details.
1134- *
1135- * You should have received a copy of the GNU General Public License
1136- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1137- */
1138-
1139-import QtQuick 2.0
1140-import Ubuntu.Components 0.1
1141-import Ubuntu.Components.Popups 0.1
1142-
1143-Rectangle {
1144- id: deleteColumn
1145- color: "transparent"
1146- height: styleMusic.common.expandHeight
1147- width: units.gu(15)
1148- Icon {
1149- id: deletePlaylistIcon
1150- anchors {
1151- left: parent.left
1152- verticalCenter: parent.verticalCenter
1153- }
1154- color: styleMusic.common.white
1155- name: "delete"
1156- height: styleMusic.common.expandedItem
1157- width: styleMusic.common.expandedItem
1158- }
1159- Label {
1160- anchors {
1161- left: deletePlaylistIcon.right
1162- leftMargin: units.gu(0.5)
1163- verticalCenter: parent.verticalCenter
1164- }
1165- color: styleMusic.common.white
1166- fontSize: "small"
1167- // TRANSLATORS: this refers to deleting a playlist
1168- text: i18n.tr("Delete")
1169- }
1170- MouseArea {
1171- anchors.fill: parent
1172- onClicked: {
1173- parent.parent.parent.expanderLink.expanderVisible = false;
1174- customdebug("Delete")
1175- oldPlaylistName = parent.parent.parent.expanderLink.model.name
1176- PopupUtils.open(removePlaylistDialog, mainView)
1177- }
1178- }
1179-}
1180
1181=== removed file 'common/ExpanderItems/EditPlaylist.qml'
1182--- common/ExpanderItems/EditPlaylist.qml 2014-07-28 00:00:45 +0000
1183+++ common/ExpanderItems/EditPlaylist.qml 1970-01-01 00:00:00 +0000
1184@@ -1,59 +0,0 @@
1185-/*
1186- * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1187- * Daniel Holm <d.holmen@gmail.com>
1188- * Victor Thompson <victor.thompson@gmail.com>
1189- *
1190- * This program is free software; you can redistribute it and/or modify
1191- * it under the terms of the GNU General Public License as published by
1192- * the Free Software Foundation; version 3.
1193- *
1194- * This program is distributed in the hope that it will be useful,
1195- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1196- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1197- * GNU General Public License for more details.
1198- *
1199- * You should have received a copy of the GNU General Public License
1200- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1201- */
1202-
1203-import QtQuick 2.0
1204-import Ubuntu.Components 0.1
1205-import Ubuntu.Components.Popups 0.1
1206-
1207-Rectangle {
1208- id: editColumn
1209- color: "transparent"
1210- height: styleMusic.common.expandHeight
1211- width: units.gu(15)
1212- Icon {
1213- id: editPlaylistIcon
1214- anchors {
1215- left: parent.left
1216- verticalCenter: parent.verticalCenter
1217- }
1218- color: styleMusic.common.white
1219- name: "edit"
1220- height: styleMusic.common.expandedItem
1221- width: styleMusic.common.expandedItem
1222- }
1223- Label {
1224- anchors {
1225- left: editPlaylistIcon.right
1226- leftMargin: units.gu(0.5)
1227- verticalCenter: parent.verticalCenter
1228- }
1229- color: styleMusic.common.white
1230- fontSize: "small"
1231- // TRANSLATORS: this refers to editing a playlist
1232- text: i18n.tr("Edit")
1233- }
1234- MouseArea {
1235- anchors.fill: parent
1236- onClicked: {
1237- parent.parent.parent.expanderLink.expanderVisible = false;
1238- customdebug("Edit playlist")
1239- oldPlaylistName = parent.parent.parent.expanderLink.model.name
1240- PopupUtils.open(editPlaylistDialog, mainView)
1241- }
1242- }
1243-}
1244
1245=== added directory 'common/ListItemActions'
1246=== added file 'common/ListItemActions/AddToPlaylist.qml'
1247--- common/ListItemActions/AddToPlaylist.qml 1970-01-01 00:00:00 +0000
1248+++ common/ListItemActions/AddToPlaylist.qml 2014-08-11 00:34:14 +0000
1249@@ -0,0 +1,34 @@
1250+/*
1251+ * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1252+ * Daniel Holm <d.holmen@gmail.com>
1253+ * Victor Thompson <victor.thompson@gmail.com>
1254+ *
1255+ * This program is free software; you can redistribute it and/or modify
1256+ * it under the terms of the GNU General Public License as published by
1257+ * the Free Software Foundation; version 3.
1258+ *
1259+ * This program is distributed in the hope that it will be useful,
1260+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1261+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1262+ * GNU General Public License for more details.
1263+ *
1264+ * You should have received a copy of the GNU General Public License
1265+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1266+ */
1267+
1268+import QtQuick 2.0
1269+import Ubuntu.Components 0.1
1270+
1271+Action {
1272+ iconName: "add-to-playlist"
1273+ objectName: "addToPlaylistAction"
1274+ text: i18n.tr("Add to playlist")
1275+
1276+ property bool primed: false
1277+
1278+ onTriggered: {
1279+ chosenElement = makeDict(model);
1280+ console.debug("Debug: Add track to playlist");
1281+ mainPageStack.push(addtoPlaylist)
1282+ }
1283+}
1284
1285=== added file 'common/ListItemActions/AddToQueue.qml'
1286--- common/ListItemActions/AddToQueue.qml 1970-01-01 00:00:00 +0000
1287+++ common/ListItemActions/AddToQueue.qml 2014-08-11 00:34:14 +0000
1288@@ -0,0 +1,31 @@
1289+/*
1290+ * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1291+ * Daniel Holm <d.holmen@gmail.com>
1292+ * Victor Thompson <victor.thompson@gmail.com>
1293+ *
1294+ * This program is free software; you can redistribute it and/or modify
1295+ * it under the terms of the GNU General Public License as published by
1296+ * the Free Software Foundation; version 3.
1297+ *
1298+ * This program is distributed in the hope that it will be useful,
1299+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1300+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1301+ * GNU General Public License for more details.
1302+ *
1303+ * You should have received a copy of the GNU General Public License
1304+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1305+ */
1306+
1307+import QtQuick 2.0
1308+import Ubuntu.Components 1.1
1309+
1310+Action {
1311+ iconName: "add"
1312+ objectName: "addToQueueAction"
1313+ text: i18n.tr("Add to Queue")
1314+
1315+ onTriggered: {
1316+ console.debug("Debug: Add track to queue: " + model)
1317+ trackQueue.append(model)
1318+ }
1319+}
1320
1321=== added file 'common/ListItemActions/CMakeLists.txt'
1322--- common/ListItemActions/CMakeLists.txt 1970-01-01 00:00:00 +0000
1323+++ common/ListItemActions/CMakeLists.txt 2014-08-11 00:34:14 +0000
1324@@ -0,0 +1,4 @@
1325+# make the qml files visible on qtcreator
1326+file(GLOB ACTIONITEMS_QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml)
1327+
1328+add_custom_target(com_ubuntu_music_ACTIONITEMS_QMLFiles ALL SOURCES ${ACTIONITEMS_QML_FILES})
1329
1330=== added file 'common/ListItemActions/DeletePlaylist.qml'
1331--- common/ListItemActions/DeletePlaylist.qml 1970-01-01 00:00:00 +0000
1332+++ common/ListItemActions/DeletePlaylist.qml 2014-08-11 00:34:14 +0000
1333@@ -0,0 +1,29 @@
1334+/*
1335+ * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1336+ * Daniel Holm <d.holmen@gmail.com>
1337+ * Victor Thompson <victor.thompson@gmail.com>
1338+ *
1339+ * This program is free software; you can redistribute it and/or modify
1340+ * it under the terms of the GNU General Public License as published by
1341+ * the Free Software Foundation; version 3.
1342+ *
1343+ * This program is distributed in the hope that it will be useful,
1344+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1345+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1346+ * GNU General Public License for more details.
1347+ *
1348+ * You should have received a copy of the GNU General Public License
1349+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1350+ */
1351+
1352+import QtQuick 2.0
1353+import Ubuntu.Components 0.1
1354+import Ubuntu.Components.Popups 0.1
1355+
1356+Action {
1357+ iconName: "delete"
1358+ // TRANSLATORS: this refers to deleting a playlist
1359+ text: i18n.tr("Delete")
1360+
1361+ property bool primed: false
1362+}
1363
1364=== added file 'common/ListItemActions/EditPlaylist.qml'
1365--- common/ListItemActions/EditPlaylist.qml 1970-01-01 00:00:00 +0000
1366+++ common/ListItemActions/EditPlaylist.qml 2014-08-11 00:34:14 +0000
1367@@ -0,0 +1,35 @@
1368+/*
1369+ * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1370+ * Daniel Holm <d.holmen@gmail.com>
1371+ * Victor Thompson <victor.thompson@gmail.com>
1372+ *
1373+ * This program is free software; you can redistribute it and/or modify
1374+ * it under the terms of the GNU General Public License as published by
1375+ * the Free Software Foundation; version 3.
1376+ *
1377+ * This program is distributed in the hope that it will be useful,
1378+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1379+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1380+ * GNU General Public License for more details.
1381+ *
1382+ * You should have received a copy of the GNU General Public License
1383+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1384+ */
1385+
1386+import QtQuick 2.0
1387+import Ubuntu.Components 1.1
1388+import Ubuntu.Components.Popups 0.1
1389+
1390+Action {
1391+ iconName: "edit"
1392+ // TRANSLATORS: this refers to editing a playlist
1393+ text: i18n.tr("Edit")
1394+
1395+ property bool primed: false
1396+
1397+ onTriggered: {
1398+ customdebug("Edit playlist")
1399+ oldPlaylistName = model.name
1400+ PopupUtils.open(editPlaylistDialog, mainView)
1401+ }
1402+}
1403
1404=== added file 'common/ListItemActions/Remove.qml'
1405--- common/ListItemActions/Remove.qml 1970-01-01 00:00:00 +0000
1406+++ common/ListItemActions/Remove.qml 2014-08-11 00:34:14 +0000
1407@@ -0,0 +1,30 @@
1408+/*
1409+ * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
1410+ * Daniel Holm <d.holmen@gmail.com>
1411+ * Victor Thompson <victor.thompson@gmail.com>
1412+ *
1413+ * This program is free software; you can redistribute it and/or modify
1414+ * it under the terms of the GNU General Public License as published by
1415+ * the Free Software Foundation; version 3.
1416+ *
1417+ * This program is distributed in the hope that it will be useful,
1418+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1419+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1420+ * GNU General Public License for more details.
1421+ *
1422+ * You should have received a copy of the GNU General Public License
1423+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1424+ */
1425+
1426+import QtQuick 2.0
1427+import Ubuntu.Components 0.1
1428+import Ubuntu.Components.Popups 0.1
1429+
1430+Action {
1431+ id: removeAction
1432+ iconName: "delete"
1433+ objectName: "swipeDeleteAction"
1434+ text: i18n.tr("Remove")
1435+
1436+ property bool primed: false
1437+}
1438
1439=== added file 'common/ListItemWithActions.qml'
1440--- common/ListItemWithActions.qml 1970-01-01 00:00:00 +0000
1441+++ common/ListItemWithActions.qml 2014-08-11 00:34:14 +0000
1442@@ -0,0 +1,547 @@
1443+/*
1444+ * Copyright (C) 2012-2014 Canonical, Ltd.
1445+ *
1446+ * This program is free software; you can redistribute it and/or modify
1447+ * it under the terms of the GNU General Public License as published by
1448+ * the Free Software Foundation; version 3.
1449+ *
1450+ * This program is distributed in the hope that it will be useful,
1451+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1452+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1453+ * GNU General Public License for more details.
1454+ *
1455+ * You should have received a copy of the GNU General Public License
1456+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1457+ */
1458+
1459+import QtQuick 2.2
1460+import Ubuntu.Components 1.1
1461+import Ubuntu.Components.ListItems 0.1 as ListItem
1462+
1463+
1464+ListItem.Standard { // CUSTOM
1465+//Item {
1466+ id: root
1467+
1468+ property Action leftSideAction: null
1469+ property list<Action> rightSideActions
1470+ property double defaultHeight: units.gu(8)
1471+ property bool locked: false
1472+ property Action activeAction: null
1473+ property var activeItem: null
1474+ property bool triggerActionOnMouseRelease: false
1475+ property alias color: main.color
1476+ default property alias contents: main.children
1477+
1478+ property bool reorderable: false // CUSTOM
1479+ property bool reordering: false // CUSTOM
1480+
1481+ readonly property double actionWidth: units.gu(5)
1482+ readonly property double leftActionWidth: units.gu(10)
1483+ readonly property double actionThreshold: actionWidth * 0.4
1484+ readonly property double threshold: 0.4
1485+ readonly property string swipeState: main.x == 0 ? "Normal" : main.x > 0 ? "LeftToRight" : "RightToLeft"
1486+ readonly property alias swipping: mainItemMoving.running
1487+
1488+ signal itemClicked(var mouse)
1489+ signal itemPressAndHold(var mouse)
1490+
1491+ signal reorder(int from, int to) // CUSTOM
1492+
1493+ onItemPressAndHold: reordering = reorderable && !reordering // CUSTOM
1494+ onReorderingChanged: { // CUSTOM
1495+ if (reordering) {
1496+ resetSwipe()
1497+ }
1498+
1499+ for (var j=0; j < main.children.length; j++) {
1500+ main.children[j].anchors.rightMargin = reordering ? actionReorder.width + units.gu(2) : 0
1501+ }
1502+
1503+ parent.state = reordering ? "reorder" : "normal"
1504+ }
1505+
1506+ function returnToBoundsRTL()
1507+ {
1508+ var actionFullWidth = actionWidth + units.gu(2)
1509+ var xOffset = Math.abs(main.x)
1510+ var index = Math.min(Math.floor(xOffset / actionFullWidth), rightSideActions.length)
1511+ var j; // CUSTOM
1512+
1513+ if (index < 1) {
1514+ main.x = 0
1515+
1516+ resetPrimed() // CUSTOM
1517+ } else if (index === rightSideActions.length) {
1518+ main.x = -rightActionsView.width
1519+
1520+ for (j=0; j < rightSideActions.length; j++) { // CUSTOM
1521+ rightActionsRepeater.itemAt(j).primed = true
1522+ }
1523+ } else {
1524+ main.x = -(actionFullWidth * index)
1525+
1526+ for (j=0; j < rightSideActions.length; j++) { // CUSTOM
1527+ rightActionsRepeater.itemAt(j).primed = j === index
1528+ }
1529+ }
1530+ }
1531+
1532+ function returnToBoundsLTR()
1533+ {
1534+ var finalX = leftActionWidth
1535+ if (main.x > (finalX * root.threshold))
1536+ main.x = finalX
1537+ else {
1538+ main.x = 0
1539+
1540+ resetPrimed() // CUSTOM
1541+ }
1542+
1543+ if (leftSideAction !== null) { // CUSTOM
1544+ leftActionIcon.primed = main.x > (finalX * root.threshold)
1545+ }
1546+ }
1547+
1548+ function returnToBounds()
1549+ {
1550+ if (main.x < 0) {
1551+ returnToBoundsRTL()
1552+ } else if (main.x > 0) {
1553+ returnToBoundsLTR()
1554+ } else { // CUSTOM
1555+ resetPrimed() // CUSTOM
1556+ }
1557+ }
1558+
1559+ function contains(item, point)
1560+ {
1561+ return (point.x >= item.x) && (point.x <= (item.x + item.width)) && (point.y >= item.y) && (point.y <= (item.y + item.height));
1562+ }
1563+
1564+ function getActionAt(point)
1565+ {
1566+ if (contains(leftActionView, point)) {
1567+ return leftSideAction
1568+ } else if (contains(rightActionsView, point)) {
1569+ var newPoint = root.mapToItem(rightActionsView, point.x, point.y)
1570+ for (var i = 0; i < rightActionsRepeater.count; i++) {
1571+ var child = rightActionsRepeater.itemAt(i)
1572+ if (contains(child, newPoint)) {
1573+ return i
1574+ }
1575+ }
1576+ }
1577+ return -1
1578+ }
1579+
1580+ function updateActiveAction()
1581+ {
1582+ if ((main.x <= -root.actionWidth) &&
1583+ (main.x > -rightActionsView.width)) {
1584+ var actionFullWidth = actionWidth + units.gu(2)
1585+ var xOffset = Math.abs(main.x)
1586+ var index = Math.min(Math.floor(xOffset / actionFullWidth), rightSideActions.length)
1587+ index = index - 1
1588+ if (index > -1) {
1589+ root.activeItem = rightActionsRepeater.itemAt(index)
1590+ root.activeAction = root.rightSideActions[index]
1591+ }
1592+ } else {
1593+ root.activeAction = null
1594+ }
1595+ }
1596+
1597+ function resetPrimed() // CUSTOM
1598+ {
1599+ if (leftSideAction !== null) {
1600+ leftActionIcon.primed = false
1601+ }
1602+
1603+ for (var j=0; j < rightSideActions.length; j++) {
1604+ rightActionsRepeater.itemAt(j).primed = false
1605+ }
1606+ }
1607+
1608+ function resetSwipe()
1609+ {
1610+ main.x = 0
1611+
1612+ resetPrimed() // CUSTOM
1613+ }
1614+
1615+ Connections { // CUSTOM
1616+ target: mainView
1617+ onListItemSwiping: {
1618+ if (i !== index) {
1619+ root.resetSwipe();
1620+ }
1621+ }
1622+ }
1623+
1624+ Connections { // CUSTOM
1625+ target: root.parent
1626+ onStateChanged: reordering = root.parent.state === "reorder"
1627+ onVisibleChanged: {
1628+ if (!visible) {
1629+ reordering = false
1630+ }
1631+ }
1632+ }
1633+
1634+ Component.onCompleted: reordering = root.parent.state === "reorder" // CUSTOM
1635+
1636+ /* CUSTOM Dim Component */
1637+ Rectangle {
1638+ id: listItemDim
1639+ anchors {
1640+ fill: parent
1641+ }
1642+
1643+ color: mouseArea.pressed ? styleMusic.common.black : "transparent"
1644+ opacity: 0.1
1645+
1646+ property bool dim: false
1647+
1648+ Behavior on color {
1649+ ColorAnimation {
1650+ duration: UbuntuAnimation.SlowDuration
1651+ }
1652+ }
1653+ }
1654+
1655+ // CUSTOM remove animation
1656+ SequentialAnimation {
1657+ id: removeAnimation
1658+
1659+ property var action
1660+
1661+ UbuntuNumberAnimation {
1662+ target: root
1663+ duration: UbuntuAnimation.BriskDuration
1664+ property: "height";
1665+ to: 0
1666+ }
1667+ ScriptAction {
1668+ script: removeAnimation.action.trigger()
1669+ }
1670+ }
1671+
1672+ height: defaultHeight
1673+ clip: height !== defaultHeight
1674+
1675+ Rectangle {
1676+ id: leftActionView
1677+
1678+ anchors {
1679+ top: parent.top
1680+ bottom: parent.bottom
1681+ right: main.left
1682+ }
1683+ width: root.leftActionWidth + actionThreshold
1684+ visible: leftSideAction
1685+ color: "red"
1686+
1687+ Icon {
1688+ id: leftActionIcon
1689+ anchors {
1690+ centerIn: parent
1691+ horizontalCenterOffset: actionThreshold / 2
1692+ }
1693+ objectName: "swipeDeleteAction" // CUSTOM
1694+ name: leftSideAction ? leftSideAction.iconName : ""
1695+ color: Theme.palette.selected.field
1696+ height: units.gu(3)
1697+ width: units.gu(3)
1698+
1699+ property bool primed: false // CUSTOM
1700+ }
1701+ }
1702+
1703+ Item {
1704+ id: rightActionsView
1705+
1706+ anchors {
1707+ top: main.top
1708+ left: main.right
1709+ leftMargin: reordering ? actionReorder.width : units.gu(1) // CUSTOM
1710+ bottom: main.bottom
1711+ }
1712+ visible: rightSideActions.length > 0
1713+ width: rightActionsRepeater.count > 0 ? rightActionsRepeater.count * (root.actionWidth + units.gu(2)) + actionThreshold : 0
1714+
1715+ Rectangle { // CUSTOM
1716+ anchors {
1717+ bottom: parent.bottom
1718+ left: parent.left
1719+ top: parent.top
1720+ }
1721+ color: styleMusic.common.black
1722+ opacity: 0.7
1723+ width: parent.width + actionThreshold
1724+ }
1725+
1726+ Row {
1727+ anchors {
1728+ fill: parent
1729+ leftMargin: units.gu(2) // CUSTOM
1730+ }
1731+ spacing: units.gu(2)
1732+ Repeater {
1733+ id: rightActionsRepeater
1734+
1735+ model: rightSideActions
1736+ Item {
1737+ property alias image: img
1738+
1739+ anchors {
1740+ top: parent.top
1741+ bottom: parent.bottom
1742+ }
1743+ width: root.actionWidth
1744+
1745+ property alias primed: img.primed // CUSTOM
1746+
1747+ Icon {
1748+ id: img
1749+
1750+ anchors.centerIn: parent
1751+ objectName: rightSideActions[index].objectName // CUSTOM
1752+ width: units.gu(3)
1753+ height: units.gu(3)
1754+ name: iconName
1755+ color: root.activeAction === modelData || !root.triggerActionOnMouseRelease ? UbuntuColors.orange : styleMusic.common.white // CUSTOM
1756+
1757+ property bool primed: false // CUSTOM
1758+ }
1759+ }
1760+ }
1761+ }
1762+ }
1763+
1764+ Rectangle {
1765+ id: main
1766+ objectName: "mainItem"
1767+
1768+ anchors {
1769+ top: parent.top
1770+ bottom: parent.bottom
1771+ }
1772+
1773+ width: parent.width
1774+
1775+ Behavior on x {
1776+ UbuntuNumberAnimation {
1777+ id: mainItemMoving
1778+
1779+ easing.type: Easing.OutElastic
1780+ duration: UbuntuAnimation.SlowDuration
1781+ }
1782+ }
1783+ }
1784+
1785+ /* CUSTOM Reorder Component */
1786+ Rectangle {
1787+ id: actionReorder
1788+ anchors {
1789+ bottom: parent.bottom
1790+ right: main.right
1791+ rightMargin: units.gu(1)
1792+ top: parent.top
1793+ }
1794+ color: "transparent"
1795+ width: units.gu(4)
1796+ visible: reordering
1797+
1798+ Icon {
1799+ anchors {
1800+ horizontalCenter: parent.horizontalCenter
1801+ verticalCenter: parent.verticalCenter
1802+ }
1803+ name: "navigation-menu" // TODO: use proper image
1804+ height: width
1805+ width: units.gu(3)
1806+ }
1807+
1808+ MouseArea {
1809+ id: actionReorderMouseArea
1810+ anchors {
1811+ fill: parent
1812+ }
1813+ property int startY: 0
1814+ property int startContentY: 0
1815+
1816+ onPressed: {
1817+ root.parent.parent.interactive = false; // stop scrolling of listview
1818+ startY = root.y;
1819+ startContentY = root.parent.parent.contentY;
1820+ root.z += 10; // force ontop of other elements
1821+
1822+ console.debug("Reorder listitem pressed", root.y)
1823+ }
1824+ onMouseYChanged: root.y += mouse.y - (root.height / 2);
1825+ onReleased: {
1826+ console.debug("Reorder diff by position", getDiff());
1827+
1828+ var diff = getDiff();
1829+
1830+ // Remove the height of the actual item if moved down
1831+ if (diff > 0) {
1832+ diff -= 1;
1833+ }
1834+
1835+ root.parent.parent.interactive = true; // reenable scrolling
1836+
1837+ if (diff === 0) {
1838+ // Nothing has changed so reset the item
1839+ // z index is restored after animation
1840+ resetListItemYAnimation.start();
1841+ }
1842+ else {
1843+ var newIndex = index + diff;
1844+
1845+ if (newIndex < 0) {
1846+ newIndex = 0;
1847+ }
1848+ else if (newIndex > root.parent.parent.count - 1) {
1849+ newIndex = root.parent.parent.count - 1;
1850+ }
1851+
1852+ root.z -= 10; // restore z index
1853+ reorder(index, newIndex)
1854+ }
1855+ }
1856+
1857+ function getDiff() {
1858+ // Get the amount of items that have been passed over (by centre)
1859+ return Math.round((((root.y - startY) + (root.parent.parent.contentY - startContentY)) / root.height) + 0.5);
1860+ }
1861+ }
1862+
1863+ SequentialAnimation {
1864+ id: resetListItemYAnimation
1865+ UbuntuNumberAnimation {
1866+ target: root;
1867+ property: "y";
1868+ to: actionReorderMouseArea.startY
1869+ }
1870+ ScriptAction {
1871+ script: {
1872+ root.z -= 10; // restore z index
1873+ }
1874+ }
1875+ }
1876+ }
1877+
1878+ SequentialAnimation {
1879+ id: triggerAction
1880+
1881+ property var currentItem: root.activeItem ? root.activeItem.image : null
1882+
1883+ running: false
1884+ ParallelAnimation {
1885+ UbuntuNumberAnimation {
1886+ target: triggerAction.currentItem
1887+ property: "opacity"
1888+ from: 1.0
1889+ to: 0.0
1890+ duration: UbuntuAnimation.SlowDuration
1891+ easing {type: Easing.InOutBack; }
1892+ }
1893+ UbuntuNumberAnimation {
1894+ target: triggerAction.currentItem
1895+ properties: "width, height"
1896+ from: units.gu(3)
1897+ to: root.actionWidth
1898+ duration: UbuntuAnimation.SlowDuration
1899+ easing {type: Easing.InOutBack; }
1900+ }
1901+ }
1902+ PropertyAction {
1903+ target: triggerAction.currentItem
1904+ properties: "width, height"
1905+ value: units.gu(3)
1906+ }
1907+ PropertyAction {
1908+ target: triggerAction.currentItem
1909+ properties: "opacity"
1910+ value: 1.0
1911+ }
1912+ ScriptAction {
1913+ script: root.activeAction.triggered(root)
1914+ }
1915+ PauseAnimation {
1916+ duration: 500
1917+ }
1918+ UbuntuNumberAnimation {
1919+ target: main
1920+ property: "x"
1921+ to: 0
1922+ }
1923+ ScriptAction {
1924+ script: resetPrimed()
1925+ }
1926+ }
1927+
1928+ MouseArea {
1929+ id: mouseArea
1930+
1931+ property bool locked: root.locked || ((root.leftSideAction === null) && (root.rightSideActions.count === 0)) || reordering // CUSTOM
1932+ property bool manual: false
1933+
1934+ anchors.fill: parent
1935+ drag {
1936+ target: locked ? null : main
1937+ axis: Drag.XAxis
1938+ minimumX: rightActionsView.visible ? -(rightActionsView.width + root.actionThreshold) : 0
1939+ maximumX: leftActionView.visible ? leftActionView.width : 0
1940+ }
1941+
1942+ onReleased: {
1943+ if (root.triggerActionOnMouseRelease && root.activeAction) {
1944+ triggerAction.start()
1945+ } else {
1946+ root.returnToBounds()
1947+ root.activeAction = null
1948+ }
1949+ }
1950+ onClicked: {
1951+ if (reordering) { // CUSTOM
1952+ reordering = false
1953+ }
1954+ else if (main.x === 0) {
1955+ root.itemClicked(mouse)
1956+ } else if (main.x > 0) {
1957+ var action = getActionAt(Qt.point(mouse.x, mouse.y))
1958+ if (action && action !== -1) {
1959+ //action.triggered(root)
1960+ removeAnimation.action = action // CUSTOM
1961+ removeAnimation.start() // CUSTOM
1962+ }
1963+ } else {
1964+ var actionIndex = getActionAt(Qt.point(mouse.x, mouse.y))
1965+ if (actionIndex !== -1) {
1966+ root.activeItem = rightActionsRepeater.itemAt(actionIndex)
1967+ root.activeAction = root.rightSideActions[actionIndex]
1968+ triggerAction.start()
1969+ return
1970+ }
1971+ }
1972+ root.resetSwipe()
1973+ }
1974+
1975+ onPositionChanged: {
1976+ if (mouseArea.pressed) {
1977+ updateActiveAction()
1978+
1979+ listItemSwiping(index) // CUSTOM
1980+ }
1981+ }
1982+ onPressAndHold: {
1983+ if (main.x === 0) {
1984+ root.itemPressAndHold(mouse)
1985+ }
1986+ }
1987+ z: -1
1988+ }
1989+}
1990
1991=== modified file 'common/MusicRow.qml'
1992--- common/MusicRow.qml 2014-07-11 23:54:41 +0000
1993+++ common/MusicRow.qml 2014-08-11 00:34:14 +0000
1994@@ -26,8 +26,7 @@
1995 left: parent.left
1996 leftMargin: units.gu(1)
1997 right: parent.right
1998- // Set to expander item width for now set to 1GU when using listitem actions
1999- rightMargin: (styleMusic.common.expandedItem * 2) + units.gu(1)
2000+ rightMargin: units.gu(1)
2001 }
2002
2003 property alias covers: coverRow.covers
2004
2005=== modified file 'common/SongsPage.qml'
2006--- common/SongsPage.qml 2014-07-21 23:36:02 +0000
2007+++ common/SongsPage.qml 2014-08-11 00:34:14 +0000
2008@@ -24,7 +24,8 @@
2009 import Ubuntu.Thumbnailer 0.1
2010 import QtQuick.LocalStorage 2.0
2011 import "../meta-database.js" as Library
2012-import "ExpanderItems"
2013+import "../playlists.js" as Playlists
2014+import "ListItemActions"
2015
2016 MusicPage {
2017 id: songStackPage
2018@@ -55,6 +56,7 @@
2019 }
2020 delegate: albumTracksDelegate
2021 model: isAlbum ? songsModel : albumTracksModel.model
2022+ objectName: "songspage-listview"
2023 width: parent.width
2024 header: ListItem.Standard {
2025 id: albumInfo
2026@@ -210,32 +212,56 @@
2027 Component {
2028 id: albumTracksDelegate
2029
2030- ListItem.Standard {
2031+ ListItemWithActions {
2032 id: track
2033+ color: "transparent"
2034 objectName: "songspage-track"
2035 iconFrame: false
2036 progression: false
2037 height: styleMusic.common.itemHeight
2038
2039- MouseArea {
2040- anchors.fill: parent
2041- onDoubleClicked: {
2042- }
2043- onClicked: {
2044- if (focus == false) {
2045- focus = true
2046- }
2047-
2048- trackClicked(albumtrackslist.model, index) // play track
2049-
2050- if (isAlbum && songStackPage.line1 !== "Genre") {
2051- Library.addRecent(songStackPage.line2, songStackPage.line1, songStackPage.covers[0], songStackPage.line2, "album")
2052- mainView.hasRecent = true
2053- recentModel.filterRecent()
2054- } else if (songStackPage.line1 === "Playlist") {
2055- Library.addRecent(songStackPage.line2, "Playlist", songStackPage.covers[0], songStackPage.line2, "playlist")
2056- mainView.hasRecent = true
2057- recentModel.filterRecent()
2058+ leftSideAction: songStackPage.line1 === "Playlist"
2059+ ? playlistRemoveAction.item : null
2060+ reorderable: songStackPage.line1 === "Playlist"
2061+ rightSideActions: [
2062+ AddToQueue {
2063+
2064+ },
2065+ AddToPlaylist {
2066+
2067+ }
2068+ ]
2069+ triggerActionOnMouseRelease: true
2070+
2071+ onItemClicked: {
2072+ trackClicked(albumtrackslist.model, index) // play track
2073+
2074+ if (isAlbum && songStackPage.line1 !== "Genre") {
2075+ Library.addRecent(songStackPage.line2, songStackPage.line1, songStackPage.covers[0], songStackPage.line2, "album")
2076+ mainView.hasRecent = true
2077+ recentModel.filterRecent()
2078+ } else if (songStackPage.line1 === "Playlist") {
2079+ Library.addRecent(songStackPage.line2, "Playlist", songStackPage.covers[0], songStackPage.line2, "playlist")
2080+ mainView.hasRecent = true
2081+ recentModel.filterRecent()
2082+ }
2083+ }
2084+ onReorder: {
2085+ console.debug("Move: ", from, to);
2086+
2087+ Playlists.move(songStackPage.line2, from, to)
2088+
2089+ albumTracksModel.filterPlaylistTracks(songStackPage.line2)
2090+ }
2091+
2092+ Loader {
2093+ id: playlistRemoveAction
2094+ sourceComponent: Remove {
2095+ onTriggered: {
2096+ Playlists.removeFromPlaylist(songStackPage.line2, model.i)
2097+
2098+ albumTracksModel.filterPlaylistTracks(songStackPage.line2)
2099+ playlistModel.filterPlaylists()
2100 }
2101 }
2102 }
2103@@ -268,23 +294,6 @@
2104 }
2105 }
2106
2107- Expander {
2108- id: expandable
2109- anchors {
2110- fill: parent
2111- }
2112- listItem: track
2113- model: isAlbum ? albumtrackslist.model.get(index, albumTracksModel.model.RoleModelData) : albumtrackslist.model.get(index)
2114- row: Row {
2115- AddToPlaylist {
2116-
2117- }
2118- AddToQueue {
2119-
2120- }
2121- }
2122- }
2123-
2124 Component.onCompleted: {
2125 if (model.date !== undefined)
2126 {
2127
2128=== modified file 'music-app.qml'
2129--- music-app.qml 2014-08-07 14:15:05 +0000
2130+++ music-app.qml 2014-08-11 00:34:14 +0000
2131@@ -370,8 +370,8 @@
2132 property var chosenElement: null
2133 property bool toolbarShown: musicToolbar.shown
2134 property bool selectedAlbum: false
2135- signal collapseExpand();
2136- signal collapseSwipeDelete(int index);
2137+
2138+ signal listItemSwiping(int i)
2139 signal onToolbarShownChanged(bool shown, var currentPage, var currentTab)
2140
2141 property bool wideAspect: width >= units.gu(70) && loadedUI
2142@@ -460,8 +460,6 @@
2143 else {
2144 player.source = file;
2145 }
2146-
2147- collapseExpand(); // collapse all expands if track clicked
2148 }
2149
2150 function trackQueueClick(index) {
2151
2152=== modified file 'po/com.ubuntu.music.pot'
2153--- po/com.ubuntu.music.pot 2014-06-18 20:26:07 +0000
2154+++ po/com.ubuntu.music.pot 2014-08-11 00:34:14 +0000
2155@@ -8,7 +8,7 @@
2156 msgstr ""
2157 "Project-Id-Version: music-app\n"
2158 "Report-Msgid-Bugs-To: \n"
2159-"POT-Creation-Date: 2014-06-17 13:05-0400\n"
2160+"POT-Creation-Date: 2014-08-11 01:07+0100\n"
2161 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
2162 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
2163 "Language-Team: LANGUAGE <LL@li.org>\n"
2164@@ -54,74 +54,82 @@
2165 msgid "You forgot to set your username and/or password"
2166 msgstr ""
2167
2168-#: ../MusicAlbums.qml:37 ../MusicStart.qml:370
2169+#: ../MusicAlbums.qml:37 ../MusicStart.qml:378
2170 msgid "Albums"
2171 msgstr ""
2172
2173+#: ../MusicAlbums.qml:155 ../MusicStart.qml:202 ../MusicStart.qml:440
2174+#: ../common/AlbumsPage.qml:276
2175+msgid "Album"
2176+msgstr ""
2177+
2178 #: ../MusicArtists.qml:37
2179 msgid "Artists"
2180 msgstr ""
2181
2182-#: ../MusicArtists.qml:153 ../common/AlbumsSheet.qml:124
2183+#: ../MusicArtists.qml:107 ../common/AlbumsPage.qml:111
2184 #, qt-format
2185 msgid "%1 album"
2186 msgid_plural "%1 albums"
2187 msgstr[0] ""
2188 msgstr[1] ""
2189
2190-#: ../MusicArtists.qml:170 ../MusicPlaylists.qml:187 ../MusicStart.qml:351
2191-#: ../common/SongsSheet.qml:144
2192+#: ../MusicArtists.qml:113 ../MusicPlaylists.qml:174 ../MusicStart.qml:359
2193+#: ../MusicaddtoPlaylist.qml:102 ../common/SongsPage.qml:123
2194 #, qt-format
2195 msgid "%1 song"
2196 msgid_plural "%1 songs"
2197 msgstr[0] ""
2198 msgstr[1] ""
2199
2200-#: ../MusicNowPlaying.qml:34
2201+#: ../MusicArtists.qml:123
2202+msgid "Artist"
2203+msgstr ""
2204+
2205+#: ../MusicNowPlaying.qml:33
2206 msgid "Now Playing"
2207 msgstr ""
2208
2209 #. TRANSLATORS: this is the name of the playlists page shown in the tab header.
2210 #. Remember to keep the translation short to fit the screen width
2211-#: ../MusicPlaylists.qml:39
2212+#: ../MusicPlaylists.qml:37
2213 msgid "Playlists"
2214 msgstr ""
2215
2216+#: ../MusicPlaylists.qml:47 ../MusicaddtoPlaylist.qml:48
2217+msgid "New playlist"
2218+msgstr ""
2219+
2220 #. TRANSLATORS: this is a title of a dialog with a prompt to rename a playlist
2221-#: ../MusicPlaylists.qml:60
2222+#: ../MusicPlaylists.qml:63
2223 msgid "Change name"
2224 msgstr ""
2225
2226-#: ../MusicPlaylists.qml:61
2227+#: ../MusicPlaylists.qml:64
2228 msgid "Enter the new name of the playlist."
2229 msgstr ""
2230
2231-#: ../MusicPlaylists.qml:72
2232+#: ../MusicPlaylists.qml:77
2233 msgid "Change"
2234 msgstr ""
2235
2236-#: ../MusicPlaylists.qml:85
2237-msgid "You didn't type in a name."
2238-msgstr ""
2239-
2240-#: ../MusicPlaylists.qml:90 ../MusicPlaylists.qml:116 ../music-app.qml:752
2241+#: ../MusicPlaylists.qml:95 ../music-app.qml:732
2242+msgid "Playlist already exists"
2243+msgstr ""
2244+
2245+#: ../MusicPlaylists.qml:99 ../music-app.qml:737
2246+msgid "Please type in a name."
2247+msgstr ""
2248+
2249+#: ../MusicPlaylists.qml:104 ../music-app.qml:743
2250 msgid "Cancel"
2251 msgstr ""
2252
2253-#. TRANSLATORS: this is a title of a dialog with a prompt to delete a playlist
2254-#: ../MusicPlaylists.qml:103
2255-msgid "Are you sure?"
2256-msgstr ""
2257-
2258-#: ../MusicPlaylists.qml:104
2259-msgid "This will delete your playlist."
2260-msgstr ""
2261-
2262-#: ../MusicPlaylists.qml:107
2263-msgid "Remove"
2264-msgstr ""
2265-
2266-#: ../MusicSearch.qml:44 ../MusicToolbar.qml:508 ../music-app.qml:94
2267+#: ../MusicPlaylists.qml:161 ../MusicStart.qml:202
2268+msgid "Playlist"
2269+msgstr ""
2270+
2271+#: ../MusicSearch.qml:44 ../MusicToolbar.qml:519 ../music-app.qml:94
2272 #: ../music-app.qml:142 ../music-app.qml:148
2273 msgid "Search"
2274 msgstr ""
2275@@ -212,81 +220,87 @@
2276 msgid "Clean everything!"
2277 msgstr ""
2278
2279-#: ../MusicStart.qml:37 ../music-app.qml:373 ../music-app.qml:767
2280+#: ../MusicStart.qml:37 ../music-app.qml:363 ../music-app.qml:909
2281 #: com.ubuntu.music_music.desktop.in.in.h:1
2282 msgid "Music"
2283 msgstr ""
2284
2285-#: ../MusicStart.qml:84
2286+#: ../MusicStart.qml:77
2287 msgid "Recent"
2288 msgstr ""
2289
2290-#: ../MusicStart.qml:112
2291+#: ../MusicStart.qml:105
2292 msgid "Clear History"
2293 msgstr ""
2294
2295-#: ../MusicStart.qml:222
2296+#: ../MusicStart.qml:224
2297 msgid "Genres"
2298 msgstr ""
2299
2300-#: ../MusicToolbar.qml:739
2301+#: ../MusicStart.qml:309
2302+msgid "Genre"
2303+msgstr ""
2304+
2305+#: ../MusicToolbar.qml:756
2306 msgid "No songs queued"
2307 msgstr ""
2308
2309-#: ../MusicToolbar.qml:749
2310+#: ../MusicToolbar.qml:766
2311 msgid "Tap play or any item to start"
2312 msgstr ""
2313
2314-#: ../MusicTracks.qml:37
2315+#: ../MusicTracks.qml:35
2316 msgid "Songs"
2317 msgstr ""
2318
2319-#: ../MusicaddtoPlaylist.qml:39 ../common/ExpanderItems/AddToPlaylist.qml:59
2320-#: ../music-app.qml:699
2321+#: ../MusicaddtoPlaylist.qml:41
2322 msgid "Select playlist"
2323 msgstr ""
2324
2325-#: ../MusicaddtoPlaylist.qml:131
2326-msgid "New playlist"
2327-msgstr ""
2328-
2329-#: ../common/AlbumsSheet.qml:180 ../common/AlbumsSheet.qml:382
2330-#: ../common/SongsSheet.qml:173
2331+#: ../common/AlbumsPage.qml:165 ../common/AlbumsPage.qml:357
2332+#: ../common/SongsPage.qml:152
2333 msgid "Play all"
2334 msgstr ""
2335
2336-#: ../common/AlbumsSheet.qml:228 ../common/AlbumsSheet.qml:427
2337-#: ../common/ExpanderItems/AddToQueue.qml:45 ../common/SongsSheet.qml:225
2338-#: ../music-app.qml:674
2339+#: ../common/AlbumsPage.qml:209 ../common/AlbumsPage.qml:397
2340+#: ../common/SongsPage.qml:199 ../music-app.qml:665
2341 msgid "Add to queue"
2342 msgstr ""
2343
2344-#: ../common/AlbumsSheet.qml:352 ../common/SongsSheet.qml:143
2345+#: ../common/AlbumsPage.qml:327 ../common/SongsPage.qml:122
2346 #, qt-format
2347 msgid " | %1 song"
2348 msgid_plural " | %1 songs"
2349 msgstr[0] ""
2350 msgstr[1] ""
2351
2352-#: ../common/ExpanderItems/AddToPlaylist.qml:47 ../music-app.qml:688
2353+#: ../common/ListItemActions/AddToPlaylist.qml:25 ../music-app.qml:679
2354 msgid "Add to playlist"
2355 msgstr ""
2356
2357+#: ../common/ListItemActions/AddToQueue.qml:25
2358+msgid "Add to Queue"
2359+msgstr ""
2360+
2361 #. TRANSLATORS: this refers to deleting a playlist
2362-#: ../common/ExpanderItems/DeletePlaylist.qml:48
2363+#: ../common/ListItemActions/DeletePlaylist.qml:26
2364 msgid "Delete"
2365 msgstr ""
2366
2367 #. TRANSLATORS: this refers to editing a playlist
2368-#: ../common/ExpanderItems/EditPlaylist.qml:48
2369+#: ../common/ListItemActions/EditPlaylist.qml:26
2370 msgid "Edit"
2371 msgstr ""
2372
2373+#: ../common/ListItemActions/Remove.qml:27
2374+msgid "Remove"
2375+msgstr ""
2376+
2377 #: ../common/LoadingSpinnerComponent.qml:44
2378 msgid "Loading..."
2379 msgstr ""
2380
2381-#: ../common/SwipeDelete.qml:51 ../common/SwipeDelete.qml:86
2382+#: ../common/SwipeDelete.qml:52 ../common/SwipeDelete.qml:88
2383 msgid "Clear"
2384 msgstr ""
2385
2386@@ -355,42 +369,34 @@
2387 msgstr ""
2388
2389 #. TRANSLATORS: this refers to a number of songs greater than one. The actual number will be prepended to the string automatically (plural forms are not yet fully supported in usermetrics, the library that displays that string)
2390-#: ../music-app.qml:288
2391+#: ../music-app.qml:278
2392 msgid "songs played today"
2393 msgstr ""
2394
2395-#: ../music-app.qml:289
2396+#: ../music-app.qml:279
2397 msgid "No songs played today"
2398 msgstr ""
2399
2400-#: ../music-app.qml:396
2401+#: ../music-app.qml:387
2402 msgid "Debug: "
2403 msgstr ""
2404
2405-#: ../music-app.qml:712
2406+#: ../music-app.qml:701
2407 msgid "New Playlist"
2408 msgstr ""
2409
2410-#: ../music-app.qml:713
2411+#: ../music-app.qml:702
2412 msgid "Name your playlist."
2413 msgstr ""
2414
2415-#: ../music-app.qml:717
2416+#: ../music-app.qml:706
2417 msgid "Name"
2418 msgstr ""
2419
2420-#: ../music-app.qml:725
2421+#: ../music-app.qml:716
2422 msgid "Create"
2423 msgstr ""
2424
2425-#: ../music-app.qml:741
2426-msgid "Error: "
2427-msgstr ""
2428-
2429-#: ../music-app.qml:746
2430-msgid "Error: You didn't type a name."
2431-msgstr ""
2432-
2433 #: com.ubuntu.music_music.desktop.in.in.h:2
2434 msgid "A music application for Ubuntu"
2435 msgstr ""
2436
2437=== modified file 'tests/autopilot/music_app/emulators.py'
2438--- tests/autopilot/music_app/emulators.py 2014-08-06 00:51:56 +0000
2439+++ tests/autopilot/music_app/emulators.py 2014-08-11 00:34:14 +0000
2440@@ -70,13 +70,23 @@
2441 albumartist = self.get_albums_albumartist(artistName)
2442 self.pointing_device.click_object(albumartist)
2443
2444- # get track item to add to queue
2445- trackicon = self.get_songs_page_listview_trackicon(trackTitle)
2446- self.pointing_device.click_object(trackicon)
2447-
2448- # click on Add to queue
2449- queueTrackLabel = self.get_songs_page_queuetrack_label()
2450- self.pointing_device.click_object(queueTrackLabel)
2451+ # get track item to swipe and queue
2452+ trackitem = self.get_songs_page_listview_tracktitle(trackTitle)
2453+ songspage = self.get_songs_page_listview()
2454+
2455+ # get coordinates to swipe
2456+ start_x = int(songspage.globalRect.x +
2457+ (songspage.globalRect.width * 0.9))
2458+ stop_x = int(songspage.globalRect.x)
2459+ line_y = int(trackitem.globalRect.y)
2460+
2461+ # swipe to add to queue
2462+ self.pointing_device.move(start_x, line_y)
2463+ self.pointing_device.drag(start_x, line_y, stop_x, line_y)
2464+
2465+ # click on add to queue
2466+ queueaction = self.get_add_to_queue_action()
2467+ self.pointing_device.click_object(queueaction)
2468
2469 def tap_new_playlist_action(self):
2470 header = self.get_header()
2471@@ -125,6 +135,16 @@
2472 if item.text == artistName:
2473 return item
2474
2475+ def get_add_to_queue_action(self):
2476+ return self.wait_select_single("*",
2477+ objectName="addToQueueAction",
2478+ primed=True)
2479+
2480+ def get_add_to_playlist_action(self):
2481+ return self.wait_select_single("*",
2482+ objectName="addToPlaylistAction",
2483+ primed=True)
2484+
2485 def get_add_to_queue_button(self):
2486 return self.wait_select_single("QQuickImage",
2487 objectName="albumpage-queue-all")
2488@@ -174,27 +194,6 @@
2489 if item.text == trackTitle:
2490 return item
2491
2492- def get_album_page_listview_trackicon(self, trackTitle):
2493- tracktitle = self.get_album_page_listview_tracktitle(trackTitle)
2494- tracktitle_position = tracktitle.globalRect[1]
2495- trackicons = self.select_many(
2496- "QQuickImage", objectName="expanditem")
2497- for item in trackicons:
2498- if item.globalRect[1] == tracktitle_position:
2499- return item
2500-
2501- def get_songs_page_listview_trackicon(self, trackTitle):
2502- tracktitle = self.get_songs_page_listview_tracktitle(trackTitle)
2503-
2504- return self.get_trackimage_from_label(tracktitle)
2505-
2506- def get_songs_page_queuetrack_label(self):
2507- queuetracks = self.select_many_retry(
2508- "Label", objectName="queuetrack")
2509- for item in queuetracks:
2510- if item.visible:
2511- return item
2512-
2513 def get_queue_track_count(self):
2514 queuelist = self.select_single(
2515 "QQuickListView", objectName="queuelist")
2516@@ -214,6 +213,14 @@
2517 if item.text == trackTitle:
2518 return item
2519
2520+ def get_tracks_tab_listview(self):
2521+ return self.select_single("QQuickListView",
2522+ objectName="trackstab-listview")
2523+
2524+ def get_songs_page_listview(self):
2525+ return self.select_single("QQuickListView",
2526+ objectName="songspage-listview")
2527+
2528 def get_songs_tab_tracktitle(self, trackTitle):
2529 tracktitles = self.select_many_retry(
2530 "Label", objectName="tracktitle")
2531@@ -221,29 +228,6 @@
2532 if item.text == trackTitle:
2533 return item
2534
2535- def get_songs_tab_trackimage(self, trackTitle):
2536- tracktitle = self.get_songs_tab_tracktitle(trackTitle)
2537-
2538- return self.get_trackimage_from_label(tracktitle)
2539-
2540- def get_trackimage_from_label(self, label):
2541- item = label.get_parent().get_parent().get_parent().get_parent()
2542- return item.select_single('QQuickImage', objectName='expanditem')
2543-
2544- def get_songs_tab_add_to_queue_label(self):
2545- addtoqueue = self.select_many(
2546- "Label", objectName="queuetrack")
2547- for item in addtoqueue:
2548- if item.visible:
2549- return item
2550-
2551- def get_songs_tab_add_to_playlist_label(self):
2552- addtoplaylist = self.select_many(
2553- "Label", objectName="addtoplaylist")
2554- for item in addtoplaylist:
2555- if item.visible:
2556- return item
2557-
2558 def get_newPlaylistDialog_createButton(self):
2559 return self.wait_select_single(
2560 "Button", objectName="newPlaylistDialog_createButton")
2561@@ -253,7 +237,7 @@
2562 "TextField", objectName="playlistnameTextfield")
2563
2564 def get_addtoplaylistview(self):
2565- return self.select_many_retry(
2566+ return self.wait_select_single(
2567 "QQuickListView", objectName="addtoplaylistview")
2568
2569 def get_playlistname(self, playlistname):
2570@@ -272,6 +256,6 @@
2571 "MusicNowPlaying", objectName="nowplayingpage")
2572
2573 def get_swipedelete_icon(self):
2574- swipedelete = self.wait_select_single(
2575- "SwipeDelete", direction="swipingRight")
2576- return swipedelete.select_single("Label", objectName="leftDelete")
2577+ return self.wait_select_single(
2578+ "*", objectName="swipeDeleteAction",
2579+ primed=True)
2580
2581=== modified file 'tests/autopilot/music_app/tests/test_music.py'
2582--- tests/autopilot/music_app/tests/test_music.py 2014-07-24 13:57:08 +0000
2583+++ tests/autopilot/music_app/tests/test_music.py 2014-08-11 00:34:14 +0000
2584@@ -359,7 +359,8 @@
2585
2586 # verify track queue has added one to initial value
2587 endtracksCount = self.main_view.get_queue_track_count()
2588- self.assertThat(endtracksCount, Equals(initialtracksCount + 1))
2589+ self.assertThat(endtracksCount,
2590+ Eventually(Equals(initialtracksCount + 1)))
2591
2592 # Assert that the song added to the list is not playing
2593 self.assertThat(self.player.currentIndex,
2594@@ -415,19 +416,32 @@
2595 # switch to songs tab
2596 self.main_view.switch_to_tab("trackstab")
2597
2598- # get track item to add to queue
2599- trackitem = self.main_view.get_songs_tab_trackimage(self.trackTitle)
2600- self.pointing_device.click_object(trackitem)
2601- addtoqueueLabel = self.main_view.get_songs_tab_add_to_queue_label()
2602- self.pointing_device.click_object(addtoqueueLabel)
2603+ # get track item to swipe and queue
2604+ trackitem = self.main_view.get_songs_tab_tracktitle(self.trackTitle)
2605+ songspage = self.main_view.get_tracks_tab_listview()
2606+
2607+ # get coordinates to swipe
2608+ start_x = int(songspage.globalRect.x +
2609+ (songspage.globalRect.width * 0.9))
2610+ stop_x = int(songspage.globalRect.x)
2611+ line_y = int(trackitem.globalRect.y)
2612+
2613+ # swipe to add to queue
2614+ self.pointing_device.move(start_x, line_y)
2615+ self.pointing_device.drag(start_x, line_y, stop_x, line_y)
2616+
2617+ # click on add to queue
2618+ queueaction = self.main_view.get_add_to_queue_action()
2619+ self.pointing_device.click_object(queueaction)
2620
2621 # verify track queue has added all songs to initial value
2622- endtracksCount = self.main_view.get_queue_track_count()
2623- self.assertThat(endtracksCount, Equals(initialtracksCount + 1))
2624+ endtracksCount = self.main_view.get_queue_track_count
2625+ self.assertThat(endtracksCount(),
2626+ Eventually(Equals(initialtracksCount + 1)))
2627
2628 # Assert that the song added to the list is not playing
2629 self.assertThat(self.player.currentIndex,
2630- Eventually(NotEquals(endtracksCount)))
2631+ Eventually(NotEquals(endtracksCount())))
2632 self.assertThat(self.player.isPlaying, Eventually(Equals(False)))
2633
2634 # verify song's metadata matches the item added to the Now Playing view
2635@@ -445,14 +459,29 @@
2636 # switch to songs tab
2637 self.main_view.switch_to_tab("trackstab")
2638
2639- # get track item to add to queue
2640- trackitem = self.main_view.get_songs_tab_trackimage(self.trackTitle)
2641- self.pointing_device.click_object(trackitem)
2642- addtoplaylistLbl = self.main_view.get_songs_tab_add_to_playlist_label()
2643- self.pointing_device.click_object(addtoplaylistLbl)
2644+ # get track item to swipe and queue
2645+ trackitem = self.main_view.get_songs_tab_tracktitle(self.trackTitle)
2646+ songspage = self.main_view.get_tracks_tab_listview()
2647+
2648+ # get coordinates to swipe
2649+ start_x = int(songspage.globalRect.x +
2650+ (songspage.globalRect.width * 0.9))
2651+ stop_x = int(songspage.globalRect.x)
2652+ line_y = int(trackitem.globalRect.y)
2653+
2654+ # swipe to add to queue
2655+ self.pointing_device.move(start_x, line_y)
2656+ self.pointing_device.drag(start_x, line_y, stop_x, line_y)
2657+
2658+ # click on add to playlist
2659+ playlistaction = self.main_view.get_add_to_playlist_action()
2660+ self.pointing_device.click_object(playlistaction)
2661+
2662+ # Wait for animations to complete
2663+ playlistaction.primed.wait_for(False)
2664
2665 # get initial list view playlist count
2666- playlist_count = self.main_view.get_addtoplaylistview()[0].count
2667+ playlist_count = self.main_view.get_addtoplaylistview().count
2668
2669 # click on New playlist button in header
2670 self.main_view.tap_new_playlist_action()
2671@@ -468,7 +497,7 @@
2672 self.pointing_device.click_object(createButton)
2673
2674 # verify playlist has been sucessfully created
2675- palylist_final_count = self.main_view.get_addtoplaylistview()[0].count
2676+ palylist_final_count = self.main_view.get_addtoplaylistview().count
2677 self.assertThat(palylist_final_count, Equals(playlist_count + 1))
2678 playlist = self.main_view.get_playlistname("myPlaylist")
2679 self.assertThat(playlist, Not(Is(None)))
2680@@ -546,15 +575,15 @@
2681 musicnowplayingpage = self.main_view.get_MusicNowPlaying_page()
2682
2683 # get coordinates to delete song
2684- startX = int(musicnowplayingpage.globalRect[0] +
2685- musicnowplayingpage.width * 0.30)
2686- stopX = int(musicnowplayingpage.globalRect[0] +
2687- musicnowplayingpage.width)
2688- lineY = int(artistToDelete.globalRect[1])
2689+ start_x = int(musicnowplayingpage.globalRect.x +
2690+ musicnowplayingpage.globalRect.width * 0.30)
2691+ stop_x = int(musicnowplayingpage.globalRect.x +
2692+ musicnowplayingpage.globalRect.width * 0.90)
2693+ line_y = int(artistToDelete.globalRect.y)
2694
2695 # swipe to remove song
2696- self.pointing_device.move(startX, lineY)
2697- self.pointing_device.drag(startX, lineY, stopX, lineY)
2698+ self.pointing_device.move(start_x, line_y)
2699+ self.pointing_device.drag(start_x, line_y, stop_x, line_y)
2700
2701 # click on delete icon/label to confirm removal
2702 swipedeleteicon = self.main_view.get_swipedelete_icon()
2703@@ -562,7 +591,8 @@
2704
2705 # verify song has been deleted
2706 finalqueueCount = self.main_view.get_queue_track_count()
2707- self.assertThat(finalqueueCount, Equals(initialqueueCount - 1))
2708+ self.assertThat(finalqueueCount,
2709+ Eventually(Equals(initialqueueCount - 1)))
2710
2711 def test_playback_stops_when_last_song_ends_and_repeat_off(self):
2712 """Check that playback stops when the last song in the queue ends"""

Subscribers

People subscribed via source and target branches

to status/vote changes: