File indexing completed on 2024-05-05 04:50:33
0001 /* 0002 SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 SPDX-FileCopyrightText: 2017 (c) Alexander Stippich <a.stippich@gmx.net> 0004 0005 SPDX-License-Identifier: LGPL-3.0-or-later 0006 */ 0007 0008 #include "abstractmediaproxymodel.h" 0009 0010 #include "mediaplaylistproxymodel.h" 0011 0012 #include <QWriteLocker> 0013 #include <QReadLocker> 0014 #include <QtConcurrentRun> 0015 0016 AbstractMediaProxyModel::AbstractMediaProxyModel(QObject *parent) : QSortFilterProxyModel(parent) 0017 { 0018 setFilterCaseSensitivity(Qt::CaseInsensitive); 0019 mThreadPool.setMaxThreadCount(1); 0020 0021 connect(&mEnqueueWatcher, &QFutureWatcher<void>::finished, this, &AbstractMediaProxyModel::afterPlaylistEnqueue); 0022 } 0023 0024 AbstractMediaProxyModel::~AbstractMediaProxyModel() 0025 { 0026 disconnect(&mEnqueueWatcher, &QFutureWatcher<void>::finished, this, &AbstractMediaProxyModel::afterPlaylistEnqueue); 0027 }; 0028 0029 QString AbstractMediaProxyModel::filterText() const 0030 { 0031 return mFilterText; 0032 } 0033 0034 int AbstractMediaProxyModel::filterRating() const 0035 { 0036 return mFilterRating; 0037 } 0038 0039 void AbstractMediaProxyModel::setFilterText(const QString &filterText) 0040 { 0041 QWriteLocker writeLocker(&mDataLock); 0042 0043 if (mFilterText == filterText) 0044 return; 0045 0046 mFilterText = filterText; 0047 0048 mFilterExpression.setPattern(mFilterText.normalized(QString::NormalizationForm_KC)); 0049 mFilterExpression.setPatternOptions(QRegularExpression::CaseInsensitiveOption); 0050 mFilterExpression.optimize(); 0051 0052 invalidate(); 0053 0054 Q_EMIT filterTextChanged(mFilterText); 0055 } 0056 0057 void AbstractMediaProxyModel::setFilterRating(int filterRating) 0058 { 0059 QWriteLocker writeLocker(&mDataLock); 0060 0061 if (mFilterRating == filterRating) { 0062 return; 0063 } 0064 0065 mFilterRating = filterRating; 0066 0067 invalidate(); 0068 0069 Q_EMIT filterRatingChanged(filterRating); 0070 } 0071 0072 bool AbstractMediaProxyModel::sortedAscending() const 0073 { 0074 return sortOrder() ? false : true; 0075 } 0076 0077 MediaPlayListProxyModel *AbstractMediaProxyModel::playList() const 0078 { 0079 return mPlayList; 0080 } 0081 0082 void AbstractMediaProxyModel::sortModel(Qt::SortOrder order) 0083 { 0084 sort(0, order); 0085 Q_EMIT sortedAscendingChanged(); 0086 } 0087 0088 void AbstractMediaProxyModel::setPlayList(MediaPlayListProxyModel *playList) 0089 { 0090 if (mPlayList == playList) { 0091 return; 0092 } 0093 0094 disconnectPlayList(); 0095 0096 mPlayList = playList; 0097 Q_EMIT playListChanged(); 0098 0099 connectPlayList(); 0100 } 0101 0102 void AbstractMediaProxyModel::disconnectPlayList() 0103 { 0104 if (mPlayList) { 0105 disconnect(this, &AbstractMediaProxyModel::entriesToEnqueue, 0106 mPlayList, static_cast<void(MediaPlayListProxyModel::*)(const DataTypes::EntryDataList&, ElisaUtils::PlayListEnqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayListProxyModel::enqueue)); 0107 disconnect(this, &AbstractMediaProxyModel::switchToTrackUrl, 0108 mPlayList, static_cast<void(MediaPlayListProxyModel::*)(const QUrl &url, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayListProxyModel::switchToTrackUrl)); 0109 } 0110 } 0111 0112 void AbstractMediaProxyModel::connectPlayList() 0113 { 0114 if (mPlayList) { 0115 connect(this, &AbstractMediaProxyModel::entriesToEnqueue, 0116 mPlayList, static_cast<void(MediaPlayListProxyModel::*)(const DataTypes::EntryDataList&, ElisaUtils::PlayListEnqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayListProxyModel::enqueue)); 0117 connect(this, &AbstractMediaProxyModel::switchToTrackUrl, 0118 mPlayList, static_cast<void(MediaPlayListProxyModel::*)(const QUrl &url, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayListProxyModel::switchToTrackUrl)); 0119 } 0120 } 0121 0122 QFuture<void> AbstractMediaProxyModel::genericEnqueueToPlayList(const QModelIndex &rootIndex, 0123 ElisaUtils::PlayListEnqueueMode enqueueMode, 0124 ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay) 0125 { 0126 return QtConcurrent::run(&mThreadPool, [=] () { 0127 QReadLocker locker(&mDataLock); 0128 auto allData = DataTypes::EntryDataList{}; 0129 allData.reserve(rowCount()); 0130 for (int rowIndex = 0, maxRowCount = rowCount(); rowIndex < maxRowCount; ++rowIndex) { 0131 auto currentIndex = index(rowIndex, 0, rootIndex); 0132 0133 allData.push_back(DataTypes::EntryData{data(currentIndex, DataTypes::FullDataRole).value<DataTypes::MusicDataType>(), 0134 data(currentIndex, Qt::DisplayRole).toString(), {}}); 0135 } 0136 Q_EMIT entriesToEnqueue(allData, enqueueMode, triggerPlay); 0137 }); 0138 } 0139 0140 void AbstractMediaProxyModel::enqueueToPlayList(const QModelIndex &rootIndex) 0141 { 0142 genericEnqueueToPlayList(rootIndex, ElisaUtils::AppendPlayList, ElisaUtils::DoNotTriggerPlay); 0143 } 0144 0145 void AbstractMediaProxyModel::replaceAndPlayOfPlayList(const QModelIndex &rootIndex) 0146 { 0147 genericEnqueueToPlayList(rootIndex, ElisaUtils::ReplacePlayList, ElisaUtils::TriggerPlay); 0148 } 0149 0150 void AbstractMediaProxyModel::replaceAndPlayOfPlayListFromTrackUrl(const QModelIndex &rootIndex, const QUrl &switchTrackUrl) 0151 { 0152 auto future = genericEnqueueToPlayList(rootIndex, ElisaUtils::ReplacePlayList, ElisaUtils::DoNotTriggerPlay); 0153 0154 // Wait until the future is finished before switching tracks 0155 mEnqueueWatcher.setFuture(future); 0156 mEnqueueWatcherTrackUrl = switchTrackUrl; 0157 } 0158 0159 void AbstractMediaProxyModel::afterPlaylistEnqueue() 0160 { 0161 if (mEnqueueWatcherTrackUrl.isEmpty()) { 0162 return; 0163 } 0164 0165 Q_EMIT switchToTrackUrl(mEnqueueWatcherTrackUrl, ElisaUtils::TriggerPlay); 0166 0167 // Reset 0168 mEnqueueWatcherTrackUrl = QUrl(); 0169 } 0170 0171 void AbstractMediaProxyModel::enqueue(const DataTypes::MusicDataType &newEntry, const QString &newEntryTitle, ElisaUtils::PlayListEnqueueMode enqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay) 0172 { 0173 auto allData = DataTypes::EntryDataList{}; 0174 0175 allData.push_back(DataTypes::EntryData{newEntry, newEntryTitle, {}}); 0176 0177 Q_EMIT entriesToEnqueue(allData, enqueueMode, triggerPlay); 0178 } 0179 0180 0181 #include "moc_abstractmediaproxymodel.cpp"