File indexing completed on 2024-03-24 04:51:45
0001 /* 0002 SPDX-FileCopyrightText: 2015 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 SPDX-FileCopyrightText: 2019 (c) Alexander Stippich <a.stippich@gmx.net> 0004 SPDX-FileCopyrightText: 2020 (c) Carson Black <uhhadd@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-3.0-or-later 0007 */ 0008 0009 #ifndef MEDIAPLAYLISTPROXYMODEL_H 0010 #define MEDIAPLAYLISTPROXYMODEL_H 0011 0012 #include "elisaLib_export.h" 0013 #include "elisautils.h" 0014 #include "datatypes.h" 0015 0016 #include <QAbstractProxyModel> 0017 #include <QMediaPlayer> 0018 #include <QMimeType> 0019 #include <QFileInfo> 0020 0021 #include <memory> 0022 0023 class M3uPlaylistParser 0024 { 0025 public: 0026 QList<QUrl> fromPlaylist(const QUrl &fileName, const QByteArray &fileContent); 0027 QString toPlaylist(const QUrl &fileName, const QList<QString> &listOfUrls); 0028 }; 0029 0030 class PlsPlaylistParser 0031 { 0032 public: 0033 QList<QUrl> fromPlaylist(const QUrl &fileName, const QByteArray &fileContent); 0034 QString toPlaylist(const QUrl &fileName, const QList<QString> &listOfUrls); 0035 }; 0036 0037 class ELISALIB_EXPORT PlaylistParser 0038 { 0039 public: 0040 QList<QUrl> fromPlaylist(const QUrl &fileName, const QByteArray &fileContent); 0041 QString toPlaylist(const QUrl &fileName, const QList<QString> &listOfUrls); 0042 0043 private: 0044 int filterImported(QList<QUrl>& result, const QUrl &playlistUrl); 0045 }; 0046 0047 class MediaPlayList; 0048 class MediaPlayListProxyModelPrivate; 0049 0050 class ELISALIB_EXPORT MediaPlayListProxyModel : public QAbstractProxyModel 0051 { 0052 0053 Q_OBJECT 0054 0055 public: 0056 enum Repeat { 0057 None, 0058 One, 0059 Playlist 0060 }; 0061 Q_ENUM(Repeat) 0062 0063 private: 0064 0065 Q_PROPERTY(QVariantMap persistentState 0066 READ persistentState 0067 WRITE setPersistentState 0068 NOTIFY persistentStateChanged) 0069 0070 Q_PROPERTY(QPersistentModelIndex previousTrack 0071 READ previousTrack 0072 NOTIFY previousTrackChanged) 0073 0074 Q_PROPERTY(QPersistentModelIndex currentTrack 0075 READ currentTrack 0076 NOTIFY currentTrackChanged) 0077 0078 Q_PROPERTY(QPersistentModelIndex nextTrack 0079 READ nextTrack 0080 NOTIFY nextTrackChanged) 0081 0082 Q_PROPERTY(Repeat repeatMode 0083 READ repeatMode 0084 WRITE setRepeatMode 0085 NOTIFY repeatModeChanged) 0086 0087 Q_PROPERTY(bool shufflePlayList 0088 READ shufflePlayList 0089 WRITE setShufflePlayList 0090 NOTIFY shufflePlayListChanged) 0091 0092 Q_PROPERTY(int remainingTracks 0093 READ remainingTracks 0094 NOTIFY remainingTracksChanged) 0095 0096 Q_PROPERTY(int currentTrackRow 0097 READ currentTrackRow 0098 NOTIFY currentTrackRowChanged) 0099 0100 Q_PROPERTY(int tracksCount 0101 READ tracksCount 0102 NOTIFY tracksCountChanged) 0103 0104 Q_PROPERTY(bool partiallyLoaded 0105 READ partiallyLoaded 0106 NOTIFY partiallyLoadedChanged 0107 RESET resetPartiallyLoaded) 0108 0109 Q_PROPERTY(bool canOpenLoadedPlaylist 0110 READ canOpenLoadedPlaylist 0111 NOTIFY canOpenLoadedPlaylistChanged) 0112 0113 public: 0114 0115 explicit MediaPlayListProxyModel(QObject *parent = nullptr); 0116 0117 ~MediaPlayListProxyModel() override; 0118 0119 [[nodiscard]] QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; 0120 0121 [[nodiscard]] QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; 0122 0123 [[nodiscard]] QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection) const override; 0124 0125 [[nodiscard]] QItemSelection mapSelectionToSource(const QItemSelection &proxySelection) const override; 0126 0127 [[nodiscard]] QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; 0128 0129 [[nodiscard]] int mapRowFromSource(const int sourceRow) const; 0130 0131 [[nodiscard]] int mapRowToSource(const int proxyRow) const; 0132 0133 [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0134 0135 [[nodiscard]] int columnCount(const QModelIndex &parent) const override; 0136 0137 [[nodiscard]] QModelIndex parent(const QModelIndex &child) const override; 0138 0139 [[nodiscard]] bool hasChildren(const QModelIndex &parent) const override; 0140 0141 void setPlayListModel(MediaPlayList* playListModel); 0142 0143 [[nodiscard]] QPersistentModelIndex previousTrack() const; 0144 0145 [[nodiscard]] QPersistentModelIndex currentTrack() const; 0146 0147 [[nodiscard]] QPersistentModelIndex nextTrack() const; 0148 0149 [[nodiscard]] Repeat repeatMode() const; 0150 0151 [[nodiscard]] bool shufflePlayList() const; 0152 0153 [[nodiscard]] int remainingTracks() const; 0154 0155 [[nodiscard]] int currentTrackRow() const; 0156 0157 [[nodiscard]] int tracksCount() const; 0158 0159 [[nodiscard]] QVariantMap persistentState() const; 0160 0161 [[nodiscard]] bool partiallyLoaded() const; 0162 0163 [[nodiscard]] bool canOpenLoadedPlaylist() const; 0164 0165 int mSeekToBeginningDelay = 2000; 0166 0167 0168 public Q_SLOTS: 0169 0170 void enqueue(const QUrl &entryUrl, 0171 ElisaUtils::PlayListEnqueueMode enqueueMode, 0172 ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); 0173 0174 void enqueue(const DataTypes::MusicDataType &newEntry, 0175 const QString &newEntryTitle, 0176 ElisaUtils::PlayListEnqueueMode enqueueMode, 0177 ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); 0178 0179 void enqueue(const DataTypes::EntryDataList &newEntries, 0180 ElisaUtils::PlayListEnqueueMode enqueueMode, 0181 ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); 0182 0183 void setRepeatMode(Repeat value); 0184 0185 void setShufflePlayList(bool value); 0186 0187 void trackInError(const QUrl &sourceInError, QMediaPlayer::Error playerError); 0188 0189 void skipNextTrack(ElisaUtils::SkipReason reason = ElisaUtils::SkipReason::Automatic); 0190 0191 void skipPreviousTrack(qint64 position); 0192 0193 void switchTo(int row); 0194 0195 void removeSelection(QList<int> selection); 0196 0197 void removeRow(int row); 0198 0199 void moveRow(int from, int to); 0200 0201 void clearPlayList(); 0202 0203 void undoClearPlayList(); 0204 0205 bool savePlayList(const QUrl &fileName); 0206 0207 void loadPlayList(const QUrl &fileName); 0208 0209 void loadPlayList(const QUrl &fileName, ElisaUtils::PlayListEnqueueMode enqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); 0210 0211 void setPersistentState(const QVariantMap &persistentState); 0212 0213 void openLoadedPlayList(); 0214 0215 void resetPartiallyLoaded(); 0216 0217 int indexForTrackUrl(const QUrl &url); 0218 0219 void switchToTrackUrl(const QUrl &url, ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay); 0220 0221 Q_SIGNALS: 0222 0223 void previousTrackChanged(const QPersistentModelIndex &previousTrack); 0224 0225 void currentTrackChanged(const QPersistentModelIndex ¤tTrack); 0226 0227 void nextTrackChanged(const QPersistentModelIndex &nextTrack); 0228 0229 void previousTrackDataChanged(); 0230 0231 void currentTrackDataChanged(); 0232 0233 void nextTrackDataChanged(); 0234 0235 void repeatModeChanged(); 0236 0237 void shufflePlayListChanged(); 0238 0239 void remainingTracksChanged(); 0240 0241 void ensurePlay(); 0242 0243 void requestPlay(); 0244 0245 void currentTrackRowChanged(); 0246 0247 void tracksCountChanged(); 0248 0249 void playListFinished(); 0250 0251 void playListLoaded(); 0252 0253 void playListLoadFailed(); 0254 0255 void persistentStateChanged(); 0256 0257 void clearPlayListPlayer(); 0258 0259 void undoClearPlayListPlayer(); 0260 0261 void displayUndoNotification(); 0262 0263 void hideUndoNotification(); 0264 0265 void seek(qint64 position); 0266 0267 void partiallyLoadedChanged(); 0268 0269 void canOpenLoadedPlaylistChanged(); 0270 0271 private Q_SLOTS: 0272 0273 void sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end); 0274 0275 void sourceRowsInserted(const QModelIndex &parent, int start, int end); 0276 0277 void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); 0278 0279 void sourceRowsRemoved(const QModelIndex &parent, int start, int end); 0280 0281 void sourceRowsAboutToBeMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow); 0282 0283 void sourceRowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow); 0284 0285 void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles); 0286 0287 void sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last); 0288 0289 void sourceLayoutAboutToBeChanged(); 0290 0291 void sourceLayoutChanged(); 0292 0293 void sourceModelAboutToBeReset(); 0294 0295 void sourceModelReset(); 0296 0297 private: 0298 0299 void setSourceModel(QAbstractItemModel *sourceModel) override; 0300 0301 void determineTracks(); 0302 0303 void notifyCurrentTrackRowChanged(); 0304 0305 void notifyCurrentTrackChanged(); 0306 0307 void determineAndNotifyPreviousAndNextTracks(); 0308 0309 void loadLocalFile(DataTypes::EntryDataList &newTracks, QSet<QString> &processedFiles, const QFileInfo &fileInfo); 0310 0311 void loadLocalPlayList(DataTypes::EntryDataList &newTracks, QSet<QString> &processedUFiles, const QUrl &fileName, const QByteArray &fileContent); 0312 0313 void loadLocalDirectory(DataTypes::EntryDataList &newTracks, QSet<QString> &processedFiles, const QUrl &dirName); 0314 0315 int filterLocalPlayList(QList<QUrl>& result, const QUrl &playlistUrl); 0316 0317 std::unique_ptr<MediaPlayListProxyModelPrivate> d; 0318 }; 0319 0320 #endif // MEDIAPLAYLISTPROXYMODEL_H