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 }