forked from clementine-player/Clementine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlibrarysearchprovider.cpp
121 lines (95 loc) · 3.47 KB
/
librarysearchprovider.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* This file is part of Clementine.
Copyright 2010, David Sansome <[email protected]>
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "librarysearchprovider.h"
#include "core/logging.h"
#include "covers/albumcoverloader.h"
#include "library/librarybackend.h"
#include "library/libraryquery.h"
#include "library/sqlrow.h"
#include "playlist/songmimedata.h"
#include <QStack>
LibrarySearchProvider::LibrarySearchProvider(LibraryBackendInterface* backend,
const QString& name,
const QString& id,
const QIcon& icon,
bool enabled_by_default,
Application* app, QObject* parent)
: BlockingSearchProvider(app, parent), backend_(backend) {
Hints hints =
WantsSerialisedArtQueries | ArtIsInSongMetadata | CanGiveSuggestions;
if (!enabled_by_default) {
hints |= DisabledByDefault;
}
Init(name, id, icon, hints);
}
SearchProvider::ResultList LibrarySearchProvider::Search(int id,
const QString& query) {
QueryOptions options;
options.set_filter(query);
LibraryQuery q(options);
q.SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
if (!backend_->ExecQuery(&q)) {
return ResultList();
}
// Build the result list
ResultList ret;
while (q.Next()) {
Result result(this);
result.metadata_.InitFromQuery(q, true);
ret << result;
}
return ret;
}
MimeData* LibrarySearchProvider::LoadTracks(const ResultList& results) {
MimeData* ret = SearchProvider::LoadTracks(results);
static_cast<SongMimeData*>(ret)->backend = backend_;
return ret;
}
QStringList LibrarySearchProvider::GetSuggestions(int count) {
// We'd like to use order by random(), but that's O(n) in sqlite, so instead
// get the largest ROWID and pick a couple of random numbers within that
// range.
LibraryQuery q;
q.SetColumnSpec("ROWID");
q.SetOrderBy("ROWID DESC");
q.SetIncludeUnavailable(true);
q.SetLimit(1);
QStringList ret;
if (!backend_->ExecQuery(&q) || !q.Next()) {
return ret;
}
const int largest_rowid = q.Value(0).toInt();
for (int attempt = 0; attempt < count * 5; ++attempt) {
if (ret.count() >= count) {
break;
}
LibraryQuery q;
q.SetColumnSpec("artist, album");
q.SetIncludeUnavailable(true);
q.AddWhere("ROWID", qrand() % largest_rowid);
q.SetLimit(1);
if (!backend_->ExecQuery(&q) || !q.Next()) {
continue;
}
const QString artist = q.Value(0).toString();
const QString album = q.Value(1).toString();
if (!artist.isEmpty() && !album.isEmpty())
ret << ((qrand() % 2 == 0) ? artist : album);
else if (!artist.isEmpty())
ret << artist;
else if (!album.isEmpty())
ret << album;
}
return ret;
}