From e2cd68e3e8a84acda925aecd39e55c6d2cd9ac2e Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 7 Mar 2021 07:01:22 +0100 Subject: [PATCH] Fix saving existing cover from file embedded for multiple albums --- src/core/imageutils.cpp | 19 ++++++++++++ src/core/imageutils.h | 1 + src/dialogs/edittagdialog.cpp | 57 ++++++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/core/imageutils.cpp b/src/core/imageutils.cpp index 179be0b1f..393dcd591 100644 --- a/src/core/imageutils.cpp +++ b/src/core/imageutils.cpp @@ -122,6 +122,25 @@ QByteArray ImageUtils::SaveImageToJpegData(const QImage &image) { } +QByteArray ImageUtils::FileToJpegData(const QString &filename) { + + if (filename.isEmpty()) return QByteArray(); + + QByteArray image_data = Utilities::ReadDataFromFile(filename); + if (Utilities::MimeTypeFromData(image_data) == "image/jpeg") return image_data; + else { + QImage image; + if (image.loadFromData(image_data)) { + if (!image.isNull()) { + image_data = SaveImageToJpegData(image); + } + } + } + + return image_data; + +} + QImage ImageUtils::ScaleAndPad(const QImage &image, const bool scale, const bool pad, const int desired_height) { if (image.isNull()) return image; diff --git a/src/core/imageutils.h b/src/core/imageutils.h index 9904e9906..76b8d03c8 100644 --- a/src/core/imageutils.h +++ b/src/core/imageutils.h @@ -41,6 +41,7 @@ class ImageUtils { static QStringList SupportedImageFormats(); static QList ImageFormatsForMimeType(const QByteArray &mimetype); static QByteArray SaveImageToJpegData(const QImage &image = QImage()); + static QByteArray FileToJpegData(const QString &filename); static QPixmap TryLoadPixmap(const QUrl &automatic, const QUrl &manual, const QUrl &url = QUrl()); static QImage ScaleAndPad(const QImage &image, const bool scale, const bool pad, const int desired_height); static QImage CreateThumbnail(const QImage &image, const bool pad, const QSize size); diff --git a/src/dialogs/edittagdialog.cpp b/src/dialogs/edittagdialog.cpp index 0522c4404..e36e150a8 100644 --- a/src/dialogs/edittagdialog.cpp +++ b/src/dialogs/edittagdialog.cpp @@ -834,6 +834,10 @@ void EditTagDialog::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderRes } else { ui_->tags_art->setPixmap(QPixmap::fromImage(image_no_cover_thumbnail_)); + for (const QModelIndex &idx : ui_->song_list->selectionModel()->selectedIndexes()) { + data_[idx.row()].cover_result_ = AlbumCoverImageResult(); + enable_change_art = data_[idx.row()].original_.is_collection_song(); + } } tags_cover_art_id_ = -1; album_cover_choice_controller_->show_cover_action()->setEnabled(result.success && result.type != AlbumCoverLoaderResult::Type_ManuallyUnset); @@ -1071,20 +1075,17 @@ void EditTagDialog::SaveData() { QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { SongSaveTagsComplete(reply, ref.current_.url().toLocalFile(), ref.current_); }, Qt::QueuedConnection); } + QString embedded_cover_from_file; // If embedded album cover is selected and it isn't saved to the tags, then save it even if no action was done. - if (ui_->checkbox_embedded_cover->isChecked() && ref.cover_action_ == UpdateCoverAction_None && !ref.original_.has_embedded_cover() && ref.original_.save_embedded_cover_supported() && - ( - (ref.original_.art_automatic().isValid() && - ref.original_.art_automatic().isLocalFile() && - QFile::exists(ref.original_.art_automatic().toLocalFile())) - || - (ref.original_.art_manual().isValid() && - ref.original_.art_manual().isLocalFile() && - QFile::exists(ref.original_.art_manual().toLocalFile())) - )) { - ref.cover_action_ = UpdateCoverAction_New; - ref.current_.clear_art_automatic(); - ref.current_.clear_art_manual(); + if (ui_->checkbox_embedded_cover->isChecked() && ref.cover_action_ == UpdateCoverAction_None && !ref.original_.has_embedded_cover() && ref.original_.save_embedded_cover_supported()) { + if (ref.original_.art_manual().isValid() && ref.original_.art_manual().isLocalFile() && QFile::exists(ref.original_.art_manual().toLocalFile())) { + ref.cover_action_ = UpdateCoverAction_New; + embedded_cover_from_file = ref.original_.art_manual().toLocalFile(); + } + else if (ref.original_.art_automatic().isValid() && ref.original_.art_automatic().isLocalFile() && QFile::exists(ref.original_.art_automatic().toLocalFile())) { + ref.cover_action_ = UpdateCoverAction_New; + embedded_cover_from_file = ref.original_.art_automatic().toLocalFile(); + } } if (ref.cover_action_ != UpdateCoverAction_None) { @@ -1141,16 +1142,16 @@ void EditTagDialog::SaveData() { } } if (ui_->checkbox_embedded_cover->isChecked() && ref.original_.save_embedded_cover_supported()) { - if (ref.cover_action_ != UpdateCoverAction_Clear && ref.cover_action_ != UpdateCoverAction_Unset) { - ++save_art_pending_; - if (ref.cover_action_ == UpdateCoverAction_Delete && ref.cover_result_.is_valid()) ref.cover_result_ = AlbumCoverImageResult(); - if (ref.cover_result_.is_jpeg() || ref.cover_result_.image_data.isNull()) { + if (ref.cover_action_ == UpdateCoverAction_New) { // Save JPEG data directly. + if (ref.cover_result_.is_jpeg()) { + ++save_art_pending_; TagReaderReply *reply = TagReaderClient::Instance()->SaveEmbeddedArt(ref.current_.url().toLocalFile(), ref.cover_result_.image_data); QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { SongSaveArtComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_); }, Qt::QueuedConnection); } - else { + else if (!ref.cover_result_.image.isNull()) { // Convert image data to JPEG. + ++save_art_pending_; QFuture future = QtConcurrent::run(&ImageUtils::SaveImageToJpegData, ref.cover_result_.image); QFutureWatcher *watcher = new QFutureWatcher(); watcher->setFuture(future); @@ -1162,6 +1163,26 @@ void EditTagDialog::SaveData() { watcher->deleteLater(); }); } + else if (!embedded_cover_from_file.isEmpty()) { // Save existing file on disk as embedded cover. + ++save_art_pending_; + QFuture future = QtConcurrent::run(&ImageUtils::FileToJpegData, embedded_cover_from_file); + QFutureWatcher *watcher = new QFutureWatcher(); + watcher->setFuture(future); + QObject::connect(watcher, &QFutureWatcher::finished, this, [=]() { + TagReaderReply *reply = TagReaderClient::Instance()->SaveEmbeddedArt(ref.current_.url().toLocalFile(), watcher->result()); + QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { + SongSaveArtComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_); + }, Qt::QueuedConnection); + watcher->deleteLater(); + }); + } + } + else if (ref.cover_action_ == UpdateCoverAction_Delete) { + ++save_art_pending_; + TagReaderReply *reply = TagReaderClient::Instance()->SaveEmbeddedArt(ref.current_.url().toLocalFile(), QByteArray()); + QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { + SongSaveArtComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_); + }, Qt::QueuedConnection); } } else if (!ref.current_.effective_albumartist().isEmpty() && !ref.current_.album().isEmpty()) {