[app] Add system volume control
Summary: Add a remote systemvolume plugin. Test Plan: Change volume via slider -> Volume on target changes Change volume on target -> Slider changes Mute via button -> Mute on target changes Mute on target -> Button changes icon Add/remove sink on host -> Sink is add/removed in list Reviewers: #kde_connect, apol Reviewed By: #kde_connect, apol Subscribers: apol, kdeconnect Tags: #kde_connect Differential Revision: https://phabricator.kde.org/D16667
This commit is contained in:
parent
061d415f83
commit
2f76d2143f
14 changed files with 562 additions and 2 deletions
|
@ -114,6 +114,12 @@ Kirigami.Page
|
|||
shareIface.shareUrl(fileDialog.fileUrl)
|
||||
}
|
||||
}
|
||||
PluginItem {
|
||||
label: i18n("Volume control")
|
||||
interfaceFactory: RemoteSystemVolumeDbusInterfaceFactory
|
||||
component: "qrc:/qml/volume.qml"
|
||||
pluginName: "remotesystemvolume"
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true }
|
||||
}
|
||||
|
|
68
app/qml/volume.qml
Normal file
68
app/qml/volume.qml
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import org.kde.kirigami 2.0 as Kirigami
|
||||
import org.kde.kdeconnect 1.0
|
||||
|
||||
Kirigami.Page
|
||||
{
|
||||
id: root
|
||||
title: i18n("Volume control")
|
||||
property QtObject pluginInterface
|
||||
|
||||
ListView {
|
||||
id: sinkList
|
||||
anchors.fill: parent
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
model: RemoteSinksModel {
|
||||
deviceId: pluginInterface.deviceId
|
||||
}
|
||||
delegate: ColumnLayout {
|
||||
|
||||
width: parent.width
|
||||
|
||||
Label {
|
||||
text: description
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
||||
Button {
|
||||
icon.name: muted ? "player-volume-muted" : "player-volume"
|
||||
onClicked: pluginInterface.sendMuted(name, !muted)
|
||||
}
|
||||
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
value: volume
|
||||
to: maxVolume
|
||||
onMoved: pluginInterface.sendVolume(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,5 +9,6 @@
|
|||
<file>qml/DevicePage.qml</file>
|
||||
<file>qml/FindDevicesPage.qml</file>
|
||||
<file>qml/runcommand.qml</file>
|
||||
<file>qml/volume.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "interfaces/devicesmodel.h"
|
||||
#include "interfaces/notificationsmodel.h"
|
||||
#include <remotecommandsmodel.h>
|
||||
#include <remotesinksmodel.h>
|
||||
|
||||
QObject* createDeviceDbusInterface(const QVariant& deviceId)
|
||||
{
|
||||
|
@ -95,6 +96,12 @@ QObject* createShareInterface(const QVariant& deviceId)
|
|||
return new ShareDbusInterface(deviceId.toString());
|
||||
}
|
||||
|
||||
QObject* createRemoteSystemVolumeInterface(const QVariant& deviceId)
|
||||
{
|
||||
return new RemoteSystemVolumeDbusInterface(deviceId.toString());
|
||||
}
|
||||
|
||||
|
||||
void KdeConnectDeclarativePlugin::registerTypes(const char* uri)
|
||||
{
|
||||
qmlRegisterType<DevicesModel>(uri, 1, 0, "DevicesModel");
|
||||
|
@ -102,13 +109,15 @@ void KdeConnectDeclarativePlugin::registerTypes(const char* uri)
|
|||
qmlRegisterType<RemoteCommandsModel>(uri, 1, 0, "RemoteCommandsModel");
|
||||
qmlRegisterType<DBusAsyncResponse>(uri, 1, 0, "DBusAsyncResponse");
|
||||
qmlRegisterType<DevicesSortProxyModel>(uri, 1, 0, "DevicesSortProxyModel");
|
||||
qmlRegisterType<RemoteSinksModel>(uri, 1, 0, "RemoteSinksModel");
|
||||
qmlRegisterUncreatableType<MprisDbusInterface>(uri, 1, 0, "MprisDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<LockDeviceDbusInterface>(uri, 1, 0, "LockDeviceDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<FindMyPhoneDeviceDbusInterface>(uri, 1, 0, "FindMyPhoneDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<RemoteKeyboardDbusInterface>(uri, 1, 0, "RemoteKeyboardDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<DeviceDbusInterface>(uri, 1, 0, "DeviceDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<DeviceDbusInterface>(uri, 1, 0, "RemoteCommandsDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<DeviceDbusInterface>(uri, 1, 0, "ShareDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<RemoteCommandsDbusInterface>(uri, 1, 0, "RemoteCommandsDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<RemoteSystemVolumeDbusInterface>(uri, 1, 0, "RemoteSystemVolumeInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterUncreatableType<ShareDbusInterface>(uri, 1, 0, "ShareDbusInterface", QStringLiteral("You're not supposed to instantiate interfaces"));
|
||||
qmlRegisterSingletonType<DaemonDbusInterface>(uri, 1, 0, "DaemonDbusInterface",
|
||||
[](QQmlEngine*, QJSEngine*) -> QObject* {
|
||||
return new DaemonDbusInterface;
|
||||
|
@ -158,4 +167,8 @@ void KdeConnectDeclarativePlugin::initializeEngine(QQmlEngine* engine, const cha
|
|||
|
||||
engine->rootContext()->setContextProperty(QStringLiteral("ShareDbusInterfaceFactory")
|
||||
, new ObjectFactory(engine, createShareInterface));
|
||||
|
||||
engine->rootContext()->setContextProperty(QStringLiteral("RemoteSystemVolumeDbusInterfaceFactory")
|
||||
, new ObjectFactory(engine, createRemoteSystemVolumeInterface));
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ set(libkdeconnect_SRC
|
|||
devicessortproxymodel.cpp
|
||||
conversationmessage.cpp
|
||||
remotecommandsmodel.cpp
|
||||
remotesinksmodel.cpp
|
||||
# modeltest.cpp
|
||||
)
|
||||
|
||||
|
@ -51,6 +52,8 @@ geninterface(${CMAKE_SOURCE_DIR}/plugins/remotekeyboard/remotekeyboardplugin.h r
|
|||
geninterface(${CMAKE_SOURCE_DIR}/plugins/sms/smsplugin.h smsinterface)
|
||||
geninterface(${CMAKE_SOURCE_DIR}/plugins/sms/conversationsdbusinterface.h conversationsinterface)
|
||||
geninterface(${CMAKE_SOURCE_DIR}/plugins/share/shareplugin.h shareinterface)
|
||||
geninterface(${CMAKE_SOURCE_DIR}/plugins/remotesystemvolume/remotesystemvolumeplugin.h remotesystemvolumeinterface)
|
||||
|
||||
|
||||
|
||||
add_library(kdeconnectinterfaces SHARED ${libkdeconnect_SRC})
|
||||
|
|
|
@ -189,3 +189,8 @@ ShareDbusInterface::ShareDbusInterface(const QString& deviceId, QObject* parent)
|
|||
}
|
||||
|
||||
ShareDbusInterface::~ShareDbusInterface() = default;
|
||||
|
||||
RemoteSystemVolumeDbusInterface::RemoteSystemVolumeDbusInterface(const QString& deviceId, QObject* parent):
|
||||
OrgKdeKdeconnectDeviceRemotesystemvolumeInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + deviceId + "/remotesystemvolume", QDBusConnection::sessionBus(), parent)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "interfaces/smsinterface.h"
|
||||
#include "interfaces/conversationsinterface.h"
|
||||
#include "interfaces/shareinterface.h"
|
||||
#include "interfaces/remotesystemvolumeinterface.h"
|
||||
|
||||
/**
|
||||
* Using these "proxy" classes just in case we need to rename the
|
||||
|
@ -229,6 +230,15 @@ public:
|
|||
~ShareDbusInterface() override;
|
||||
};
|
||||
|
||||
class KDECONNECTINTERFACES_EXPORT RemoteSystemVolumeDbusInterface
|
||||
: public OrgKdeKdeconnectDeviceRemotesystemvolumeInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RemoteSystemVolumeDbusInterface(const QString& deviceId, QObject* parent = nullptr);
|
||||
~RemoteSystemVolumeDbusInterface() = default;
|
||||
};
|
||||
|
||||
template <typename T, typename W>
|
||||
static void setWhenAvailable(const QDBusPendingReply<T>& pending, W func, QObject* parent)
|
||||
{
|
||||
|
|
173
interfaces/remotesinksmodel.cpp
Normal file
173
interfaces/remotesinksmodel.cpp
Normal file
|
@ -0,0 +1,173 @@
|
|||
/**
|
||||
* Copyright 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "remotesinksmodel.h"
|
||||
#include "interfaces_debug.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDBusInterface>
|
||||
|
||||
RemoteSinksModel::RemoteSinksModel(QObject* parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_dbusInterface(nullptr)
|
||||
{
|
||||
|
||||
connect(this, &QAbstractItemModel::rowsInserted,
|
||||
this, &RemoteSinksModel::rowsChanged);
|
||||
connect(this, &QAbstractItemModel::rowsRemoved,
|
||||
this, &RemoteSinksModel::rowsChanged);
|
||||
|
||||
QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(),
|
||||
QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
|
||||
connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &RemoteSinksModel::refreshSinkList);
|
||||
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &RemoteSinksModel::refreshSinkList);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> RemoteSinksModel::roleNames() const
|
||||
{
|
||||
//Role names for QML
|
||||
QHash<int, QByteArray> names = QAbstractItemModel::roleNames();
|
||||
names.insert(NameRole, "name");
|
||||
names.insert(DescriptionRole, "description");
|
||||
names.insert(MaxVolumeRole, "maxVolume");
|
||||
names.insert(VolumeRole, "volume");
|
||||
names.insert(MutedRole, "muted");
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
RemoteSinksModel::~RemoteSinksModel()
|
||||
{
|
||||
}
|
||||
|
||||
QString RemoteSinksModel::deviceId() const
|
||||
{
|
||||
return m_deviceId;
|
||||
}
|
||||
|
||||
void RemoteSinksModel::setDeviceId(const QString& deviceId)
|
||||
{
|
||||
m_deviceId = deviceId;
|
||||
|
||||
if (m_dbusInterface) {
|
||||
delete m_dbusInterface;
|
||||
}
|
||||
|
||||
m_dbusInterface = new RemoteSystemVolumeDbusInterface(deviceId, this);
|
||||
|
||||
connect(m_dbusInterface, &OrgKdeKdeconnectDeviceRemotesystemvolumeInterface::sinksChanged,
|
||||
this, &RemoteSinksModel::refreshSinkList);
|
||||
|
||||
connect(m_dbusInterface, &OrgKdeKdeconnectDeviceRemotesystemvolumeInterface::volumeChanged, this, [this](const QString& name, int volume) {
|
||||
for (Sink* s: m_sinkList) {
|
||||
if (s->name == name) {
|
||||
s->volume = volume;
|
||||
Q_EMIT dataChanged(index(0,0), index(m_sinkList.size() - 1, 0));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_dbusInterface, &OrgKdeKdeconnectDeviceRemotesystemvolumeInterface::mutedChanged, this, [this](const QString& name, bool muted) {
|
||||
for (Sink* s: m_sinkList) {
|
||||
if (s->name == name) {
|
||||
s->muted = muted;
|
||||
Q_EMIT dataChanged(index(0,0), index(m_sinkList.size() - 1, 0));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
refreshSinkList();
|
||||
|
||||
Q_EMIT deviceIdChanged(deviceId);
|
||||
}
|
||||
|
||||
void RemoteSinksModel::refreshSinkList()
|
||||
{
|
||||
if (!m_dbusInterface) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_dbusInterface->isValid()) {
|
||||
qCWarning(KDECONNECT_INTERFACES) << "dbus interface not valid";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cmds = QJsonDocument::fromJson(m_dbusInterface->sinks()).array();
|
||||
|
||||
beginResetModel();
|
||||
|
||||
qDeleteAll(m_sinkList);
|
||||
m_sinkList.clear();
|
||||
|
||||
for (auto it = cmds.constBegin(), itEnd = cmds.constEnd(); it!=itEnd; ++it) {
|
||||
const QJsonObject cont = it->toObject();
|
||||
Sink* sink = new Sink();
|
||||
sink->name = cont.value(QStringLiteral("name")).toString();
|
||||
sink->description = cont.value(QStringLiteral("description")).toString();
|
||||
sink->maxVolume = cont.value(QStringLiteral("maxVolume")).toInt();
|
||||
sink->volume = cont.value(QStringLiteral("volume")).toInt();
|
||||
sink->muted = cont.value(QStringLiteral("muted")).toBool();
|
||||
|
||||
m_sinkList.append(sink);
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QVariant RemoteSinksModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid()
|
||||
|| index.row() < 0
|
||||
|| index.row() >= m_sinkList.count())
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (!m_dbusInterface || !m_dbusInterface->isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Sink* sink = m_sinkList[index.row()];
|
||||
|
||||
switch (role) {
|
||||
case NameRole:
|
||||
return sink->name;
|
||||
case DescriptionRole:
|
||||
return sink->description;
|
||||
case MaxVolumeRole:
|
||||
return sink->maxVolume;
|
||||
case VolumeRole:
|
||||
return sink->volume;
|
||||
case MutedRole:
|
||||
return sink->muted;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
int RemoteSinksModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
//Return size 0 if we are a child because this is not a tree
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_sinkList.count();
|
||||
}
|
75
interfaces/remotesinksmodel.h
Normal file
75
interfaces/remotesinksmodel.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Copyright 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REMOTESINKSMODEL_H
|
||||
#define REMOTESINKSMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "interfaces/dbusinterfaces.h"
|
||||
|
||||
struct Sink {
|
||||
QString name;
|
||||
QString description;
|
||||
int maxVolume;
|
||||
int volume;
|
||||
bool muted;
|
||||
};
|
||||
|
||||
class KDECONNECTINTERFACES_EXPORT RemoteSinksModel
|
||||
: public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
|
||||
|
||||
public:
|
||||
enum ModelRoles {
|
||||
NameRole,
|
||||
DescriptionRole,
|
||||
MaxVolumeRole,
|
||||
VolumeRole,
|
||||
MutedRole
|
||||
};
|
||||
|
||||
explicit RemoteSinksModel(QObject* parent = nullptr);
|
||||
~RemoteSinksModel() override;
|
||||
|
||||
QString deviceId() const;
|
||||
void setDeviceId(const QString& deviceId);
|
||||
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void refreshSinkList();
|
||||
|
||||
Q_SIGNALS:
|
||||
void deviceIdChanged(const QString& value);
|
||||
void rowsChanged();
|
||||
|
||||
private:
|
||||
RemoteSystemVolumeDbusInterface* m_dbusInterface;
|
||||
QVector<Sink*> m_sinkList;
|
||||
QString m_deviceId;
|
||||
};
|
||||
|
||||
#endif // DEVICESMODEL_H
|
|
@ -37,6 +37,7 @@ if(SAILFISHOS OR EXPERIMENTALAPP_ENABLED)
|
|||
add_subdirectory(mprisremote)
|
||||
add_subdirectory(remotecontrol)
|
||||
add_subdirectory(lockdevice)
|
||||
add_subdirectory(remotesystemvolume)
|
||||
endif()
|
||||
|
||||
if(KF5PulseAudioQt_FOUND)
|
||||
|
|
11
plugins/remotesystemvolume/CMakeLists.txt
Normal file
11
plugins/remotesystemvolume/CMakeLists.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
set(kdeconnect_remotesystemvolume_SRCS
|
||||
remotesystemvolumeplugin.cpp
|
||||
)
|
||||
|
||||
kdeconnect_add_plugin(kdeconnect_remotesystemvolume JSON kdeconnect_remotesystemvolume.json SOURCES ${kdeconnect_remotesystemvolume_SRCS})
|
||||
|
||||
target_link_libraries(kdeconnect_remotesystemvolume
|
||||
kdeconnectcore
|
||||
Qt5::DBus
|
||||
KF5::I18n
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"KPlugin": {
|
||||
"Authors": [
|
||||
{
|
||||
"Email": "nicolas.fella@gmx.de",
|
||||
"Name": "Nicolas Fella"
|
||||
}
|
||||
],
|
||||
"Description": "Control the volume of the connected device",
|
||||
"EnabledByDefault": true,
|
||||
"Icon": "player-volume",
|
||||
"Id": "kdeconnect_remotesystemvolume",
|
||||
"License": "GPL",
|
||||
"Name": "Remote system volume",
|
||||
"ServiceTypes": [
|
||||
"KdeConnect/Plugin"
|
||||
],
|
||||
"Version": "0.1",
|
||||
"Website": "https://nicolasfella.wordpress.com"
|
||||
},
|
||||
"X-KdeConnect-OutgoingPacketType": [
|
||||
"kdeconnect.systemvolume.request"
|
||||
],
|
||||
"X-KdeConnect-SupportedPacketType": [
|
||||
"kdeconnect.systemvolume"
|
||||
]
|
||||
}
|
105
plugins/remotesystemvolume/remotesystemvolumeplugin.cpp
Normal file
105
plugins/remotesystemvolume/remotesystemvolumeplugin.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* Copyright 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "remotesystemvolumeplugin.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginFactory>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDBusConnection>
|
||||
#include <QLoggingCategory>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <core/device.h>
|
||||
#include <core/daemon.h>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_remotesystemvolume.json", registerPlugin< RemoteSystemVolumePlugin >(); )
|
||||
|
||||
Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_PING, "kdeconnect.plugin.remotesystemvolume")
|
||||
|
||||
RemoteSystemVolumePlugin::RemoteSystemVolumePlugin(QObject* parent, const QVariantList& args)
|
||||
: KdeConnectPlugin(parent, args)
|
||||
{
|
||||
}
|
||||
|
||||
RemoteSystemVolumePlugin::~RemoteSystemVolumePlugin()
|
||||
{
|
||||
}
|
||||
|
||||
bool RemoteSystemVolumePlugin::receivePacket(const NetworkPacket& np)
|
||||
{
|
||||
|
||||
if (np.has(QStringLiteral("sinkList"))) {
|
||||
QJsonDocument document(np.get<QJsonArray>(QStringLiteral("sinkList")));
|
||||
m_sinks = document.toJson();
|
||||
Q_EMIT sinksChanged();
|
||||
} else {
|
||||
|
||||
QString name = np.get<QString>(QStringLiteral("name"));
|
||||
|
||||
if (np.has(QStringLiteral("volume"))) {
|
||||
Q_EMIT volumeChanged(name, np.get<int>(QStringLiteral("volume")));
|
||||
}
|
||||
|
||||
if (np.has(QStringLiteral("muted"))) {
|
||||
Q_EMIT mutedChanged(name, np.get<int>(QStringLiteral("muted")));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteSystemVolumePlugin::sendVolume(const QString& name, int volume)
|
||||
{
|
||||
NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME_REQUEST);
|
||||
np.set<QString>(QStringLiteral("name"), name);
|
||||
np.set<int>(QStringLiteral("volume"), volume);
|
||||
sendPacket(np);
|
||||
}
|
||||
|
||||
void RemoteSystemVolumePlugin::sendMuted(const QString& name, bool muted)
|
||||
{
|
||||
NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME_REQUEST);
|
||||
np.set<QString>(QStringLiteral("name"), name);
|
||||
np.set<bool>(QStringLiteral("muted"), muted);
|
||||
sendPacket(np);
|
||||
}
|
||||
|
||||
void RemoteSystemVolumePlugin::connected()
|
||||
{
|
||||
NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME_REQUEST);
|
||||
np.set<bool>(QStringLiteral("requestSinks"), true);
|
||||
sendPacket(np);
|
||||
}
|
||||
|
||||
QByteArray RemoteSystemVolumePlugin::sinks()
|
||||
{
|
||||
return m_sinks;
|
||||
}
|
||||
|
||||
QString RemoteSystemVolumePlugin::dbusPath() const
|
||||
{
|
||||
return "/modules/kdeconnect/devices/" + device()->id() + "/remotesystemvolume";
|
||||
}
|
||||
|
||||
#include "remotesystemvolumeplugin.moc"
|
||||
|
62
plugins/remotesystemvolume/remotesystemvolumeplugin.h
Normal file
62
plugins/remotesystemvolume/remotesystemvolumeplugin.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REMOTESYSTEMVOLUMEPLUGIN_H
|
||||
#define REMOTESYSTEMVOLUMEPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <core/kdeconnectplugin.h>
|
||||
|
||||
#define PACKET_TYPE_SYSTEMVOLUME QStringLiteral("kdeconnect.systemvolume")
|
||||
#define PACKET_TYPE_SYSTEMVOLUME_REQUEST QStringLiteral("kdeconnect.systemvolume.request")
|
||||
|
||||
class Q_DECL_EXPORT RemoteSystemVolumePlugin
|
||||
: public KdeConnectPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.remotesystemvolume")
|
||||
Q_PROPERTY(QByteArray sinks READ sinks NOTIFY sinksChanged)
|
||||
Q_PROPERTY(QString deviceId READ deviceId CONSTANT)
|
||||
|
||||
public:
|
||||
explicit RemoteSystemVolumePlugin(QObject* parent, const QVariantList& args);
|
||||
~RemoteSystemVolumePlugin() override;
|
||||
|
||||
bool receivePacket(const NetworkPacket& np) override;
|
||||
void connected() override;
|
||||
QString dbusPath() const override;
|
||||
|
||||
QString deviceId() const { return device()->id(); }
|
||||
QByteArray sinks();
|
||||
|
||||
Q_SCRIPTABLE void sendVolume(const QString& name, int volume);
|
||||
Q_SCRIPTABLE void sendMuted(const QString& name, bool muted);
|
||||
|
||||
Q_SIGNALS:
|
||||
Q_SCRIPTABLE void sinksChanged();
|
||||
Q_SCRIPTABLE void volumeChanged(const QString& name, int volume);
|
||||
Q_SCRIPTABLE void mutedChanged(const QString& name, bool muted);
|
||||
|
||||
private:
|
||||
QByteArray m_sinks;
|
||||
};
|
||||
|
||||
#endif // REMOTESYSTEMVOLUMEPLUGIN_H
|
Loading…
Reference in a new issue