File indexing completed on 2024-06-02 05:18:43

0001 /*
0002    SPDX-FileCopyrightText: 2017 Volker Krause <vkrause@kde.org>
0003    SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include "config-itinerary.h"
0007 #include "kdeconnect.h"
0008 
0009 #if HAVE_DBUS
0010 #include <QDBusConnection>
0011 #include <QDBusInterface>
0012 #include <QDBusMessage>
0013 #include <QDBusReply>
0014 #endif
0015 
0016 #include <QDebug>
0017 #include <QUrl>
0018 #include <QVector>
0019 
0020 KDEConnectDeviceModel::KDEConnectDeviceModel(QObject *parent)
0021     : QAbstractListModel(parent)
0022 {
0023 
0024 }
0025 
0026 KDEConnectDeviceModel::~KDEConnectDeviceModel() = default;
0027 
0028 void KDEConnectDeviceModel::refresh()
0029 {
0030     if (!m_devices.empty()) // ### this is wrong, but the consumer code can't handle proper update yet...
0031         return;
0032 
0033 #if HAVE_DBUS
0034     beginResetModel();
0035 
0036     // TODO we might want to do all this asynchronously by watching change signals and cache the device list
0037     auto msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"),
0038                                               QStringLiteral("/modules/kdeconnect"),
0039                                               QStringLiteral("org.kde.kdeconnect.daemon"),
0040                                               QStringLiteral("devices"));
0041     msg.setArguments({true, true});
0042     QDBusPendingReply<QStringList> reply = QDBusConnection::sessionBus().asyncCall(msg);
0043     reply.waitForFinished();
0044 
0045     if (!reply.isValid()) {
0046         return;
0047     }
0048 
0049     const auto values = reply.value();
0050     for (const QString &deviceId : values) {
0051         QDBusInterface deviceIface(QStringLiteral("org.kde.kdeconnect"),
0052                                    QStringLiteral("/modules/kdeconnect/devices/") + deviceId,
0053                                    QStringLiteral("org.kde.kdeconnect.device"));
0054         QDBusReply<bool> pluginReply = deviceIface.call(QStringLiteral("hasPlugin"), QLatin1StringView("kdeconnect_share"));
0055 
0056         if (pluginReply.value()) {
0057             m_devices.push_back({deviceId, deviceIface.property("name").toString()});
0058         }
0059     }
0060     endResetModel();
0061 #endif
0062 }
0063 
0064 int KDEConnectDeviceModel::rowCount(const QModelIndex &parent) const
0065 {
0066     if (parent.isValid()) {
0067         return 0;
0068     }
0069     return m_devices.size();
0070 }
0071 
0072 QVariant KDEConnectDeviceModel::data(const QModelIndex &index, int role) const
0073 {
0074     if (!checkIndex(index)) {
0075         return {};
0076     }
0077 
0078     switch (role) {
0079         case DeviceNameRole:
0080             return m_devices[index.row()].name;
0081         case DeviceIdRole:
0082             return m_devices[index.row()].deviceId;
0083     }
0084 
0085     return {};
0086 }
0087 
0088 QHash<int, QByteArray> KDEConnectDeviceModel::roleNames() const
0089 {
0090     auto r = QAbstractListModel::roleNames();
0091     r.insert(DeviceNameRole, "name");
0092     r.insert(DeviceIdRole, "deviceId");
0093     return r;
0094 }
0095 
0096 void KDEConnect::sendToDevice(const QString &fileName, const QString &deviceId)
0097 {
0098 #if HAVE_DBUS
0099     const QString method = QStringLiteral("openFile");
0100 
0101     QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"),
0102                                                       QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/share"),
0103                                                       QStringLiteral("org.kde.kdeconnect.device.share"),
0104                                                       method);
0105     msg.setArguments({QUrl::fromLocalFile(fileName).toString()});
0106 
0107     QDBusConnection::sessionBus().asyncCall(msg);
0108 #endif
0109 }
0110 
0111 #include "moc_kdeconnect.cpp"