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