From cf826aeee0903dccbbd5fe967eeed689837a6dcd Mon Sep 17 00:00:00 2001 From: David Sansome Date: Mon, 14 Mar 2011 20:01:27 +0000 Subject: [PATCH] Support dragging and dropping image files onto the now playing widget and edit tag dialog to set an album's cover art --- src/ui/albumcoverchoicecontroller.cpp | 38 ++++++++++++++++++++++++++- src/ui/albumcoverchoicecontroller.h | 8 ++++++ src/ui/edittagdialog.cpp | 33 +++++++++++++++++++++-- src/ui/edittagdialog.ui | 2 +- src/widgets/nowplayingwidget.cpp | 24 ++++++++++++++--- src/widgets/nowplayingwidget.h | 2 ++ 6 files changed, 99 insertions(+), 8 deletions(-) diff --git a/src/ui/albumcoverchoicecontroller.cpp b/src/ui/albumcoverchoicecontroller.cpp index 334673ace..b20d001c0 100644 --- a/src/ui/albumcoverchoicecontroller.cpp +++ b/src/ui/albumcoverchoicecontroller.cpp @@ -31,11 +31,13 @@ #include #include #include +#include #include #include #include #include #include +#include const char* AlbumCoverChoiceController::kLoadImageFileFilter = QT_TR_NOOP("Images (*.png *.jpg *.jpeg *.bmp *.gif *.xpm *.pbm *.pgm *.ppm *.xbm)"); @@ -44,6 +46,8 @@ const char* AlbumCoverChoiceController::kSaveImageFileFilter = const char* AlbumCoverChoiceController::kAllFilesFilter = QT_TR_NOOP("All files (*)"); +QSet* AlbumCoverChoiceController::sImageExtensions = NULL; + AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget* parent) : QWidget(parent), #ifdef HAVE_LIBLASTFM @@ -228,5 +232,37 @@ QString AlbumCoverChoiceController::SaveCoverInCache( image.save(path, "JPG"); return path; - +} + +bool AlbumCoverChoiceController::IsKnownImageExtension(const QString& suffix) { + if (!sImageExtensions) { + sImageExtensions = new QSet(); + (*sImageExtensions) << "png" << "jpg" << "jpeg" << "bmp" << "gif" << "xpm" + << "pbm" << "pgm" << "ppm" << "xbm"; + } + + return sImageExtensions->contains(suffix); +} + +bool AlbumCoverChoiceController::CanAcceptDrag(const QDragEnterEvent* e) { + foreach (const QUrl& url, e->mimeData()->urls()) { + const QString suffix = QFileInfo(url.toLocalFile()).suffix().toLower(); + if (IsKnownImageExtension(suffix)) + return true; + } + return false; +} + +QString AlbumCoverChoiceController::SaveCover(Song* song, const QDropEvent* e) { + foreach (const QUrl& url, e->mimeData()->urls()) { + const QString filename = url.toLocalFile(); + const QString suffix = QFileInfo(filename).suffix().toLower(); + + if (IsKnownImageExtension(suffix)) { + SaveCover(song, filename); + return filename; + } + } + + return QString(); } diff --git a/src/ui/albumcoverchoicecontroller.h b/src/ui/albumcoverchoicecontroller.h index 2b8bf8d60..7e3824bfb 100644 --- a/src/ui/albumcoverchoicecontroller.h +++ b/src/ui/albumcoverchoicecontroller.h @@ -95,10 +95,15 @@ class AlbumCoverChoiceController : public QWidget { // Saves the chosen cover as manual cover path of this song in library. void SaveCover(Song* song, const QString& cover); + // Saves the cover that the user picked through a drag and drop operation. + QString SaveCover(Song* song, const QDropEvent* e); + // Saves the given image in cache as a cover for 'artist' - 'album'. // The method returns path of the cached image. QString SaveCoverInCache(const QString& artist, const QString& album, const QImage& image); + static bool CanAcceptDrag(const QDragEnterEvent* e); + private: QString GetInitialPathForFileDialog(const Song& song, const QString& filename); @@ -107,6 +112,9 @@ private: static const char* kSaveImageFileFilter; static const char* kAllFilesFilter; + static bool IsKnownImageExtension(const QString& suffix); + static QSet* sImageExtensions; + #ifdef HAVE_LIBLASTFM AlbumCoverSearcher* cover_searcher_; AlbumCoverFetcher* cover_fetcher_; diff --git a/src/ui/edittagdialog.cpp b/src/ui/edittagdialog.cpp index 67701d79f..c87f65de8 100644 --- a/src/ui/edittagdialog.cpp +++ b/src/ui/edittagdialog.cpp @@ -145,6 +145,7 @@ EditTagDialog::EditTagDialog(QWidget* parent) ui_->summary_art_button->setMenu(cover_menu_); ui_->art->installEventFilter(this); + ui_->art->setAcceptDrops(true); // Add the next/previous buttons previous_button_ = new QPushButton(IconLoader::Load("go-previous"), tr("Previous"), this); @@ -632,8 +633,36 @@ void EditTagDialog::AcceptFinished() { } bool EditTagDialog::eventFilter(QObject* o, QEvent* e) { - if (o == ui_->art && e->type() == QEvent::MouseButtonRelease) { - cover_menu_->popup(static_cast(e)->globalPos()); + if (o == ui_->art) { + switch (e->type()) { + case QEvent::MouseButtonRelease: + cover_menu_->popup(static_cast(e)->globalPos()); + break; + + case QEvent::DragEnter: { + QDragEnterEvent* event = static_cast(e); + if (AlbumCoverChoiceController::CanAcceptDrag(event)) { + event->acceptProposedAction(); + } + break; + } + + case QEvent::Drop: { + const QDropEvent* event = static_cast(e); + const QModelIndexList sel = ui_->song_list->selectionModel()->selectedIndexes(); + Song* song = GetFirstSelected(); + + const QString cover = album_cover_choice_controller_->SaveCover(song, event); + if (!cover.isEmpty()) { + UpdateCoverOf(*song, sel, cover); + } + + break; + } + + default: + break; + } } return false; } diff --git a/src/ui/edittagdialog.ui b/src/ui/edittagdialog.ui index b29630ed6..8f783801c 100644 --- a/src/ui/edittagdialog.ui +++ b/src/ui/edittagdialog.ui @@ -30,7 +30,7 @@ - 1 + 0 diff --git a/src/widgets/nowplayingwidget.cpp b/src/widgets/nowplayingwidget.cpp index 3c366cdec..7773c0956 100644 --- a/src/widgets/nowplayingwidget.cpp +++ b/src/widgets/nowplayingwidget.cpp @@ -78,6 +78,9 @@ NowPlayingWidget::NowPlayingWidget(QWidget *parent) s.beginGroup(kSettingsGroup); mode_ = Mode(s.value("mode", SmallSongDetails).toInt()); + // Accept drops for setting album art + setAcceptDrops(true); + // Context menu QActionGroup* mode_group = new QActionGroup(this); QSignalMapper* mode_mapper = new QSignalMapper(this); @@ -370,16 +373,14 @@ void NowPlayingWidget::resizeEvent(QResizeEvent* e) { void NowPlayingWidget::contextMenuEvent(QContextMenuEvent* e) { // initial 'enabled' values depending on the kitty mode album_cover_choice_controller_->cover_from_file_action()->setEnabled(!aww_); - album_cover_choice_controller_->cover_to_file_action()->setEnabled(!aww_); + album_cover_choice_controller_->cover_to_file_action()->setEnabled(aww_); album_cover_choice_controller_->cover_from_url_action()->setEnabled(!aww_); album_cover_choice_controller_->search_for_cover_action()->setEnabled(!aww_); album_cover_choice_controller_->unset_cover_action()->setEnabled(!aww_); album_cover_choice_controller_->show_cover_action()->setEnabled(!aww_); // some special cases - if(aww_) { - album_cover_choice_controller_->cover_to_file_action()->setEnabled(true); - } else { + if (!aww_) { #ifndef HAVE_LIBLASTFM album_cover_choice_controller_->cover_from_file_action()->setEnabled(false); album_cover_choice_controller_->search_for_cover_action()->setEnabled(false); @@ -476,3 +477,18 @@ void NowPlayingWidget::Bask() { big_hypnotoad_.reset(new FullscreenHypnotoad); big_hypnotoad_->showFullScreen(); } + +void NowPlayingWidget::dragEnterEvent(QDragEnterEvent* e) { + if (AlbumCoverChoiceController::CanAcceptDrag(e)) { + e->acceptProposedAction(); + } + + QWidget::dragEnterEvent(e); +} + +void NowPlayingWidget::dropEvent(QDropEvent* e) { + album_cover_choice_controller_->SaveCover(&metadata_, e); + NowPlaying(metadata_); + + QWidget::dropEvent(e); +} diff --git a/src/widgets/nowplayingwidget.h b/src/widgets/nowplayingwidget.h index 5bcbf4cca..8f25b47ad 100644 --- a/src/widgets/nowplayingwidget.h +++ b/src/widgets/nowplayingwidget.h @@ -79,6 +79,8 @@ protected: void paintEvent(QPaintEvent* e); void resizeEvent(QResizeEvent*); void contextMenuEvent(QContextMenuEvent* e); + void dragEnterEvent(QDragEnterEvent* e); + void dropEvent(QDropEvent* e); private slots: void SetMode(int mode);