Warning, file /utilities/telly-skout/src/channelsmodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // SPDX-FileCopyrightText: 2022 Plata Hill <plata.hill@kdemail.net>
0002 // SPDX-License-Identifier: LGPL-2.1-or-later
0003 
0004 #include "channelsmodel.h"
0005 
0006 #include "channel.h"
0007 #include "database.h"
0008 #include "fetcher.h"
0009 
0010 #include <QDebug>
0011 
0012 #include <algorithm>
0013 #include <limits>
0014 
0015 ChannelsModel::ChannelsModel(QObject *parent)
0016     : QAbstractListModel(parent)
0017     , m_onlyFavorites(true) // deliberately lazy to save time if only favorites required
0018     , m_channelFactory(m_onlyFavorites)
0019 {
0020     connect(&Fetcher::instance(), &Fetcher::groupUpdated, this, [this](const GroupId &id) {
0021         Q_UNUSED(id)
0022         beginResetModel();
0023         qDeleteAll(m_channels);
0024         m_channels.clear();
0025         m_channelFactory.load();
0026         endResetModel();
0027     });
0028 
0029     connect(&Database::instance(), &Database::channelDetailsUpdated, this, [this](const ChannelId &id, bool favorite) {
0030         // with "only favorites", a row must be added/removed -> not sufficient to call only dataChanged()
0031         if (m_onlyFavorites) {
0032             beginResetModel();
0033             qDeleteAll(m_channels);
0034             m_channels.clear();
0035             m_channelFactory.update(id);
0036             endResetModel();
0037         } else {
0038             for (int i = 0; i < m_channels.length(); i++) {
0039                 if (m_channels[i]->id() == id.value()) {
0040                     m_channels[i]->setFavorite(favorite);
0041                     m_channelFactory.update(id);
0042                     Q_EMIT dataChanged(createIndex(i, 0), createIndex(i, 0));
0043                     break;
0044                 }
0045             }
0046         }
0047     });
0048 
0049     // TODO: this should not be neccessary as the favorites page is reloaded anyways
0050     // however, if it is removed, the favorites page must be opened twice before the changes take effect
0051     connect(&Database::instance(), &Database::favoritesUpdated, this, [this]() {
0052         beginResetModel();
0053         qDeleteAll(m_channels);
0054         m_channels.clear();
0055         m_channelFactory.load();
0056         endResetModel();
0057     });
0058 }
0059 
0060 ChannelsModel::~ChannelsModel()
0061 {
0062     qDeleteAll(m_channels);
0063 }
0064 
0065 bool ChannelsModel::onlyFavorites() const
0066 {
0067     return m_onlyFavorites;
0068 }
0069 
0070 void ChannelsModel::setOnlyFavorites(bool onlyFavorites)
0071 {
0072     m_onlyFavorites = onlyFavorites;
0073     m_channelFactory.setOnlyFavorites(onlyFavorites);
0074 }
0075 
0076 QHash<int, QByteArray> ChannelsModel::roleNames() const
0077 {
0078     QHash<int, QByteArray> roleNames;
0079     roleNames[0] = "channel";
0080     return roleNames;
0081 }
0082 
0083 int ChannelsModel::rowCount(const QModelIndex &parent) const
0084 {
0085     Q_UNUSED(parent)
0086     Q_ASSERT(m_channelFactory.count() <= std::numeric_limits<int>::max());
0087     return static_cast<int>(m_channelFactory.count());
0088 }
0089 
0090 QVariant ChannelsModel::data(const QModelIndex &index, int role) const
0091 {
0092     if (role != 0) {
0093         return QVariant();
0094     }
0095     if (m_channels.length() <= index.row()) {
0096         loadChannel(index.row());
0097     }
0098     return QVariant::fromValue(m_channels[index.row()]);
0099 }
0100 
0101 void ChannelsModel::loadChannel(int index) const
0102 {
0103     m_channels += m_channelFactory.create(index);
0104 }
0105 
0106 void ChannelsModel::setFavorite(const QString &channelId, bool favorite)
0107 {
0108     if (favorite) {
0109         Database::instance().addFavorite(ChannelId(channelId));
0110     } else {
0111         Database::instance().removeFavorite(ChannelId(channelId));
0112     }
0113 }
0114 
0115 void ChannelsModel::move(int from, int to)
0116 {
0117     const int destination = to > from ? to + 1 : to;
0118 
0119     beginMoveRows(QModelIndex(), from, from, QModelIndex(), destination);
0120     m_channels.move(from, to);
0121     endMoveRows();
0122 }
0123 
0124 void ChannelsModel::save()
0125 {
0126     QVector<ChannelId> channelIds(m_channels.size());
0127     std::transform(m_channels.begin(), m_channels.end(), channelIds.begin(), [](const Channel *channel) {
0128         return ChannelId(channel->id());
0129     });
0130     Database::instance().sortFavorites(channelIds);
0131 }