Merge lp:~danielholm/music-app/search into lp:music-app/trusty
- search
- Merge into trusty
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 | ||||
Related bugs: |
|
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.
Daniel Holm (danielholm) wrote : | # |
Daniel Holm (danielholm) wrote : | # |
Also the search button will go away later.
- 339. By Daniel Holm
-
Restored manifest.json
Daniel Holm (danielholm) wrote : | # |
Removed the search button and restored the manifest file. Give it a go so we can merge .)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:339
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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?
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.
Victor Thompson (vthompson) : | # |
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.
Andrew Hayzen (ahayzen) wrote : | # |
I can add the keyboard shortcut to my branch [1] if that is easier?
1 - https:/
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.
Daniel Holm (danielholm) wrote : | # |
Hi, I'll take a look at it this evening again.
- 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.
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.
- 342. By Daniel Holm
-
HUD action Search now actually opens the search sheet.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:342
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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.
- 343. By Daniel Holm
-
Added the HUD action to enable search action; added highlight on start for search field.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:343
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel Holm (danielholm) wrote : | # |
Victor, I forgot about that. Added now, as well as highlight for the text field.
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.
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.
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.
- 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.
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.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:345
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
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 | } |
I know I have to fix the manifest.json file. I really have to get that one fixed.