File indexing completed on 2024-05-05 04:48:13

0001 /****************************************************************************************
0002  * Copyright (c) 2008 Ian Monroe <ian@monroe.nu>                                        *
0003  * Copyright (c) 2013 Matěj Laitl <matej@laitl.cz>                                      *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) version 3 or        *
0008  * any later version accepted by the membership of KDE e.V. (or its successor approved  *
0009  * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of  *
0010  * version 3 of the license.                                                            *
0011  *                                                                                      *
0012  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0013  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0014  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0015  *                                                                                      *
0016  * You should have received a copy of the GNU General Public License along with         *
0017  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0018  ****************************************************************************************/
0019 
0020 #ifndef AMAROK_TRACKLOADER_H
0021 #define AMAROK_TRACKLOADER_H
0022 
0023 #include "amarok_export.h"
0024 #include "core/meta/forward_declarations.h"
0025 #include "core/meta/Observer.h"
0026 #include "core/playlists/Playlist.h"
0027 
0028 namespace KIO {
0029     class Job;
0030     class UDSEntry;
0031     typedef QList<UDSEntry> UDSEntryList;
0032 }
0033 
0034 /**
0035  * Helper class that helps with loading of urls (with local and remote tracks,
0036  * playlists and local directories) to tracks.
0037  *
0038  * Only explicitly listed playlists are loaded, not the ones found in subdirectories.
0039  * TrackLoader takes care to preserve order of urls you pass, and it sorts tracks in
0040  * directories you pass it using directory- and locale-aware sort.
0041  */
0042 class AMAROK_EXPORT TrackLoader : public QObject, public Playlists::PlaylistObserver, public Meta::Observer
0043 {
0044     Q_OBJECT
0045 
0046     public:
0047         /**
0048          * FullMetadataRequired: signal TrackLoader that it should postpone the finished()
0049          * signal until the any possible proxy tracks have resolved and their full
0050          * metadata is available. Also use this flag when you need to immediately play
0051          * the tracks. This no longer implies any blocking behaviour, you'll just get the
0052          * finished signal a bit later.
0053          *
0054          * RemotePlaylistsAreStreams: treat playlists with remote urls as Streams with
0055          * multiple alternative download locations (Meta::MultiTracks). Works even when
0056          * you pass playlists.
0057          */
0058         enum Flag {
0059             FullMetadataRequired = 1 << 0,
0060             RemotePlaylistsAreStreams = 1 << 1,
0061         };
0062         Q_DECLARE_FLAGS( Flags, Flag )
0063 
0064         /**
0065          * Construct TrackLoader. You must construct it on the heap, it will auto-delete
0066          * itself.
0067          *
0068          * @param flags binary or of flags, see TrackLoader::Flags enum
0069          * @param timeout if FullMetadataRequired is in flags, this is the timeout in
0070          * milliseconds for waiting on track to resolve. Ignored otherwise.
0071          */
0072         explicit TrackLoader( Flags flags = {}, int timeout = 2000 );
0073         ~TrackLoader() override;
0074 
0075         /**
0076          * Convenience overload for init( const QList<QUrl> &urls )
0077          */
0078         void init( const QUrl &url );
0079 
0080         /**
0081          * Starts TrackLoader's job, you'll get finished() signal in the end and
0082          * TrackLoader will auto-delete itself.
0083          *
0084          * @param urls list of urls to load tracks from, you can pass local and remote urls
0085          * pointing to directories, tracks and playlists.
0086          */
0087         void init( const QList<QUrl> &urls );
0088 
0089         /**
0090          * Short-hand if you already have a list of playlists and want a convenient way
0091          * to get notified of their loaded tracks. See init( const QList<QUrl> ) and
0092          * class description.
0093          */
0094         void init( const Playlists::PlaylistList &playlists );
0095 
0096         /* PlaylistObserver methods */
0097         using PlaylistObserver::metadataChanged;
0098         void tracksLoaded( Playlists::PlaylistPtr playlist ) override;
0099 
0100         /* Meta::Observer methods */
0101         using Observer::metadataChanged;
0102         void metadataChanged( const Meta::TrackPtr &track ) override;
0103 
0104     Q_SIGNALS:
0105         void finished( const Meta::TrackList &tracks );
0106 
0107     private Q_SLOTS:
0108         void processNextSourceUrl();
0109         void directoryListResults( KIO::Job *job, const KIO::UDSEntryList &list );
0110         void processNextResultUrl();
0111         /**
0112          * Emits the result and auto-destroys the TrackLoader
0113          */
0114         void finish();
0115 
0116     private:
0117         enum Status {
0118             LoadingTracks,
0119             MayFinish,
0120             Finished
0121         };
0122         void mayFinish();
0123 
0124         static bool directorySensitiveLessThan( const QUrl &left, const QUrl &right );
0125 
0126         Status m_status;
0127         const Flags m_flags;
0128         int m_timeout;
0129         /// passed urls, may contain urls of directories
0130         QList<QUrl> m_sourceUrls;
0131         /// contains just urls of tracks and playlists
0132         QList<QUrl> m_resultUrls;
0133         /// a list of playlists directly passed, same semantics as m_resultUrls
0134         Playlists::PlaylistList m_resultPlaylists;
0135         /// the tracks found
0136         Meta::TrackList m_tracks;
0137         /// set of unresolved MetaProxy::Tracks that we wait for
0138         QSet<Meta::TrackPtr> m_unresolvedTracks;
0139         QMutex m_unresolvedTracksMutex;
0140 };
0141 
0142 Q_DECLARE_OPERATORS_FOR_FLAGS( TrackLoader::Flags )
0143 
0144 #endif // AMAROK_TRACKLOADER_H