1 /****************************************************************************************
2  * Copyright (c) 2007 Bart Cerneels <bart.cerneels@kde.org>                             *
3  * Copyright (c) 2011 Lucas Lira Gomes <x8lucas8x@gmail.com>                            *
4  *                                                                                      *
5  * This program is free software; you can redistribute it and/or modify it under        *
6  * the terms of the GNU General Public License as published by the Free Software        *
7  * Foundation; either version 2 of the License, or (at your option) any later           *
8  * version.                                                                             *
9  *                                                                                      *
10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
12  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
13  *                                                                                      *
14  * You should have received a copy of the GNU General Public License along with         *
15  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
16  ****************************************************************************************/
17 
18 #ifndef AMAROK_PLAYLISTMANAGER_H
19 #define AMAROK_PLAYLISTMANAGER_H
20 
21 #include "core/support/Amarok.h"
22 #include "amarok_export.h"
23 
24 #include "core/playlists/Playlist.h"
25 #include "core/playlists/PlaylistProvider.h"
26 
27 #include "SyncedPlaylist.h"
28 #include "SyncRelationStorage.h"
29 
30 #include <QMultiMap>
31 #include <QList>
32 
33 class KJob;
34 class PlaylistManager;
35 
36 namespace Playlists {
37     class PlaylistFile;
38     class PlaylistFileProvider;
39     class UserPlaylistProvider;
40     typedef AmarokSharedPointer<PlaylistFile> PlaylistFilePtr;
41 }
42 
43 namespace Podcasts {
44     class PodcastProvider;
45 }
46 
47 namespace The {
48     AMAROK_EXPORT PlaylistManager* playlistManager();
49 }
50 
51 typedef QList<Playlists::PlaylistProvider *> PlaylistProviderList;
52 
53 /**
54  * Facility for managing PlaylistProviders registered by other
55  * parts of the application, plugins and scripts.
56  */
57 class AMAROK_EXPORT PlaylistManager : public QObject
58 {
59     Q_OBJECT
60 
61     public:
62         enum PlaylistCategory
63         {
64             UserPlaylist = 1,
65             PodcastChannel
66         };
67         Q_ENUM( PlaylistCategory )
68 
69         static PlaylistManager *instance();
70         static void destroy();
71 
72         /**
73          * @returns all available categories registered at that moment
74          */
availableCategories()75         QList<int> availableCategories() { return m_providerMap.uniqueKeys(); }
76 
77         /**
78          * returns playlists of a certain category from all registered PlaylistProviders
79          */
80         Playlists::PlaylistList playlistsOfCategory( int playlistCategory );
81 
82         /**
83         * returns all PlaylistProviders that provider a certain playlist category.
84         **/
85         PlaylistProviderList providersForCategory( int playlistCategory );
86 
87         /**
88          * Add a PlaylistProvider that contains Playlists of a category defined
89          * in the PlaylistCategory enum.
90          * @arg provider a PlaylistProvider
91          * @arg category a default Category from the PlaylistManager::PlaylistCategory enum or a
92          * custom one registered before with registerCustomCategory.
93          */
94         void addProvider( Playlists::PlaylistProvider *provider, int category );
95 
96         /**
97          * Do all the work necessary to sync playlists, including the
98          * SyncedPlaylist creation and more. This sync is persistent.
99          * @arg playlist of the master playlist
100          * @arg playlist of the slave playlist
101          */
102         void setupSync( const Playlists::PlaylistPtr master, const Playlists::PlaylistPtr slave );
103 
104         /**
105          * Remove a PlaylistProvider.
106          * @arg provider a PlaylistProvider
107          */
108         void removeProvider( Playlists::PlaylistProvider *provider );
109 
110         Playlists::PlaylistProvider *playlistProvider( int category, QString name );
111 
112         /**
113         *   Saves a list of tracks to a new playlist. Used in the Playlist save button.
114         *   @arg tracks list of tracks to save
115         *   @arg name name of playlist to save
116         *   @arg toProvider If 0 (default) will save to the default UserPlaylistProvider
117         *   @arg editName whether to edit new playlist name as soon as it is created
118         *   @see defaultUserPlaylists
119         */
120         bool save( Meta::TrackList tracks, const QString &name = QString(),
121                    Playlists::PlaylistProvider *toProvider = 0, bool editName = true );
122 
123         /**
124          *  Saves a playlist from a file to the database.
125          *  @param fromLocation Saved playlist file to load
126          */
127          bool import( const QUrl &fromLocation );
128 
129         /**
130          * Initiates renaming of playlists. Can Focus Saved Playlists and
131          * initiate inline rename.
132          *
133          *  @param playlist the playlists.
134          */
135         void rename( Playlists::PlaylistPtr playlist );
136 
137         /**
138          * Rename @p playlist to @p newName, return true if renaming was successful,
139          * false otherwise.
140          *
141          * @param playlist the playlist.
142          * @param newName the new name.
143          */
144         bool rename( Playlists::PlaylistPtr playlist, const QString &newName );
145 
146         bool deletePlaylists( Playlists::PlaylistList playlistlist );
147 
defaultPodcasts()148         Podcasts::PodcastProvider *defaultPodcasts() { return m_defaultPodcastProvider; }
defaultUserPlaylists()149         Playlists::UserPlaylistProvider *defaultUserPlaylists()
150                 { return m_defaultUserPlaylistProvider; }
151 
152         /**
153          *  Retrieves the provider owning the given playlist.
154          *  Will only return multiple providers if this is a synced playlist
155          *  @arg playlist the playlist whose provider we want
156          */
157         QList<Playlists::PlaylistProvider*>
158                 getProvidersForPlaylist( const Playlists::PlaylistPtr playlist );
159 
160         /**
161          *  Checks if the provider to whom this playlist belongs supports writing
162          *  @arg playlist the playlist we are testing for writability
163          *  @return whether or not the playlist is writable
164          */
165 
166         bool isWritable( const Playlists::PlaylistPtr &playlist );
167 
168         void completePodcastDownloads();
169 
170     Q_SIGNALS:
171         void updated( int category );
172         void categoryAdded( int category );
173         void providerAdded( Playlists::PlaylistProvider *provider, int category );
174         void providerRemoved( Playlists::PlaylistProvider *provider, int category );
175         void playlistAdded( Playlists::PlaylistPtr playlist, int category );
176         void playlistRemoved( Playlists::PlaylistPtr playlist, int category );
177         void playlistUpdated( Playlists::PlaylistPtr playlist, int category );
178 
179         void renamePlaylist( Playlists::PlaylistPtr playlist );
180 
181     private Q_SLOTS:
182         void slotUpdated();
183         void slotPlaylistAdded( Playlists::PlaylistPtr playlist );
184         void slotPlaylistRemoved( Playlists::PlaylistPtr playlist );
185         void slotSyncNeeded();
186 
187     private:
188         void loadPlaylists( Playlists::PlaylistProvider *provider, int category );
189         void removePlaylists( Playlists::PlaylistProvider *provider );
190 
191         void addPlaylist( Playlists::PlaylistPtr playlist, int category );
192         void removePlaylist( Playlists::PlaylistPtr playlist, int category );
193 
194         static PlaylistManager *s_instance;
195         PlaylistManager();
196         ~PlaylistManager() override;
197 
198         SyncRelationStorage *m_syncRelStore;
199         QList<SyncedPlaylistPtr> m_syncNeeded;
200 
201         bool hasToSync( Playlists::PlaylistPtr master, Playlists::PlaylistPtr slave );
202 
203         Podcasts::PodcastProvider *m_defaultPodcastProvider;
204         Playlists::UserPlaylistProvider *m_defaultUserPlaylistProvider;
205         Playlists::PlaylistFileProvider *m_playlistFileProvider;
206 
207         QMultiMap<int, Playlists::PlaylistProvider*> m_providerMap; //Map PlaylistCategories to providers
208         QMultiMap<int, Playlists::PlaylistPtr> m_playlistMap;
209         QMultiMap<SyncedPlaylistPtr, Playlists::PlaylistPtr> m_syncedPlaylistMap;
210 
211         QMap<int, QString> m_customCategories;
212 
213         QMap<KJob *, Playlists::PlaylistFilePtr> m_downloadJobMap;
214 };
215 
216 Q_DECLARE_METATYPE( PlaylistProviderList )
217 
218 #endif
219