1 /****************************************************************************************
2  * Copyright (c) 2009-2011 Bart Cerneels <bart.cerneels@kde.org>                        *
3  *                                                                                      *
4  * This program is free software; you can redistribute it and/or modify it under        *
5  * the terms of the GNU General Public License as published by the Free Software        *
6  * Foundation; either version 2 of the License, or (at your option) any later           *
7  * version.                                                                             *
8  *                                                                                      *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12  *                                                                                      *
13  * You should have received a copy of the GNU General Public License along with         *
14  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15  ****************************************************************************************/
16 
17 #ifndef METAPLAYLISTFILE_H
18 #define METAPLAYLISTFILE_H
19 
20 #include "amarok_export.h"
21 #include "core/playlists/Playlist.h"
22 #include "core/meta/forward_declarations.h"
23 #include "core-impl/meta/proxy/MetaProxy.h"
24 
25 #include <QMutex>
26 #include <QSemaphore>
27 
28 class QFile;
29 
30 namespace Playlists
31 {
32     class PlaylistProvider;
33     class PlaylistFile;
34     class PlaylistFileLoaderJob;
35 
36     typedef AmarokSharedPointer<PlaylistFile> PlaylistFilePtr;
37     typedef QList<PlaylistFilePtr> PlaylistFileList;
38 
39     /**
40      * Base class for all playlist files
41      **/
42     class AMAROK_EXPORT PlaylistFile : public Playlist
43     {
44         friend class PlaylistFileLoaderJob;
45 
46         public:
47             /* Playlist methods */
uidUrl()48             QUrl uidUrl() const override { return m_url; }
name()49             QString name() const override { return m_url.fileName(); }
tracks()50             Meta::TrackList tracks() override { return m_tracks; }
51             int trackCount() const override;
52             void addTrack( const Meta::TrackPtr &track, int position ) override;
53             void removeTrack( int position ) override;
54             void triggerTrackLoad() override;
55 
56             /**
57              * Overrides filename
58              */
59             void setName( const QString &name ) override;
provider()60             PlaylistProvider *provider() const override { return m_provider; }
61 
62             /* PlaylistFile methods */
queue()63             virtual QList<int> queue() { return QList<int>(); }
setQueue(const QList<int> & rows)64             virtual void setQueue( const QList<int> &rows ) { Q_UNUSED( rows ); }
65 
66             /**
67              * Returns file extension which is corresponding to the playlist type
68              */
69             virtual QString extension() const = 0;
70 
71             /**
72              * Returns mime type of this playlist file
73              */
74             virtual QString mimetype() const = 0;
75             virtual bool isWritable() const;
76 
77             /**
78              * Saves the playlist to underlying file immediately.
79              *
80              * @param relative whether to use relative paths to track in the file
81              */
82             bool save( bool relative );
83 
84             /**
85              * Adds tracks to internal store.
86              *
87              * @note in order to save tracks to file, save method should be called
88              **/
addTracks(const Meta::TrackList & tracks)89             virtual void addTracks( const Meta::TrackList &tracks ) { m_tracks += tracks; }
setGroups(const QStringList & groups)90             void setGroups( const QStringList &groups ) override { m_groups = groups; }
groups()91             QStringList groups() override { return m_groups; }
92 
93         protected:
94             PlaylistFile( const QUrl &url, PlaylistProvider *provider );
95 
96             /**
97              * Schedule this playlist file to be saved on the next iteration of the
98              * mainloop. Useful in addTrack() and removeTrack() functions.
99              */
100             void saveLater();
101 
102             /**
103              * Actual file-specific implementation of playlist saving.
104              */
105             virtual void savePlaylist( QFile &file ) = 0;
106 
107             /**
108              * Appends MetaProxy::Track* to m_tracks and invokes notifyObserversTrackAdded()
109              */
110             void addProxyTrack( const Meta::TrackPtr &proxyTrack );
111 
112             /**
113              * Loads playlist from the stream.
114              * @returns true if the loading was successful.
115              */
116             virtual bool load( QTextStream &stream ) = 0;
117 
118             /**
119              * Loads playlist from QByteArray in order to postpone encoding detection procedure
120              * @returns true if the loading was successful.
121              */
load(QByteArray & content)122             virtual bool load( QByteArray &content ) { QTextStream stream( &content ); return load( stream ); }
123 
124             /** Normalizes track location */
125             QString trackLocation( const Meta::TrackPtr &track ) const;
126 
127             /**
128              * If the passed url is relative, this method convert given url to absolute.
129              * For example, "tunes/tune.ogg" gets converted to "file:///playlists/tunes/tune.ogg"
130              * Sets m_relative to true if it ecounters a relative url
131              * (this serves to preserve playlist "relativity" across reads & saves)
132              **/
133             QUrl getAbsolutePath( const QUrl &url );
134 
135             PlaylistProvider *m_provider;
136             QStringList m_groups;
137 
138             QUrl m_url;
139 
140             mutable bool m_tracksLoaded;
141             mutable Meta::TrackList m_tracks;
142             QString m_name;
143             /** true if tracks path are relative */
144             bool m_relativePaths;
145 
146             QMutex m_saveLock;
147             /** allows to wait for end of loading */
148             QSemaphore m_loadingDone;
149     };
150 }
151 
152 Q_DECLARE_METATYPE( Playlists::PlaylistFilePtr )
153 Q_DECLARE_METATYPE( Playlists::PlaylistFileList )
154 
155 #endif
156