Merge lp:~danielholm/music-app/search into lp:music-app/trusty

Proposed by Daniel Holm
Status: Merged
Approved by: Daniel Holm
Approved revision: 345
Merged at revision: 346
Proposed branch: lp:~danielholm/music-app/search
Merge into: lp:music-app/trusty
Diff against target: 735 lines (+653/-4)
7 files modified
LibraryListModel.qml (+6/-0)
MusicSearch.qml (+441/-0)
MusicStart.qml (+20/-1)
MusicaddtoPlaylist.qml (+2/-2)
images/search.svg (+153/-0)
meta-database.js (+16/-0)
music-app.qml (+15/-1)
To merge this branch: bzr merge lp:~danielholm/music-app/search
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Daniel Holm Approve
Andrew Hayzen Approve
Victor Thompson Approve
Review via email: mp+204098@code.launchpad.net

Commit message

Search functionality.

Description of the change

Added a basic search functions that searches for tracks based on artist, album, title and genre. Displays them in a sheet just like in the Songs tab. Queries the meta-database.

To post a comment you must log in.
Revision history for this message
Daniel Holm (danielholm) wrote :

I know I have to fix the manifest.json file. I really have to get that one fixed.

Revision history for this message
Daniel Holm (danielholm) wrote :

Also the search button will go away later.

lp:~danielholm/music-app/search updated
339. By Daniel Holm

Restored manifest.json

Revision history for this message
Daniel Holm (danielholm) wrote :

Removed the search button and restored the manifest file. Give it a go so we can merge .)

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 :

There is currently no way of showing the search sheet?

When searching if you start typing a value and then clear the text, it attempts to show everything - maybe it should return no results?

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

I think we need a desktop shortcut in addition to the HUD action you added.

1. Fix HUD action to do show the search sheet.
2. Add a shortcut to show the sheet. I vote for "CTRL + F"
3. I think it makes sense to have the expander on the search results so you can easily add multiple tracks to the queue/playlist.
4. I think the search textfield should get autofocus when the sheet is made visible.

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

I agree that when the text is cleared the results should be 0. Same if the user started typing and then deleted his/her search terms.

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

I can add the keyboard shortcut to my branch [1] if that is easier?

1 - https://code.launchpad.net/~andrew-hayzen/music-app/convergence-keyboard-shortcuts

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

That might be easier, but it'd need this branch to land first--which is possible because I believe you are currently blocked, Andrew. I wouldn't want to make this branch depend on your's, so I agree.

Revision history for this message
Daniel Holm (danielholm) wrote :

Hi, I'll take a look at it this evening again.

lp:~danielholm/music-app/search updated
340. By Daniel Holm

If no search term is entered, don't search at all.

341. By Daniel Holm

Commented out the dev search button.

Revision history for this message
Daniel Holm (danielholm) wrote :

Resolved that search is made when no search terms are entered. If this is a stopper I think we should merge and then add the expander in another branch, because I don't know when I will be able to add it.

lp:~danielholm/music-app/search updated
342. By Daniel Holm

HUD action Search now actually opens the search sheet.

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

You need to add your "searchAction" to the list of actions in MainView called "actions" in order for it to work.

review: Needs Fixing
lp:~danielholm/music-app/search updated
343. By Daniel Holm

Added the HUD action to enable search action; added highlight on start for search field.

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
Daniel Holm (danielholm) wrote :

Victor, I forgot about that. Added now, as well as highlight for the text field.

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

What does setting highlighted do? Does it force auto focus? If not do you plan on setting auto focus so the keyboard is automatically displayed when the sheet is shown? If not, this is probably good. I'll test in a few hours.

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

I approve. I'd prefer we auto focus the TextField, but I'm not going to require we do so now. Andrew, please chime in when you have time whether you think we should clear the results when no search terms exist. Currently, it just doesn't update the query to return every song--so the most recent results are shown. Perhaps not ideal, but I think it's OK.

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

Ok its looking good :)

I agree that ideally the TextField should auto focus.
I think that the results should clear when the search box is empty.

Also I think the delay of 2 seconds maybe to high (at least for desktop, maybe it is ok for mobile with the touch keyboard?), what do you guys think?

Another feature we could add is a count of how many tracks were returned.

Other than these minor points, which can either be done in this branch or another, I approve.

review: Approve
lp:~danielholm/music-app/search updated
344. By Daniel Holm

Added expander to search results; shortned down the search timer; added search icon to file and field; moved add to playlist button to bottom in sheet; when no search word, no results; only allow input without word help.

345. By Daniel Holm

Removed dev search button for the 100th time; and restored the manifest for the 1000th.

Revision history for this message
Daniel Holm (danielholm) wrote :

There, I've shortned the search timer, added the expander, made it so that no results are visible when there are no search terms. Also I added a keyboard hint so that individual characters are mede possible to enter - no word help since that only make searching worse/harder. Also I moved the "Add to playlist" button to parent.bottom. Added a search icon to the field to more look like the other core apps' search fields.
Finally I cant seem to get the text field to auto focus, but neither does Weather or Clock app.

Approving.

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

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-29 01:24:50 +0000
3+++ LibraryListModel.qml 2014-02-20 01:28:57 +0000
4@@ -219,4 +219,10 @@
5 worker.sendMessage({'clear': true, 'model': libraryModel})
6 }
7 }
8+
9+ function filterSearch(searchQuery) {
10+ query = Library.search
11+ param = searchQuery
12+ worker.list = Library.search(searchQuery)
13+ }
14 }
15
16=== added file 'MusicSearch.qml'
17--- MusicSearch.qml 1970-01-01 00:00:00 +0000
18+++ MusicSearch.qml 2014-02-20 01:28:57 +0000
19@@ -0,0 +1,441 @@
20+/*
21+ * Copyright (C) 2014 Andrew Hayzen <ahayzen@gmail.com>
22+ * Daniel Holm <d.holmen@gmail.com>
23+ * Victor Thompson <victor.thompson@gmail.com>
24+ *
25+ * This program is free software; you can redistribute it and/or modify
26+ * it under the terms of the GNU General Public License as published by
27+ * the Free Software Foundation; version 3.
28+ *
29+ * This program is distributed in the hope that it will be useful,
30+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32+ * GNU General Public License for more details.
33+ *
34+ * You should have received a copy of the GNU General Public License
35+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36+ */
37+
38+import QtMultimedia 5.0
39+import QtQuick 2.0
40+import Ubuntu.Components 0.1
41+import Ubuntu.Components.ListItems 0.1 as ListItem
42+import Ubuntu.Components.Popups 0.1
43+import QtQuick.LocalStorage 2.0
44+import "playlists.js" as Playlists
45+import "meta-database.js" as Library
46+import "common"
47+
48+// Sheet to search for music tracks
49+ DefaultSheet {
50+ id: searchTrack
51+ title: i18n.tr("Search")
52+ contentsHeight: units.gu(80)
53+
54+ onDoneClicked: PopupUtils.close(searchTrack)
55+
56+ Component.onCompleted: {
57+ }
58+
59+ onVisibleChanged: {
60+ if (visible === true)
61+ {
62+ musicToolbar.disableToolbar()
63+ }
64+ else
65+ {
66+ musicToolbar.enableToolbar()
67+ }
68+ }
69+
70+ TextField {
71+ id: searchField
72+ anchors {
73+ left: parent.left;
74+ leftMargin: units.gu(2);
75+ top: parent.top;
76+ right: parent.right;
77+ rightMargin: units.gu(2);
78+ }
79+
80+ width: parent.width/1.5
81+ placeholderText: "Search"
82+ hasClearButton: true
83+ highlighted: true
84+ focus: true
85+ inputMethodHints: Qt.ImhNoPredictiveText
86+ //canPaste: true // why work, you do not, hrm?
87+
88+ // search icon
89+ primaryItem: Image {
90+ height: parent.height*0.5
91+ width: parent.height*0.5
92+ anchors.verticalCenter: parent.verticalCenter
93+ anchors.verticalCenterOffset: -units.gu(0.2)
94+ source: Qt.resolvedUrl("images/search.svg")
95+ }
96+
97+ onTextChanged: {
98+ searchTimer.start() // start the countdown, baby!
99+ }
100+
101+ // Provide a small pause before search
102+ Timer {
103+ id: searchTimer
104+ interval: 1500
105+ repeat: false
106+ onTriggered: {
107+ if(searchField.text) {
108+ searchModel.filterSearch(searchField.text) // query the databse
109+ searchActivity.running = true // start the activity indicator
110+ }
111+ else {
112+ customdebug("No search terms.")
113+ searchModel.filterSearch("empty somehow?")
114+ }
115+ indicatorTimer.start()
116+ }
117+ }
118+ // and onother one for the indicator
119+ Timer {
120+ id: indicatorTimer
121+ interval: 500
122+ repeat: false
123+ onTriggered: {
124+ searchActivity.running = false
125+ }
126+ }
127+
128+ // Indicator to show search activity
129+ ActivityIndicator {
130+ id: searchActivity
131+ anchors {
132+ verticalCenter: searchField.verticalCenter;
133+ right: searchField.right;
134+ rightMargin: units.gu(1)
135+ }
136+ running: false
137+ }
138+ }
139+
140+ Rectangle {
141+ width: parent.width
142+ height: parent.height
143+ color: "transparent"
144+ clip: true
145+ anchors {
146+ top: searchField.bottom
147+ bottom: parent.bottom
148+ left: parent.left
149+ right: parent.right
150+ }
151+
152+ // show each playlist and make them chosable
153+ ListView {
154+ id: searchTrackView
155+ objectName: "searchtrackview"
156+ width: parent.width
157+ height: parent.width
158+ model: searchModel.model
159+ delegate: ListItem.Standard {
160+ id: search
161+ objectName: "playlist"
162+ width: parent.width
163+ height: styleMusic.common.itemHeight
164+ property string title: model.title
165+ property string artist: model.artist
166+ property string file: model.file
167+ property string album: model.album
168+ property string cover: model.cover
169+ property string genre: model.genre
170+
171+ onClicked: {
172+ console.debug("Debug: "+title+" added to queue")
173+ // now play this track, but keep current queue
174+ trackQueue.model.append({"title": title, "artist": artist, "file": file, "album": album, "cover": cover, "genre": genre})
175+ trackClicked(trackQueue, trackQueue.model.count - 1, true)
176+ onDoneClicked: PopupUtils.close(searchTrack)
177+ }
178+
179+ UbuntuShape {
180+ id: trackCover
181+ anchors.left: parent.left
182+ anchors.leftMargin: units.gu(2)
183+ anchors.top: parent.top
184+ anchors.topMargin: units.gu(1)
185+ width: styleMusic.common.albumSize
186+ height: styleMusic.common.albumSize
187+ image: Image {
188+ source: cover !== "" ? cover : Qt.resolvedUrl("images/cover_default_icon.png")
189+ }
190+ }
191+
192+ Label {
193+ id: trackArtist
194+ wrapMode: Text.NoWrap
195+ maximumLineCount: 2
196+ fontSize: "x-small"
197+ anchors.left: trackCover.left
198+ anchors.leftMargin: units.gu(11)
199+ anchors.top: parent.top
200+ anchors.topMargin: units.gu(1.5)
201+ anchors.right: expandItem.left
202+ anchors.rightMargin: units.gu(1.5)
203+ elide: Text.ElideRight
204+ text: artist
205+ }
206+ Label {
207+ id: trackTitle
208+ objectName: "tracktitle"
209+ wrapMode: Text.NoWrap
210+ maximumLineCount: 1
211+ fontSize: "small"
212+ color: styleMusic.common.music
213+ anchors.left: trackCover.left
214+ anchors.leftMargin: units.gu(11)
215+ anchors.top: trackArtist.bottom
216+ anchors.topMargin: units.gu(1)
217+ anchors.right: expandItem.left
218+ anchors.rightMargin: units.gu(1.5)
219+ elide: Text.ElideRight
220+ text: title
221+ }
222+ Label {
223+ id: trackAlbum
224+ wrapMode: Text.NoWrap
225+ maximumLineCount: 2
226+ fontSize: "xx-small"
227+ anchors.left: trackCover.left
228+ anchors.leftMargin: units.gu(11)
229+ anchors.top: trackTitle.bottom
230+ anchors.topMargin: units.gu(2)
231+ anchors.right: expandItem.left
232+ anchors.rightMargin: units.gu(1.5)
233+ elide: Text.ElideRight
234+ text: album
235+ }
236+ Label {
237+ id: trackDuration
238+ wrapMode: Text.NoWrap
239+ maximumLineCount: 2
240+ fontSize: "small"
241+ color: styleMusic.common.music
242+ anchors.left: trackCover.left
243+ anchors.leftMargin: units.gu(12)
244+ anchors.top: trackAlbum.bottom
245+ anchors.right: expandItem.left
246+ anchors.rightMargin: units.gu(1.5)
247+ elide: Text.ElideRight
248+ visible: false
249+ text: ""
250+ }
251+
252+ //Icon { // use for 1.0
253+ Image {
254+ id: expandItem
255+ objectName: "trackimage"
256+ anchors.right: parent.right
257+ anchors.rightMargin: units.gu(2)
258+ // name: "dropdown-menu" Use for 1.0
259+ source: expandable.visible ? "images/dropdown-menu-up.svg" : "images/dropdown-menu.svg"
260+ height: styleMusic.common.expandedItem
261+ width: styleMusic.common.expandedItem
262+ y: parent.y + (styleMusic.common.itemHeight / 2) - (height / 2)
263+ }
264+
265+ MouseArea {
266+ anchors.bottom: parent.bottom
267+ anchors.right: parent.right
268+ anchors.top: parent.top
269+ width: styleMusic.common.expandedItem * 3
270+ onClicked: {
271+ if(expandable.visible) {
272+ customdebug("clicked collapse")
273+ expandable.visible = false
274+ search.height = styleMusic.common.itemHeight
275+ Rotation: {
276+ source: expandItem;
277+ angle: 0;
278+ }
279+ }
280+ else {
281+ customdebug("clicked expand")
282+ collapseExpand(-1); // collapse all others
283+ expandable.visible = true
284+ search.height = styleMusic.common.expandedHeight
285+ Rotation: {
286+ source: expandItem;
287+ angle: 180;
288+ }
289+ }
290+ }
291+ }
292+
293+ Rectangle {
294+ id: expandable
295+ color: "transparent"
296+ height: styleMusic.common.expandHeight
297+ visible: false
298+ MouseArea {
299+ anchors.fill: parent
300+ onClicked: {
301+ customdebug("User pressed outside the playlist item and expanded items.")
302+ }
303+ }
304+
305+ Component.onCompleted: {
306+ collapseExpand.connect(onCollapseExpand);
307+ }
308+
309+ function onCollapseExpand(indexCol)
310+ {
311+ if ((indexCol === index || indexCol === -1) && expandable !== undefined && expandable.visible === true)
312+ {
313+ customdebug("auto collapse")
314+ expandable.visible = false
315+ search.height = styleMusic.common.itemHeight
316+ }
317+ }
318+
319+ // background for expander
320+ Rectangle {
321+ id: expandedBackground
322+ anchors.top: parent.top
323+ anchors.topMargin: styleMusic.common.itemHeight
324+ color: styleMusic.common.black
325+ height: styleMusic.common.expandedHeight - styleMusic.common.itemHeight
326+ width: search.width
327+ opacity: 0.4
328+ }
329+
330+ // add to playlist
331+ Rectangle {
332+ id: playlistRow
333+ anchors.top: expandedBackground.top
334+ anchors.left: parent.left
335+ anchors.leftMargin: styleMusic.common.expandedLeftMargin
336+ color: "transparent"
337+ height: expandedBackground.height
338+ width: units.gu(15)
339+ Icon {
340+ id: playlistTrack
341+ anchors.verticalCenter: parent.verticalCenter
342+ color: styleMusic.common.white
343+ name: "add"
344+ height: styleMusic.common.expandedItem
345+ width: styleMusic.common.expandedItem
346+ }
347+ Label {
348+ objectName: "songstab_addtoplaylist"
349+ anchors.left: playlistTrack.right
350+ anchors.leftMargin: units.gu(0.5)
351+ anchors.verticalCenter: parent.verticalCenter
352+ color: styleMusic.common.white
353+ fontSize: "small"
354+ width: parent.width - playlistTrack.width - units.gu(1)
355+ text: i18n.tr("Add to playlist")
356+ wrapMode: Text.WordWrap
357+ maximumLineCount: 3
358+ }
359+ MouseArea {
360+ anchors.fill: parent
361+ onClicked: {
362+ expandable.visible = false
363+ search.height = styleMusic.common.itemHeight
364+ chosenArtist = artist
365+ chosenTitle = title
366+ chosenTrack = file
367+ chosenAlbum = album
368+ chosenCover = cover
369+ chosenGenre = genre
370+ chosenIndex = index
371+ console.debug("Debug: Add track to playlist")
372+ PopupUtils.open(Qt.resolvedUrl("MusicaddtoPlaylist.qml"), mainView,
373+ {
374+ title: i18n.tr("Select playlist")
375+ } )
376+ }
377+ }
378+ }
379+ // Queue
380+ Rectangle {
381+ id: queueRow
382+ anchors.top: expandedBackground.top
383+ anchors.left: playlistRow.left
384+ anchors.leftMargin: units.gu(15)
385+ color: "transparent"
386+ height: expandedBackground.height
387+ width: units.gu(15)
388+ Image {
389+ id: queueTrack
390+ anchors.verticalCenter: parent.verticalCenter
391+ source: "images/queue.png"
392+ height: styleMusic.common.expandedItem
393+ width: styleMusic.common.expandedItem
394+ }
395+ Label {
396+ objectName: "songstab_addtoqueue"
397+ anchors.left: queueTrack.right
398+ anchors.leftMargin: units.gu(0.5)
399+ anchors.verticalCenter: parent.verticalCenter
400+ color: styleMusic.common.white
401+ fontSize: "small"
402+ width: parent.width - queueTrack.width - units.gu(1)
403+ text: i18n.tr("Add to queue")
404+ wrapMode: Text.WordWrap
405+ maximumLineCount: 3
406+ }
407+ MouseArea {
408+ anchors.fill: parent
409+ onClicked: {
410+ expandable.visible = false
411+ search.height = styleMusic.common.itemHeight
412+ console.debug("Debug: Add track to queue: " + title)
413+ trackQueue.model.append({"title": title, "artist": artist, "file": file, "album": album, "cover": cover, "genre": genre})
414+ }
415+ }
416+ }
417+ // Share
418+ Rectangle {
419+ id: shareRow
420+ anchors.top: expandedBackground.top
421+ anchors.left: queueRow.left
422+ anchors.leftMargin: units.gu(15)
423+ color: "transparent"
424+ height: expandedBackground.height
425+ width: units.gu(15)
426+ visible: false
427+ Icon {
428+ id: shareTrack
429+ color: styleMusic.common.white
430+ name: "share"
431+ height: styleMusic.common.expandedItem
432+ width: styleMusic.common.expandedItem
433+ }
434+ Label {
435+ anchors.left: shareTrack.right
436+ anchors.leftMargin: units.gu(0.5)
437+ anchors.top: parent.top
438+ anchors.topMargin: units.gu(0.5)
439+ color: styleMusic.common.white
440+ fontSize: "small"
441+ text: i18n.tr("Share")
442+ width: units.gu(5)
443+ height: parent.height
444+ wrapMode: Text.WordWrap
445+ }
446+ MouseArea {
447+ anchors.fill: parent
448+ onClicked: {
449+ expandable.visible = false
450+ search.height = styleMusic.common.itemHeight
451+ customdebug("Share")
452+ }
453+ }
454+ }
455+ }
456+ }
457+ }
458+
459+ }
460+ }
461
462=== modified file 'MusicStart.qml'
463--- MusicStart.qml 2014-01-16 19:22:52 +0000
464+++ MusicStart.qml 2014-02-20 01:28:57 +0000
465@@ -39,12 +39,31 @@
466 }
467 }
468
469+ /* Dev button for search.
470+ Button {
471+ id: searchButton
472+ text: "Search"
473+ anchors.top: parent.top
474+ anchors.topMargin: units.gu(2)
475+ anchors.bottom: recentlyPlayed.top
476+ anchors.bottomMargin: units.gu(1)
477+ height: units.gu(4)
478+ onClicked: {
479+ PopupUtils.open(Qt.resolvedUrl("MusicSearch.qml"), mainView,
480+ {
481+ title: i18n.tr("Search")
482+ } )
483+ }
484+ }
485+ */
486+
487+
488 ListItem.Standard {
489 id: recentlyPlayed
490 text: i18n.tr("Recent")
491 }
492 Item {
493- id: recentlistempty
494+ id: recentlistempty
495 anchors.top: recentlyPlayed.bottom
496 anchors.topMargin: units.gu(1)
497 height: units.gu(22)
498
499=== modified file 'MusicaddtoPlaylist.qml'
500--- MusicaddtoPlaylist.qml 2014-01-24 19:13:11 +0000
501+++ MusicaddtoPlaylist.qml 2014-02-20 01:28:57 +0000
502@@ -124,8 +124,8 @@
503 iconSource: "images/add.svg"
504 iconPosition: "left"
505 width: parent.width
506- anchors.top: addtoPlaylistView.bottom
507- anchors.topMargin: units.gu(5)
508+ anchors.bottom: parent.bottom
509+ anchors.bottomMargin: units.gu(0.5)
510 onClicked: {
511 customdebug("New playlist.")
512 PopupUtils.open(newPlaylistDialog, mainView)
513
514=== added file 'images/search.svg'
515--- images/search.svg 1970-01-01 00:00:00 +0000
516+++ images/search.svg 2014-02-20 01:28:57 +0000
517@@ -0,0 +1,153 @@
518+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
519+<!-- Created with Inkscape (http://www.inkscape.org/) -->
520+
521+<svg
522+ xmlns:dc="http://purl.org/dc/elements/1.1/"
523+ xmlns:cc="http://creativecommons.org/ns#"
524+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
525+ xmlns:svg="http://www.w3.org/2000/svg"
526+ xmlns="http://www.w3.org/2000/svg"
527+ xmlns:xlink="http://www.w3.org/1999/xlink"
528+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
529+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
530+ width="90"
531+ height="90.000015"
532+ id="svg3133"
533+ version="1.1"
534+ inkscape:version="0.48+devel r12262"
535+ sodipodi:docname="search.svg">
536+ <defs
537+ id="defs3135">
538+ <linearGradient
539+ inkscape:collect="always"
540+ id="linearGradient3803">
541+ <stop
542+ style="stop-color:#e7e5e5;stop-opacity:1;"
543+ offset="0"
544+ id="stop3805" />
545+ <stop
546+ style="stop-color:#e2dfdf;stop-opacity:1"
547+ offset="1"
548+ id="stop3807" />
549+ </linearGradient>
550+ <linearGradient
551+ inkscape:collect="always"
552+ xlink:href="#linearGradient3803"
553+ id="linearGradient3809"
554+ x1="53.012165"
555+ y1="-102.79017"
556+ x2="53.012165"
557+ y2="-66.661224"
558+ gradientUnits="userSpaceOnUse" />
559+ <linearGradient
560+ inkscape:collect="always"
561+ xlink:href="#linearGradient3803"
562+ id="linearGradient3813"
563+ gradientUnits="userSpaceOnUse"
564+ x1="53.012165"
565+ y1="-102.79017"
566+ x2="53.012165"
567+ y2="-66.661224"
568+ gradientTransform="translate(-625,0)" />
569+ </defs>
570+ <sodipodi:namedview
571+ id="base"
572+ pagecolor="#ffffff"
573+ bordercolor="#666666"
574+ borderopacity="1.0"
575+ inkscape:pageopacity="0.0"
576+ inkscape:pageshadow="2"
577+ inkscape:zoom="7.9580781"
578+ inkscape:cx="47.57328"
579+ inkscape:cy="40.531144"
580+ inkscape:document-units="px"
581+ inkscape:current-layer="g3842"
582+ showgrid="true"
583+ inkscape:window-width="1920"
584+ inkscape:window-height="1029"
585+ inkscape:window-x="0"
586+ inkscape:window-y="24"
587+ inkscape:window-maximized="1"
588+ inkscape:snap-grids="true"
589+ inkscape:snap-global="true"
590+ fit-margin-top="0"
591+ fit-margin-left="0"
592+ fit-margin-right="0"
593+ fit-margin-bottom="0"
594+ inkscape:snap-bbox="true"
595+ inkscape:bbox-paths="true"
596+ inkscape:bbox-nodes="true"
597+ inkscape:snap-bbox-edge-midpoints="true"
598+ inkscape:snap-bbox-midpoints="true"
599+ inkscape:object-paths="true"
600+ inkscape:snap-intersection-paths="true"
601+ inkscape:snap-midpoints="true"
602+ inkscape:snap-smooth-nodes="true"
603+ inkscape:object-nodes="true"
604+ inkscape:snap-object-midpoints="true"
605+ inkscape:snap-center="true">
606+ <inkscape:grid
607+ type="xygrid"
608+ id="grid3016"
609+ empspacing="6"
610+ visible="true"
611+ enabled="true"
612+ snapvisiblegridlinesonly="true"
613+ originx="-2.98e-06px"
614+ originy="2.6171874e-06px" />
615+ </sodipodi:namedview>
616+ <metadata
617+ id="metadata3138">
618+ <rdf:RDF>
619+ <cc:Work
620+ rdf:about="">
621+ <dc:format>image/svg+xml</dc:format>
622+ <dc:type
623+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
624+ <dc:title />
625+ </cc:Work>
626+ </rdf:RDF>
627+ </metadata>
628+ <g
629+ inkscape:label="Layer 1"
630+ inkscape:groupmode="layer"
631+ id="layer1"
632+ transform="translate(-2.98e-6,-962.36219)"
633+ style="display:inline">
634+ <g
635+ transform="matrix(0.99934414,0,0,1,-106.92982,549.00002)"
636+ id="g3842"
637+ style="display:inline">
638+ <rect
639+ style="opacity:0.05;color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
640+ id="rect3844"
641+ width="90.059067"
642+ height="90.000015"
643+ x="107"
644+ y="-503.36218"
645+ transform="scale(1,-1)" />
646+ <path
647+ sodipodi:type="arc"
648+ style="color:#000000;fill:none;stroke:#808080;stroke-width:10.49972248;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
649+ id="path2995"
650+ sodipodi:cx="35.999996"
651+ sodipodi:cy="36.500011"
652+ sodipodi:rx="33"
653+ sodipodi:ry="33.5"
654+ d="m 68.999996,36.500011 a 33,33.5 0 1 1 -65.9999998,0 A 33,33.5 0 1 1 68.999996,36.500011 Z"
655+ transform="matrix(0.86331274,0,0,0.85161915,120.95028,427.27807)" />
656+ <path
657+ style="font-size:xx-small;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#808080;fill-opacity:1;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
658+ d="m 175.1697,477.23717 -4.25279,4.25 12.00787,12 L 187.17757,489.23717 Z"
659+ id="path3765"
660+ inkscape:connector-curvature="0"
661+ sodipodi:nodetypes="ccccc" />
662+ <path
663+ style="font-size:xx-small;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#808080;fill-opacity:1;stroke:none;stroke-width:11.80387211;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
664+ d="m 180.97203,481.40625 c -2.32437,0.012 -4.57033,1.53501 -5.44162,3.68994 -0.87128,2.15492 -0.31496,4.81092 1.34787,6.43506 l 8.79632,8.79991 c 4.02735,4.27401 4.89575,3.69726 8.46955,0.1258 3.57381,-3.57146 4.15747,-4.18909 -0.1258,-8.46955 l -8.79632,-8.79991 C 184.12024,482.05781 182.55003,481.39971 180.97203,481.40625 Z"
665+ id="path3767"
666+ inkscape:connector-curvature="0"
667+ sodipodi:nodetypes="cscczccc" />
668+ </g>
669+ </g>
670+</svg>
671
672=== modified file 'meta-database.js'
673--- meta-database.js 2014-01-16 19:22:52 +0000
674+++ meta-database.js 2014-02-20 01:28:57 +0000
675@@ -461,3 +461,19 @@
676 return res === 0;
677 }
678
679+// Search track LIKE
680+function search(input) {
681+ console.debug("Got a new search: "+input)
682+ input = "%" + input + "%" // workaround
683+ var res = [];
684+ var db = getDatabase();
685+ db.transaction( function(tx) {
686+ var rs = tx.executeSql("SELECT * FROM metadata WHERE title LIKE ? OR artist LIKE ? OR album LIKE ? OR genre LIKE ?;", [input,input,input,input]); // WRONG! WHy?
687+ for(var i = 0; i < rs.rows.length; i++) {
688+ var dbItem = rs.rows.item(i);
689+ console.log("Artist:"+ dbItem.artist + ", Album:"+dbItem.album + ", Title:"+dbItem.title + ", File:"+dbItem.file + ", Art:"+dbItem.cover + ", Genre:"+dbItem.genre);
690+ 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});
691+ }
692+ });
693+ return res;
694+}
695
696=== modified file 'music-app.qml'
697--- music-app.qml 2014-01-24 23:33:12 +0000
698+++ music-app.qml 2014-02-20 01:28:57 +0000
699@@ -71,6 +71,15 @@
700
701 // HUD Actions
702 Action {
703+ id: searchAction
704+ text: i18n.tr("Search")
705+ keywords: i18n.tr("Search Track")
706+ onTriggered: PopupUtils.open(Qt.resolvedUrl("MusicSearch.qml"), mainView,
707+ {
708+ title: i18n.tr("Search")
709+ } )
710+ }
711+ Action {
712 id: nextAction
713 text: i18n.tr("Next")
714 keywords: i18n.tr("Next Track")
715@@ -124,7 +133,7 @@
716 onTriggered: Qt.quit()
717 }
718
719- actions: [nextAction, playsAction, prevAction, stopAction, backAction, settingsAction, quitAction]
720+ actions: [searchAction, nextAction, playsAction, prevAction, stopAction, backAction, settingsAction, quitAction]
721
722 // signal to open new URIs
723 // TODO currently this only allows playing file:// URIs of known files
724@@ -984,6 +993,11 @@
725 }
726 }
727
728+ // search model
729+ LibraryListModel {
730+ id: searchModel
731+ }
732+
733 // Blurred background
734 BlurredBackground {
735 }

Subscribers

People subscribed via source and target branches

to status/vote changes: