2018-02-27 18:06:05 +01:00
/*
* Strawberry Music Player
* This file was part of Clementine .
* Copyright 2010 , David Sansome < me @ davidsansome . com >
2021-06-21 19:54:12 +02:00
* Copyright 2018 - 2021 , Jonas Kvinge < jonas @ jkvinge . net >
2018-02-27 18:06:05 +01:00
*
* Strawberry is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Strawberry is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with Strawberry . If not , see < http : //www.gnu.org/licenses/>.
2018-08-09 18:39:44 +02:00
*
2018-02-27 18:06:05 +01:00
*/
# include "config.h"
# include <QFile>
2018-05-01 00:41:33 +02:00
# include <QSize>
# include <QString>
# include <QImage>
2018-02-27 18:06:05 +01:00
# include "core/song.h"
# include "core/tagreaderclient.h"
2020-02-09 02:29:35 +01:00
# include "albumcoverexport.h"
2018-02-27 18:06:05 +01:00
# include "coverexportrunnable.h"
2021-07-11 07:40:57 +02:00
CoverExportRunnable : : CoverExportRunnable ( const AlbumCoverExport : : DialogResult & dialog_result , const Song & song , QObject * parent )
: QObject ( parent ) ,
dialog_result_ ( dialog_result ) ,
song_ ( song ) { }
2018-02-27 18:06:05 +01:00
void CoverExportRunnable : : run ( ) {
QString cover_path = GetCoverPath ( ) ;
2018-05-01 00:41:33 +02:00
// Manually unset?
2018-02-27 18:06:05 +01:00
if ( cover_path . isEmpty ( ) ) {
EmitCoverSkipped ( ) ;
}
else {
2021-08-23 21:21:08 +02:00
if ( dialog_result_ . RequiresCoverProcessing ( ) ) {
2018-02-27 18:06:05 +01:00
ProcessAndExportCover ( ) ;
2021-08-23 21:21:08 +02:00
}
else {
2018-02-27 18:06:05 +01:00
ExportCover ( ) ;
2021-08-23 21:21:08 +02:00
}
2018-02-27 18:06:05 +01:00
}
}
QString CoverExportRunnable : : GetCoverPath ( ) {
if ( song_ . has_manually_unset_cover ( ) ) {
return QString ( ) ;
// Export downloaded covers?
}
else if ( ! song_ . art_manual ( ) . isEmpty ( ) & & dialog_result_ . export_downloaded_ ) {
2019-07-07 21:14:24 +02:00
return song_ . art_manual ( ) . toLocalFile ( ) ;
2018-02-27 18:06:05 +01:00
// Export embedded covers?
}
2019-07-07 21:14:24 +02:00
else if ( ! song_ . art_automatic ( ) . isEmpty ( ) & & song_ . art_automatic ( ) . path ( ) = = Song : : kEmbeddedCover & & dialog_result_ . export_embedded_ ) {
return song_ . art_automatic ( ) . toLocalFile ( ) ;
2018-02-27 18:06:05 +01:00
}
else {
return QString ( ) ;
}
}
// Exports a single album cover using a "save QImage to file" approach.
2018-05-01 00:41:33 +02:00
// For performance reasons this method will be invoked only if loading and in memory processing of images is necessary for current settings which means that:
2018-02-27 18:06:05 +01:00
// - either the force size flag is being used
// - or the "overwrite smaller" mode is used
// In all other cases, the faster ExportCover() method will be used.
void CoverExportRunnable : : ProcessAndExportCover ( ) {
QString cover_path = GetCoverPath ( ) ;
// either embedded or disk - the one we'll export for the current album
QImage cover ;
QImage embedded_cover ;
QImage disk_cover ;
// load embedded cover if any
if ( song_ . has_embedded_cover ( ) ) {
2021-02-26 21:03:51 +01:00
embedded_cover = TagReaderClient : : Instance ( ) - > LoadEmbeddedArtAsImageBlocking ( song_ . url ( ) . toLocalFile ( ) ) ;
2018-02-27 18:06:05 +01:00
if ( embedded_cover . isNull ( ) ) {
EmitCoverSkipped ( ) ;
return ;
}
cover = embedded_cover ;
}
// load a file cover which iss mandatory if there's no embedded cover
disk_cover . load ( cover_path ) ;
if ( embedded_cover . isNull ( ) ) {
if ( disk_cover . isNull ( ) ) {
EmitCoverSkipped ( ) ;
return ;
}
cover = disk_cover ;
}
// rescale if necessary
if ( dialog_result_ . IsSizeForced ( ) ) {
cover = cover . scaled ( QSize ( dialog_result_ . width_ , dialog_result_ . height_ ) , Qt : : IgnoreAspectRatio ) ;
}
QString dir = song_ . url ( ) . toLocalFile ( ) . section ( ' / ' , 0 , - 2 ) ;
QString extension = cover_path . section ( ' . ' , - 1 ) ;
2021-06-21 19:55:18 +02:00
QString new_file = dir + ' / ' + dialog_result_ . filename_ + ' . ' + ( cover_path = = Song : : kEmbeddedCover ? " jpg " : extension ) ;
2018-02-27 18:06:05 +01:00
// If the file exists, do not override!
if ( dialog_result_ . overwrite_ = = AlbumCoverExport : : OverwriteMode_None & & QFile : : exists ( new_file ) ) {
EmitCoverSkipped ( ) ;
return ;
}
2018-05-01 00:41:33 +02:00
// we're handling overwrite as remove + copy so we need to delete the old file first
2018-02-27 18:06:05 +01:00
if ( QFile : : exists ( new_file ) & & dialog_result_ . overwrite_ ! = AlbumCoverExport : : OverwriteMode_None ) {
2018-05-01 00:41:33 +02:00
// if the mode is "overwrite smaller" then skip the cover if a bigger one is already available in the folder
2018-02-27 18:06:05 +01:00
if ( dialog_result_ . overwrite_ = = AlbumCoverExport : : OverwriteMode_Smaller ) {
QImage existing ;
existing . load ( new_file ) ;
if ( existing . isNull ( ) | | existing . size ( ) . height ( ) > = cover . size ( ) . height ( ) | | existing . size ( ) . width ( ) > = cover . size ( ) . width ( ) ) {
EmitCoverSkipped ( ) ;
return ;
}
}
if ( ! QFile : : remove ( new_file ) ) {
EmitCoverSkipped ( ) ;
return ;
}
}
2021-08-23 21:21:08 +02:00
if ( cover . save ( new_file ) ) {
2018-02-27 18:06:05 +01:00
EmitCoverExported ( ) ;
2021-08-23 21:21:08 +02:00
}
else {
2018-02-27 18:06:05 +01:00
EmitCoverSkipped ( ) ;
2021-08-23 21:21:08 +02:00
}
2018-02-27 18:06:05 +01:00
}
// Exports a single album cover using a "copy file" approach.
void CoverExportRunnable : : ExportCover ( ) {
QString cover_path = GetCoverPath ( ) ;
QString dir = song_ . url ( ) . toLocalFile ( ) . section ( ' / ' , 0 , - 2 ) ;
QString extension = cover_path . section ( ' . ' , - 1 ) ;
2021-06-21 19:55:18 +02:00
QString new_file = dir + ' / ' + dialog_result_ . filename_ + ' . ' + ( cover_path = = Song : : kEmbeddedCover ? " jpg " : extension ) ;
2018-02-27 18:06:05 +01:00
// If the file exists, do not override!
if ( dialog_result_ . overwrite_ = = AlbumCoverExport : : OverwriteMode_None & & QFile : : exists ( new_file ) ) {
EmitCoverSkipped ( ) ;
return ;
}
2019-07-07 21:14:24 +02:00
// We're handling overwrite as remove + copy so we need to delete the old file first
2018-02-27 18:06:05 +01:00
if ( dialog_result_ . overwrite_ ! = AlbumCoverExport : : OverwriteMode_None & & QFile : : exists ( new_file ) ) {
if ( ! QFile : : remove ( new_file ) ) {
EmitCoverSkipped ( ) ;
return ;
}
}
if ( cover_path = = Song : : kEmbeddedCover ) {
// an embedded cover
2021-02-26 21:03:51 +01:00
QImage embedded = TagReaderClient : : Instance ( ) - > LoadEmbeddedArtAsImageBlocking ( song_ . url ( ) . toLocalFile ( ) ) ;
2018-02-27 18:06:05 +01:00
if ( ! embedded . save ( new_file ) ) {
EmitCoverSkipped ( ) ;
return ;
}
}
else {
2019-07-07 21:14:24 +02:00
// Automatic or manual cover, available in an image file
2018-02-27 18:06:05 +01:00
if ( ! QFile : : copy ( cover_path , new_file ) ) {
EmitCoverSkipped ( ) ;
return ;
}
}
EmitCoverExported ( ) ;
}
void CoverExportRunnable : : EmitCoverExported ( ) { emit CoverExported ( ) ; }
void CoverExportRunnable : : EmitCoverSkipped ( ) { emit CoverSkipped ( ) ; }