Support dragging and dropping image files onto the now playing widget and edit tag dialog to set an album's cover art

This commit is contained in:
David Sansome 2011-03-14 20:01:27 +00:00
parent c8a0ab9625
commit cf826aeee0
6 changed files with 99 additions and 8 deletions

View File

@ -31,11 +31,13 @@
#include <QAction> #include <QAction>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QDialog> #include <QDialog>
#include <QDragEnterEvent>
#include <QFileDialog> #include <QFileDialog>
#include <QImageWriter> #include <QImageWriter>
#include <QLabel> #include <QLabel>
#include <QList> #include <QList>
#include <QMenu> #include <QMenu>
#include <QUrl>
const char* AlbumCoverChoiceController::kLoadImageFileFilter = const char* AlbumCoverChoiceController::kLoadImageFileFilter =
QT_TR_NOOP("Images (*.png *.jpg *.jpeg *.bmp *.gif *.xpm *.pbm *.pgm *.ppm *.xbm)"); 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 = const char* AlbumCoverChoiceController::kAllFilesFilter =
QT_TR_NOOP("All files (*)"); QT_TR_NOOP("All files (*)");
QSet<QString>* AlbumCoverChoiceController::sImageExtensions = NULL;
AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget* parent) AlbumCoverChoiceController::AlbumCoverChoiceController(QWidget* parent)
: QWidget(parent), : QWidget(parent),
#ifdef HAVE_LIBLASTFM #ifdef HAVE_LIBLASTFM
@ -228,5 +232,37 @@ QString AlbumCoverChoiceController::SaveCoverInCache(
image.save(path, "JPG"); image.save(path, "JPG");
return path; return path;
}
bool AlbumCoverChoiceController::IsKnownImageExtension(const QString& suffix) {
if (!sImageExtensions) {
sImageExtensions = new QSet<QString>();
(*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();
} }

View File

@ -95,10 +95,15 @@ class AlbumCoverChoiceController : public QWidget {
// Saves the chosen cover as manual cover path of this song in library. // Saves the chosen cover as manual cover path of this song in library.
void SaveCover(Song* song, const QString& cover); 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'. // Saves the given image in cache as a cover for 'artist' - 'album'.
// The method returns path of the cached image. // The method returns path of the cached image.
QString SaveCoverInCache(const QString& artist, const QString& album, const QImage& image); QString SaveCoverInCache(const QString& artist, const QString& album, const QImage& image);
static bool CanAcceptDrag(const QDragEnterEvent* e);
private: private:
QString GetInitialPathForFileDialog(const Song& song, QString GetInitialPathForFileDialog(const Song& song,
const QString& filename); const QString& filename);
@ -107,6 +112,9 @@ private:
static const char* kSaveImageFileFilter; static const char* kSaveImageFileFilter;
static const char* kAllFilesFilter; static const char* kAllFilesFilter;
static bool IsKnownImageExtension(const QString& suffix);
static QSet<QString>* sImageExtensions;
#ifdef HAVE_LIBLASTFM #ifdef HAVE_LIBLASTFM
AlbumCoverSearcher* cover_searcher_; AlbumCoverSearcher* cover_searcher_;
AlbumCoverFetcher* cover_fetcher_; AlbumCoverFetcher* cover_fetcher_;

View File

@ -145,6 +145,7 @@ EditTagDialog::EditTagDialog(QWidget* parent)
ui_->summary_art_button->setMenu(cover_menu_); ui_->summary_art_button->setMenu(cover_menu_);
ui_->art->installEventFilter(this); ui_->art->installEventFilter(this);
ui_->art->setAcceptDrops(true);
// Add the next/previous buttons // Add the next/previous buttons
previous_button_ = new QPushButton(IconLoader::Load("go-previous"), tr("Previous"), this); 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) { bool EditTagDialog::eventFilter(QObject* o, QEvent* e) {
if (o == ui_->art && e->type() == QEvent::MouseButtonRelease) { if (o == ui_->art) {
cover_menu_->popup(static_cast<QMouseEvent*>(e)->globalPos()); switch (e->type()) {
case QEvent::MouseButtonRelease:
cover_menu_->popup(static_cast<QMouseEvent*>(e)->globalPos());
break;
case QEvent::DragEnter: {
QDragEnterEvent* event = static_cast<QDragEnterEvent*>(e);
if (AlbumCoverChoiceController::CanAcceptDrag(event)) {
event->acceptProposedAction();
}
break;
}
case QEvent::Drop: {
const QDropEvent* event = static_cast<QDropEvent*>(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; return false;
} }

View File

@ -30,7 +30,7 @@
</widget> </widget>
<widget class="QTabWidget" name="tab_widget"> <widget class="QTabWidget" name="tab_widget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="summary_tab"> <widget class="QWidget" name="summary_tab">
<attribute name="title"> <attribute name="title">

View File

@ -78,6 +78,9 @@ NowPlayingWidget::NowPlayingWidget(QWidget *parent)
s.beginGroup(kSettingsGroup); s.beginGroup(kSettingsGroup);
mode_ = Mode(s.value("mode", SmallSongDetails).toInt()); mode_ = Mode(s.value("mode", SmallSongDetails).toInt());
// Accept drops for setting album art
setAcceptDrops(true);
// Context menu // Context menu
QActionGroup* mode_group = new QActionGroup(this); QActionGroup* mode_group = new QActionGroup(this);
QSignalMapper* mode_mapper = new QSignalMapper(this); QSignalMapper* mode_mapper = new QSignalMapper(this);
@ -370,16 +373,14 @@ void NowPlayingWidget::resizeEvent(QResizeEvent* e) {
void NowPlayingWidget::contextMenuEvent(QContextMenuEvent* e) { void NowPlayingWidget::contextMenuEvent(QContextMenuEvent* e) {
// initial 'enabled' values depending on the kitty mode // initial 'enabled' values depending on the kitty mode
album_cover_choice_controller_->cover_from_file_action()->setEnabled(!aww_); 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_->cover_from_url_action()->setEnabled(!aww_);
album_cover_choice_controller_->search_for_cover_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_->unset_cover_action()->setEnabled(!aww_);
album_cover_choice_controller_->show_cover_action()->setEnabled(!aww_); album_cover_choice_controller_->show_cover_action()->setEnabled(!aww_);
// some special cases // some special cases
if(aww_) { if (!aww_) {
album_cover_choice_controller_->cover_to_file_action()->setEnabled(true);
} else {
#ifndef HAVE_LIBLASTFM #ifndef HAVE_LIBLASTFM
album_cover_choice_controller_->cover_from_file_action()->setEnabled(false); album_cover_choice_controller_->cover_from_file_action()->setEnabled(false);
album_cover_choice_controller_->search_for_cover_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_.reset(new FullscreenHypnotoad);
big_hypnotoad_->showFullScreen(); 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);
}

View File

@ -79,6 +79,8 @@ protected:
void paintEvent(QPaintEvent* e); void paintEvent(QPaintEvent* e);
void resizeEvent(QResizeEvent*); void resizeEvent(QResizeEvent*);
void contextMenuEvent(QContextMenuEvent* e); void contextMenuEvent(QContextMenuEvent* e);
void dragEnterEvent(QDragEnterEvent* e);
void dropEvent(QDropEvent* e);
private slots: private slots:
void SetMode(int mode); void SetMode(int mode);