[SCM] kdeconnect packaging branch, master, updated. debian/0.9g-1-1183-g9d69498

Maximiliano Curia maxy at moszumanska.debian.org
Fri Oct 14 14:26:43 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/kdeconnect.git;a=commitdiff;h=88fab1f

The following commit has been merged in the master branch:
commit 88fab1f333cdc352014eb544a9a770f2183e1b4e
Author: Albert Vaca <albertvaka at gmail.com>
Date:   Tue Aug 13 05:07:32 2013 +0200

    Plugins are now owned by devices and not by daemon
    
    Plugins can no longer emit networkpackages for *every* device.
    Plugins are stored in device, wich selectively loads them.
    A Device is needed in order to instantiate a Plugin (via PluginLoader)
    PluginLoader is a singleton, because every instance of Device need it.
    Added KPluginSelector in the KCM to select the plugins to load.
    Added architecture explanation to README
    
    Only PingPlugin is working by now.
---
 README                                       |  42 ++++++++-
 daemon/daemon.cpp                            |  32 +------
 daemon/daemon.h                              |   9 +-
 daemon/device.cpp                            |  52 ++++++++++-
 daemon/device.h                              |  16 ++--
 daemon/plugins/CMakeLists.txt                |   3 +
 daemon/plugins/packageinterface.cpp          |  13 ++-
 daemon/plugins/packageinterface.h            |  12 ++-
 daemon/plugins/ping/kdeconnect_ping.desktop  |   5 -
 daemon/plugins/ping/pingpackageinterface.cpp |  13 +--
 daemon/plugins/ping/pingpackageinterface.h   |   7 +-
 daemon/plugins/pluginloader.cpp              |  67 ++++++++------
 daemon/plugins/pluginloader.h                |  24 +++--
 kcm/CMakeLists.txt                           |   2 +-
 kcm/devicesmodel.cpp                         |   1 -
 kcm/kcm.cpp                                  |  61 +++++++++++--
 kcm/kcm.h                                    |  12 ++-
 kcm/kcm.ui                                   | 132 ++++++++++++++++-----------
 18 files changed, 326 insertions(+), 177 deletions(-)

diff --git a/README b/README
index 7af405a..1c6445f 100644
--- a/README
+++ b/README
@@ -1,8 +1,41 @@
-The kdeconnect protocol:
+Class diagram
+==============
+
+   Backend_1  ...  Backend_N
+           \   |  /
+            Daemon
+           /   |  \
+     Device_1  ...  Device_N
+                   /         \
+                   |-Plugin_1 |-DeviceLink_1
+                   |-Plugin_2 |-DeviceLink_2
+                   |- ...     |-...
+                   |-Plugin_N |-DeviceLink_N
+
+
+Daemon instantiates Backends
+
+Backends manage to create DeviceLinks with the devices they can reach, and Q_EMIT them to Daemon.
+
+When Daemon receives a DeviceLink from a backend it:
+    - If he already knows the Device, adds the DeviceLink to the Device
+    - If not, it creates a new Device.
+
+Devices contain a list of DeviceLinks, plus a list of Plugins (instantiated automatically)
+
+Information for and from Plugins is encapsulated in NetworkPackages.
+
+When a DeviceLink receives a NetworkPackage from the device in the other end, Device will notify all the plugins.
+
+When a Plugin wants to send a NetworkPackage, it does so using the pointer to Device
+
+
+
+The NetworkPackage format
+=========================
 
-Communication between heterogenous devices is achieved using NetworkPackages.
 NetworkPackages are independent and self-contained pieces of information that
-are sent from one device to another serialized in json.
+are sent from one device to another (via a DeviceLink) serialized in json.
 
 The basic structure of a NetworkPackage is the following:
 
@@ -16,5 +49,6 @@ The basic structure of a NetworkPackage is the following:
 }
 
 Each type of package defines what it should contain inside its "body", so only
-the sender and receiver of this type of package need agree about it.
+the emisor Plugin and receiver Plugin of this type of package need agree about
+its content.
 
diff --git a/daemon/daemon.cpp b/daemon/daemon.cpp
index 9b94716..b8cff21 100644
--- a/daemon/daemon.cpp
+++ b/daemon/daemon.cpp
@@ -57,13 +57,7 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&)
     //Debugging
     qDebug() << "Starting KdeConnect daemon";
 
-    //Load plugins
-    PluginLoader *loader = new PluginLoader(this);
-    connect(loader, SIGNAL(pluginLoaded(PackageInterface*)), this, SLOT(pluginLoaded(PackageInterface*)));
-    loader->loadAllPlugins();
-
-    //Load backends (hardcoded by now)
-    //use: https://techbase.kde.org/Development/Tutorials/Services/Plugins
+    //Load backends (hardcoded by now, should be plugins in a future)
     mLinkProviders.insert(new BroadcastTcpLinkProvider());
     //mLinkProviders.insert(new AvahiTcpLinkProvider());
     //mLinkProviders.insert(new LoopbackLinkProvider());
@@ -77,12 +71,6 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&)
         const QString& name = data.readEntry<QString>("name", defaultName);
         Device* device = new Device(id, name);
         mDevices[id] = device;
-        Q_FOREACH (PackageInterface* pr, mPackageInterfaces) {
-            connect(device, SIGNAL(receivedPackage(const Device&, const NetworkPackage&)),
-                    pr, SLOT(receivePackage(const Device&, const NetworkPackage&)));
-            connect(pr, SIGNAL(sendPackage(const NetworkPackage&)),
-                    device, SLOT(sendPackage(const NetworkPackage&)));
-        }
     }
     
     QNetworkSession* network = new QNetworkSession(QNetworkConfigurationManager().defaultConfiguration());
@@ -123,19 +111,6 @@ QStringList Daemon::devices()
     return mDevices.keys();
 }
 
-void Daemon::pluginLoaded(PackageInterface* packageInterface)
-{
-    qDebug() << "PLUUUUUUUUUUUUUUUUGINLOADEEEEEEEEEEEEEEEEEEEEEEED";
-    mPackageInterfaces.append(packageInterface);
-    Q_FOREACH(Device* device, mDevices) {
-        connect(device, SIGNAL(receivedPackage(const Device&, const NetworkPackage&)),
-                packageInterface, SLOT(receivePackage(const Device&, const NetworkPackage&)));
-        connect(packageInterface, SIGNAL(sendPackage(const NetworkPackage&)),
-                device, SLOT(sendPackage(const NetworkPackage&)));
-    }
-
-}
-
 void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl)
 {
     const QString& id = identityPackage.get<QString>("deviceId");
@@ -166,10 +141,7 @@ void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink*
 
         Device* device = new Device(id, name, dl);
         mDevices[id] = device;
-        Q_FOREACH (PackageInterface* pr, mPackageInterfaces) {
-            connect(device, SIGNAL(receivedPackage(const Device&, const NetworkPackage&)),
-                    pr, SLOT(receivePackage(const Device&, const NetworkPackage&)));
-        }
+
         Q_EMIT newDeviceAdded(id);
     }
 
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 9e6a8bb..e69cd6e 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -72,19 +72,14 @@ Q_SIGNALS:
 
 private Q_SLOTS:
     void onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl);
-    void pluginLoaded(PackageInterface*);
 
 private:
 
-
-    //Every known device
-    QMap<QString, Device*> mDevices;
-
     //Different ways to find devices and connect to them
     QSet<LinkProvider*> mLinkProviders;
 
-    //The classes that send and receive the packages
-    QVector<PackageInterface*> mPackageInterfaces;
+    //Every known device
+    QMap<QString, Device*> mDevices;
 
 };
 
diff --git a/daemon/device.cpp b/daemon/device.cpp
index b380a68..1b46d78 100644
--- a/daemon/device.cpp
+++ b/daemon/device.cpp
@@ -3,8 +3,14 @@
 #include <KSharedPtr>
 #include <KSharedConfig>
 #include <KConfigGroup>
+#include <KStandardDirs>
+#include <KPluginSelector>
+#include <KServiceTypeTrader>
+#include <KPluginInfo>
+
 #include <QDebug>
 
+#include "plugins/pluginloader.h"
 #include "devicelinks/devicelink.h"
 #include "linkproviders/linkprovider.h"
 #include "networkpackage.h"
@@ -19,6 +25,7 @@ Device::Device(const QString& id, const QString& name)
     //Register in bus
     QDBusConnection::sessionBus().registerObject("/modules/kdeconnect/devices/"+id, this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
 
+    reloadPlugins();
 }
 
 Device::Device(const QString& id, const QString& name, DeviceLink* link)
@@ -32,6 +39,8 @@ Device::Device(const QString& id, const QString& name, DeviceLink* link)
     QDBusConnection::sessionBus().registerObject("/modules/kdeconnect/devices/"+id, this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
 
     addLink(link);
+
+    reloadPlugins();
 }
 /*
 Device::Device(const QString& id, const QString& name, DeviceLink* link)
@@ -50,6 +59,43 @@ Device::Device(const QString& id, const QString& name, DeviceLink* link)
     QDBusConnection::sessionBus().registerObject("/modules/kdeconnect/Devices/"+id, this);
 }
 */
+
+void Device::reloadPlugins()
+{
+
+    qDeleteAll(m_plugins);
+    m_plugins.clear();
+
+    QString path = KStandardDirs().resourceDirs("config").first()+"kdeconnect/";
+    QMap<QString,QString> pluginStates = KSharedConfig::openConfig(path + id())->group("Plugins").entryMap();
+
+    PluginLoader* loader = PluginLoader::instance();
+
+    //Code borrowed from KWin
+    foreach (const QString& pluginName, loader->getPluginList()) {
+
+        const QString value = pluginStates.value(pluginName + QString::fromLatin1("Enabled"), QString());
+        bool enabled = (value.isNull() ? true : QVariant(value).toBool()); //Enable all plugins by default
+
+        qDebug() << pluginName << "enabled:" << enabled;
+
+        if (enabled) {
+            PackageInterface* plugin = loader->instantiatePluginForDevice(pluginName, this);
+
+            connect(this, SIGNAL(receivedPackage(const NetworkPackage&)),
+                    plugin, SLOT(receivePackage(const NetworkPackage&)));
+    //        connect(packageInterface, SIGNAL(sendPackage(const NetworkPackage&)),
+    //                device, SLOT(sendPackage(const NetworkPackage&)));
+
+
+            m_plugins.append(plugin);
+        }
+    }
+
+
+}
+
+
 void Device::setPair(bool b)
 {
     qDebug() << "setPair" << b;
@@ -122,10 +168,10 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
     if (np.type() == "kdeconnect.identity" && !m_knownIdentiy) {
         m_deviceName = np.get<QString>("deviceName");
     } else if (m_paired) {
-        qDebug() << "package received from paired device";
-        emit receivedPackage(*this, np);
+        qDebug() << "package received from trusted device";
+        Q_EMIT receivedPackage(np);
     } else {
-        qDebug() << "not paired, ignoring package";
+        qDebug() << "device" << name() << "not trusted, ignoring package" << np.type();
     }
 }
 
diff --git a/daemon/device.h b/daemon/device.h
index 74ec9d3..813a8ff 100644
--- a/daemon/device.h
+++ b/daemon/device.h
@@ -28,6 +28,7 @@
 #include "devicelinks/devicelink.h"
 
 class DeviceLink;
+class PackageInterface;
 
 class Device
     : public QObject
@@ -38,7 +39,6 @@ class Device
     Q_PROPERTY(QString name READ name)
 
 public:
-
     //Device known from KConfig, we trust it but we need to wait for a incoming devicelink to communicate
     Device(const QString& id, const QString& name);
 
@@ -56,19 +56,20 @@ public:
     void addLink(DeviceLink*);
     void removeLink(DeviceLink*);
 
+    Q_SCRIPTABLE QStringList availableLinks() const;
+    Q_SCRIPTABLE bool paired() const { return m_paired; }
+    Q_SCRIPTABLE bool reachable() const { return !m_deviceLinks.empty(); }
 
     //Send and receive
 Q_SIGNALS:
-    void receivedPackage(const Device& device, const NetworkPackage& np);
+    void receivedPackage(const NetworkPackage& np);
 public Q_SLOTS:
     bool sendPackage(const NetworkPackage& np) const;
 
-    //Public dbus operations
+    //Dbus operations called from kcm
 public Q_SLOTS:
-    Q_SCRIPTABLE QStringList availableLinks() const;
-    Q_SCRIPTABLE bool paired() const { return m_paired; }
-    Q_SCRIPTABLE bool reachable() const { return !m_deviceLinks.empty(); }
     Q_SCRIPTABLE void setPair(bool b);
+    Q_SCRIPTABLE void reloadPlugins();
     Q_SCRIPTABLE void sendPing();
 
 Q_SIGNALS:
@@ -83,9 +84,12 @@ private:
     QString m_deviceId;
     QString m_deviceName;
     QList<DeviceLink*> m_deviceLinks;
+    QList<PackageInterface*> m_plugins;
     bool m_knownIdentiy;
 
 
 };
 
+Q_DECLARE_METATYPE(Device*)
+
 #endif // DEVICE_H
diff --git a/daemon/plugins/CMakeLists.txt b/daemon/plugins/CMakeLists.txt
index 4467d26..b710c04 100644
--- a/daemon/plugins/CMakeLists.txt
+++ b/daemon/plugins/CMakeLists.txt
@@ -1,2 +1,5 @@
 
+install(FILES kdeconnect_package_interface.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR})
+
 add_subdirectory(ping)
+
diff --git a/daemon/plugins/packageinterface.cpp b/daemon/plugins/packageinterface.cpp
index b5f5f72..efa8dd4 100644
--- a/daemon/plugins/packageinterface.cpp
+++ b/daemon/plugins/packageinterface.cpp
@@ -20,8 +20,17 @@
 
 #include "packageinterface.h"
 
-PackageInterface::PackageInterface(QObject* parent)
+#include <QPointer>
+
+#include "../device.h"
+
+PackageInterface::PackageInterface(QObject* parent, const QVariantList& args)
     : QObject(parent)
 {
-    //gcc complains if we don't add something to compile on a class with virtual functions
+    mDevice = qvariant_cast< Device* >(args.first());
+}
+
+Device* PackageInterface::device()
+{
+    return mDevice;
 }
diff --git a/daemon/plugins/packageinterface.h b/daemon/plugins/packageinterface.h
index 4569087..dd2d360 100644
--- a/daemon/plugins/packageinterface.h
+++ b/daemon/plugins/packageinterface.h
@@ -22,6 +22,7 @@
 #define PACKAGEINTERFACE_H
 
 #include <QObject>
+#include <QVariantList>
 
 #include <kdemacros.h>
 #include <KPluginFactory>
@@ -40,17 +41,18 @@ class KDE_EXPORT PackageInterface
     Q_OBJECT
 
 public:
-    PackageInterface(QObject* parent = 0);
+    PackageInterface(QObject* parent, const QVariantList& args);
     virtual ~PackageInterface() { }
+    Device* device();
 
 public Q_SLOTS:
     //Returns true if it has handled the package in some way
     //device.sendPackage can be used to send an answer back to the device
-    virtual bool receivePackage(const Device& device, const NetworkPackage& np) = 0;
+    virtual bool receivePackage(const NetworkPackage& np) = 0;
+
+private:
+    Device* mDevice;
 
-Q_SIGNALS:
-    //Sends a package to *all* connected devices
-    void sendPackage(const NetworkPackage& np);
 };
 
 #endif
diff --git a/daemon/plugins/ping/kdeconnect_ping.desktop b/daemon/plugins/ping/kdeconnect_ping.desktop
index fe19ccd..4fbe2a1 100644
--- a/daemon/plugins/ping/kdeconnect_ping.desktop
+++ b/daemon/plugins/ping/kdeconnect_ping.desktop
@@ -8,11 +8,6 @@ X-KDE-PluginInfo-Email=albertvaka at gmail.com
 X-KDE-PluginInfo-Name=kdeconnect_ping
 X-KDE-PluginInfo-Version=0.1
 X-KDE-PluginInfo-Website=http://albertvaka.wordpress.com
-X-KDE-PluginInfo-Category=Network
-X-KDE-PluginInfo-Depends=
 X-KDE-PluginInfo-License=GPL
-X-KDE-PluginInfo-EnabledByDefault=true
-X-KDE-ParentApp=kdeconnect
-X-KDE-Version=4.0
 Name=Ping
 Comment=Send and receive pings
diff --git a/daemon/plugins/ping/pingpackageinterface.cpp b/daemon/plugins/ping/pingpackageinterface.cpp
index 4bc0a53..be28f68 100644
--- a/daemon/plugins/ping/pingpackageinterface.cpp
+++ b/daemon/plugins/ping/pingpackageinterface.cpp
@@ -20,19 +20,20 @@
 
 #include "pingpackageinterface.h"
 
-#include <KDebug>
-#include <kicon.h>
+#include <KNotification>
+#include <KIcon>
+#include <QDebug>
 
 K_PLUGIN_FACTORY( KdeConnectPluginFactory, registerPlugin< PingPackageInterface >(); )
 K_EXPORT_PLUGIN( KdeConnectPluginFactory("kdeconnect_ping", "kdeconnect_ping") )
 
 PingPackageInterface::PingPackageInterface(QObject* parent, const QVariantList& args)
-    : PackageInterface(parent)
+    : PackageInterface(parent, args)
 {
-    Q_UNUSED(args);
+    qDebug() << "Plugin constructor for device" << device()->name();
 }
 
-bool PingPackageInterface::receivePackage(const Device& device, const NetworkPackage& np)
+bool PingPackageInterface::receivePackage(const NetworkPackage& np)
 {
 
     if (np.type() != PACKAGE_TYPE_PING) return false;
@@ -41,7 +42,7 @@ bool PingPackageInterface::receivePackage(const Device& device, const NetworkPac
     notification->setPixmap(KIcon("dialog-ok").pixmap(48, 48));
     notification->setComponentData(KComponentData("kdeconnect", "kdeconnect"));
     notification->setTitle("Ping!");
-    notification->setText(device.name());
+    notification->setText(device()->name());
     notification->sendEvent();
 
     return true;
diff --git a/daemon/plugins/ping/pingpackageinterface.h b/daemon/plugins/ping/pingpackageinterface.h
index 5ad4474..e21354f 100644
--- a/daemon/plugins/ping/pingpackageinterface.h
+++ b/daemon/plugins/ping/pingpackageinterface.h
@@ -21,7 +21,7 @@
 #ifndef PINGPACKAGEINTERFACE_H
 #define PINGPACKAGEINTERFACE_H
 
-#include <knotification.h>
+#include <QObject>
 
 #include "../packageinterface.h"
 
@@ -32,8 +32,9 @@ class KDE_EXPORT PingPackageInterface
 
 public:
     explicit PingPackageInterface(QObject *parent, const QVariantList &args);
-
-    virtual bool receivePackage(const Device& device, const NetworkPackage& np);
+    
+public Q_SLOTS:
+    virtual bool receivePackage(const NetworkPackage& np);
 
 };
 
diff --git a/daemon/plugins/pluginloader.cpp b/daemon/plugins/pluginloader.cpp
index b6eaedc..194ed44 100644
--- a/daemon/plugins/pluginloader.cpp
+++ b/daemon/plugins/pluginloader.cpp
@@ -21,49 +21,58 @@
 #include "pluginloader.h"
 
 #include "packageinterface.h"
+#include "plugins/ping/pingpackageinterface.h"
 
 #include <KServiceTypeTrader>
 #include <KDebug>
 
-PluginLoader::PluginLoader(QObject * parent)
-  : QObject(parent)
-{
-}
+#include "../device.h"
 
-PluginLoader::~PluginLoader()
+PluginLoader* PluginLoader::instance()
 {
+    static PluginLoader* instance = new PluginLoader();
+    return instance;
 }
 
-void PluginLoader::loadAllPlugins()
+PluginLoader::PluginLoader()
 {
-    kDebug() << "Load all plugins";
     KService::List offers = KServiceTypeTrader::self()->query("KdeConnect/Plugin");
+    for(KService::List::const_iterator iter = offers.begin(); iter < offers.end(); ++iter) {
+        KService::Ptr service = *iter;
+        plugins[service->library()] = service;
+    }
+}
 
-    qDebug() << "LO TRAIGO DE OFERTA CHACHO" << offers;
+QStringList PluginLoader::getPluginList()
+{
+    return plugins.keys();
+}
 
-    KService::List::const_iterator iter;
-    for(iter = offers.begin(); iter < offers.end(); ++iter)
-    {
-       QString error;
-       KService::Ptr service = *iter;
+PackageInterface* PluginLoader::instantiatePluginForDevice(QString id, Device* device) {
 
-        KPluginFactory *factory = KPluginLoader(service->library()).factory();
+    KService::Ptr service = plugins[id];
+    if (!service) {
+        qDebug() << "Plugin unknown" << id;
+        return NULL;
+    }
 
-        if (!factory)
-        {
-            //KMessageBox::error(0, i18n("<html><p>KPluginFactory could not load the plugin:<br /><i>%1</i></p></html>",
-              //                         service->library()));
-            kError(5001) << "KPluginFactory could not load the plugin:" << service->library();
-            continue;
-        }
+    KPluginFactory *factory = KPluginLoader(service->library()).factory();
+    if (!factory) {
+        qDebug() << "KPluginFactory could not load the plugin:" << service->library();
+        return NULL;
+    }
 
-       PackageInterface *plugin = factory->create<PackageInterface>(this);
+    QVariant deviceVariant;
+    deviceVariant.setValue<Device*>(device);
 
-       if (plugin) {
-           kDebug() << "Load plugin:" << service->name();
-           emit pluginLoaded(plugin);
-       } else {
-           kDebug() << error;
-       }
+    //FIXME: create<PackageInterface> return NULL
+    QObject *plugin = factory->create<QObject>(device, QVariantList() << deviceVariant);
+    if (!plugin) {
+        qDebug() << "Error loading plugin";
+        return NULL;
     }
-}
\ No newline at end of file
+
+    qDebug() << "Loaded plugin:" << service->name();
+    return (PackageInterface*)plugin;
+}
+
diff --git a/daemon/plugins/pluginloader.h b/daemon/plugins/pluginloader.h
index 4ae29d2..8a2b6bd 100644
--- a/daemon/plugins/pluginloader.h
+++ b/daemon/plugins/pluginloader.h
@@ -22,21 +22,29 @@
 #define PACKAGEINTERFACELOADER_H
 
 #include <QObject>
+#include <QMap>
+#include <QString>
 
 #include "packageinterface.h"
 
+#include <KPluginFactory>
+#include <KService>
 
-class PluginLoader : public QObject
+class Device;
+
+class PluginLoader
 {
-    Q_OBJECT
-    public:
-        PluginLoader(QObject * parent);
-        virtual ~PluginLoader();
 
-        void loadAllPlugins();
+public:
+    static PluginLoader* instance();
+    PackageInterface* instantiatePluginForDevice(QString name, Device* device);
+    QStringList getPluginList();
+
+private:
+    PluginLoader();
+    QMap<QString,KService::Ptr> plugins;
+
 
-    signals:
-        void pluginLoaded(PackageInterface * plugin);
 };
 
 #endif
diff --git a/kcm/CMakeLists.txt b/kcm/CMakeLists.txt
index 8b5ed0a..9c39d42 100644
--- a/kcm/CMakeLists.txt
+++ b/kcm/CMakeLists.txt
@@ -25,7 +25,7 @@ target_link_libraries(kcm_kdeconnect
     ${QT_QTCORE_LIBRARY}
     ${QT_QTGUI_LIBRARY}
     ${KDE4_KDEUI_LIBRARY}
-    ${KDE4_KIO_LIBRARY}
+    ${KDE4_KCMUTILS_LIBS}
 )
 
 add_dependencies(kcm_kdeconnect
diff --git a/kcm/devicesmodel.cpp b/kcm/devicesmodel.cpp
index 3ae3509..990f87b 100644
--- a/kcm/devicesmodel.cpp
+++ b/kcm/devicesmodel.cpp
@@ -118,7 +118,6 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
     }
 
 
-    qDebug() << index.row() << ">= " << m_deviceList.count() << (index.row() >= m_deviceList.count());
     if (!index.isValid() || index.row() < 0 || index.row() >= m_deviceList.count()) {
         return QVariant();
     }
diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp
index fc909b4..d6156c0 100644
--- a/kcm/kcm.cpp
+++ b/kcm/kcm.cpp
@@ -32,6 +32,8 @@
 #include <QDBusConnection>
 #include <QDBusInterface>
 
+#include <KServiceTypeTrader>
+#include <KPluginInfo>
 #include <KDebug>
 #include <kpluginfactory.h>
 #include <kstandarddirs.h>
@@ -43,7 +45,8 @@ KdeConnectKcm::KdeConnectKcm(QWidget *parent, const QVariantList&)
     : KCModule(KdeConnectKcmFactory::componentData(), parent)
     , kcmUi(new Ui::KdeConnectKcmUi())
     , pairedDevicesList(new DevicesModel(this))
-    , config(KSharedConfig::openConfig("kdeconnectrc"))
+    , currentDevice(0)
+    //, config(KSharedConfig::openConfig("kdeconnectrc"))
 {
     kcmUi->setupUi(this);
 
@@ -52,6 +55,8 @@ KdeConnectKcm::KdeConnectKcm(QWidget *parent, const QVariantList&)
 
     kcmUi->deviceInfo->setVisible(false);
 
+    setButtons(KCModule::NoAdditionalButton);
+
     connect(kcmUi->deviceList, SIGNAL(pressed(QModelIndex)), this, SLOT(deviceSelected(QModelIndex)));
     connect(kcmUi->ping_button, SIGNAL(pressed()), this, SLOT(sendPing()));
     connect(kcmUi->trust_checkbox,SIGNAL(toggled(bool)), this, SLOT(trustedStateChanged(bool)));
@@ -64,27 +69,63 @@ KdeConnectKcm::~KdeConnectKcm()
 
 void KdeConnectKcm::deviceSelected(const QModelIndex& current)
 {
+    //Store previous selection
+    pluginsConfigChanged();
+
+    //FIXME: KPluginSelector has no way to remove a list of plugins and load another, so we need to destroy and recreate it each time
+    delete kcmUi->pluginSelector;
+    kcmUi->pluginSelector = new KPluginSelector(this);
+    kcmUi->verticalLayout_2->addWidget(kcmUi->pluginSelector);
+
     bool valid = current.isValid();
     kcmUi->deviceInfo->setVisible(valid);
     if (!valid) return;
-    selectedIndex = current;
-    bool paired = pairedDevicesList->getDevice(current)->paired();
-    kcmUi->trust_checkbox->setChecked(paired);
+
+    currentDevice = pairedDevicesList->getDevice(current);
+    kcmUi->deviceName->setText(currentDevice->name());
+    kcmUi->trust_checkbox->setChecked(currentDevice->paired());
+
+    KService::List offers = KServiceTypeTrader::self()->query("KdeConnect/Plugin");
+    QList<KPluginInfo> scriptinfos = KPluginInfo::fromServices(offers);
+
+    QString path = KStandardDirs().resourceDirs("config").first()+"kdeconnect/";
+    KSharedConfigPtr deviceConfig = KSharedConfig::openConfig(path + currentDevice->id());
+    kcmUi->pluginSelector->addPlugins(scriptinfos, KPluginSelector::ReadConfigFile, "Plugins", QString(), deviceConfig);
+
+    connect(kcmUi->pluginSelector, SIGNAL(changed(bool)), this, SLOT(pluginsConfigChanged()));
 }
 
 void KdeConnectKcm::trustedStateChanged(bool b)
 {
-    if (!selectedIndex.isValid()) return;
-    DeviceDbusInterface* device = pairedDevicesList->getDevice(selectedIndex);
-    device->setPair(b);
-    pairedDevicesList->deviceStatusChanged(device->id());
+    if (!currentDevice) return;
+    currentDevice->setPair(b);
+    pairedDevicesList->deviceStatusChanged(currentDevice->id());
+}
+
+void KdeConnectKcm::pluginsConfigChanged()
+{
+    //Store previous selection
+    if (!currentDevice) return;
+
+    DeviceDbusInterface* auxCurrentDevice = currentDevice; //HACK to avoid infinite recursion (for some reason calling save on pluginselector emits changed)
+    currentDevice = 0;
+    kcmUi->pluginSelector->save();
+    currentDevice = auxCurrentDevice;
+
+    currentDevice->reloadPlugins();
+}
+
+void KdeConnectKcm::save()
+{
+    pluginsConfigChanged();
+    KCModule::save();
 }
 
 
 void KdeConnectKcm::sendPing()
 {
-    if (!selectedIndex.isValid()) return;
-    pairedDevicesList->getDevice(selectedIndex)->sendPing();
+    if (!currentDevice) return;
+    currentDevice->sendPing();
 }
 
 
diff --git a/kcm/kcm.h b/kcm/kcm.h
index dbfb943..f03696d 100644
--- a/kcm/kcm.h
+++ b/kcm/kcm.h
@@ -30,13 +30,13 @@
 #include "wizard.h"
 #include "devicesmodel.h"
 
-class Create;
 class QModelIndex;
 class AccountsModel;
 class AccountWidget;
 class QStackedLayout;
 class QItemSelectionModel;
 class QDBusInterface;
+class DeviceDbusInterface;
 
 namespace Ui {
     class KdeConnectKcmUi;
@@ -50,17 +50,21 @@ public:
     KdeConnectKcm(QWidget *parent, const QVariantList&);
     virtual ~KdeConnectKcm();
 
+private:
+    virtual void save();
+
 private Q_SLOTS:
     void deviceSelected(const QModelIndex& current);
     void trustedStateChanged(bool);
+    void pluginsConfigChanged();
     void sendPing();
-    
+
 private:
     Ui::KdeConnectKcmUi* kcmUi;
     DevicesModel* pairedDevicesList;
     AddDeviceWizard* addDeviceWizard;
-    KSharedConfigPtr config;
-    QModelIndex selectedIndex;
+    DeviceDbusInterface* currentDevice;
+    //KSharedConfigPtr config;
 
 };
 
diff --git a/kcm/kcm.ui b/kcm/kcm.ui
index 13f8063..b9879b6 100644
--- a/kcm/kcm.ui
+++ b/kcm/kcm.ui
@@ -45,84 +45,102 @@
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="deviceInfoBorder">
+    <widget class="QGroupBox" name="deviceInfoBorder_2">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
-     <property name="title">
-      <string/>
-     </property>
-     <property name="flat">
-      <bool>false</bool>
-     </property>
-     <property name="checkable">
-      <bool>false</bool>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
+     <layout class="QVBoxLayout" name="deviceInfoBorder">
       <item>
        <widget class="QGroupBox" name="deviceInfo">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
         <property name="title">
          <string/>
         </property>
         <property name="flat">
          <bool>true</bool>
         </property>
-        <layout class="QVBoxLayout" name="verticalLayout_3">
-         <item>
-          <spacer name="verticalSpacer_2">
-           <property name="orientation">
-            <enum>Qt::Vertical</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>215</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
+        <property name="checkable">
+         <bool>false</bool>
+        </property>
+        <layout class="QVBoxLayout" name="verticalLayout_2">
          <item>
-          <widget class="QCheckBox" name="trust_checkbox">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Trust this device</string>
-           </property>
-          </widget>
+          <layout class="QHBoxLayout" name="horizontalLayout">
+           <item>
+            <widget class="QLabel" name="deviceName">
+             <property name="font">
+              <font>
+               <pointsize>10</pointsize>
+               <weight>75</weight>
+               <bold>true</bold>
+              </font>
+             </property>
+             <property name="text">
+              <string>Device</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="horizontalSpacer">
+             <property name="orientation">
+              <enum>Qt::Horizontal</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>40</width>
+               <height>20</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+           <item>
+            <widget class="QCheckBox" name="trust_checkbox">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+             <property name="text">
+              <string>Trust this device</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QPushButton" name="ping_button">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+             <property name="text">
+              <string>Send ping</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
          </item>
          <item>
-          <widget class="QPushButton" name="ping_button">
+          <widget class="KPluginSelector" name="pluginSelector" native="true">
            <property name="sizePolicy">
-            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+            <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
-           <property name="text">
-            <string>Send ping</string>
+           <property name="focusPolicy">
+            <enum>Qt::WheelFocus</enum>
            </property>
           </widget>
          </item>
-         <item>
-          <spacer name="verticalSpacer">
-           <property name="orientation">
-            <enum>Qt::Vertical</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>215</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
         </layout>
        </widget>
       </item>
@@ -131,6 +149,14 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KPluginSelector</class>
+   <extends>QWidget</extends>
+   <header>kpluginselector.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>

-- 
kdeconnect packaging



More information about the pkg-kde-commits mailing list