Clementine-audio-player-Mac.../src/globalsearch/librarysearchprovider.cpp

127 lines
4.1 KiB
C++
Raw Normal View History

/* This file is part of Clementine.
Copyright 2010, David Sansome <me@davidsansome.com>
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"
LibrarySearchProvider::LibrarySearchProvider(LibraryBackendInterface* backend,
const QString& name,
const QIcon& icon,
QObject* parent)
: BlockingSearchProvider(parent),
backend_(backend),
cover_loader_(new BackgroundThreadImplementation<AlbumCoverLoader, AlbumCoverLoader>(this))
{
Init(name, icon, false, true);
cover_loader_->Start(true);
cover_loader_->Worker()->SetDesiredHeight(kArtHeight);
cover_loader_->Worker()->SetPadOutputImage(true);
cover_loader_->Worker()->SetScaleOutputImage(true);
connect(cover_loader_->Worker().get(),
SIGNAL(ImageLoaded(quint64,QImage)),
SLOT(AlbumArtLoaded(quint64,QImage)));
}
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();
}
const QStringList tokens = TokenizeQuery(query);
QMultiMap<QString, Song> albums;
QSet<QString> albums_with_non_track_matches;
ResultList ret;
while (q.Next()) {
Song song;
song.InitFromQuery(q, true);
QString album_key = song.album();
if (song.is_compilation() && !song.albumartist().isEmpty()) {
album_key.prepend(song.albumartist() + " - ");
} else if (!song.is_compilation()) {
album_key.prepend(song.artist());
}
Result::MatchQuality quality = MatchQuality(tokens, song.title());
if (quality != Result::Quality_None) {
// If the query matched in the song title then we're interested in this
// as an individual song.
Result result(this);
result.type_ = Result::Type_Track;
result.metadata_ = song;
result.match_quality_ = quality;
ret << result;
} else {
// Otherwise we record this as being an interesting album.
albums_with_non_track_matches.insert(album_key);
}
albums.insertMulti(album_key, song);
}
// Add any albums that contained least one song that wasn't matched on the
// song title.
foreach (const QString& key, albums_with_non_track_matches) {
Result result(this);
result.type_ = Result::Type_Album;
result.metadata_ = albums.value(key);
result.album_size_ = albums.count(key);
result.match_quality_ =
qMin(
MatchQuality(tokens, result.metadata_.albumartist()),
qMin(MatchQuality(tokens, result.metadata_.artist()),
MatchQuality(tokens, result.metadata_.album())));
ret << result;
}
return ret;
}
void LibrarySearchProvider::LoadArtAsync(int id, const Result& result) {
quint64 loader_id = cover_loader_->Worker()->LoadImageAsync(result.metadata_);
cover_loader_tasks_[loader_id] = id;
}
void LibrarySearchProvider::AlbumArtLoaded(quint64 id, const QImage& image) {
if (!cover_loader_tasks_.contains(id))
return;
int orig_id = cover_loader_tasks_.take(id);
emit ArtLoaded(orig_id, image);
}
void LibrarySearchProvider::LoadTracksAsync(int id, const Result& result) {
emit TracksLoaded(id, SongList());
}