Merge lp:~vthompson/music-app/use-sheet-pattern into lp:music-app/trusty

Proposed by Victor Thompson
Status: Merged
Approved by: Victor Thompson
Approved revision: 308
Merged at revision: 305
Proposed branch: lp:~vthompson/music-app/use-sheet-pattern
Merge into: lp:music-app/trusty
Diff against target: 3373 lines (+1132/-1931)
12 files modified
LibraryListModel.qml (+10/-0)
MusicAlbums.qml (+16/-320)
MusicArtists.qml (+102/-426)
MusicPlaylists.qml (+349/-1091)
MusicStart.qml (+33/-56)
MusicToolbar.qml (+1/-27)
common/AlbumsSheet.qml (+154/-0)
common/SongsSheet.qml (+403/-0)
meta-database.js (+27/-1)
music-app.qml (+15/-9)
tests/autopilot/music_app/emulators.py (+1/-1)
tests/autopilot/music_app/tests/test_music.py (+21/-0)
To merge this branch: bzr merge lp:~vthompson/music-app/use-sheet-pattern
Reviewer Review Type Date Requested Status
Andrew Hayzen Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+200140@code.launchpad.net

Commit message

Use sheet component for recent albums, artist albums, tracks in an artist's album, playlists, and genres.

Description of the change

Use sheet component for recent albums, artist albums, tracks in an artist's album, playlists, and genres.

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: Approve (continuous-integration)
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
Andrew Hayzen (ahayzen) wrote :

Awesome work :)

Assuming this isn't supposed to fix the Genre part of bug 1238834, it looks good to go.

Although it does highlight the issue of the toolbar not appearing above the sheet patterns.

I'm hoping that this branch will assist with resolving the Artist tab part of bug 1239106 (look at the last two comments for reproducible steps [#12, #13])

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

Note that running albumTracksModel.populate() causes a big performance hit, and it is on the startTab, anyway of delaying this?

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

Ok i've managed to push back the loading, would it be possible for you to use the following changes in your branch?

P.S. What does sheetItem.file actually do? Every instance I can see of 'file' in that document uses the model.file if I'm understanding your code correctly.

=== modified file 'MusicStart.qml'
--- MusicStart.qml 2013-12-29 01:24:50 +0000
+++ MusicStart.qml 2013-12-29 12:27:42 +0000
@@ -164,8 +164,6 @@
                             albumTracksModel.filterAlbumTracks(title)
                             albumSheet.artist = title2
                             albumSheet.album = title
- albumSheet.file = albumTracksModel.model.get(0).file
- albumSheet.year = albumTracksModel.model.get(0).year
                             albumSheet.cover = cover
                             PopupUtils.open(albumSheet.sheet)
                         } else if (type === "playlist") {

=== modified file 'common/SongsSheet.qml'
--- common/SongsSheet.qml 2013-12-29 01:24:50 +0000
+++ common/SongsSheet.qml 2013-12-29 12:28:26 +0000
@@ -327,6 +327,11 @@
                         onFocusChanged: {
                         }
                         Component.onCompleted: {
+ if (index === 0)
+ {
+ sheetItem.file = model.file;
+ sheetItem.year = model.year;
+ }
                         }
                     }
                 }

=== modified file 'music-app.qml'
--- music-app.qml 2013-12-29 01:24:50 +0000
+++ music-app.qml 2013-12-29 12:28:03 +0000
@@ -1091,7 +1091,7 @@
             // First tab is all music
             Tab {
                 property bool populated: false
- property var loader: [recentModel.filterRecent, genreModel.filterGenres, albumTracksModel.populate]
+ property var loader: [recentModel.filterRecent, genreModel.filterGenres]
                 property bool loading: false
                 property var model: [recentModel, genreModel, albumTracksModel]
                 id: startTab

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

I intend on adding both a sheet for each playlist (used on the Music and Playlists tabs) as well as each genre (used on the Music tab).

I don't think it will fix bug 1239106 from the Artists tab. However, the spec seems to suggest that an organic grid is to be used on the Artists tab. So when a grid is used on the Artists tab it should be fixed.

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

Add goBack function back in

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

Fix AP tests

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

Fix label height

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

Update queue population

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

Update queue population

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

Does this intentionally remove swipeDelete and reordering in the playlists?

Once [1] lands it would probably be very easy to add conditional (eg only on certain sheets) reordering/swipeDelete to the sheet if that is the issue?

1 - https://code.launchpad.net/~andrew-hayzen/music-app/reorder-support-001

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

No, that was an oversight. It could possibly wait until the reorder implementation is worked out. Swipe to delete would be a bit clumsy on the sheet with how short each item is.

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

merge with trunk

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

Order Artist album covers properly.

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

Ensure playlist sheet is defined with isAlbum = false

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

Small update to try to get cover art if it exists for any song in a genre

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

Revert last change

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

Display blank cover art when playlist is empty

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
Andrew Hayzen (ahayzen) wrote :

Could the playlists sheet be the same as the songs list in the fact that it has Album art for *each* track [1]. This would then fix the issue of SwipeDelete and reordering being clumsy as each item would be larger and would make more sense because a playlist can have tracks from multiple albums.

1 - https://docs.google.com/presentation/d/1nc7RTAD5ViEAdc3VsZyN-lkmG-AnO664uV-5wXZoZZg/edit#slide=id.ge8e1d63f_022

306. By Victor Thompson

Show album art for playlists and genre sheets.

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

What do you think of deferring the re-order and swipe to delete functionalities until we have the patterns solidified? I'm not too keen on implementing it again here if it's going to change again.

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
Andrew Hayzen (ahayzen) wrote :

I agree, once this is merged I will pull the changes into [1] (I'll also update [2] to take into account the new sheets) and will resolve any issues there. We can live without swipeDelete/reordering for playlists in the interim period.

OK I'll have a double check through the code in this MP tonight but otherwise it should be good to go :)

1 - lp:~andrew-hayzen/music-app/reorder-support-001
2 - lp:~andrew-hayzen/music-app/convergence-keyboard-shortcuts

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

Ok found an initial issue.

1) Navigate to the album tab
2) Open up an album to see the songs (shows the sheet)
3) Close the sheet
4) Switch to the playlists tab
5) Select a playlist that is known to have tracks
6) No tracks appear in the sheet

If I go straight to the playlists tab at start up I can see the tracks but if I have used a sheet before (eg via the album sheet) then nothing appears?

review: Needs Fixing
307. By Victor Thompson

Fix issue with playlist sheet not populating.

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
Andrew Hayzen (ahayzen) wrote :

I noticed a minor flicker when moving between listing of albums for an artist and the list of tracks for the album selected. The following change stops this flicker.

=== modified file 'common/AlbumsSheet.qml'
--- common/AlbumsSheet.qml 2014-01-05 02:18:39 +0000
+++ common/AlbumsSheet.qml 2014-01-12 22:09:00 +0000
@@ -133,7 +133,6 @@
                                 // TODO: This closes the SDK defined sheet
                                 // component. It should be able to close
                                 // albumSheet.
- PopupUtils.close(sheet)

                                 albumTracksModel.filterAlbumTracks(album)
                                 albumSheet.line1 = artist
@@ -143,6 +142,8 @@
                                 albumSheet.year = year
                                 albumSheet.cover = Library.getAlbumCover(model.album) || Qt.resolvedUrl("../images/cover_default.png")
                                 PopupUtils.open(albumSheet.sheet)
+
+ PopupUtils.close(sheet)

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

Hmm actually it is still there, just leave it for now I'll check that over when attaching it to the toolbar sheet detection

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

I tried your change and on my device it prevents the flicker.

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

It appears to *reduce* it on the desktop, add it in if you want to.

308. By Victor Thompson

Close sheet after album sheet is opened.

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

On my Saucy desktop I do still see a bit of flicker. However, on a Trusty VM the flicker is gone.

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

Looks good to me :)

Lets get this landed so we can start working on the other components, top approve when you are ready.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'LibraryListModel.qml'
2--- LibraryListModel.qml 2013-12-14 19:37:34 +0000
3+++ LibraryListModel.qml 2014-01-12 22:19:24 +0000
4@@ -133,6 +133,16 @@
5 worker.list = Library.getArtistTracks(artist);
6 }
7
8+ function filterArtistAlbums(artist) {
9+ console.log("called LibraryListModel::filterArtistAlbums()")
10+
11+ // Save query for queue
12+ query = Library.getArtistAlbums
13+ param = artist
14+
15+ worker.list = Library.getArtistAlbums(artist);
16+ }
17+
18 function filterAlbums() {
19 console.log("called LibraryListModel::filterAlbums()")
20
21
22=== modified file 'MusicAlbums.qml'
23--- MusicAlbums.qml 2013-12-23 22:53:59 +0000
24+++ MusicAlbums.qml 2014-01-12 22:19:24 +0000
25@@ -32,14 +32,6 @@
26 id: mainpage
27 title: i18n.tr("Albums")
28
29- property string artist: ""
30- property string album: ""
31- property string songtitle: ""
32- property string cover: ""
33- property string length: ""
34- property string file: ""
35- property string year: ""
36-
37 onVisibleChanged: {
38 if (visible === true)
39 {
40@@ -66,6 +58,14 @@
41 Component {
42 id: albumDelegate
43 Item {
44+ property string artist: model.artist
45+ property string album: model.album
46+ property string title: model.title
47+ property string cover: model.cover !== "" ? model.cover : "images/cover_default.png"
48+ property string length: model.length
49+ property string file: model.file
50+ property string year: model.year
51+
52 id: albumItem
53 height: albumlist.cellHeight - units.gu(1)
54 width: albumlist.cellHeight - units.gu(1)
55@@ -77,14 +77,7 @@
56 image: Image {
57 id: icon
58 fillMode: Image.Stretch
59- property string artist: model.artist
60- property string album: model.album
61- property string title: model.title
62- property string cover: model.cover
63- property string length: model.length
64- property string file: model.file
65- property string year: model.year
66- source: cover !== "" ? cover : "images/cover_default.png"
67+ source: cover
68 }
69 UbuntuShape { // Background so can see text in current state
70 id: albumBg2
71@@ -140,310 +133,13 @@
72 }
73 onClicked: {
74 albumTracksModel.filterAlbumTracks(album)
75- mainpage.artist = artist
76- mainpage.album = album
77- mainpage.file = file
78- mainpage.year = year
79- mainpage.cover = cover
80- PopupUtils.open(albumSheet)
81- }
82- }
83- }
84- }
85- }
86-
87- Component {
88- id: albumSheet
89- DefaultSheet {
90- id: sheet
91- anchors.bottomMargin: units.gu(.5)
92- doneButton: false
93- contentsHeight: parent.height
94- contentsWidth: parent.width
95-
96- ListView {
97- clip: true
98- id: albumtrackslist
99- width: parent.width
100- anchors.top: parent.top
101- anchors.bottom: parent.bottom
102- model: albumTracksModel.model
103- delegate: albumTracksDelegate
104- header: ListItem.Standard {
105- id: albumInfo
106- width: parent.width
107- height: units.gu(20)
108-
109- UbuntuShape {
110- id: albumImage
111- anchors.left: parent.left
112- anchors.top: parent.top
113- anchors.verticalCenter: parent.verticalCenter
114- anchors.margins: units.gu(1)
115- height: parent.height
116- width: height
117- image: Image {
118- source: Library.hasCover(mainpage.file) ? mainpage.cover : Qt.resolvedUrl("images/cover_default.png")
119- }
120- }
121- Label {
122- id: albumArtist
123- objectName: "albumsheet-albumartist"
124- wrapMode: Text.NoWrap
125- maximumLineCount: 1
126- fontSize: "small"
127- anchors.left: albumImage.right
128- anchors.leftMargin: units.gu(1)
129- anchors.top: parent.top
130- anchors.topMargin: units.gu(1.5)
131- anchors.right: parent.right
132- anchors.rightMargin: units.gu(1.5)
133- elide: Text.ElideRight
134- text: mainpage.artist
135- }
136- Label {
137- id: albumLabel
138- wrapMode: Text.NoWrap
139- maximumLineCount: 2
140- fontSize: "medium"
141- color: styleMusic.common.music
142- anchors.left: albumImage.right
143- anchors.leftMargin: units.gu(1)
144- anchors.top: albumArtist.bottom
145- anchors.topMargin: units.gu(0.8)
146- anchors.right: parent.right
147- anchors.rightMargin: units.gu(1.5)
148- elide: Text.ElideRight
149- text: mainpage.album
150- }
151- Label {
152- id: albumYear
153- wrapMode: Text.NoWrap
154- maximumLineCount: 1
155- fontSize: "x-small"
156- anchors.left: albumImage.right
157- anchors.leftMargin: units.gu(1)
158- anchors.top: albumLabel.bottom
159- anchors.topMargin: units.gu(2)
160- anchors.right: parent.right
161- anchors.rightMargin: units.gu(1.5)
162- elide: Text.ElideRight
163- text: i18n.tr(mainpage.year + " | %1 song", mainpage.year + " | %1 songs", albumTracksModel.model.count).arg(albumTracksModel.model.count)
164- }
165- }
166-
167- onCountChanged: {
168- albumtrackslist.currentIndex = albumTracksModel.indexOf(currentFile)
169- }
170-
171- Component {
172- id: albumTracksDelegate
173-
174- ListItem.Standard {
175- id: track
176- objectName: "albumsheet-track"
177- iconFrame: false
178- progression: false
179- height: styleMusic.albums.itemHeight
180-
181- MouseArea {
182- anchors.fill: parent
183- onDoubleClicked: {
184- }
185- onClicked: {
186- if (focus == false) {
187- focus = true
188- }
189- trackClicked(albumTracksModel, index) // play track
190- Library.addRecent(album, artist, cover, album, "album")
191- mainView.hasRecent = true
192- recentModel.filterRecent()
193-
194- // TODO: This closes the SDK defined sheet
195- // component. It should be able to close
196- // albumSheet.
197- PopupUtils.close(sheet)
198- }
199- }
200-
201- Label {
202- id: trackTitle
203- objectName: "albumsheet-tracktitle"
204- wrapMode: Text.NoWrap
205- maximumLineCount: 1
206- fontSize: "medium"
207- anchors.left: parent.left
208- anchors.leftMargin: units.gu(2)
209- anchors.top: parent.top
210- anchors.topMargin: units.gu(1)
211- anchors.bottom: parent.bottom
212- anchors.bottomMargin: units.gu(1)
213- anchors.right: expandItem.left
214- anchors.rightMargin: units.gu(1.5)
215- elide: Text.ElideRight
216- text: model.title
217- }
218-
219- Image {
220- id: expandItem
221- objectName: "albumsheet-expanditem"
222- anchors.right: parent.right
223- anchors.rightMargin: units.gu(2)
224- source: expandable.visible ? "images/dropdown-menu-up.svg" : "images/dropdown-menu.svg"
225- height: styleMusic.common.expandedItem
226- width: styleMusic.common.expandedItem
227- y: parent.y + (styleMusic.albums.itemHeight / 2) - (height / 2)
228- }
229-
230- MouseArea {
231- anchors.bottom: parent.bottom
232- anchors.right: parent.right
233- anchors.top: parent.top
234- width: styleMusic.common.expandedItem * 3
235- onClicked: {
236- if(expandable.visible) {
237- customdebug("clicked collapse")
238- expandable.visible = false
239- track.height = styleMusic.albums.itemHeight
240- }
241- else {
242- customdebug("clicked expand")
243- collapseExpand(-1); // collapse all others
244- expandable.visible = true
245- track.height = styleMusic.albums.expandedHeight
246- }
247- }
248- }
249-
250- Rectangle {
251- id: expandable
252- color: "transparent"
253- height: styleMusic.albums.expandHeight
254- visible: false
255- MouseArea {
256- anchors.fill: parent
257- onClicked: {
258- customdebug("User pressed outside the playlist item and expanded items.")
259- }
260- }
261-
262- Component.onCompleted: {
263- collapseExpand.connect(onCollapseExpand);
264- }
265-
266- function onCollapseExpand(indexCol)
267- {
268- if ((indexCol === index || indexCol === -1) && expandable !== undefined && expandable.visible === true)
269- {
270- customdebug("auto collapse")
271- expandable.visible = false
272- track.height = styleMusic.albums.itemHeight
273- }
274- }
275-
276- // background for expander
277- Rectangle {
278- id: expandedBackground
279- anchors.top: parent.top
280- anchors.topMargin: styleMusic.albums.itemHeight
281- color: styleMusic.common.black
282- height: styleMusic.albums.expandedHeight - styleMusic.albums.itemHeight
283- width: track.width
284- opacity: 0.4
285- }
286-
287- // add to playlist
288- Rectangle {
289- id: playlistRow
290- anchors.top: expandedBackground.top
291- anchors.left: parent.left
292- anchors.leftMargin: styleMusic.albums.expandedLeftMargin
293- color: "transparent"
294- height: expandedBackground.height
295- width: units.gu(15)
296- Icon {
297- id: playlistTrack
298- anchors.verticalCenter: parent.verticalCenter
299- color: styleMusic.common.white
300- name: "add"
301- height: styleMusic.common.expandedItem
302- width: styleMusic.common.expandedItem
303- }
304- Label {
305- anchors.left: playlistTrack.right
306- anchors.leftMargin: units.gu(0.5)
307- anchors.verticalCenter: parent.verticalCenter
308- color: styleMusic.common.white
309- fontSize: "small"
310- width: parent.width - playlistTrack.width - units.gu(1)
311- text: i18n.tr("Add to playlist")
312- wrapMode: Text.WordWrap
313- maximumLineCount: 3
314- }
315- MouseArea {
316- anchors.fill: parent
317- onClicked: {
318- expandable.visible = false
319- track.height = styleMusic.albums.itemHeight
320- chosenArtist = artist
321- chosenTitle = title
322- chosenTrack = file
323- chosenAlbum = album
324- chosenCover = cover
325- chosenGenre = genre
326- chosenIndex = index
327- console.debug("Debug: Add track to playlist")
328- PopupUtils.open(Qt.resolvedUrl("MusicaddtoPlaylist.qml"), mainView,
329- {
330- title: i18n.tr("Select playlist")
331- } )
332- }
333- }
334- }
335- // Queue
336- Rectangle {
337- id: queueRow
338- anchors.top: expandedBackground.top
339- anchors.left: playlistRow.left
340- anchors.leftMargin: units.gu(15)
341- color: "transparent"
342- height: expandedBackground.height
343- width: units.gu(15)
344- Image {
345- id: queueTrack
346- objectName: "albumsheet-queuetrack"
347- anchors.verticalCenter: parent.verticalCenter
348- source: "images/queue.png"
349- height: styleMusic.common.expandedItem
350- width: styleMusic.common.expandedItem
351- }
352- Label {
353- anchors.left: queueTrack.right
354- anchors.leftMargin: units.gu(0.5)
355- anchors.verticalCenter: parent.verticalCenter
356- color: styleMusic.common.white
357- fontSize: "small"
358- width: parent.width - queueTrack.width - units.gu(1)
359- text: i18n.tr("Add to queue")
360- wrapMode: Text.WordWrap
361- maximumLineCount: 3
362- }
363- MouseArea {
364- anchors.fill: parent
365- onClicked: {
366- expandable.visible = false
367- track.height = styleMusic.albums.itemHeight
368- console.debug("Debug: Add track to queue: " + title)
369- trackQueue.model.append({"title": title, "artist": artist, "file": file, "album": album, "cover": cover, "genre": genre})
370- }
371- }
372- }
373- }
374-
375- onFocusChanged: {
376- }
377- Component.onCompleted: {
378- }
379+ songsSheet.line1 = artist
380+ songsSheet.line2 = album
381+ songsSheet.isAlbum = true
382+ songsSheet.file = file
383+ songsSheet.year = year
384+ songsSheet.cover = cover
385+ PopupUtils.open(songsSheet.sheet)
386 }
387 }
388 }
389
390=== modified file 'MusicArtists.qml'
391--- MusicArtists.qml 2014-01-10 00:31:12 +0000
392+++ MusicArtists.qml 2014-01-12 22:19:24 +0000
393@@ -27,441 +27,117 @@
394 import "playlists.js" as Playlists
395 import "common"
396
397-PageStack {
398- id: pageStack
399- anchors.fill: parent
400+
401+Page {
402+ id: mainpage
403+ title: i18n.tr("Artists")
404+
405+ onVisibleChanged: {
406+ if (visible === true)
407+ {
408+ musicToolbar.setPage(mainpage);
409+ }
410+ }
411
412 MusicSettings {
413 id: musicSettings
414 }
415
416- Page {
417- id: mainpage
418- title: i18n.tr("Artists")
419-
420- onVisibleChanged: {
421- if (visible === true)
422- {
423- musicToolbar.setPage(mainpage);
424- }
425- }
426-
427- Component.onCompleted: {
428- pageStack.push(mainpage)
429- }
430-
431- ListView {
432- id: artistlist
433- anchors.fill: parent
434- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
435- model: artistModel.model
436- delegate: artistDelegate
437-
438- Component {
439- id: artistDelegate
440-
441- ListItem.Standard {
442- id: track
443- property string artist: model.artist
444- height: styleMusic.common.itemHeight
445-
446- CoverRow {
447- id: coverRow
448- anchors {
449- top: parent.top
450- left: parent.left
451- margins: units.gu(1)
452- }
453- count: parseInt(Library.getArtistCovers(artist).length)
454- size: styleMusic.common.albumSize
455- covers: [Library.getArtistCovers(artist)[3] || "", Library.getArtistCovers(artist)[2] || "", Library.getArtistCovers(artist)[1] || "", Library.getArtistCovers(artist)[0] || ""]
456- }
457-
458- Label {
459- id: trackArtistAlbum
460- wrapMode: Text.NoWrap
461- maximumLineCount: 2
462- fontSize: "medium"
463- color: styleMusic.common.music
464- anchors {
465- left: coverRow.right
466- leftMargin: units.gu(2)
467- top: parent.top
468- topMargin: units.gu(2)
469- right: parent.right
470- rightMargin: units.gu(1.5)
471- }
472- elide: Text.ElideRight
473- text: artist
474- }
475-
476- Label {
477- id: trackArtistAlbums
478- wrapMode: Text.NoWrap
479- maximumLineCount: 2
480- fontSize: "x-small"
481- anchors {
482- left: trackArtistAlbum.left
483- top: trackArtistAlbum.bottom
484- topMargin: units.gu(1)
485- right: parent.right
486- rightMargin: units.gu(1.5)
487- }
488- elide: Text.ElideRight
489- // model for number of albums?
490- text: i18n.tr("%1 album", "%1 albums", Library.getArtistAlbumCount(artist)).arg(Library.getArtistAlbumCount(artist))
491- }
492-
493- Label {
494- id: trackArtistAlbumTracks
495- wrapMode: Text.NoWrap
496- maximumLineCount: 2
497- fontSize: "x-small"
498- anchors {
499- left: trackArtistAlbum.left
500- top: trackArtistAlbums.bottom
501- topMargin: units.gu(1)
502- right: parent.right
503- rightMargin: units.gu(1.5)
504- }
505- elide: Text.ElideRight
506- text: i18n.tr("%1 song", "%1 songs", Library.getArtistTracks(artist).length).arg(Library.getArtistTracks(artist).length)
507- }
508- onFocusChanged: {
509- }
510- MouseArea {
511- anchors.fill: parent
512- onDoubleClicked: {
513- }
514- onPressAndHold: {
515- }
516- onClicked: {
517- artistTracksModel.filterArtistTracks(artist)
518- artisttrackslist.artist = artist
519- artisttrackslist.file = file
520- artisttrackslist.cover = cover
521- pageStack.push(artistpage)
522- }
523- }
524- Component.onCompleted: {
525- }
526- }
527- }
528- }
529- }
530-
531- Page {
532- id: artistpage
533- title: i18n.tr("Tracks")
534- tools: null
535- visible: false
536-
537- onVisibleChanged: {
538- if (visible === true)
539- {
540- musicToolbar.setPage(artistpage, mainpage, pageStack);
541- }
542- }
543-
544- ListView {
545- id: artisttrackslist
546- property string artist: ""
547- property string file: ""
548- property string cover: ""
549- anchors.fill: parent
550- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
551- highlightFollowsCurrentItem: false
552- model: artistTracksModel.model
553- delegate: artistTracksDelegate
554- header: ListItem.Standard {
555- id: albumInfo
556- width: parent.width
557- height: units.gu(20)
558- UbuntuShape {
559- id: artistImage
560- anchors.left: parent.left
561- anchors.top: parent.top
562- anchors.verticalCenter: parent.verticalCenter
563- anchors.margins: units.gu(2)
564- height: parent.height
565- width: height
566- image: Image {
567- source: artisttrackslist.cover !== "" ? artisttrackslist.cover : "images/cover_default.png"
568- }
569- }
570- Label {
571- id: albumCount
572- wrapMode: Text.NoWrap
573- maximumLineCount: 1
574- fontSize: "small"
575- anchors.left: artistImage.right
576- anchors.leftMargin: units.gu(1)
577- anchors.top: parent.top
578- anchors.topMargin: units.gu(3)
579- anchors.right: parent.right
580- anchors.rightMargin: units.gu(1.5)
581- elide: Text.ElideRight
582- text: i18n.tr("%1 song", "%1 songs", artistTracksModel.model.count).arg(artistTracksModel.model.count)
583- }
584- Label {
585- id: albumArtist
586- wrapMode: Text.NoWrap
587- maximumLineCount: 1
588+ ListView {
589+ id: artistlist
590+ anchors.fill: parent
591+ anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
592+ model: artistModel.model
593+ delegate: artistDelegate
594+
595+ Component {
596+ id: artistDelegate
597+
598+ ListItem.Standard {
599+ id: track
600+ property string artist: model.artist
601+ height: styleMusic.common.itemHeight
602+
603+ CoverRow {
604+ id: coverRow
605+ anchors {
606+ top: parent.top
607+ left: parent.left
608+ margins: units.gu(1)
609+ }
610+ count: parseInt(Library.getArtistCovers(artist).length)
611+ size: styleMusic.common.albumSize
612+ covers: [Library.getArtistCovers(artist)[0] || "", Library.getArtistCovers(artist)[1] || "", Library.getArtistCovers(artist)[2] || "", Library.getArtistCovers(artist)[3] || ""]
613+ }
614+
615+ Label {
616+ id: trackArtistAlbum
617+ wrapMode: Text.NoWrap
618+ maximumLineCount: 2
619 fontSize: "medium"
620 color: styleMusic.common.music
621- anchors.left: artistImage.right
622- anchors.leftMargin: units.gu(1)
623- anchors.top: albumCount.bottom
624- anchors.topMargin: units.gu(1)
625- anchors.right: parent.right
626- anchors.rightMargin: units.gu(1.5)
627- elide: Text.ElideRight
628- text: artisttrackslist.artist
629- }
630- }
631-
632- onCountChanged: {
633- artisttrackslist.currentIndex = artistTracksModel.indexOf(currentFile)
634- }
635-
636- Component {
637- id: artistTracksDelegate
638-
639- ListItem.Standard {
640- id: track
641- property string artist: model.artist
642- property string album: model.album
643- property string title: model.title
644- property string cover: model.cover
645- property string length: model.length
646- property string file: model.file
647- progression: false
648- height: styleMusic.artists.itemHeight
649- MouseArea {
650- anchors.fill: parent
651- onDoubleClicked: {
652- }
653- onPressAndHold: {
654- PopupUtils.open(trackPopoverComponent, mainView)
655- chosenArtist = artist
656- chosenAlbum = album
657- chosenTitle = title
658- chosenTrack = file
659- chosenCover = cover
660- chosenGenre = genre
661- }
662- onClicked: {
663- if (focus == false) {
664- focus = true
665- }
666- trackClicked(artistTracksModel, index) // play track
667- }
668- }
669- UbuntuShape {
670- id: trackCover
671- anchors.left: parent.left
672- anchors.leftMargin: units.gu(2)
673- anchors.top: parent.top
674- anchors.topMargin: units.gu(1)
675- width: styleMusic.common.albumSize
676- height: styleMusic.common.albumSize
677- image: Image {
678- source: cover !== "" ? cover : Qt.resolvedUrl("images/cover_default_icon.png")
679- }
680- }
681-
682- Label {
683- id: trackTitle
684- wrapMode: Text.NoWrap
685- maximumLineCount: 1
686- fontSize: "small"
687- color: styleMusic.common.music
688- anchors.left: trackCover.right
689- anchors.leftMargin: units.gu(2)
690- anchors.top: trackCover.top
691- anchors.topMargin: units.gu(2)
692- anchors.right: expandItem.left
693- anchors.rightMargin: units.gu(1.5)
694- elide: Text.ElideRight
695- text: track.title
696- }
697- Label {
698- id: trackAlbum
699- wrapMode: Text.NoWrap
700- maximumLineCount: 2
701- fontSize: "x-small"
702- anchors.left: trackCover.right
703- anchors.leftMargin: units.gu(2)
704- anchors.top: trackTitle.bottom
705- anchors.topMargin: units.gu(2)
706- anchors.right: expandItem.left
707- anchors.rightMargin: units.gu(1.5)
708- elide: Text.ElideRight
709- text: album
710- }
711- Image {
712- id: expandItem
713- anchors.right: parent.right
714- anchors.rightMargin: units.gu(2)
715- source: expandable.visible ? "images/dropdown-menu-up.svg" : "images/dropdown-menu.svg"
716- height: styleMusic.common.expandedItem
717- width: styleMusic.common.expandedItem
718- y: parent.y + (styleMusic.artists.itemHeight / 2) - (height / 2)
719- }
720-
721- MouseArea {
722- anchors.bottom: parent.bottom
723- anchors.right: parent.right
724- anchors.top: parent.top
725- width: styleMusic.common.expandedItem * 3
726- onClicked: {
727- if(expandable.visible) {
728- customdebug("clicked collapse")
729- expandable.visible = false
730- track.height = styleMusic.artists.itemHeight
731-
732- }
733- else {
734- customdebug("clicked expand")
735- collapseExpand(-1); // collapse all others
736- expandable.visible = true
737- track.height = styleMusic.artists.expandedHeight
738- }
739- }
740- }
741-
742- Rectangle {
743- id: expandable
744- color: "transparent"
745- height: styleMusic.artists.expandHeight
746- visible: false
747- MouseArea {
748- anchors.fill: parent
749- onClicked: {
750- customdebug("User pressed outside the playlist item and expanded items.")
751- }
752- }
753-
754- Component.onCompleted: {
755- collapseExpand.connect(onCollapseExpand);
756- }
757-
758- function onCollapseExpand(indexCol)
759- {
760- if ((indexCol === index || indexCol === -1) && expandable !== undefined && expandable.visible === true)
761- {
762- customdebug("auto collapse")
763- expandable.visible = false
764- track.height = styleMusic.artists.itemHeight
765- }
766- }
767-
768- // background for expander
769- Rectangle {
770- id: expandedBackground
771- anchors.top: parent.top
772- anchors.topMargin: styleMusic.artists.itemHeight
773- color: styleMusic.common.black
774- height: styleMusic.artists.expandedHeight - styleMusic.artists.itemHeight
775- width: track.width
776- opacity: 0.4
777- }
778-
779- // add to playlist
780- Rectangle {
781- id: playlistRow
782- anchors.top: expandedBackground.top
783- anchors.left: parent.left
784- anchors.leftMargin: styleMusic.artists.expandedLeftMargin
785- color: "transparent"
786- height: expandedBackground.height
787- width: units.gu(15)
788- Icon {
789- id: playlistTrack
790- anchors.verticalCenter: parent.verticalCenter
791- color: styleMusic.common.white
792- name: "add"
793- height: styleMusic.common.expandedItem
794- width: styleMusic.common.expandedItem
795- }
796- Label {
797- anchors.left: playlistTrack.right
798- anchors.leftMargin: units.gu(0.5)
799- anchors.verticalCenter: parent.verticalCenter
800- color: styleMusic.common.white
801- fontSize: "small"
802- width: parent.width - playlistTrack.width - units.gu(1)
803- text: i18n.tr("Add to playlist")
804- wrapMode: Text.WordWrap
805- maximumLineCount: 3
806- }
807- MouseArea {
808- anchors.fill: parent
809- onClicked: {
810- expandable.visible = false
811- track.height = styleMusic.artists.itemHeight
812- chosenArtist = artist
813- chosenTitle = title
814- chosenTrack = file
815- chosenAlbum = album
816- chosenCover = cover
817- chosenGenre = genre
818- chosenIndex = index
819- console.debug("Debug: Add track to playlist")
820- PopupUtils.open(Qt.resolvedUrl("MusicaddtoPlaylist.qml"), mainView,
821- {
822- title: i18n.tr("Select playlist")
823- } )
824- }
825- }
826- }
827- // Queue
828- Rectangle {
829- id: queueRow
830- anchors.top: expandedBackground.top
831- anchors.left: playlistRow.left
832- anchors.leftMargin: units.gu(15)
833- color: "transparent"
834- height: expandedBackground.height
835- width: units.gu(15)
836- Image {
837- id: queueTrack
838- anchors.verticalCenter: parent.verticalCenter
839- source: "images/queue.png"
840- height: styleMusic.common.expandedItem
841- width: styleMusic.common.expandedItem
842- }
843- Label {
844- anchors.left: queueTrack.right
845- anchors.leftMargin: units.gu(0.5)
846- anchors.verticalCenter: parent.verticalCenter
847- color: styleMusic.common.white
848- fontSize: "small"
849- width: parent.width - queueTrack.width - units.gu(1)
850- text: i18n.tr("Add to queue")
851- wrapMode: Text.WordWrap
852- maximumLineCount: 3
853- }
854- MouseArea {
855- anchors.fill: parent
856- onClicked: {
857- expandable.visible = false
858- track.height = styleMusic.artists.itemHeight
859- console.debug("Debug: Add track to queue: " + title)
860- trackQueue.model.append({"title": title, "artist": artist, "file": file, "album": album, "cover": cover, "genre": genre})
861- }
862- }
863- }
864- }
865- onFocusChanged: {
866- }
867-
868- states: State {
869- name: "Current"
870- when: track.ListView.isCurrentItem
871- }
872+ anchors {
873+ left: coverRow.right
874+ leftMargin: units.gu(2)
875+ top: parent.top
876+ topMargin: units.gu(2)
877+ right: parent.right
878+ rightMargin: units.gu(1.5)
879+ }
880+ elide: Text.ElideRight
881+ text: artist
882+ }
883+
884+ Label {
885+ id: trackArtistAlbums
886+ wrapMode: Text.NoWrap
887+ maximumLineCount: 2
888+ fontSize: "x-small"
889+ anchors {
890+ left: trackArtistAlbum.left
891+ top: trackArtistAlbum.bottom
892+ topMargin: units.gu(1)
893+ right: parent.right
894+ rightMargin: units.gu(1.5)
895+ }
896+ elide: Text.ElideRight
897+ // model for number of albums?
898+ text: i18n.tr("%1 album", "%1 albums", Library.getArtistAlbumCount(artist)).arg(Library.getArtistAlbumCount(artist))
899+ }
900+
901+ Label {
902+ id: trackArtistAlbumTracks
903+ wrapMode: Text.NoWrap
904+ maximumLineCount: 2
905+ fontSize: "x-small"
906+ anchors {
907+ left: trackArtistAlbum.left
908+ top: trackArtistAlbums.bottom
909+ topMargin: units.gu(1)
910+ right: parent.right
911+ rightMargin: units.gu(1.5)
912+ }
913+ elide: Text.ElideRight
914+ text: i18n.tr("%1 song", "%1 songs", Library.getArtistTracks(artist).length).arg(Library.getArtistTracks(artist).length)
915+ }
916+ onFocusChanged: {
917+ }
918+ MouseArea {
919+ anchors.fill: parent
920+ onDoubleClicked: {
921+ }
922+ onPressAndHold: {
923+ }
924+ onClicked: {
925+ artistAlbumsModel.filterArtistAlbums(artist)
926+ artistSheet.artist = artist
927+ PopupUtils.open(artistSheet.sheet)
928+ }
929+ }
930+ Component.onCompleted: {
931 }
932 }
933 }
934 }
935 }
936+
937
938=== modified file 'MusicPlaylists.qml'
939--- MusicPlaylists.qml 2014-01-09 00:43:35 +0000
940+++ MusicPlaylists.qml 2014-01-12 22:19:24 +0000
941@@ -29,9 +29,12 @@
942 import "playlists.js" as Playlists
943 import "common"
944
945-PageStack {
946- id: pageStack
947- anchors.fill: parent
948+// page for the playlists
949+Page {
950+ id: listspage
951+ // TRANSLATORS: this is the name of the playlists page shown in the tab header.
952+ // Remember to keep the translation short to fit the screen width
953+ title: i18n.tr("Playlists")
954
955 property string playlistTracks: ""
956 property string oldPlaylistName: ""
957@@ -39,1108 +42,363 @@
958 property string oldPlaylistID: ""
959 property string inPlaylist: ""
960
961- // Remove playlist dialog
962- Component {
963- id: removePlaylistDialog
964- Dialog {
965- id: dialogueRemovePlaylist
966- // TRANSLATORS: this is a title of a dialog with a prompt to delete a playlist
967- title: i18n.tr("Are you sure?")
968- text: i18n.tr("This will delete your playlist.")
969-
970- Button {
971- text: i18n.tr("Remove")
972- onClicked: {
973- // removing playlist
974- Playlists.removePlaylist(oldPlaylistID, oldPlaylistName) // remove using both ID and name, if playlists has similair names
975- playlistModel.model.remove(oldPlaylistIndex)
976- PopupUtils.close(dialogueRemovePlaylist)
977- if (inPlaylist) {
978- customdebug("Back to playlists")
979- pageStack.pop()
980- }
981- }
982- }
983- Button {
984- text: i18n.tr("Cancel")
985- color: styleMusic.dialog.buttonColor
986- onClicked: PopupUtils.close(dialogueRemovePlaylist)
987- }
988- }
989- }
990-
991- // Edit name of playlist dialog
992- Component {
993- id: editPlaylistDialog
994- Dialog {
995- id: dialogueEditPlaylist
996- // TRANSLATORS: this is a title of a dialog with a prompt to rename a playlist
997- title: i18n.tr("Change name")
998- text: i18n.tr("Enter the new name of the playlist.")
999- TextField {
1000- id: playlistName
1001- placeholderText: oldPlaylistName
1002- }
1003- ListItem.Standard {
1004- id: editplaylistoutput
1005- visible: false
1006- }
1007-
1008- Button {
1009- text: i18n.tr("Change")
1010- onClicked: {
1011- editplaylistoutput.visible = true
1012- if (playlistName.text.length > 0) { // make sure something is acually inputed
1013- var editList = Playlists.namechangePlaylist(oldPlaylistName,playlistName.text) // change the name of the playlist in DB
1014- console.debug("Debug: User changed name from "+oldPlaylistName+" to "+playlistName.text)
1015- playlistModel.model.set(oldPlaylistIndex, {"name": playlistName.text})
1016- PopupUtils.close(dialogueEditPlaylist)
1017- if (inPlaylist) {
1018- playlistInfoLabel.text = playlistName.text
1019- }
1020- }
1021- else {
1022- editplaylistoutput.text = i18n.tr("You didn't type in a name.")
1023- }
1024- }
1025- }
1026- Button {
1027- text: i18n.tr("Cancel")
1028- color: styleMusic.dialog.buttonColor
1029- onClicked: PopupUtils.close(dialogueEditPlaylist)
1030- }
1031- }
1032- }
1033-
1034 Component.onCompleted: {
1035- pageStack.push(listspage)
1036- // fix pageStack bug the ugly way
1037- pageStack.push(playlistpage)
1038- pageStack.pop()
1039-
1040 random = Settings.getSetting("shuffle") == "1" // shuffle state
1041 scrobble = Settings.getSetting("scrobble") == "1" // scrobble state
1042 lastfmusername = Settings.getSetting("lastfmusername") // lastfm username
1043 lastfmpassword = Settings.getSetting("lastfmpassword") // lastfm password
1044 }
1045
1046+ onVisibleChanged: {
1047+ if (visible === true)
1048+ {
1049+ musicToolbar.setPage(listspage);
1050+ }
1051+ }
1052+
1053+ // Edit name of playlist dialog
1054+ Component {
1055+ id: editPlaylistDialog
1056+ Dialog {
1057+ id: dialogueEditPlaylist
1058+ // TRANSLATORS: this is a title of a dialog with a prompt to rename a playlist
1059+ title: i18n.tr("Change name")
1060+ text: i18n.tr("Enter the new name of the playlist.")
1061+ TextField {
1062+ id: playlistName
1063+ placeholderText: oldPlaylistName
1064+ }
1065+ ListItem.Standard {
1066+ id: editplaylistoutput
1067+ visible: false
1068+ }
1069+
1070+ Button {
1071+ text: i18n.tr("Change")
1072+ onClicked: {
1073+ editplaylistoutput.visible = true
1074+ if (playlistName.text.length > 0) { // make sure something is acually inputed
1075+ var editList = Playlists.namechangePlaylist(oldPlaylistName,playlistName.text) // change the name of the playlist in DB
1076+ console.debug("Debug: User changed name from "+oldPlaylistName+" to "+playlistName.text)
1077+ playlistModel.model.set(oldPlaylistIndex, {"name": playlistName.text})
1078+ PopupUtils.close(dialogueEditPlaylist)
1079+ if (inPlaylist) {
1080+ playlistInfoLabel.text = playlistName.text
1081+ }
1082+ }
1083+ else {
1084+ editplaylistoutput.text = i18n.tr("You didn't type in a name.")
1085+ }
1086+ }
1087+ }
1088+ Button {
1089+ text: i18n.tr("Cancel")
1090+ color: styleMusic.dialog.buttonColor
1091+ onClicked: PopupUtils.close(dialogueEditPlaylist)
1092+ }
1093+ }
1094+ }
1095+
1096+ // Remove playlist dialog
1097+ Component {
1098+ id: removePlaylistDialog
1099+ Dialog {
1100+ id: dialogueRemovePlaylist
1101+ // TRANSLATORS: this is a title of a dialog with a prompt to delete a playlist
1102+ title: i18n.tr("Are you sure?")
1103+ text: i18n.tr("This will delete your playlist.")
1104+
1105+ Button {
1106+ text: i18n.tr("Remove")
1107+ onClicked: {
1108+ // removing playlist
1109+ Playlists.removePlaylist(oldPlaylistID, oldPlaylistName) // remove using both ID and name, if playlists has similair names
1110+ playlistModel.model.remove(oldPlaylistIndex)
1111+ PopupUtils.close(dialogueRemovePlaylist)
1112+ }
1113+ }
1114+ Button {
1115+ text: i18n.tr("Cancel")
1116+ color: styleMusic.dialog.buttonColor
1117+ onClicked: PopupUtils.close(dialogueRemovePlaylist)
1118+ }
1119+ }
1120+ }
1121+
1122 MusicSettings {
1123 id: musicSettings
1124 }
1125
1126- // page for the playlists
1127- Page {
1128- id: listspage
1129- // TRANSLATORS: this is the name of the playlists page shown in the tab header.
1130- // Remember to keep the translation short to fit the screen width
1131- title: i18n.tr("Playlists")
1132-
1133- onVisibleChanged: {
1134- if (visible === true)
1135- {
1136- musicToolbar.setPage(listspage);
1137- }
1138- }
1139-
1140- ListView {
1141- id: playlistslist
1142- objectName: "playlistslist"
1143- anchors.fill: parent
1144- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
1145- model: playlistModel.model
1146- delegate: playlistDelegate
1147- onCountChanged: {
1148- customdebug("onCountChanged: " + playlistslist.count)
1149- }
1150- onCurrentIndexChanged: {
1151- customdebug("tracklist.currentIndex = " + playlistslist.currentIndex)
1152- }
1153-
1154- Component {
1155- id: playlistDelegate
1156- ListItem.Standard {
1157- id: playlist
1158- property string name: model.name
1159- property string count: model.count
1160- property string cover0: model.cover0 || ""
1161- property string cover1: model.cover1 || ""
1162- property string cover2: model.cover2 || ""
1163- property string cover3: model.cover3 || ""
1164- iconFrame: false
1165- height: styleMusic.playlist.playlistItemHeight
1166-
1167- CoverRow {
1168- id: coverRow
1169- anchors {
1170- top: parent.top
1171- left: parent.left
1172- margins: units.gu(1)
1173- }
1174- count: parseInt(playlist.count)
1175- size: styleMusic.playlist.playlistAlbumSize
1176- covers: [playlist.cover0, playlist.cover1, playlist.cover2, playlist.cover3]
1177- }
1178-
1179- // songs count
1180- Label {
1181- id: playlistCount
1182- anchors {
1183- top: parent.top
1184- left: parent.left
1185- right: expandItem.left
1186- topMargin: units.gu(2)
1187- leftMargin: units.gu(12)
1188- rightMargin: units.gu(1.5)
1189- }
1190- elide: Text.ElideRight
1191- fontSize: "x-small"
1192- height: units.gu(1)
1193- text: i18n.tr("%1 song", "%1 songs", playlist.count).arg(playlist.count)
1194- }
1195- // playlist name
1196- Label {
1197- id: playlistName
1198- anchors {
1199- top: playlistCount.bottom
1200- left: playlistCount.left
1201- right: expandItem.left
1202- topMargin: units.gu(1)
1203- rightMargin: units.gu(1.5)
1204- }
1205- wrapMode: Text.NoWrap
1206- maximumLineCount: 1
1207- fontSize: "medium"
1208- color: styleMusic.common.music
1209- elide: Text.ElideRight
1210- text: playlist.name
1211- }
1212-
1213- //Icon {
1214- Image {
1215- id: expandItem
1216- // name: "dropdown-menu"
1217- source: expandable.visible ? "images/dropdown-menu-up.svg" : "images/dropdown-menu.svg"
1218- anchors.right: parent.right
1219- anchors.rightMargin: units.gu(2)
1220- height: styleMusic.common.expandedItem
1221- width: styleMusic.common.expandedItem
1222- y: parent.y + (styleMusic.playlist.playlistItemHeight / 2) - (height / 2)
1223- }
1224-
1225- MouseArea {
1226- anchors.bottom: parent.bottom
1227- anchors.right: parent.right
1228- anchors.top: parent.top
1229- width: styleMusic.common.expandedItem * 3
1230- onClicked: {
1231- if(expandable.visible) {
1232- customdebug("clicked collapse")
1233- expandable.visible = false
1234- playlist.height = styleMusic.playlist.playlistItemHeight
1235- }
1236- else {
1237- customdebug("clicked expand")
1238- collapseExpand(-1); // collapse all others
1239- expandable.visible = true
1240- playlist.height = styleMusic.playlists.expandedHeight
1241- }
1242- }
1243- }
1244-
1245- Rectangle {
1246- id: expandable
1247- anchors.fill: parent
1248- color: "transparent"
1249- height: styleMusic.common.expandHeight
1250- visible: false
1251-
1252- Component.onCompleted: {
1253- collapseExpand.connect(onCollapseExpand);
1254- }
1255-
1256- function onCollapseExpand(indexCol)
1257- {
1258- if ((indexCol === index || indexCol === -1) && expandable !== undefined && expandable.visible === true)
1259- {
1260- customdebug("auto collapse")
1261- expandable.visible = false
1262- playlist.height = styleMusic.playlist.playlistItemHeight
1263- }
1264- }
1265-
1266- // background for expander
1267- Rectangle {
1268- anchors.top: parent.top
1269- anchors.topMargin: styleMusic.playlist.playlistItemHeight
1270- color: styleMusic.common.black
1271- height: styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight
1272- width: playlist.width
1273- opacity: 0.4
1274- }
1275-
1276- Rectangle {
1277- id: editColumn
1278- anchors.top: parent.top
1279- anchors.topMargin: ((styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight) / 2)
1280- + styleMusic.playlist.playlistItemHeight
1281- - (height / 2)
1282- anchors.left: parent.left
1283- anchors.leftMargin: styleMusic.common.expandedLeftMargin
1284- height: styleMusic.common.expandedItem
1285- Rectangle {
1286- color: "transparent"
1287- height: styleMusic.common.expandedItem
1288- width: units.gu(15)
1289- Icon {
1290- id: editPlaylist
1291- color: styleMusic.common.white
1292- name: "edit"
1293- height: styleMusic.common.expandedItem
1294- width: styleMusic.common.expandedItem
1295- }
1296- Label {
1297- anchors.left: editPlaylist.right
1298- anchors.leftMargin: units.gu(0.5)
1299- color: styleMusic.common.white
1300- fontSize: "small"
1301- // TRANSLATORS: this refers to editing a playlist
1302- text: i18n.tr("Edit")
1303- }
1304- MouseArea {
1305- anchors.fill: parent
1306- onClicked: {
1307- expandable.visible = false
1308- playlist.height = styleMusic.playlist.playlistItemHeight
1309- customdebug("Edit playlist")
1310- oldPlaylistName = name
1311- oldPlaylistID = id
1312- oldPlaylistIndex = index
1313- PopupUtils.open(editPlaylistDialog, mainView)
1314- }
1315- }
1316- }
1317- }
1318-
1319- Rectangle {
1320- id: deleteColumn
1321- anchors.top: parent.top
1322- anchors.topMargin: ((styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight) / 2)
1323- + styleMusic.playlist.playlistItemHeight
1324- - (height / 2)
1325- anchors.horizontalCenter: parent.horizontalCenter
1326- height: styleMusic.common.expandedItem
1327- Rectangle {
1328- color: "transparent"
1329- height: styleMusic.common.expandedItem
1330- width: units.gu(15)
1331- Icon {
1332- id: deletePlaylist
1333- color: styleMusic.common.white
1334- name: "delete"
1335- height: styleMusic.common.expandedItem
1336- width: styleMusic.common.expandedItem
1337- }
1338- Label {
1339- anchors.left: deletePlaylist.right
1340- anchors.leftMargin: units.gu(0.5)
1341- color: styleMusic.common.white
1342- fontSize: "small"
1343- // TRANSLATORS: this refers to deleting a playlist
1344- text: i18n.tr("Delete")
1345- }
1346- MouseArea {
1347- anchors.fill: parent
1348- onClicked: {
1349- expandable.visible = false
1350- playlist.height = styleMusic.playlist.playlistItemHeight
1351- customdebug("Delete")
1352- oldPlaylistName = name
1353- oldPlaylistID = id
1354- oldPlaylistIndex = index
1355- PopupUtils.open(removePlaylistDialog, mainView)
1356- }
1357- }
1358- }
1359- }
1360- // share
1361- Rectangle {
1362- id: shareColumn
1363- anchors.top: parent.top
1364- anchors.topMargin: ((styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight) / 2)
1365- + styleMusic.playlist.playlistItemHeight
1366- - (height / 2)
1367- anchors.left: deleteColumn.right
1368- anchors.leftMargin: units.gu(2)
1369- anchors.right: parent.right
1370- visible: false
1371- Rectangle {
1372- color: "transparent"
1373- height: styleMusic.common.expandedItem
1374- width: units.gu(15)
1375- Icon {
1376- id: sharePlaylist
1377- color: styleMusic.common.white
1378- name: "share"
1379- height: styleMusic.common.expandedItem
1380- width: styleMusic.common.expandedItem
1381- }
1382- Label {
1383- anchors.left: sharePlaylist.right
1384- anchors.leftMargin: units.gu(0.5)
1385- color: styleMusic.common.white
1386- fontSize: "small"
1387- // TRANSLATORS: this refers to sharing a playlist
1388- text: i18n.tr("Share")
1389- }
1390- MouseArea {
1391- anchors.fill: parent
1392- onClicked: {
1393- expandable.visible = false
1394- playlist.height = styleMusic.playlist.playlistItemHeight
1395- customdebug("Share")
1396- inPlaylist = true
1397- }
1398- }
1399- }
1400- }
1401- }
1402-
1403+ ListView {
1404+ id: playlistslist
1405+ objectName: "playlistslist"
1406+ anchors.fill: parent
1407+ anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
1408+ model: playlistModel.model
1409+ delegate: playlistDelegate
1410+ onCountChanged: {
1411+ customdebug("onCountChanged: " + playlistslist.count)
1412+ }
1413+ onCurrentIndexChanged: {
1414+ customdebug("tracklist.currentIndex = " + playlistslist.currentIndex)
1415+ }
1416+
1417+ Component {
1418+ id: playlistDelegate
1419+ ListItem.Standard {
1420+ id: playlist
1421+ property string name: model.name
1422+ property string count: model.count
1423+ property string cover0: model.cover0 || ""
1424+ property string cover1: model.cover1 || ""
1425+ property string cover2: model.cover2 || ""
1426+ property string cover3: model.cover3 || ""
1427+ iconFrame: false
1428+ height: styleMusic.playlist.playlistItemHeight
1429+
1430+ CoverRow {
1431+ id: coverRow
1432+ anchors {
1433+ top: parent.top
1434+ left: parent.left
1435+ margins: units.gu(1)
1436+ }
1437+ count: parseInt(playlist.count)
1438+ size: styleMusic.playlist.playlistAlbumSize
1439+ covers: [playlist.cover0, playlist.cover1, playlist.cover2, playlist.cover3]
1440+ }
1441+
1442+ // songs count
1443+ Label {
1444+ id: playlistCount
1445+ anchors {
1446+ top: parent.top
1447+ left: parent.left
1448+ right: expandItem.left
1449+ topMargin: units.gu(2)
1450+ leftMargin: units.gu(12)
1451+ rightMargin: units.gu(1.5)
1452+ }
1453+ elide: Text.ElideRight
1454+ fontSize: "x-small"
1455+ height: units.gu(1)
1456+ text: i18n.tr("%1 song", "%1 songs", playlist.count).arg(playlist.count)
1457+ }
1458+ // playlist name
1459+ Label {
1460+ id: playlistName
1461+ anchors {
1462+ top: playlistCount.bottom
1463+ left: playlistCount.left
1464+ right: expandItem.left
1465+ topMargin: units.gu(1)
1466+ rightMargin: units.gu(1.5)
1467+ }
1468+ wrapMode: Text.NoWrap
1469+ maximumLineCount: 1
1470+ fontSize: "medium"
1471+ color: styleMusic.common.music
1472+ elide: Text.ElideRight
1473+ text: playlist.name
1474+ }
1475+
1476+ //Icon {
1477+ Image {
1478+ id: expandItem
1479+ // name: "dropdown-menu"
1480+ source: expandable.visible ? "images/dropdown-menu-up.svg" : "images/dropdown-menu.svg"
1481+ anchors.right: parent.right
1482+ anchors.rightMargin: units.gu(2)
1483+ height: styleMusic.common.expandedItem
1484+ width: styleMusic.common.expandedItem
1485+ y: parent.y + (styleMusic.playlist.playlistItemHeight / 2) - (height / 2)
1486+ }
1487+
1488+ MouseArea {
1489+ anchors.bottom: parent.bottom
1490+ anchors.right: parent.right
1491+ anchors.top: parent.top
1492+ width: styleMusic.common.expandedItem * 3
1493 onClicked: {
1494- customdebug("Playlist chosen: " + name)
1495- expandable.visible = false
1496- playlist.height = styleMusic.playlist.playlistItemHeight
1497- playlisttracksModel.filterPlaylistTracks(name)
1498- playlistlist.playlistName = name
1499- pageStack.push(playlistpage) // show the chosen playlists content
1500- playlistpage.title = name + " " + "("+ count +")" // change name of the tab
1501- // for removal or edit in playlist
1502- oldPlaylistName = name
1503- oldPlaylistID = id
1504- oldPlaylistIndex = index
1505- expandable.visible = false
1506- playlistInfo.count = playlist.count
1507- playlistInfo.cover0 = playlist.cover0
1508- playlistInfo.cover1 = playlist.cover1
1509- playlistInfo.cover2 = playlist.cover2
1510- playlistInfo.cover3 = playlist.cover3
1511- }
1512- }
1513- }
1514- }
1515- }
1516-
1517- // page for the tracks in the playlist
1518- Page {
1519- id: playlistpage
1520- title: i18n.tr("Playlist")
1521- tools: null
1522- visible: false
1523-
1524- onVisibleChanged: {
1525- if (visible === true)
1526- {
1527- musicToolbar.setPage(playlistpage, listspage, pageStack);
1528- }
1529- else
1530- {
1531- collapseSwipeDelete(-1); // collapse all expands
1532- }
1533- }
1534-
1535- // playlist name and info
1536- Rectangle {
1537- id: playlistInfo
1538- anchors.top: parent.top
1539- width: parent.width
1540- height: styleMusic.playlist.infoHeight
1541- color: styleMusic.playerControls.backgroundColor
1542- //opacity: 0.7
1543-
1544- property int count: 0
1545- property string cover0: ""
1546- property string cover1: ""
1547- property string cover2: ""
1548- property string cover3: ""
1549-
1550- CoverRow {
1551- id: coverRow2
1552- anchors {
1553- top: parent.top
1554- left: parent.left
1555- margins: units.gu(2)
1556- }
1557- count: playlistInfo.count
1558- size: styleMusic.common.albumSize
1559- covers: [playlistInfo.cover0, playlistInfo.cover1, playlistInfo.cover2, playlistInfo.cover3]
1560- }
1561-
1562- Label {
1563- id: playlistInfoLabel
1564- anchors {
1565- top: parent.top
1566- left: parent.left
1567- right: expandInfoItem.left
1568- topMargin: units.gu(2.5)
1569- leftMargin: units.gu(14)
1570- rightMargin: units.gu(1.5)
1571- }
1572- text: playlistlist.playlistName
1573- color: styleMusic.common.white
1574- fontSize: "large"
1575- elide: Text.ElideRight
1576- }
1577-
1578- Label {
1579- id: playlistInfoCount
1580- anchors {
1581- top: playlistInfoLabel.bottom
1582- left: playlistInfoLabel.left
1583- right: expandInfoItem.left
1584- topMargin: units.gu(1)
1585- rightMargin: units.gu(1.5)
1586- }
1587- text: i18n.tr("%1 song", "%1 songs", playlist.count).arg(playlist.count)
1588- color: styleMusic.common.white
1589- fontSize: "medium"
1590- elide: Text.ElideRight
1591- }
1592-
1593- //Icon { use for 1.0
1594- Image {
1595- id: expandInfoItem
1596- anchors.right: parent.right
1597- anchors.rightMargin: units.gu(2)
1598- //name: "dropdown-menu" use for 1.0
1599- source: expandableInfo.visible ? "images/dropdown-menu-up.svg" : "images/dropdown-menu.svg"
1600- height: styleMusic.common.expandedItem
1601- width: styleMusic.common.expandedItem
1602- y: parent.y + (styleMusic.playlist.infoHeight / 2) - (height / 2)
1603- }
1604-
1605- MouseArea {
1606- anchors.bottom: parent.bottom
1607- anchors.right: parent.right
1608- anchors.top: parent.top
1609- width: styleMusic.common.expandedItem * 3
1610- onClicked: {
1611- if(expandableInfo.visible) {
1612- customdebug("clicked collapse")
1613- expandableInfo.visible = false
1614- playlistInfo.height = styleMusic.playlist.infoHeight
1615-
1616- }
1617- else {
1618- customdebug("clicked expand")
1619- expandableInfo.visible = true
1620- playlistInfo.height = styleMusic.playlist.expandedHeight
1621- }
1622- }
1623- }
1624-
1625- Rectangle {
1626- id: expandableInfo
1627- anchors.fill: parent
1628- color: "transparent"
1629- height: styleMusic.common.expandHeight
1630- visible: false
1631- Rectangle {
1632- id: editColumn
1633- anchors.top: parent.top
1634- anchors.topMargin: styleMusic.common.expandedTopMargin
1635- anchors.left: parent.left
1636- anchors.leftMargin: styleMusic.common.expandedLeftMargin
1637- color: "transparent"
1638- Rectangle {
1639- id: editRow
1640- color: "transparent"
1641- height: styleMusic.common.expandedItem
1642- width: units.gu(15)
1643- Icon {
1644- id: editPlaylist
1645- name: "edit"
1646- height: styleMusic.common.expandedItem
1647- width: styleMusic.common.expandedItem
1648- }
1649- Label {
1650- text: i18n.tr("Edit")
1651- fontSize: "small"
1652- wrapMode: Text.WordWrap
1653- anchors.left: editPlaylist.right
1654- anchors.leftMargin: units.gu(0.5)
1655- }
1656- MouseArea {
1657- anchors.fill: parent
1658- onClicked: {
1659- expandableInfo.visible = false
1660- playlistInfo.height = styleMusic.playlist.infoHeight
1661- customdebug("Edit playlist")
1662- inPlaylist = true
1663- PopupUtils.open(editPlaylistDialog, mainView)
1664- }
1665- }
1666- }
1667- }
1668-
1669- Rectangle {
1670- id: deleteColumn
1671- anchors.horizontalCenter: parent.horizontalCenter
1672- anchors.top: parent.top
1673- anchors.topMargin: styleMusic.common.expandedTopMargin
1674- color: "transparent"
1675- Rectangle {
1676- id: deleteRow
1677- color: "transparent"
1678- height: styleMusic.common.expandedItem
1679- width: units.gu(15)
1680- Icon {
1681- id: deletePlaylist
1682- name: "delete"
1683- height: styleMusic.common.expandedItem
1684- width: styleMusic.common.expandedItem
1685- }
1686- Label {
1687- text: i18n.tr("Delete")
1688- fontSize: "small"
1689- anchors.left: deletePlaylist.right
1690- anchors.leftMargin: units.gu(0.5)
1691- }
1692- MouseArea {
1693- anchors.fill: parent
1694- onClicked: {
1695- expandableInfo.visible = false
1696- playlistInfo.height = styleMusic.playlist.infoHeight
1697- customdebug("Delete")
1698- inPlaylist = true
1699- PopupUtils.open(removePlaylistDialog, mainView)
1700- }
1701- }
1702- }
1703- }
1704- // share
1705- Rectangle {
1706- id: shareColumn
1707- anchors.top: parent.top
1708- anchors.topMargin: styleMusic.common.expandedTopMargin
1709- anchors.left: deleteColumn.right
1710- anchors.leftMargin: units.gu(2)
1711- anchors.right: parent.right
1712- color: "transparent"
1713+ if(expandable.visible) {
1714+ customdebug("clicked collapse")
1715+ expandable.visible = false
1716+ playlist.height = styleMusic.playlist.playlistItemHeight
1717+ }
1718+ else {
1719+ customdebug("clicked expand")
1720+ collapseExpand(-1); // collapse all others
1721+ expandable.visible = true
1722+ playlist.height = styleMusic.playlists.expandedHeight
1723+ }
1724+ }
1725+ }
1726+
1727+ Rectangle {
1728+ id: expandable
1729+ anchors.fill: parent
1730+ color: "transparent"
1731+ height: styleMusic.common.expandHeight
1732 visible: false
1733- Rectangle {
1734- id: shareRow
1735- color: "transparent"
1736- height: styleMusic.common.expandedItem
1737- width: units.gu(15)
1738- Icon {
1739- id: sharePlaylist
1740- name: "share"
1741- height: styleMusic.common.expandedItem
1742- width: styleMusic.common.expandedItem
1743- }
1744- Label {
1745- text: i18n.tr("Share")
1746- fontSize: "small"
1747- anchors.left: sharePlaylist.right
1748- anchors.leftMargin: units.gu(0.5)
1749- }
1750- MouseArea {
1751- anchors.fill: parent
1752- onClicked: {
1753- expandableInfo.visible = false
1754- playlistInfo.height = styleMusic.playlist.infoHeight
1755- customdebug("Share")
1756- inPlaylist = true
1757- }
1758- }
1759- }
1760- }
1761- }
1762- }
1763-
1764- ListView {
1765- id: playlistlist
1766- anchors.bottom: parent.bottom
1767- anchors.top: playlistInfo.bottom
1768- width: parent.width
1769- anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
1770- highlightFollowsCurrentItem: false
1771- model: playlisttracksModel.model
1772- delegate: playlisttrackDelegate
1773- state: "normal"
1774- z: -1
1775- states: [
1776- State {
1777- name: "normal"
1778- PropertyChanges {
1779- target: playlistlist
1780- interactive: true
1781- }
1782- },
1783- State {
1784- name: "reorder"
1785- PropertyChanges {
1786- target: playlistlist
1787- interactive: false
1788- }
1789- }
1790- ]
1791-
1792- onCountChanged: {
1793- console.log("Tracks in playlist onCountChanged: " + playlistlist.count)
1794- playlistlist.currentIndex = playlisttracksModel.indexOf(currentFile)
1795- }
1796- onCurrentIndexChanged: {
1797- console.log("Tracks in playlist tracklist.currentIndex = " + playlistlist.currentIndex)
1798- }
1799-
1800- property int normalHeight: styleMusic.common.itemHeight
1801- property string playlistName: ""
1802- property int transitionDuration: 250
1803-
1804- Component {
1805- id: playlisttrackDelegate
1806- ListItem.Standard {
1807- id: playlistTracks
1808- property string artist: model.artist
1809- property string album: model.album
1810- property string title: model.title
1811- property string cover: model.cover
1812- property string length: model.length
1813- property string file: model.file
1814- height: playlistlist.normalHeight
1815-
1816- SwipeDelete {
1817- id: swipeBackground
1818- duration: playlistlist.transitionDuration
1819-
1820- onDeleteStateChanged: {
1821- if (deleteState === true)
1822- {
1823- playlistTracksRemoveAnimation.start();
1824- }
1825- }
1826- }
1827-
1828- function onCollapseSwipeDelete(indexCol)
1829+
1830+ Component.onCompleted: {
1831+ collapseExpand.connect(onCollapseExpand);
1832+ }
1833+
1834+ function onCollapseExpand(indexCol)
1835 {
1836- if ((indexCol !== index || indexCol === -1) && swipeBackground !== undefined && swipeBackground.direction !== "")
1837- {
1838- customdebug("auto collapse swipeDelete")
1839- playlistTracksResetStartAnimation.start();
1840- }
1841- }
1842-
1843- Component.onCompleted: {
1844- collapseSwipeDelete.connect(onCollapseSwipeDelete);
1845- }
1846-
1847- MouseArea {
1848- id: playlistTrackArea
1849- anchors.fill: parent
1850-
1851- property int startX: playlistTracks.x
1852- property int startY: playlistTracks.y
1853- property int startMouseY: -1
1854-
1855- // Allow dragging on the X axis for swipeDelete if not reordering
1856- drag.target: playlistTracks
1857- drag.axis: Drag.XAxis
1858- drag.minimumX: playlistlist.state == "reorder" ? 0 : -playlistTracks.width
1859- drag.maximumX: playlistlist.state == "reorder" ? 0 : playlistTracks.width
1860-
1861- /* Get the mouse and item difference from the starting positions */
1862- function getDiff(mouseY)
1863- {
1864- return (mouseY - startMouseY) + (playlistTracks.y - startY);
1865- }
1866-
1867- function getNewIndex(mouseY, index)
1868- {
1869- var diff = getDiff(mouseY);
1870- var negPos = diff < 0 ? -1 : 1;
1871-
1872- return index + (Math.round(diff / playlistlist.normalHeight));
1873- }
1874-
1875- onClicked: {
1876- collapseSwipeDelete(-1); // collapse all expands
1877- customdebug("File: " + file) // debugger
1878- trackClicked(playlisttracksModel, index) // play track
1879- Library.addRecent(oldPlaylistName, "Playlist", cover, oldPlaylistName, "playlist")
1880- mainView.hasRecent = true
1881- recentModel.filterRecent()
1882- }
1883-
1884- onMouseXChanged: {
1885- // Only allow XChange if not in reorder state
1886- if (playlistlist.state == "reorder")
1887- {
1888- return;
1889- }
1890-
1891- // New X is less than start so swiping left
1892- if (playlistTracks.x < startX)
1893- {
1894- swipeBackground.state = "swipingLeft";
1895- }
1896- // New X is greater sow swiping right
1897- else if (playlistTracks.x > startX)
1898- {
1899- swipeBackground.state = "swipingRight";
1900- }
1901- // Same so reset state back to normal
1902- else
1903- {
1904- swipeBackground.state = "normal";
1905- playlistlist.state = "normal";
1906- }
1907- }
1908-
1909- onMouseYChanged: {
1910- // Y change only affects when in reorder mode
1911- if (playlistlist.state == "reorder")
1912- {
1913- /* update the listitem y position so that the
1914- * listitem horizontalCenter is under the mouse.y */
1915- playlistTracks.y += mouse.y - (playlistTracks.height / 2);
1916- }
1917- }
1918-
1919- onPressed: {
1920- startX = playlistTracks.x;
1921- startY = playlistTracks.y;
1922- startMouseY = mouse.y;
1923- }
1924-
1925- onPressAndHold: {
1926- collapseSwipeDelete(-1); // collapse all expands
1927- customdebug("Pressed and held track playlist "+file)
1928- playlistlist.state = "reorder"; // enable reordering state
1929- trackContainerReorderAnimation.start();
1930- //PopupUtils.open(playlistPopoverComponent, mainView)
1931- }
1932-
1933- onReleased: {
1934- // Get current state to determine what to do
1935- if (playlistlist.state == "reorder")
1936- {
1937- var newIndex = getNewIndex(mouse.y + (playlistTracks.height / 2), index); // get new index
1938-
1939- // Indexes larger than current need -1 because when it is moved the current is removed
1940- if (newIndex > index)
1941- {
1942- newIndex -= 1;
1943- }
1944-
1945- if (newIndex === index)
1946- {
1947- playlistTracksResetAnimation.start(); // reset item position
1948- trackContainerResetAnimation.start(); // reset the trackContainer
1949- }
1950- else
1951- {
1952- playlistTracks.x = startX; // ensure X position is correct
1953- trackContainerResetAnimation.start(); // reset the trackContainer
1954-
1955- // Check that the newIndex is within the range
1956- if (newIndex < 0)
1957- {
1958- newIndex = 0;
1959- }
1960- else if (newIndex > playlistlist.count - 1)
1961- {
1962- newIndex = playlistlist.count - 1;
1963- }
1964-
1965- console.debug("Move: " + index + " To: " + newIndex);
1966-
1967- // get the real IDs and update the database
1968- var realID = Playlists.getRealID(playlistlist.playlistName, index);
1969- var realNewID = Playlists.getRealID(playlistlist.playlistName, newIndex);
1970- Playlists.move(playlistlist.playlistName, realID, realNewID);
1971-
1972- playlistlist.model.move(index, newIndex, 1); // update the model
1973- queueChanged = true;
1974- }
1975- }
1976- else if (swipeBackground.state == "swipingLeft" || swipeBackground.state == "swipingRight")
1977- {
1978- var moved = Math.abs(playlistTracks.x - startX);
1979-
1980- // Make sure that item has been dragged far enough
1981- if (moved > playlistTracks.width / 2 || (swipeBackground.primed === true && moved > units.gu(5)))
1982- {
1983- if (swipeBackground.primed === false)
1984- {
1985- collapseSwipeDelete(index); // collapse other swipeDeletes
1986-
1987- // Move the listitem half way across to reveal the delete button
1988- playlistTracksPrepareRemoveAnimation.start();
1989- }
1990- else
1991- {
1992- // Check that actually swiping to cancel
1993- if (swipeBackground.direction !== "" &&
1994- swipeBackground.direction !== swipeBackground.state)
1995- {
1996- // Reset the listitem to the centre
1997- playlistTracksResetStartAnimation.start();
1998- }
1999- else
2000- {
2001- // Reset the listitem to the centre
2002- playlistTracksResetAnimation.start();
2003- }
2004- }
2005- }
2006- else
2007- {
2008- // Reset the listitem to the centre
2009- playlistTracksResetAnimation.start();
2010- }
2011- }
2012-
2013- // ensure states are normal
2014- swipeBackground.state = "normal";
2015- playlistlist.state = "normal";
2016- }
2017-
2018- // Animation to reset the x, y of the item
2019- ParallelAnimation {
2020- id: playlistTracksResetAnimation
2021- running: false
2022- NumberAnimation { // reset X
2023- target: playlistTracks
2024- property: "x"
2025- to: playlistTrackArea.startX
2026- duration: playlistlist.transitionDuration
2027- }
2028- NumberAnimation { // reset Y
2029- target: playlistTracks
2030- property: "y"
2031- to: playlistTrackArea.startY
2032- duration: playlistlist.transitionDuration
2033- }
2034- }
2035-
2036- // Animation to reset the x, y of the item
2037- ParallelAnimation {
2038- id: playlistTracksResetStartAnimation
2039- running: false
2040- NumberAnimation { // reset X
2041- target: playlistTracks
2042- property: "x"
2043- to: 0
2044- duration: playlistlist.transitionDuration
2045- }
2046- NumberAnimation { // reset Y
2047- target: playlistTracks
2048- property: "y"
2049- to: playlistTrackArea.startY
2050- duration: playlistlist.transitionDuration
2051- }
2052- onRunningChanged: {
2053- if (running === true)
2054- {
2055- swipeBackground.direction = "";
2056- swipeBackground.primed = false;
2057- }
2058- }
2059- }
2060-
2061- // Move the listitem half way across to reveal the delete button
2062- NumberAnimation {
2063- id: playlistTracksPrepareRemoveAnimation
2064- target: playlistTracks
2065- property: "x"
2066- to: swipeBackground.state == "swipingRight" ? playlistTracks.width / 2 : 0 - (playlistTracks.width / 2)
2067- duration: playlistlist.transitionDuration
2068- onRunningChanged: {
2069- if (running === true)
2070- {
2071- swipeBackground.direction = swipeBackground.state;
2072- swipeBackground.primed = true;
2073- }
2074- }
2075- }
2076-
2077- ParallelAnimation {
2078- id: playlistTracksRemoveAnimation
2079- running: false
2080- NumberAnimation { // 'slide' up
2081- target: playlistTracks
2082- property: "height"
2083- to: 0
2084- duration: playlistlist.transitionDuration
2085- }
2086- NumberAnimation { // 'slide' in direction of removal
2087- target: playlistTracks
2088- property: "x"
2089- to: swipeBackground.direction === "swipingLeft" ? 0 - playlistTracks.width : playlistTracks.width
2090- duration: playlistlist.transitionDuration
2091- }
2092- onRunningChanged: {
2093- if (running === false)
2094- {
2095- console.debug("Remove from playlist: " + playlistlist.playlistName + " file: " + file);
2096-
2097- var realID = Playlists.getRealID(playlistlist.playlistName, index);
2098- Playlists.removeFromPlaylist(playlistlist.playlistName, realID);
2099-
2100- playlistlist.model.remove(index);
2101- playlistModel.model.get(oldPlaylistIndex).count -= 1;
2102- queueChanged = true;
2103- }
2104- }
2105- }
2106- }
2107- Rectangle {
2108- id: trackContainer;
2109- anchors.fill: parent
2110- anchors.margins: units.gu(1)
2111- color: "transparent"
2112-
2113- NumberAnimation {
2114- id: trackContainerReorderAnimation
2115- target: trackContainer;
2116- property: "anchors.leftMargin";
2117- duration: playlistlist.transitionDuration;
2118- to: units.gu(2)
2119- }
2120-
2121- NumberAnimation {
2122- id: trackContainerResetAnimation
2123- target: trackContainer;
2124- property: "anchors.leftMargin";
2125- duration: playlistlist.transitionDuration;
2126- to: units.gu(0.5)
2127- }
2128-
2129- UbuntuShape {
2130- id: trackCover
2131- anchors.left: parent.left
2132- anchors.leftMargin: units.gu(1)
2133- anchors.top: parent.top
2134- anchors.verticalCenter: parent.verticalCenter
2135- width: styleMusic.common.albumSize
2136- height: styleMusic.common.albumSize
2137- image: Image {
2138- source: cover !== "" ? cover : Qt.resolvedUrl("images/cover_default_icon.png")
2139- }
2140- UbuntuShape { // Background so can see text in current state
2141- id: trackBg
2142- anchors.top: parent.top
2143- color: styleMusic.common.black
2144- width: styleMusic.common.albumSize
2145- height: styleMusic.common.albumSize
2146- opacity: 0
2147- }
2148- }
2149-
2150- Label {
2151- id: trackArtist
2152- wrapMode: Text.NoWrap
2153- maximumLineCount: 2
2154- fontSize: "x-small"
2155- anchors.left: trackCover.left
2156- anchors.leftMargin: units.gu(11)
2157- anchors.top: parent.top
2158- anchors.topMargin: units.gu(1)
2159- anchors.right: parent.right
2160- anchors.rightMargin: units.gu(1.5)
2161- elide: Text.ElideRight
2162- text: playlistTracks.artist
2163- }
2164- Label {
2165- id: trackTitle
2166- wrapMode: Text.NoWrap
2167- maximumLineCount: 1
2168- fontSize: "small"
2169- color: styleMusic.common.music
2170- anchors.left: trackCover.left
2171- anchors.leftMargin: units.gu(11)
2172- anchors.top: trackArtist.bottom
2173- anchors.topMargin: units.gu(1)
2174- anchors.right: parent.right
2175- anchors.rightMargin: units.gu(1.5)
2176- elide: Text.ElideRight
2177- text: playlistTracks.title
2178- }
2179- Label {
2180- id: trackAlbum
2181- wrapMode: Text.NoWrap
2182- maximumLineCount: 2
2183- fontSize: "xx-small"
2184- anchors.left: trackCover.left
2185- anchors.leftMargin: units.gu(11)
2186- anchors.top: trackTitle.bottom
2187- anchors.topMargin: units.gu(2)
2188- anchors.right: parent.right
2189- anchors.rightMargin: units.gu(1.5)
2190- elide: Text.ElideRight
2191- text: playlistTracks.album
2192- }
2193- Label {
2194- id: trackDuration
2195- wrapMode: Text.NoWrap
2196- maximumLineCount: 2
2197- fontSize: "small"
2198- color: styleMusic.common.music
2199- anchors.left: trackCover.left
2200- anchors.leftMargin: units.gu(12)
2201- anchors.top: trackAlbum.bottom
2202- anchors.right: parent.right
2203- anchors.rightMargin: units.gu(1.5)
2204- elide: Text.ElideRight
2205- visible: false
2206- text: ""
2207- }
2208- states: State {
2209- name: "Current"
2210- when: playlistTracks.ListView.isCurrentItem
2211- }
2212- Image {
2213- visible: false // activate when cover art stops expanding togehter with the row
2214- id: expandItem
2215- anchors.right: parent.right
2216- anchors.rightMargin: units.gu(2)
2217- anchors.top: parent.top
2218- anchors.topMargin: units.gu(4)
2219- source: "images/select.png"
2220- height: styleMusic.common.expandedItem
2221- width: styleMusic.common.expandedItem
2222-
2223- MouseArea {
2224- anchors.fill: parent
2225- onClicked: {
2226- if(expandable.visible) {
2227- customdebug("clicked collapse")
2228- expandable.visible = false
2229- playlistTracks.height = styleMusic.common.itemHeight
2230-
2231- }
2232- else {
2233- customdebug("clicked expand")
2234- expandable.visible = true
2235- playlistTracks.height = styleMusic.common.expandedHeight
2236- }
2237- }
2238- }
2239- }
2240-
2241- Rectangle {
2242- id: expandable
2243- visible: false
2244- width: parent.fill
2245- height: styleMusic.common.expandHeight
2246- MouseArea {
2247- anchors.fill: parent
2248- onClicked: {
2249- customdebug("User pressed outside the playlist item and expanded items.")
2250- }
2251- }
2252- }
2253- }
2254+ if ((indexCol === index || indexCol === -1) && expandable !== undefined && expandable.visible === true)
2255+ {
2256+ customdebug("auto collapse")
2257+ expandable.visible = false
2258+ playlist.height = styleMusic.playlist.playlistItemHeight
2259+ }
2260+ }
2261+
2262+ // background for expander
2263+ Rectangle {
2264+ anchors.top: parent.top
2265+ anchors.topMargin: styleMusic.playlist.playlistItemHeight
2266+ color: styleMusic.common.black
2267+ height: styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight
2268+ width: playlist.width
2269+ opacity: 0.4
2270+ }
2271+
2272+ Rectangle {
2273+ id: editColumn
2274+ anchors.top: parent.top
2275+ anchors.topMargin: ((styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight) / 2)
2276+ + styleMusic.playlist.playlistItemHeight
2277+ - (height / 2)
2278+ anchors.left: parent.left
2279+ anchors.leftMargin: styleMusic.common.expandedLeftMargin
2280+ height: styleMusic.common.expandedItem
2281+ Rectangle {
2282+ color: "transparent"
2283+ height: styleMusic.common.expandedItem
2284+ width: units.gu(15)
2285+ Icon {
2286+ id: editPlaylist
2287+ color: styleMusic.common.white
2288+ name: "edit"
2289+ height: styleMusic.common.expandedItem
2290+ width: styleMusic.common.expandedItem
2291+ }
2292+ Label {
2293+ anchors.left: editPlaylist.right
2294+ anchors.leftMargin: units.gu(0.5)
2295+ color: styleMusic.common.white
2296+ fontSize: "small"
2297+ // TRANSLATORS: this refers to editing a playlist
2298+ text: i18n.tr("Edit")
2299+ }
2300+ MouseArea {
2301+ anchors.fill: parent
2302+ onClicked: {
2303+ expandable.visible = false
2304+ playlist.height = styleMusic.playlist.playlistItemHeight
2305+ customdebug("Edit playlist")
2306+ oldPlaylistName = name
2307+ oldPlaylistID = id
2308+ oldPlaylistIndex = index
2309+ PopupUtils.open(editPlaylistDialog, mainView)
2310+ }
2311+ }
2312+ }
2313+ }
2314+
2315+ Rectangle {
2316+ id: deleteColumn
2317+ anchors.top: parent.top
2318+ anchors.topMargin: ((styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight) / 2)
2319+ + styleMusic.playlist.playlistItemHeight
2320+ - (height / 2)
2321+ anchors.horizontalCenter: parent.horizontalCenter
2322+ height: styleMusic.common.expandedItem
2323+ Rectangle {
2324+ color: "transparent"
2325+ height: styleMusic.common.expandedItem
2326+ width: units.gu(15)
2327+ Icon {
2328+ id: deletePlaylist
2329+ color: styleMusic.common.white
2330+ name: "delete"
2331+ height: styleMusic.common.expandedItem
2332+ width: styleMusic.common.expandedItem
2333+ }
2334+ Label {
2335+ anchors.left: deletePlaylist.right
2336+ anchors.leftMargin: units.gu(0.5)
2337+ color: styleMusic.common.white
2338+ fontSize: "small"
2339+ // TRANSLATORS: this refers to deleting a playlist
2340+ text: i18n.tr("Delete")
2341+ }
2342+ MouseArea {
2343+ anchors.fill: parent
2344+ onClicked: {
2345+ expandable.visible = false
2346+ playlist.height = styleMusic.playlist.playlistItemHeight
2347+ customdebug("Delete")
2348+ oldPlaylistName = name
2349+ oldPlaylistID = id
2350+ oldPlaylistIndex = index
2351+ PopupUtils.open(removePlaylistDialog, mainView)
2352+ }
2353+ }
2354+ }
2355+ }
2356+ // share
2357+ Rectangle {
2358+ id: shareColumn
2359+ anchors.top: parent.top
2360+ anchors.topMargin: ((styleMusic.playlists.expandedHeight - styleMusic.playlist.playlistItemHeight) / 2)
2361+ + styleMusic.playlist.playlistItemHeight
2362+ - (height / 2)
2363+ anchors.left: deleteColumn.right
2364+ anchors.leftMargin: units.gu(2)
2365+ anchors.right: parent.right
2366+ visible: false
2367+ Rectangle {
2368+ color: "transparent"
2369+ height: styleMusic.common.expandedItem
2370+ width: units.gu(15)
2371+ Icon {
2372+ id: sharePlaylist
2373+ color: styleMusic.common.white
2374+ name: "share"
2375+ height: styleMusic.common.expandedItem
2376+ width: styleMusic.common.expandedItem
2377+ }
2378+ Label {
2379+ anchors.left: sharePlaylist.right
2380+ anchors.leftMargin: units.gu(0.5)
2381+ color: styleMusic.common.white
2382+ fontSize: "small"
2383+ // TRANSLATORS: this refers to sharing a playlist
2384+ text: i18n.tr("Share")
2385+ }
2386+ MouseArea {
2387+ anchors.fill: parent
2388+ onClicked: {
2389+ expandable.visible = false
2390+ playlist.height = styleMusic.playlist.playlistItemHeight
2391+ customdebug("Share")
2392+ inPlaylist = true
2393+ }
2394+ }
2395+ }
2396+ }
2397+ }
2398+
2399+ onClicked: {
2400+ albumTracksModel.filterPlaylistTracks(name)
2401+ songsSheet.isAlbum = false
2402+ songsSheet.line1 = "Playlist"
2403+ songsSheet.line2 = model.name
2404+ songsSheet.cover = playlist.cover0
2405+ PopupUtils.open(songsSheet.sheet)
2406 }
2407 }
2408 }
2409
2410=== modified file 'MusicStart.qml'
2411--- MusicStart.qml 2013-12-19 14:39:27 +0000
2412+++ MusicStart.qml 2014-01-12 22:19:24 +0000
2413@@ -97,6 +97,12 @@
2414 Component {
2415 id: recentDelegate
2416 Item {
2417+ property string title: model.title
2418+ property string title2: model.title2
2419+ property string cover: model.cover !== "" ? model.cover : "images/cover_default.png"
2420+ property string type: model.type
2421+ property string time: model.time
2422+ property string key: model.key
2423 id: recentItem
2424 height: units.gu(20)
2425 width: units.gu(20)
2426@@ -107,13 +113,7 @@
2427 image: Image {
2428 id: icon
2429 fillMode: Image.Stretch
2430- property string title: model.title
2431- property string title2: model.title2
2432- property string cover: model.cover
2433- property string type: model.type
2434- property string time: model.time
2435- property string key: model.key
2436- source: cover !== "" ? cover : "images/cover_default.png"
2437+ source: cover
2438 }
2439 }
2440 UbuntuShape { // Background so can see text in current state
2441@@ -160,32 +160,16 @@
2442 MouseArea {
2443 anchors.fill: parent
2444 onClicked: {
2445- if (type === "album") {
2446- recentAlbumTracksModel.filterAlbumTracks(key)
2447- trackQueue.model.clear()
2448- addQueueFromModel(recentAlbumTracksModel)
2449- currentModel = recentAlbumTracksModel
2450- currentQuery = recentAlbumTracksModel.query
2451- currentParam = recentAlbumTracksModel.param
2452- } else if (type === "playlist") {
2453- recentPlaylistTracksModel.filterPlaylistTracks(key)
2454- trackQueue.model.clear()
2455- addQueueFromModel(recentPlaylistTracksModel)
2456- currentModel = recentPlaylistTracksModel
2457- currentQuery = recentPlaylistTracksModel.query
2458- currentParam = recentPlaylistTracksModel.param
2459+ if (type === "playlist") {
2460+ albumTracksModel.filterPlaylistTracks(key)
2461+ } else {
2462+ albumTracksModel.filterAlbumTracks(title)
2463 }
2464- Library.addRecent(title, title2, cover, key, type)
2465- mainView.hasRecent = true
2466- recentModel.filterRecent()
2467- var file = trackQueue.model.get(0).file
2468- currentIndex = trackQueue.indexOf(file)
2469- queueChanged = true
2470- player.stop()
2471- player.source = Qt.resolvedUrl(file)
2472- player.play()
2473- nowPlaying.visible = true
2474- musicToolbar.showToolbar()
2475+ songsSheet.line1 = title2
2476+ songsSheet.line2 = title
2477+ songsSheet.cover = cover
2478+ PopupUtils.open(songsSheet.sheet)
2479+ songsSheet.isAlbum = (type === "album")
2480 }
2481 }
2482 }
2483@@ -220,6 +204,15 @@
2484 Component {
2485 id: genreDelegate
2486 Item {
2487+ property string artist: model.artist
2488+ property string album: model.album
2489+ property string title: model.title
2490+ property string cover: model.cover !== "" ? model.cover : "images/cover_default.png"
2491+ property string length: model.length
2492+ property string file: model.file
2493+ property string year: model.year
2494+ property string genre: model.genre
2495+
2496 id: genreItem
2497 objectName: "genreItemObject"
2498 height: units.gu(20)
2499@@ -231,34 +224,18 @@
2500 image: Image {
2501 id: icon
2502 fillMode: Image.Stretch
2503- property string artist: model.artist
2504- property string album: model.album
2505- property string title: model.title
2506- property string cover: model.cover
2507- property string length: model.length
2508- property string file: model.file
2509- property string year: model.year
2510- property string genre: model.genre
2511- source: cover !== "" ? cover : "images/cover_default.png"
2512+ source: cover
2513 }
2514 }
2515 MouseArea {
2516 anchors.fill: parent
2517 onClicked: {
2518- genreTracksModel.filterGenreTracks(genre)
2519- trackQueue.model.clear()
2520- addQueueFromModel(genreTracksModel)
2521- currentModel = genreTracksModel
2522- currentQuery = genreTracksModel.query
2523- currentParam = genreTracksModel.param
2524- var file = trackQueue.model.get(0).file
2525- currentIndex = trackQueue.indexOf(file)
2526- queueChanged = true
2527- player.stop()
2528- player.source = Qt.resolvedUrl(file)
2529- player.play()
2530- nowPlaying.visible = true
2531- musicToolbar.showToolbar();
2532+ albumTracksModel.filterGenreTracks(genre)
2533+ songsSheet.line1 = "Genre"
2534+ songsSheet.line2 = genre
2535+ songsSheet.isAlbum = false
2536+ songsSheet.cover = cover
2537+ PopupUtils.open(songsSheet.sheet)
2538 }
2539 }
2540 Rectangle { // Background so can see text in current state
2541@@ -299,7 +276,7 @@
2542 anchors.rightMargin: units.gu(1)
2543 color: styleMusic.nowPlaying.labelSecondaryColor
2544 elide: Text.ElideRight
2545- text: i18n.tr("%1 song", "%1 songs", model.total).arg(model.total)
2546+ text: i18n.tr("%1 song", "%1 songs", model.total).arg(model.total)
2547 fontSize: "x-small"
2548 }
2549 }
2550
2551=== modified file 'MusicToolbar.qml'
2552--- MusicToolbar.qml 2014-01-09 21:01:25 +0000
2553+++ MusicToolbar.qml 2014-01-12 22:19:24 +0000
2554@@ -463,37 +463,11 @@
2555 }
2556 }
2557
2558- /* Back button to go up pageStack */
2559- Item {
2560- id: playerControlBackButton
2561- anchors.left: parent.left
2562- anchors.leftMargin: units.gu(1)
2563- anchors.verticalCenter: parent.verticalCenter
2564- width: units.gu(6)
2565- height: width
2566- visible: currentPageStack !== null && currentParentPage !== null
2567-
2568- Image {
2569- height: units.gu(3)
2570- source: Qt.resolvedUrl("images/back.svg")
2571- width: height
2572- anchors.horizontalCenter: parent.horizontalCenter
2573- anchors.verticalCenter: parent.verticalCenter
2574- }
2575-
2576- MouseArea {
2577- anchors.fill: parent
2578- onClicked: {
2579- goBack();
2580- }
2581- }
2582- }
2583-
2584 /* Container holding the labels for the toolbar */
2585 Rectangle {
2586 id: playerControlLabelContainer
2587 anchors.bottom: parent.bottom
2588- anchors.left: playerControlBackButton.right
2589+ anchors.left: parent.left
2590 anchors.right: playerControlsPlayButton.left
2591 anchors.top: parent.top
2592 color: "transparent"
2593
2594=== added file 'common/AlbumsSheet.qml'
2595--- common/AlbumsSheet.qml 1970-01-01 00:00:00 +0000
2596+++ common/AlbumsSheet.qml 2014-01-12 22:19:24 +0000
2597@@ -0,0 +1,154 @@
2598+/*
2599+ * Copyright (C) 2013 Andrew Hayzen <ahayzen@gmail.com>
2600+ * Daniel Holm <d.holmen@gmail.com>
2601+ * Victor Thompson <victor.thompson@gmail.com>
2602+ *
2603+ * This program is free software; you can redistribute it and/or modify
2604+ * it under the terms of the GNU General Public License as published by
2605+ * the Free Software Foundation; version 3.
2606+ *
2607+ * This program is distributed in the hope that it will be useful,
2608+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2609+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2610+ * GNU General Public License for more details.
2611+ *
2612+ * You should have received a copy of the GNU General Public License
2613+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2614+ */
2615+
2616+import QtQuick 2.0
2617+import Ubuntu.Components 0.1
2618+import Ubuntu.Components.ListItems 0.1
2619+import Ubuntu.Components.Popups 0.1
2620+import Ubuntu.Components.ListItems 0.1 as ListItem
2621+import QtQuick.LocalStorage 2.0
2622+import "../meta-database.js" as Library
2623+
2624+Item {
2625+ id: sheetItem
2626+
2627+ property string artist: ""
2628+ property alias sheet: sheetComponent
2629+
2630+ SongsSheet {
2631+ id: albumSheet
2632+ }
2633+
2634+ Component {
2635+ id: sheetComponent
2636+ DefaultSheet {
2637+ id: sheet
2638+ anchors.bottomMargin: units.gu(.5)
2639+ doneButton: false
2640+ contentsHeight: parent.height
2641+ contentsWidth: parent.width
2642+
2643+ ListView {
2644+ clip: true
2645+ id: albumtrackslist
2646+ width: parent.width
2647+ anchors.top: parent.top
2648+ anchors.bottom: parent.bottom
2649+ model: artistAlbumsModel.model
2650+ delegate: albumTracksDelegate
2651+
2652+ onCountChanged: {
2653+ albumtrackslist.currentIndex = albumTracksModel.indexOf(currentFile)
2654+ }
2655+
2656+ Component {
2657+ id: albumTracksDelegate
2658+
2659+
2660+ ListItem.Standard {
2661+ id: albumInfo
2662+ width: parent.width
2663+ height: units.gu(20)
2664+
2665+ UbuntuShape {
2666+ id: albumImage
2667+ anchors.left: parent.left
2668+ anchors.top: parent.top
2669+ anchors.verticalCenter: parent.verticalCenter
2670+ anchors.margins: units.gu(1)
2671+ height: parent.height
2672+ width: height
2673+ image: Image {
2674+ source: Library.getAlbumCover(model.album) || Qt.resolvedUrl("../images/cover_default.png")
2675+ }
2676+ }
2677+ Label {
2678+ id: albumArtist
2679+ objectName: "albumsheet-albumartist"
2680+ wrapMode: Text.NoWrap
2681+ maximumLineCount: 1
2682+ fontSize: "small"
2683+ anchors.left: albumImage.right
2684+ anchors.leftMargin: units.gu(1)
2685+ anchors.top: parent.top
2686+ anchors.topMargin: units.gu(1.5)
2687+ anchors.right: parent.right
2688+ anchors.rightMargin: units.gu(1.5)
2689+ elide: Text.ElideRight
2690+ text: artist
2691+ }
2692+ Label {
2693+ id: albumLabel
2694+ wrapMode: Text.NoWrap
2695+ maximumLineCount: 2
2696+ fontSize: "medium"
2697+ color: styleMusic.common.music
2698+ anchors.left: albumImage.right
2699+ anchors.leftMargin: units.gu(1)
2700+ anchors.top: albumArtist.bottom
2701+ anchors.topMargin: units.gu(0.8)
2702+ anchors.right: parent.right
2703+ anchors.rightMargin: units.gu(1.5)
2704+ elide: Text.ElideRight
2705+ text: album
2706+ }
2707+ Label {
2708+ id: albumYear
2709+ wrapMode: Text.NoWrap
2710+ maximumLineCount: 1
2711+ fontSize: "x-small"
2712+ anchors.left: albumImage.right
2713+ anchors.leftMargin: units.gu(1)
2714+ anchors.top: albumLabel.bottom
2715+ anchors.topMargin: units.gu(2)
2716+ anchors.right: parent.right
2717+ anchors.rightMargin: units.gu(1.5)
2718+ elide: Text.ElideRight
2719+ text: i18n.tr(model.year + " | %1 song", model.year + " | %1 songs", Library.getAlbumTracks(album).length).arg(Library.getAlbumTracks(album).length)
2720+ }
2721+ MouseArea {
2722+ anchors.fill: parent
2723+ onDoubleClicked: {
2724+ }
2725+ onClicked: {
2726+ if (focus == false) {
2727+ focus = true
2728+ }
2729+
2730+ albumTracksModel.filterAlbumTracks(album)
2731+ albumSheet.line1 = artist
2732+ albumSheet.line2 = model.album
2733+ albumSheet.isAlbum = true
2734+ albumSheet.file = file
2735+ albumSheet.year = year
2736+ albumSheet.cover = Library.getAlbumCover(model.album) || Qt.resolvedUrl("../images/cover_default.png")
2737+ PopupUtils.open(albumSheet.sheet)
2738+
2739+ // TODO: This closes the SDK defined sheet
2740+ // component. It should be able to close
2741+ // albumSheet.
2742+ PopupUtils.close(sheet)
2743+ }
2744+ }
2745+ }
2746+ }
2747+ }
2748+ }
2749+ }
2750+}
2751+
2752
2753=== added file 'common/SongsSheet.qml'
2754--- common/SongsSheet.qml 1970-01-01 00:00:00 +0000
2755+++ common/SongsSheet.qml 2014-01-12 22:19:24 +0000
2756@@ -0,0 +1,403 @@
2757+/*
2758+ * Copyright (C) 2013 Andrew Hayzen <ahayzen@gmail.com>
2759+ * Daniel Holm <d.holmen@gmail.com>
2760+ * Victor Thompson <victor.thompson@gmail.com>
2761+ *
2762+ * This program is free software; you can redistribute it and/or modify
2763+ * it under the terms of the GNU General Public License as published by
2764+ * the Free Software Foundation; version 3.
2765+ *
2766+ * This program is distributed in the hope that it will be useful,
2767+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2768+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2769+ * GNU General Public License for more details.
2770+ *
2771+ * You should have received a copy of the GNU General Public License
2772+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2773+ */
2774+
2775+import QtQuick 2.0
2776+import Ubuntu.Components 0.1
2777+import Ubuntu.Components.ListItems 0.1
2778+import Ubuntu.Components.Popups 0.1
2779+import Ubuntu.Components.ListItems 0.1 as ListItem
2780+import QtQuick.LocalStorage 2.0
2781+import "../meta-database.js" as Library
2782+
2783+Item {
2784+ id: sheetItem
2785+
2786+ property string line1: ""
2787+ property string line2: ""
2788+ property string songtitle: ""
2789+ property string cover: ""
2790+ property string length: ""
2791+ property string file: ""
2792+ property string year: ""
2793+ property bool isAlbum: false
2794+ property alias sheet: sheetComponent
2795+
2796+ Component {
2797+ id: sheetComponent
2798+ DefaultSheet {
2799+ id: sheet
2800+ anchors.bottomMargin: units.gu(.5)
2801+ doneButton: false
2802+ contentsHeight: parent.height
2803+ contentsWidth: parent.width
2804+
2805+ ListView {
2806+ clip: true
2807+ id: albumtrackslist
2808+ width: parent.width
2809+ anchors.top: parent.top
2810+ anchors.bottom: parent.bottom
2811+ model: albumTracksModel.model
2812+ delegate: albumTracksDelegate
2813+ header: ListItem.Standard {
2814+ id: albumInfo
2815+ width: parent.width
2816+ height: units.gu(20)
2817+
2818+ UbuntuShape {
2819+ id: albumImage
2820+ anchors.left: parent.left
2821+ anchors.top: parent.top
2822+ anchors.verticalCenter: parent.verticalCenter
2823+ anchors.margins: units.gu(1)
2824+ height: parent.height
2825+ width: height
2826+ image: Image {
2827+ source: cover || "../images/cover_default.png"
2828+ }
2829+ }
2830+ Label {
2831+ id: albumArtist
2832+ objectName: "albumsheet-albumartist"
2833+ wrapMode: Text.NoWrap
2834+ maximumLineCount: 1
2835+ fontSize: "small"
2836+ anchors.left: albumImage.right
2837+ anchors.leftMargin: units.gu(1)
2838+ anchors.top: parent.top
2839+ anchors.topMargin: units.gu(1.5)
2840+ anchors.right: parent.right
2841+ anchors.rightMargin: units.gu(1.5)
2842+ elide: Text.ElideRight
2843+ text: line1
2844+ }
2845+ Label {
2846+ id: albumLabel
2847+ wrapMode: Text.NoWrap
2848+ maximumLineCount: 2
2849+ fontSize: "medium"
2850+ color: styleMusic.common.music
2851+ anchors.left: albumImage.right
2852+ anchors.leftMargin: units.gu(1)
2853+ anchors.top: albumArtist.bottom
2854+ anchors.topMargin: units.gu(0.8)
2855+ anchors.right: parent.right
2856+ anchors.rightMargin: units.gu(1.5)
2857+ elide: Text.ElideRight
2858+ text: line2
2859+ }
2860+ Label {
2861+ id: albumYear
2862+ wrapMode: Text.NoWrap
2863+ maximumLineCount: 1
2864+ fontSize: "x-small"
2865+ anchors.left: albumImage.right
2866+ anchors.leftMargin: units.gu(1)
2867+ anchors.top: albumLabel.bottom
2868+ anchors.topMargin: units.gu(2)
2869+ anchors.right: parent.right
2870+ anchors.rightMargin: units.gu(1.5)
2871+ elide: Text.ElideRight
2872+ text: isAlbum ? i18n.tr(year + " | %1 song", year + " | %1 songs", albumTracksModel.model.count).arg(albumTracksModel.model.count)
2873+ : i18n.tr("%1 song", "%1 songs", albumTracksModel.model.count).arg(albumTracksModel.model.count)
2874+
2875+ }
2876+ }
2877+
2878+ onCountChanged: {
2879+ albumtrackslist.currentIndex = albumTracksModel.indexOf(currentFile)
2880+ }
2881+
2882+ Component {
2883+ id: albumTracksDelegate
2884+
2885+ ListItem.Standard {
2886+ id: track
2887+ objectName: "albumsheet-track"
2888+ iconFrame: false
2889+ progression: false
2890+ height: isAlbum ? styleMusic.albums.itemHeight : styleMusic.common.albumSize + units.gu(2)
2891+
2892+ MouseArea {
2893+ anchors.fill: parent
2894+ onDoubleClicked: {
2895+ }
2896+ onClicked: {
2897+ if (focus == false) {
2898+ focus = true
2899+ }
2900+ trackClicked(albumTracksModel, index) // play track
2901+ if (isAlbum) {
2902+ Library.addRecent(sheetItem.line2, sheetItem.line1, sheetItem.cover, sheetItem.line2, "album")
2903+ mainView.hasRecent = true
2904+ recentModel.filterRecent()
2905+ } else if (sheetItem.line1 == "Playlist") {
2906+ Library.addRecent(sheetItem.line2, "Playlist", sheetItem.cover, sheetItem.line2, "playlist")
2907+ mainView.hasRecent = true
2908+ recentModel.filterRecent()
2909+ }
2910+
2911+ // TODO: This closes the SDK defined sheet
2912+ // component. It should be able to close
2913+ // albumSheet.
2914+ PopupUtils.close(sheet)
2915+ }
2916+ }
2917+
2918+ UbuntuShape {
2919+ id: trackCover
2920+ anchors {
2921+ left: parent.left
2922+ leftMargin: units.gu(2)
2923+ top: parent.top
2924+ topMargin: units.gu(1)
2925+ }
2926+ width: styleMusic.common.albumSize
2927+ height: styleMusic.common.albumSize
2928+ visible: !isAlbum
2929+ image: Image {
2930+ source: model.cover !== "" ? model.cover : Qt.resolvedUrl("../images/cover_default_icon.png")
2931+ }
2932+ }
2933+
2934+ Label {
2935+ id: trackArtist
2936+ wrapMode: Text.NoWrap
2937+ maximumLineCount: 2
2938+ fontSize: "x-small"
2939+ visible: !isAlbum
2940+ anchors {
2941+ left: trackCover.right
2942+ leftMargin: units.gu(2)
2943+ top: parent.top
2944+ topMargin: units.gu(1.5)
2945+ right: expandItem.left
2946+ rightMargin: units.gu(1.5)
2947+ }
2948+ elide: Text.ElideRight
2949+ text: model.artist
2950+ }
2951+
2952+ Label {
2953+ id: trackTitle
2954+ objectName: "albumsheet-tracktitle"
2955+ wrapMode: Text.NoWrap
2956+ maximumLineCount: 1
2957+ fontSize: "medium"
2958+ anchors {
2959+ left: isAlbum ? parent.left : trackCover.right
2960+ leftMargin: units.gu(2)
2961+ top: isAlbum ? parent.top : trackArtist.bottom
2962+ topMargin: units.gu(1)
2963+ right: expandItem.left
2964+ rightMargin: units.gu(1.5)
2965+ }
2966+ elide: Text.ElideRight
2967+ text: model.title
2968+ }
2969+
2970+ Label {
2971+ id: trackAlbum
2972+ wrapMode: Text.NoWrap
2973+ maximumLineCount: 2
2974+ fontSize: "xx-small"
2975+ visible: !isAlbum
2976+ anchors {
2977+ left: trackCover.right
2978+ leftMargin: units.gu(2)
2979+ top: trackTitle.bottom
2980+ topMargin: units.gu(2)
2981+ right: expandItem.left
2982+ rightMargin: units.gu(1.5)
2983+ }
2984+ elide: Text.ElideRight
2985+ text: model.album
2986+ }
2987+
2988+ Image {
2989+ id: expandItem
2990+ objectName: "albumsheet-expanditem"
2991+ anchors.right: parent.right
2992+ anchors.rightMargin: units.gu(2)
2993+ source: expandable.visible ? "../images/dropdown-menu-up.svg" : "../images/dropdown-menu.svg"
2994+ height: styleMusic.common.expandedItem
2995+ width: styleMusic.common.expandedItem
2996+ y: parent.y + ((isAlbum ? styleMusic.albums.itemHeight : styleMusic.common.albumSize + units.gu(2)) / 2) - (height / 2)
2997+ }
2998+
2999+ MouseArea {
3000+ anchors.bottom: parent.bottom
3001+ anchors.right: parent.right
3002+ anchors.top: parent.top
3003+ width: styleMusic.common.expandedItem * 3
3004+ onClicked: {
3005+ if(expandable.visible) {
3006+ customdebug("clicked collapse")
3007+ expandable.visible = false
3008+ track.height = isAlbum ? styleMusic.albums.itemHeight : styleMusic.common.albumSize + units.gu(2)
3009+ }
3010+ else {
3011+ customdebug("clicked expand")
3012+ collapseExpand(-1); // collapse all others
3013+ expandable.visible = true
3014+ track.height = isAlbum ? styleMusic.albums.expandedHeight : styleMusic.common.expandedHeight
3015+ }
3016+ }
3017+ }
3018+
3019+ Rectangle {
3020+ id: expandable
3021+ color: "transparent"
3022+ height: styleMusic.albums.expandHeight
3023+ visible: false
3024+ MouseArea {
3025+ anchors.fill: parent
3026+ onClicked: {
3027+ customdebug("User pressed outside the playlist item and expanded items.")
3028+ }
3029+ }
3030+
3031+ Component.onCompleted: {
3032+ collapseExpand.connect(onCollapseExpand);
3033+ }
3034+
3035+ function onCollapseExpand(indexCol)
3036+ {
3037+ if ((indexCol === index || indexCol === -1) && expandable !== undefined && expandable.visible === true)
3038+ {
3039+ customdebug("auto collapse")
3040+ expandable.visible = false
3041+ track.height = isAlbum ? styleMusic.albums.itemHeight : styleMusic.common.albumSize + unis.gu(2)
3042+ }
3043+ }
3044+
3045+ // background for expander
3046+ Rectangle {
3047+ id: expandedBackground
3048+ anchors.top: parent.top
3049+ anchors.topMargin: isAlbum ? styleMusic.albums.itemHeight : styleMusic.common.albumSize + units.gu(2)
3050+ color: styleMusic.common.black
3051+ height: styleMusic.albums.expandedHeight - styleMusic.albums.itemHeight
3052+ width: track.width
3053+ opacity: 0.4
3054+ }
3055+
3056+ // add to playlist
3057+ Rectangle {
3058+ id: playlistRow
3059+ anchors.top: expandedBackground.top
3060+ anchors.left: parent.left
3061+ anchors.leftMargin: styleMusic.albums.expandedLeftMargin
3062+ color: "transparent"
3063+ height: expandedBackground.height
3064+ width: units.gu(15)
3065+ Icon {
3066+ id: playlistTrack
3067+ anchors.verticalCenter: parent.verticalCenter
3068+ color: styleMusic.common.white
3069+ name: "add"
3070+ height: styleMusic.common.expandedItem
3071+ width: styleMusic.common.expandedItem
3072+ }
3073+ Label {
3074+ anchors.left: playlistTrack.right
3075+ anchors.leftMargin: units.gu(0.5)
3076+ anchors.verticalCenter: parent.verticalCenter
3077+ color: styleMusic.common.white
3078+ fontSize: "small"
3079+ width: parent.width - playlistTrack.width - units.gu(1)
3080+ text: i18n.tr("Add to playlist")
3081+ wrapMode: Text.WordWrap
3082+ maximumLineCount: 3
3083+ }
3084+ MouseArea {
3085+ anchors.fill: parent
3086+ onClicked: {
3087+ expandable.visible = false
3088+ track.height = isAlbum ? styleMusic.albums.itemHeight : styleMusic.common.albumSize + units.gu(2)
3089+ chosenArtist = artist
3090+ chosenTitle = title
3091+ chosenTrack = file
3092+ chosenAlbum = album
3093+ chosenCover = cover
3094+ chosenGenre = genre
3095+ chosenIndex = index
3096+ console.debug("Debug: Add track to playlist")
3097+ PopupUtils.open(Qt.resolvedUrl("../MusicaddtoPlaylist.qml"), mainView,
3098+ {
3099+ title: i18n.tr("Select playlist")
3100+ } )
3101+ }
3102+ }
3103+ }
3104+ // Queue
3105+ Rectangle {
3106+ id: queueRow
3107+ anchors.top: expandedBackground.top
3108+ anchors.left: playlistRow.left
3109+ anchors.leftMargin: units.gu(15)
3110+ color: "transparent"
3111+ height: expandedBackground.height
3112+ width: units.gu(15)
3113+ Image {
3114+ id: queueTrack
3115+ objectName: "albumsheet-queuetrack"
3116+ anchors.verticalCenter: parent.verticalCenter
3117+ source: "../images/queue.png"
3118+ height: styleMusic.common.expandedItem
3119+ width: styleMusic.common.expandedItem
3120+ }
3121+ Label {
3122+ anchors.left: queueTrack.right
3123+ anchors.leftMargin: units.gu(0.5)
3124+ anchors.verticalCenter: parent.verticalCenter
3125+ color: styleMusic.common.white
3126+ fontSize: "small"
3127+ width: parent.width - queueTrack.width - units.gu(1)
3128+ text: i18n.tr("Add to queue")
3129+ wrapMode: Text.WordWrap
3130+ maximumLineCount: 3
3131+ }
3132+ MouseArea {
3133+ anchors.fill: parent
3134+ onClicked: {
3135+ expandable.visible = false
3136+ track.height = isAlbum ? styleMusic.albums.itemHeight : styleMusic.common.albumSize + units.gu(2)
3137+ console.debug("Debug: Add track to queue: " + title)
3138+ trackQueue.model.append({"title": title, "artist": artist, "file": file, "album": album, "cover": cover, "genre": genre})
3139+ }
3140+ }
3141+ }
3142+ }
3143+
3144+ onFocusChanged: {
3145+ }
3146+ Component.onCompleted: {
3147+ if (index === 0)
3148+ {
3149+ sheetItem.file = model.file;
3150+ sheetItem.year = model.year;
3151+ }
3152+ }
3153+ }
3154+ }
3155+ }
3156+ }
3157+ }
3158+}
3159+
3160
3161=== modified file 'meta-database.js'
3162--- meta-database.js 2013-12-24 19:18:18 +0000
3163+++ meta-database.js 2014-01-12 22:19:24 +0000
3164@@ -237,11 +237,25 @@
3165 return res;
3166 }
3167
3168+function getArtistAlbums(artist) {
3169+ var res = [];
3170+ var db = getDatabase();
3171+ db.transaction( function(tx) {
3172+ var rs = tx.executeSql("SELECT * FROM metadata WHERE artist=? GROUP BY album ORDER BY year ASC, CAST(number AS int) ASC", [artist]);
3173+ for(var i = 0; i < rs.rows.length; i++) {
3174+ var dbItem = rs.rows.item(i);
3175+ //console.log("Artist:"+ dbItem.artist + ", Album:"+dbItem.album + ", Title:"+dbItem.title + ", File:"+dbItem.file + ", Art:"+dbItem.cover + ", Genre:"+dbItem.genre);
3176+ res.push({artist:dbItem.artist, album:dbItem.album, title:dbItem.title, file:dbItem.file, cover:dbItem.cover, length:dbItem.length, year:dbItem.year, genre:dbItem.genre});
3177+ }
3178+ });
3179+ return res;
3180+}
3181+
3182 function getArtistCovers(artist) {
3183 var res = [];
3184 var db = getDatabase();
3185 db.transaction( function(tx) {
3186- var rs = tx.executeSql("SELECT cover FROM metadata WHERE artist=? ORDER BY artist COLLATE NOCASE ASC, album COLLATE NOCASE ASC", [artist]);
3187+ var rs = tx.executeSql("SELECT cover FROM metadata WHERE artist=? AND cover <> '' ORDER BY album COLLATE NOCASE ASC", [artist]);
3188 for(var i = 0; i < rs.rows.length; i++) {
3189 var dbItem = rs.rows.item(i);
3190 //console.log("Cover:"+ dbItem.cover+" Size:"+res.length);
3191@@ -251,6 +265,18 @@
3192 return res;
3193 }
3194
3195+function getAlbumCover(album) {
3196+ var res = "";
3197+ var db = getDatabase();
3198+ db.transaction( function(tx) {
3199+ var rs = tx.executeSql("SELECT cover FROM metadata WHERE album=? ORDER BY cover DESC", [album]);
3200+ var dbItem = rs.rows.item(0);
3201+ //console.log("Cover:"+ dbItem.cover+" Size:"+res.length);
3202+ if (res.indexOf(dbItem.cover) == -1) res = dbItem.cover;
3203+ });
3204+ return res;
3205+}
3206+
3207 function getArtistAlbumCount(artist) {
3208 var res = 0;
3209 var db = getDatabase();
3210
3211=== modified file 'music-app.qml'
3212--- music-app.qml 2014-01-10 01:22:23 +0000
3213+++ music-app.qml 2014-01-12 22:19:24 +0000
3214@@ -604,6 +604,14 @@
3215 }
3216 }
3217
3218+ SongsSheet {
3219+ id: songsSheet
3220+ }
3221+
3222+ AlbumsSheet {
3223+ id: artistSheet
3224+ }
3225+
3226 // Model to send the data
3227 XmlListModel {
3228 id: scrobblemodel
3229@@ -774,7 +782,7 @@
3230 cover: media.thumbnail.toString(),
3231 length: media.duration.toString(),
3232 number: media.trackNumber,
3233- year: media.year.toString(),
3234+ year: media.year.toString() !== "0" ? media.year.toString(): i18n.tr("Unknown Year"),
3235 genre: media.genre || i18n.tr("Unknown Genre")
3236 };
3237
3238@@ -861,6 +869,9 @@
3239 LibraryListModel {
3240 id: artistTracksModel
3241 }
3242+ LibraryListModel {
3243+ id: artistAlbumsModel
3244+ }
3245
3246 LibraryListModel {
3247 id: albumModel
3248@@ -963,11 +974,6 @@
3249 }
3250 }
3251
3252- // create the listmodel for tracks in playlists
3253- LibraryListModel {
3254- id: playlisttracksModel
3255- }
3256-
3257 // Blurred background
3258 BlurredBackground {
3259 }
3260@@ -1095,7 +1101,7 @@
3261 property bool populated: false
3262 property var loader: [recentModel.filterRecent, genreModel.filterGenres]
3263 property bool loading: false
3264- property var model: [recentModel, genreModel]
3265+ property var model: [recentModel, genreModel, albumTracksModel]
3266 id: startTab
3267 objectName: "starttab"
3268 anchors.fill: parent
3269@@ -1112,7 +1118,7 @@
3270 property bool populated: false
3271 property var loader: [artistModel.filterArtists]
3272 property bool loading: false
3273- property var model: [artistModel, artistTracksModel]
3274+ property var model: [artistModel, artistAlbumsModel, albumTracksModel]
3275 id: artistsTab
3276 objectName: "artiststab"
3277 anchors.fill: parent
3278@@ -1164,7 +1170,7 @@
3279 property bool populated: false
3280 property var loader: [playlistModel.filterPlaylists]
3281 property bool loading: false
3282- property var model: [playlistModel, playlisttracksModel]
3283+ property var model: [playlistModel, albumTracksModel]
3284 id: playlistTab
3285 objectName: "playlisttab"
3286 anchors.fill: parent
3287
3288=== modified file 'tests/autopilot/music_app/emulators.py'
3289--- tests/autopilot/music_app/emulators.py 2013-12-16 21:23:07 +0000
3290+++ tests/autopilot/music_app/emulators.py 2014-01-12 22:19:24 +0000
3291@@ -107,7 +107,7 @@
3292 return item
3293
3294 def get_album_sheet_listview_tracktitle(self, trackTitle):
3295- tracktitles = self.select_many(
3296+ tracktitles = self.select_many_retry(
3297 "Label", objectName="albumsheet-tracktitle")
3298 for item in tracktitles:
3299 if item.text == trackTitle:
3300
3301=== modified file 'tests/autopilot/music_app/tests/test_music.py'
3302--- tests/autopilot/music_app/tests/test_music.py 2013-12-15 21:32:59 +0000
3303+++ tests/autopilot/music_app/tests/test_music.py 2014-01-12 22:19:24 +0000
3304@@ -37,6 +37,9 @@
3305 # populate queue
3306 first_genre_item = self.main_view.get_first_genre_item()
3307 self.pointing_device.click_object(first_genre_item)
3308+ trackTitle = "Foss Yeaaaah! (Radio Edit)"
3309+ song = self.main_view.get_album_sheet_listview_tracktitle(trackTitle)
3310+ self.pointing_device.click_object(song)
3311
3312 title = lambda: self.main_view.currentTracktitle
3313 artist = lambda: self.main_view.currentArtist
3314@@ -50,6 +53,9 @@
3315 # populate queue
3316 first_genre_item = self.main_view.get_first_genre_item()
3317 self.pointing_device.click_object(first_genre_item)
3318+ trackTitle = "Foss Yeaaaah! (Radio Edit)"
3319+ song = self.main_view.get_album_sheet_listview_tracktitle(trackTitle)
3320+ self.pointing_device.click_object(song)
3321
3322 # click back button
3323 back_button = self.main_view.get_back_button()
3324@@ -75,6 +81,9 @@
3325 # populate queue
3326 first_genre_item = self.main_view.get_first_genre_item()
3327 self.pointing_device.click_object(first_genre_item)
3328+ trackTitle = "Foss Yeaaaah! (Radio Edit)"
3329+ song = self.main_view.get_album_sheet_listview_tracktitle(trackTitle)
3330+ self.pointing_device.click_object(song)
3331
3332 playbutton = self.main_view.get_now_playing_play_button()
3333
3334@@ -95,6 +104,9 @@
3335 # populate queue
3336 first_genre_item = self.main_view.get_first_genre_item()
3337 self.pointing_device.click_object(first_genre_item)
3338+ trackTitle = "Foss Yeaaaah! (Radio Edit)"
3339+ song = self.main_view.get_album_sheet_listview_tracktitle(trackTitle)
3340+ self.pointing_device.click_object(song)
3341
3342 playbutton = self.main_view.get_now_playing_play_button()
3343 shufflebutton = self.main_view.get_shuffle_button()
3344@@ -153,6 +165,9 @@
3345 # populate queue
3346 first_genre_item = self.main_view.get_first_genre_item()
3347 self.pointing_device.click_object(first_genre_item)
3348+ trackTitle = "Foss Yeaaaah! (Radio Edit)"
3349+ song = self.main_view.get_album_sheet_listview_tracktitle(trackTitle)
3350+ self.pointing_device.click_object(song)
3351
3352 playbutton = self.main_view.get_now_playing_play_button()
3353 shufflebutton = self.main_view.get_shuffle_button()
3354@@ -207,6 +222,9 @@
3355 # populate queue
3356 first_genre_item = self.main_view.get_first_genre_item()
3357 self.pointing_device.click_object(first_genre_item)
3358+ trackTitle = "Foss Yeaaaah! (Radio Edit)"
3359+ song = self.main_view.get_album_sheet_listview_tracktitle(trackTitle)
3360+ self.pointing_device.click_object(song)
3361
3362 """ Track is playing, shuffle is turned on"""
3363 shufflebutton = self.main_view.get_shuffle_button()
3364@@ -480,6 +498,9 @@
3365 # populate queue
3366 first_genre_item = self.main_view.get_first_genre_item()
3367 self.pointing_device.click_object(first_genre_item)
3368+ trackTitle = "Foss Yeaaaah! (Radio Edit)"
3369+ song = self.main_view.get_album_sheet_listview_tracktitle(trackTitle)
3370+ self.pointing_device.click_object(song)
3371
3372 # get initial queue count
3373 initialqueueCount = self.main_view.get_queue_track_count()

Subscribers

People subscribed via source and target branches

to status/vote changes: