From 101b30c4b59653d9130966a3bbe0a70945aa5321 Mon Sep 17 00:00:00 2001 From: David Sansome Date: Wed, 3 Mar 2010 14:29:53 +0000 Subject: [PATCH] Add some more options to the album cover manager: show fullsize, fetch automatically, choose manually, unset cover --- data/data.qrc | 1 + data/zoom-in.png | Bin 0 -> 1191 bytes src/albumcoverloader.cpp | 30 ++++++++-- src/albumcoverloader.h | 5 ++ src/albumcovermanager.cpp | 122 ++++++++++++++++++++++++++++++++++++-- src/albumcovermanager.h | 14 +++++ src/albumcovermanager.ui | 40 ++++++++++++- src/song.cpp | 9 ++- 8 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 data/zoom-in.png diff --git a/data/data.qrc b/data/data.qrc index 22edaf759..30bf46669 100644 --- a/data/data.qrc +++ b/data/data.qrc @@ -64,5 +64,6 @@ nocover.png view-choose.png download.png + zoom-in.png diff --git a/data/zoom-in.png b/data/zoom-in.png new file mode 100644 index 0000000000000000000000000000000000000000..8393e281aad5e679f45139d6d940ac0646072204 GIT binary patch literal 1191 zcmV;Y1X%ltP)GLZP?+=%wwwy}kcD4|^~n6wUOLd|yuP z_nTkNJ>PS{{{;g6hF-5nMn=ADEw8BPqe!X=K@q&b7uM2D`iECv8MwtTjQp>Ihlhu& z+uI$V$CBBzQ}@D1n9j$q2wNprH&&tc4W(f%-_}-28^jkRHUfomi42 zTCc+l8CgNheaEL9M$LB>6jm7j!g~ei2=Mwx@4uZCWIVx&n$$|N!l0!nRADmEmnpi( z>2&(17Bi(`H)2MS7ctlX2}6-W#1{nN#ULOtlm`e9C0PMtE>AgYsH#{jb{BecMS~|M zCPqpLhH+^5HZGdhv%E<1iUORj%5OS7maim4k@KR0b7@XnM#oy)P4a=6ncqHvUa9Cg zW*{1kmhSZ&9YC|l!R3sS6tpV7*4g;bWN%)jSxHCJ8KY^7KJiiw-({{c;PANRSeE@U z7!1nA3IhCo-y*Ew=4pHF^Ihe-cD=_JEd_Ld&ojbR`HI`DiUQ9LB$=jC0JYBD>FA|UDXMX zev8F&dvbDevqw|l_laxILGjy^0Byg$)sGz&X$ z&1$u}w^J!I$8i+grvC2k?npM9oyWiv5Rb<>nx?O{KwuM_U~w>;&DINFq5uY-kVGO; z2!%qUcDubstJSu8z1}|pfxsp3Utuztu=gMykH-ige*p#7_HGjoqu~Gm002ovPDHLk FV1mKNG^+pr literal 0 HcmV?d00001 diff --git a/src/albumcoverloader.cpp b/src/albumcoverloader.cpp index 688624af3..cfb1c398c 100644 --- a/src/albumcoverloader.cpp +++ b/src/albumcoverloader.cpp @@ -4,6 +4,8 @@ #include #include +const char* AlbumCoverLoader::kManuallyUnsetCover = "(unset)"; + AlbumCoverLoader::AlbumCoverLoader(QObject* parent) : QObject(parent), height_(120), @@ -50,11 +52,7 @@ void AlbumCoverLoader::ProcessTasks() { } // Try to load the image - QImage image; - if (!task.art_manual.isEmpty()) - image.load(task.art_manual); - if (!task.art_automatic.isEmpty() && image.isNull()) - image.load(task.art_automatic); + QImage image(TryLoadImage(task.art_automatic, task.art_manual)); if (!image.isNull()) { // Scale the image down @@ -75,3 +73,25 @@ void AlbumCoverLoader::ProcessTasks() { emit ImageLoaded(task.id, image); } } + +QImage AlbumCoverLoader::TryLoadImage(const QString &automatic, const QString &manual) { + QImage ret; + if (manual == kManuallyUnsetCover) + return ret; + if (!manual.isEmpty()) + ret.load(manual); + if (!automatic.isEmpty() && ret.isNull()) + ret.load(automatic); + return ret; +} + +QPixmap AlbumCoverLoader::TryLoadPixmap(const QString &automatic, const QString &manual) { + QPixmap ret; + if (manual == kManuallyUnsetCover) + return ret; + if (!manual.isEmpty()) + ret.load(manual); + if (!automatic.isEmpty() && ret.isNull()) + ret.load(automatic); + return ret; +} diff --git a/src/albumcoverloader.h b/src/albumcoverloader.h index b28ffdbdd..9f140b4ab 100644 --- a/src/albumcoverloader.h +++ b/src/albumcoverloader.h @@ -21,6 +21,11 @@ class AlbumCoverLoader : public QObject { void Clear(); + static QImage TryLoadImage(const QString& automatic, const QString& manual); + static QPixmap TryLoadPixmap(const QString& automatic, const QString& manual); + + static const char* kManuallyUnsetCover; + signals: void ImageLoaded(quint64 id, const QImage& image); diff --git a/src/albumcovermanager.cpp b/src/albumcovermanager.cpp index e7d124074..c9c0ed270 100644 --- a/src/albumcovermanager.cpp +++ b/src/albumcovermanager.cpp @@ -12,6 +12,10 @@ #include #include #include +#include +#include +#include +#include const char* AlbumCoverManager::kSettingsGroup = "CoverManager"; @@ -21,7 +25,8 @@ AlbumCoverManager::AlbumCoverManager(QWidget *parent) cover_loader_(new BackgroundThread(this)), cover_fetcher_(new AlbumCoverFetcher(this)), artist_icon_(":/artist.png"), - all_artists_icon_(":/album.png") + all_artists_icon_(":/album.png"), + context_menu_(new QMenu(this)) { ui_.setupUi(this); @@ -37,9 +42,9 @@ AlbumCoverManager::AlbumCoverManager(QWidget *parent) // View menu QActionGroup* filter_group = new QActionGroup(this); - filter_all_ = filter_group->addAction("All albums"); - filter_with_covers_ = filter_group->addAction("Albums with covers"); - filter_without_covers_ = filter_group->addAction("Albums without covers"); + filter_all_ = filter_group->addAction(tr("All albums")); + filter_with_covers_ = filter_group->addAction(tr("Albums with covers")); + filter_without_covers_ = filter_group->addAction(tr("Albums without covers")); filter_all_->setCheckable(true); filter_with_covers_->setCheckable(true); filter_without_covers_->setCheckable(true); @@ -51,6 +56,14 @@ AlbumCoverManager::AlbumCoverManager(QWidget *parent) ui_.view->setMenu(view_menu); + // Context menu + context_menu_->addAction(ui_.action_show_fullsize); + context_menu_->addAction(ui_.action_fetch); + context_menu_->addAction(ui_.action_choose_manual); + context_menu_->addSeparator(); + context_menu_->addAction(ui_.action_unset_cover); + ui_.albums->installEventFilter(this); + // Connections connect(cover_loader_, SIGNAL(Initialised()), SLOT(CoverLoaderInitialised())); connect(ui_.artists, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), @@ -61,6 +74,10 @@ AlbumCoverManager::AlbumCoverManager(QWidget *parent) connect(ui_.fetch, SIGNAL(clicked()), SLOT(FetchAlbumCovers())); connect(cover_fetcher_, SIGNAL(AlbumCoverFetched(quint64,QImage)), SLOT(AlbumCoverFetched(quint64,QImage))); + connect(ui_.action_show_fullsize, SIGNAL(triggered()), SLOT(ShowFullsize())); + connect(ui_.action_fetch, SIGNAL(triggered()), SLOT(FetchSingleCover())); + connect(ui_.action_choose_manual, SIGNAL(triggered()), SLOT(ChooseManualCover())); + connect(ui_.action_unset_cover, SIGNAL(triggered()), SLOT(UnsetCover())); // Restore settings QSettings s; @@ -122,7 +139,7 @@ void AlbumCoverManager::Reset() { return; ui_.artists->clear(); - new QListWidgetItem(all_artists_icon_, "All artists", ui_.artists, All_Artists); + new QListWidgetItem(all_artists_icon_, tr("All artists"), ui_.artists, All_Artists); foreach (const QString& artist, backend_->GetAllArtists()) { if (artist.isEmpty()) @@ -143,6 +160,7 @@ void AlbumCoverManager::ArtistChanged(QListWidgetItem* current) { artist = current->text(); ui_.albums->clear(); + context_menu_items_.clear(); CancelRequests(); foreach (const LibraryBackend::Album& info, @@ -154,6 +172,8 @@ void AlbumCoverManager::ArtistChanged(QListWidgetItem* current) { if (!info.art_automatic.isEmpty() || !info.art_manual.isEmpty()) { quint64 id = cover_loader_->Worker()->LoadImageAsync( info.art_automatic, info.art_manual); + item->setData(Role_PathAutomatic, info.art_automatic); + item->setData(Role_PathManual, info.art_manual); cover_loading_tasks_[id] = item; } } @@ -236,6 +256,7 @@ void AlbumCoverManager::AlbumCoverFetched(quint64 id, const QImage &image) { // Update the icon in our list quint64 id = cover_loader_->Worker()->LoadImageAsync(QString(), path); + item->setData(Role_PathManual, path); cover_loading_tasks_[id] = item; } @@ -250,10 +271,99 @@ bool AlbumCoverManager::event(QEvent* e) { // We seem to have to reset them to sensible values each time the contents // of ui_.albums changes. ui_.albums->setVerticalScrollMode(QListWidget::ScrollPerPixel); - //ui_.albums->verticalScrollBar()->setPageStep(10); ui_.albums->verticalScrollBar()->setSingleStep(20); } QDialog::event(e); return false; } + +bool AlbumCoverManager::eventFilter(QObject *obj, QEvent *event) { + if (obj == ui_.albums && event->type() == QEvent::ContextMenu) { + context_menu_items_ = ui_.albums->selectedItems(); + if (context_menu_items_.isEmpty()) + return false; + + bool some_with_covers = false; + + foreach (QListWidgetItem* item, context_menu_items_) { + if (item->icon().cacheKey() != no_cover_icon_.cacheKey()) + some_with_covers = true; + } + + ui_.action_show_fullsize->setEnabled(some_with_covers && context_menu_items_.size() == 1); + ui_.action_choose_manual->setEnabled(context_menu_items_.size() == 1); + ui_.action_unset_cover->setEnabled(some_with_covers); + + QContextMenuEvent* e = static_cast(event); + context_menu_->popup(e->globalPos()); + return true; + } + return false; +} + +void AlbumCoverManager::ShowFullsize() { + if (context_menu_items_.size() != 1) + return; + QListWidgetItem* item = context_menu_items_[0]; + + QString title = item->data(Role_AlbumName).toString(); + if (!item->data(Role_ArtistName).toString().isNull()) + title = item->data(Role_ArtistName).toString() + " - " + title; + + QDialog* dialog = new QDialog(this); + dialog->setAttribute(Qt::WA_DeleteOnClose, true); + dialog->setWindowTitle(title); + + QLabel* label = new QLabel(dialog); + label->setPixmap(AlbumCoverLoader::TryLoadPixmap( + item->data(Role_PathAutomatic).toString(), + item->data(Role_PathManual).toString())); + + dialog->resize(label->pixmap()->size()); + dialog->show(); +} + +void AlbumCoverManager::FetchSingleCover() { + foreach (QListWidgetItem* item, context_menu_items_) { + quint64 id = cover_fetcher_->FetchAlbumCover( + item->data(Role_ArtistName).toString(), item->data(Role_AlbumName).toString()); + cover_fetching_tasks_[id] = item; + } +} + +void AlbumCoverManager::ChooseManualCover() { + if (context_menu_items_.size() != 1) + return; + QListWidgetItem* item = context_menu_items_[0]; + + QString cover = QFileDialog::getOpenFileName( + this, tr("Choose manual cover"), item->data(Role_PathAutomatic).toString()); + if (cover.isNull()) + return; + + // Can we load the image? + QImage image(cover); + if (image.isNull()) + return; + + // Update database + backend_->UpdateManualAlbumArtAsync(item->data(Role_ArtistName).toString(), + item->data(Role_AlbumName).toString(), + cover); + + // Update the icon in our list + quint64 id = cover_loader_->Worker()->LoadImageAsync(QString(), cover); + item->setData(Role_PathManual, cover); + cover_loading_tasks_[id] = item; +} + +void AlbumCoverManager::UnsetCover() { + foreach (QListWidgetItem* item, context_menu_items_) { + item->setIcon(no_cover_icon_); + item->setData(Role_PathManual, AlbumCoverLoader::kManuallyUnsetCover); + backend_->UpdateManualAlbumArtAsync(item->data(Role_ArtistName).toString(), + item->data(Role_AlbumName).toString(), + AlbumCoverLoader::kManuallyUnsetCover); + } +} diff --git a/src/albumcovermanager.h b/src/albumcovermanager.h index 131813d1b..abacb8e6c 100644 --- a/src/albumcovermanager.h +++ b/src/albumcovermanager.h @@ -31,6 +31,9 @@ class AlbumCoverManager : public QDialog { void closeEvent(QCloseEvent *); bool event(QEvent *); + // For the album view context menu events + bool eventFilter(QObject *obj, QEvent *event); + private slots: void ArtistChanged(QListWidgetItem* current); void CoverLoaderInitialised(); @@ -39,6 +42,12 @@ class AlbumCoverManager : public QDialog { void FetchAlbumCovers(); void AlbumCoverFetched(quint64 id, const QImage& image); + // On the context menu + void ShowFullsize(); + void FetchSingleCover(); + void ChooseManualCover(); + void UnsetCover(); + private: enum ArtistItemType { All_Artists, @@ -48,6 +57,8 @@ class AlbumCoverManager : public QDialog { enum Role { Role_ArtistName = Qt::UserRole + 1, Role_AlbumName, + Role_PathAutomatic, + Role_PathManual, }; void CancelRequests(); @@ -71,6 +82,9 @@ class AlbumCoverManager : public QDialog { QIcon artist_icon_; QIcon all_artists_icon_; QIcon no_cover_icon_; + + QMenu* context_menu_; + QList context_menu_items_; }; #endif // ALBUMCOVERMANAGER_H diff --git a/src/albumcovermanager.ui b/src/albumcovermanager.ui index 236f212ac..9ca80508e 100644 --- a/src/albumcovermanager.ui +++ b/src/albumcovermanager.ui @@ -124,6 +124,42 @@ + + + + :/zoom-in.png:/zoom-in.png + + + Show fullsize... + + + + + + :/download.png:/download.png + + + Fetch automatically + + + + + + :/open_media.png:/open_media.png + + + Choose manual cover... + + + + + + :/list-remove.png:/list-remove.png + + + Unset cover + + @@ -140,9 +176,7 @@ fetch albums - - - + clear diff --git a/src/song.cpp b/src/song.cpp index 5b4573656..0798f19f2 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -21,6 +21,7 @@ #include "trackslider.h" #include "enginebase.h" +#include "albumcoverloader.h" const char* Song::kColumnSpec = "title, album, artist, albumartist, composer, " @@ -372,11 +373,9 @@ QImage Song::GetBestImage() const { if (!d->image_.isNull()) return d->image_; - if (!d->art_manual_.isEmpty()) - return QImage(d->art_manual_); - - if (!d->art_automatic_.isEmpty()) - return QImage(d->art_automatic_); + QImage art(AlbumCoverLoader::TryLoadImage(d->art_automatic_, d->art_manual_)); + if (!art.isNull()) + return art; return QImage(":/nocover.png"); }