1 /* 2 * Strawberry Music Player 3 * This file was part of Clementine. 4 * Copyright 2010, David Sansome <me@davidsansome.com> 5 * Copyright 2019-2021, Jonas Kvinge <jonas@jkvinge.net> 6 * 7 * Strawberry is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * Strawberry is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with Strawberry. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 #ifndef ALBUMCOVERCHOICECONTROLLER_H 23 #define ALBUMCOVERCHOICECONTROLLER_H 24 25 #include "config.h" 26 27 #include <QtGlobal> 28 #include <QObject> 29 #include <QWidget> 30 #include <QPair> 31 #include <QSet> 32 #include <QList> 33 #include <QMap> 34 #include <QByteArray> 35 #include <QString> 36 #include <QUrl> 37 #include <QImage> 38 #include <QMutex> 39 40 #include "core/song.h" 41 #include "settings/collectionsettingspage.h" 42 #include "albumcoverimageresult.h" 43 44 class QFileDialog; 45 class QAction; 46 class QActionGroup; 47 class QMenu; 48 class QDragEnterEvent; 49 class QDropEvent; 50 51 class Application; 52 class AlbumCoverFetcher; 53 class AlbumCoverSearcher; 54 class CoverFromURLDialog; 55 struct CoverSearchStatistics; 56 57 // Controller for the common album cover related menu options. 58 class AlbumCoverChoiceController : public QWidget { 59 Q_OBJECT 60 61 public: 62 static const char *kLoadImageFileFilter; 63 static const char *kSaveImageFileFilter; 64 static const char *kAllFilesFilter; 65 66 explicit AlbumCoverChoiceController(QWidget *parent = nullptr); 67 ~AlbumCoverChoiceController() override; 68 69 void Init(Application *app); 70 void ReloadSettings(); 71 get_save_album_cover_type()72 CollectionSettingsPage::SaveCoverType get_save_album_cover_type() const { return (save_embedded_cover_override_ ? CollectionSettingsPage::SaveCoverType_Embedded : save_cover_type_); } get_collection_save_album_cover_type()73 CollectionSettingsPage::SaveCoverType get_collection_save_album_cover_type() const { return save_cover_type_; } 74 75 // Getters for all QActions implemented by this controller. 76 cover_from_file_action()77 QAction *cover_from_file_action() const { return cover_from_file_; } cover_to_file_action()78 QAction *cover_to_file_action() const { return cover_to_file_; } cover_from_url_action()79 QAction *cover_from_url_action() const { return cover_from_url_; } search_for_cover_action()80 QAction *search_for_cover_action() const { return search_for_cover_; } unset_cover_action()81 QAction *unset_cover_action() const { return unset_cover_; } delete_cover_action()82 QAction *delete_cover_action() const { return delete_cover_; } clear_cover_action()83 QAction *clear_cover_action() const { return clear_cover_; } show_cover_action()84 QAction *show_cover_action() const { return show_cover_; } search_cover_auto_action()85 QAction *search_cover_auto_action() const { return search_cover_auto_; } 86 87 // Returns QAction* for every operation implemented by this controller. 88 // The list contains QAction* for: 89 // 1. loading cover from file 90 // 2. loading cover from URL 91 // 3. searching for cover using last.fm 92 // 4. unsetting the cover manually 93 // 5. showing the cover in original size 94 QList<QAction*> GetAllActions(); 95 96 // All of the methods below require a currently selected song as an input parameter. 97 // Also - LoadCoverFromFile, LoadCoverFromURL, SearchForCover, UnsetCover and SaveCover all update manual path of the given song in collection to the new cover. 98 99 // Lets the user choose a cover from disk. If no cover will be chosen or the chosen cover will not be a proper image, this returns an empty string. 100 // Otherwise, the path to the chosen cover will be returned. 101 AlbumCoverImageResult LoadImageFromFile(Song *song); 102 QUrl LoadCoverFromFile(Song *song); 103 104 // Shows a dialog that allows user to save the given image on disk. 105 // The image is supposed to be the cover of the given song's album. 106 void SaveCoverToFileManual(const Song &song, const AlbumCoverImageResult &result); 107 108 // Downloads the cover from an URL given by user. 109 // This returns the downloaded image or null image if something went wrong for example when user cancelled the dialog. 110 QUrl LoadCoverFromURL(Song *song); 111 AlbumCoverImageResult LoadImageFromURL(); 112 113 // Lets the user choose a cover among all that have been found on last.fm. 114 // Returns the chosen cover or null cover if user didn't choose anything. 115 QUrl SearchForCover(Song *song); 116 AlbumCoverImageResult SearchForImage(Song *song); 117 118 // Returns a path which indicates that the cover has been unset manually. 119 QUrl UnsetCover(Song *song, const bool clear_art_automatic = false); 120 121 // Clears any album cover art associated with the song. 122 void ClearCover(Song *song, const bool clear_art_automatic = false); 123 124 // Physically deletes associated album covers from disk. 125 bool DeleteCover(Song *song, const bool manually_unset = false); 126 127 // Shows the cover of given song in it's original size. 128 void ShowCover(const Song &song, const QImage &image = QImage()); 129 void ShowCover(const Song &song, const QPixmap &pixmap); 130 131 // Search for covers automatically 132 quint64 SearchCoverAutomatically(const Song &song); 133 134 // Saves the chosen cover as manual cover path of this song in collection. 135 void SaveArtAutomaticToSong(Song *song, const QUrl &art_automatic); 136 void SaveArtManualToSong(Song *song, const QUrl &art_manual, const bool clear_art_automatic = false); 137 138 // Saves the cover that the user picked through a drag and drop operation. 139 QUrl SaveCover(Song *song, const QDropEvent *e); 140 141 // Saves the given image in album directory or cache as a cover for 'album artist' - 'album'. The method returns path of the image. 142 QUrl SaveCoverAutomatic(Song *song, const AlbumCoverImageResult &result); 143 QUrl SaveCoverToFileAutomatic(const Song *song, const AlbumCoverImageResult &result, const bool force_overwrite = false); 144 QUrl SaveCoverToFileAutomatic(const Song::Source source, const QString &artist, const QString &album, const QString &album_id, const QString &album_dir, const AlbumCoverImageResult &result, const bool force_overwrite = false); 145 void SaveCoverEmbeddedAutomatic(const Song &song, const AlbumCoverImageResult &result); 146 void SaveCoverEmbeddedAutomatic(const Song &song, const QUrl &cover_url); 147 void SaveCoverEmbeddedAutomatic(const Song &song, const QString &cover_filename); 148 void SaveCoverEmbeddedAutomatic(const QList<QUrl> &urls, const QImage &image); 149 150 static bool CanAcceptDrag(const QDragEnterEvent *e); 151 152 public slots: set_save_embedded_cover_override(const bool value)153 void set_save_embedded_cover_override(const bool value) { save_embedded_cover_override_ = value; } 154 155 private slots: 156 void AlbumCoverFetched(const quint64 id, const AlbumCoverImageResult &result, const CoverSearchStatistics &statistics); 157 void SaveEmbeddedCoverAsyncFinished(quint64 id, const bool success, const bool cleared); 158 159 signals: 160 void Error(QString); 161 void AutomaticCoverSearchDone(); 162 163 private: 164 static QString GetInitialPathForFileDialog(const Song &song, const QString &filename); 165 166 static bool IsKnownImageExtension(const QString &suffix); 167 static QSet<QString> *sImageExtensions; 168 169 Application *app_; 170 AlbumCoverSearcher *cover_searcher_; 171 AlbumCoverFetcher *cover_fetcher_; 172 173 QFileDialog *save_file_dialog_; 174 CoverFromURLDialog *cover_from_url_dialog_; 175 176 QAction *cover_from_file_; 177 QAction *cover_to_file_; 178 QAction *cover_from_url_; 179 QAction *search_for_cover_; 180 QAction *separator1_; 181 QAction *unset_cover_; 182 QAction *delete_cover_; 183 QAction *clear_cover_; 184 QAction *separator2_; 185 QAction *show_cover_; 186 QAction *search_cover_auto_; 187 188 QMap<quint64, Song> cover_fetching_tasks_; 189 QMap<quint64, Song> cover_save_tasks_; 190 QMutex mutex_cover_save_tasks_; 191 192 CollectionSettingsPage::SaveCoverType save_cover_type_; 193 CollectionSettingsPage::SaveCoverFilename save_cover_filename_; 194 QString cover_pattern_; 195 bool cover_overwrite_; 196 bool cover_lowercase_; 197 bool cover_replace_spaces_; 198 bool save_embedded_cover_override_; 199 200 }; 201 202 #endif // ALBUMCOVERCHOICECONTROLLER_H 203