2018-02-27 18:06:05 +01:00
/*
* Strawberry Music Player
* This file was part of Clementine .
* Copyright 2010 , David Sansome < me @ davidsansome . com >
2019-07-07 21:14:24 +02:00
* Copyright 2019 , 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"
2018-05-01 00:41:33 +02:00
# include <QtGlobal>
2019-07-08 22:10:43 +02:00
# include <QGuiApplication>
# include <QScreen>
2020-01-05 19:14:25 +01:00
# include <QWindow>
2018-05-01 00:41:33 +02:00
# include <QWidget>
2018-02-27 18:06:05 +01:00
# include <QDialog>
2018-05-01 00:41:33 +02:00
# include <QDir>
2020-02-09 02:29:35 +01:00
# include <QFile>
2018-05-01 00:41:33 +02:00
# include <QFileInfo>
2018-02-27 18:06:05 +01:00
# include <QMimeData>
2020-02-09 02:29:35 +01:00
# include <QSet>
# include <QList>
2018-05-01 00:41:33 +02:00
# include <QVariant>
# include <QString>
2020-07-18 04:05:07 +02:00
# include <QRegularExpression>
2018-05-01 00:41:33 +02:00
# include <QUrl>
# include <QImage>
# include <QImageWriter>
# include <QPixmap>
# include <QIcon>
# include <QRect>
# include <QFileDialog>
# include <QLabel>
2020-02-09 02:29:35 +01:00
# include <QAction>
# include <QSettings>
2018-05-01 00:41:33 +02:00
# include <QtEvents>
2018-02-27 18:06:05 +01:00
2018-05-01 00:41:33 +02:00
# include "core/song.h"
2018-02-27 18:06:05 +01:00
# include "core/iconloader.h"
2018-05-01 00:41:33 +02:00
# include "core/application.h"
2018-02-27 18:06:05 +01:00
2018-05-01 00:41:33 +02:00
# include "collection/collectionbackend.h"
2019-03-11 23:07:11 +01:00
# include "settings/collectionsettingspage.h"
2020-08-04 21:18:14 +02:00
# include "organize/organizeformat.h"
2019-07-07 21:14:24 +02:00
# include "internet/internetservices.h"
# include "internet/internetservice.h"
2018-05-01 00:41:33 +02:00
# include "albumcoverchoicecontroller.h"
# include "albumcoverfetcher.h"
# include "albumcoverloader.h"
# include "albumcoversearcher.h"
# include "coverfromurldialog.h"
2019-07-07 21:14:24 +02:00
# include "currentalbumcoverloader.h"
2018-02-27 18:06:05 +01:00
const char * AlbumCoverChoiceController : : kLoadImageFileFilter = QT_TR_NOOP ( " Images (*.png *.jpg *.jpeg *.bmp *.gif *.xpm *.pbm *.pgm *.ppm *.xbm) " ) ;
const char * AlbumCoverChoiceController : : kSaveImageFileFilter = QT_TR_NOOP ( " Images (*.png *.jpg *.jpeg *.bmp *.xpm *.pbm *.ppm *.xbm) " ) ;
const char * AlbumCoverChoiceController : : kAllFilesFilter = QT_TR_NOOP ( " All files (*) " ) ;
QSet < QString > * AlbumCoverChoiceController : : sImageExtensions = nullptr ;
AlbumCoverChoiceController : : AlbumCoverChoiceController ( QWidget * parent ) :
QWidget ( parent ) ,
2019-02-10 21:25:36 +01:00
app_ ( nullptr ) ,
cover_searcher_ ( nullptr ) ,
cover_fetcher_ ( nullptr ) ,
save_file_dialog_ ( nullptr ) ,
2019-03-11 23:07:11 +01:00
cover_from_url_dialog_ ( nullptr ) ,
cover_album_dir_ ( false ) ,
cover_filename_ ( CollectionSettingsPage : : SaveCover_Hash ) ,
cover_overwrite_ ( false ) ,
cover_lowercase_ ( true ) ,
cover_replace_spaces_ ( true )
{
2018-02-27 18:06:05 +01:00
cover_from_file_ = new QAction ( IconLoader : : Load ( " document-open " ) , tr ( " Load cover from disk... " ) , this ) ;
cover_to_file_ = new QAction ( IconLoader : : Load ( " document-save " ) , tr ( " Save cover to disk... " ) , this ) ;
cover_from_url_ = new QAction ( IconLoader : : Load ( " download " ) , tr ( " Load cover from URL... " ) , this ) ;
search_for_cover_ = new QAction ( IconLoader : : Load ( " search " ) , tr ( " Search for album covers... " ) , this ) ;
unset_cover_ = new QAction ( IconLoader : : Load ( " list-remove " ) , tr ( " Unset cover " ) , this ) ;
show_cover_ = new QAction ( IconLoader : : Load ( " zoom-in " ) , tr ( " Show fullsize... " ) , this ) ;
2018-08-29 21:42:24 +02:00
search_cover_auto_ = new QAction ( tr ( " Search automatically " ) , this ) ;
2018-02-27 18:06:05 +01:00
search_cover_auto_ - > setCheckable ( true ) ;
search_cover_auto_ - > setChecked ( false ) ;
separator_ = new QAction ( this ) ;
separator_ - > setSeparator ( true ) ;
2019-03-12 00:01:52 +01:00
ReloadSettings ( ) ;
2018-02-27 18:06:05 +01:00
}
AlbumCoverChoiceController : : ~ AlbumCoverChoiceController ( ) { }
2019-07-07 21:14:24 +02:00
void AlbumCoverChoiceController : : Init ( Application * app ) {
app_ = app ;
cover_fetcher_ = new AlbumCoverFetcher ( app_ - > cover_providers ( ) , this ) ;
cover_searcher_ = new AlbumCoverSearcher ( QIcon ( " :/pictures/cdcase.png " ) , app , this ) ;
cover_searcher_ - > Init ( cover_fetcher_ ) ;
2020-04-13 05:57:48 +02:00
connect ( cover_fetcher_ , SIGNAL ( AlbumCoverFetched ( quint64 , QUrl , QImage , CoverSearchStatistics ) ) , this , SLOT ( AlbumCoverFetched ( quint64 , QUrl , QImage , CoverSearchStatistics ) ) ) ;
2019-07-07 21:14:24 +02:00
}
2019-03-11 23:07:11 +01:00
void AlbumCoverChoiceController : : ReloadSettings ( ) {
QSettings s ;
s . beginGroup ( CollectionSettingsPage : : kSettingsGroup ) ;
cover_album_dir_ = s . value ( " cover_album_dir " , false ) . toBool ( ) ;
cover_filename_ = CollectionSettingsPage : : SaveCover ( s . value ( " cover_filename " , CollectionSettingsPage : : SaveCover_Hash ) . toInt ( ) ) ;
cover_pattern_ = s . value ( " cover_pattern " , " %albumartist-%album " ) . toString ( ) ;
cover_overwrite_ = s . value ( " cover_overwrite " , false ) . toBool ( ) ;
cover_lowercase_ = s . value ( " cover_lowercase " , false ) . toBool ( ) ;
cover_replace_spaces_ = s . value ( " cover_replace_spaces " , false ) . toBool ( ) ;
s . endGroup ( ) ;
}
2018-02-27 18:06:05 +01:00
QList < QAction * > AlbumCoverChoiceController : : GetAllActions ( ) {
2019-11-19 21:19:44 +01:00
return QList < QAction * > ( ) < < cover_from_file_ < < cover_to_file_ < < separator_ < < cover_from_url_ < < search_for_cover_ < < unset_cover_ < < separator_ < < show_cover_ ;
2018-02-27 18:06:05 +01:00
}
2019-07-07 21:14:24 +02:00
QUrl AlbumCoverChoiceController : : LoadCoverFromFile ( Song * song ) {
2018-04-06 22:13:11 +02:00
2019-07-07 21:14:24 +02:00
QString cover_file = QFileDialog : : getOpenFileName ( this , tr ( " Load cover from disk " ) , GetInitialPathForFileDialog ( * song , QString ( ) ) , tr ( kLoadImageFileFilter ) + " ;; " + tr ( kAllFilesFilter ) ) ;
2018-02-27 18:06:05 +01:00
2019-07-07 21:14:24 +02:00
if ( cover_file . isNull ( ) ) return QUrl ( ) ;
2018-02-27 18:06:05 +01:00
// Can we load the image?
2019-07-07 21:14:24 +02:00
QImage image ( cover_file ) ;
2018-02-27 18:06:05 +01:00
2019-07-07 21:14:24 +02:00
if ( image . isNull ( ) ) {
return QUrl ( ) ;
2018-02-27 18:06:05 +01:00
}
else {
2019-07-08 22:10:43 +02:00
QUrl cover_url ( QUrl : : fromLocalFile ( cover_file ) ) ;
2019-07-07 21:14:24 +02:00
SaveCoverToSong ( song , cover_url ) ;
return cover_url ;
2018-02-27 18:06:05 +01:00
}
}
2019-03-11 23:07:11 +01:00
void AlbumCoverChoiceController : : SaveCoverToFileManual ( const Song & song , const QImage & image ) {
2018-02-27 18:06:05 +01:00
2019-03-11 23:07:11 +01:00
QString initial_file_name = " / " ;
if ( ! song . effective_albumartist ( ) . isEmpty ( ) ) {
initial_file_name = initial_file_name + song . effective_albumartist ( ) ;
}
initial_file_name = initial_file_name + " - " + ( song . effective_album ( ) . isEmpty ( ) ? tr ( " unknown " ) : song . effective_album ( ) ) + " .jpg " ;
initial_file_name = initial_file_name . toLower ( ) ;
2020-07-18 04:05:07 +02:00
initial_file_name . replace ( QRegularExpression ( " \\ s " ) , " - " ) ;
2020-08-04 21:18:14 +02:00
initial_file_name . remove ( OrganizeFormat : : kInvalidFatCharacters ) ;
2018-02-27 18:06:05 +01:00
QString save_filename = QFileDialog : : getSaveFileName ( this , tr ( " Save album cover " ) , GetInitialPathForFileDialog ( song , initial_file_name ) , tr ( kSaveImageFileFilter ) + " ;; " + tr ( kAllFilesFilter ) ) ;
if ( save_filename . isNull ( ) ) return ;
QString extension = save_filename . right ( 4 ) ;
if ( ! extension . startsWith ( ' . ' ) | | ! QImageWriter : : supportedImageFormats ( ) . contains ( extension . right ( 3 ) . toUtf8 ( ) ) ) {
save_filename . append ( " .jpg " ) ;
}
image . save ( save_filename ) ;
}
QString AlbumCoverChoiceController : : GetInitialPathForFileDialog ( const Song & song , const QString & filename ) {
2018-10-02 00:38:52 +02:00
2018-05-01 00:41:33 +02:00
// Art automatic is first to show user which cover the album may be using now;
// The song is using it if there's no manual path but we cannot use manual path here because it can contain cached paths
2019-07-07 21:14:24 +02:00
if ( ! song . art_automatic ( ) . isEmpty ( ) & & ! song . art_automatic ( ) . path ( ) . isEmpty ( ) & & ! song . has_embedded_cover ( ) ) {
if ( song . art_automatic ( ) . scheme ( ) . isEmpty ( ) & & QFile : : exists ( QFileInfo ( song . art_automatic ( ) . path ( ) ) . path ( ) ) ) {
return song . art_automatic ( ) . path ( ) ;
}
2019-07-08 22:10:43 +02:00
else if ( song . art_automatic ( ) . isLocalFile ( ) & & QFile : : exists ( QFileInfo ( song . art_automatic ( ) . toLocalFile ( ) ) . path ( ) ) ) {
2019-07-07 21:14:24 +02:00
return song . art_automatic ( ) . toLocalFile ( ) ;
}
2018-05-01 00:41:33 +02:00
// If no automatic art, start in the song's folder
2018-02-27 18:06:05 +01:00
}
else if ( ! song . url ( ) . isEmpty ( ) & & song . url ( ) . toLocalFile ( ) . contains ( ' / ' ) ) {
return song . url ( ) . toLocalFile ( ) . section ( ' / ' , 0 , - 2 ) + filename ;
2018-05-01 00:41:33 +02:00
// Fallback - start in home
2018-02-27 18:06:05 +01:00
}
2019-07-07 21:14:24 +02:00
return QDir : : home ( ) . absolutePath ( ) + filename ;
2018-02-27 18:06:05 +01:00
}
2019-07-07 21:14:24 +02:00
QUrl AlbumCoverChoiceController : : LoadCoverFromURL ( Song * song ) {
2018-10-02 00:38:52 +02:00
2018-02-27 18:06:05 +01:00
if ( ! cover_from_url_dialog_ ) { cover_from_url_dialog_ = new CoverFromURLDialog ( this ) ; }
QImage image = cover_from_url_dialog_ - > Exec ( ) ;
2019-07-07 21:14:24 +02:00
if ( image . isNull ( ) ) {
return QUrl ( ) ;
}
else {
QUrl cover_url = SaveCoverToFileAutomatic ( song , QUrl ( ) , image , true ) ;
if ( cover_url . isEmpty ( ) ) return QUrl ( ) ;
SaveCoverToSong ( song , cover_url ) ;
return cover_url ;
2018-02-27 18:06:05 +01:00
}
2018-10-02 00:38:52 +02:00
2018-02-27 18:06:05 +01:00
}
2019-07-07 21:14:24 +02:00
QUrl AlbumCoverChoiceController : : SearchForCover ( Song * song ) {
2018-03-04 14:10:50 +01:00
2018-02-27 18:06:05 +01:00
QString album = song - > effective_album ( ) ;
2019-01-22 22:49:48 +01:00
album . remove ( Song : : kAlbumRemoveDisc ) ;
album . remove ( Song : : kAlbumRemoveMisc ) ;
2018-02-27 18:06:05 +01:00
// Get something sensible to stick in the search box
QImage image = cover_searcher_ - > Exec ( song - > effective_albumartist ( ) , album ) ;
2019-07-07 21:14:24 +02:00
if ( image . isNull ( ) ) {
return QUrl ( ) ;
}
else {
QUrl cover_url = SaveCoverToFileAutomatic ( song , QUrl ( ) , image , true ) ;
if ( cover_url . isEmpty ( ) ) return QUrl ( ) ;
SaveCoverToSong ( song , cover_url ) ;
return cover_url ;
2018-02-27 18:06:05 +01:00
}
2018-10-02 00:38:52 +02:00
2018-02-27 18:06:05 +01:00
}
2019-07-07 21:14:24 +02:00
QUrl AlbumCoverChoiceController : : UnsetCover ( Song * song ) {
2018-02-27 18:06:05 +01:00
2019-07-08 22:10:43 +02:00
QUrl cover_url ( QUrl : : fromLocalFile ( Song : : kManuallyUnsetCover ) ) ;
2019-07-07 21:14:24 +02:00
SaveCoverToSong ( song , cover_url ) ;
2018-02-27 18:06:05 +01:00
2019-07-07 21:14:24 +02:00
return cover_url ;
2018-02-27 18:06:05 +01:00
}
void AlbumCoverChoiceController : : ShowCover ( const Song & song ) {
2019-07-09 01:14:58 +02:00
QPixmap pixmap = AlbumCoverLoader : : TryLoadPixmap ( song . art_automatic ( ) , song . art_manual ( ) , song . url ( ) ) ;
2019-07-09 21:43:56 +02:00
if ( pixmap . isNull ( ) ) return ;
2018-09-10 21:58:57 +02:00
ShowCover ( song , pixmap ) ;
}
2019-07-09 01:05:42 +02:00
void AlbumCoverChoiceController : : ShowCover ( const Song & song , const QImage & image ) {
2018-09-10 21:58:57 +02:00
2019-07-09 21:43:56 +02:00
if ( song . art_manual ( ) . isLocalFile ( ) | | song . art_automatic ( ) . isLocalFile ( ) ) {
2019-07-09 01:14:58 +02:00
QPixmap pixmap = AlbumCoverLoader : : TryLoadPixmap ( song . art_automatic ( ) , song . art_manual ( ) , song . url ( ) ) ;
2019-07-09 01:05:42 +02:00
if ( ! pixmap . isNull ( ) ) ShowCover ( song , pixmap ) ;
2018-09-10 21:58:57 +02:00
}
2019-07-09 21:43:56 +02:00
else if ( ! image . isNull ( ) ) ShowCover ( song , QPixmap : : fromImage ( image ) ) ;
2018-09-10 21:58:57 +02:00
}
void AlbumCoverChoiceController : : ShowCover ( const Song & song , const QPixmap & pixmap ) {
2018-02-27 18:06:05 +01:00
QDialog * dialog = new QDialog ( this ) ;
dialog - > setAttribute ( Qt : : WA_DeleteOnClose , true ) ;
// Use Artist - Album as the window title
QString title_text ( song . effective_albumartist ( ) ) ;
if ( ! song . effective_album ( ) . isEmpty ( ) ) title_text + = " - " + song . effective_album ( ) ;
QLabel * label = new QLabel ( dialog ) ;
2018-09-10 21:58:57 +02:00
label - > setPixmap ( pixmap ) ;
2018-02-27 18:06:05 +01:00
2018-05-01 00:41:33 +02:00
// Add (WxHpx) to the title before possibly resizing
2020-05-29 17:45:00 +02:00
title_text + = " ( " + QString : : number ( pixmap . width ( ) ) + " x " + QString : : number ( pixmap . height ( ) ) + " px) " ;
2018-02-27 18:06:05 +01:00
2018-05-01 00:41:33 +02:00
// If the cover is larger than the screen, resize the window 85% seems to be enough to account for title bar and taskbar etc.
2020-01-05 19:14:25 +01:00
# if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QScreen * screen = QWidget : : screen ( ) ;
# else
QScreen * screen = ( window ( ) & & window ( ) - > windowHandle ( ) ? window ( ) - > windowHandle ( ) - > screen ( ) : QGuiApplication : : primaryScreen ( ) ) ;
# endif
QRect screenGeometry = screen - > availableGeometry ( ) ;
2019-07-08 22:10:43 +02:00
int desktop_height = screenGeometry . height ( ) ;
int desktop_width = screenGeometry . width ( ) ;
2018-02-27 18:06:05 +01:00
2018-05-01 00:41:33 +02:00
// Resize differently if monitor is in portrait mode
2018-02-27 18:06:05 +01:00
if ( desktop_width < desktop_height ) {
2020-06-15 17:59:02 +02:00
const int new_width = static_cast < double > ( desktop_width ) * 0.95 ;
2020-05-29 17:45:00 +02:00
if ( new_width < pixmap . width ( ) ) {
label - > setPixmap ( pixmap . scaledToWidth ( new_width , Qt : : SmoothTransformation ) ) ;
2018-02-27 18:06:05 +01:00
}
}
else {
2020-06-15 17:59:02 +02:00
const int new_height = static_cast < double > ( desktop_height ) * 0.85 ;
2020-05-29 17:45:00 +02:00
if ( new_height < pixmap . height ( ) ) {
label - > setPixmap ( pixmap . scaledToHeight ( new_height , Qt : : SmoothTransformation ) ) ;
2018-02-27 18:06:05 +01:00
}
}
dialog - > setWindowTitle ( title_text ) ;
2020-05-29 17:45:00 +02:00
# if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
dialog - > setFixedSize ( label - > pixmap ( Qt : : ReturnByValue ) . size ( ) ) ;
# else
2018-02-27 18:06:05 +01:00
dialog - > setFixedSize ( label - > pixmap ( ) - > size ( ) ) ;
2020-05-29 17:45:00 +02:00
# endif
2018-02-27 18:06:05 +01:00
dialog - > show ( ) ;
}
2020-04-20 18:03:18 +02:00
qint64 AlbumCoverChoiceController : : SearchCoverAutomatically ( const Song & song ) {
2018-02-27 18:06:05 +01:00
2020-04-20 18:03:18 +02:00
qint64 id = cover_fetcher_ - > FetchAlbumCover ( song . effective_albumartist ( ) , song . album ( ) , song . title ( ) , true ) ;
2018-02-27 18:06:05 +01:00
cover_fetching_tasks_ [ id ] = song ;
2020-04-20 18:03:18 +02:00
return id ;
2018-02-27 18:06:05 +01:00
}
2019-07-07 21:14:24 +02:00
void AlbumCoverChoiceController : : AlbumCoverFetched ( const quint64 id , const QUrl & cover_url , const QImage & image , const CoverSearchStatistics & statistics ) {
2018-02-27 18:06:05 +01:00
2019-09-15 20:27:32 +02:00
Q_UNUSED ( statistics ) ;
2018-02-27 18:06:05 +01:00
Song song ;
if ( cover_fetching_tasks_ . contains ( id ) ) {
song = cover_fetching_tasks_ . take ( id ) ;
}
if ( ! image . isNull ( ) ) {
2019-07-07 21:14:24 +02:00
QUrl new_cover_url = SaveCoverToFileAutomatic ( & song , cover_url , image , false ) ;
if ( ! new_cover_url . isEmpty ( ) ) SaveCoverToSong ( & song , new_cover_url ) ;
2018-02-27 18:06:05 +01:00
}
emit AutomaticCoverSearchDone ( ) ;
}
2019-07-07 21:14:24 +02:00
void AlbumCoverChoiceController : : SaveCoverToSong ( Song * song , const QUrl & cover_url ) {
if ( ! song - > is_valid ( ) ) return ;
song - > set_art_manual ( cover_url ) ;
if ( song - > id ( ) ! = - 1 ) { // Update the backends.
switch ( song - > source ( ) ) {
case Song : : Source_Collection :
app_ - > collection_backend ( ) - > UpdateManualAlbumArtAsync ( song - > artist ( ) , song - > albumartist ( ) , song - > album ( ) , cover_url ) ;
break ;
case Song : : Source_LocalFile :
case Song : : Source_CDDA :
case Song : : Source_Device :
case Song : : Source_Stream :
case Song : : Source_Unknown :
break ;
case Song : : Source_Tidal :
case Song : : Source_Qobuz :
case Song : : Source_Subsonic :
InternetService * service = app_ - > internet_services ( ) - > ServiceBySource ( song - > source ( ) ) ;
if ( ! service ) break ;
if ( service - > artists_collection_backend ( ) )
service - > artists_collection_backend ( ) - > UpdateManualAlbumArtAsync ( song - > artist ( ) , song - > albumartist ( ) , song - > album ( ) , cover_url ) ;
if ( service - > albums_collection_backend ( ) )
service - > albums_collection_backend ( ) - > UpdateManualAlbumArtAsync ( song - > artist ( ) , song - > albumartist ( ) , song - > album ( ) , cover_url ) ;
if ( service - > songs_collection_backend ( ) )
service - > songs_collection_backend ( ) - > UpdateManualAlbumArtAsync ( song - > artist ( ) , song - > albumartist ( ) , song - > album ( ) , cover_url ) ;
break ;
}
2018-02-27 18:06:05 +01:00
2019-07-07 21:14:24 +02:00
}
2018-02-27 18:06:05 +01:00
2020-04-20 18:03:18 +02:00
if ( * song = = app_ - > current_albumcover_loader ( ) - > last_song ( ) ) {
2019-07-07 21:14:24 +02:00
app_ - > current_albumcover_loader ( ) - > LoadAlbumCover ( * song ) ;
2018-02-27 18:06:05 +01:00
}
}
2019-07-07 21:14:24 +02:00
QUrl AlbumCoverChoiceController : : SaveCoverToFileAutomatic ( const Song * song , const QUrl & cover_url , const QImage & image , const bool overwrite ) {
2019-03-11 23:07:11 +01:00
2019-07-07 21:14:24 +02:00
return SaveCoverToFileAutomatic ( song - > source ( ) , song - > effective_albumartist ( ) , song - > effective_album ( ) , song - > album_id ( ) , song - > url ( ) . adjusted ( QUrl : : RemoveFilename ) . path ( ) , cover_url , image , overwrite ) ;
2019-03-11 23:07:11 +01:00
}
2019-07-07 21:14:24 +02:00
QUrl AlbumCoverChoiceController : : SaveCoverToFileAutomatic ( const Song : : Source source , const QString & artist , const QString & album , const QString & album_id , const QString & album_dir , const QUrl & cover_url , const QImage & image , const bool overwrite ) {
2018-02-27 18:06:05 +01:00
2020-05-12 18:50:57 +02:00
QString filepath = app_ - > album_cover_loader ( ) - > CoverFilePath ( source , artist , album , album_id , album_dir , cover_url , " jpg " ) ;
2019-07-07 21:14:24 +02:00
if ( filepath . isEmpty ( ) ) return QUrl ( ) ;
2018-05-01 00:41:33 +02:00
2019-07-08 22:10:43 +02:00
QUrl new_cover_url ( QUrl : : fromLocalFile ( filepath ) ) ;
2019-03-11 23:07:11 +01:00
2019-07-07 21:14:24 +02:00
// Don't overwrite when saving in album dir if the filename is set to pattern unless the "overwrite" is set.
if ( source = = Song : : Source_Collection & & QFile : : exists ( filepath ) & & ! cover_overwrite_ & & ! overwrite & & cover_album_dir_ & & cover_filename_ = = CollectionSettingsPage : : SaveCover_Pattern ) {
return new_cover_url ;
2019-03-11 23:07:11 +01:00
}
2018-02-27 18:06:05 +01:00
2019-07-07 21:14:24 +02:00
if ( ! image . save ( filepath , " JPG " ) & & ! QFile : : exists ( filepath ) ) return QUrl ( ) ;
2018-02-27 18:06:05 +01:00
2019-07-07 21:14:24 +02:00
return new_cover_url ;
2018-02-27 18:06:05 +01:00
}
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 ) {
for ( const QUrl & url : e - > mimeData ( ) - > urls ( ) ) {
const QString suffix = QFileInfo ( url . toLocalFile ( ) ) . suffix ( ) . toLower ( ) ;
if ( IsKnownImageExtension ( suffix ) ) return true ;
}
2019-04-08 18:46:11 +02:00
return e - > mimeData ( ) - > hasImage ( ) ;
2018-02-27 18:06:05 +01:00
}
2019-07-07 21:14:24 +02:00
QUrl AlbumCoverChoiceController : : SaveCover ( Song * song , const QDropEvent * e ) {
2018-02-27 18:06:05 +01:00
for ( const QUrl & url : e - > mimeData ( ) - > urls ( ) ) {
2018-09-10 21:58:57 +02:00
2018-02-27 18:06:05 +01:00
const QString filename = url . toLocalFile ( ) ;
const QString suffix = QFileInfo ( filename ) . suffix ( ) . toLower ( ) ;
if ( IsKnownImageExtension ( suffix ) ) {
2019-07-07 21:14:24 +02:00
SaveCoverToSong ( song , url ) ;
return url ;
2018-02-27 18:06:05 +01:00
}
}
if ( e - > mimeData ( ) - > hasImage ( ) ) {
QImage image = qvariant_cast < QImage > ( e - > mimeData ( ) - > imageData ( ) ) ;
if ( ! image . isNull ( ) ) {
2019-07-07 21:14:24 +02:00
QUrl cover_url = SaveCoverToFileAutomatic ( song , QUrl ( ) , image , true ) ;
if ( cover_url . isEmpty ( ) ) return QUrl ( ) ;
SaveCoverToSong ( song , cover_url ) ;
return cover_url ;
2018-02-27 18:06:05 +01:00
}
}
2019-07-07 21:14:24 +02:00
return QUrl ( ) ;
2018-02-27 18:06:05 +01:00
}