File indexing completed on 2023-09-24 08:52:41
0001 /** 0002 * SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "remotesinksmodel.h" 0008 #include "interfaces_debug.h" 0009 0010 #include <QDebug> 0011 0012 #include <core/qtcompat_p.h> 0013 #include <dbushelper.h> 0014 0015 RemoteSinksModel::RemoteSinksModel(QObject *parent) 0016 : QAbstractListModel(parent) 0017 , m_dbusInterface(nullptr) 0018 { 0019 connect(this, &QAbstractItemModel::rowsInserted, this, &RemoteSinksModel::rowsChanged); 0020 connect(this, &QAbstractItemModel::rowsRemoved, this, &RemoteSinksModel::rowsChanged); 0021 0022 QDBusServiceWatcher *watcher = 0023 new QDBusServiceWatcher(DaemonDbusInterface::activatedService(), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); 0024 connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &RemoteSinksModel::refreshSinkList); 0025 connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &RemoteSinksModel::refreshSinkList); 0026 } 0027 0028 QHash<int, QByteArray> RemoteSinksModel::roleNames() const 0029 { 0030 // Role names for QML 0031 QHash<int, QByteArray> names = QAbstractItemModel::roleNames(); 0032 names.insert(NameRole, "name"); 0033 names.insert(DescriptionRole, "description"); 0034 names.insert(MaxVolumeRole, "maxVolume"); 0035 names.insert(VolumeRole, "volume"); 0036 names.insert(MutedRole, "muted"); 0037 0038 return names; 0039 } 0040 0041 RemoteSinksModel::~RemoteSinksModel() 0042 { 0043 } 0044 0045 QString RemoteSinksModel::deviceId() const 0046 { 0047 return m_deviceId; 0048 } 0049 0050 void RemoteSinksModel::setDeviceId(const QString &deviceId) 0051 { 0052 m_deviceId = deviceId; 0053 0054 if (m_dbusInterface) { 0055 delete m_dbusInterface; 0056 } 0057 0058 m_dbusInterface = new RemoteSystemVolumeDbusInterface(deviceId, this); 0059 0060 connect(m_dbusInterface, &OrgKdeKdeconnectDeviceRemotesystemvolumeInterface::sinksChanged, this, &RemoteSinksModel::refreshSinkList); 0061 0062 connect(m_dbusInterface, &OrgKdeKdeconnectDeviceRemotesystemvolumeInterface::volumeChanged, this, [this](const QString &name, int volume) { 0063 auto iter = std::find_if(m_sinkList.begin(), m_sinkList.end(), [&name](const Sink &s) { 0064 return s.name == name; 0065 }); 0066 if (iter != m_sinkList.end()) { 0067 iter->volume = volume; 0068 int i = std::distance(m_sinkList.begin(), iter); 0069 Q_EMIT dataChanged(index(i, 0), index(i, 0), {VolumeRole}); 0070 } 0071 }); 0072 0073 connect(m_dbusInterface, &OrgKdeKdeconnectDeviceRemotesystemvolumeInterface::mutedChanged, this, [this](const QString &name, bool muted) { 0074 auto iter = std::find_if(m_sinkList.begin(), m_sinkList.end(), [&name](const Sink &s) { 0075 return s.name == name; 0076 }); 0077 if (iter != m_sinkList.cend()) { 0078 iter->muted = muted; 0079 int i = std::distance(m_sinkList.begin(), iter); 0080 Q_EMIT dataChanged(index(i, 0), index(i, 0), {MutedRole}); 0081 } 0082 }); 0083 0084 refreshSinkList(); 0085 0086 Q_EMIT deviceIdChanged(deviceId); 0087 } 0088 0089 void RemoteSinksModel::refreshSinkList() 0090 { 0091 if (!m_dbusInterface) { 0092 return; 0093 } 0094 0095 if (!m_dbusInterface->isValid()) { 0096 qCWarning(KDECONNECT_INTERFACES) << "dbus interface not valid"; 0097 return; 0098 } 0099 0100 beginResetModel(); 0101 m_sinkList.clear(); 0102 0103 const auto cmds = QJsonDocument::fromJson(m_dbusInterface->sinks()).array(); 0104 for (const QJsonValue &cmd : cmds) { 0105 const QJsonObject cont = cmd.toObject(); 0106 Sink sink; 0107 sink.name = cont.value(QStringLiteral("name")).toString(); 0108 sink.description = cont.value(QStringLiteral("description")).toString(); 0109 sink.maxVolume = cont.value(QStringLiteral("maxVolume")).toInt(); 0110 sink.volume = cont.value(QStringLiteral("volume")).toInt(); 0111 sink.muted = cont.value(QStringLiteral("muted")).toBool(); 0112 m_sinkList.append(sink); 0113 } 0114 0115 endResetModel(); 0116 } 0117 0118 QVariant RemoteSinksModel::data(const QModelIndex &index, int role) const 0119 { 0120 if (!index.isValid() || index.row() < 0 || index.row() >= m_sinkList.count()) { 0121 return QVariant(); 0122 } 0123 0124 if (!m_dbusInterface || !m_dbusInterface->isValid()) { 0125 return QVariant(); 0126 } 0127 0128 const Sink &sink = m_sinkList[index.row()]; 0129 0130 switch (role) { 0131 case NameRole: 0132 return sink.name; 0133 case DescriptionRole: 0134 return sink.description; 0135 case MaxVolumeRole: 0136 return sink.maxVolume; 0137 case VolumeRole: 0138 return sink.volume; 0139 case MutedRole: 0140 return sink.muted; 0141 default: 0142 return QVariant(); 0143 } 0144 } 0145 0146 bool RemoteSinksModel::setData(const QModelIndex &index, const QVariant &value, int role) 0147 { 0148 if (!index.isValid() || index.row() < 0 || index.row() >= m_sinkList.count()) { 0149 return false; 0150 } 0151 0152 if (!m_dbusInterface || !m_dbusInterface->isValid()) { 0153 return false; 0154 } 0155 0156 const QString sinkName = m_sinkList[index.row()].name; 0157 switch (role) { 0158 case VolumeRole: 0159 m_dbusInterface->sendVolume(sinkName, value.toInt()); 0160 return true; 0161 case MutedRole: 0162 m_dbusInterface->sendMuted(sinkName, value.toBool()); 0163 return true; 0164 default: 0165 return false; 0166 } 0167 } 0168 0169 int RemoteSinksModel::rowCount(const QModelIndex &parent) const 0170 { 0171 if (parent.isValid()) { 0172 // Return size 0 if we are a child because this is not a tree 0173 return 0; 0174 } 0175 0176 return m_sinkList.count(); 0177 }