diff --git a/src/globalsearch/globalsearch.cpp b/src/globalsearch/globalsearch.cpp index 634cf47c9..a28d6288e 100644 --- a/src/globalsearch/globalsearch.cpp +++ b/src/globalsearch/globalsearch.cpp @@ -40,6 +40,8 @@ void GlobalSearch::AddProvider(SearchProvider* provider) { SLOT(SearchFinishedSlot(int))); connect(provider, SIGNAL(ArtLoaded(int,QImage)), SLOT(ArtLoadedSlot(int,QImage))); + connect(provider, SIGNAL(TracksLoaded(int,MimeData*)), + SIGNAL(TracksLoaded(int,MimeData*))); connect(provider, SIGNAL(destroyed(QObject*)), SLOT(ProviderDestroyedSlot(QObject*))); @@ -190,3 +192,11 @@ bool GlobalSearch::FindCachedPixmap(const SearchProvider::Result& result, return pixmap_cache_.find(result.pixmap_cache_key_, pixmap); } +int GlobalSearch::LoadTracksAsync(const SearchProvider::Result& result) { + const int id = next_id_ ++; + + result.provider_->LoadTracksAsync(id, result); + + return id; +} + diff --git a/src/globalsearch/globalsearch.h b/src/globalsearch/globalsearch.h index f1447d04b..6d353097c 100644 --- a/src/globalsearch/globalsearch.h +++ b/src/globalsearch/globalsearch.h @@ -36,6 +36,7 @@ public: int SearchAsync(const QString& query); int LoadArtAsync(const SearchProvider::Result& result); + int LoadTracksAsync(const SearchProvider::Result& result); void CancelSearch(int id); void CancelArt(int id); @@ -49,6 +50,8 @@ signals: void ArtLoaded(int id, const QPixmap& pixmap); + void TracksLoaded(int id, MimeData* mime_data); + void ProviderDestroyed(SearchProvider* provider); protected: diff --git a/src/globalsearch/globalsearchwidget.cpp b/src/globalsearch/globalsearchwidget.cpp index 1df57e739..21c4d6199 100644 --- a/src/globalsearch/globalsearchwidget.cpp +++ b/src/globalsearch/globalsearchwidget.cpp @@ -24,6 +24,7 @@ #include "ui_globalsearchwidget.h" #include "core/logging.h" #include "core/utilities.h" +#include "playlist/songmimedata.h" #include "widgets/stylehelper.h" #ifdef HAVE_SPOTIFY @@ -73,6 +74,8 @@ GlobalSearchWidget::GlobalSearchWidget(QWidget* parent) SLOT(AddResults(int,SearchProvider::ResultList))); connect(engine_, SIGNAL(SearchFinished(int)), SLOT(SearchFinished(int))); connect(engine_, SIGNAL(ArtLoaded(int,QPixmap)), SLOT(ArtLoaded(int,QPixmap))); + connect(engine_, SIGNAL(TracksLoaded(int,MimeData*)), SLOT(TracksLoaded(int,MimeData*))); + connect(view_, SIGNAL(doubleClicked(QModelIndex)), SLOT(AddCurrent())); } GlobalSearchWidget::~GlobalSearchWidget() { @@ -276,7 +279,7 @@ bool GlobalSearchWidget::eventFilter(QObject* o, QEvent* e) { case Qt::Key_Enter: case Qt::Key_Tab: view_->hide(); - // TODO: complete + AddCurrent(); break; case Qt::Key_F4: @@ -339,3 +342,24 @@ void GlobalSearchWidget::ArtLoaded(int id, const QPixmap& pixmap) { model_->itemFromIndex(index)->setData(pixmap, Qt::DecorationRole); } +void GlobalSearchWidget::AddCurrent() { + QModelIndex index = view_->currentIndex(); + if (!index.isValid()) + index = proxy_->index(0, 0); + + if (!index.isValid()) + return; + + engine_->LoadTracksAsync(index.data(Role_Result).value()); +} + +void GlobalSearchWidget::TracksLoaded(int id, MimeData* mime_data) { + Q_UNUSED(id); + + if (!mime_data) + return; + + mime_data->from_doubleclick_ = true; + emit AddToPlaylist(mime_data); +} + diff --git a/src/globalsearch/globalsearchwidget.h b/src/globalsearch/globalsearchwidget.h index 38ded445f..cfa1cc75f 100644 --- a/src/globalsearch/globalsearchwidget.h +++ b/src/globalsearch/globalsearchwidget.h @@ -27,6 +27,7 @@ class LibraryBackendInterface; class Ui_GlobalSearchWidget; class QListView; +class QMimeData; class QModelIndex; class QSortFilterProxyModel; class QStandardItemModel; @@ -55,6 +56,9 @@ public: // QWidget bool eventFilter(QObject* o, QEvent* e); +signals: + void AddToPlaylist(QMimeData* data); + protected: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); @@ -66,6 +70,10 @@ private slots: void ArtLoaded(int id, const QPixmap& pixmap); + void TracksLoaded(int id, MimeData* mime_data); + + void AddCurrent(); + private: void Reset(); void RepositionPopup(); diff --git a/src/globalsearch/librarysearchprovider.cpp b/src/globalsearch/librarysearchprovider.cpp index fee3e660a..c14bb618c 100644 --- a/src/globalsearch/librarysearchprovider.cpp +++ b/src/globalsearch/librarysearchprovider.cpp @@ -21,6 +21,7 @@ #include "library/librarybackend.h" #include "library/libraryquery.h" #include "library/sqlrow.h" +#include "playlist/songmimedata.h" LibrarySearchProvider::LibrarySearchProvider(LibraryBackendInterface* backend, @@ -122,5 +123,40 @@ void LibrarySearchProvider::AlbumArtLoaded(quint64 id, const QImage& image) { } void LibrarySearchProvider::LoadTracksAsync(int id, const Result& result) { - emit TracksLoaded(id, SongList()); + SongList ret; + + switch (result.type_) { + case Result::Type_Track: + // This is really easy - we just emit the track again. + ret << result.metadata_; + break; + + case Result::Type_Album: { + // Find all the songs in this album. + LibraryQuery query; + query.SetOrderBy("track"); + query.SetColumnSpec("ROWID, " + Song::kColumnSpec); + query.AddCompilationRequirement(result.metadata_.is_compilation()); + query.AddWhere("album", result.metadata_.album()); + + if (!result.metadata_.is_compilation()) + query.AddWhere("artist", result.metadata_.artist()); + + if (!backend_->ExecQuery(&query)) { + break; + } + + while (query.Next()) { + Song song; + song.InitFromQuery(query, true); + ret << song; + } + } + } + + SongMimeData* mime_data = new SongMimeData; + mime_data->backend = backend_; + mime_data->songs = ret; + + emit TracksLoaded(id, mime_data); } diff --git a/src/globalsearch/searchprovider.h b/src/globalsearch/searchprovider.h index 55950afc5..2d7ea3e28 100644 --- a/src/globalsearch/searchprovider.h +++ b/src/globalsearch/searchprovider.h @@ -24,6 +24,9 @@ #include "core/song.h" +class MimeData; + + class SearchProvider : public QObject { Q_OBJECT @@ -93,7 +96,7 @@ signals: void ArtLoaded(int id, const QImage& image); - void TracksLoaded(int id, const SongList& tracks); + void TracksLoaded(int id, MimeData* mime_data); protected: // These functions treat queries in the same way as LibraryQuery. They're diff --git a/src/globalsearch/spotifysearchprovider.cpp b/src/globalsearch/spotifysearchprovider.cpp index 9f5680f6f..91f385cb7 100644 --- a/src/globalsearch/spotifysearchprovider.cpp +++ b/src/globalsearch/spotifysearchprovider.cpp @@ -134,7 +134,7 @@ void SpotifySearchProvider::ArtLoadedSlot(const QString& id, const QImage& image } void SpotifySearchProvider::LoadTracksAsync(int id, const Result& result) { - emit TracksLoaded(id, SongList()); + emit TracksLoaded(id, NULL); } diff --git a/src/library/librarybackend.h b/src/library/librarybackend.h index 54dad4429..fab2e3634 100644 --- a/src/library/librarybackend.h +++ b/src/library/librarybackend.h @@ -56,6 +56,8 @@ public: }; typedef QList AlbumList; + virtual QString songs_table() const = 0; + // Get a list of directories in the library. Emits DirectoriesDiscovered. virtual void LoadDirectoriesAsync() = 0; diff --git a/src/playlist/songmimedata.h b/src/playlist/songmimedata.h index 95b8e96f6..f35d6a265 100644 --- a/src/playlist/songmimedata.h +++ b/src/playlist/songmimedata.h @@ -23,7 +23,7 @@ #include "core/mimedata.h" #include "core/song.h" -class LibraryBackend; +class LibraryBackendInterface; class SongMimeData : public MimeData { Q_OBJECT @@ -32,7 +32,7 @@ public: SongMimeData() : backend(NULL) {} - LibraryBackend* backend; + LibraryBackendInterface* backend; SongList songs; }; diff --git a/src/ui/albumcovermanagerlist.cpp b/src/ui/albumcovermanagerlist.cpp index 0d54b58b8..a73cb9f5a 100644 --- a/src/ui/albumcovermanagerlist.cpp +++ b/src/ui/albumcovermanagerlist.cpp @@ -17,6 +17,7 @@ #include "albumcovermanager.h" #include "albumcovermanagerlist.h" +#include "library/librarybackend.h" #include "playlist/songmimedata.h" #include diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index f060bc293..89fd8dbd9 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -229,7 +229,9 @@ MainWindow::MainWindow( // Initialise the global search widget StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker()); + ui_->global_search->Init(library_->backend()); + connect(ui_->global_search, SIGNAL(AddToPlaylist(QMimeData*)), SLOT(AddToPlaylist(QMimeData*))); // Add tabs to the fancy tab widget ui_->tabs->AddTab(library_view_, IconLoader::Load("folder-sound"), tr("Library"));