File indexing completed on 2024-06-09 04:48:44
0001 /** 0002 * SPDX-FileCopyrightText: 2021-2023 Bart De Vries <bart@mogwai.be> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "models/queuemodel.h" 0008 #include "models/queuemodellogging.h" 0009 0010 #include <QThread> 0011 0012 #include <KFormat> 0013 0014 #include "audiomanager.h" 0015 #include "datamanager.h" 0016 #include "entry.h" 0017 #include "settingsmanager.h" 0018 0019 QueueModel::QueueModel(QObject *parent) 0020 : AbstractEpisodeModel(parent) 0021 { 0022 connect(&DataManager::instance(), &DataManager::queueEntryMoved, this, [this](int from, int to_orig) { 0023 int to = (from < to_orig) ? to_orig + 1 : to_orig; 0024 beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); 0025 endMoveRows(); 0026 qCDebug(kastsQueueModel) << "Moved entry" << from << "to" << to; 0027 }); 0028 connect(&DataManager::instance(), &DataManager::queueEntryAdded, this, [this](int pos, const QString &id) { 0029 Q_UNUSED(id) 0030 beginInsertRows(QModelIndex(), pos, pos); 0031 endInsertRows(); 0032 Q_EMIT timeLeftChanged(); 0033 qCDebug(kastsQueueModel) << "Added entry at pos" << pos; 0034 }); 0035 connect(&DataManager::instance(), &DataManager::queueEntryRemoved, this, [this](int pos, const QString &id) { 0036 Q_UNUSED(id) 0037 beginRemoveRows(QModelIndex(), pos, pos); 0038 endRemoveRows(); 0039 Q_EMIT timeLeftChanged(); 0040 qCDebug(kastsQueueModel) << "Removed entry at pos" << pos; 0041 }); 0042 connect(&DataManager::instance(), &DataManager::queueSorted, this, [this]() { 0043 beginResetModel(); 0044 endResetModel(); 0045 qCDebug(kastsQueueModel) << "Queue was sorted"; 0046 }); 0047 // Connect positionChanged to make sure that the remaining playing time in 0048 // the queue header is up-to-date 0049 connect(&AudioManager::instance(), &AudioManager::positionChanged, this, [this](qint64 position) { 0050 Q_UNUSED(position) 0051 Q_EMIT timeLeftChanged(); 0052 }); 0053 } 0054 0055 QVariant QueueModel::data(const QModelIndex &index, int role) const 0056 { 0057 switch (role) { 0058 case AbstractEpisodeModel::Roles::EntryRole: 0059 return QVariant::fromValue(DataManager::instance().getQueueEntry(index.row())); 0060 case AbstractEpisodeModel::Roles::IdRole: 0061 return QVariant::fromValue(DataManager::instance().queue()[index.row()]); 0062 default: 0063 return QVariant(); 0064 } 0065 } 0066 0067 int QueueModel::rowCount(const QModelIndex &parent) const 0068 { 0069 Q_UNUSED(parent) 0070 qCDebug(kastsQueueModel) << "queueCount is" << DataManager::instance().queueCount(); 0071 return DataManager::instance().queueCount(); 0072 } 0073 0074 int QueueModel::timeLeft() const 0075 { 0076 int result = 0; 0077 QStringList queue = DataManager::instance().queue(); 0078 for (const QString &item : queue) { 0079 Entry *entry = DataManager::instance().getEntry(item); 0080 if (entry->enclosure()) { 0081 result += entry->enclosure()->duration() * 1000 - entry->enclosure()->playPosition(); 0082 } 0083 } 0084 qCDebug(kastsQueueModel) << "timeLeft is" << result; 0085 return result; 0086 } 0087 0088 QString QueueModel::formattedTimeLeft() const 0089 { 0090 qreal rate = 1.0; 0091 if (SettingsManager::self()->adjustTimeLeft()) { 0092 rate = AudioManager::instance().playbackRate(); 0093 rate = (rate > 0.0) ? rate : 1.0; 0094 } 0095 static KFormat format; 0096 return format.formatDuration(timeLeft() / rate); 0097 } 0098 0099 QString QueueModel::getSortName(AbstractEpisodeProxyModel::SortType type) 0100 { 0101 return AbstractEpisodeProxyModel::getSortName(type); 0102 } 0103 0104 QString QueueModel::getSortIconName(AbstractEpisodeProxyModel::SortType type) 0105 { 0106 return AbstractEpisodeProxyModel::getSortIconName(type); 0107 } 0108 0109 void QueueModel::updateInternalState() 0110 { 0111 // nothing to do; DataManager already has the updated data. 0112 } 0113 0114 // Hack to get a QItemSelection in QML 0115 QItemSelection QueueModel::createSelection(int rowa, int rowb) 0116 { 0117 return QItemSelection(index(rowa, 0), index(rowb, 0)); 0118 }