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:
parent
c8a0ab9625
commit
cf826aeee0
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue