File indexing completed on 2025-02-23 04:35:14
0001 // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com> 0002 // SPDX-License-Identifier: GPL-3.0-or-later 0003 0004 #include "sourcemanager.h" 0005 0006 #include <KSharedConfig> 0007 0008 SourceManager::SourceManager(QObject *parent) 0009 : QAbstractListModel(parent) 0010 { 0011 } 0012 0013 void SourceManager::load() 0014 { 0015 auto config = KSharedConfig::openStateConfig(); 0016 for (const auto &id : config->groupList()) { 0017 if (id.contains(QLatin1String("source-"))) { 0018 const QString uuid = QString(id).remove(QLatin1String("source-")); 0019 qInfo() << "Loading source" << uuid; 0020 0021 auto source = new VideoSource(uuid, this); 0022 insertSource(source); 0023 } 0024 } 0025 0026 // TODO: save last used source 0027 if (!m_sources.isEmpty()) { 0028 selectSource(m_sources[0]); 0029 } 0030 } 0031 0032 int SourceManager::rowCount(const QModelIndex &index) const 0033 { 0034 Q_UNUSED(index) 0035 return static_cast<int>(m_sources.size()); 0036 } 0037 0038 QVariant SourceManager::data(const QModelIndex &index, int role) const 0039 { 0040 if (!checkIndex(index)) { 0041 return {}; 0042 } 0043 0044 const int row = index.row(); 0045 if (role == SourceRole) { 0046 return QVariant::fromValue(m_sources[row]); 0047 } 0048 0049 return {}; 0050 } 0051 0052 QHash<int, QByteArray> SourceManager::roleNames() const 0053 { 0054 return {{SourceRole, QByteArrayLiteral("source")}}; 0055 } 0056 0057 void SourceManager::selectSource(VideoSource *source) 0058 { 0059 if (!m_sources.contains(source)) { 0060 qDebug() << "WTF: attempt to select unmanaged source" << source; 0061 return; 0062 } 0063 0064 m_selectedSource = source; 0065 0066 Q_EMIT sourceSelected(); 0067 } 0068 0069 VideoSource *SourceManager::selectedSource() const 0070 { 0071 return m_selectedSource; 0072 } 0073 0074 int SourceManager::selectedIndex() const 0075 { 0076 if (m_selectedSource != nullptr) { 0077 return m_sources.indexOf(m_selectedSource); 0078 } else { 0079 return -1; 0080 } 0081 } 0082 0083 bool SourceManager::canRemove() const 0084 { 0085 return m_sources.size() != 1; 0086 } 0087 0088 void SourceManager::removeSource(VideoSource *source) 0089 { 0090 source->logOut(); 0091 0092 auto config = KSharedConfig::openStateConfig(); 0093 config->deleteGroup(QStringLiteral("source-%1").arg(source->uuid())); 0094 config->sync(); 0095 0096 const int row = static_cast<int>(m_sources.indexOf(source)); 0097 beginRemoveRows(QModelIndex(), row, row); 0098 m_sources.removeAll(source); 0099 endRemoveRows(); 0100 } 0101 0102 bool SourceManager::hasAnySources() const 0103 { 0104 return !m_sources.isEmpty(); 0105 } 0106 0107 bool SourceManager::hasFinishedLoading() const 0108 { 0109 return m_finishedLoading; 0110 } 0111 0112 void SourceManager::createInvidiousSource(const QString &url) 0113 { 0114 auto source = new VideoSource(QUuid::createUuid().toString(), this); 0115 source->setType(VideoSource::Type::Invidious); 0116 source->setUrl(url); 0117 0118 insertSource(source); 0119 } 0120 0121 void SourceManager::createPeerTubeSource(const QString &url) 0122 { 0123 auto source = new VideoSource(QUuid::createUuid().toString(), this); 0124 source->setType(VideoSource::Type::PeerTube); 0125 source->setUrl(url); 0126 0127 insertSource(source); 0128 } 0129 0130 void SourceManager::createPipedSource(const QString &url) 0131 { 0132 auto source = new VideoSource(QUuid::createUuid().toString(), this); 0133 source->setType(VideoSource::Type::Piped); 0134 source->setUrl(url); 0135 0136 insertSource(source); 0137 } 0138 0139 void SourceManager::insertSource(VideoSource *pSource) 0140 { 0141 const int index = m_finishedSources.size(); 0142 0143 beginInsertRows(QModelIndex(), static_cast<int>(m_sources.size()), static_cast<int>(m_sources.size())); 0144 m_sources.append(pSource); 0145 m_finishedSources.append(false); 0146 endInsertRows(); 0147 Q_EMIT sourcesChanged(); 0148 0149 if (pSource->hasFinishedLoading()) { 0150 m_finishedSources[index] = true; 0151 checkIfFinishedLoading(); 0152 } else { 0153 connect(pSource, &VideoSource::finishedLoading, this, [this, index] { 0154 m_finishedSources[index] = true; 0155 checkIfFinishedLoading(); 0156 }); 0157 } 0158 0159 if (m_selectedSource == nullptr) { 0160 selectSource(pSource); 0161 } 0162 } 0163 0164 void SourceManager::checkIfFinishedLoading() 0165 { 0166 const bool didFinish = std::all_of(m_finishedSources.cbegin(), m_finishedSources.cend(), [](bool b) { 0167 return b; 0168 }); 0169 0170 if (didFinish != m_finishedLoading) { 0171 m_finishedLoading = didFinish; 0172 Q_EMIT finishedLoading(); 0173 } 0174 } 0175 0176 #include "moc_sourcemanager.cpp"