[OpenDocString] kdeconnect-kde (cpp)
systemvolumeplugin-pulse.cpp
SystemvolumePlugin::SystemvolumePlugin(QObject *parent, const QVariantList &args)
    : KdeConnectPlugin(parent, args)
    , sinksMap()
{
}
Constructs a plugin object and assigns its data to its internal list of sinks.
bool SystemvolumePlugin::receivePacket(const NetworkPacket &np)
{
    if (!PulseAudioQt::Context::instance()->isValid())
        return false;

    if (np.has(QStringLiteral("requestSinks"))) {
        sendSinkList();
    } else {
        QString name = np.get(QStringLiteral("name"));

        PulseAudioQt::Sink *sink = sinksMap.value(name);
        if (sink) {
            if (np.has(QStringLiteral("volume"))) {
                int volume = np.get(QStringLiteral("volume"));
                sink->setVolume(volume);
                sink->setMuted(false);
            }
            if (np.has(QStringLiteral("muted"))) {
                sink->setMuted(np.get(QStringLiteral("muted")));
            }
            if (np.has(QStringLiteral("enabled"))) {
                sink->setDefault(np.get(QStringLiteral("enabled")));
            }
        }
    }
    return true;
}
This sends a network packet to all sinks.
void SystemvolumePlugin::sendSinkList()
{
    QJsonDocument document;
    QJsonArray array;

    sinksMap.clear();

    const auto sinks = PulseAudioQt::Context::instance()->sinks();
    for (PulseAudioQt::Sink *sink : sinks) {
        sinksMap.insert(sink->name(), sink);

        connect(sink, &PulseAudioQt::Sink::volumeChanged, this, [this, sink] {
            NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME);
            np.set(QStringLiteral("volume"), sink->volume());
            np.set(QStringLiteral("name"), sink->name());
            sendPacket(np);
        });

        connect(sink, &PulseAudioQt::Sink::mutedChanged, this, [this, sink] {
            NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME);
            np.set(QStringLiteral("muted"), sink->isMuted());
            np.set(QStringLiteral("name"), sink->name());
            sendPacket(np);
        });

        connect(sink, &PulseAudioQt::Sink::defaultChanged, this, [this, sink] {
            NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME);
            np.set(QStringLiteral("enabled"), sink->isDefault());
            np.set(QStringLiteral("name"), sink->name());
            sendPacket(np);
        });

        QJsonObject sinkObject{{QStringLiteral("name"), sink->name()},
                               {QStringLiteral("muted"), sink->isMuted()},
                               {QStringLiteral("description"), sink->description()},
                               {QStringLiteral("volume"), sink->volume()},
                               {QStringLiteral("maxVolume"), PulseAudioQt::normalVolume()},
                               {QStringLiteral("enabled"), sink->isDefault()}};

        array.append(sinkObject);
    }

    document.setArray(array);

    NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME);
    np.set(QStringLiteral("sinkList"), document);
    sendPacket(np);
}
This sends a list of sinks to all sinks.
void SystemvolumePlugin::connected()
{
    connect(PulseAudioQt::Context::instance(), &PulseAudioQt::Context::sinkAdded, this, [this] {
        sendSinkList();
    });

    connect(PulseAudioQt::Context::instance(), &PulseAudioQt::Context::sinkRemoved, this, [this] {
        sendSinkList();
    });

    const auto sinks = PulseAudioQt::Context::instance()->sinks();
    for (PulseAudioQt::Sink *sink : sinks) {
        sinksMap.insert(sink->name(), sink);
    }
}
This sets up the connections to the sinks of the system volume. It sets up signal'sinkAdded', and signal'sinkRemoved'.