1 /**************************************************************************************** 2 * Copyright (c) 2008 Ian Monroe <ian@monroe.nu> * 3 * Copyright (c) 2013 Matěj Laitl <matej@laitl.cz> * 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) version 3 or * 8 * any later version accepted by the membership of KDE e.V. (or its successor approved * 9 * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of * 10 * version 3 of the license. * 11 * * 12 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 14 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU General Public License along with * 17 * this program. If not, see <http://www.gnu.org/licenses/>. * 18 ****************************************************************************************/ 19 20 #ifndef AMAROK_TRACKLOADER_H 21 #define AMAROK_TRACKLOADER_H 22 23 #include "amarok_export.h" 24 #include "core/meta/forward_declarations.h" 25 #include "core/meta/Observer.h" 26 #include "core/playlists/Playlist.h" 27 28 namespace KIO { 29 class Job; 30 class UDSEntry; 31 typedef QList<UDSEntry> UDSEntryList; 32 } 33 34 /** 35 * Helper class that helps with loading of urls (with local and remote tracks, 36 * playlists and local directories) to tracks. 37 * 38 * Only explicitly listed playlists are loaded, not the ones found in subdirectories. 39 * TrackLoader takes care to preserve order of urls you pass, and it sorts tracks in 40 * directories you pass it using directory- and locale-aware sort. 41 */ 42 class AMAROK_EXPORT TrackLoader : public QObject, public Playlists::PlaylistObserver, public Meta::Observer 43 { 44 Q_OBJECT 45 46 public: 47 /** 48 * FullMetadataRequired: signal TrackLoader that it should postpone the finished() 49 * signal until the any possible proxy tracks have resolved and their full 50 * metadata is available. Also use this flag when you need to immediately play 51 * the tracks. This no longer implies any blocking behaviour, you'll just get the 52 * finished signal a bit later. 53 * 54 * RemotePlaylistsAreStreams: treat playlists with remote urls as Streams with 55 * multiple alternative download locations (Meta::MultiTracks). Works even when 56 * you pass playlists. 57 */ 58 enum Flag { 59 FullMetadataRequired = 1 << 0, 60 RemotePlaylistsAreStreams = 1 << 1, 61 }; 62 Q_DECLARE_FLAGS( Flags, Flag ) 63 64 /** 65 * Construct TrackLoader. You must construct it on the heap, it will auto-delete 66 * itself. 67 * 68 * @param flags binary or of flags, see TrackLoader::Flags enum 69 * @param timeout if FullMetadataRequired is in flags, this is the timeout in 70 * milliseconds for waiting on track to resolve. Ignored otherwise. 71 */ 72 explicit TrackLoader( Flags flags = 0, int timeout = 2000 ); 73 ~TrackLoader() override; 74 75 /** 76 * Convenience overload for init( const QList<QUrl> &urls ) 77 */ 78 void init( const QUrl &url ); 79 80 /** 81 * Starts TrackLoader's job, you'll get finished() signal in the end and 82 * TrackLoader will auto-delete itself. 83 * 84 * @param urls list of urls to load tracks from, you can pass local and remote urls 85 * pointing to directories, tracks and playlists. 86 */ 87 void init( const QList<QUrl> &urls ); 88 89 /** 90 * Short-hand if you already have a list of playlists and want a convenient way 91 * to get notified of their loaded tracks. See init( const QList<QUrl> ) and 92 * class description. 93 */ 94 void init( const Playlists::PlaylistList &playlists ); 95 96 /* PlaylistObserver methods */ 97 using PlaylistObserver::metadataChanged; 98 void tracksLoaded( Playlists::PlaylistPtr playlist ) override; 99 100 /* Meta::Observer methods */ 101 using Observer::metadataChanged; 102 void metadataChanged( const Meta::TrackPtr &track ) override; 103 104 Q_SIGNALS: 105 void finished( const Meta::TrackList &tracks ); 106 107 private Q_SLOTS: 108 void processNextSourceUrl(); 109 void directoryListResults( KIO::Job *job, const KIO::UDSEntryList &list ); 110 void processNextResultUrl(); 111 /** 112 * Emits the result and auto-destroys the TrackLoader 113 */ 114 void finish(); 115 116 private: 117 enum Status { 118 LoadingTracks, 119 MayFinish, 120 Finished 121 }; 122 void mayFinish(); 123 124 static bool directorySensitiveLessThan( const QUrl &left, const QUrl &right ); 125 126 Status m_status; 127 const Flags m_flags; 128 int m_timeout; 129 /// passed urls, may contain urls of directories 130 QList<QUrl> m_sourceUrls; 131 /// contains just urls of tracks and playlists 132 QList<QUrl> m_resultUrls; 133 /// a list of playlists directly passed, same semantics as m_resultUrls 134 Playlists::PlaylistList m_resultPlaylists; 135 /// the tracks found 136 Meta::TrackList m_tracks; 137 /// set of unresolved MetaProxy::Tracks that we wait for 138 QSet<Meta::TrackPtr> m_unresolvedTracks; 139 QMutex m_unresolvedTracksMutex; 140 }; 141 142 Q_DECLARE_OPERATORS_FOR_FLAGS( TrackLoader::Flags ) 143 144 #endif // AMAROK_TRACKLOADER_H 145