diff --git a/CMakeLists.txt b/CMakeLists.txt index 51662bac..e2dbb908 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,119 +1,119 @@ cmake_minimum_required(VERSION 3.0) project(kdeconnect) if (SAILFISHOS) set(KF5_MIN_VERSION "5.36.0") set(QT_MIN_VERSION "5.6.0") else() set(KF5_MIN_VERSION "5.64.0") set(QT_MIN_VERSION "5.10.0") endif() set(QCA_MIN_VERSION "2.1.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) include(KDEInstallDirs) include(KDECompilerSettings NO_POLICY_SCOPE) include(KDECMakeSettings) include(ECMAddTests) include(ECMSetupVersion) include(ECMInstallIcons) include(FeatureSummary) include(GenerateExportHeader) include(KDEConnectMacros.cmake) ecm_setup_version(1.4.0 VARIABLE_PREFIX KDECONNECT VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/kdeconnect-version.h ) if (SAILFISHOS) set(KF5_REQUIRED_COMPONENTS I18n CoreAddons Config) set(KF5_OPTIONAL_COMPONENTS) set(Qca_LIBRARY CONAN_PKG::Qca-qt5) add_definitions(-DSAILFISHOS) else() find_package(Qca-qt5 ${QCA_MIN_VERSION} REQUIRED) set(Qca_LIBRARY qca-qt5) set(KF5_REQUIRED_COMPONENTS I18n ConfigWidgets DBusAddons IconThemes Notifications KIO KCMUtils Service Kirigami2 People) set(KF5_OPTIONAL_COMPONENTS DocTools) set_package_properties(KF5Kirigami2 PROPERTIES DESCRIPTION "QtQuick plugins to build user interfaces based on KDE UX guidelines" PURPOSE "Required for KDE Connect's QML-based GUI applications" URL "https://www.kde.org/products/kirigami/" TYPE RUNTIME ) if(UNIX AND NOT APPLE) find_package(KF5PulseAudioQt) endif() find_package(KF5PeopleVCard) set_package_properties(KF5PeopleVCard PROPERTIES PURPOSE "Read vcards from the file system" URL "https://phabricator.kde.org/source/kpeoplevcard/" TYPE RUNTIME ) add_definitions(-DHAVE_KIO) endif() add_definitions(-DQT_NO_URL_CAST_FROM_STRING -DQT_NO_KEYWORDS -DQT_NO_CAST_FROM_ASCII) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS DBus Quick Network Multimedia) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS ${KF5_REQUIRED_COMPONENTS}) if (KF5_OPTIONAL_COMPONENTS) find_package(KF5 ${KF5_MIN_VERSION} COMPONENTS ${KF5_OPTIONAL_COMPONENTS}) endif() if (NOT ZSH_AUTOCOMPLETE_DIR) set(ZSH_AUTOCOMPLETE_DIR "${CMAKE_INSTALL_PREFIX}/share/zsh/site-functions") endif() option(PRIVATE_DBUS_ENABLED "Use private dbus session for kdeconnect" OFF) if(PRIVATE_DBUS_ENABLED OR APPLE) add_compile_definitions(USE_PRIVATE_DBUS) endif() add_subdirectory(core) +add_subdirectory(plugins) +add_subdirectory(interfaces) if (NOT SAILFISHOS) add_subdirectory(icon) - add_subdirectory(interfaces) add_subdirectory(data) - add_subdirectory(plugins) add_subdirectory(cli) add_subdirectory(declarativeplugin) add_subdirectory(kcm) add_subdirectory(kcmplugin) add_subdirectory(daemon) add_subdirectory(app) add_subdirectory(indicator) add_subdirectory(urlhandler) add_subdirectory(nautilus-extension) add_subdirectory(fileitemactionplugin) add_subdirectory(smsapp) if(NOT WIN32) add_subdirectory(kio) add_subdirectory(plasmoid) endif() endif() if(KF5DocTools_FOUND) add_subdirectory(doc) endif() if(BUILD_TESTING) add_subdirectory(tests) endif() feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/interfaces/CMakeLists.txt b/interfaces/CMakeLists.txt index 22adafea..6c71c7cf 100644 --- a/interfaces/CMakeLists.txt +++ b/interfaces/CMakeLists.txt @@ -1,60 +1,60 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kdeconnect-interfaces\") function(geninterface source_h output_h) set(xml_file ${CMAKE_CURRENT_BINARY_DIR}/${output_h}.xml) qt5_generate_dbus_interface( ${source_h} ${xml_file}) set_source_files_properties(${xml_file} PROPERTIES NO_NAMESPACE true) qt5_add_dbus_interface(libkdeconnect_SRC ${xml_file} ${output_h}) set(libkdeconnect_SRC ${libkdeconnect_SRC} PARENT_SCOPE) endfunction() set(libkdeconnect_SRC dbusinterfaces.cpp devicesmodel.cpp notificationsmodel.cpp devicessortproxymodel.cpp conversationmessage.cpp remotecommandsmodel.cpp remotesinksmodel.cpp devicespluginfilterproxymodel.cpp # modeltest.cpp ) -geninterface(${CMAKE_SOURCE_DIR}/core/daemon.h daemoninterface) -geninterface(${CMAKE_SOURCE_DIR}/core/device.h deviceinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/battery/batterydbusinterface.h devicebatteryinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/sftp/sftpplugin.h devicesftpinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/notifications/notificationsdbusinterface.h devicenotificationsinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/findmyphone/findmyphoneplugin.h devicefindmyphoneinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/notifications/notification.h notificationinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/mprisremote/mprisremoteplugin.h mprisremoteinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/remotecontrol/remotecontrolplugin.h remotecontrolinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/lockdevice/lockdeviceplugin.h lockdeviceinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/remotecommands/remotecommandsplugin.h remotecommandsinterface) -geninterface(${CMAKE_SOURCE_DIR}/plugins/remotekeyboard/remotekeyboardplugin.h remotekeyboardinterface) -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) +geninterface(${PROJECT_SOURCE_DIR}/core/daemon.h daemoninterface) +geninterface(${PROJECT_SOURCE_DIR}/core/device.h deviceinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/battery/batterydbusinterface.h devicebatteryinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/sftp/sftpplugin.h devicesftpinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/notifications/notificationsdbusinterface.h devicenotificationsinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/findmyphone/findmyphoneplugin.h devicefindmyphoneinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/notifications/notification.h notificationinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/mprisremote/mprisremoteplugin.h mprisremoteinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/remotecontrol/remotecontrolplugin.h remotecontrolinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/lockdevice/lockdeviceplugin.h lockdeviceinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/remotecommands/remotecommandsplugin.h remotecommandsinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/remotekeyboard/remotekeyboardplugin.h remotekeyboardinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/sms/smsplugin.h smsinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/sms/conversationsdbusinterface.h conversationsinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/share/shareplugin.h shareinterface) +geninterface(${PROJECT_SOURCE_DIR}/plugins/remotesystemvolume/remotesystemvolumeplugin.h remotesystemvolumeinterface) add_library(kdeconnectinterfaces SHARED ${libkdeconnect_SRC}) set_target_properties(kdeconnectinterfaces PROPERTIES VERSION ${KDECONNECT_VERSION} SOVERSION ${KDECONNECT_VERSION_MAJOR} ) generate_export_header(kdeconnectinterfaces EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/kdeconnectinterfaces_export.h BASE_NAME KDEConnectInterfaces) target_link_libraries(kdeconnectinterfaces LINK_PUBLIC Qt5::Gui Qt5::DBus LINK_PRIVATE KF5::ConfigCore KF5::I18n kdeconnectcore ) install(TARGETS kdeconnectinterfaces EXPORT kdeconnectLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) diff --git a/interfaces/dbusinterfaces.cpp b/interfaces/dbusinterfaces.cpp index 678ac53f..98f5b385 100644 --- a/interfaces/dbusinterfaces.cpp +++ b/interfaces/dbusinterfaces.cpp @@ -1,197 +1,201 @@ /** * Copyright 2013 Albert Vaca * * 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 . */ #include "dbusinterfaces.h" #include QString DaemonDbusInterface::activatedService() { static const QString service = QStringLiteral("org.kde.kdeconnect"); + +#ifndef SAILFISHOS auto reply = DBusHelper::sessionBus().interface()->startService(service); if (!reply.isValid()) { qWarning() << "error activating kdeconnectd:" << reply.error(); } +#endif + return service; } DaemonDbusInterface::DaemonDbusInterface(QObject* parent) : OrgKdeKdeconnectDaemonInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect"), DBusHelper::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDaemonInterface::pairingRequestsChanged, this, &DaemonDbusInterface::pairingRequestsChangedProxy); } DaemonDbusInterface::~DaemonDbusInterface() { } DeviceDbusInterface::DeviceDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") +id, DBusHelper::sessionBus(), parent) , m_id(id) { connect(this, &OrgKdeKdeconnectDeviceInterface::trustedChanged, this, &DeviceDbusInterface::trustedChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::reachableChanged, this, &DeviceDbusInterface::reachableChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::nameChanged, this, &DeviceDbusInterface::nameChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::hasPairingRequestsChanged, this, &DeviceDbusInterface::hasPairingRequestsChangedProxy); } DeviceDbusInterface::~DeviceDbusInterface() { } QString DeviceDbusInterface::id() const { return m_id; } void DeviceDbusInterface::pluginCall(const QString& plugin, const QString& method) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") +id() + QStringLiteral("/") + plugin, QStringLiteral("org.kde.kdeconnect.device.") + plugin, method); DBusHelper::sessionBus().asyncCall(msg); } DeviceBatteryDbusInterface::DeviceBatteryDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceBatteryInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") +id, DBusHelper::sessionBus(), parent) { } DeviceBatteryDbusInterface::~DeviceBatteryDbusInterface() { } DeviceNotificationsDbusInterface::DeviceNotificationsDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceNotificationsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") +id, DBusHelper::sessionBus(), parent) { } DeviceNotificationsDbusInterface::~DeviceNotificationsDbusInterface() { } NotificationDbusInterface::NotificationDbusInterface(const QString& deviceId, const QString& notificationId, QObject* parent) : OrgKdeKdeconnectDeviceNotificationsNotificationInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/notifications/") + notificationId, DBusHelper::sessionBus(), parent) , id(notificationId) { } NotificationDbusInterface::~NotificationDbusInterface() { } DeviceConversationsDbusInterface::DeviceConversationsDbusInterface(const QString& deviceId, QObject* parent) : OrgKdeKdeconnectDeviceConversationsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId, DBusHelper::sessionBus(), parent) { } DeviceConversationsDbusInterface::~DeviceConversationsDbusInterface() { } SftpDbusInterface::SftpDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceSftpInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/sftp"), DBusHelper::sessionBus(), parent) { } SftpDbusInterface::~SftpDbusInterface() { } MprisDbusInterface::MprisDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceMprisremoteInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/mprisremote"), DBusHelper::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDeviceMprisremoteInterface::propertiesChanged, this, &MprisDbusInterface::propertiesChangedProxy); } MprisDbusInterface::~MprisDbusInterface() { } RemoteControlDbusInterface::RemoteControlDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceRemotecontrolInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/remotecontrol"), DBusHelper::sessionBus(), parent) { } RemoteControlDbusInterface::~RemoteControlDbusInterface() { } LockDeviceDbusInterface::LockDeviceDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceLockdeviceInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/lockdevice"), DBusHelper::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDeviceLockdeviceInterface::lockedChanged, this, &LockDeviceDbusInterface::lockedChangedProxy); Q_ASSERT(isValid()); } LockDeviceDbusInterface::~LockDeviceDbusInterface() { } FindMyPhoneDeviceDbusInterface::FindMyPhoneDeviceDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceFindmyphoneInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/findmyphone"), DBusHelper::sessionBus(), parent) { } FindMyPhoneDeviceDbusInterface::~FindMyPhoneDeviceDbusInterface() { } RemoteCommandsDbusInterface::RemoteCommandsDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceRemotecommandsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotecommands"), DBusHelper::sessionBus(), parent) { } RemoteCommandsDbusInterface::~RemoteCommandsDbusInterface() = default; RemoteKeyboardDbusInterface::RemoteKeyboardDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceRemotekeyboardInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotekeyboard"), DBusHelper::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDeviceRemotekeyboardInterface::remoteStateChanged, this, &RemoteKeyboardDbusInterface::remoteStateChanged); } RemoteKeyboardDbusInterface::~RemoteKeyboardDbusInterface() = default; SmsDbusInterface::SmsDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceSmsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/sms"), DBusHelper::sessionBus(), parent) { } SmsDbusInterface::~SmsDbusInterface() = default; ShareDbusInterface::ShareDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceShareInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/share"), DBusHelper::sessionBus(), parent) { } ShareDbusInterface::~ShareDbusInterface() = default; RemoteSystemVolumeDbusInterface::RemoteSystemVolumeDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceRemotesystemvolumeInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotesystemvolume"), DBusHelper::sessionBus(), parent) { } diff --git a/interfaces/remotesinksmodel.cpp b/interfaces/remotesinksmodel.cpp index 4b986b31..82cd228a 100644 --- a/interfaces/remotesinksmodel.cpp +++ b/interfaces/remotesinksmodel.cpp @@ -1,175 +1,176 @@ /** * Copyright 2018 Nicolas Fella * * 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 . */ #include "remotesinksmodel.h" #include "interfaces_debug.h" #include #include #include +#include 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(), DBusHelper::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &RemoteSinksModel::refreshSinkList); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &RemoteSinksModel::refreshSinkList); } QHash RemoteSinksModel::roleNames() const { //Role names for QML QHash 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: qAsConst(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: qAsConst(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(); }