1 /* This file is part of Clementine. 2 Copyright 2010, David Sansome <me@davidsansome.com> 3 4 Clementine is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 Clementine is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with Clementine. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef PLAYLISTMANAGER_H 19 #define PLAYLISTMANAGER_H 20 21 #include <QColor> 22 #include <QItemSelection> 23 #include <QMap> 24 #include <QObject> 25 #include <QSettings> 26 27 #include "core/song.h" 28 #include "playlist.h" 29 #include "smartplaylists/generator_fwd.h" 30 31 class Application; 32 class LibraryBackend; 33 class PlaylistBackend; 34 class PlaylistContainer; 35 class PlaylistParser; 36 class PlaylistSequence; 37 class TaskManager; 38 39 class QModelIndex; 40 class QUrl; 41 42 class PlaylistManagerInterface : public QObject { 43 Q_OBJECT 44 45 public: PlaylistManagerInterface(Application * app,QObject * parent)46 PlaylistManagerInterface(Application* app, QObject* parent) 47 : QObject(parent) {} 48 49 virtual int current_id() const = 0; 50 virtual int active_id() const = 0; 51 52 virtual Playlist* playlist(int id) const = 0; 53 virtual Playlist* current() const = 0; 54 virtual Playlist* active() const = 0; 55 56 // Returns the collection of playlists managed by this PlaylistManager. 57 virtual QList<Playlist*> GetAllPlaylists() const = 0; 58 // Grays out and reloads all deleted songs in all playlists. 59 virtual void InvalidateDeletedSongs() = 0; 60 // Removes all deleted songs from all playlists. 61 virtual void RemoveDeletedSongs() = 0; 62 63 virtual QItemSelection selection(int id) const = 0; 64 virtual QItemSelection current_selection() const = 0; 65 virtual QItemSelection active_selection() const = 0; 66 67 virtual QString GetPlaylistName(int index) const = 0; 68 69 virtual LibraryBackend* library_backend() const = 0; 70 virtual PlaylistBackend* playlist_backend() const = 0; 71 virtual PlaylistSequence* sequence() const = 0; 72 virtual PlaylistParser* parser() const = 0; 73 virtual PlaylistContainer* playlist_container() const = 0; 74 75 public slots: 76 virtual void New(const QString& name, const SongList& songs = SongList(), 77 const QString& special_type = QString()) = 0; 78 virtual void Load(const QString& filename) = 0; 79 virtual void Save(int id, const QString& filename, 80 Playlist::Path path_type) = 0; 81 virtual void Rename(int id, const QString& new_name) = 0; 82 virtual void Delete(int id) = 0; 83 virtual bool Close(int id) = 0; 84 virtual void Open(int id) = 0; 85 virtual void ChangePlaylistOrder(const QList<int>& ids) = 0; 86 87 virtual void Enque(int id, int index) = 0; 88 89 virtual void SongChangeRequestProcessed(const QUrl& url, bool valid) = 0; 90 91 virtual void SetCurrentPlaylist(int id) = 0; 92 virtual void SetActivePlaylist(int id) = 0; 93 virtual void SetActiveToCurrent() = 0; 94 95 virtual void SelectionChanged(const QItemSelection& selection) = 0; 96 97 // Convenience slots that defer to either current() or active() 98 virtual void ClearCurrent() = 0; 99 virtual void ShuffleCurrent() = 0; 100 virtual void RemoveDuplicatesCurrent() = 0; 101 virtual void RemoveUnavailableCurrent() = 0; 102 virtual void SetActivePlaying() = 0; 103 virtual void SetActivePaused() = 0; 104 virtual void SetActiveStopped() = 0; 105 virtual void SetActiveStreamMetadata(const QUrl& url, const Song& song) = 0; 106 // Rate current song using 0.0 - 1.0 scale. 107 virtual void RateCurrentSong(double rating) = 0; 108 // Rate current song using 0 - 5 scale. 109 virtual void RateCurrentSong(int rating) = 0; 110 111 virtual void PlaySmartPlaylist(smart_playlists::GeneratorPtr generator, 112 bool as_new, bool clear) = 0; 113 114 signals: 115 void PlaylistManagerInitialized(); 116 117 void PlaylistAdded(int id, const QString& name, bool favorite); 118 void PlaylistDeleted(int id); 119 void PlaylistClosed(int id); 120 void PlaylistRenamed(int id, const QString& new_name); 121 void PlaylistFavorited(int id, bool favorite); 122 void CurrentChanged(Playlist* new_playlist); 123 void ActiveChanged(Playlist* new_playlist); 124 125 void Error(const QString& message); 126 void SummaryTextChanged(const QString& summary); 127 128 // Forwarded from individual playlists 129 void CurrentSongChanged(const Song& song); 130 131 // Signals that one of manager's playlists has changed (new items, new 132 // ordering etc.) - the argument shows which. 133 void PlaylistChanged(Playlist* playlist); 134 void EditingFinished(const QModelIndex& index); 135 void PlayRequested(const QModelIndex& index); 136 }; 137 138 class PlaylistManager : public PlaylistManagerInterface { 139 Q_OBJECT 140 141 public: 142 PlaylistManager(Application* app, QObject* parent = nullptr); 143 ~PlaylistManager(); 144 current_id()145 int current_id() const { return current_; } active_id()146 int active_id() const { return active_; } 147 playlist(int id)148 Playlist* playlist(int id) const { return playlists_[id].p; } current()149 Playlist* current() const { return playlist(current_id()); } active()150 Playlist* active() const { return playlist(active_id()); } 151 152 // Returns the collection of playlists managed by this PlaylistManager. 153 QList<Playlist*> GetAllPlaylists() const; 154 // Grays out and reloads all deleted songs in all playlists. 155 void InvalidateDeletedSongs(); 156 // Removes all deleted songs from all playlists. 157 void RemoveDeletedSongs(); 158 // Returns true if the playlist is open 159 bool IsPlaylistOpen(int id); 160 161 // Returns a pretty automatic name for playlist created from the given list of 162 // songs. 163 static QString GetNameForNewPlaylist(const SongList& songs); 164 165 QItemSelection selection(int id) const; current_selection()166 QItemSelection current_selection() const { return selection(current_id()); } active_selection()167 QItemSelection active_selection() const { return selection(active_id()); } 168 GetPlaylistName(int index)169 QString GetPlaylistName(int index) const { return playlists_[index].name; } IsPlaylistFavorite(int index)170 bool IsPlaylistFavorite(int index) const { 171 return playlists_[index].p->is_favorite(); 172 } 173 174 void Init(LibraryBackend* library_backend, PlaylistBackend* playlist_backend, 175 PlaylistSequence* sequence, PlaylistContainer* playlist_container); 176 library_backend()177 LibraryBackend* library_backend() const { return library_backend_; } playlist_backend()178 PlaylistBackend* playlist_backend() const { return playlist_backend_; } sequence()179 PlaylistSequence* sequence() const { return sequence_; } parser()180 PlaylistParser* parser() const { return parser_; } playlist_container()181 PlaylistContainer* playlist_container() const { return playlist_container_; } 182 183 public slots: 184 void New(const QString& name, const SongList& songs = SongList(), 185 const QString& special_type = QString()); 186 void Load(const QString& filename); 187 void Save(int id, const QString& filename, Playlist::Path path_type); 188 // Display a file dialog to let user choose a file before saving the file 189 void SaveWithUI(int id, const QString& playlist_name); 190 void Rename(int id, const QString& new_name); 191 void Favorite(int id, bool favorite); 192 void Delete(int id); 193 bool Close(int id); 194 void Open(int id); 195 void ChangePlaylistOrder(const QList<int>& ids); 196 197 void Enque(int id, int index); 198 199 void SetCurrentPlaylist(int id); 200 void SetActivePlaylist(int id); 201 void SetActiveToCurrent(); 202 203 void SelectionChanged(const QItemSelection& selection); 204 205 // Makes a playlist current if it's open already, or opens it and makes it 206 // current if it is hidden. 207 void SetCurrentOrOpen(int id); 208 209 // Convenience slots that defer to either current() or active() 210 void ClearCurrent(); 211 void ShuffleCurrent(); 212 void RemoveDuplicatesCurrent(); 213 void RemoveUnavailableCurrent(); 214 void SetActiveStreamMetadata(const QUrl& url, const Song& song); 215 // Rate current song using 0.0 - 1.0 scale. 216 void RateCurrentSong(double rating); 217 // Rate current song using 0 - 5 scale. 218 void RateCurrentSong(int rating); 219 220 void PlaySmartPlaylist(smart_playlists::GeneratorPtr generator, bool as_new, 221 bool clear); 222 223 void SongChangeRequestProcessed(const QUrl& url, bool valid); 224 225 void InsertUrls(int id, const QList<QUrl>& urls, int pos = -1, 226 bool play_now = false, bool enqueue = false); 227 void InsertSongs(int id, const SongList& songs, int pos = -1, 228 bool play_now = false, bool enqueue = false); 229 // Removes items with given indices from the playlist. This operation is not 230 // undoable. 231 void RemoveItemsWithoutUndo(int id, const QList<int>& indices); 232 // Remove the current playing song 233 void RemoveCurrentSong(); 234 235 private slots: 236 void SetActivePlaying(); 237 void SetActivePaused(); 238 void SetActiveStopped(); 239 240 void OneOfPlaylistsChanged(); 241 void UpdateSummaryText(); 242 void SongsDiscovered(const SongList& songs); 243 void ItemsLoadedForSavePlaylist(QFuture<SongList> future, 244 const QString& filename, 245 Playlist::Path path_type); 246 247 private: 248 Playlist* AddPlaylist(int id, const QString& name, 249 const QString& special_type, const QString& ui_path, 250 bool favorite); 251 252 private: 253 struct Data { 254 Data(Playlist* _p = nullptr, const QString& _name = QString()) pData255 : p(_p), name(_name) {} 256 Playlist* p; 257 QString name; 258 QItemSelection selection; 259 }; 260 261 Application* app_; 262 PlaylistBackend* playlist_backend_; 263 LibraryBackend* library_backend_; 264 PlaylistSequence* sequence_; 265 PlaylistParser* parser_; 266 PlaylistContainer* playlist_container_; 267 268 // key = id 269 QMap<int, Data> playlists_; 270 271 int current_; 272 int active_; 273 }; 274 275 #endif // PLAYLISTMANAGER_H 276