[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdeconnect-kde] /: Build kdeconnect on sailfish and port some simple plugins
From:       Adam Pigg <null () kde ! org>
Date:       2018-08-02 19:11:11
Message-ID: E1flJ0B-00012c-F9 () code ! kde ! org
[Download RAW message or body]

Git commit 9a8f1b48a0c83752262ffcd6f2bda0965b21916e by Adam Pigg.
Committed on 02/08/2018 at 19:10.
Pushed by piggz into branch 'master'.

Build kdeconnect on sailfish and port some simple plugins

Summary:
Below is a lost of the commits, but, in summary
Port the build system for Sailfish, which means selectively building only the bits we \
need/can, and only against the KF5 libs that are available. Allow to build on Qt 5.6
Switch from knotification to nemo notification (not complete!)
Add a very simple example sailfish app.

Note, there is still much missing functionality.  Notifications dont work, pairing \
sort of works but not really, but when it is paired you can send a ping to the \
desktop client

Dont build kio for Sailfish

Port core build system

Port daemon buld system

Require CoreAddons on Sailfish

Port plugins build for sailfish and include the ping plugin for now

Final build changes for sailfish.

Disable tests and other not needed parts

Add includes for QCA

Fix build errors on sailfish

Get core/ to build on sailfish

Get interfaces/ to build on sailfish

Build daemon on sailfish

On sailfish, dont install the kcm file

Start port plugin to sailfish

Fixup installed files

Add sfos app

Hack declarative plugin to give a public interface

Build sfos app

Compile declarativeplugin into the sfos app for now

Redefine qAsConst for qt 5.6

Packaging fixes

Use official icon

Package .desktop

Reviewers: #kde_connect, apol, nicolasfella, albertvaka

Reviewed By: #kde_connect, apol, nicolasfella, albertvaka

Subscribers: kdeconnect, andyholmes, albertvaka, kossebau, mtijink, vonreth, apol, \
#kde_connect, nicolasfella

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10703

M  +49   -18   CMakeLists.txt
M  +1    -0    core/backends/devicelink.h
M  +3    -0    core/daemon.cpp
M  +3    -0    core/device.cpp
M  +3    -0    core/pluginloader.cpp
A  +82   -0    core/qtcompat_p.h     [License: LGPL (v2+)]
M  +3    -0    interfaces/notificationsmodel.cpp
M  +2    -0    plasmoid/CMakeLists.txt
M  +10   -7    plasmoid/declarativeplugin/responsewaiter.cpp
M  +27   -19   plugins/CMakeLists.txt
M  +1    -1    plugins/battery/batteryplugin.cpp
M  +6    -3    plugins/notifications/notificationsdbusinterface.cpp
M  +3    -0    plugins/pausemusic/pausemusicplugin.cpp
M  +14   -3    plugins/sendnotifications/CMakeLists.txt
R  +1    -1    plugins/sendnotifications/kdeconnect_sendnotifications.json.in [from: \
plugins/sendnotifications/kdeconnect_sendnotifications.json - 099% similarity] M  +4  \
-1    plugins/sendnotifications/notificationslistener.cpp A  +26   -0    \
sfos/CMakeLists.txt A  +60   -0    sfos/kdeconnect-sfos.cpp     [License: BSD]
A  +12   -0    sfos/kdeconnect-sfos.desktop
A  +47   -0    sfos/kdeconnectd.desktop.cmake
A  +3    -0    sfos/org.kde.kdeconnect.service.in
A  +74   -0    sfos/qml/cover/CoverPage.qml     [License: BSD]
A  +48   -0    sfos/qml/kdeconnect-sfos.qml     [License: BSD]
A  +105  -0    sfos/qml/pages/DevicePage.qml     [License: BSD]
A  +77   -0    sfos/qml/pages/FindDevices.qml     [License: BSD]
A  +61   -0    sfos/qml/pages/FirstPage.qml     [License: BSD]
A  +47   -0    sfos/qml/pages/PluginItem.qml     [License: GPL (v2/3)]
A  +104  -0    sfos/qml/pages/mousepad.qml     [License: GPL (v2/3)]
A  +82   -0    sfos/qml/pages/mpris.qml     [License: GPL (v2/3)]
A  +18   -0    sfos/rpm/kdeconnect-sfos.changes.in
A  +25   -0    sfos/rpm/kdeconnect-sfos.changes.run.in
A  +85   -0    sfos/rpm/kdeconnect-sfos.spec
A  +116  -0    sfos/sailfishdaemon.cpp     [License: GPL (v2/3)]

https://commits.kde.org/kdeconnect-kde/9a8f1b48a0c83752262ffcd6f2bda0965b21916e

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d1adf10e..dab0317b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,19 +7,38 @@ set(KDECONNECT_VERSION_MINOR 3)
 set(KDECONNECT_VERSION_PATCH 0)
 set(KDECONNECT_VERSION \
"${KDECONNECT_VERSION_MAJOR}.${KDECONNECT_VERSION_MINOR}.${KDECONNECT_VERSION_PATCH}")
  
-set(QT_MIN_VERSION "5.7.0")
-set(KF5_MIN_VERSION "5.42.0")
+find_package(PkgConfig)
+
+if (SAILFISHOS)
+    set(KF5_MIN_VERSION "5.31.0")
+    set(QT_MIN_VERSION "5.6.0")
+    set(KF5_REQUIRED_COMPONENTS I18n DBusAddons CoreAddons IconThemes Config)
+    set(KF5_OPTIONAL_COMPONENTS)
+    set(QCA_MIN_VERSION 2.0.0)
+    pkg_search_module(SFOS REQUIRED sailfishapp)
+    pkg_check_modules(QCA2 qca2-qt5>=${QCA_MIN_VERSION} REQUIRED)
+    add_definitions(-DSAILFISHOS)
+    include_directories(${QCA2_INCLUDEDIR})
+    add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
+else()
+    set(KF5_MIN_VERSION "5.42.0")
+    set(QT_MIN_VERSION "5.7.0")
+    set(KF5_REQUIRED_COMPONENTS I18n ConfigWidgets DBusAddons IconThemes \
Notifications KIO KCMUtils) +    set(KF5_OPTIONAL_COMPONENTS DocTools PulseAudioQt)
+    set(QCA_MIN_VERSION "2.1.0")
+    find_package(Qca-qt5 ${QCA_MIN_VERSION} REQUIRED)
+    add_definitions(-DQT_NO_URL_CAST_FROM_STRING -DQT_NO_KEYWORDS)
+endif()
 
 find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
 set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} \
${CMAKE_SOURCE_DIR}/cmake)  
 find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Quick Network)
+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()
 
-find_package(KF5 ${KF5_MIN_VERSION}
-    REQUIRED COMPONENTS I18n ConfigWidgets DBusAddons IconThemes Notifications KIO \
                KCMUtils
-    OPTIONAL_COMPONENTS DocTools PulseAudioQt
-)
-find_package(Qca-qt5 2.1.0 REQUIRED)
 find_package(Phonon4Qt5 4.9.0 NO_MODULE)
 set_package_properties(Phonon4Qt5 PROPERTIES
    DESCRIPTION "Qt-based audio library"
@@ -41,18 +60,23 @@ include(FeatureSummary)
 
 include(KDEConnectMacros.cmake)
 
-add_definitions(-DQT_NO_URL_CAST_FROM_STRING -DQT_NO_KEYWORDS)
-
 include(GenerateExportHeader)
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 add_subdirectory(core)
-add_subdirectory(kcm)
-add_subdirectory(kcmplugin)
+if(NOT SAILFISHOS)
+    add_subdirectory(kcm)
+    add_subdirectory(kcmplugin)
+    add_subdirectory(daemon)
+endif()
+
 if(NOT WIN32)
-	add_subdirectory(kio)
+    if (NOT SAILFISHOS)
+        add_subdirectory(kio)
+    endif()
 	add_subdirectory(plasmoid)
 endif()
+
 add_subdirectory(icon)
 add_subdirectory(interfaces)
 
@@ -60,25 +84,32 @@ option(EXPERIMENTALAPP_ENABLED OFF)
 if(EXPERIMENTALAPP_ENABLED)
     add_subdirectory(app)
 endif()
-add_subdirectory(daemon)
 add_subdirectory(plugins)
 add_subdirectory(cli)
-add_subdirectory(indicator)
-add_subdirectory(urlhandler)
-add_subdirectory(nautilus-extension)
+
+if (NOT SAILFISHOS)
+    add_subdirectory(indicator)
+    add_subdirectory(urlhandler)
+    add_subdirectory(nautilus-extension)
+else()
+    add_subdirectory(sfos)
+endif()
 
 option(SMSAPP_ENABLED OFF)
 if(SMSAPP_ENABLED)
     find_package(KF5People REQUIRED)
     add_subdirectory(smsapp)
 endif()
+
 if(KF5DocTools_FOUND)
     add_subdirectory(doc)
 endif()
 
-if(BUILD_TESTING)
+if(BUILD_TESTING AND NOT SAILFISHOS)
     add_subdirectory(tests)
 endif()
 
-install(FILES org.kde.kdeconnect.kcm.appdata.xml DESTINATION \
${KDE_INSTALL_METAINFODIR}) +if(NOT SAILFISHOS)
+    install(FILES org.kde.kdeconnect.kcm.appdata.xml DESTINATION \
${KDE_INSTALL_METAINFODIR}) +endif()
 feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/core/backends/devicelink.h b/core/backends/devicelink.h
index a941d650..752d797a 100644
--- a/core/backends/devicelink.h
+++ b/core/backends/devicelink.h
@@ -22,6 +22,7 @@
 #define DEVICELINK_H
 
 #include <QObject>
+#include <QIODevice> //Fix build on older QCA
 #include <QtCrypto>
 
 #include "core/networkpacket.h"
diff --git a/core/daemon.cpp b/core/daemon.cpp
index de98076c..c123e47a 100644
--- a/core/daemon.cpp
+++ b/core/daemon.cpp
@@ -40,6 +40,9 @@
 #include "backends/devicelink.h"
 #include "backends/linkprovider.h"
 
+//In older Qt released, qAsConst isnt available
+#include "qtcompat_p.h"
+
 static Daemon* s_instance = nullptr;
 
 struct DaemonPrivate
diff --git a/core/device.cpp b/core/device.cpp
index 05754de7..5cd095d9 100644
--- a/core/device.cpp
+++ b/core/device.cpp
@@ -39,6 +39,9 @@
 #include "kdeconnectconfig.h"
 #include "daemon.h"
 
+//In older Qt released, qAsConst isnt available
+#include "qtcompat_p.h"
+
 class Device::DevicePrivate
 {
 public:
diff --git a/core/pluginloader.cpp b/core/pluginloader.cpp
index 41fd09be..f29ca730 100644
--- a/core/pluginloader.cpp
+++ b/core/pluginloader.cpp
@@ -28,6 +28,9 @@
 #include "device.h"
 #include "kdeconnectplugin.h"
 
+//In older Qt released, qAsConst isnt available
+#include "qtcompat_p.h"
+
 PluginLoader* PluginLoader::instance()
 {
     static PluginLoader* instance = new PluginLoader();
diff --git a/core/qtcompat_p.h b/core/qtcompat_p.h
new file mode 100644
index 00000000..c71bbcef
--- /dev/null
+++ b/core/qtcompat_p.h
@@ -0,0 +1,82 @@
+/*
+    Copyright (c) 2017 Kevin Funk <kfunk@.kde.org
+
+    This library is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Library General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This library 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 Library General Public
+    License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to the
+    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+*/
+
+#ifndef KDEVELOP_QTCOMPAT_P_H
+#define KDEVELOP_QTCOMPAT_P_H
+
+#include <qglobal.h>
+
+#include <QDir>
+
+#if QT_VERSION < QT_VERSION_CHECK(5,7,0)
+namespace QtPrivate
+{
+template <typename T> struct QAddConst {
+    typedef const T Type;
+};
+}
+
+// this adds const to non-const objects (like std::as_const)
+template <typename T>
+Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) \
Q_DECL_NOTHROW { return t; } +// prevent rvalue arguments:
+template <typename T>
+void qAsConst(const T &&) Q_DECL_EQ_DELETE;
+#endif
+
+// compat for Q_FALLTHROUGH
+#if QT_VERSION < QT_VERSION_CHECK(5,8,0)
+
+#if defined(__has_cpp_attribute)
+#    if __has_cpp_attribute(fallthrough)
+#        define Q_FALLTHROUGH() [[fallthrough]]
+#    elif __has_cpp_attribute(clang::fallthrough)
+#        define Q_FALLTHROUGH() [[clang::fallthrough]]
+#    elif __has_cpp_attribute(gnu::fallthrough)
+#        define Q_FALLTHROUGH() [[gnu::fallthrough]]
+#    endif
+#endif
+
+#ifndef Q_FALLTHROUGH
+#    if defined(__GNUC__) && !defined(__INTEL_COMPILER) && (((__GNUC__ * 100) + \
__GNUC_MINOR__) >= 700) +#        define Q_FALLTHROUGH() __attribute__((fallthrough))
+#    else
+#        define Q_FALLTHROUGH() (void)0
+#    endif
+#endif
+
+#endif
+
+namespace QtCompat {
+// TODO: Just use QDir::listSeparator once we depend on Qt 5.6
+Q_DECL_CONSTEXPR inline QChar listSeparator() Q_DECL_NOTHROW
+{
+#if QT_VERSION < QT_VERSION_CHECK(5,6,0)
+#ifdef Q_OS_WIN
+    return QLatin1Char(';');
+#else
+    return QLatin1Char(':');
+#endif
+#else
+    return QDir::listSeparator();
+#endif
+}
+}
+
+#endif
diff --git a/interfaces/notificationsmodel.cpp b/interfaces/notificationsmodel.cpp
index 5b884c56..16fbcd3b 100644
--- a/interfaces/notificationsmodel.cpp
+++ b/interfaces/notificationsmodel.cpp
@@ -29,6 +29,9 @@
 
 //#include "modeltest.h"
 
+//In older Qt released, qAsConst isnt available
+#include "core/qtcompat_p.h"
+
 NotificationsModel::NotificationsModel(QObject* parent)
     : QAbstractListModel(parent)
     , m_dbusInterface(nullptr)
diff --git a/plasmoid/CMakeLists.txt b/plasmoid/CMakeLists.txt
index 51ea5ffa..6442fb4c 100644
--- a/plasmoid/CMakeLists.txt
+++ b/plasmoid/CMakeLists.txt
@@ -1,9 +1,11 @@
 
 add_subdirectory(declarativeplugin)
 
+if (NOT SAILFISHOS)
 install(DIRECTORY package/
         DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/org.kde.kdeconnect)
 
 install(FILES package/metadata.desktop
         DESTINATION ${SERVICES_INSTALL_DIR}
         RENAME plasma-kdeconnect.desktop)
+endif()
diff --git a/plasmoid/declarativeplugin/responsewaiter.cpp \
b/plasmoid/declarativeplugin/responsewaiter.cpp index 6288e782..dca838dc 100644
--- a/plasmoid/declarativeplugin/responsewaiter.cpp
+++ b/plasmoid/declarativeplugin/responsewaiter.cpp
@@ -5,6 +5,9 @@
 #include <QDebug>
 #include <QCoreApplication>
 
+//In older Qt released, qAsConst isnt available
+#include "core/qtcompat_p.h"
+
 Q_DECLARE_METATYPE(QDBusPendingReply<>)
 Q_DECLARE_METATYPE(QDBusPendingReply<QVariant>)
 Q_DECLARE_METATYPE(QDBusPendingReply<bool>)
@@ -29,7 +32,7 @@ DBusResponseWaiter::DBusResponseWaiter()
         << qRegisterMetaType<QDBusPendingReply<> >("QDBusPendingReply<>")
         << qRegisterMetaType<QDBusPendingReply<QVariant> \
                >("QDBusPendingReply<QVariant>")
         << qRegisterMetaType<QDBusPendingReply<bool> >("QDBusPendingReply<bool>")
-        << qRegisterMetaType<QDBusPendingReply<int> >("QDBusPendingReply<int>")      \
 +        << qRegisterMetaType<QDBusPendingReply<int> >("QDBusPendingReply<int>")
         << qRegisterMetaType<QDBusPendingReply<QString> \
>("QDBusPendingReply<QString>")  ;
 }
@@ -39,13 +42,13 @@ QVariant DBusResponseWaiter::waitForReply(QVariant variant) const
     if (QDBusPendingCall* call = \
const_cast<QDBusPendingCall*>(extractPendingCall(variant)))  {
         call->waitForFinished();
-        
+
         if (call->isError())
         {
             qWarning() << "error:" << call->error();
             return QVariant("error");
         }
-        
+
         QDBusMessage reply = call->reply();
 
         if (reply.arguments().count() > 0)
@@ -69,7 +72,7 @@ DBusAsyncResponse::DBusAsyncResponse(QObject* parent)
 void DBusAsyncResponse::setPendingCall(QVariant variant)
 {
     if (QDBusPendingCall* call = \
const_cast<QDBusPendingCall*>(DBusResponseWaiter::instance()->extractPendingCall(variant)))
                
-    {  
+    {
         QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(*call);
         watcher->setProperty("pengingCallVariant", variant);
         connect(watcher, &QDBusPendingCallWatcher::finished, this, \
&DBusAsyncResponse::onCallFinished); @@ -83,7 +86,7 @@ void \
DBusAsyncResponse::onCallFinished(QDBusPendingCallWatcher* watcher)  {
     m_timeout.stop();
     QVariant variant = watcher->property("pengingCallVariant");
-    
+
     if (QDBusPendingCall* call = \
const_cast<QDBusPendingCall*>(DBusResponseWaiter::instance()->extractPendingCall(variant)))
  {
         if (call->isError())
@@ -121,10 +124,10 @@ const QDBusPendingCall* \
DBusResponseWaiter::extractPendingCall(QVariant& variant  {
         if (variant.canConvert(QVariant::Type(type)))
         {
-            return reinterpret_cast<const QDBusPendingCall*>(variant.constData());  
+            return reinterpret_cast<const QDBusPendingCall*>(variant.constData());
         }
     }
-    
+
     return nullptr;
 }
 
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 0ecc7858..b778946e 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -3,27 +3,35 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kdeconnect-plugins\")
 install(FILES kdeconnect_plugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR})
 
 add_subdirectory(ping)
-add_subdirectory(clipboard)
-add_subdirectory(contacts)
-add_subdirectory(telephony)
-add_subdirectory(share)
-add_subdirectory(notifications)
 add_subdirectory(battery)
-add_subdirectory(findmyphone)
-if(Phonon4Qt5_FOUND)
-    add_subdirectory(findthisdevice)
-endif()
-add_subdirectory(remotekeyboard)
-add_subdirectory(mousepad)
-if(NOT WIN32)
-    add_subdirectory(runcommand)
-    add_subdirectory(sendnotifications)
-    add_subdirectory(pausemusic)
-    add_subdirectory(mpriscontrol)
-    add_subdirectory(screensaver-inhibit)
-    add_subdirectory(sftp)
+add_subdirectory(sendnotifications)
+add_subdirectory(clipboard)
+
+if(NOT SAILFISHOS)
+    add_subdirectory(contacts)
+    add_subdirectory(share)
+    add_subdirectory(remotekeyboard)
+    add_subdirectory(notifications)
+    add_subdirectory(findmyphone)
+    add_subdirectory(telephony)
+
+    if(WIN32)
+        add_subdirectory(mousepad_windows)
+    else()
+        add_subdirectory(runcommand)
+        add_subdirectory(pausemusic)
+        add_subdirectory(mpriscontrol)
+        add_subdirectory(mousepad)
+        add_subdirectory(screensaver-inhibit)
+        add_subdirectory(sftp)
+    endif()
+
+    if(Phonon4Qt5_FOUND)
+        add_subdirectory(findthisdevice)
+    endif()
 endif()
-if(EXPERIMENTALAPP_ENABLED)
+
+if(SAILFISHOS OR EXPERIMENTALAPP_ENABLED)
     add_subdirectory(remotecommands)
     add_subdirectory(mprisremote)
     add_subdirectory(remotecontrol)
diff --git a/plugins/battery/batteryplugin.cpp b/plugins/battery/batteryplugin.cpp
index 3bf8b243..9727a376 100644
--- a/plugins/battery/batteryplugin.cpp
+++ b/plugins/battery/batteryplugin.cpp
@@ -21,6 +21,7 @@
 #include "batteryplugin.h"
 
 #include <QIcon>
+
 #include <KLocalizedString>
 #include <KPluginFactory>
 
@@ -73,7 +74,6 @@ bool BatteryPlugin::receivePacket(const NetworkPacket& np)
 
     if ( thresholdEvent == ThresholdBatteryLow && !isCharging ) {
         Daemon::instance()->sendSimpleNotification(QStringLiteral("batteryLow"), \
i18nc("device name: low battery", "%1: Low Battery", device()->name()), i18n("Battery \
                at %1%", currentCharge), QStringLiteral("battery-040"));
-
     }
 
     return true;
diff --git a/plugins/notifications/notificationsdbusinterface.cpp \
b/plugins/notifications/notificationsdbusinterface.cpp index ec61a53b..a8aa7faa \
                100644
--- a/plugins/notifications/notificationsdbusinterface.cpp
+++ b/plugins/notifications/notificationsdbusinterface.cpp
@@ -30,6 +30,9 @@
 #include "notificationsplugin.h"
 #include "sendreplydialog.h"
 
+//In older Qt released, qAsConst isnt available
+#include "qtcompat_p.h"
+
 NotificationsDbusInterface::NotificationsDbusInterface(KdeConnectPlugin* plugin)
     : QDBusAbstractAdaptor(const_cast<Device*>(plugin->device()))
     , m_device(plugin->device())
@@ -114,9 +117,9 @@ void NotificationsDbusInterface::addNotification(Notification* \
noti)  
     connect(noti, &Notification::dismissRequested,
             this, &NotificationsDbusInterface::dismissRequested);
-    
-    connect(noti, &Notification::replyRequested, this, [this,noti]{ 
-        replyRequested(noti); 
+
+    connect(noti, &Notification::replyRequested, this, [this,noti]{
+        replyRequested(noti);
     });
 
     const QString& publicId = newId();
diff --git a/plugins/pausemusic/pausemusicplugin.cpp \
b/plugins/pausemusic/pausemusicplugin.cpp index 3e68bcf0..ece11317 100644
--- a/plugins/pausemusic/pausemusicplugin.cpp
+++ b/plugins/pausemusic/pausemusicplugin.cpp
@@ -30,6 +30,9 @@
 
 #include <KPluginFactory>
 
+//In older Qt released, qAsConst isnt available
+#include "qtcompat_p.h"
+
 K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_pausemusic.json", \
registerPlugin< PauseMusicPlugin >(); )  
 Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_PAUSEMUSIC, "kdeconnect.plugin.pausemusic")
diff --git a/plugins/sendnotifications/CMakeLists.txt \
b/plugins/sendnotifications/CMakeLists.txt index a6d972d0..b8858ed4 100644
--- a/plugins/sendnotifications/CMakeLists.txt
+++ b/plugins/sendnotifications/CMakeLists.txt
@@ -1,23 +1,33 @@
+if (SAILFISHOS)
+	set(SN_PLUGIN_ENABLED_BY_DEFAULT "true")
+else()
+	set(SN_PLUGIN_ENABLED_BY_DEFAULT "false")
+endif()
+
+configure_file(kdeconnect_sendnotifications.json.in \
kdeconnect_sendnotifications.json) +
 set(kdeconnect_sendnotifications_SRCS
     sendnotificationsplugin.cpp
     notificationslistener.cpp
     notifyingapplication.cpp
+    kdeconnect_sendnotifications.json
 )
 
-kdeconnect_add_plugin(kdeconnect_sendnotifications JSON \
kdeconnect_sendnotifications.json SOURCES ${kdeconnect_sendnotifications_SRCS}) \
+kdeconnect_add_plugin(kdeconnect_sendnotifications JSON \
"${CMAKE_CURRENT_BINARY_DIR}/kdeconnect_sendnotifications.json" SOURCES \
${kdeconnect_sendnotifications_SRCS})  
 target_link_libraries(kdeconnect_sendnotifications
     kdeconnectcore
     Qt5::DBus
-    KF5::Notifications
+    ${NOTIFICATION_LIB}
     KF5::I18n
+    Qt5::Gui
     KF5::IconThemes
     KF5::ConfigCore
 )
 
 #######################################
 # Config
-
+if (NOT SAILFISHOS)
 set( kdeconnect_sendnotifications_config_SRCS
      sendnotifications_config.cpp
      notifyingapplication.cpp
@@ -35,3 +45,4 @@ target_link_libraries( kdeconnect_sendnotifications_config
 
 install( TARGETS kdeconnect_sendnotifications_config DESTINATION \
${PLUGIN_INSTALL_DIR} )  install( FILES kdeconnect_sendnotifications_config.desktop \
DESTINATION ${SERVICES_INSTALL_DIR} ) +endif()
diff --git a/plugins/sendnotifications/kdeconnect_sendnotifications.json \
b/plugins/sendnotifications/kdeconnect_sendnotifications.json.in similarity index 99%
rename from plugins/sendnotifications/kdeconnect_sendnotifications.json
rename to plugins/sendnotifications/kdeconnect_sendnotifications.json.in
index 7c01f178..cbbe3118 100644
--- a/plugins/sendnotifications/kdeconnect_sendnotifications.json
+++ b/plugins/sendnotifications/kdeconnect_sendnotifications.json.in
@@ -45,7 +45,7 @@
         "Description[x-test]": "xxBroadcast this computer's notifications, so they \
                can be shown on other devices.xx",
         "Description[zh_CN]": \
                "广播此计算机的通知,以被其他设备显示。",
         "Description[zh_TW]": \
                "廣播此電腦的通知,這樣可以顯示在其他裝置上。",
-        "EnabledByDefault": false,
+        "EnabledByDefault": ${SN_PLUGIN_ENABLED_BY_DEFAULT},
         "Icon": "preferences-desktop-notification",
         "Id": "kdeconnect_sendnotifications",
         "License": "GPL",
diff --git a/plugins/sendnotifications/notificationslistener.cpp \
b/plugins/sendnotifications/notificationslistener.cpp index c69c20ca..235a5d0a 100644
--- a/plugins/sendnotifications/notificationslistener.cpp
+++ b/plugins/sendnotifications/notificationslistener.cpp
@@ -27,7 +27,6 @@
 #include <QImage>
 #include <KConfig>
 #include <KConfigGroup>
-
 #include <kiconloader.h>
 #include <kicontheme.h>
 
@@ -39,6 +38,9 @@
 #include "sendnotification_debug.h"
 #include "notifyingapplication.h"
 
+//In older Qt released, qAsConst isnt available
+#include "qtcompat_p.h"
+
 NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin)
     : QDBusAbstractAdaptor(aPlugin),
       m_plugin(aPlugin)
@@ -179,6 +181,7 @@ QSharedPointer<QIODevice> \
NotificationsListener::iconForIconName(const QString&  return \
QSharedPointer<QIODevice>(new QFile(iconPath));  return QSharedPointer<QIODevice>();
 }
+
 uint NotificationsListener::Notify(const QString& appName, uint replacesId,
                                    const QString& appIcon,
                                    const QString& summary, const QString& body,
diff --git a/sfos/CMakeLists.txt b/sfos/CMakeLists.txt
new file mode 100644
index 00000000..9ab670da
--- /dev/null
+++ b/sfos/CMakeLists.txt
@@ -0,0 +1,26 @@
+find_package(Qt5 5.2 REQUIRED COMPONENTS DBus)
+
+pkg_check_modules(NNQT5 REQUIRED nemonotifications-qt5)
+include_directories(${NNQT5_INCLUDE_DIRS})
+
+set(kdeconnectsfos_SRCS
+    kdeconnect-sfos.cpp
+)
+
+add_executable(kdeconnect-sfos ${kdeconnectsfos_SRCS})
+target_link_libraries(kdeconnect-sfos Qt5::Quick sailfishapp)
+
+install(TARGETS kdeconnect-sfos ${INSTALL_TARGETS_DEFAULT_ARGS})
+install(PROGRAMS kdeconnect-sfos.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
+INSTALL( DIRECTORY qml DESTINATION ${SHARE_INSTALL_PREFIX}/kdeconnect-sfos/ )
+
+#Daemon
+add_executable(kdeconnectd sailfishdaemon.cpp)
+target_link_libraries(kdeconnectd kdeconnectcore KF5::DBusAddons ${NNQT5_LIBRARIES} \
KF5::I18n) +
+configure_file(kdeconnectd.desktop.cmake \
${CMAKE_CURRENT_BINARY_DIR}/kdeconnectd.desktop) \
+configure_file(org.kde.kdeconnect.service.in \
${CMAKE_CURRENT_BINARY_DIR}/org.kde.kdeconnect.service) +
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kdeconnectd.desktop DESTINATION \
${AUTOSTART_INSTALL_DIR}) +install(FILES \
${CMAKE_CURRENT_BINARY_DIR}/org.kde.kdeconnect.service DESTINATION \
${DBUS_SERVICES_INSTALL_DIR}) +install(TARGETS kdeconnectd DESTINATION \
                ${LIBEXEC_INSTALL_DIR})
diff --git a/sfos/kdeconnect-sfos.cpp b/sfos/kdeconnect-sfos.cpp
new file mode 100644
index 00000000..5e4e9de0
--- /dev/null
+++ b/sfos/kdeconnect-sfos.cpp
@@ -0,0 +1,60 @@
+/*
+  Copyright (C) 2013 Jolla Ltd.
+  Contact: Thomas Perl <thomas.perl@jollamobile.com>
+  All rights reserved.
+
+  You may use this file under the terms of BSD license as follows:
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Jolla Ltd nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef QT_QML_DEBUG
+#include <QtQuick>
+#endif
+
+#include <sailfishapp/sailfishapp.h>
+#include <QGuiApplication>
+#include <QQuickView>
+
+int main(int argc, char *argv[])
+{
+    // SailfishApp::main() will display "qml/kdeconnect-sfos.qml", if you need more
+    // control over initialization, you can use:
+    //
+    //   - SailfishApp::application(int, char *[]) to get the QGuiApplication *
+    //   - SailfishApp::createView() to get a new QQuickView * instance
+    //   - SailfishApp::pathTo(QString) to get a QUrl to a resource file
+    //   - SailfishApp::pathToMainQml() to get a QUrl to the main QML file
+    //
+    // To display the view, call "show()" (will show fullscreen on device).
+
+    //return SailfishApp::main(argc, argv);
+    QGuiApplication *app = SailfishApp::application(argc, argv);
+    QScopedPointer<QQuickView> view(SailfishApp::createView());
+
+    view->setSource(SailfishApp::pathTo("qml/kdeconnect-sfos.qml"));
+    view->showFullScreen();
+
+    return app->exec();
+}
+
diff --git a/sfos/kdeconnect-sfos.desktop b/sfos/kdeconnect-sfos.desktop
new file mode 100644
index 00000000..7ba1133d
--- /dev/null
+++ b/sfos/kdeconnect-sfos.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Type=Application
+X-Nemo-Application-Type=generic
+Icon=kdeconnect
+Exec=kdeconnect-sfos
+Name=KDE Connect
+# translation example:
+# your app name in German locale (de)
+#
+# Remember to comment out the following line, if you do not want to use
+# a different app name in German locale (de).
+#Name[de]=kdeconnect-sfos
diff --git a/sfos/kdeconnectd.desktop.cmake b/sfos/kdeconnectd.desktop.cmake
new file mode 100644
index 00000000..ab93439c
--- /dev/null
+++ b/sfos/kdeconnectd.desktop.cmake
@@ -0,0 +1,47 @@
+[Desktop Entry]
+Type=Application
+Exec=${KDE_INSTALL_FULL_LIBEXECDIR}/kdeconnectd
+X-KDE-StartupNotify=false
+X-KDE-autostart-phase=1
+X-GNOME-Autostart-enabled=true
+OnlyShowIn=KDE;GNOME;Unity;XFCE;
+NoDisplay=true
+
+Name=KDEConnect daemon
+Name[ar]=عفريت KDEConnect
+Name[ast]=Degorriu KDEConnect
+Name[bg]=Услуга KDE Connect
+Name[ca]=Dimoni del KDEConnect
+Name[ca@valencia]=Dimoni del KDEConnect
+Name[cs]=Démon KDE Connect
+Name[da]=KDEConnect-dæmon
+Name[de]=KDE-Connect-Dienst
+Name[el]=Δαίμονας του KDEConnect
+Name[en_GB]=KDEConnect daemon
+Name[es]=Demonio de KDE Connect
+Name[et]=KDEConnecti deemon
+Name[eu]=KDEConnect daimona
+Name[fi]=KDEConnect-taustapalvelu
+Name[fr]=Démon KDE Connect
+Name[gl]=Servizo de KDE Connect
+Name[he]=דמון KDEConnect
+Name[hu]=KDEConnect szolgáltatás
+Name[it]=Demone KDE Connect
+Name[ko]=KDE Connect 데몬
+Name[nl]=KDEConnect-daemon
+Name[nn]=KDEConnect-teneste
+Name[pl]=Usługa KDEConnect
+Name[pt]=Serviço do KDE Connect
+Name[pt_BR]=Serviço do KDE Connect
+Name[ru]=Служба KDE Connect
+Name[sk]=KDEConnect démon
+Name[sr]=КДЕ‑конекцијин демон
+Name[sr@ijekavian]=КДЕ‑конекцијин демон
+Name[sr@ijekavianlatin]=KDE‑konekcijin demon
+Name[sr@latin]=KDE‑konekcijin demon
+Name[sv]=Demon för KDE-anslut
+Name[tr]=KDEConnect süreci
+Name[uk]=Фонова служба KDEConnect
+Name[x-test]=xxKDEConnect daemonxx
+Name[zh_CN]=KDEConnect 守护进程
+Name[zh_TW]=KDE連線作業
diff --git a/sfos/org.kde.kdeconnect.service.in b/sfos/org.kde.kdeconnect.service.in
new file mode 100644
index 00000000..4f747186
--- /dev/null
+++ b/sfos/org.kde.kdeconnect.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.kde.kdeconnect
+Exec=@KDE_INSTALL_FULL_LIBEXECDIR@/kdeconnectd
diff --git a/sfos/qml/cover/CoverPage.qml b/sfos/qml/cover/CoverPage.qml
new file mode 100644
index 00000000..a252225f
--- /dev/null
+++ b/sfos/qml/cover/CoverPage.qml
@@ -0,0 +1,74 @@
+/*
+  Copyright (C) 2013 Jolla Ltd.
+  Contact: Thomas Perl <thomas.perl@jollamobile.com>
+  All rights reserved.
+
+  You may use this file under the terms of BSD license as follows:
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Jolla Ltd nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import org.kde.kdeconnect 1.0
+
+CoverBackground {
+    Label {
+        id: label
+        anchors.top: parent.top
+        anchors.topMargin: Theme.paddingMedium
+        anchors.horizontalCenter: parent.horizontalCenter
+        text: qsTr("KDE Connect")
+    }
+
+    SilicaListView {
+        id: devices
+        anchors.top: label.bottom
+        anchors.margins: Theme.paddingSmall
+        anchors.bottom: parent.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        visible: count > 0
+
+        model: DevicesSortProxyModel {
+                sourceModel: DevicesModel { displayFilter: DevicesModel.Reachable | \
DevicesModel.Paired } +            }
+
+        width: parent.width
+        spacing: Theme.paddingLarge
+
+        delegate: ListItem {
+            width: ListView.view.width
+            height: Theme.itemSizeMedium
+
+            Label { text: display }
+        }
+    }
+    Label {
+        text: qsTr("No paired \ndevices in range")
+        anchors.centerIn: parent
+        visible: devices.count == 0
+    }
+
+}
+
diff --git a/sfos/qml/kdeconnect-sfos.qml b/sfos/qml/kdeconnect-sfos.qml
new file mode 100644
index 00000000..b8a1cf7c
--- /dev/null
+++ b/sfos/qml/kdeconnect-sfos.qml
@@ -0,0 +1,48 @@
+/*
+  Copyright (C) 2013 Jolla Ltd.
+  Contact: Thomas Perl <thomas.perl@jollamobile.com>
+  All rights reserved.
+
+  You may use this file under the terms of BSD license as follows:
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Jolla Ltd nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "pages"
+
+ApplicationWindow
+{
+    initialPage: Component { FirstPage { } }
+    cover: Qt.resolvedUrl("cover/CoverPage.qml")
+    allowedOrientations: defaultAllowedOrientations
+
+    Keys.onPressed: {
+        if (event.key == Qt.Key_Back) {
+            console.log("back");
+            pageStack.pop();
+        }
+    }
+}
+
diff --git a/sfos/qml/pages/DevicePage.qml b/sfos/qml/pages/DevicePage.qml
new file mode 100644
index 00000000..4e5d4c98
--- /dev/null
+++ b/sfos/qml/pages/DevicePage.qml
@@ -0,0 +1,105 @@
+/*
+  Copyright (C) 2013 Jolla Ltd.
+  Contact: Thomas Perl <thomas.perl@jollamobile.com>
+  All rights reserved.
+
+  You may use this file under the terms of BSD license as follows:
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Jolla Ltd nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import org.kde.kdeconnect 1.0
+
+Page {
+    id: deviceView
+    property QtObject currentDevice
+
+    // The effective value will be restricted by \
ApplicationWindow.allowedOrientations +    allowedOrientations: Orientation.Portrait
+
+    Column {
+        id: column
+        anchors.fill: parent
+        spacing: Theme.paddingMedium
+
+        PageHeader {
+            title: currentDevice.name
+        }
+
+        Label {
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: "Device is " + (currentDevice.isTrusted ? "trusted" : "not \
trusted") +        }
+
+        Button {
+            id: text
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: currentDevice.isTrusted ? "Un-Pair" : "Pair"
+
+            onClicked: {
+                if (currentDevice.isTrusted) {
+                    currentDevice.unpair()
+                } else {
+                    currentDevice.requestPair()
+                }
+            }
+        }
+
+        Button {
+            anchors.horizontalCenter: parent.horizontalCenter
+            visible: currentDevice.isTrusted
+            text: qsTr("Ping")
+            onClicked: {
+                currentDevice.pluginCall("ping", "sendPing");
+            }
+        }
+
+        PluginItem {
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: ("Multimedia control")
+            interfaceFactory: MprisDbusInterfaceFactory
+            component: "mpris.qml"
+            pluginName: "mprisremote"
+        }
+        PluginItem {
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: ("Remote input")
+            interfaceFactory: RemoteControlDbusInterfaceFactory
+            component: "mousepad.qml"
+            pluginName: "remotecontrol"
+        }
+        PluginItem {
+            anchors.horizontalCenter: parent.horizontalCenter
+            readonly property var lockIface: \
LockDeviceDbusInterfaceFactory.create(deviceView.currentDevice.id()) +            \
pluginName: "lockdevice" +            text: lockIface.isLocked ? ("Unlock") : \
("Lock") +            onClicked: {
+                lockIface.isLocked = !lockIface.isLocked;
+            }
+        }
+    }
+}
+
+
diff --git a/sfos/qml/pages/FindDevices.qml b/sfos/qml/pages/FindDevices.qml
new file mode 100644
index 00000000..acceb8c4
--- /dev/null
+++ b/sfos/qml/pages/FindDevices.qml
@@ -0,0 +1,77 @@
+/*
+  Copyright (C) 2013 Jolla Ltd.
+  Contact: Thomas Perl <thomas.perl@jollamobile.com>
+  All rights reserved.
+
+  You may use this file under the terms of BSD license as follows:
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Jolla Ltd nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import org.kde.kdeconnect 1.0
+
+Page {
+    id: page
+
+    // The effective value will be restricted by \
ApplicationWindow.allowedOrientations +    allowedOrientations: Orientation.Portrait
+
+    // To enable PullDownMenu, place our content in a SilicaFlickable
+    SilicaListView {
+        anchors.fill: parent
+
+        header: PageHeader {
+            title: qsTr("Devices")
+        }
+
+        // Place our content in a Column.  The PageHeader is always placed at the \
top +        // of the page, followed by our content.
+
+        id: devices
+        model: DevicesModel {
+            id: devicesModel
+        }
+
+        width: page.width
+        spacing: Theme.paddingLarge
+
+
+        delegate: ListItem {
+            width: ListView.view.width
+            height: Theme.itemSizeMedium
+
+            Label { text: display + "\n" + toolTip }
+
+            onClicked: {
+                var devicePage = pageStack.push(Qt.resolvedUrl("DevicePage.qml"),
+                    {currentDevice: device}
+                );
+            }
+
+
+        }
+    }
+}
+
diff --git a/sfos/qml/pages/FirstPage.qml b/sfos/qml/pages/FirstPage.qml
new file mode 100644
index 00000000..fb0624e0
--- /dev/null
+++ b/sfos/qml/pages/FirstPage.qml
@@ -0,0 +1,61 @@
+/*
+Copyright (C) 2013 Jolla Ltd.
+Contact: Thomas Perl <thomas.perl@jollamobile.com>
+All rights reserved.
+
+You may use this file under the terms of BSD license as follows:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    * Neither the name of the Jolla Ltd nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import org.kde.kdeconnect 1.0
+import Nemo.Notifications 1.0
+
+Page {
+    allowedOrientations: Orientation.Portrait
+
+    SilicaFlickable {
+            anchors.fill: parent
+            contentHeight: column.height
+
+            // PullDownMenu and PushUpMenu must be declared in SilicaFlickable, \
SilicaListView or SilicaGridView +            PullDownMenu {
+                MenuItem {
+                    text: qsTr("Find Devices")
+                    onClicked: pageStack.push(Qt.resolvedUrl("FindDevices.qml"))
+                }
+            }
+
+            Column {
+                id: column
+                width: parent.width
+                spacing: 20
+
+                PageHeader { title: "KDE Connect" }
+
+            }
+    }
+}
+
diff --git a/sfos/qml/pages/PluginItem.qml b/sfos/qml/pages/PluginItem.qml
new file mode 100644
index 00000000..fcee5fd1
--- /dev/null
+++ b/sfos/qml/pages/PluginItem.qml
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Aleix Pol Gonzalez <aleixpol@kde.org>
+ *
+ * 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.0
+import Sailfish.Silica 1.0
+import org.kde.kdeconnect 1.0
+
+Button
+{
+    property alias pluginName: checker.pluginName
+    property var interfaceFactory
+    property string component
+
+    readonly property var checker: PluginChecker {
+        id: checker
+        device: deviceView.currentDevice
+    }
+    visible: checker.available
+    onClicked: {
+        if (component === "")
+            return;
+
+        var obj = interfaceFactory.create(deviceView.currentDevice.id());
+        var page = pageStack.push(
+            component,
+            { pluginInterface: obj }
+        );
+        obj.parent = page
+    }
+}
diff --git a/sfos/qml/pages/mousepad.qml b/sfos/qml/pages/mousepad.qml
new file mode 100644
index 00000000..f6c43dd4
--- /dev/null
+++ b/sfos/qml/pages/mousepad.qml
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Aleix Pol Gonzalez <aleixpol@kde.org>
+ *
+ * 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.0
+import Sailfish.Silica 1.0
+import org.kde.kdeconnect 1.0
+
+Page
+{
+    id: mousepad
+    property QtObject pluginInterface
+    backNavigation: false
+
+    Column
+    {
+        anchors.fill: parent
+        PageHeader {
+            id: header
+            title: "Remote Control"
+        }
+        MouseArea {
+            id: area
+            width: parent.width
+            height: parent.height - buttons.height - header.height - 20
+            property var lastPos: Qt.point(-1, -1)
+
+            //onClicked: mousepad.pluginInterface.sendCommand("singleclick", true);
+
+            onPositionChanged: {
+                if (lastPos.x > -1) {
+                    //console.log("move", mouse.x, mouse.y, lastPos)
+                    var delta = Qt.point(mouse.x-lastPos.x, mouse.y-lastPos.y);
+
+                    pluginInterface.moveCursor(delta);
+                }
+                lastPos = Qt.point(mouse.x, mouse.y);
+            }
+            onReleased: {
+                lastPos = Qt.point(-1, -1)
+            }
+        }
+        Row {
+            id: buttons
+            height: childrenRect.height
+            width: parent.width
+
+            Button {
+                width: parent.width / 3
+                text: "Single"
+                onClicked: mousepad.pluginInterface.sendCommand("singleclick", \
true); +            }
+            Button {
+                width: parent.width / 3
+                text: "Middle"
+                onClicked: mousepad.pluginInterface.sendCommand("middleclick", \
true); +            }
+            Button {
+                width: parent.width / 3
+                text: "Right"
+                onClicked: mousepad.pluginInterface.sendCommand("rightclick", true);
+            }
+        }
+    }
+
+   function myPop() {
+        pageStack._pageStackIndicator._backPageIndicator().data[0].clicked.disconnect(myPop)
 +        pageStack.pop()
+    }
+
+    onStatusChanged: {
+        if (status == PageStatus.Active) {
+            pageStack._createPageIndicator()
+            pageStack._pageStackIndicator.clickablePageIndicators = true
+            pageStack._pageStackIndicator._backPageIndicator().backNavigation = true
+            pageStack._pageStackIndicator._backPageIndicator().data[0].clicked.connect(myPop)
 +        } else if (status == PageStatus.Deactivating) {
+            pageStack._pageStackIndicator.clickablePageIndicators = \
Qt.binding(function() { +                return pageStack.currentPage ? \
pageStack.currentPage._clickablePageIndicators : true +            })
+            pageStack._pageStackIndicator._backPageIndicator().backNavigation = \
Qt.binding(function() { +                return pageStack._currentContainer && \
pageStack._currentContainer.page +                       && \
pageStack._currentContainer.page.backNavigation && \
pageStack._currentContainer.pageStackIndex !== 0 +            })
+        }
+}
+
+}
diff --git a/sfos/qml/pages/mpris.qml b/sfos/qml/pages/mpris.qml
new file mode 100644
index 00000000..1b0c7268
--- /dev/null
+++ b/sfos/qml/pages/mpris.qml
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 Aleix Pol Gonzalez <aleixpol@kde.org>
+ *
+ * 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.0
+import Sailfish.Silica 1.0
+import org.kde.kdeconnect 1.0
+
+Page
+{
+    id: root
+    property QtObject pluginInterface
+
+    Column
+    {
+        anchors.fill: parent
+        PageHeader { title: "Multimedia Controls" }
+
+        Component.onCompleted: {
+            pluginInterface.requestPlayerList();
+        }
+
+        Item { height: parent.height }
+        ComboBox {
+            label: "Player"
+            width: parent.width
+            onCurrentIndexChanged: root.pluginInterface.player = value
+
+            menu: ContextMenu {
+                Repeater {
+                    model: root.pluginInterface.playerList
+                    MenuItem { text: modelData }
+                }
+            }
+        }
+        Label {
+            width: parent.width
+            text: root.pluginInterface.nowPlaying
+        }
+        Row {
+            width: parent.width
+            IconButton {
+                icon.source: "image://theme/icon-m-previous"
+                onClicked: root.pluginInterface.sendAction("Previous")
+            }
+            IconButton {
+                icon.source: root.pluginInterface.isPlaying ? \
"icon-m-image://theme/pause" : "image://theme/icon-m-play" +                \
onClicked: root.pluginInterface.sendAction("PlayPause"); +            }
+            IconButton {
+                icon.source: "image://theme/icon-m-next"
+                onClicked: root.pluginInterface.sendAction("Next")
+            }
+        }
+        Row {
+            width: parent.width
+            Label { text: ("Volume:") }
+            Slider {
+                value: root.pluginInterface.volume
+                maximumValue: 100
+                width: parent.width
+            }
+        }
+        Item { height: parent.height }
+    }
+}
diff --git a/sfos/rpm/kdeconnect-sfos.changes.in \
b/sfos/rpm/kdeconnect-sfos.changes.in new file mode 100644
index 00000000..60e402b1
--- /dev/null
+++ b/sfos/rpm/kdeconnect-sfos.changes.in
@@ -0,0 +1,18 @@
+# Rename this file as kdeconnect-sfos.changes to include changelog
+# entries in your RPM file.
+#
+# Add new changelog entries following the format below.
+# Add newest entries to the top of the list.
+# Separate entries from eachother with a blank line.
+#
+# Alternatively, if your changelog is automatically generated (e.g. with
+# the git-change-log command provided with Sailfish OS SDK), create a
+# kdeconnect-sfos.changes.run script to let mb2 run the required commands for you.
+
+# * date Author's Name <author's email> version-release
+# - Summary of changes
+
+* Sun Apr 13 2014 Jack Tar <jack.tar@example.com> 0.0.1-1
+- Scrubbed the deck
+- Hoisted the sails
+
diff --git a/sfos/rpm/kdeconnect-sfos.changes.run.in \
b/sfos/rpm/kdeconnect-sfos.changes.run.in new file mode 100644
index 00000000..90c6facd
--- /dev/null
+++ b/sfos/rpm/kdeconnect-sfos.changes.run.in
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# Rename this file as kdeconnect-sfos.changes.run to let mb2 automatically
+# generate changelog from well formatted Git commit messages and tag
+# annotations.
+
+git-change-log
+
+# Here are some basic examples how to change from the default behavior. Run
+# git-change-log --help inside the Sailfish OS SDK chroot or build engine to
+# learn all the options git-change-log accepts.
+
+# Use a subset of tags
+#git-change-log --tags refs/tags/my-prefix/*
+
+# Group entries by minor revision, suppress headlines for patch-level revisions
+#git-change-log --dense '/[0-9]\+\.[0-9\+$'
+
+# Trim very old changes
+#git-change-log --since 2014-04-01
+#echo '[ Some changelog entries trimmed for brevity ]'
+
+# Use the subjects (first lines) of tag annotations when no entry would be
+# included for a revision otherwise
+#git-change-log --auto-add-annotations
diff --git a/sfos/rpm/kdeconnect-sfos.spec b/sfos/rpm/kdeconnect-sfos.spec
new file mode 100644
index 00000000..e8a880c0
--- /dev/null
+++ b/sfos/rpm/kdeconnect-sfos.spec
@@ -0,0 +1,85 @@
+#
+# Do NOT Edit the Auto-generated Part!
+# Generated by: spectacle version 0.27
+#
+
+Name:       kdeconnect-sfos
+
+# >> macros
+# << macros
+
+Summary:    KDEConnect client for Sailfish
+Version:    0.1
+Release:    1
+Group:      Qt/Qt
+License:    LICENSE
+URL:        http://example.org/
+Source0:    %{name}-%{version}.tar.bz2
+Source100:  kdeconnect-sfos.yaml
+Requires:   sailfishsilica-qt5 >= 0.10.9
+BuildRequires:  pkgconfig(sailfishapp) >= 1.0.2
+BuildRequires:  pkgconfig(Qt5Core)
+BuildRequires:  pkgconfig(Qt5Qml)
+BuildRequires:  pkgconfig(Qt5Quick)
+BuildRequires:  pkgconfig(nemonotifications-qt5)
+BuildRequires:  pkgconfig(qca2-qt5) >= 2.0.0
+BuildRequires:  desktop-file-utils
+BuildRequires:  cmake >= 3.0
+BuildRequires:  extra-cmake-modules >= 5.31.0
+BuildRequires:  kcoreaddons-devel >= 5.31.0
+BuildRequires:  kdbusaddons-devel >= 5.31.0
+BuildRequires:  ki18n-devel >= 5.31.0
+BuildRequires:  kconfig-devel >= 5.31.0
+BuildRequires:  kiconthemes-devel >= 5.31.0
+
+%description
+Short description of my Sailfish OS Application
+
+
+%prep
+%setup -q
+
+# >> setup
+# << setup
+
+%build
+# >> build pre
+# << build pre
+mkdir -p build
+cd build
+%cmake  .. -DSAILFISHOS=YES
+make %{?jobs:-j%jobs}
+
+# >> build post
+# << build post
+
+%install
+rm -rf %{buildroot}
+# >> install pre
+# << install pre
+pushd build
+%make_install
+popd
+
+
+# >> install post
+# << install post
+
+desktop-file-install --delete-original       \
+  --dir %{buildroot}%{_datadir}/applications             \
+   %{buildroot}%{_datadir}/applications/*.desktop
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}
+%{_libdir}
+%{_datadir}/%{name}
+%{_datadir}/applications/%{name}.desktop
+/etc/xdg/autostart/kdeconnectd.desktop
+/usr/share/dbus-1/services/org.kde.kdeconnect.service
+/usr/share/knotifications5/kdeconnect.notifyrc
+/usr/share/kservicetypes5/kdeconnect_plugin.desktop
+#%{_datadir}/icons/hicolor/*/apps/%{name}.png
+/usr/share/icons/
+# >> files
+# << files
diff --git a/sfos/sailfishdaemon.cpp b/sfos/sailfishdaemon.cpp
new file mode 100644
index 00000000..da25896c
--- /dev/null
+++ b/sfos/sailfishdaemon.cpp
@@ -0,0 +1,116 @@
+/**
+ * Copyright 2018 Adam Pigg <adam@piggz.co.uk>
+ *
+ * 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 <QCoreApplication>
+#include <QNetworkAccessManager>
+
+#include <KDBusService>
+#include <KLocalizedString>
+
+#include "core/daemon.h"
+#include "core/device.h"
+#include "core/backends/pairinghandler.h"
+#include "kdeconnect-version.h"
+
+#include <notification.h>
+
+class SailfishDaemon : public Daemon
+{
+    Q_OBJECT
+    Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.daemon")
+public:
+    SailfishDaemon(QObject* parent = Q_NULLPTR)
+        : Daemon(parent)
+        , m_nam(Q_NULLPTR)
+    {}
+
+    void askPairingConfirmation(Device* device) override
+    {
+        qDebug() << "Pairing request from " << device->name().toHtmlEscaped();
+
+        Notification *notification = new Notification(this);
+
+        notification->setAppName(QCoreApplication::applicationName());
+        notification->setPreviewSummary(i18n("Pairing request from %1", \
device->name().toHtmlEscaped())); +        notification->setPreviewBody(i18n("Click \
here to pair")); +        notification->setIcon("icon-s-sync");
+        notification->setExpireTimeout(10000);
+
+        connect(notification, &Notification::closed,
+                [=]( uint reason ) {
+                    qDebug() << "Notification closed" << reason;
+                    if (reason == 2) { //clicked
+                        device->acceptPairing();
+                    } else {
+                        device->rejectPairing();
+                    }
+                });
+
+        notification->publish();
+    }
+
+    void reportError(const QString & title, const QString & description) override
+    {
+        qDebug() << "Error:  " << title << ":" << description;
+    }
+
+    QNetworkAccessManager* networkAccessManager() override
+    {
+        if (!m_nam) {
+            m_nam = new QNetworkAccessManager(this);
+        }
+        return m_nam;
+    }
+
+       void sendSimpleNotification(const QString &eventId, const QString &title, \
const QString &text, const QString &iconName) override +    {
+        Q_UNUSED(eventId);
+        Notification *notification = new Notification(this);
+
+        notification->setAppName(QCoreApplication::applicationName());
+        notification->setPreviewSummary(title);
+        notification->setPreviewBody(text);
+        notification->setIcon(iconName);
+        notification->publish();
+    }
+
+
+private:
+    QNetworkAccessManager* m_nam;
+};
+
+int main(int argc, char* argv[])
+{
+    QCoreApplication app(argc, argv);
+
+    app.setApplicationName(QStringLiteral("kdeconnectd"));
+    app.setApplicationVersion(QStringLiteral(KDECONNECT_VERSION_STRING));
+    app.setOrganizationDomain(QStringLiteral("kde.org"));
+
+    KDBusService dbusService(KDBusService::Unique);
+
+    Daemon* daemon = new SailfishDaemon;
+
+    QObject::connect(daemon, SIGNAL(destroyed(QObject*)), &app, SLOT(quit()));
+
+    return app.exec();
+}
+
+#include "sailfishdaemon.moc"


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic