diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cddc7b705..5dba787dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,6 +138,7 @@ set(SOURCES globalsearch/digitallyimportedsearchprovider.cpp globalsearch/globalsearch.cpp + globalsearch/globalsearchitemdelegate.cpp globalsearch/globalsearchsettingspage.cpp globalsearch/globalsearchsortmodel.cpp globalsearch/globalsearchview.cpp diff --git a/src/globalsearch/globalsearchitemdelegate.cpp b/src/globalsearch/globalsearchitemdelegate.cpp new file mode 100644 index 000000000..bd5f8d763 --- /dev/null +++ b/src/globalsearch/globalsearchitemdelegate.cpp @@ -0,0 +1,34 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + 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 . +*/ + +#include "globalsearchitemdelegate.h" +#include "globalsearchview.h" + +GlobalSearchItemDelegate::GlobalSearchItemDelegate(GlobalSearchView* view) + : LibraryItemDelegate(view), + view_(view) +{ +} + +void GlobalSearchItemDelegate::paint( + QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const { + // Tell the view we painted this item so it can lazy load some art. + const_cast(view_)->LazyLoadArt(index); + + LibraryItemDelegate::paint(painter, option, index); +} diff --git a/src/globalsearch/globalsearchitemdelegate.h b/src/globalsearch/globalsearchitemdelegate.h new file mode 100644 index 000000000..72536a57d --- /dev/null +++ b/src/globalsearch/globalsearchitemdelegate.h @@ -0,0 +1,36 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + 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 . +*/ + +#ifndef GLOBALSEARCHITEMDELEGATE_H +#define GLOBALSEARCHITEMDELEGATE_H + +#include "library/libraryview.h" + +class GlobalSearchView; + +class GlobalSearchItemDelegate : public LibraryItemDelegate { +public: + GlobalSearchItemDelegate(GlobalSearchView* view); + + void paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + +private: + GlobalSearchView* view_; +}; + +#endif // GLOBALSEARCHITEMDELEGATE_H diff --git a/src/globalsearch/globalsearchview.cpp b/src/globalsearch/globalsearchview.cpp index f37232d45..864bd6f80 100644 --- a/src/globalsearch/globalsearchview.cpp +++ b/src/globalsearch/globalsearchview.cpp @@ -16,6 +16,7 @@ */ #include "globalsearch.h" +#include "globalsearchitemdelegate.h" #include "globalsearchsortmodel.h" #include "globalsearchview.h" #include "searchprovider.h" @@ -24,7 +25,6 @@ #include "core/logging.h" #include "core/mimedata.h" #include "library/librarymodel.h" -#include "library/libraryview.h" #include #include @@ -44,18 +44,24 @@ GlobalSearchView::GlobalSearchView(Application* app, QWidget* parent) front_proxy_(new GlobalSearchSortModel(this)), back_proxy_(new GlobalSearchSortModel(this)), current_proxy_(front_proxy_), - swap_models_timer_(new QTimer(this)) + swap_models_timer_(new QTimer(this)), + artist_icon_(":/icons/22x22/x-clementine-artist.png"), + album_icon_(":/icons/22x22/x-clementine-album.png") { ui_->setupUi(this); connect(ui_->search, SIGNAL(textChanged(QString)), SLOT(TextEdited(QString))); - ui_->results->setItemDelegate(new LibraryItemDelegate(this)); + ui_->results->setItemDelegate(new GlobalSearchItemDelegate(this)); group_by_[0] = LibraryModel::GroupBy_Artist; group_by_[1] = LibraryModel::GroupBy_Album; group_by_[2] = LibraryModel::GroupBy_None; + no_cover_icon_ = QPixmap(":nocover.png").scaled( + LibraryModel::kPrettyCoverSize, LibraryModel::kPrettyCoverSize, + Qt::KeepAspectRatio, Qt::SmoothTransformation); + // Set up the sorting proxy model front_proxy_->setSourceModel(front_model_); front_proxy_->setDynamicSortFilter(true); @@ -164,6 +170,7 @@ QStandardItem* GlobalSearchView::BuildContainers( return parent; } + QIcon icon; QString display_text; QString sort_text; int year = 0; @@ -172,12 +179,14 @@ QStandardItem* GlobalSearchView::BuildContainers( case LibraryModel::GroupBy_Artist: display_text = LibraryModel::TextOrUnknown(s.artist()); sort_text = LibraryModel::SortTextForArtist(s.artist()); + icon = artist_icon_; break; case LibraryModel::GroupBy_YearAlbum: year = qMax(0, s.year()); display_text = LibraryModel::PrettyYearAlbum(year, s.album()); sort_text = LibraryModel::SortTextForYear(year) + s.album(); + icon = album_icon_; break; case LibraryModel::GroupBy_Year: @@ -192,6 +201,7 @@ QStandardItem* GlobalSearchView::BuildContainers( case LibraryModel::GroupBy_AlbumArtist: if (display_text.isNull()) display_text = s.effective_albumartist(); display_text = LibraryModel::TextOrUnknown(display_text); sort_text = LibraryModel::SortTextForArtist(display_text); + icon = album_icon_; break; case LibraryModel::GroupBy_FileType: @@ -207,7 +217,7 @@ QStandardItem* GlobalSearchView::BuildContainers( key->group_[level] = display_text; QStandardItem* container = containers_[*key]; if (!container) { - container = new QStandardItem(display_text); + container = new QStandardItem(icon, display_text); container->setData(key->provider_index_, Role_ProviderIndex); container->setData(sort_text, LibraryModel::Role_SortText); container->setData(group_by_[level], LibraryModel::Role_ContainerType); @@ -237,12 +247,30 @@ void GlobalSearchView::LazyLoadArt(const QModelIndex& proxy_index) { return; } + // Only load art for albums + const LibraryModel::GroupBy container_type = LibraryModel::GroupBy( + proxy_index.data(LibraryModel::Role_ContainerType).toInt()); + if (container_type != LibraryModel::GroupBy_Album && + container_type != LibraryModel::GroupBy_AlbumArtist && + container_type != LibraryModel::GroupBy_YearAlbum) { + return; + } + + // Mark the item as loading art const QModelIndex source_index = front_proxy_->mapToSource(proxy_index); - front_model_->itemFromIndex(source_index)->setData(true, Role_LazyLoadingArt); + QStandardItem* item = front_model_->itemFromIndex(source_index); + item->setData(true, Role_LazyLoadingArt); + // Walk down the item's children until we find a track + while (item->rowCount()) { + item = item->child(0); + } + + // Get the track's Result const SearchProvider::Result result = - source_index.data(Role_Result).value(); + item->data(Role_Result).value(); + // Load the art. int id = engine_->LoadArtAsync(result); art_requests_[id] = source_index; } diff --git a/src/globalsearch/globalsearchview.h b/src/globalsearch/globalsearchview.h index 4a564bcdc..0850f0931 100644 --- a/src/globalsearch/globalsearchview.h +++ b/src/globalsearch/globalsearchview.h @@ -106,6 +106,10 @@ private: QMap track_requests_; QMap art_requests_; + + QIcon artist_icon_; + QIcon album_icon_; + QPixmap no_cover_icon_; }; inline uint qHash(const GlobalSearchView::ContainerKey& key) { diff --git a/src/globalsearch/globalsearchview.ui b/src/globalsearch/globalsearchview.ui index 1e196178b..a6a2a8ba0 100644 --- a/src/globalsearch/globalsearchview.ui +++ b/src/globalsearch/globalsearchview.ui @@ -28,7 +28,7 @@ - + QAbstractItemView::NoEditTriggers @@ -48,6 +48,11 @@ QLineEdit
widgets/lineedit.h
+ + AutoExpandingTreeView + QTreeView +
widgets/autoexpandingtreeview.h
+
diff --git a/src/library/librarymodel.cpp b/src/library/librarymodel.cpp index 2d496091b..aa2709ed1 100644 --- a/src/library/librarymodel.cpp +++ b/src/library/librarymodel.cpp @@ -71,7 +71,6 @@ LibraryModel::LibraryModel(LibraryBackend* backend, Application* app, total_song_count_(0), artist_icon_(":/icons/22x22/x-clementine-artist.png"), album_icon_(":/icons/22x22/x-clementine-album.png"), - no_cover_icon_(":nocover.png"), playlists_dir_icon_(IconLoader::Load("folder-sound")), playlist_icon_(":/icons/22x22/x-clementine-albums.png"), init_task_id_(-1), @@ -92,7 +91,7 @@ LibraryModel::LibraryModel(LibraryBackend* backend, Application* app, SIGNAL(ImageLoaded(quint64,QImage)), SLOT(AlbumArtLoaded(quint64,QImage))); - no_cover_icon_pretty_ = QPixmap(":nocover.png").scaled( + no_cover_icon_ = QPixmap(":nocover.png").scaled( kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } @@ -405,7 +404,7 @@ QString LibraryModel::AlbumIconPixmapCacheKey(const QModelIndex& index) const { QVariant LibraryModel::AlbumIcon(const QModelIndex& index) { LibraryItem* item = IndexToItem(index); if (!item) - return no_cover_icon_pretty_; + return no_cover_icon_; // Check the cache for a pixmap we already loaded. const QString cache_key = AlbumIconPixmapCacheKey(index); @@ -416,7 +415,7 @@ QVariant LibraryModel::AlbumIcon(const QModelIndex& index) { // Maybe we're loading a pixmap already? if (pending_cache_keys_.contains(cache_key)) { - return no_cover_icon_pretty_; + return no_cover_icon_; } // No art is cached and we're not loading it already. Load art for the first @@ -429,7 +428,7 @@ QVariant LibraryModel::AlbumIcon(const QModelIndex& index) { pending_cache_keys_.insert(cache_key); } - return no_cover_icon_pretty_; + return no_cover_icon_; } void LibraryModel::AlbumArtLoaded(quint64 id, const QImage& image) { @@ -444,7 +443,7 @@ void LibraryModel::AlbumArtLoaded(quint64 id, const QImage& image) { // Insert this image in the cache. if (image.isNull()) { // Set the no_cover image so we don't continually try to load art. - QPixmapCache::insert(cache_key, no_cover_icon_pretty_); + QPixmapCache::insert(cache_key, no_cover_icon_); } else { QPixmapCache::insert(cache_key, QPixmap::fromImage(image)); } diff --git a/src/library/librarymodel.h b/src/library/librarymodel.h index 8fa94f01f..a4a7a509c 100644 --- a/src/library/librarymodel.h +++ b/src/library/librarymodel.h @@ -136,8 +136,9 @@ class LibraryModel : public SimpleTreeModel { // Whether or not to use album cover art, if it exists, in the library view void set_pretty_covers(bool use_pretty_covers); + bool use_pretty_covers() const { return use_pretty_covers_; } - //Whether or not to show letters heading in the library view + // Whether or not to show letters heading in the library view void set_show_dividers(bool show_dividers); // Utility functions for manipulating text @@ -259,8 +260,7 @@ class LibraryModel : public SimpleTreeModel { QIcon album_icon_; // used as a generic icon to show when no cover art is found, // fixed to the same size as the artwork (32x32) - QPixmap no_cover_icon_pretty_; - QIcon no_cover_icon_; + QPixmap no_cover_icon_; QIcon playlists_dir_icon_; QIcon playlist_icon_;