File indexing completed on 2024-04-21 08:38:41

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 &currentTrack);
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