File indexing completed on 2024-05-19 04:49:24

0001 /****************************************************************************************
0002  * Copyright (c) 2009-2011 Bart Cerneels <bart.cerneels@kde.org>                        *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #ifndef METAPLAYLISTFILE_H
0018 #define METAPLAYLISTFILE_H
0019 
0020 #include "amarok_export.h"
0021 #include "core/playlists/Playlist.h"
0022 #include "core/meta/forward_declarations.h"
0023 #include "core-impl/meta/proxy/MetaProxy.h"
0024 
0025 #include <QMutex>
0026 #include <QSemaphore>
0027 
0028 class QFile;
0029 
0030 namespace Playlists
0031 {
0032     class PlaylistProvider;
0033     class PlaylistFile;
0034     class PlaylistFileLoaderJob;
0035 
0036     typedef AmarokSharedPointer<PlaylistFile> PlaylistFilePtr;
0037     typedef QList<PlaylistFilePtr> PlaylistFileList;
0038 
0039     /**
0040      * Base class for all playlist files
0041      **/
0042     class AMAROK_EXPORT PlaylistFile : public Playlist
0043     {
0044         friend class PlaylistFileLoaderJob;
0045 
0046         public:
0047             /* Playlist methods */
0048             QUrl uidUrl() const override { return m_url; }
0049             QString name() const override { return m_url.fileName(); }
0050             Meta::TrackList tracks() override { return m_tracks; }
0051             int trackCount() const override;
0052             void addTrack( const Meta::TrackPtr &track, int position ) override;
0053             void removeTrack( int position ) override;
0054             void triggerTrackLoad() override;
0055 
0056             /**
0057              * Overrides filename
0058              */
0059             void setName( const QString &name ) override;
0060             PlaylistProvider *provider() const override { return m_provider; }
0061 
0062             /* PlaylistFile methods */
0063             virtual QList<int> queue() { return QList<int>(); }
0064             virtual void setQueue( const QList<int> &rows ) { Q_UNUSED( rows ); }
0065 
0066             /**
0067              * Returns file extension which is corresponding to the playlist type
0068              */
0069             virtual QString extension() const = 0;
0070 
0071             /**
0072              * Returns mime type of this playlist file
0073              */
0074             virtual QString mimetype() const = 0;
0075             virtual bool isWritable() const;
0076 
0077             /**
0078              * Saves the playlist to underlying file immediately.
0079              *
0080              * @param relative whether to use relative paths to track in the file
0081              */
0082             bool save( bool relative );
0083 
0084             /**
0085              * Adds tracks to internal store.
0086              *
0087              * @note in order to save tracks to file, save method should be called
0088              **/
0089             virtual void addTracks( const Meta::TrackList &tracks ) { m_tracks += tracks; }
0090             void setGroups( const QStringList &groups ) override { m_groups = groups; }
0091             QStringList groups() override { return m_groups; }
0092 
0093         protected:
0094             PlaylistFile( const QUrl &url, PlaylistProvider *provider );
0095 
0096             /**
0097              * Schedule this playlist file to be saved on the next iteration of the
0098              * mainloop. Useful in addTrack() and removeTrack() functions.
0099              */
0100             void saveLater();
0101 
0102             /**
0103              * Actual file-specific implementation of playlist saving.
0104              */
0105             virtual void savePlaylist( QFile &file ) = 0;
0106 
0107             /**
0108              * Appends MetaProxy::Track* to m_tracks and invokes notifyObserversTrackAdded()
0109              */
0110             void addProxyTrack( const Meta::TrackPtr &proxyTrack );
0111 
0112             /**
0113              * Loads playlist from the stream.
0114              * @returns true if the loading was successful.
0115              */
0116             virtual bool load( QTextStream &stream ) = 0;
0117 
0118             /**
0119              * Loads playlist from QByteArray in order to postpone encoding detection procedure
0120              * @returns true if the loading was successful.
0121              */
0122             virtual bool load( QByteArray &content ) { QTextStream stream( &content ); return load( stream ); }
0123 
0124             /** Normalizes track location */
0125             QString trackLocation( const Meta::TrackPtr &track ) const;
0126 
0127             /**
0128              * If the passed url is relative, this method convert given url to absolute.
0129              * For example, "tunes/tune.ogg" gets converted to "file:///playlists/tunes/tune.ogg"
0130              * Sets m_relative to true if it ecounters a relative url
0131              * (this serves to preserve playlist "relativity" across reads & saves)
0132              **/
0133             QUrl getAbsolutePath( const QUrl &url );
0134 
0135             PlaylistProvider *m_provider;
0136             QStringList m_groups;
0137 
0138             QUrl m_url;
0139 
0140             mutable bool m_tracksLoaded;
0141             mutable Meta::TrackList m_tracks;
0142             QString m_name;
0143             /** true if tracks path are relative */
0144             bool m_relativePaths;
0145 
0146             QMutex m_saveLock;
0147             /** allows to wait for end of loading */
0148             QSemaphore m_loadingDone;
0149     };
0150 }
0151 
0152 Q_DECLARE_METATYPE( Playlists::PlaylistFilePtr )
0153 Q_DECLARE_METATYPE( Playlists::PlaylistFileList )
0154 
0155 #endif