summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--po/de.po39
-rw-r--r--po/en_GB.po40
-rw-r--r--po/eu.po33
-rw-r--r--po/fr.po93
-rw-r--r--po/hu.po34
-rw-r--r--po/it.po121
-rw-r--r--po/pt.po83
-rw-r--r--po/rockwork.mzanetti.pot25
-rw-r--r--po/ru.po31
-rw-r--r--po/template.pot25
-rw-r--r--rockpool.pro14
-rw-r--r--rockpool.pro.user407
-rw-r--r--rockwork.pro.user407
-rw-r--r--rockwork/AppStorePage.qml266
-rw-r--r--rockwork/InstalledAppDelegate.qml88
-rw-r--r--rockwork/InstalledAppsPage.qml201
-rw-r--r--rockwork/MainMenuPage.qml317
-rw-r--r--rockwork/PebbleModels.qml28
-rw-r--r--rockwork/artwork/back-cover.pngbin0 -> 1939 bytes
-rw-r--r--rockwork/artwork/rockwork.svg275
-rw-r--r--rockwork/main.cpp36
-rw-r--r--rockwork/qml/AppSettingsPage.qml (renamed from rockwork/AppSettingsPage.qml)6
-rw-r--r--rockwork/qml/AppStoreDetailsPage.qml (renamed from rockwork/AppStoreDetailsPage.qml)6
-rw-r--r--rockwork/qml/AppStorePage.qml268
-rw-r--r--rockwork/qml/ContentPeerPickerPage.qml (renamed from rockwork/ContentPeerPickerPage.qml)7
-rw-r--r--rockwork/qml/CoverPage.qml44
-rw-r--r--rockwork/qml/DeveloperToolsPage.qml (renamed from rockwork/DeveloperToolsPage.qml)8
-rw-r--r--rockwork/qml/FirmwareUpgradePage.qml (renamed from rockwork/FirmwareUpgradePage.qml)4
-rw-r--r--rockwork/qml/HealthSettingsDialog.qml (renamed from rockwork/HealthSettingsDialog.qml)8
-rw-r--r--rockwork/qml/ImportPackagePage.qml (renamed from rockwork/ImportPackagePage.qml)6
-rw-r--r--rockwork/qml/InfoPage.qml84
-rw-r--r--rockwork/qml/InstalledAppDelegate.qml78
-rw-r--r--rockwork/qml/InstalledAppsPage.qml205
-rw-r--r--rockwork/qml/Main.qml45
-rw-r--r--rockwork/qml/MainMenuPage.qml292
-rw-r--r--rockwork/qml/NotificationsPage.qml99
-rw-r--r--rockwork/qml/PebbleModels.qml28
-rw-r--r--rockwork/qml/PebblesPage.qml (renamed from rockwork/PebblesPage.qml)6
-rw-r--r--rockwork/qml/ScreenshotsPage.qml (renamed from rockwork/ScreenshotsPage.qml)9
-rw-r--r--rockwork/qml/SettingsPage.qml (renamed from rockwork/SettingsPage.qml)7
-rw-r--r--rockwork/qml/SystemAppIcon.qml (renamed from rockwork/SystemAppIcon.qml)30
-rw-r--r--rockwork/rockpool.desktop7
-rw-r--r--rockwork/rockpool.pngbin0 -> 5507 bytes
-rw-r--r--rockwork/rockwork.apparmor7
-rw-r--r--rockwork/rockwork.desktop8
-rw-r--r--rockwork/rockwork.pro126
-rw-r--r--rockwork/rockwork.qrc23
-rw-r--r--rockwork/rockwork.svg275
-rw-r--r--rockwork/rockwork.url-dispatcher5
-rw-r--r--rockwork/servicecontrol.cpp133
-rw-r--r--rockwork/servicecontrol.h23
-rw-r--r--rockwork/snowywhite.pngbin14213 -> 0 bytes
-rw-r--r--rockwork/snowywhite.svg241
-rw-r--r--rockworkd/core.cpp4
-rw-r--r--rockworkd/jsfiles.qrc2
-rw-r--r--rockworkd/libpebble/bluez/bluezclient.cpp87
-rw-r--r--rockworkd/libpebble/bluez/bluezclient.h11
-rw-r--r--rockworkd/libpebble/bluez/device.cpp498
-rw-r--r--rockworkd/libpebble/bluez/device.h172
-rw-r--r--rockworkd/libpebble/jskit/typedarray.js61
-rw-r--r--rockworkd/libpebble/pebble.cpp2
-rw-r--r--rockworkd/libpebble/watchconnection.cpp18
-rw-r--r--rockworkd/pebblemanager.cpp8
-rw-r--r--rockworkd/platformintegration/sailfish/callchannelobserver.cpp166
-rw-r--r--rockworkd/platformintegration/sailfish/callchannelobserver.h74
-rw-r--r--rockworkd/platformintegration/sailfish/organizeradapter.cpp97
-rw-r--r--rockworkd/platformintegration/sailfish/organizeradapter.h44
-rw-r--r--rockworkd/platformintegration/sailfish/sailfishplatform.cpp313
-rw-r--r--rockworkd/platformintegration/sailfish/sailfishplatform.h58
-rw-r--r--rockworkd/platformintegration/sailfish/syncmonitorclient.cpp100
-rw-r--r--rockworkd/platformintegration/sailfish/syncmonitorclient.h51
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallhandler.cpp372
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallhandler.h96
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallmanager.cpp315
-rw-r--r--rockworkd/platformintegration/sailfish/voicecallmanager.h111
-rw-r--r--rockworkd/rockpoold.service11
-rw-r--r--rockworkd/rockworkd.pro145
-rw-r--r--rpm/rockpool.changes2
-rw-r--r--rpm/rockpool.spec97
-rw-r--r--rpm/rockpool.yaml43
80 files changed, 5440 insertions, 2169 deletions
diff --git a/po/de.po b/po/de.po
index 2b6a02d..aa8956d 100644
--- a/po/de.po
+++ b/po/de.po
@@ -6,17 +6,28 @@
msgid ""
msgstr ""
"Project-Id-Version: rockwork\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+"PO-Revision-Date: 2016-01-12 09:52+0000\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
"PO-Revision-Date: 2016-02-15 06:05+0000\n"
+>>>>>>> refs/heads/rockwork
"Last-Translator: Michael Zanetti <michael.zanetti@canonical.com>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-16 05:44+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: de\n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -58,7 +69,7 @@ msgstr "Neue App hinzufügen"
msgid "Add new watchface"
msgstr "Neues Ziffernblatt hinzufügen"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "Alle anzeigen"
@@ -76,25 +87,38 @@ msgstr "Bildschirmfotos"
msgid "Report problem"
msgstr "Fehler berichten"
+<<<<<<< HEAD
+=======
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
msgid "Install app or watchface from file"
msgstr "App oder Watchface aus datei installieren"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr "Bereite Logs vor..."
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
+<<<<<<< HEAD
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
+msgstr ""
+=======
msgid "pebble.log"
msgstr "pebble.log"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "rockworkd.log senden"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
msgid "rockworkd.log"
msgstr "rockworkd.log"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
@@ -112,8 +136,13 @@ msgid "Firmware upgrade"
msgstr "Software updaten"
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
+<<<<<<< HEAD
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
+msgstr ""
+=======
msgid "A new firmware upgrade is available for your Pebble smartwatch."
msgstr "Eine neue Software für Ihre Pebble Uhr steht zur Verfügung."
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
#, qt-format
@@ -183,10 +212,13 @@ msgstr "Ich möchte mehr schlafen"
msgid "OK"
msgstr "OK"
+<<<<<<< HEAD
+=======
#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
msgid "Import watchapp or watchface"
msgstr "Watchapp oder Watchface importieren"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
@@ -242,8 +274,13 @@ msgid "Loading..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
+<<<<<<< HEAD
+msgid "Info"
+msgstr ""
+=======
msgid "About"
msgstr "Über"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
msgid "Developer tools"
diff --git a/po/en_GB.po b/po/en_GB.po
index 0d69af1..2a022a8 100644
--- a/po/en_GB.po
+++ b/po/en_GB.po
@@ -6,17 +6,29 @@
msgid ""
msgstr ""
"Project-Id-Version: rockwork\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+"PO-Revision-Date: 2016-01-26 18:00+0000\n"
+"Last-Translator: Emanuele Antonio Faraone <emanueleant03@gmail.com>\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
"PO-Revision-Date: 2016-02-15 08:54+0000\n"
"Last-Translator: Adrian Chiang <Unknown>\n"
+>>>>>>> refs/heads/rockwork
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-16 05:44+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: \n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -58,7 +70,7 @@ msgstr "Add new watchapp"
msgid "Add new watchface"
msgstr "Add new watchface"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "See all"
@@ -76,25 +88,38 @@ msgstr "Screenshots"
msgid "Report problem"
msgstr "Report problem"
+<<<<<<< HEAD
+=======
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
msgid "Install app or watchface from file"
msgstr "Install app or watchface from file"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr "Preparing logs package..."
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
+<<<<<<< HEAD
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
+msgstr ""
+=======
msgid "pebble.log"
msgstr "pebble.log"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Send rockworkd.log"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
msgid "rockworkd.log"
msgstr "rockworkd.log"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
@@ -112,8 +137,13 @@ msgid "Firmware upgrade"
msgstr "Firmware upgrade"
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
+<<<<<<< HEAD
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
+msgstr ""
+=======
msgid "A new firmware upgrade is available for your Pebble smartwatch."
msgstr "A new firmware upgrade is available for your Pebble smartwatch."
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
#, qt-format
@@ -182,10 +212,13 @@ msgstr "I want to sleep more"
msgid "OK"
msgstr "OK"
+<<<<<<< HEAD
+=======
#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
msgid "Import watchapp or watchface"
msgstr "Import watchapp or watchface"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
@@ -241,8 +274,13 @@ msgid "Loading..."
msgstr "Loading..."
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
+<<<<<<< HEAD
+msgid "Info"
+msgstr ""
+=======
msgid "About"
msgstr "About"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
msgid "Developer tools"
diff --git a/po/eu.po b/po/eu.po
index ec328ed..b7c9dcf 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -6,17 +6,27 @@
msgid ""
msgstr ""
"Project-Id-Version: rockwork\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
+>>>>>>> refs/heads/rockwork
"PO-Revision-Date: 2016-02-03 22:34+0000\n"
"Last-Translator: Aitzol Berasategi <aitzol76@gmail.com>\n"
"Language-Team: Basque <eu@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-15 05:44+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: eu\n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -58,7 +68,7 @@ msgstr "Watchapp berria gehitu"
msgid "Add new watchface"
msgstr "Watchface berria gehitu"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "Guztiak ikusi"
@@ -76,26 +86,19 @@ msgstr "Pantaila-argazkiak"
msgid "Report problem"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
-msgid "Install app or watchface from file"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
-msgid "pebble.log"
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
msgstr ""
@@ -112,7 +115,11 @@ msgid "Firmware upgrade"
msgstr "Firmware eguneraketa"
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
+<<<<<<< HEAD
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
+=======
msgid "A new firmware upgrade is available for your Pebble smartwatch."
+>>>>>>> refs/heads/rockwork
msgstr ""
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
@@ -182,10 +189,6 @@ msgstr ""
msgid "OK"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
-msgid "Import watchapp or watchface"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
@@ -239,7 +242,7 @@ msgid "Loading..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
-msgid "About"
+msgid "Info"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
diff --git a/po/fr.po b/po/fr.po
index 0f95bd5..b069940 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -6,17 +6,28 @@
msgid ""
msgstr ""
"Project-Id-Version: upebble\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+"PO-Revision-Date: 2016-02-07 15:41+0000\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
"PO-Revision-Date: 2016-02-15 06:05+0000\n"
+>>>>>>> refs/heads/rockwork
"Last-Translator: Anne <anneonyme017@gmail.com>\n"
"Language-Team: French <fr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-16 05:44+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: fr\n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -56,15 +67,15 @@ msgstr "Ajouter une nouvelle application pour montre"
#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:8
msgid "Add new watchface"
-msgstr "Ajouter une nouveau cadran"
+msgstr "Ajouter un nouveau thème de montre"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "Tout voir"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:9
msgid "Developer Tools"
-msgstr "Outils pour développeurs"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:28
#: /home/micha/Develop/upebble/rockwork/ScreenshotsPage.qml:11
@@ -74,27 +85,33 @@ msgstr "Captures d'écran"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:35
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:102
msgid "Report problem"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Signaler un problème"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
msgid "Install app or watchface from file"
msgstr "Installer une application ou un cadran à partir d'un fichier"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr "Préparation de l'ensemble des rapports…"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
+<<<<<<< HEAD
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
+msgstr ""
+=======
msgid "pebble.log"
msgstr "pebble.log"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
-msgstr "Envoi de rockworkd.log"
-
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr "rockworkd.log"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
@@ -112,7 +129,11 @@ msgid "Firmware upgrade"
msgstr "Mise à niveau du micrologiciel"
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
+<<<<<<< HEAD
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
+=======
msgid "A new firmware upgrade is available for your Pebble smartwatch."
+>>>>>>> refs/heads/rockwork
msgstr ""
"Une nouvelle mise à niveau du micrologiciel est disponible pour votre montre "
"connectée Pebble."
@@ -147,27 +168,31 @@ msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:9
msgid "Health settings"
-msgstr "Paramètre de Bien-Être"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:17
msgid "Health app enabled"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "L'application Bien-Être est activée"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:28
msgid "Female"
-msgstr "Femme"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:28
msgid "Male"
-msgstr "Homme"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:34
msgid "Age"
-msgstr "Âge"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:47
msgid "Height (cm)"
-msgstr "Taille (cm):"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:60
msgid "Weight"
@@ -183,20 +208,31 @@ msgstr "Je veux dormir plus"
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:95
msgid "OK"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Valider"
#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
msgid "Import watchapp or watchface"
msgstr "Importer une application ou un cadran"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
-msgstr "Version %1"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:40
+<<<<<<< HEAD
+msgid "Contributors"
+msgstr ""
+
+#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:52
+=======
+>>>>>>> refs/heads/rockwork
msgid "Legal"
-msgstr "Informations légales"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:62
msgid ""
@@ -212,7 +248,7 @@ msgstr "Pebble est une marque déposée par Pebble Technology Corp."
#: /home/micha/Develop/upebble/rockwork/InstalledAppsPage.qml:9
msgid "Apps & Watchfaces"
-msgstr "Applications & Cadrans"
+msgstr "Applications & thèmes de montre"
#: /home/micha/Develop/upebble/rockwork/InstalledAppsPage.qml:9
msgid "Apps"
@@ -220,7 +256,7 @@ msgstr "Applications"
#: /home/micha/Develop/upebble/rockwork/InstalledAppsPage.qml:9
msgid "Watchfaces"
-msgstr "Cadrans"
+msgstr "Thèmes de montre"
#: /home/micha/Develop/upebble/rockwork/InstalledAppsPage.qml:167
msgid "Launch"
@@ -244,12 +280,17 @@ msgid "Loading..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
+<<<<<<< HEAD
+msgid "Info"
+msgstr ""
+=======
msgid "About"
msgstr "À propos"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
msgid "Developer tools"
-msgstr "Outils de développement"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:52
msgid "Manage notifications"
@@ -261,12 +302,12 @@ msgstr "Gérer les applications"
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:67
msgid "Manage Watchfaces"
-msgstr "Gérer les cadrans"
+msgstr "Gérer les thèmes de montre"
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:75
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:8
msgid "Settings"
-msgstr "Paramètres"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:190
#: /home/micha/Develop/upebble/rockwork/PebblesPage.qml:36
@@ -351,20 +392,24 @@ msgstr "Enregistrer"
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:19
msgid "Distance Units"
-msgstr "Unités de Distance"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:35
msgid "Metric"
-msgstr "Métrique"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:48
msgid "Imperial"
-msgstr "Impérial"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:55
msgid "Calendar"
-msgstr "Agenda"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:62
msgid "Sync calendar to timeline"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Synchroniser l'agenda sur la Timeline."
+>>>>>>> refs/heads/rockwork
diff --git a/po/hu.po b/po/hu.po
index 2cdae4e..968cd20 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -6,17 +6,27 @@
msgid ""
msgstr ""
"Project-Id-Version: rockwork\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
+>>>>>>> refs/heads/rockwork
"PO-Revision-Date: 2016-02-02 09:30+0000\n"
"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
"Language-Team: Hungarian <hu@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-15 05:44+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: hu\n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -58,7 +68,7 @@ msgstr "Új alkalmazás hozzáadása"
msgid "Add new watchface"
msgstr "Új számlap hozzáadása"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "Összes"
@@ -76,26 +86,19 @@ msgstr "Képernyőképek"
msgid "Report problem"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
-msgid "Install app or watchface from file"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
-msgid "pebble.log"
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
msgstr ""
@@ -112,8 +115,13 @@ msgid "Firmware upgrade"
msgstr "Firmware frissítés"
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
+<<<<<<< HEAD
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
+msgstr "Egy új firmware frissítés érhető el a Pebble okosórájához"
+=======
msgid "A new firmware upgrade is available for your Pebble smartwatch."
msgstr ""
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
#, qt-format
@@ -182,10 +190,6 @@ msgstr ""
msgid "OK"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
-msgid "Import watchapp or watchface"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
@@ -239,7 +243,7 @@ msgid "Loading..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
-msgid "About"
+msgid "Info"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
diff --git a/po/it.po b/po/it.po
index 83e53d4..2f9b978 100644
--- a/po/it.po
+++ b/po/it.po
@@ -6,17 +6,29 @@
msgid ""
msgstr ""
"Project-Id-Version: upebble\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+"PO-Revision-Date: 2016-02-02 06:06+0000\n"
+"Last-Translator: Emanuele Antonio Faraone <emanueleant03@gmail.com>\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
"PO-Revision-Date: 2016-02-15 12:21+0000\n"
"Last-Translator: Marco Trevisan (Treviño) <mail@3v1n0.net>\n"
+>>>>>>> refs/heads/rockwork
"Language-Team: Italian <it@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-16 05:44+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: it\n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -58,13 +70,17 @@ msgstr "Aggiungi Watchapp"
msgid "Add new watchface"
msgstr "Aggiungi Watchface"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "Mostra tutto"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:9
msgid "Developer Tools"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Strumenti per sviluppatori"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:28
#: /home/micha/Develop/upebble/rockwork/ScreenshotsPage.qml:11
@@ -74,31 +90,45 @@ msgstr "Screenshot"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:35
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:102
msgid "Report problem"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Riporta un problema"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
msgid "Install app or watchface from file"
msgstr "Installa app o watchface da file"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Preparazione del pacchetto di log..."
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
+<<<<<<< HEAD
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
+msgstr ""
+=======
msgid "pebble.log"
msgstr "pebble.log"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
-msgstr "Invia rockworkd.log"
-
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr "rockworkd.log"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Invia log dell'orologio"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:146
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:110
@@ -112,9 +142,14 @@ msgid "Firmware upgrade"
msgstr "Aggiornamento Firmware"
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
+<<<<<<< HEAD
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
+msgstr "Un nuovo aggiornamento del firmware è disponibile per il tuo Pebble."
+=======
msgid "A new firmware upgrade is available for your Pebble smartwatch."
msgstr ""
"Un nuovo aggiornamento firmware è disponibile per il tuo Smartwatch Pebble"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
#, qt-format
@@ -145,68 +180,98 @@ msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:9
msgid "Health settings"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Impostazioni Health"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:17
msgid "Health app enabled"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "App Health attiva"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:28
msgid "Female"
-msgstr "Femmina"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:28
msgid "Male"
-msgstr "Maschio"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:34
msgid "Age"
-msgstr "Età"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:47
msgid "Height (cm)"
-msgstr "Altezza (cm)"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:60
msgid "Weight"
-msgstr "Peso"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:73
msgid "I want to be more active"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Vorrei essere più attivo"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:84
msgid "I want to sleep more"
-msgstr "Vorrei dormire di più"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:95
msgid "OK"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "OK"
#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
msgid "Import watchapp or watchface"
msgstr "Importa una app o una watchface"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
-msgstr "Versione %1"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:40
+<<<<<<< HEAD
+msgid "Contributors"
+msgstr ""
+
+#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:52
+=======
+>>>>>>> refs/heads/rockwork
msgid "Legal"
-msgstr "Note legali"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:62
msgid ""
"This application is neither affiliated with nor endorsed by Pebble "
"Technology Corp."
msgstr ""
+<<<<<<< HEAD
+=======
"Questa applicazione non è né affiliata né supportata da Pebble Techology "
"Corp."
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:67
msgid "Pebble is a trademark of Pebble Technology Corp."
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Pebble è un marchio registrato di Pebble Technology Corp."
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/InstalledAppsPage.qml:9
msgid "Apps & Watchfaces"
@@ -242,12 +307,17 @@ msgid "Loading..."
msgstr "Caricamento..."
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
+<<<<<<< HEAD
+msgid "Info"
+msgstr ""
+=======
msgid "About"
msgstr "Informazioni su..."
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
msgid "Developer tools"
-msgstr "Strumenti per sviluppatori"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:52
msgid "Manage notifications"
@@ -264,7 +334,7 @@ msgstr "Gestisci le Watchfaces"
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:75
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:8
msgid "Settings"
-msgstr "Impostazioni"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:190
#: /home/micha/Develop/upebble/rockwork/PebblesPage.qml:36
@@ -293,7 +363,12 @@ msgstr "Apri Impostazioni"
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:221
msgid ""
"Your Pebble smartwatch is in factory mode and needs to be initialized."
+<<<<<<< HEAD
+msgstr ""
+"Il tuo Pebble è in modalitá di fabbrica e sta per essere inizializzato"
+=======
msgstr "Il tuo Pebble è in modalità di fabbrica e deve essere inizializzato."
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:230
msgid "Initialize Pebble"
@@ -347,20 +422,28 @@ msgstr "Salva"
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:19
msgid "Distance Units"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Unità di misura distanza"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:35
msgid "Metric"
-msgstr "Metrica"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:48
msgid "Imperial"
-msgstr "Imperiale"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:55
msgid "Calendar"
-msgstr "Calendario"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:62
msgid "Sync calendar to timeline"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Sincronizza calendario con la timeline"
+>>>>>>> refs/heads/rockwork
diff --git a/po/pt.po b/po/pt.po
index bcacaff..cf5fcd2 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -6,17 +6,28 @@
msgid ""
msgstr ""
"Project-Id-Version: upebble\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+"PO-Revision-Date: 2016-02-05 15:12+0000\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
"PO-Revision-Date: 2016-02-16 15:41+0000\n"
+>>>>>>> refs/heads/rockwork
"Last-Translator: Vitor Loureiro <Unknown>\n"
"Language-Team: Portuguese <pt@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-17 05:49+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: pt\n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -58,13 +69,13 @@ msgstr "Adicionar nova watchapp"
msgid "Add new watchface"
msgstr "Adicionar nova watchface"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "Ver todos"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:9
msgid "Developer Tools"
-msgstr "Ferramentas de Desenvolvimento"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:28
#: /home/micha/Develop/upebble/rockwork/ScreenshotsPage.qml:11
@@ -74,31 +85,37 @@ msgstr "Capturas de ecrã"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:35
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:102
msgid "Report problem"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "Reportar problema"
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
msgid "Install app or watchface from file"
msgstr "Instalar app ou watchface de arquivo"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr "A preparar pacote de logs..."
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
+<<<<<<< HEAD
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
+msgstr ""
+=======
msgid "pebble.log"
msgstr "pebble.log"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
-msgstr "Enviar rockworkd.log"
-
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr "rockworkd.log"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
-msgstr "Enviar logs do relógio"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:146
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:110
@@ -112,7 +129,11 @@ msgid "Firmware upgrade"
msgstr "Atualização do firmware"
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
+<<<<<<< HEAD
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
+=======
msgid "A new firmware upgrade is available for your Pebble smartwatch."
+>>>>>>> refs/heads/rockwork
msgstr ""
"Um novo upgrade de firmware está disponível para o seu Pebble smartwatch."
@@ -153,48 +174,59 @@ msgstr "Aplicação Health ativada"
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:28
msgid "Female"
-msgstr "Feminino"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:28
msgid "Male"
-msgstr "Masculino"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:34
msgid "Age"
-msgstr "Idade"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:47
msgid "Height (cm)"
-msgstr "Altura (cm)"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:60
msgid "Weight"
-msgstr "Peso"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:73
msgid "I want to be more active"
-msgstr "Eu quero ser mais ativo"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:84
msgid "I want to sleep more"
-msgstr "Eu quero dormir mais"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/HealthSettingsDialog.qml:95
msgid "OK"
+<<<<<<< HEAD
+msgstr ""
+=======
msgstr "OK"
#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
msgid "Import watchapp or watchface"
msgstr "Importar watchapp ou watchface"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
-msgstr "Versão %1"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:40
+<<<<<<< HEAD
+msgid "Contributors"
+msgstr ""
+
+#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:52
+=======
+>>>>>>> refs/heads/rockwork
msgid "Legal"
-msgstr "Legal"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:62
msgid ""
@@ -205,7 +237,7 @@ msgstr ""
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:67
msgid "Pebble is a trademark of Pebble Technology Corp."
-msgstr "Pebble é uma marca comercial da Pebble Technology Corp."
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/InstalledAppsPage.qml:9
msgid "Apps & Watchfaces"
@@ -241,12 +273,17 @@ msgid "Loading..."
msgstr "A carregar..."
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
+<<<<<<< HEAD
+msgid "Info"
+msgstr ""
+=======
msgid "About"
msgstr "Acerca"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
msgid "Developer tools"
-msgstr "Ferramentas do programador"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:52
msgid "Manage notifications"
@@ -263,7 +300,7 @@ msgstr "Gerir watchfaces"
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:75
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:8
msgid "Settings"
-msgstr "Configurações"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:190
#: /home/micha/Develop/upebble/rockwork/PebblesPage.qml:36
@@ -346,15 +383,15 @@ msgstr "Guardar"
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:19
msgid "Distance Units"
-msgstr "Unidades de distância"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:35
msgid "Metric"
-msgstr "Métrica"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:48
msgid "Imperial"
-msgstr "Imperial"
+msgstr ""
#: /home/micha/Develop/upebble/rockwork/SettingsPage.qml:55
msgid "Calendar"
diff --git a/po/rockwork.mzanetti.pot b/po/rockwork.mzanetti.pot
index 6017fa8..a783b9a 100644
--- a/po/rockwork.mzanetti.pot
+++ b/po/rockwork.mzanetti.pot
@@ -8,7 +8,11 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
+<<<<<<< HEAD
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+=======
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
+>>>>>>> refs/heads/rockwork
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -57,7 +61,7 @@ msgstr ""
msgid "Add new watchface"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr ""
@@ -75,26 +79,19 @@ msgstr ""
msgid "Report problem"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
-msgid "Install app or watchface from file"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
-msgid "pebble.log"
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
msgstr ""
@@ -111,7 +108,7 @@ msgid "Firmware upgrade"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
-msgid "A new firmware upgrade is available for your Pebble smartwatch."
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
@@ -179,10 +176,6 @@ msgstr ""
msgid "OK"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
-msgid "Import watchapp or watchface"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
@@ -236,7 +229,7 @@ msgid "Loading..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
-msgid "About"
+msgid "Info"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
diff --git a/po/ru.po b/po/ru.po
index c3576f5..0a7628d 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -6,17 +6,27 @@
msgid ""
msgstr ""
"Project-Id-Version: rockwork\n"
+<<<<<<< HEAD
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+=======
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
+>>>>>>> refs/heads/rockwork
"PO-Revision-Date: 2016-01-23 13:33+0000\n"
"Last-Translator: Eugene Marshal <Unknown>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+<<<<<<< HEAD
+"X-Launchpad-Export-Date: 2016-02-08 05:41+0000\n"
+"X-Generator: Launchpad (build 17908)\n"
+=======
"X-Launchpad-Export-Date: 2016-02-15 05:44+0000\n"
"X-Generator: Launchpad (build 17925)\n"
"Language: ru\n"
+>>>>>>> refs/heads/rockwork
#: /home/micha/Develop/upebble/rockwork/AppSettingsPage.qml:13
msgid "App Settings"
@@ -58,7 +68,7 @@ msgstr "Добавить приложение"
msgid "Add new watchface"
msgstr "Добавить циферблат"
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr "См. все"
@@ -76,26 +86,19 @@ msgstr "Снимки экрана"
msgid "Report problem"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
-msgid "Install app or watchface from file"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
-msgid "pebble.log"
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
msgstr ""
@@ -112,7 +115,7 @@ msgid "Firmware upgrade"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
-msgid "A new firmware upgrade is available for your Pebble smartwatch."
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
@@ -180,10 +183,6 @@ msgstr ""
msgid "OK"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
-msgid "Import watchapp or watchface"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
@@ -237,7 +236,7 @@ msgid "Loading..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
-msgid "About"
+msgid "Info"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
diff --git a/po/template.pot b/po/template.pot
index 6017fa8..a783b9a 100644
--- a/po/template.pot
+++ b/po/template.pot
@@ -8,7 +8,11 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
+<<<<<<< HEAD
+"POT-Creation-Date: 2016-02-08 03:04+0100\n"
+=======
"POT-Creation-Date: 2016-02-14 23:39+0100\n"
+>>>>>>> refs/heads/rockwork
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -57,7 +61,7 @@ msgstr ""
msgid "Add new watchface"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:125
+#: /home/micha/Develop/upebble/rockwork/AppStorePage.qml:119
msgid "See all"
msgstr ""
@@ -75,26 +79,19 @@ msgstr ""
msgid "Report problem"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:42
-msgid "Install app or watchface from file"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:109
msgid "Preparing logs package..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:120
-msgid "pebble.log"
+#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
+msgid "rockworkd.log"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:127
msgid "Send rockworkd.log"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:132
-msgid "rockworkd.log"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/DeveloperToolsPage.qml:137
msgid "Send watch logs"
msgstr ""
@@ -111,7 +108,7 @@ msgid "Firmware upgrade"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:16
-msgid "A new firmware upgrade is available for your Pebble smartwatch."
+msgid "A new firmware upgrade is available for your Pebble smarwatch."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/FirmwareUpgradePage.qml:23
@@ -179,10 +176,6 @@ msgstr ""
msgid "OK"
msgstr ""
-#: /home/micha/Develop/upebble/rockwork/ImportPackagePage.qml:7
-msgid "Import watchapp or watchface"
-msgstr ""
-
#: /home/micha/Develop/upebble/rockwork/InfoPage.qml:31
#, qt-format
msgid "Version %1"
@@ -236,7 +229,7 @@ msgid "Loading..."
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:15
-msgid "About"
+msgid "Info"
msgstr ""
#: /home/micha/Develop/upebble/rockwork/MainMenuPage.qml:22
diff --git a/rockpool.pro b/rockpool.pro
new file mode 100644
index 0000000..d38aaf6
--- /dev/null
+++ b/rockpool.pro
@@ -0,0 +1,14 @@
+TEMPLATE = subdirs
+SUBDIRS = rockwork rockworkd
+OTHER_FILES += \
+ README.md \
+ rpm/rockpool.spec \
+ rpm/rockpool.yaml \
+ rpm/rockpool.changes
+
+# TODO:
+# Merge in latest changes from rockwork release
+# Migrate VoiceCallManager over to replace callchannelobserver
+# Dismiss notifications
+# Integrate calendar
+# Alarms?
diff --git a/rockpool.pro.user b/rockpool.pro.user
new file mode 100644
index 0000000..a24f009
--- /dev/null
+++ b/rockpool.pro.user
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 3.5.0, 2016-02-17T01:14:22. -->
+<qtcreator>
+ <data>
+ <variable>EnvironmentId</variable>
+ <value type="QByteArray">{bfe4fced-130c-4a1d-b5dd-4ef663a59e13}</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.ActiveTarget</variable>
+ <value type="int">0</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.EditorSettings</variable>
+ <valuemap type="QVariantMap">
+ <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+ <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+ <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+ <value type="QString" key="language">Cpp</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+ </valuemap>
+ </valuemap>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+ <value type="QString" key="language">QmlJS</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+ </valuemap>
+ </valuemap>
+ <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+ <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+ <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+ <value type="int" key="EditorConfiguration.IndentSize">4</value>
+ <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+ <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+ <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+ <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+ <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+ <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+ <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+ <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+ <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+ <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+ <value type="int" key="EditorConfiguration.TabSize">8</value>
+ <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+ <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+ <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+ <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+ <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+ <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.PluginSettings</variable>
+ <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.0</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">MerSDK-SailfishOS-armv7hl</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">MerSDK-SailfishOS-armv7hl</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{a1087e50-1b78-48e9-a186-a57cbfa9e4dd}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">2</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Git/build-rockpool-MerSDK_SailfishOS_armv7hl-Debug</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">false</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Git/build-rockpool-MerSDK_SailfishOS_armv7hl-Release</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmBuildStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM Validation</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmValidationStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy By Building An RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerMb2RpmBuildConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Rsync</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRsyncDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy By Copying Binaries</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRSyncDeployConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.2">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy As RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">3</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">rockpool (on Remote Device)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRunConfiguration:rockpool</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.Arguments"/>
+ <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.TargetName">rockpool</value>
+ <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+ <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory"></value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">rockpoold (on Remote Device)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRunConfiguration:rockpoold</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.Arguments"/>
+ <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.TargetName">rockpoold</value>
+ <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+ <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory"></value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">true</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.TargetCount</variable>
+ <value type="int">1</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+ <value type="int">18</value>
+ </data>
+ <data>
+ <variable>Version</variable>
+ <value type="int">18</value>
+ </data>
+</qtcreator>
diff --git a/rockwork.pro.user b/rockwork.pro.user
new file mode 100644
index 0000000..b336876
--- /dev/null
+++ b/rockwork.pro.user
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 3.5.0, 2016-02-10T00:15:52. -->
+<qtcreator>
+ <data>
+ <variable>EnvironmentId</variable>
+ <value type="QByteArray">{bfe4fced-130c-4a1d-b5dd-4ef663a59e13}</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.ActiveTarget</variable>
+ <value type="int">0</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.EditorSettings</variable>
+ <valuemap type="QVariantMap">
+ <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+ <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+ <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+ <value type="QString" key="language">Cpp</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+ </valuemap>
+ </valuemap>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+ <value type="QString" key="language">QmlJS</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+ </valuemap>
+ </valuemap>
+ <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+ <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+ <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+ <value type="int" key="EditorConfiguration.IndentSize">4</value>
+ <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+ <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+ <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+ <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+ <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+ <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+ <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+ <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+ <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+ <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+ <value type="int" key="EditorConfiguration.TabSize">8</value>
+ <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+ <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+ <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+ <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+ <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+ <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.PluginSettings</variable>
+ <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.0</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">MerSDK-SailfishOS-armv7hl</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">MerSDK-SailfishOS-armv7hl</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{a1087e50-1b78-48e9-a186-a57cbfa9e4dd}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Git/build-rockwork-MerSDK_SailfishOS_armv7hl-Debug</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">false</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Git/build-rockwork-MerSDK_SailfishOS_armv7hl-Release</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start SDK</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmBuildStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM Validation</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmValidationStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy By Building An RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerMb2RpmBuildConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Rsync</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRsyncDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy By Copying Binaries</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRSyncDeployConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.2">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy As RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">3</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">rockworkd (on Remote Device)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRunConfiguration:rockworkd</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.Arguments"/>
+ <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.TargetName">rockworkd</value>
+ <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+ <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory"></value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">-1</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">rockwork (on Remote Device)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRunConfiguration:rockwork</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.Arguments"/>
+ <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.TargetName">rockwork</value>
+ <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+ <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory"></value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.TargetCount</variable>
+ <value type="int">1</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+ <value type="int">18</value>
+ </data>
+ <data>
+ <variable>Version</variable>
+ <value type="int">18</value>
+ </data>
+</qtcreator>
diff --git a/rockwork/AppStorePage.qml b/rockwork/AppStorePage.qml
deleted file mode 100644
index bb8712b..0000000
--- a/rockwork/AppStorePage.qml
+++ /dev/null
@@ -1,266 +0,0 @@
-import QtQuick 2.4
-import Ubuntu.Components 1.3
-import QtQuick.Layouts 1.1
-import RockWork 1.0
-
-Page {
- id: root
- title: showWatchApps ? i18n.tr("Add new watchapp") : i18n.tr("Add new watchface")
-
- property var pebble: null
- property bool showWatchApps: false
- property bool showWatchFaces: false
-
- property string link: ""
-
- function fetchHome() {
- if (showWatchApps) {
- client.fetchHome(AppStoreClient.TypeWatchapp)
- } else {
- client.fetchHome(AppStoreClient.TypeWatchface)
- }
- }
-
- head {
- actions: [
- Action {
- iconName: "search"
- onTriggered: {
- if (searchField.shown) {
- searchField.shown = false;
- root.fetchHome();
- } else {
- searchField.shown = true;
- }
- }
- }
- ]
- }
-
- Component.onCompleted: {
- if (root.link) {
- client.fetchLink(link)
- } else {
- root.fetchHome()
- }
- }
-
- AppStoreClient {
- id: client
- hardwarePlatform: pebble.hardwarePlatform
- }
-
- Item {
- id: searchField
- anchors { left: parent.left; right: parent.right; top: parent.top }
- anchors.topMargin: shown ? 0 : -height
- Behavior on anchors.topMargin { UbuntuNumberAnimation {} }
- opacity: shown ? 1 : 0
- Behavior on opacity { UbuntuNumberAnimation {} }
- height: units.gu(6)
-
- property bool shown: false
- onShownChanged: {
- if (shown) {
- searchTextField.focus = true;
- }
- }
-
- TextField {
- id: searchTextField
- anchors.centerIn: parent
- width: parent.width - units.gu(2)
- onDisplayTextChanged: {
- searchTimer.restart()
- }
-
- Timer {
- id: searchTimer
- interval: 300
- onTriggered: {
- client.search(searchTextField.displayText, root.showWatchApps ? AppStoreClient.TypeWatchapp : AppStoreClient.TypeWatchface);
- }
- }
- }
- }
-
- Item {
- anchors { left: parent.left; top: searchField.bottom; right: parent.right; bottom: parent.bottom }
- ListView {
- anchors.fill: parent
- model: ApplicationsFilterModel {
- id: appsFilterModel
- model: client.model
- }
- clip: true
- section.property: "groupId"
- section.labelPositioning: ViewSection.CurrentLabelAtStart |
- ViewSection.InlineLabels
- section.delegate: ListItem {
- height: section ? label.implicitHeight + units.gu(3) : 0
-
- Rectangle {
- anchors.fill: parent
- color: "white"
- }
-
- RowLayout {
- anchors.fill: parent
- anchors.margins: units.gu(1)
- Label {
- id: label
- text: client.model.groupName(section)
- fontSize: "large"
-// font.weight: Font.DemiBold
- elide: Text.ElideRight
- Layout.fillWidth: true
- }
- AbstractButton {
- Layout.fillHeight: true
- implicitWidth: seeAllLabel.implicitWidth + height
- Row {
- anchors.verticalCenter: parent.verticalCenter
- Label {
- id: seeAllLabel
- text: i18n.tr("See all")
- }
- Icon {
- implicitHeight: parent.height
- implicitWidth: height
- name: "go-next"
- }
- }
- onClicked: {
- pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, link: client.model.groupLink(section), title: client.model.groupName(section)});
- }
- }
- }
- }
-
- footer: Item {
- height: client.model.links.length > 0 ? units.gu(6) : 0
- width: parent.width
-
- RowLayout {
- anchors {
- fill: parent
- margins: units.gu(1)
- }
- spacing: units.gu(1)
-
- Repeater {
- model: client.model.links
- Button {
- text: client.model.linkName(client.model.links[index])
- onClicked: client.fetchLink(client.model.links[index]);
- color: UbuntuColors.orange
- Layout.fillWidth: true
- }
- }
- }
- }
-
- delegate: ListItem {
- height: delegateColumn.height + units.gu(2)
-
- RowLayout {
- id: delegateRow
- anchors.fill: parent
- anchors.margins: units.gu(1)
- spacing: units.gu(1)
-
- AnimatedImage {
- Layout.fillHeight: true
- Layout.preferredWidth: height
- source: model.icon
- asynchronous: true
-// sourceSize.width: width
-// sourceSize.height: height
- }
-
- ColumnLayout {
- id: delegateColumn
- Layout.fillWidth: true;
- Layout.fillHeight: true;
- Label {
- Layout.fillWidth: true
- text: model.name
- font.weight: Font.DemiBold
- elide: Text.ElideRight
- }
- Label {
- Layout.fillWidth: true
- text: model.category
- }
- RowLayout {
- Icon {
- name: "like"
- Layout.preferredHeight: parent.height
- Layout.preferredWidth: height
- implicitHeight: parent.height
- }
- Label {
- Layout.fillWidth: true
- text: model.hearts
- }
- Icon {
- id: tickIcon
- name: "tick"
- implicitHeight: parent.height
- Layout.preferredWidth: height
- visible: root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId)
- Connections {
- target: root.pebble.installedApps
- onChanged: {
- tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId)
- }
- }
-
- Connections {
- target: root.pebble.installedWatchfaces
- onChanged: {
- tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId)
- }
- }
-
- }
- }
- }
-
- }
-
- onClicked: {
- client.fetchAppDetails(model.storeId);
- pageStack.push(Qt.resolvedUrl("AppStoreDetailsPage.qml"), {app: appsFilterModel.get(index), pebble: root.pebble})
- }
- }
- }
-
-// RowLayout {
-// id: buttonRow
-// anchors { left: parent.left; bottom: parent.bottom; right: parent.right; margins: units.gu(1) }
-// spacing: units.gu(1)
-// Button {
-// text: i18n.tr("Previous")
-// Layout.fillWidth: true
-// enabled: client.offset > 0
-// onClicked: {
-// client.previous()
-// }
-// }
-// Button {
-// text: i18n.tr("Next")
-// Layout.fillWidth: true
-// onClicked: {
-// client.next()
-// }
-// }
-// }
- }
-
- ActivityIndicator {
- anchors.centerIn: parent
- running: client.busy
- }
-}
-
diff --git a/rockwork/InstalledAppDelegate.qml b/rockwork/InstalledAppDelegate.qml
deleted file mode 100644
index 89f6ba8..0000000
--- a/rockwork/InstalledAppDelegate.qml
+++ /dev/null
@@ -1,88 +0,0 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-import RockWork 1.0
-
-ListItem {
- id: root
-
- property string uuid: ""
- property string name: ""
- property string iconSource: ""
- property string vendor: ""
- property bool hasSettings: false
- property alias hasGrip: grip.visible
- property bool isSystemApp: false
-
- signal deleteApp();
- signal configureApp();
-
- leadingActions: ListItemActions {
- actions: [
- Action {
- visible: !root.isSystemApp
- iconName: "delete"
- onTriggered: {
- root.deleteApp();
- }
- }
- ]
- }
-
- trailingActions: ListItemActions {
- actions: [
- Action {
- visible: root.hasSettings
- iconName: "settings"
- onTriggered: {
- print("settings triggered")
- root.configureApp();
- }
- }
- ]
- }
-
- RowLayout {
- anchors {
- fill: parent
- margins: units.gu(1)
- }
- spacing: units.gu(1)
-
- SystemAppIcon {
- Layout.fillHeight: true
- Layout.preferredWidth: height
- isSystemApp: root.isSystemApp
- uuid: root.uuid
- iconSource: root.iconSource
- }
-
- ColumnLayout {
- Layout.fillWidth: true
- Label {
- text: root.name
- Layout.fillWidth: true
- }
-
- Label {
- text: root.vendor
- Layout.fillWidth: true
- fontSize: "small"
- }
- }
-
- Item {
- id: grip
- Layout.fillHeight: true
- Layout.preferredWidth: height
- opacity: (root.contentMoving || root.swiped || root.dragging) ? 0 : 1
- Behavior on opacity { UbuntuNumberAnimation {} }
- Icon {
- width: units.gu(3)
- height: width
- anchors.centerIn: parent
- name: "grip-large"
- }
- }
- }
-}
diff --git a/rockwork/InstalledAppsPage.qml b/rockwork/InstalledAppsPage.qml
deleted file mode 100644
index a18cd3f..0000000
--- a/rockwork/InstalledAppsPage.qml
+++ /dev/null
@@ -1,201 +0,0 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-import Ubuntu.Components.Popups 1.3
-import RockWork 1.0
-
-Page {
- id: root
- title: showWatchApps ? (showWatchFaces ? i18n.tr("Apps & Watchfaces") : i18n.tr("Apps")) : i18n.tr("Watchfaces")
-
- property var pebble: null
- property bool showWatchApps: false
- property bool showWatchFaces: false
-
- head {
- actions: [
- Action {
- iconName: "add"
- onTriggered: pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, showWatchApps: root.showWatchApps, showWatchFaces: root.showWatchFaces})
- }
- ]
- }
-
- function configureApp(uuid) {
- // The health app is special :/
- if (uuid == "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}") {
- var popup = PopupUtils.open(Qt.resolvedUrl("HealthSettingsDialog.qml"), root, {healthParams: pebble.healthParams});
- popup.accepted.connect(function() {
- pebble.healthParams = popup.healthParams
- })
- } else {
- pebble.requestConfigurationURL(uuid);
- }
- }
-
- Item {
- anchors.fill: parent
- ListView {
- id: listView
- anchors.fill: parent
- model: root.showWatchApps ? root.pebble.installedApps : root.pebble.installedWatchfaces
- clip: true
- property real realContentY: contentY + originY
-
- delegate: InstalledAppDelegate {
- id: delegate
- uuid: model.uuid
- name: model.name
- iconSource: model.icon
- vendor: model.vendor
- visible: dndArea.draggedIndex !== index
- hasGrip: index > 0
- isSystemApp: model.isSystemApp
- hasSettings: model.hasSettings
-
- onDeleteApp: {
- pebble.removeApp(model.uuid)
- }
- onConfigureApp: {
- root.configureApp(model.uuid)
- }
- onClicked: {
- PopupUtils.open(dialogComponent, root, {app: listView.model.get(index)})
- }
- }
- }
- MouseArea {
- id: dndArea
- anchors {
- top: parent.top
- bottom: parent.bottom
- right: parent.right
- }
- drag.axis: Drag.YAxis
- propagateComposedEvents: true
- width: units.gu(5)
-
- property int startY: 0
- property int draggedIndex: -1
-
-
- onPressAndHold: {
- startY = mouseY;
- draggedIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height)
- if (draggedIndex == 0) {
- print("cannot drag settings app");
- return;
- }
-
- var draggedItem = listView.model.get(draggedIndex);
- fakeDragItem.uuid = draggedItem.uuid;
- fakeDragItem.name = draggedItem.name;
- fakeDragItem.vendor = draggedItem.vendor;
- fakeDragItem.iconSource = draggedItem.icon;
- fakeDragItem.isSystemApp = draggedItem.isSystemApp;
- fakeDragItem.y = (fakeDragItem.height * draggedIndex) - listView.realContentY
- drag.target = fakeDragItem;
- }
-
- onMouseYChanged: {
- var newIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height)
-
- if (newIndex > draggedIndex) {
- newIndex = draggedIndex + 1;
- } else if (newIndex < draggedIndex) {
- newIndex = draggedIndex - 1;
- } else {
- return;
- }
-
- if (newIndex >= 1 && newIndex < listView.count) {
- listView.model.move(draggedIndex, newIndex);
- draggedIndex = newIndex;
- }
- }
-
- onReleased: {
- if (draggedIndex > -1) {
- listView.model.commitMove();
- draggedIndex = -1;
- drag.target = null;
- }
- }
- }
- }
-
-
-
- InstalledAppDelegate {
- id: fakeDragItem
- visible: dndArea.draggedIndex != -1
-
- }
-
- Component {
- id: dialogComponent
- Dialog {
- id: dialog
- property var app: null
-
- RowLayout {
- SystemAppIcon {
- height: titleCol.height
- width: height
- isSystemApp: app.isSystemApp
- uuid: app.uuid
- iconSource: app.icon
- }
-
- ColumnLayout {
- id: titleCol
- Layout.fillWidth: true
-
- Label {
- Layout.fillWidth: true
- text: app.name
- fontSize: "large"
- }
- Label {
- Layout.fillWidth: true
- text: app.vendor
- }
- }
- }
-
- Button {
- text: i18n.tr("Launch")
- color: UbuntuColors.green
- onClicked: {
- pebble.launchApp(app.uuid);
- PopupUtils.close(dialog);
- }
- }
-
- Button {
- text: i18n.tr("Configure")
- color: UbuntuColors.blue
- visible: app.hasSettings
- onClicked: {
- root.configureApp(app.uuid);
- PopupUtils.close(dialog);
- }
- }
-
- Button {
- text: i18n.tr("Delete")
- color: UbuntuColors.red
- visible: !app.isSystemApp
- onClicked: {
- pebble.removeApp(app.uuid);
- PopupUtils.close(dialog);
- }
- }
-
- Button {
- text: i18n.tr("Close")
- onClicked: PopupUtils.close(dialog)
- }
- }
- }
-}
diff --git a/rockwork/MainMenuPage.qml b/rockwork/MainMenuPage.qml
deleted file mode 100644
index 32c7b96..0000000
--- a/rockwork/MainMenuPage.qml
+++ /dev/null
@@ -1,317 +0,0 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-
-Page {
- id: root
- title: pebble.name
-
- property var pebble: null
-
- head {
- actions: [
- Action {
- iconName: "info"
- text: i18n.tr("About")
- onTriggered: {
- pageStack.push(Qt.resolvedUrl("InfoPage.qml"))
- }
- },
- Action {
- iconName: "ubuntu-sdk-symbolic"
- text: i18n.tr("Developer tools")
- onTriggered: {
- pageStack.push(Qt.resolvedUrl("DeveloperToolsPage.qml"), {pebble: root.pebble})
- }
- }
- ]
- }
-
- //Creating the menu list this way to allow the text field to be translatable (http://askubuntu.com/a/476331)
- ListModel {
- id: mainMenuModel
- dynamicRoles: true
- }
-
- Component.onCompleted: {
- populateMainMenu();
- }
-
- Connections {
- target: root.pebble
- onFirmwareUpgradeAvailableChanged: {
- populateMainMenu();
- }
- }
-
- function populateMainMenu() {
- mainMenuModel.clear();
-
- mainMenuModel.append({
- icon: "stock_notification",
- text: i18n.tr("Manage notifications"),
- page: "NotificationsPage.qml",
- color: "blue"
- });
-
- mainMenuModel.append({
- icon: "stock_application",
- text: i18n.tr("Manage Apps"),
- page: "InstalledAppsPage.qml",
- showWatchApps: true,
- color: UbuntuColors.green
- });
-
- mainMenuModel.append({
- icon: "clock-app-symbolic",
- text: i18n.tr("Manage Watchfaces"),
- page: "InstalledAppsPage.qml",
- showWatchFaces: true,
- color: "black"
- });
-
- mainMenuModel.append({
- icon: "settings",
- text: i18n.tr("Settings"),
- page: "SettingsPage.qml",
- showWatchFaces: true,
- color: "gold"
- });
-
- if (root.pebble.firmwareUpgradeAvailable) {
- mainMenuModel.append({
- icon: "preferences-system-updates-symbolic",
- text: i18n.tr("Firmware upgrade"),
- page: "FirmwareUpgradePage.qml",
- color: "red"
- });
- }
-
- }
-
- PebbleModels {
- id: modelModel
- }
-
- GridLayout {
- anchors.fill: parent
- columns: parent.width > parent.height ? 2 : 1
-
- Item {
- Layout.fillWidth: true
- Layout.fillHeight: true
- Layout.maximumHeight: units.gu(30)
-
- RowLayout {
- anchors.fill: parent
- anchors.margins: units.gu(1)
- spacing: units.gu(1)
-
- Item {
- Layout.alignment: Qt.AlignHCenter
- Layout.fillHeight: true
- Layout.fillWidth: true
- Layout.minimumWidth: watchImage.width
- Image {
- id: watchImage
- width: implicitWidth * height / implicitHeight
- height: parent.height
- anchors.horizontalCenter: parent.horizontalCenter
-
- source: modelModel.get(root.pebble.model).image
- fillMode: Image.PreserveAspectFit
-
- Item {
- id: watchFace
- height: parent.height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .5 : .515)
- width: height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .85 : 1)
- anchors.centerIn: parent
- anchors.horizontalCenterOffset: units.dp(1)
- anchors.verticalCenterOffset: units.dp(modelModel.get(root.pebble.model - 1).shape === "rectangle" ? 0 : 1)
-
- Image {
- id: image
- anchors.fill: parent
- source: "file://" + root.pebble.screenshots.latestScreenshot
- visible: false
- }
-
- Component.onCompleted: {
- if (!root.pebble.screenshots.latestScreenshot) {
- root.pebble.requestScreenshot();
- }
- }
-
- Rectangle {
- id: textItem
- anchors.fill: parent
- layer.enabled: true
- radius: modelModel.get(root.pebble.model - 1).shape === "rectangle" ? units.gu(.5) : height / 2
- // This item should be used as the 'mask'
- layer.samplerName: "maskSource"
- layer.effect: ShaderEffect {
- property var colorSource: image;
- fragmentShader: "
- uniform lowp sampler2D colorSource;
- uniform lowp sampler2D maskSource;
- uniform lowp float qt_Opacity;
- varying highp vec2 qt_TexCoord0;
- void main() {
- gl_FragColor =
- texture2D(colorSource, qt_TexCoord0)
- * texture2D(maskSource, qt_TexCoord0).a
- * qt_Opacity;
- }
- "
- }
- }
- }
- }
- }
- ColumnLayout {
- Layout.fillWidth: true
- Layout.fillHeight: true
- spacing: units.gu(2)
- Rectangle {
- height: units.gu(10)
- width: height
- radius: height / 2
- color: root.pebble.connected ? UbuntuColors.green : UbuntuColors.red
-
- Icon {
- anchors.fill: parent
- anchors.margins: units.gu(2)
- color: "white"
- name: root.pebble.connected ? "tick" : "dialog-error-symbolic"
- }
- }
-
- Label {
- text: root.pebble.connected ? i18n.tr("Connected") : i18n.tr("Disconnected")
- Layout.fillWidth: true
- }
- }
- }
- }
-
-
- Column {
- Layout.fillWidth: true
- Layout.preferredHeight: childrenRect.height
- spacing: menuRepeater.count > 0 ? 0 : units.gu(2)
- Label {
- text: i18n.tr("Your Pebble smartwatch is disconnected. Please make sure it is powered on, within range and it is paired properly in the Bluetooth System Settings.")
- width: parent.width - units.gu(4)
- anchors.horizontalCenter: parent.horizontalCenter
- wrapMode: Text.WordWrap
- visible: !root.pebble.connected
- fontSize: "large"
- horizontalAlignment: Text.AlignHCenter
- }
-
- Button {
- text: i18n.tr("Open System Settings")
- visible: !root.pebble.connected
- onClicked: Qt.openUrlExternally("settings://system/bluetooth")
- color: UbuntuColors.orange
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- Label {
- text: i18n.tr("Your Pebble smartwatch is in factory mode and needs to be initialized.")
- width: parent.width - units.gu(4)
- anchors.horizontalCenter: parent.horizontalCenter
- wrapMode: Text.WordWrap
- visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware
- fontSize: "large"
- horizontalAlignment: Text.AlignHCenter
- }
- Button {
- text: i18n.tr("Initialize Pebble")
- onClicked: root.pebble.performFirmwareUpgrade();
- visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware
- color: UbuntuColors.orange
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- Rectangle {
- id: upgradeIcon
- height: units.gu(10)
- width: height
- radius: width / 2
- color: UbuntuColors.orange
- anchors.horizontalCenter: parent.horizontalCenter
- Icon {
- anchors.fill: parent
- anchors.margins: units.gu(1)
- name: "preferences-system-updates-symbolic"
- color: "white"
- }
-
- RotationAnimation on rotation {
- duration: 2000
- loops: Animation.Infinite
- from: 0
- to: 360
- running: upgradeIcon.visible
- }
- visible: root.pebble.connected && root.pebble.upgradingFirmware
- }
-
- Label {
- text: i18n.tr("Upgrading...")
- fontSize: "large"
- anchors.horizontalCenter: parent.horizontalCenter
- visible: root.pebble.connected && root.pebble.upgradingFirmware
- }
-
- Repeater {
- id: menuRepeater
- model: root.pebble.connected && !root.pebble.recovery && !root.pebble.upgradingFirmware ? mainMenuModel : null
- delegate: ListItem {
-
- RowLayout {
- anchors.fill: parent
- anchors.margins: units.gu(1)
-
- UbuntuShape {
- Layout.fillHeight: true
- Layout.preferredWidth: height
- backgroundColor: model.color
- Icon {
- anchors.fill: parent
- anchors.margins: units.gu(.5)
- name: model.icon
- color: "white"
- }
- }
-
-
- Label {
- text: model.text
- Layout.fillWidth: true
- }
- }
-
- onClicked: {
- var options = {};
- options["pebble"] = root.pebble
- var modelItem = mainMenuModel.get(index)
- options["showWatchApps"] = modelItem.showWatchApps
- options["showWatchFaces"] = modelItem.showWatchFaces
- pageStack.push(Qt.resolvedUrl(model.page), options)
- }
- }
- }
- }
- }
-
- Connections {
- target: pebble
- onOpenURL: {
- if (url) {
- pageStack.push(Qt.resolvedUrl("AppSettingsPage.qml"), {uuid: uuid, url: url, pebble: pebble})
- }
- }
- }
-}
diff --git a/rockwork/PebbleModels.qml b/rockwork/PebbleModels.qml
deleted file mode 100644
index 103064a..0000000
--- a/rockwork/PebbleModels.qml
+++ /dev/null
@@ -1,28 +0,0 @@
-import QtQuick 2.4
-
-ListModel {
- id: modelModel
- ListElement { image: 'artwork/tintin-black.png'; shape: "rectangle" } // Fallback for Unknown
- ListElement { image: 'artwork/tintin-black.png'; shape: "rectangle" }
- ListElement { image: 'artwork/tintin-white.png'; shape: "rectangle" }
- ListElement { image: 'artwork/tintin-red.png'; shape: "rectangle" }
- ListElement { image: 'artwork/tintin-orange.png'; shape: "rectangle" }
- ListElement { image: 'artwork/tintin-grey.png'; shape: "rectangle" }
- ListElement { image: 'artwork/bianca-silver.png'; shape: "rectangle" }
- ListElement { image: 'artwork/bianca-black.png'; shape: "rectangle" }
- ListElement { image: 'artwork/tintin-blue.png'; shape: "rectangle" }
- ListElement { image: 'artwork/tintin-green.png'; shape: "rectangle" }
- ListElement { image: 'artwork/tintin-pink.png'; shape: "rectangle" }
- ListElement { image: 'artwork/snowy-white.png'; shape: "rectangle" }
- ListElement { image: 'artwork/snowy-black.png'; shape: "rectangle" }
- ListElement { image: 'artwork/snowy-red.png'; shape: "rectangle" }
- ListElement { image: 'artwork/bobby-silver.png'; shape: "rectangle" }
- ListElement { image: 'artwork/bobby-black.png'; shape: "rectangle" }
- ListElement { image: 'artwork/bobby-gold.png'; shape: "rectangle" }
- ListElement { image: 'artwork/spalding-14mm-silver.png'; shape: "round" }
- ListElement { image: 'artwork/spalding-14mm-black.png'; shape: "round" }
- ListElement { image: 'artwork/spalding-20mm-silver.png'; shape: "round" }
- ListElement { image: 'artwork/spalding-20mm-black.png'; shape: "round" }
- ListElement { image: 'artwork/spalding-14mm-rose-gold.png'; shape: "round" }
-}
-
diff --git a/rockwork/artwork/back-cover.png b/rockwork/artwork/back-cover.png
new file mode 100644
index 0000000..2d5ab14
--- /dev/null
+++ b/rockwork/artwork/back-cover.png
Binary files differ
diff --git a/rockwork/artwork/rockwork.svg b/rockwork/artwork/rockwork.svg
deleted file mode 100644
index e4e92c0..0000000
--- a/rockwork/artwork/rockwork.svg
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="72.248886mm"
- height="72.248886mm"
- viewBox="0 0 255.99999 255.99999"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="upebble.svg">
- <defs
- id="defs4">
- <filter
- inkscape:collect="always"
- style="color-interpolation-filters:sRGB"
- id="filter4248"
- x="-0.025328101"
- width="1.0506562"
- y="-0.013960773"
- height="1.0279215">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2.3907822"
- id="feGaussianBlur4250" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="3.959798"
- inkscape:cx="89.121544"
- inkscape:cy="77.044911"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:window-width="2880"
- inkscape:window-height="1752"
- inkscape:window-x="0"
- inkscape:window-y="48"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- originx="-40.000001"
- originy="-539"
- snapvisiblegridlinesonly="true"
- enabled="false" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-40,-257.36221)">
- <rect
- style="opacity:1;fill:#78d3fc;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4200"
- width="256"
- height="256"
- x="40"
- y="257.36221" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:0.0479798;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 40,257.36221 256,0 -256,256 z"
- id="rect4252"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" />
- <g
- id="g4300">
- <g
- style="fill:#000000;fill-opacity:1;opacity:0.291;filter:url(#filter4248)"
- id="g4202"
- transform="matrix(0.60632857,0,0,0.60632857,-37.462675,74.399202)">
- <path
- sodipodi:nodetypes="czccc"
- inkscape:connector-curvature="0"
- id="path4204"
- d="m 437.97969,445.08937 c 0,0 11.49464,-4.59544 12.27285,0.25253 0.77821,4.84797 2.06459,45.23266 2.06459,45.23266 -8.36034,0.32794 -13.15013,-0.0886 -13.15013,-0.0886 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path4206"
- d="m 439.49492,491.6046 12.68287,0.70015 0.54937,42.27954 -13.73731,0.25254 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4208"
- width="120"
- height="95"
- x="280"
- y="623.36218" />
- <rect
- y="307.36221"
- x="280"
- height="95"
- width="120"
- id="rect4210"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zcczz"
- inkscape:connector-curvature="0"
- id="path4212"
- d="M 228.0862,442.4309 C 228.58744,435.98794 240,437.36221 240,437.36221 l 0,42.02031 c 0,0 -14.31567,-1.22669 -13.80125,-2.84014 0.51442,-1.61345 1.3862,-27.66851 1.88745,-34.11148 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 420,643.715 337.60905,658.36221 255,643.715 l 0,-20 165,0 z"
- id="path4214"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="path4216"
- d="M 255,382.36221 337.39095,367.715 420,382.36221 l 0,20 -165,0 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cczcc"
- inkscape:connector-curvature="0"
- id="path4218"
- d="m 438.52906,535.82255 c 0,0 5.15979,0.84007 13.83236,0.44761 0.13423,13.76866 -1.20901,37.74804 -1.85634,42.35471 -0.64733,4.60667 -11.01016,-0.50508 -11.01016,-0.50508 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zzzzzzzzz"
- inkscape:connector-curvature="0"
- id="path4220"
- d="m 244.85206,406.56127 c 16.07143,-13.92858 66.12644,-13.34299 97.65304,-13.30725 31.5266,0.0357 73.56632,-0.53467 90.70918,15.17961 17.14286,15.71428 12.91706,70.98675 13.01566,106.0726 0.0986,35.08586 5.19864,81.42741 -13.01565,99.64169 C 415,632.3622 371.12033,628.47664 339.15317,628.18658 307.186,627.89652 263.91063,632.7014 245.3392,615.91569 226.76777,599.12997 231.43107,540.45867 231.61582,505.9352 c 0.18475,-34.52347 -2.83519,-85.44536 13.23624,-99.37393 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- ry="20"
- rx="20"
- y="422.36221"
- x="260"
- height="174.99998"
- width="155"
- id="rect4222"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- y="442.36221"
- x="280"
- height="135"
- width="120"
- id="rect4224"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0"
- id="path4226"
- d="m 375,442.36221 25,0 0,135 -25,0 0,-109.75206 -7.32361,-5.3033 7.32361,-4.9245 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
- <path
- sodipodi:nodetypes="czccc"
- inkscape:connector-curvature="0"
- id="rect4177"
- d="m 228.09692,344.2696 c 0,0 6.96953,-2.78634 7.44138,0.15312 0.47185,2.93946 1.25182,27.42585 1.25182,27.42585 -5.06911,0.19884 -7.9733,-0.0537 -7.9733,-0.0537 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="rect4179"
- d="m 229.01565,372.47312 7.68999,0.42452 0.3331,25.63529 -8.32933,0.15312 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4167"
- width="72.75943"
- height="57.601215"
- x="132.30933"
- y="452.36151" />
- <rect
- y="260.76169"
- x="132.30933"
- height="57.601215"
- width="72.75943"
- id="rect4165"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zcczz"
- inkscape:connector-curvature="0"
- id="rect4169"
- d="m 100.8325,342.6577 c 0.30392,-3.90655 7.22368,-3.07329 7.22368,-3.07329 l 0,25.47811 c 0,0 -8.679998,-0.74378 -8.36809,-1.72206 0.311907,-0.97828 0.84049,-16.77621 1.14441,-20.68276 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 217.19532,464.702 -49.95598,8.88102 -50.08823,-8.88102 0,-12.12657 100.04421,0 z"
- id="path4175"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="rect4172"
- d="m 117.15111,306.23633 49.95599,-8.88102 50.08822,8.88102 0,12.12658 -100.04421,0 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cczcc"
- inkscape:connector-curvature="0"
- id="rect4181"
- d="m 228.43002,399.28372 c 0,0 3.12853,0.50936 8.38696,0.2714 0.0814,8.34833 -0.73306,22.88772 -1.12555,25.68087 -0.3925,2.79316 -6.67578,-0.30624 -6.67578,-0.30624 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zzzzzzzzz"
- inkscape:connector-curvature="0"
- id="rect4149"
- d="m 110.99812,320.90892 c 9.74457,-8.4453 40.09435,-8.09024 59.20983,-8.06857 19.11548,0.0217 44.60536,-0.32419 54.99957,9.20383 10.39421,9.52802 7.83198,43.0413 7.89177,64.31485 0.0598,21.27356 3.15208,49.37176 -7.89176,60.4156 -11.04385,11.04384 -37.64935,8.68791 -57.03195,8.51204 -19.38261,-0.17587 -45.6217,2.73747 -56.88209,-7.44019 -11.26039,-10.17766 -8.4329,-45.75175 -8.32088,-66.68431 0.11202,-20.93257 -1.71905,-51.80796 8.02551,-60.25325 z"
- style="opacity:1;fill:#cbcbcb;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 133.22587,330.48948 69.72779,0 c 6.71812,0 11.83367,5.41484 12.12657,12.12657 1.19073,27.28478 1.19022,54.56956 0,81.85435 -0.29278,6.71174 -5.40845,12.12657 -12.12657,12.12657 l -69.72779,0 c -6.71812,0 -11.82926,-5.41504 -12.12657,-12.12657 -1.18246,-26.69356 -1.65764,-53.74075 0,-81.85435 0.39543,-6.70647 5.40845,-12.12657 12.12657,-12.12657 z"
- id="rect4152"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="sssssssss" />
- <rect
- y="342.61606"
- x="131.62029"
- height="81.854355"
- width="72.75943"
- id="rect4154"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0"
- id="rect4156"
- d="m 189.2215,342.61605 15.15821,0 0,81.85436 -15.15821,0 0,-66.54581 -4.44052,-3.21555 4.44052,-2.98586 z"
- style="opacity:1;fill:#78d3fc;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
- <path
- style="fill:#000000"
- d="m 143.63128,393.17695 c -0.82884,-0.82884 0.32908,-1.46136 2.67524,-1.46136 3.02637,0 3.07586,-0.7116 0.31911,-4.58902 l -2.10477,-2.96041 2.0287,-2.94922 c 1.15063,-1.67272 2.20678,-4.13671 2.44014,-5.69282 0.40696,-2.71383 0.44252,-2.74828 3.27625,-3.17322 1.57564,-0.23629 4.03472,-1.23453 5.46462,-2.21832 1.42988,-0.98379 2.85437,-1.78871 3.16551,-1.78871 0.31114,0 1.68177,0.80847 3.04585,1.7966 1.40341,1.01663 3.70432,1.98019 5.29992,2.21946 2.92933,0.43928 2.99923,0.52347 3.81465,4.59457 0.23714,1.18397 1.22649,3.16119 2.19857,4.39382 0.97208,1.23265 1.76741,2.42825 1.76741,2.6569 0,0.22864 -0.83031,1.62253 -1.84514,3.09753 -2.44659,3.556 -2.38325,4.49115 0.32038,4.72947 1.19102,0.10499 2.22891,0.46766 2.30641,0.80594 0.15778,0.68864 -33.49245,1.21919 -34.17285,0.53879 z m 27.8729,-2.84521 c 0.009,-0.76112 0.83738,-2.4679 1.83992,-3.79283 l 1.82279,-2.40898 -1.58789,-2.08183 c -0.87334,-1.14501 -1.90888,-3.37431 -2.30119,-4.954 -0.68475,-2.75721 -0.82407,-2.89364 -3.48101,-3.40876 -1.52223,-0.29514 -3.68339,-1.22898 -4.80255,-2.0752 l -2.03486,-1.53859 -2.27046,1.53481 c -2.19134,1.48132 -2.85113,1.74296 -6.34208,2.51493 -1.32103,0.29212 -1.68348,0.80695 -2.01126,2.85674 -0.2199,1.37522 -1.11243,3.57721 -1.98338,4.8933 l -1.58355,2.39291 1.54803,2.0343 c 0.85141,1.11887 1.73796,2.79542 1.97011,3.72567 l 0.42209,1.69138 10.38909,0 c 10.35877,0 10.38914,-0.004 10.4062,-1.38385 z m -16.16204,-1.17442 c -3.00082,-0.83158 -3.29439,-2.70542 -0.30753,-1.96294 1.0994,0.27329 2.9676,0.49689 4.15156,0.49689 1.18396,0 3.05216,-0.2236 4.15155,-0.49689 1.34833,-0.33517 1.9989,-0.27586 1.9989,0.18225 0,1.61808 -6.44052,2.76557 -9.99448,1.78069 z m -1.87921,-5.21512 c -0.23497,-0.23497 -0.42721,-1.51123 -0.42721,-2.83614 0,-2.76084 1.40937,-2.98541 1.73071,-0.27578 0.21201,1.78766 -0.62633,3.78908 -1.3035,3.11192 z m 10.02856,-2.68238 c 0,-1.7768 0.25627,-2.46018 0.92256,-2.46018 0.6663,0 0.92257,0.68338 0.92257,2.46018 0,1.7768 -0.25627,2.46018 -0.92257,2.46018 -0.66629,0 -0.92256,-0.68338 -0.92256,-2.46018 z m -22.75668,2.7677 c 0,-0.69366 0.43166,-0.94682 1.38386,-0.81158 0.76111,0.10809 1.38385,0.47331 1.38385,0.81158 0,0.33828 -0.62274,0.70349 -1.38385,0.81159 -0.9522,0.13523 -1.38386,-0.11793 -1.38386,-0.81159 z m 37.8226,0.30318 c -0.46699,-0.7556 1.22568,-1.49279 2.13592,-0.93022 0.35999,0.22248 0.4953,0.66216 0.30068,0.97707 -0.46943,0.75955 -1.95589,0.73096 -2.4366,-0.0469 z m -32.49939,-13.42132 c -1.23387,-1.36341 -1.29125,-1.95046 -0.19065,-1.95046 1.05106,0 3.00139,2.11681 2.45435,2.66385 -0.65422,0.65422 -1.17438,0.49029 -2.2637,-0.71339 z m 27.38286,0.11435 c 0.23773,-1.20797 2.11252,-2.50883 2.72827,-1.89307 0.48678,0.48678 -1.47947,2.90348 -2.36232,2.90348 -0.31065,0 -0.47533,-0.45468 -0.36595,-1.01041 z m -13.38512,-4.7488 c -0.52662,-1.37234 -0.0519,-3.6431 0.82178,-3.93083 0.51752,-0.17043 0.76881,0.45533 0.76881,1.91443 0,2.29458 -0.99824,3.56005 -1.59059,2.0164 z"
- id="path4285"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ssscsssssssssssssssscsssscsssscsscsssssssssssssssssssssscssccssssssssssss" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="136.46957"
- y="405.82156"
- id="text4342"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan4344"
- x="136.46957"
- y="405.82156"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu">Tomorrow</tspan></text>
- </g>
-</svg>
diff --git a/rockwork/main.cpp b/rockwork/main.cpp
index 70fd0d7..57a8772 100644
--- a/rockwork/main.cpp
+++ b/rockwork/main.cpp
@@ -12,26 +12,28 @@
#include "applicationsfiltermodel.h"
#include "appstoreclient.h"
#include "screenshotmodel.h"
+#include <sailfishapp.h>
int main(int argc, char *argv[])
{
- QGuiApplication app(argc, argv);
+ QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));
+ app->setApplicationName("pebble");
+ app->setOrganizationName("");
- qmlRegisterUncreatableType<Pebble>("RockWork", 1, 0, "Pebble", "Get them from the model");
- qmlRegisterUncreatableType<ApplicationsModel>("RockWork", 1, 0, "ApplicationsModel", "Get them from a Pebble object");
- qmlRegisterUncreatableType<AppItem>("RockWork", 1, 0, "AppItem", "Get them from an ApplicationsModel");
- qmlRegisterType<ApplicationsFilterModel>("RockWork", 1, 0, "ApplicationsFilterModel");
- qmlRegisterType<Pebbles>("RockWork", 1, 0, "Pebbles");
- qmlRegisterUncreatableType<NotificationSourceModel>("RockWork", 1, 0, "NotificationSourceModel", "Get it from a Pebble object");
- qmlRegisterType<ServiceControl>("RockWork", 1, 0, "ServiceController");
- qmlRegisterType<AppStoreClient>("RockWork", 1, 0, "AppStoreClient");
- qmlRegisterType<ScreenshotModel>("RockWork", 1, 0, "ScreenshotModel");
+ qmlRegisterUncreatableType<Pebble>("RockPool", 1, 0, "Pebble", "Get them from the model");
+ qmlRegisterUncreatableType<ApplicationsModel>("RockPool", 1, 0, "ApplicationsModel", "Get them from a Pebble object");
+ qmlRegisterUncreatableType<AppItem>("RockPool", 1, 0, "AppItem", "Get them from an ApplicationsModel");
+ qmlRegisterType<ApplicationsFilterModel>("RockPool", 1, 0, "ApplicationsFilterModel");
+ qmlRegisterType<Pebbles>("RockPool", 1, 0, "Pebbles");
+ qmlRegisterUncreatableType<NotificationSourceModel>("RockPool", 1, 0, "NotificationSourceModel", "Get it from a Pebble object");
+ qmlRegisterType<ServiceControl>("RockPool", 1, 0, "ServiceController");
+ qmlRegisterType<AppStoreClient>("RockPool", 1, 0, "AppStoreClient");
+ qmlRegisterType<ScreenshotModel>("RockPool", 1, 0, "ScreenshotModel");
- QQuickView view;
- view.engine()->rootContext()->setContextProperty("version", QStringLiteral(VERSION));
- view.engine()->rootContext()->setContextProperty("homePath", QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
- view.setSource(QUrl(QStringLiteral("qrc:///Main.qml")));
- view.setResizeMode(QQuickView::SizeRootObjectToView);
- view.show();
- return app.exec();
+ QScopedPointer<QQuickView> view(SailfishApp::createView());
+ view->rootContext()->setContextProperty("version", QStringLiteral(VERSION));
+ view->setSource(SailfishApp::pathTo("qml/Main.qml"));
+ view->show();
+
+ return app->exec();
}
diff --git a/rockwork/AppSettingsPage.qml b/rockwork/qml/AppSettingsPage.qml
index d8d865b..da7d577 100644
--- a/rockwork/AppSettingsPage.qml
+++ b/rockwork/qml/AppSettingsPage.qml
@@ -1,7 +1,5 @@
-import QtQuick 2.4
-import Ubuntu.Web 0.2
-import Ubuntu.Components 1.3
-import com.canonical.Oxide 1.0 as Oxide
+import QtQuick 2.0
+import Sailfish.Silica 1.0
Page {
id: settings
diff --git a/rockwork/AppStoreDetailsPage.qml b/rockwork/qml/AppStoreDetailsPage.qml
index 696e3c6..dbb8d5f 100644
--- a/rockwork/AppStoreDetailsPage.qml
+++ b/rockwork/qml/AppStoreDetailsPage.qml
@@ -1,7 +1,5 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-import Ubuntu.Components.ListItems 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
import QtGraphicalEffects 1.0
Page {
diff --git a/rockwork/qml/AppStorePage.qml b/rockwork/qml/AppStorePage.qml
new file mode 100644
index 0000000..7e006da
--- /dev/null
+++ b/rockwork/qml/AppStorePage.qml
@@ -0,0 +1,268 @@
+import QtQuick 2.0
+import QtQml 2.1
+import Sailfish.Silica 1.0
+import RockPool 1.0
+
+Page {
+ id: root
+
+ property var pebble: null
+ property bool showWatchApps: false
+ property bool showWatchFaces: false
+
+ property string link: ""
+
+ function fetchHome() {
+ if (showWatchApps) {
+ client.fetchHome(AppStoreClient.TypeWatchapp)
+ } else {
+ client.fetchHome(AppStoreClient.TypeWatchface)
+ }
+ }
+ SilicaFlickable {
+ id: flickable
+ anchors.top: parent.top
+ width: parent.width
+ PageHeader {
+ title: showWatchApps ? qsTr("Add new watchapp") : qsTr("Add new watchface")
+ }
+ PullDownMenu {
+ MenuItem {
+ text: qsTr("Show search")
+ onClicked: {
+ if (searchField.shown) {
+ searchField.shown = false;
+ root.fetchHome();
+ } else {
+ searchField.shown = true;
+ }
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ if (root.link) {
+ client.fetchLink(link)
+ } else {
+ root.fetchHome()
+ }
+ }
+
+ AppStoreClient {
+ id: client
+ hardwarePlatform: pebble.hardwarePlatform
+ }
+
+ Item {
+ id: searchField
+ anchors { left: parent.left; right: parent.right; top: parent.top }
+ anchors.topMargin: shown ? 0 : -height
+ Behavior on anchors.topMargin { NumberAnimation {} }
+ opacity: shown ? 1 : 0
+ Behavior on opacity { NumberAnimation {} }
+ height: units.gu(6)
+
+ property bool shown: false
+ onShownChanged: {
+ if (shown) {
+ searchTextField.focus = true;
+ }
+ }
+
+ SearchField {
+ id: searchTextField
+ anchors.centerIn: parent
+ width: parent.width - units.gu(2)
+ onDisplayTextChanged: {
+ searchTimer.restart()
+ }
+
+ Timer {
+ id: searchTimer
+ interval: 300
+ onTriggered: {
+ client.search(searchTextField.displayText, root.showWatchApps ? AppStoreClient.TypeWatchapp : AppStoreClient.TypeWatchface);
+ }
+ }
+ }
+ }
+
+ Item {
+ anchors { left: parent.left; top: searchField.bottom; right: parent.right; bottom: parent.bottom }
+ ListView {
+ anchors.fill: parent
+ model: ApplicationsFilterModel {
+ id: appsFilterModel
+ model: client.model
+ }
+ clip: true
+ section.property: "groupId"
+ section.labelPositioning: ViewSection.CurrentLabelAtStart |
+ ViewSection.InlineLabels
+ section.delegate: ListItem {
+ height: section ? label.implicitHeight + units.gu(3) : 0
+
+ Rectangle {
+ anchors.fill: parent
+ color: "white"
+ }
+
+ Row {
+ anchors.fill: parent
+ anchors.margins: units.gu(1)
+ Label {
+ id: label
+ text: client.model.groupName(section)
+ font.pixelSize: Theme.fontSizeLarge
+ // font.weight: Font.DemiBold
+ elide: Text.ElideRight
+ width: parent.width
+ }
+ Button {
+ implicitWidth: seeAllLabel.implicitWidth + height
+ Row {
+ anchors.verticalCenter: parent.verticalCenter
+ Label {
+ id: seeAllLabel
+ text: qsTr("See all")
+ }
+ IconButton {
+ implicitHeight: parent.height
+ implicitWidth: height
+ icon.source: "image://theme/icon-m-forward"
+ }
+ }
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, link: client.model.groupLink(section), title: client.model.groupName(section)});
+ }
+ }
+ }
+ }
+
+ footer: Item {
+ height: client.model.links.length > 0 ? units.gu(6) : 0
+ width: parent.width
+
+ Row {
+ anchors {
+ fill: parent
+ margins: units.gu(1)
+ }
+ spacing: units.gu(1)
+
+ Repeater {
+ model: client.model.links
+ Button {
+ text: client.model.linkName(client.model.links[index])
+ onClicked: client.fetchLink(client.model.links[index]);
+ color: UbuntuColors.orange
+ width: parent.width
+ }
+ }
+ }
+ }
+
+ delegate: ListItem {
+ height: delegateColumn.height + units.gu(2)
+
+ Row {
+ id: delegateRow
+ anchors.fill: parent
+ anchors.margins: units.gu(1)
+ spacing: units.gu(1)
+
+ AnimatedImage {
+ source: model.icon
+ asynchronous: true
+ // sourceSize.width: width
+ // sourceSize.height: height
+ }
+
+ Column {
+ id: delegateColumn
+ width: parent.width
+ //Layout.fillHeight: true;
+ Label {
+ width: parent.width
+ text: model.name
+ font.weight: Font.DemiBold
+ elide: Text.ElideRight
+ }
+ Label {
+ width: parent.width
+ text: model.category
+ }
+ Row {
+ IconButton {
+ icon.source: "image://theme/icon-m-back"
+ id: like
+ //Layout.preferredHeight: parent.height
+ //Layout.preferredWidth: height
+ implicitHeight: parent.height
+ }
+ Label {
+ width: parent.width
+ text: model.hearts
+ }
+ IconButton {
+ id: tickIcon
+ icon.source: "image://theme/icon-m-acknowledge"
+ implicitHeight: parent.height
+ //Layout.preferredWidth: height
+ visible: root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId)
+ Connections {
+ target: root.pebble.installedApps
+ onTargetChanged: {
+ tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId)
+ }
+ }
+
+ Connections {
+ target: root.pebble.installedWatchfaces
+ onTargetChanged: {
+ tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId)
+ }
+ }
+
+ }
+ }
+ }
+
+ }
+
+ onClicked: {
+ client.fetchAppDetails(model.storeId);
+ pageStack.push(Qt.resolvedUrl("AppStoreDetailsPage.qml"), {app: appsFilterModel.get(index), pebble: root.pebble})
+ }
+ }
+ }
+
+ // RowLayout {
+ // id: buttonRow
+ // anchors { left: parent.left; bottom: parent.bottom; right: parent.right; margins: units.gu(1) }
+ // spacing: units.gu(1)
+ // Button {
+ // text: qsTr("Previous")
+ // Layout.fillWidth: true
+ // enabled: client.offset > 0
+ // onClicked: {
+ // client.previous()
+ // }
+ // }
+ // Button {
+ // text: qsTr("Next")
+ // Layout.fillWidth: true
+ // onClicked: {
+ // client.next()
+ // }
+ // }
+ // }
+ }
+
+ BusyIndicator {
+ anchors.centerIn: parent
+ running: client.busy
+ }
+ }
+}
+
diff --git a/rockwork/ContentPeerPickerPage.qml b/rockwork/qml/ContentPeerPickerPage.qml
index 7ee9702..9f9917f 100644
--- a/rockwork/ContentPeerPickerPage.qml
+++ b/rockwork/qml/ContentPeerPickerPage.qml
@@ -1,7 +1,6 @@
-import QtQuick 2.4
-import Ubuntu.Components 1.3
-import Ubuntu.Content 1.3
-import RockWork 1.0
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Page {
id: pickerPage
diff --git a/rockwork/qml/CoverPage.qml b/rockwork/qml/CoverPage.qml
new file mode 100644
index 0000000..962e876
--- /dev/null
+++ b/rockwork/qml/CoverPage.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+CoverBackground {
+ property var pebble: null
+ Image {
+ fillMode: Image.PreserveAspectCrop
+ anchors.fill: parent
+ source: "back-cover.png"
+ }
+
+ Label {
+ id: label
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: state.top
+ anchors.bottomMargin: Theme.paddingSmall
+ font.pointSize: Theme.fontSizeExtraLarge
+ text: pebble.name ? pebble.name : "Pebble"
+ }
+ Label {
+ id: state
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.verticalCenter
+ font.pointSize: Theme.fontSizeExtraSmall
+ color: Theme.highlightColor
+ text: pebble.connected ? qsTr("connected") : qsTr("disconnected")
+ }
+
+ CoverActionList {
+ id: coverAction
+ enabled: pebble.connected
+
+ CoverAction {
+ iconSource: pebble.connected ? "image://theme/icon-cover-transfers" : "image://theme/icon-cover-sync"
+ onTriggered: {
+ if (pebble.connected) {
+ pebble.requestScreenshot();
+ } else {
+ pebble.reconnect();
+ }
+ }
+ }
+ }
+}
diff --git a/rockwork/DeveloperToolsPage.qml b/rockwork/qml/DeveloperToolsPage.qml
index 2f77254..dec03d1 100644
--- a/rockwork/DeveloperToolsPage.qml
+++ b/rockwork/qml/DeveloperToolsPage.qml
@@ -1,8 +1,6 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-import Ubuntu.Components.Popups 1.3
-import Ubuntu.Content 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Page {
id: root
diff --git a/rockwork/FirmwareUpgradePage.qml b/rockwork/qml/FirmwareUpgradePage.qml
index 3281a12..0b0a6d5 100644
--- a/rockwork/FirmwareUpgradePage.qml
+++ b/rockwork/qml/FirmwareUpgradePage.qml
@@ -1,5 +1,5 @@
-import QtQuick 2.4
-import Ubuntu.Components 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
Page {
id: root
diff --git a/rockwork/HealthSettingsDialog.qml b/rockwork/qml/HealthSettingsDialog.qml
index 94e5d22..66a0215 100644
--- a/rockwork/HealthSettingsDialog.qml
+++ b/rockwork/qml/HealthSettingsDialog.qml
@@ -1,8 +1,6 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-import Ubuntu.Components.Popups 1.3
-import Ubuntu.Components.ListItems 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Dialog {
id: root
diff --git a/rockwork/ImportPackagePage.qml b/rockwork/qml/ImportPackagePage.qml
index 4f86f78..5de3df0 100644
--- a/rockwork/ImportPackagePage.qml
+++ b/rockwork/qml/ImportPackagePage.qml
@@ -1,6 +1,6 @@
-import QtQuick 2.4
-import Ubuntu.Components 1.3
-import Ubuntu.Content 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Page {
id: root
diff --git a/rockwork/qml/InfoPage.qml b/rockwork/qml/InfoPage.qml
new file mode 100644
index 0000000..b23aed1
--- /dev/null
+++ b/rockwork/qml/InfoPage.qml
@@ -0,0 +1,84 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Page {
+ title: "About RockWork"
+
+ Flickable {
+ anchors.fill: parent
+ contentHeight: contentColumn.height + units.gu(4)
+
+ ColumnLayout {
+ id: contentColumn
+ anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(2) }
+ spacing: units.gu(2)
+
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: units.gu(2)
+ UbuntuShape {
+ source: Image {
+ anchors.fill: parent
+ source: "artwork/rockwork.svg"
+ }
+ height: units.gu(6)
+ width: height
+ }
+
+ Label {
+ text: i18n.tr("Version %1").arg(version)
+ Layout.fillWidth: true
+ fontSize: "large"
+ }
+ }
+
+ ThinDivider {}
+
+ Label {
+ text: i18n.tr("Contributors")
+ Layout.fillWidth: true
+ font.bold: true
+ }
+ Label {
+ text: "Michael Zanetti<br>Brian Douglas<br>Katharine Berry"
+ Layout.fillWidth: true
+ }
+
+ ThinDivider {}
+
+ Label {
+ text: i18n.tr("Legal")
+ Layout.fillWidth: true
+ font.bold: true
+ }
+
+ Label {
+ text: "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, version 3 of the License.<br>" +
+
+ "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.<br>" +
+
+ "You should have received a copy of the GNU General Public License" +
+ "along with this program. If not, see <http://www.gnu.org/licenses/>."
+ Layout.fillWidth: true
+ wrapMode: Text.WordWrap
+ }
+
+ Label {
+ text: i18n.tr("This application is neither affiliated with nor endorsed by Pebble Technology Corp.")
+ Layout.fillWidth: true
+ wrapMode: Text.WordWrap
+ }
+ Label {
+ text: i18n.tr("Pebble is a trademark of Pebble Technology Corp.")
+ Layout.fillWidth: true
+ wrapMode: Text.WordWrap
+ }
+ }
+ }
+}
+
diff --git a/rockwork/qml/InstalledAppDelegate.qml b/rockwork/qml/InstalledAppDelegate.qml
new file mode 100644
index 0000000..e910a40
--- /dev/null
+++ b/rockwork/qml/InstalledAppDelegate.qml
@@ -0,0 +1,78 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
+
+ListItem {
+ id: root
+
+ property string uuid: ""
+ property string name: ""
+ property string iconSource: ""
+ property string vendor: ""
+ property bool hasSettings: false
+ property alias hasGrip: grip.visible
+ property bool isSystemApp: false
+
+ signal deleteApp();
+ signal configureApp();
+
+ menu: ContextMenu {
+ MenuItem {
+ visible: !root.isSystemApp
+ text: "Delete"
+ onClicked: {
+ root.deleteApp();
+ }
+ }
+ MenuItem {
+ visible: root.hasSettings
+ text: "Settings"
+ onClicked: {
+ print("Settings triggered")
+ root.configureApp();
+ }
+ }
+ }
+
+ Row {
+ anchors {
+ fill: parent
+ //margins: units.gu(1)
+ }
+ //spacing: units.gu(1)
+
+ SystemAppIcon {
+ isSystemApp: root.isSystemApp
+ uuid: root.uuid
+ iconSource: root.iconSource
+ }
+
+ Column {
+ width: parent.width
+ Label {
+ text: root.name
+ width: parent.width
+ }
+
+ Label {
+ text: root.vendor
+ width: parent.width
+ font.pixelSize: Theme.fontSizeSmall
+ }
+ }
+
+ Item {
+ id: grip
+// Layout.fillHeight: true
+// Layout.preferredWidth: height
+ opacity: (root.contentMoving || root.swiped || root.dragging) ? 0 : 1
+ Behavior on opacity { NumberAnimation {} }
+ IconButton {
+ //width: units.gu(3)
+ height: width
+ anchors.centerIn: parent
+ icon.source: "image://theme/icon-m-gesture"
+ }
+ }
+ }
+}
diff --git a/rockwork/qml/InstalledAppsPage.qml b/rockwork/qml/InstalledAppsPage.qml
new file mode 100644
index 0000000..f7c8113
--- /dev/null
+++ b/rockwork/qml/InstalledAppsPage.qml
@@ -0,0 +1,205 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
+
+Page {
+ id: root
+
+ property var pebble: null
+ property bool showWatchApps: false
+ property bool showWatchFaces: false
+
+ SilicaFlickable {
+ id: flickable
+ anchors.top: parent.top
+ width: parent.width
+ PullDownMenu {
+ MenuItem {
+ text: qsTr("Add")
+ onClicked: pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, showWatchApps: root.showWatchApps, showWatchFaces: root.showWatchFaces})
+ }
+ }
+
+ PageHeader {
+ title: showWatchApps ? (showWatchFaces ? qsTr("Apps & Watchfaces") : qsTr("Apps")) : qsTr("Watchfaces")
+ }
+
+ function configureApp(uuid) {
+ // The health app is special :/
+ if (uuid == "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}") {
+ var popup = PopupUtils.open(Qt.resolvedUrl("HealthSettingsDialog.qml"), root, {healthParams: pebble.healthParams});
+ popup.accepted.connect(function() {
+ pebble.healthParams = popup.healthParams
+ })
+ } else {
+ pebble.requestConfigurationURL(uuid);
+ }
+ }
+
+ Item {
+ anchors.fill: parent
+ ListView {
+ id: listView
+ anchors.fill: parent
+ model: root.showWatchApps ? root.pebble.installedApps : root.pebble.installedWatchfaces
+ clip: true
+ property real realContentY: contentY + originY
+
+ delegate: InstalledAppDelegate {
+ id: delegate
+ uuid: model.uuid
+ name: model.name
+ iconSource: model.icon
+ vendor: model.vendor
+ visible: dndArea.draggedIndex !== index
+ hasGrip: index > 0
+ isSystemApp: model.isSystemApp
+ hasSettings: model.hasSettings
+
+ onDeleteApp: {
+ pebble.removeApp(model.uuid)
+ }
+ onConfigureApp: {
+ root.configureApp(model.uuid)
+ }
+ onClicked: {
+ PopupUtils.open(dialogComponent, root, {app: listView.model.get(index)})
+ }
+ }
+ }
+ MouseArea {
+ id: dndArea
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ right: parent.right
+ }
+ drag.axis: Drag.YAxis
+ propagateComposedEvents: true
+ //width: units.gu(5)
+
+ property int startY: 0
+ property int draggedIndex: -1
+
+
+ onPressAndHold: {
+ startY = mouseY;
+ draggedIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height)
+ if (draggedIndex == 0) {
+ print("cannot drag settings app");
+ return;
+ }
+
+ var draggedItem = listView.model.get(draggedIndex);
+ fakeDragItem.uuid = draggedItem.uuid;
+ fakeDragItem.name = draggedItem.name;
+ fakeDragItem.vendor = draggedItem.vendor;
+ fakeDragItem.iconSource = draggedItem.icon;
+ fakeDragItem.isSystemApp = draggedItem.isSystemApp;
+ fakeDragItem.y = (fakeDragItem.height * draggedIndex) - listView.realContentY
+ drag.target = fakeDragItem;
+ }
+
+ onMouseYChanged: {
+ var newIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height)
+
+ if (newIndex > draggedIndex) {
+ newIndex = draggedIndex + 1;
+ } else if (newIndex < draggedIndex) {
+ newIndex = draggedIndex - 1;
+ } else {
+ return;
+ }
+
+ if (newIndex >= 1 && newIndex < listView.count) {
+ listView.model.move(draggedIndex, newIndex);
+ draggedIndex = newIndex;
+ }
+ }
+
+ onReleased: {
+ if (draggedIndex > -1) {
+ listView.model.commitMove();
+ draggedIndex = -1;
+ drag.target = null;
+ }
+ }
+ }
+ }
+
+
+
+ InstalledAppDelegate {
+ id: fakeDragItem
+ visible: dndArea.draggedIndex != -1
+
+ }
+
+ Component {
+ id: dialogComponent
+ Dialog {
+ id: dialog
+ property var app: null
+
+ Row {
+ SystemAppIcon {
+ height: titleCol.height
+ width: height
+ isSystemApp: app.isSystemApp
+ uuid: app.uuid
+ iconSource: app.icon
+ }
+
+ Column {
+ id: titleCol
+ width: parent.width;
+
+ Label {
+ width: parent.width;
+ text: app.name
+ font.pixelSize: Theme.fontSizeLarge
+ }
+ Label {
+ width: parent.width;
+ text: app.vendor
+ }
+ }
+ }
+
+ Button {
+ text: qsTr("Launch")
+ color: UbuntuColors.green
+ onClicked: {
+ pebble.launchApp(app.uuid);
+ PopupUtils.close(dialog);
+ }
+ }
+
+ Button {
+ text: qsTr("Configure")
+ color: UbuntuColors.blue
+ visible: app.hasSettings
+ onClicked: {
+ root.configureApp(app.uuid);
+ PopupUtils.close(dialog);
+ }
+ }
+
+ Button {
+ text: qsTr("Delete")
+ color: UbuntuColors.red
+ visible: !app.isSystemApp
+ onClicked: {
+ pebble.removeApp(app.uuid);
+ PopupUtils.close(dialog);
+ }
+ }
+
+ Button {
+ text: qsTr("Close")
+ onClicked: PopupUtils.close(dialog)
+ }
+ }
+ }
+ }
+}
diff --git a/rockwork/qml/Main.qml b/rockwork/qml/Main.qml
new file mode 100644
index 0000000..aae852b
--- /dev/null
+++ b/rockwork/qml/Main.qml
@@ -0,0 +1,45 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
+
+/*!
+ \brief MainView with a Label and Button elements.
+*/
+
+ApplicationWindow {
+ id: app
+
+ ServiceController {
+ id: serviceController
+ Component.onCompleted: {
+ if (!serviceController.serviceRunning) {
+ print("Service not running. Starting now.")
+ serviceController.startService();
+ }
+ if (pebbles.version !== version) {
+ print("Service file version (", version, ") is not equal running service version (", pebbles.version, "). Restarting service.")
+ serviceController.restartService();
+ }
+ }
+ }
+
+ Pebbles {
+ id: pebbles
+ onCountChanged: loadStack()
+ }
+
+ function loadStack() {
+ pageStack.clear()
+ if (pebbles.count == 1) {
+ pageStack.push(Qt.resolvedUrl("MainMenuPage.qml"), {pebble: pebbles.get(0)})
+ app.cover.replace(Qt.resolvedUrl("CoverPage.qml"), {pebble: pebbles.get(0)})
+ } else {
+ pageStack.push(Qt.resolvedUrl("PebblesPage.qml"))
+ }
+ }
+
+ PageStack {
+ id: pageStack
+ Component.onCompleted: loadStack();
+ }
+}
diff --git a/rockwork/qml/MainMenuPage.qml b/rockwork/qml/MainMenuPage.qml
new file mode 100644
index 0000000..6713d70
--- /dev/null
+++ b/rockwork/qml/MainMenuPage.qml
@@ -0,0 +1,292 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Page {
+ id: root
+
+ property var pebble: null
+
+ SilicaFlickable {
+ id: flickable
+ anchors.fill: parent
+ contentHeight: column.height
+
+ VerticalScrollDecorator { flickable: flickable }
+
+ PullDownMenu {
+ MenuItem {
+ text: qsTr("About")
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("InfoPage.qml"))
+ }
+ }
+ MenuItem {
+ text: qsTr("Developer tools")
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("DeveloperToolsPage.qml"), {pebble: root.pebble})
+ }
+ }
+ }
+ Column {
+ id: column
+ width: root.width
+ spacing: Theme.paddingLarge
+ PageHeader {
+ title: qsTr("RockPool")
+ }
+
+ ListView {
+ model: mainMenuModel
+ }
+
+ //Creating the menu list this way to allow the text field to be translatable (http://askubuntu.com/a/476331)
+ ListModel {
+ id: mainMenuModel
+ dynamicRoles: true
+ }
+
+ Component.onCompleted: {
+ populateMainMenu();
+ }
+
+ Connections {
+ target: root.pebble
+ onFirmwareUpgradeAvailableChanged: {
+ populateMainMenu();
+ }
+ }
+
+ function populateMainMenu() {
+ mainMenuModel.clear();
+
+ mainMenuModel.append({
+ icon: "stock_notification",
+ text: qsTr("Manage notifications"),
+ page: "NotificationsPage.qml",
+ color: "blue"
+ });
+
+ mainMenuModel.append({
+ icon: "stock_application",
+ text: qsTr("Manage Apps"),
+ page: "InstalledAppsPage.qml",
+ showWatchApps: true,
+ color: "green"
+ });
+
+ mainMenuModel.append({
+ icon: "clock-app-symbolic",
+ text: qsTr("Manage Watchfaces"),
+ page: "InstalledAppsPage.qml",
+ showWatchFaces: true,
+ color: "black"
+ });
+
+ mainMenuModel.append({
+ icon: "settings",
+ text: qsTr("Settings"),
+ page: "SettingsPage.qml",
+ showWatchFaces: true,
+ color: "gold"
+ });
+
+ if (root.pebble.firmwareUpgradeAvailable) {
+ mainMenuModel.append({
+ icon: "preferences-system-updates-symbolic",
+ text: qsTr("Firmware upgrade"),
+ page: "FirmwareUpgradePage.qml",
+ color: "red"
+ });
+ }
+ }
+
+ PebbleModels {
+ id: modelModel
+ }
+
+ Column {
+ anchors.fill: parent
+ Item {
+ //Layout.alignment: Qt.AlignHCenter
+ width: root.width
+ Image {
+ id: watchImage
+ width: implicitWidth * height / implicitHeight
+ height: parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ source: Qt.resolvedUrl("qrc:///"+modelModel.get(root.pebble.model).image)
+ fillMode: Image.PreserveAspectFit
+ }
+ Item {
+ id: watchFace
+ height: parent.height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .5 : .515)
+ width: height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .85 : 1)
+ anchors.centerIn: parent
+ anchors.horizontalCenterOffset: units.dp(1)
+ anchors.verticalCenterOffset: units.dp(modelModel.get(root.pebble.model - 1).shape === "rectangle" ? 0 : 1)
+
+ Image {
+ id: image
+ anchors.fill: parent
+ source: "file://" + root.pebble.screenshots.latestScreenshot
+ visible: false
+ }
+
+ Component.onCompleted: {
+ if (!root.pebble.screenshots.latestScreenshot) {
+ root.pebble.requestScreenshot();
+ }
+ }
+
+ Rectangle {
+ id: textItem
+ anchors.fill: parent
+ layer.enabled: true
+ radius: modelModel.get(root.pebble.model - 1).shape === "rectangle" ? units.gu(.5) : height / 2
+ // This item should be used as the 'mask'
+ layer.samplerName: "maskSource"
+ layer.effect: ShaderEffect {
+ property var colorSource: image;
+ fragmentShader: "
+ uniform lowp sampler2D colorSource;
+ uniform lowp sampler2D maskSource;
+ uniform lowp float qt_Opacity;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ gl_FragColor =
+ texture2D(colorSource, qt_TexCoord0)
+ * texture2D(maskSource, qt_TexCoord0).a
+ * qt_Opacity;
+ }
+ "
+ }
+ }
+ }
+ }
+ Column {
+ width: root.width
+ spacing: units.gu(2)
+ Rectangle {
+ height: units.gu(10)
+ width: height
+ radius: height / 2
+ color: root.pebble.connected ? "green" : "red"
+
+ IconButton {
+ anchors.fill: parent
+ anchors.margins: units.gu(2)
+ icon.source: root.pebble.connected ? "image://theme/icon-m-acknowledge" : "image://theme/icon-m-reset"
+ }
+ }
+
+ Label {
+ text: root.pebble.connected ? qsTr("Connected") : qsTr("Disconnected")
+ width: root.width
+ }
+ }
+ }
+
+
+ Column {
+ width: root.width
+ //Layout.preferredHeight: childrenRect.height
+ spacing: menuRepeater.count > 0 ? 0 : units.gu(2)
+ Label {
+ text: qsTr("Your Pebble smartwatch is disconnected. Please make sure it is powered on, within range and it is paired properly in the Bluetooth System Settings.")
+ width: parent.width - units.gu(4)
+ anchors.horizontalCenter: parent.horizontalCenter
+ wrapMode: Text.WordWrap
+ visible: !root.pebble.connected
+ font.pixelSize: Theme.fontSizeLarge
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Label {
+ text: qsTr("Your Pebble smartwatch is in factory mode and needs to be initialized.")
+ width: parent.width - units.gu(4)
+ anchors.horizontalCenter: parent.horizontalCenter
+ wrapMode: Text.WordWrap
+ visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware
+ font.pixelSize: Theme.fontSizeLarge
+ horizontalAlignment: Text.AlignHCenter
+ }
+ Button {
+ text: qsTr("Initialize Pebble")
+ onClicked: root.pebble.performFirmwareUpgrade();
+ visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware
+ color: "orange"
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ Rectangle {
+ id: upgradeIcon
+ height: units.gu(10)
+ width: height
+ radius: width / 2
+ color: Theme.highlightColor
+ anchors.horizontalCenter: parent.horizontalCenter
+ BusyIndicator {
+ anchors.horizontalCenter: parent.horizontalCenter
+ running: upgradeInProgress
+ size: BusyIndicatorSize.Large
+ }
+ visible: root.pebble.connected && root.pebble.upgradingFirmware
+ }
+
+ Label {
+ text: qsTr("Upgrading...")
+ font.pixelSize: Theme.fontSizeLarge
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: root.pebble.connected && root.pebble.upgradingFirmware
+ }
+
+ Repeater {
+ id: menuRepeater
+ model: root.pebble.connected && !root.pebble.recovery && !root.pebble.upgradingFirmware ? mainMenuModel : null
+ delegate: ListItem {
+
+ Row {
+ anchors.fill: parent
+ anchors.margins: units.gu(1)
+
+ Rectangle {
+ //Layout.fillHeight: true
+ //Layout.preferredWidth: height
+ //backgroundColor: model.color
+ Image {
+ anchors.fill: parent
+ anchors.margins: units.gu(.5)
+ source: model.icon
+ }
+ }
+
+
+ Label {
+ text: model.text
+ width: page.width
+ }
+ }
+
+ onClicked: {
+ var options = {};
+ options["pebble"] = root.pebble
+ var modelItem = mainMenuModel.get(index)
+ options["showWatchApps"] = modelItem.showWatchApps
+ options["showWatchFaces"] = modelItem.showWatchFaces
+ pageStack.push(Qt.resolvedUrl(model.page), options)
+ }
+ }
+ }
+ }
+ }
+ }
+ Connections {
+ target: pebble
+ onOpenURL: {
+ if (url) {
+ pageStack.push(Qt.resolvedUrl("AppSettingsPage.qml"), {uuid: uuid, url: url, pebble: pebble})
+ }
+ }
+ }
+}
diff --git a/rockwork/qml/NotificationsPage.qml b/rockwork/qml/NotificationsPage.qml
new file mode 100644
index 0000000..3942ecf
--- /dev/null
+++ b/rockwork/qml/NotificationsPage.qml
@@ -0,0 +1,99 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
+
+Page {
+ id: root
+
+ property var pebble: null
+
+ SilicaFlickable {
+ id: flickable
+ anchors.fill: parent
+ contentHeight: column.height
+ PageHeader {
+ title: qsTr("Notifications")
+ }
+ Column {
+
+ anchors.fill: parent
+ anchors.topMargin: units.gu(1)
+
+
+
+ Item {
+ width: parent.width
+ implicitHeight: infoLabel.height
+
+ Label {
+ id: infoLabel
+ anchors {
+ left: parent.left
+ right: parent.right
+ margins: units.gu(2)
+ }
+
+ wrapMode: Text.WordWrap
+ text: i18n.tr("Entries here will be added as notifications appear on the phone. Selected notifications will be shown on your Pebble smartwatch.")
+ }
+ }
+
+
+ ListView {
+ width: parent.width
+ //Layout.fillHeight: true
+ clip: true
+ model: root.pebble.notifications
+
+ delegate: ListItem {
+ Item {
+ Rectangle {
+ //SlotsLayout.position: SlotsLayout.Leading;
+ height: units.gu(5)
+ width: height
+ color: {
+ // Add some hacks for known icons
+ switch (model.icon) {
+ case "calendar":
+ return "orange";
+ case "settings":
+ return "grey";
+ case "dialog-question-symbolic":
+ return "red";
+ case "alarm-clock":
+ return "purple";
+ case "gpm-battery-050":
+ return "green";
+ }
+ return "black"
+ }
+ // source: Image {
+ // height: parent.height
+ // width: parent.width
+ // source: model.icon.indexOf("/") === 0 ? "file://" + model.icon : ""
+ // }
+ Label {
+ text: model.name
+ }
+
+ IconButton {
+ anchors.fill: parent
+ anchors.margins: units.gu(.5)
+ icon.source: model.icon.indexOf("/") !== 0 ? model.icon : ""
+ //color: "white"
+ }
+ }
+
+ Switch {
+ checked: model.enabled
+ // SlotsLayout.position: SlotsLayout.Trailing;
+ onClicked: {
+ root.pebble.setNotificationFilter(model.name, checked)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/rockwork/qml/PebbleModels.qml b/rockwork/qml/PebbleModels.qml
new file mode 100644
index 0000000..d2248c1
--- /dev/null
+++ b/rockwork/qml/PebbleModels.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+
+ListModel {
+ id: modelModel
+ ListElement { image: 'tintin-black.png'; shape: "rectangle" } // Fallback for Unknown
+ ListElement { image: 'tintin-black.png'; shape: "rectangle" }
+ ListElement { image: 'tintin-white.png'; shape: "rectangle" }
+ ListElement { image: 'tintin-red.png'; shape: "rectangle" }
+ ListElement { image: 'tintin-orange.png'; shape: "rectangle" }
+ ListElement { image: 'tintin-grey.png'; shape: "rectangle" }
+ ListElement { image: 'bianca-silver.png'; shape: "rectangle" }
+ ListElement { image: 'bianca-black.png'; shape: "rectangle" }
+ ListElement { image: 'tintin-blue.png'; shape: "rectangle" }
+ ListElement { image: 'tintin-green.png'; shape: "rectangle" }
+ ListElement { image: 'tintin-pink.png'; shape: "rectangle" }
+ ListElement { image: 'snowy-white.png'; shape: "rectangle" }
+ ListElement { image: 'snowy-black.png'; shape: "rectangle" }
+ ListElement { image: 'snowy-red.png'; shape: "rectangle" }
+ ListElement { image: 'bobby-silver.png'; shape: "rectangle" }
+ ListElement { image: 'bobby-black.png'; shape: "rectangle" }
+ ListElement { image: 'bobby-gold.png'; shape: "rectangle" }
+ ListElement { image: 'spalding-14mm-silver.png'; shape: "round" }
+ ListElement { image: 'spalding-14mm-black.png'; shape: "round" }
+ ListElement { image: 'spalding-20mm-silver.png'; shape: "round" }
+ ListElement { image: 'spalding-20mm-black.png'; shape: "round" }
+ ListElement { image: 'spalding-14mm-rose-gold.png'; shape: "round" }
+}
+
diff --git a/rockwork/PebblesPage.qml b/rockwork/qml/PebblesPage.qml
index a973b0a..13aca60 100644
--- a/rockwork/PebblesPage.qml
+++ b/rockwork/qml/PebblesPage.qml
@@ -1,6 +1,6 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Page {
title: i18n.tr("Manage Pebble Watches")
diff --git a/rockwork/ScreenshotsPage.qml b/rockwork/qml/ScreenshotsPage.qml
index fdbeb9a..28ca866 100644
--- a/rockwork/ScreenshotsPage.qml
+++ b/rockwork/qml/ScreenshotsPage.qml
@@ -1,9 +1,6 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-import Ubuntu.Components.Popups 1.3
-import Ubuntu.Content 1.3
-import RockWork 1.0
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Page {
id: root
diff --git a/rockwork/SettingsPage.qml b/rockwork/qml/SettingsPage.qml
index 153aaf4..8116f7a 100644
--- a/rockwork/SettingsPage.qml
+++ b/rockwork/qml/SettingsPage.qml
@@ -1,7 +1,6 @@
-import QtQuick 2.4
-import QtQuick.Layouts 1.1
-import Ubuntu.Components 1.3
-import Ubuntu.Components.ListItems 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Page {
id: root
diff --git a/rockwork/SystemAppIcon.qml b/rockwork/qml/SystemAppIcon.qml
index 88e37bc..3823cf2 100644
--- a/rockwork/SystemAppIcon.qml
+++ b/rockwork/qml/SystemAppIcon.qml
@@ -1,5 +1,6 @@
-import QtQuick 2.4
-import Ubuntu.Components 1.3
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import RockPool 1.0
Item {
id: root
@@ -8,10 +9,10 @@ Item {
property string uuid: ""
property string iconSource: ""
- UbuntuShape {
+ Rectangle {
anchors.fill: parent
visible: root.isSystemApp
- backgroundColor: {
+ color: {
switch (root.uuid) {
case "{07e0d9cb-8957-4bf7-9d42-35bf47caadfe}":
return "gray";
@@ -32,28 +33,27 @@ Item {
return "";
}
}
- Icon {
+ IconButton {
anchors.fill: parent
implicitHeight: height
- anchors.margins: units.gu(1)
+ //anchors.margins: units.gu(1)
visible: root.isSystemApp
- color: "white"
- name: {
+ icon.source: {
switch (root.uuid) {
case "{07e0d9cb-8957-4bf7-9d42-35bf47caadfe}":
- return "settings";
+ return "image://theme/icon-m-developer-mode";
case "{18e443ce-38fd-47c8-84d5-6d0c775fbe55}":
- return "clock-app-symbolic";
+ return "image://theme/icon-m-clock";
case "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}":
- return "like";
+ return "image://theme/icon-m-like";
case "{1f03293d-47af-4f28-b960-f2b02a6dd757}":
- return "stock_music";
+ return "image://theme/icon-m-music";
case "{b2cae818-10f8-46df-ad2b-98ad2254a3c1}":
- return "stock_notification";
+ return "image://theme/icon-m-notifications";
case "{67a32d95-ef69-46d4-a0b9-854cc62f97f9}":
- return "stock_alarm-clock";
+ return "image://theme/icon-m-alarm";
case "{8f3c8686-31a1-4f5f-91f5-01600c9bdc59}":
- return "clock-app-symbolic";
+ return "image://theme/icon-m-clock";
}
return "";
}
diff --git a/rockwork/rockpool.desktop b/rockwork/rockpool.desktop
new file mode 100644
index 0000000..989d24d
--- /dev/null
+++ b/rockwork/rockpool.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Name=RockPool
+Exec=rockpool
+Icon=rockpool
+Type=Application
+X-Nemo-Application-Type=silica-qt5
+
diff --git a/rockwork/rockpool.png b/rockwork/rockpool.png
new file mode 100644
index 0000000..571ac11
--- /dev/null
+++ b/rockwork/rockpool.png
Binary files differ
diff --git a/rockwork/rockwork.apparmor b/rockwork/rockwork.apparmor
deleted file mode 100644
index 9756323..0000000
--- a/rockwork/rockwork.apparmor
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "policy_groups": [
- "networking"
- ],
- "policy_version": 1.3,
- "template": "unconfined"
-}
diff --git a/rockwork/rockwork.desktop b/rockwork/rockwork.desktop
deleted file mode 100644
index 0a75199..0000000
--- a/rockwork/rockwork.desktop
+++ /dev/null
@@ -1,8 +0,0 @@
-[Desktop Entry]
-Name=RockWork
-Exec=rockwork
-Icon=rockwork/rockwork.svg
-Terminal=false
-Type=Application
-X-Ubuntu-Touch=true
-
diff --git a/rockwork/rockwork.pro b/rockwork/rockwork.pro
index 43b1dea..a695e42 100644
--- a/rockwork/rockwork.pro
+++ b/rockwork/rockwork.pro
@@ -1,72 +1,54 @@
-TEMPLATE = app
-TARGET = rockwork
-
-include(../version.pri)
-load(ubuntu-click)
-
-QT += qml quick dbus
-
-CONFIG += c++11
-
-HEADERS += \
- notificationsourcemodel.h \
- servicecontrol.h \
- pebble.h \
- pebbles.h \
- applicationsmodel.h \
- applicationsfiltermodel.h \
- appstoreclient.h \
- screenshotmodel.h
-
-SOURCES += main.cpp \
- notificationsourcemodel.cpp \
- servicecontrol.cpp \
- pebble.cpp \
- pebbles.cpp \
- applicationsmodel.cpp \
- applicationsfiltermodel.cpp \
- appstoreclient.cpp \
- screenshotmodel.cpp
-
-RESOURCES += rockwork.qrc
-
-QML_FILES += $$files(*.qml,true) \
- $$files(*.js,true)
-
-CONF_FILES += rockwork.apparmor \
- rockwork.svg \
- rockwork.desktop \
- rockwork.url-dispatcher
-
-AP_TEST_FILES += tests/autopilot/run \
- $$files(tests/*.py,true)
-
-#show all the files in QtCreator
-OTHER_FILES += $${CONF_FILES} \
- $${QML_FILES} \
- $${AP_TEST_FILES} \
-
-
-#specify where the config files are installed to
-config_files.path = /rockwork
-config_files.files += $${CONF_FILES}
-INSTALLS+=config_files
-
-#install the desktop file, a translated version is
-#automatically created in the build directory
-desktop_file.path = /rockwork
-desktop_file.files = $$OUT_PWD/rockwork.desktop
-desktop_file.CONFIG += no_check_exist
-INSTALLS+=desktop_file
-
-# Default rules for deployment.
-target.path = $${UBUNTU_CLICK_BINARY_PATH}
-INSTALLS+=target
-
-DISTFILES += \
- NotificationsPage.qml \
- PebblesPage.qml \
- AppStorePage.qml \
- AppStoreDetailsPage.qml \
- PebbleModels.qml \
- InfoPage.qml
+TARGET = rockpool
+
+include(../version.pri)
+
+QT += qml quick dbus webkit quick-private webkit-private
+
+CONFIG += c++11
+CONFIG += sailfishapp
+
+HEADERS += \
+ notificationsourcemodel.h \
+ servicecontrol.h \
+ pebble.h \
+ pebbles.h \
+ applicationsmodel.h \
+ applicationsfiltermodel.h \
+ appstoreclient.h \
+ screenshotmodel.h
+
+SOURCES += main.cpp \
+ notificationsourcemodel.cpp \
+ servicecontrol.cpp \
+ pebble.cpp \
+ pebbles.cpp \
+ applicationsmodel.cpp \
+ applicationsfiltermodel.cpp \
+ appstoreclient.cpp \
+ screenshotmodel.cpp
+
+RESOURCES += rockwork.qrc
+
+QML_FILES += $$files(qml/*.qml,true)
+
+CONF_FILES += rockpool.png \
+ rockpool.desktop
+
+#show all the files in QtCreator
+OTHER_FILES += $${QML_FILES} \
+ $${CONF_FILES}
+
+#specify where the qml files are installed to
+qml.path = /usr/share/rockpool/qml
+qml.files += $${QML_FILES}
+INSTALLS+=qml
+
+#and the app icon
+icon.path = /usr/share/icons/hicolor/86x86/apps/
+icon.files = rockpool.png
+INSTALLS+=icon
+
+# Default rules for deployment.
+INSTALLS+=target icon
+target.path = /usr/bin
+
diff --git a/rockwork/rockwork.qrc b/rockwork/rockwork.qrc
index 1d565a1..3cb6f76 100644
--- a/rockwork/rockwork.qrc
+++ b/rockwork/rockwork.qrc
@@ -1,18 +1,6 @@
<RCC>
<qresource prefix="/">
- <file>Main.qml</file>
- <file>NotificationsPage.qml</file>
- <file>PebblesPage.qml</file>
- <file>InstalledAppsPage.qml</file>
- <file>MainMenuPage.qml</file>
- <file>AppSettingsPage.qml</file>
- <file>AppStorePage.qml</file>
- <file>AppStoreDetailsPage.qml</file>
- <file>InstalledAppDelegate.qml</file>
- <file>SystemAppIcon.qml</file>
- <file>ScreenshotsPage.qml</file>
- <file>snowywhite.svg</file>
- <file>snowywhite.png</file>
+ <file>artwork/back-cover.png</file>
<file>artwork/bianca-black.png</file>
<file>artwork/bianca-silver.png</file>
<file>artwork/black-20mm-hole.png</file>
@@ -35,14 +23,5 @@
<file>artwork/tintin-pink.png</file>
<file>artwork/tintin-red.png</file>
<file>artwork/tintin-white.png</file>
- <file>PebbleModels.qml</file>
- <file>FirmwareUpgradePage.qml</file>
- <file>InfoPage.qml</file>
- <file>artwork/rockwork.svg</file>
- <file>DeveloperToolsPage.qml</file>
- <file>ContentPeerPickerPage.qml</file>
- <file>HealthSettingsDialog.qml</file>
- <file>SettingsPage.qml</file>
- <file>ImportPackagePage.qml</file>
</qresource>
</RCC>
diff --git a/rockwork/rockwork.svg b/rockwork/rockwork.svg
deleted file mode 100644
index e4e92c0..0000000
--- a/rockwork/rockwork.svg
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="72.248886mm"
- height="72.248886mm"
- viewBox="0 0 255.99999 255.99999"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="upebble.svg">
- <defs
- id="defs4">
- <filter
- inkscape:collect="always"
- style="color-interpolation-filters:sRGB"
- id="filter4248"
- x="-0.025328101"
- width="1.0506562"
- y="-0.013960773"
- height="1.0279215">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2.3907822"
- id="feGaussianBlur4250" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="3.959798"
- inkscape:cx="89.121544"
- inkscape:cy="77.044911"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:window-width="2880"
- inkscape:window-height="1752"
- inkscape:window-x="0"
- inkscape:window-y="48"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- originx="-40.000001"
- originy="-539"
- snapvisiblegridlinesonly="true"
- enabled="false" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-40,-257.36221)">
- <rect
- style="opacity:1;fill:#78d3fc;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4200"
- width="256"
- height="256"
- x="40"
- y="257.36221" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:0.0479798;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 40,257.36221 256,0 -256,256 z"
- id="rect4252"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" />
- <g
- id="g4300">
- <g
- style="fill:#000000;fill-opacity:1;opacity:0.291;filter:url(#filter4248)"
- id="g4202"
- transform="matrix(0.60632857,0,0,0.60632857,-37.462675,74.399202)">
- <path
- sodipodi:nodetypes="czccc"
- inkscape:connector-curvature="0"
- id="path4204"
- d="m 437.97969,445.08937 c 0,0 11.49464,-4.59544 12.27285,0.25253 0.77821,4.84797 2.06459,45.23266 2.06459,45.23266 -8.36034,0.32794 -13.15013,-0.0886 -13.15013,-0.0886 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path4206"
- d="m 439.49492,491.6046 12.68287,0.70015 0.54937,42.27954 -13.73731,0.25254 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4208"
- width="120"
- height="95"
- x="280"
- y="623.36218" />
- <rect
- y="307.36221"
- x="280"
- height="95"
- width="120"
- id="rect4210"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zcczz"
- inkscape:connector-curvature="0"
- id="path4212"
- d="M 228.0862,442.4309 C 228.58744,435.98794 240,437.36221 240,437.36221 l 0,42.02031 c 0,0 -14.31567,-1.22669 -13.80125,-2.84014 0.51442,-1.61345 1.3862,-27.66851 1.88745,-34.11148 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 420,643.715 337.60905,658.36221 255,643.715 l 0,-20 165,0 z"
- id="path4214"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="path4216"
- d="M 255,382.36221 337.39095,367.715 420,382.36221 l 0,20 -165,0 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cczcc"
- inkscape:connector-curvature="0"
- id="path4218"
- d="m 438.52906,535.82255 c 0,0 5.15979,0.84007 13.83236,0.44761 0.13423,13.76866 -1.20901,37.74804 -1.85634,42.35471 -0.64733,4.60667 -11.01016,-0.50508 -11.01016,-0.50508 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zzzzzzzzz"
- inkscape:connector-curvature="0"
- id="path4220"
- d="m 244.85206,406.56127 c 16.07143,-13.92858 66.12644,-13.34299 97.65304,-13.30725 31.5266,0.0357 73.56632,-0.53467 90.70918,15.17961 17.14286,15.71428 12.91706,70.98675 13.01566,106.0726 0.0986,35.08586 5.19864,81.42741 -13.01565,99.64169 C 415,632.3622 371.12033,628.47664 339.15317,628.18658 307.186,627.89652 263.91063,632.7014 245.3392,615.91569 226.76777,599.12997 231.43107,540.45867 231.61582,505.9352 c 0.18475,-34.52347 -2.83519,-85.44536 13.23624,-99.37393 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- ry="20"
- rx="20"
- y="422.36221"
- x="260"
- height="174.99998"
- width="155"
- id="rect4222"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- y="442.36221"
- x="280"
- height="135"
- width="120"
- id="rect4224"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0"
- id="path4226"
- d="m 375,442.36221 25,0 0,135 -25,0 0,-109.75206 -7.32361,-5.3033 7.32361,-4.9245 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
- <path
- sodipodi:nodetypes="czccc"
- inkscape:connector-curvature="0"
- id="rect4177"
- d="m 228.09692,344.2696 c 0,0 6.96953,-2.78634 7.44138,0.15312 0.47185,2.93946 1.25182,27.42585 1.25182,27.42585 -5.06911,0.19884 -7.9733,-0.0537 -7.9733,-0.0537 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="rect4179"
- d="m 229.01565,372.47312 7.68999,0.42452 0.3331,25.63529 -8.32933,0.15312 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4167"
- width="72.75943"
- height="57.601215"
- x="132.30933"
- y="452.36151" />
- <rect
- y="260.76169"
- x="132.30933"
- height="57.601215"
- width="72.75943"
- id="rect4165"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zcczz"
- inkscape:connector-curvature="0"
- id="rect4169"
- d="m 100.8325,342.6577 c 0.30392,-3.90655 7.22368,-3.07329 7.22368,-3.07329 l 0,25.47811 c 0,0 -8.679998,-0.74378 -8.36809,-1.72206 0.311907,-0.97828 0.84049,-16.77621 1.14441,-20.68276 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 217.19532,464.702 -49.95598,8.88102 -50.08823,-8.88102 0,-12.12657 100.04421,0 z"
- id="path4175"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="rect4172"
- d="m 117.15111,306.23633 49.95599,-8.88102 50.08822,8.88102 0,12.12658 -100.04421,0 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cczcc"
- inkscape:connector-curvature="0"
- id="rect4181"
- d="m 228.43002,399.28372 c 0,0 3.12853,0.50936 8.38696,0.2714 0.0814,8.34833 -0.73306,22.88772 -1.12555,25.68087 -0.3925,2.79316 -6.67578,-0.30624 -6.67578,-0.30624 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="zzzzzzzzz"
- inkscape:connector-curvature="0"
- id="rect4149"
- d="m 110.99812,320.90892 c 9.74457,-8.4453 40.09435,-8.09024 59.20983,-8.06857 19.11548,0.0217 44.60536,-0.32419 54.99957,9.20383 10.39421,9.52802 7.83198,43.0413 7.89177,64.31485 0.0598,21.27356 3.15208,49.37176 -7.89176,60.4156 -11.04385,11.04384 -37.64935,8.68791 -57.03195,8.51204 -19.38261,-0.17587 -45.6217,2.73747 -56.88209,-7.44019 -11.26039,-10.17766 -8.4329,-45.75175 -8.32088,-66.68431 0.11202,-20.93257 -1.71905,-51.80796 8.02551,-60.25325 z"
- style="opacity:1;fill:#cbcbcb;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 133.22587,330.48948 69.72779,0 c 6.71812,0 11.83367,5.41484 12.12657,12.12657 1.19073,27.28478 1.19022,54.56956 0,81.85435 -0.29278,6.71174 -5.40845,12.12657 -12.12657,12.12657 l -69.72779,0 c -6.71812,0 -11.82926,-5.41504 -12.12657,-12.12657 -1.18246,-26.69356 -1.65764,-53.74075 0,-81.85435 0.39543,-6.70647 5.40845,-12.12657 12.12657,-12.12657 z"
- id="rect4152"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="sssssssss" />
- <rect
- y="342.61606"
- x="131.62029"
- height="81.854355"
- width="72.75943"
- id="rect4154"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0"
- id="rect4156"
- d="m 189.2215,342.61605 15.15821,0 0,81.85436 -15.15821,0 0,-66.54581 -4.44052,-3.21555 4.44052,-2.98586 z"
- style="opacity:1;fill:#78d3fc;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
- <path
- style="fill:#000000"
- d="m 143.63128,393.17695 c -0.82884,-0.82884 0.32908,-1.46136 2.67524,-1.46136 3.02637,0 3.07586,-0.7116 0.31911,-4.58902 l -2.10477,-2.96041 2.0287,-2.94922 c 1.15063,-1.67272 2.20678,-4.13671 2.44014,-5.69282 0.40696,-2.71383 0.44252,-2.74828 3.27625,-3.17322 1.57564,-0.23629 4.03472,-1.23453 5.46462,-2.21832 1.42988,-0.98379 2.85437,-1.78871 3.16551,-1.78871 0.31114,0 1.68177,0.80847 3.04585,1.7966 1.40341,1.01663 3.70432,1.98019 5.29992,2.21946 2.92933,0.43928 2.99923,0.52347 3.81465,4.59457 0.23714,1.18397 1.22649,3.16119 2.19857,4.39382 0.97208,1.23265 1.76741,2.42825 1.76741,2.6569 0,0.22864 -0.83031,1.62253 -1.84514,3.09753 -2.44659,3.556 -2.38325,4.49115 0.32038,4.72947 1.19102,0.10499 2.22891,0.46766 2.30641,0.80594 0.15778,0.68864 -33.49245,1.21919 -34.17285,0.53879 z m 27.8729,-2.84521 c 0.009,-0.76112 0.83738,-2.4679 1.83992,-3.79283 l 1.82279,-2.40898 -1.58789,-2.08183 c -0.87334,-1.14501 -1.90888,-3.37431 -2.30119,-4.954 -0.68475,-2.75721 -0.82407,-2.89364 -3.48101,-3.40876 -1.52223,-0.29514 -3.68339,-1.22898 -4.80255,-2.0752 l -2.03486,-1.53859 -2.27046,1.53481 c -2.19134,1.48132 -2.85113,1.74296 -6.34208,2.51493 -1.32103,0.29212 -1.68348,0.80695 -2.01126,2.85674 -0.2199,1.37522 -1.11243,3.57721 -1.98338,4.8933 l -1.58355,2.39291 1.54803,2.0343 c 0.85141,1.11887 1.73796,2.79542 1.97011,3.72567 l 0.42209,1.69138 10.38909,0 c 10.35877,0 10.38914,-0.004 10.4062,-1.38385 z m -16.16204,-1.17442 c -3.00082,-0.83158 -3.29439,-2.70542 -0.30753,-1.96294 1.0994,0.27329 2.9676,0.49689 4.15156,0.49689 1.18396,0 3.05216,-0.2236 4.15155,-0.49689 1.34833,-0.33517 1.9989,-0.27586 1.9989,0.18225 0,1.61808 -6.44052,2.76557 -9.99448,1.78069 z m -1.87921,-5.21512 c -0.23497,-0.23497 -0.42721,-1.51123 -0.42721,-2.83614 0,-2.76084 1.40937,-2.98541 1.73071,-0.27578 0.21201,1.78766 -0.62633,3.78908 -1.3035,3.11192 z m 10.02856,-2.68238 c 0,-1.7768 0.25627,-2.46018 0.92256,-2.46018 0.6663,0 0.92257,0.68338 0.92257,2.46018 0,1.7768 -0.25627,2.46018 -0.92257,2.46018 -0.66629,0 -0.92256,-0.68338 -0.92256,-2.46018 z m -22.75668,2.7677 c 0,-0.69366 0.43166,-0.94682 1.38386,-0.81158 0.76111,0.10809 1.38385,0.47331 1.38385,0.81158 0,0.33828 -0.62274,0.70349 -1.38385,0.81159 -0.9522,0.13523 -1.38386,-0.11793 -1.38386,-0.81159 z m 37.8226,0.30318 c -0.46699,-0.7556 1.22568,-1.49279 2.13592,-0.93022 0.35999,0.22248 0.4953,0.66216 0.30068,0.97707 -0.46943,0.75955 -1.95589,0.73096 -2.4366,-0.0469 z m -32.49939,-13.42132 c -1.23387,-1.36341 -1.29125,-1.95046 -0.19065,-1.95046 1.05106,0 3.00139,2.11681 2.45435,2.66385 -0.65422,0.65422 -1.17438,0.49029 -2.2637,-0.71339 z m 27.38286,0.11435 c 0.23773,-1.20797 2.11252,-2.50883 2.72827,-1.89307 0.48678,0.48678 -1.47947,2.90348 -2.36232,2.90348 -0.31065,0 -0.47533,-0.45468 -0.36595,-1.01041 z m -13.38512,-4.7488 c -0.52662,-1.37234 -0.0519,-3.6431 0.82178,-3.93083 0.51752,-0.17043 0.76881,0.45533 0.76881,1.91443 0,2.29458 -0.99824,3.56005 -1.59059,2.0164 z"
- id="path4285"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ssscsssssssssssssssscsssscsssscsscsssssssssssssssssssssscssccssssssssssss" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="136.46957"
- y="405.82156"
- id="text4342"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan4344"
- x="136.46957"
- y="405.82156"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu">Tomorrow</tspan></text>
- </g>
-</svg>
diff --git a/rockwork/rockwork.url-dispatcher b/rockwork/rockwork.url-dispatcher
deleted file mode 100644
index 3453482..0000000
--- a/rockwork/rockwork.url-dispatcher
+++ /dev/null
@@ -1,5 +0,0 @@
-[
- {
- "protocol": "pebblejs"
- }
-]
diff --git a/rockwork/servicecontrol.cpp b/rockwork/servicecontrol.cpp
index 4d6903f..ced7f1a 100644
--- a/rockwork/servicecontrol.cpp
+++ b/rockwork/servicecontrol.cpp
@@ -5,84 +5,42 @@
#include <QDebug>
#include <QCoreApplication>
#include <QProcess>
+#include <QDBusReply>
-ServiceControl::ServiceControl(QObject *parent) : QObject(parent)
+ServiceControl::ServiceControl(QObject *parent) : QObject(parent),
+ systemd(new QDBusInterface("org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ QDBusConnection::sessionBus(), this))
{
+ systemd->call("Subscribe");
-}
+ QDBusReply<QDBusObjectPath> unit = systemd->call("LoadUnit", ROCKPOOLD_SYSTEMD_UNIT);
+ if (unit.isValid()) {
+ unitPath = unit.value();
-QString ServiceControl::serviceName() const
-{
- return m_serviceName;
-}
+ getUnitProperties();
-void ServiceControl::setServiceName(const QString &serviceName)
-{
- if (m_serviceName != serviceName) {
- m_serviceName = serviceName;
- emit serviceNameChanged();
+ QDBusConnection::sessionBus().connect(
+ "org.freedesktop.systemd1", unitPath.path(),
+ "org.freedesktop.DBus.Properties", "PropertiesChanged",
+ this, SLOT(onPropertiesChanged(QString,QMap<QString,QVariant>,QStringList)));
+ } else {
+ qWarning() << unit.error().message();
}
}
-bool ServiceControl::serviceFileInstalled() const
+void ServiceControl::onPropertiesChanged(QString interface, QMap<QString,QVariant> changed, QStringList invalidated)
{
- if (m_serviceName.isEmpty()) {
- qDebug() << "Service name not set.";
- return false;
- }
- QFile f(QDir::homePath() + "/.config/upstart/" + m_serviceName + ".conf");
- return f.exists();
-}
-
-bool ServiceControl::installServiceFile()
-{
- if (m_serviceName.isEmpty()) {
- qDebug() << "Service name not set. Cannot generate service file.";
- return false;
- }
-
- QFile f(QDir::homePath() + "/.config/upstart/" + m_serviceName + ".conf");
- if (f.exists()) {
- qDebug() << "Service file already existing...";
- return false;
- }
-
- if (!f.open(QFile::WriteOnly | QFile::Truncate)) {
- qDebug() << "Cannot create service file";
- return false;
- }
-
- QString appDir = qApp->applicationDirPath();
- // Try to replace version with "current" to be more robust against updates
- appDir.replace(QRegExp("rockwork.mzanetti\/[0-9.]*\/"), "rockwork.mzanetti/current/");
-
- f.write("start on started unity8\n");
- f.write("pre-start script\n");
- f.write(" initctl set-env LD_LIBRARY_PATH=" + appDir.toUtf8() + "/../:$LD_LIBRARY_PATH\n");
- f.write("end script\n");
- f.write("exec " + appDir.toUtf8() + "/" + m_serviceName.toUtf8() + "\n");
- f.close();
- return true;
-}
-
-bool ServiceControl::removeServiceFile()
-{
- if (m_serviceName.isEmpty()) {
- qDebug() << "Service name not set.";
- return false;
- }
- QFile f(QDir::homePath() + "/.config/upstart/" + m_serviceName + ".conf");
- return f.remove();
+ qDebug() << Q_FUNC_INFO << interface << changed << invalidated;
+ if (interface != "org.freedesktop.systemd1.Unit") return;
+ if (invalidated.contains("UnitFileState") || invalidated.contains("ActiveState"))
+ getUnitProperties();
}
bool ServiceControl::serviceRunning() const
{
- QProcess p;
- p.start("initctl", {"status", m_serviceName});
- p.waitForFinished();
- QByteArray output = p.readAll();
- qDebug() << output;
- return output.contains("running");
+ return unitProperties["UnitFileState"].toString() == "enabled";
}
bool ServiceControl::setServiceRunning(bool running)
@@ -97,22 +55,49 @@ bool ServiceControl::setServiceRunning(bool running)
bool ServiceControl::startService()
{
- qDebug() << "should start service";
- int ret = QProcess::execute("start", {m_serviceName});
- return ret == 0;
+ QDBusError reply;
+ systemd->call("EnableUnitFiles", QStringList() << ROCKPOOLD_SYSTEMD_UNIT, false, true);
+ if (reply.isValid()) {
+ qWarning() << reply.message();
+ return false;
+ } else {
+ systemd->call("Reload");
+ return true;
+ }
}
bool ServiceControl::stopService()
{
- qDebug() << "should stop service";
- int ret = QProcess::execute("stop", {m_serviceName});
- return ret == 0;
+ QDBusError reply;
+ systemd->call("DisableUnitFiles", QStringList() << ROCKPOOLD_SYSTEMD_UNIT, false);
+ if (reply.isValid()) {
+ qWarning() << reply.message();
+ return false;
+ } else {
+ systemd->call("Reload");
+ return true;
+ }
}
bool ServiceControl::restartService()
{
- qDebug() << "should stop service";
- int ret = QProcess::execute("restart", {m_serviceName});
- return ret == 0;
+ return stopService() && startService();
}
+void ServiceControl::getUnitProperties()
+{
+ QDBusMessage request = QDBusMessage::createMethodCall(
+ "org.freedesktop.systemd1", unitPath.path(),
+ "org.freedesktop.DBus.Properties", "GetAll");
+ request << "org.freedesktop.systemd1.Unit";
+ QDBusReply<QVariantMap> reply = QDBusConnection::sessionBus().call(request);
+ if (reply.isValid()) {
+ QVariantMap newProperties = reply.value();
+ //bool emitEnabledChanged = (unitProperties["UnitFileState"] != newProperties["UnitFileState"]);
+ bool emitRunningChanged = (unitProperties["ActiveState"] != newProperties["ActiveState"]);
+ unitProperties = newProperties;
+ if (emitRunningChanged) emit serviceRunning();
+ } else {
+ qWarning() << reply.error().message();
+ }
+}
diff --git a/rockwork/servicecontrol.h b/rockwork/servicecontrol.h
index 4689506..ebab061 100644
--- a/rockwork/servicecontrol.h
+++ b/rockwork/servicecontrol.h
@@ -1,38 +1,37 @@
#ifndef SERVICECONTROL_H
#define SERVICECONTROL_H
+#include <QDBusInterface>
#include <QObject>
+static const QString ROCKPOOLD_SYSTEMD_UNIT("rockpoold.service");
+
class ServiceControl : public QObject
{
Q_OBJECT
- Q_PROPERTY(QString serviceName READ serviceName WRITE setServiceName NOTIFY serviceNameChanged)
- Q_PROPERTY(bool serviceFileInstalled READ serviceFileInstalled NOTIFY serviceFileInstalledChanged)
Q_PROPERTY(bool serviceRunning READ serviceRunning WRITE setServiceRunning NOTIFY serviceRunningChanged)
public:
explicit ServiceControl(QObject *parent = 0);
- QString serviceName() const;
- void setServiceName(const QString &serviceName);
-
- bool serviceFileInstalled() const;
- Q_INVOKABLE bool installServiceFile();
- Q_INVOKABLE bool removeServiceFile();
-
bool serviceRunning() const;
bool setServiceRunning(bool running);
Q_INVOKABLE bool startService();
Q_INVOKABLE bool stopService();
Q_INVOKABLE bool restartService();
+private slots:
+ void getUnitProperties();
+ void onPropertiesChanged(QString interface, QMap<QString, QVariant> changed, QStringList invalidated);
+
signals:
- void serviceNameChanged();
- void serviceFileInstalledChanged();
void serviceRunningChanged();
private:
- QString m_serviceName;
+ QDBusInterface *systemd;
+ QDBusObjectPath unitPath;
+ QVariantMap unitProperties;
+
};
#endif // SERVICECONTROL_H
diff --git a/rockwork/snowywhite.png b/rockwork/snowywhite.png
deleted file mode 100644
index 1a354b4..0000000
--- a/rockwork/snowywhite.png
+++ /dev/null
Binary files differ
diff --git a/rockwork/snowywhite.svg b/rockwork/snowywhite.svg
deleted file mode 100644
index 0544670..0000000
--- a/rockwork/snowywhite.svg
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="72.248886mm"
- height="72.248886mm"
- viewBox="0 0 255.99999 255.99999"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="snowywhite.svg">
- <defs
- id="defs4">
- <filter
- inkscape:collect="always"
- style="color-interpolation-filters:sRGB"
- id="filter4364"
- x="-0.059098901"
- width="1.1181978"
- y="-0.032575137"
- height="1.0651503">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="5.5784918"
- id="feGaussianBlur4366" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="3.959798"
- inkscape:cx="89.121544"
- inkscape:cy="77.044911"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:window-width="2880"
- inkscape:window-height="1752"
- inkscape:window-x="0"
- inkscape:window-y="48"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- originx="-40.000001"
- originy="-539"
- snapvisiblegridlinesonly="true"
- enabled="false" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-40,-257.36221)">
- <g
- transform="matrix(0.60632857,0,0,0.60632857,-37.462675,74.399202)"
- id="g4202"
- style="opacity:0.581;fill:#000000;fill-opacity:1;filter:url(#filter4364)">
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 437.97969,445.08937 c 0,0 11.49464,-4.59544 12.27285,0.25253 0.77821,4.84797 2.06459,45.23266 2.06459,45.23266 -8.36034,0.32794 -13.15013,-0.0886 -13.15013,-0.0886 z"
- id="path4204"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czccc" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 439.49492,491.6046 12.68287,0.70015 0.54937,42.27954 -13.73731,0.25254 z"
- id="path4206"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <rect
- y="623.36218"
- x="280"
- height="95"
- width="120"
- id="rect4208"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4210"
- width="120"
- height="95"
- x="280"
- y="307.36221" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 228.0862,442.4309 C 228.58744,435.98794 240,437.36221 240,437.36221 l 0,42.02031 c 0,0 -14.31567,-1.22669 -13.80125,-2.84014 0.51442,-1.61345 1.3862,-27.66851 1.88745,-34.11148 z"
- id="path4212"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="zcczz" />
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="path4214"
- d="M 420,643.715 337.60905,658.36221 255,643.715 l 0,-20 165,0 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 255,382.36221 337.39095,367.715 420,382.36221 l 0,20 -165,0 z"
- id="path4216"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 438.52906,535.82255 c 0,0 5.15979,0.84007 13.83236,0.44761 0.13423,13.76866 -1.20901,37.74804 -1.85634,42.35471 -0.64733,4.60667 -11.01016,-0.50508 -11.01016,-0.50508 z"
- id="path4218"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cczcc" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 244.85206,406.56127 c 16.07143,-13.92858 66.12644,-13.34299 97.65304,-13.30725 31.5266,0.0357 73.56632,-0.53467 90.70918,15.17961 17.14286,15.71428 12.91706,70.98675 13.01566,106.0726 0.0986,35.08586 5.19864,81.42741 -13.01565,99.64169 C 415,632.3622 371.12033,628.47664 339.15317,628.18658 307.186,627.89652 263.91063,632.7014 245.3392,615.91569 226.76777,599.12997 231.43107,540.45867 231.61582,505.9352 c 0.18475,-34.52347 -2.83519,-85.44536 13.23624,-99.37393 z"
- id="path4220"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="zzzzzzzzz" />
- <rect
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4222"
- width="155"
- height="174.99998"
- x="260"
- y="422.36221"
- rx="20"
- ry="20" />
- <rect
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4224"
- width="120"
- height="135"
- x="280"
- y="442.36221" />
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 375,442.36221 25,0 0,135 -25,0 0,-109.75206 -7.32361,-5.3033 7.32361,-4.9245 z"
- id="path4226"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccc" />
- </g>
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 228.09692,344.2696 c 0,0 6.96953,-2.78634 7.44138,0.15312 0.47185,2.93946 1.25182,27.42585 1.25182,27.42585 -5.06911,0.19884 -7.9733,-0.0537 -7.9733,-0.0537 z"
- id="rect4177"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czccc" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 229.01565,372.47312 7.68999,0.42452 0.3331,25.63529 -8.32933,0.15312 z"
- id="rect4179"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <rect
- y="452.36151"
- x="132.30933"
- height="57.601215"
- width="72.75943"
- id="rect4167"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4165"
- width="72.75943"
- height="57.601215"
- x="132.30933"
- y="260.76169" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 100.8325,342.6577 c 0.30392,-3.90655 7.22368,-3.07329 7.22368,-3.07329 l 0,25.47811 c 0,0 -8.679998,-0.74378 -8.36809,-1.72206 0.311907,-0.97828 0.84049,-16.77621 1.14441,-20.68276 z"
- id="rect4169"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="zcczz" />
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="path4175"
- d="m 217.19532,464.702 -49.95598,8.88102 -50.08823,-8.88102 0,-12.12657 100.04421,0 z"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 117.15111,306.23633 49.95599,-8.88102 50.08822,8.88102 0,12.12658 -100.04421,0 z"
- id="rect4172"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 228.43002,399.28372 c 0,0 3.12853,0.50936 8.38696,0.2714 0.0814,8.34833 -0.73306,22.88772 -1.12555,25.68087 -0.3925,2.79316 -6.67578,-0.30624 -6.67578,-0.30624 z"
- id="rect4181"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cczcc" />
- <path
- style="opacity:1;fill:#cbcbcb;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 110.99812,320.90892 c 9.74457,-8.4453 40.09435,-8.09024 59.20983,-8.06857 19.11548,0.0217 44.60536,-0.32419 54.99957,9.20383 10.39421,9.52802 7.83198,43.0413 7.89177,64.31485 0.0598,21.27356 3.15208,49.37176 -7.89176,60.4156 -11.04385,11.04384 -37.64935,8.68791 -57.03195,8.51204 -19.38261,-0.17587 -45.6217,2.73747 -56.88209,-7.44019 -11.26039,-10.17766 -8.4329,-45.75175 -8.32088,-66.68431 0.11202,-20.93257 -1.71905,-51.80796 8.02551,-60.25325 z"
- id="rect4149"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="zzzzzzzzz" />
- <path
- sodipodi:nodetypes="sssssssss"
- inkscape:connector-curvature="0"
- id="rect4152"
- d="m 133.22587,330.48948 69.72779,0 c 6.71812,0 11.83367,5.41484 12.12657,12.12657 1.19073,27.28478 1.19022,54.56956 0,81.85435 -0.29278,6.71174 -5.40845,12.12657 -12.12657,12.12657 l -69.72779,0 c -6.71812,0 -11.82926,-5.41504 -12.12657,-12.12657 -1.18246,-26.69356 -1.65764,-53.74075 0,-81.85435 0.39543,-6.70647 5.40845,-12.12657 12.12657,-12.12657 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4154"
- width="72.75943"
- height="81.854355"
- x="131.62029"
- y="342.61606" />
- <path
- style="opacity:1;fill:#78d3fc;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 189.2215,342.61605 15.15821,0 0,81.85436 -15.15821,0 0,-66.54581 -4.44052,-3.21555 4.44052,-2.98586 z"
- id="rect4156"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccc" />
- </g>
-</svg>
diff --git a/rockworkd/core.cpp b/rockworkd/core.cpp
index 38a25c5..eb98dfd 100644
--- a/rockworkd/core.cpp
+++ b/rockworkd/core.cpp
@@ -3,7 +3,7 @@
#include "pebblemanager.h"
#include "dbusinterface.h"
-#include "platformintegration/ubuntu/ubuntuplatform.h"
+#include "platformintegration/sailfish/sailfishplatform.h"
#ifdef ENABLE_TESTING
#include "platformintegration/testing/testingplatform.h"
#endif
@@ -41,7 +41,7 @@ void Core::init()
#ifdef ENABLE_TESTING
m_platform = new TestingPlatform(this);
#else
- m_platform = new UbuntuPlatform(this);
+ m_platform = new SailfishPlatform(this);
#endif
m_pebbleManager = new PebbleManager(this);
diff --git a/rockworkd/jsfiles.qrc b/rockworkd/jsfiles.qrc
deleted file mode 100644
index 807350d..0000000
--- a/rockworkd/jsfiles.qrc
+++ /dev/null
@@ -1,2 +0,0 @@
-<RCC/>
-
diff --git a/rockworkd/libpebble/bluez/bluezclient.cpp b/rockworkd/libpebble/bluez/bluezclient.cpp
index 8cdf848..313c540 100644
--- a/rockworkd/libpebble/bluez/bluezclient.cpp
+++ b/rockworkd/libpebble/bluez/bluezclient.cpp
@@ -1,5 +1,6 @@
#include "bluezclient.h"
#include "dbus-shared.h"
+#include "device.h"
#include <QDBusConnection>
#include <QDBusReply>
@@ -26,32 +27,84 @@ BluezClient::BluezClient(QObject *parent):
InterfaceList ifaces = objectList.value(path);
if (ifaces.contains(BLUEZ_DEVICE_IFACE)) {
QString candidatePath = path.path();
+ qDebug() << "have device" << candidatePath;
auto properties = ifaces.value(BLUEZ_DEVICE_IFACE);
addDevice(path, properties);
}
}
+
+ if (m_devices.isEmpty()) {
+ // Try with bluez 4
+ QDBusConnection system = QDBusConnection::systemBus();
+
+ QDBusReply<QList<QDBusObjectPath> > listAdaptersReply = system.call(
+ QDBusMessage::createMethodCall("org.bluez", "/", "org.bluez.Manager",
+ "ListAdapters"));
+ if (!listAdaptersReply.isValid()) {
+ qWarning() << listAdaptersReply.error().message();
+ return;
+ }
+
+ QList<QDBusObjectPath> adapters = listAdaptersReply.value();
+
+ if (adapters.isEmpty()) {
+ qWarning() << "No BT adapters found";
+ return;
+ }
+
+ QDBusReply<QVariantMap> adapterPropertiesReply = system.call(
+ QDBusMessage::createMethodCall("org.bluez", adapters[0].path(), "org.bluez.Adapter",
+ "GetProperties"));
+ if (!adapterPropertiesReply.isValid()) {
+ qWarning() << adapterPropertiesReply.error().message();
+ return;
+ }
+
+ QList<QDBusObjectPath> devices;
+ adapterPropertiesReply.value()["Devices"].value<QDBusArgument>() >> devices;
+
+ foreach (QDBusObjectPath path, devices) {
+ QDBusReply<QVariantMap> devicePropertiesReply = system.call(
+ QDBusMessage::createMethodCall("org.bluez", path.path(), "org.bluez.Device",
+ "GetProperties"));
+ if (!devicePropertiesReply.isValid()) {
+ qCritical() << devicePropertiesReply.error().message();
+ continue;
+ }
+
+ const QVariantMap &dict = devicePropertiesReply.value();
+
+ QString name = dict["Name"].toString();
+ if (name.startsWith("Pebble") && !name.startsWith("Pebble Time LE") && !name.startsWith("Pebble-LE")) {
+ qDebug() << "Found Pebble:" << name;
+ addDevice(path, dict);
+ }
+ }
+ }
}
}
-QList<Device> BluezClient::pairedPebbles() const
+QList<BluezDevice> BluezClient::pairedPebbles() const
{
- QList<Device> ret;
- if (m_bluezManager.isValid()) {
- foreach (const Device &dev, m_devices) {
- ret << dev;
- }
+ QList<BluezDevice> ret;
+
+ foreach (const BluezDevice &dev, m_devices) {
+ ret << dev;
}
+
return ret;
+
}
void BluezClient::addDevice(const QDBusObjectPath &path, const QVariantMap &properties)
{
QString address = properties.value("Address").toString();
QString name = properties.value("Name").toString();
+ qDebug() << "Adding device" << address << name;
if (name.startsWith("Pebble") && !name.startsWith("Pebble Time LE") && !name.startsWith("Pebble-LE") && !m_devices.contains(address)) {
qDebug() << "Found new Pebble:" << address << name;
- Device device;
+ BluezDevice device;
device.address = QBluetoothAddress(address);
device.name = name;
device.path = path.path();
@@ -70,6 +123,26 @@ void BluezClient::slotInterfacesAdded(const QDBusObjectPath &path, InterfaceList
}
}
+void BluezClient::slotDevicePairingDone(bool success)
+{
+ qDebug() << "pairing done" << success;
+ if (!success) {
+ return;
+ }
+
+ Device *device = static_cast<Device*>(sender());
+ device->deleteLater();
+
+ if (!m_devices.contains(device->getAddress())) {
+ BluezDevice bluezDevice;
+ bluezDevice.address = QBluetoothAddress(device->getAddress());
+ bluezDevice.name = device->getName();
+ bluezDevice.path = device->getPath();
+ m_devices.insert(device->getAddress(), bluezDevice);
+ emit devicesChanged();
+ }
+}
+
void BluezClient::slotInterfacesRemoved(const QDBusObjectPath &path, const QStringList &ifaces)
{
qDebug() << "interfaces removed" << path.path() << ifaces;
diff --git a/rockworkd/libpebble/bluez/bluezclient.h b/rockworkd/libpebble/bluez/bluezclient.h
index f8e5749..cbe7c0f 100644
--- a/rockworkd/libpebble/bluez/bluezclient.h
+++ b/rockworkd/libpebble/bluez/bluezclient.h
@@ -11,7 +11,7 @@
#include "bluez_adapter1.h"
#include "bluez_agentmanager1.h"
-class Device {
+class BluezDevice {
public:
QBluetoothAddress address;
QString name;
@@ -26,14 +26,15 @@ public:
BluezClient(QObject *parent = 0);
- QList<Device> pairedPebbles() const;
+ QList<BluezDevice> pairedPebbles() const;
private slots:
void addDevice(const QDBusObjectPath &path, const QVariantMap &properties);
void slotInterfacesAdded(const QDBusObjectPath&path, InterfaceList ifaces);
- void slotInterfacesRemoved(const QDBusObjectPath&path, const QStringList &ifaces);
-
+ void slotDevicePairingDone(bool success);
+ void slotInterfacesRemoved(const QDBusObjectPath&path, const QStringList &ifaces);
+
signals:
void devicesChanged();
@@ -45,7 +46,7 @@ private:
FreeDesktopProperties *m_bluezAdapterProperties = nullptr;
- QHash<QString, Device> m_devices;
+ QHash<QString, BluezDevice> m_devices;
};
#endif // BLUEZCLIENT_H
diff --git a/rockworkd/libpebble/bluez/device.cpp b/rockworkd/libpebble/bluez/device.cpp
new file mode 100644
index 0000000..9a0e9c3
--- /dev/null
+++ b/rockworkd/libpebble/bluez/device.cpp
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2013-2015 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * 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/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#include "device.h"
+
+#include <QDBusReply>
+#include <QDebug> // qWarning()
+#include <QThread>
+#include <QTimer>
+
+#include "dbus-shared.h"
+
+Device::Device(const QString &path, QDBusConnection &bus) :
+ m_strength(Device::None)
+{
+ initDevice(path, bus);
+}
+
+void Device::initDevice(const QString &path, QDBusConnection &bus)
+{
+ /* whenever any of the properties changes,
+ trigger the catch-all deviceChanged() signal */
+ QObject::connect(this, SIGNAL(nameChanged()), this, SIGNAL(deviceChanged()));
+ QObject::connect(this, SIGNAL(iconNameChanged()), this, SIGNAL(deviceChanged()));
+ QObject::connect(this, SIGNAL(addressChanged()), this, SIGNAL(deviceChanged()));
+ QObject::connect(this, SIGNAL(pairedChanged()), this, SIGNAL(deviceChanged()));
+ QObject::connect(this, SIGNAL(trustedChanged()), this, SIGNAL(deviceChanged()));
+ QObject::connect(this, SIGNAL(typeChanged()), this, SIGNAL(deviceChanged()));
+ QObject::connect(this, SIGNAL(connectionChanged()), this, SIGNAL(deviceChanged()));
+ QObject::connect(this, SIGNAL(strengthChanged()), this, SIGNAL(deviceChanged()));
+
+ m_bluezDevice.reset(new BluezDevice1(BLUEZ_SERVICE, path, bus));
+ /* Give our calls a bit more time than the default 25 seconds to
+ * complete whatever they are doing. In some situations (e.g. with
+ * specific devices) the default doesn't seem to be enough to. */
+ m_bluezDevice->setTimeout(60 * 1000 /* 60 seconds */);
+
+ m_bluezDeviceProperties.reset(new FreeDesktopProperties(BLUEZ_SERVICE, path, bus));
+
+ QObject::connect(m_bluezDeviceProperties.data(), SIGNAL(PropertiesChanged(const QString&, const QVariantMap&, const QStringList&)),
+ this, SLOT(slotPropertiesChanged(const QString&, const QVariantMap&, const QStringList&)));
+
+ Q_EMIT(pathChanged());
+
+ watchCall(m_bluezDeviceProperties->GetAll(BLUEZ_DEVICE_IFACE), [=](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QVariantMap> reply = *watcher;
+
+ if (reply.isError()) {
+ qWarning() << "Failed to retrieve properties for device" << m_bluezDevice->path();
+ watcher->deleteLater();
+ return;
+ }
+
+ auto properties = reply.argumentAt<0>();
+ setProperties(properties);
+
+ watcher->deleteLater();
+ });
+}
+
+void Device::slotPropertiesChanged(const QString &interface, const QVariantMap &changedProperties,
+ const QStringList &invalidatedProperties)
+{
+ Q_UNUSED(invalidatedProperties);
+
+ if (interface != BLUEZ_DEVICE_IFACE)
+ return;
+
+ setProperties(changedProperties);
+}
+
+void Device::setProperties(const QMap<QString,QVariant> &properties)
+{
+ QMapIterator<QString,QVariant> it(properties);
+ while (it.hasNext()) {
+ it.next();
+ updateProperty(it.key(), it.value());
+ }
+}
+
+void Device::setConnectAfterPairing(bool value)
+{
+ if (m_connectAfterPairing == value)
+ return;
+
+ m_connectAfterPairing = value;
+}
+
+void Device::disconnect()
+{
+ setConnection(Device::Disconnecting);
+
+ QDBusPendingCall call = m_bluezDevice->Disconnect();
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<void> reply = *watcher;
+
+ if (reply.isError()) {
+ qWarning() << "Could not disconnect device:"
+ << reply.error().message();
+
+ // Make sure we switch the connection indicator back to
+ // a sane state
+ updateConnection();
+ }
+
+ watcher->deleteLater();
+ });
+}
+
+void Device::connectAfterPairing()
+{
+ if (!m_connectAfterPairing)
+ return;
+
+ connect();
+}
+
+void Device::pair()
+{
+ if (m_paired) {
+ // If we are already paired we just have to make sure we
+ // trigger the connection process if we have to
+ connectAfterPairing();
+ return;
+ }
+
+ setConnection(Device::Connecting);
+
+ m_isPairing = true;
+
+ auto call = m_bluezDevice->asyncCall("Pair");
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<void> reply = *watcher;
+ bool success = true;
+
+ if (reply.isError()) {
+ qWarning() << "Failed to pair with device:"
+ << reply.error().message();
+ updateConnection();
+ success = false;
+ }
+
+ m_isPairing = false;
+
+ Q_EMIT(pairingDone(success));
+
+ watcher->deleteLater();
+ });
+}
+
+void Device::cancelPairing()
+{
+ if (!m_isPairing)
+ return;
+
+ auto call = m_bluezDevice->asyncCall("CancelPairing");
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<void> reply = *watcher;
+
+ if (reply.isError()) {
+ qWarning() << "Failed to cancel pairing attempt with device:"
+ << reply.error().message();
+ updateConnection();
+ } else {
+ // Only mark us a not pairing when call succeeded
+ m_isPairing = false;
+ }
+
+ watcher->deleteLater();
+ });
+}
+
+void Device::connect()
+{
+ // If we have just paired then the device switched to connected = true for
+ // a short moment as BlueZ opened up a RFCOMM channel to perform SDP. If
+ // we should connect with the device on specific profiles now we go ahead
+ // here even if we're marked as connected as this still doesn't mean we're
+ // connected on any profile. Calling org.bluez.Device1.Connect multiple
+ // times doesn't hurt an will not fail.
+ if (m_isConnected && !m_connectAfterPairing)
+ return;
+
+ setConnection(Device::Connecting);
+
+ QDBusPendingCall call = m_bluezDevice->asyncCall("Connect");
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<void> reply = *watcher;
+
+ if (reply.isError()) {
+ qWarning() << "Could not connect device:"
+ << reply.error().message();
+ } else {
+ makeTrusted(true);
+ }
+
+ // Regardless if the Connected property has changed or not we update
+ // the connection state here as the connection process is over now
+ // and we should have received any state change already at this
+ // point.
+ updateConnection();
+
+ watcher->deleteLater();
+ });
+}
+
+void Device::slotMakeTrustedDone(QDBusPendingCallWatcher *call)
+{
+ QDBusPendingReply<void> reply = *call;
+
+ if (reply.isError()) {
+ qWarning() << "Could not mark device as trusted:"
+ << reply.error().message();
+ }
+
+ call->deleteLater();
+}
+
+void Device::makeTrusted(bool trusted)
+{
+ auto call = m_bluezDeviceProperties->Set(BLUEZ_DEVICE_IFACE, "Trusted", QDBusVariant(trusted));
+
+ auto watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(slotMakeTrustedDone(QDBusPendingCallWatcher*)));
+}
+
+void Device::setName(const QString &name)
+{
+ if (m_name != name) {
+ m_name = name;
+ Q_EMIT(nameChanged());
+ }
+}
+
+void Device::setIconName(const QString &iconName)
+{
+ if (m_iconName != iconName) {
+ m_iconName = iconName;
+ Q_EMIT(iconNameChanged());
+ }
+}
+
+void Device::setAddress(const QString &address)
+{
+ if (m_address != address) {
+ m_address = address;
+ Q_EMIT(addressChanged());
+ }
+}
+
+void Device::setType(Type type)
+{
+ if (m_type != type) {
+ m_type = type;
+ Q_EMIT(typeChanged());
+ updateIcon();
+ }
+}
+
+void Device::setPaired(bool paired)
+{
+ if (m_paired != paired) {
+ m_paired = paired;
+ Q_EMIT(pairedChanged());
+ }
+}
+
+void Device::setTrusted(bool trusted)
+{
+ if (m_trusted != trusted) {
+ m_trusted = trusted;
+ Q_EMIT(trustedChanged());
+ }
+}
+
+void Device::setConnection(Connection connection)
+{
+ if (m_connection != connection) {
+ m_connection = connection;
+ Q_EMIT(connectionChanged());
+ }
+}
+
+void Device::updateIcon()
+{
+ /* bluez-provided icon is unreliable? In testing I'm getting
+ an "audio-card" icon from bluez for my NoiseHush N700 headset.
+ Try to guess the icon from the device type,
+ and use the bluez-provided icon as a fallback */
+
+ const auto type = getType();
+
+ switch (type) {
+ case Type::Headset:
+ setIconName("image://theme/audio-headset-symbolic");
+ break;
+ case Type::Headphones:
+ setIconName("image://theme/audio-headphones-symbolic");
+ break;
+ case Type::Carkit:
+ setIconName("image://theme/audio-carkit-symbolic");
+ break;
+ case Type::Speakers:
+ case Type::OtherAudio:
+ setIconName("image://theme/audio-speakers-symbolic");
+ break;
+ case Type::Mouse:
+ setIconName("image://theme/input-mouse-symbolic");
+ break;
+ case Type::Keyboard:
+ setIconName("image://theme/input-keyboard-symbolic");
+ break;
+ case Type::Cellular:
+ setIconName("image://theme/phone-cellular-symbolic");
+ break;
+ case Type::Smartphone:
+ setIconName("image://theme/phone-smartphone-symbolic");
+ break;
+ case Type::Phone:
+ setIconName("image://theme/phone-uncategorized-symbolic");
+ break;
+ case Type::Computer:
+ setIconName("image://theme/computer-symbolic");
+ break;
+ default:
+ setIconName(QString("image://theme/%1").arg(m_fallbackIconName));
+ }
+}
+
+void Device::updateConnection()
+{
+ Connection c;
+
+ c = m_isConnected ? Connection::Connected : Connection::Disconnected;
+
+ setConnection(c);
+}
+
+void Device::updateProperty(const QString &key, const QVariant &value)
+{
+ if (key == "Name") {
+ setName(value.toString());
+ } else if (key == "Address") {
+ setAddress(value.toString());
+ } else if (key == "Connected") {
+ m_isConnected = value.toBool();
+ updateConnection();
+ } else if (key == "Class") {
+ setType(getTypeFromClass(value.toUInt()));
+ } else if (key == "Paired") {
+ setPaired(value.toBool());
+
+ if (m_paired && m_connectAfterPairing) {
+ connectAfterPairing();
+ return;
+ }
+
+ updateConnection();
+ } else if (key == "Trusted") {
+ setTrusted(value.toBool());
+ } else if (key == "Icon") {
+ m_fallbackIconName = value.toString();
+ updateIcon ();
+ } else if (key == "RSSI") {
+ m_strength = getStrengthFromRssi(value.toInt());
+ Q_EMIT(strengthChanged());
+ }
+}
+
+/* Determine the Type from the bits in the Class of Device (CoD) field.
+ https://www.bluetooth.org/en-us/specification/assigned-numbers/baseband */
+Device::Type Device::getTypeFromClass (quint32 c)
+{
+ switch ((c & 0x1f00) >> 8) {
+ case 0x01:
+ return Type::Computer;
+
+ case 0x02:
+ switch ((c & 0xfc) >> 2) {
+ case 0x01:
+ return Type::Cellular;
+ case 0x03:
+ return Type::Smartphone;
+ case 0x04:
+ return Type::Modem;
+ default:
+ return Type::Phone;
+ }
+ break;
+
+ case 0x03:
+ return Type::Network;
+
+ case 0x04:
+ switch ((c & 0xfc) >> 2) {
+ case 0x01:
+ case 0x02:
+ return Type::Headset;
+
+ case 0x05:
+ return Type::Speakers;
+
+ case 0x06:
+ return Type::Headphones;
+
+ case 0x08:
+ return Type::Carkit;
+
+ case 0x0b: // vcr
+ case 0x0c: // video camera
+ case 0x0d: // camcorder
+ return Type::Video;
+
+ default:
+ return Type::OtherAudio;
+ }
+ break;
+
+ case 0x05:
+ switch ((c & 0xc0) >> 6) {
+ case 0x00:
+ switch ((c & 0x1e) >> 2) {
+ case 0x01:
+ case 0x02:
+ return Type::Joypad;
+ }
+ break;
+
+ case 0x01:
+ return Type::Keyboard;
+
+ case 0x02:
+ switch ((c & 0x1e) >> 2) {
+ case 0x05:
+ return Type::Tablet;
+ default:
+ return Type::Mouse;
+ }
+ }
+ break;
+
+ case 0x06:
+ if ((c & 0x80) != 0)
+ return Type::Printer;
+ if ((c & 0x20) != 0)
+ return Type::Camera;
+ break;
+
+ case 0x07:
+ if ((c & 0x4) != 0)
+ return Type::Watch;
+ break;
+ }
+
+ return Type::Other;
+}
+
+Device::Strength Device::getStrengthFromRssi(int rssi)
+{
+ /* Modelled similar to what Mac OS X does.
+ * See http://www.cnet.com/how-to/how-to-check-bluetooth-connection-strength-in-os-x/ */
+
+ if (rssi >= -60)
+ return Excellent;
+ else if (rssi < -60 && rssi >= -70)
+ return Good;
+ else if (rssi < -70 && rssi >= -90)
+ return Fair;
+ else if (rssi < -90)
+ return Poor;
+
+ return None;
+}
diff --git a/rockworkd/libpebble/bluez/device.h b/rockworkd/libpebble/bluez/device.h
new file mode 100644
index 0000000..bcc044b
--- /dev/null
+++ b/rockworkd/libpebble/bluez/device.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2013-2015 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * 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/>.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ */
+
+#ifndef USS_BLUETOOTH_DEVICE_H
+#define USS_BLUETOOTH_DEVICE_H
+
+#include <QDBusConnection>
+#include <QDBusInterface>
+#include <QDBusPendingCallWatcher>
+#include <QSharedPointer>
+#include <QString>
+
+#include "freedesktop_properties.h"
+#include "bluez_device1.h"
+
+struct Device: QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString path
+ READ getPath
+ NOTIFY pathChanged)
+
+ Q_PROPERTY(QString name
+ READ getName
+ NOTIFY nameChanged)
+
+ Q_PROPERTY(QString iconName
+ READ getIconName
+ NOTIFY iconNameChanged)
+
+ Q_PROPERTY(QString address
+ READ getAddress
+ NOTIFY addressChanged)
+
+ Q_PROPERTY(Type type
+ READ getType
+ NOTIFY typeChanged)
+
+ Q_PROPERTY(bool paired
+ READ isPaired
+ NOTIFY pairedChanged)
+
+ Q_PROPERTY(bool trusted
+ READ isTrusted
+ WRITE makeTrusted
+ NOTIFY trustedChanged)
+
+ Q_PROPERTY(Connection connection
+ READ getConnection
+ NOTIFY connectionChanged)
+
+ Q_PROPERTY(Strength strength
+ READ getStrength
+ NOTIFY strengthChanged)
+
+public:
+
+ enum Type { Other, Computer, Cellular, Smartphone, Phone, Modem, Network,
+ Headset, Speakers, Headphones, Video, OtherAudio, Joypad,
+ Keypad, Keyboard, Tablet, Mouse, Printer, Camera, Carkit, Watch };
+
+ enum Strength { None, Poor, Fair, Good, Excellent };
+
+ enum Connection { Disconnected=1, Connecting=2,
+ Connected=4, Disconnecting=8 };
+
+ Q_ENUMS(Type Strength Connection)
+
+ Q_DECLARE_FLAGS(Connections, Connection)
+
+Q_SIGNALS:
+ void pathChanged();
+ void nameChanged();
+ void iconNameChanged();
+ void addressChanged();
+ void typeChanged();
+ void pairedChanged();
+ void trustedChanged();
+ void connectionChanged();
+ void strengthChanged();
+ void deviceChanged(); // catchall for any change
+ void pairingDone(bool success);
+
+public:
+ const QString& getName() const { return m_name; }
+ const QString& getAddress() const { return m_address; }
+ const QString& getIconName() const { return m_iconName; }
+ Type getType() const { return m_type; }
+ bool isPaired() const { return m_paired; }
+ bool isTrusted() const { return m_trusted; }
+ Connection getConnection() const { return m_connection; }
+ Strength getStrength() const { return m_strength; }
+ QString getPath() const { return m_bluezDevice ? m_bluezDevice->path() : QString(); }
+
+ private:
+ QString m_name;
+ QString m_state;
+ QString m_address;
+ QString m_iconName;
+ QString m_fallbackIconName;
+ Type m_type = Type::Other;
+ bool m_paired = false;
+ bool m_trusted = false;
+ Connection m_connection = Connection::Disconnected;
+ Strength m_strength = Strength::None;
+ bool m_isConnected = false;
+ bool m_connectAfterPairing = false;
+ QScopedPointer<BluezDevice1> m_bluezDevice;
+ QScopedPointer<FreeDesktopProperties> m_bluezDeviceProperties;
+ bool m_isPairing = false;
+
+ protected:
+ void setName(const QString &name);
+ void setIconName(const QString &name);
+ void setAddress(const QString &address);
+ void setType(Type type);
+ void setPaired(bool paired);
+ void setTrusted(bool trusted);
+ void setConnection(Connection connection);
+ void setStrength(Strength strength);
+ void updateIcon();
+ void updateConnection();
+
+ public:
+ Device() {}
+ Device(const QString &path, QDBusConnection &bus);
+ ~Device() {}
+ bool isValid() const { return getType() != Type::Other; }
+ void pair();
+ Q_INVOKABLE void cancelPairing();
+ void connect();
+ void makeTrusted(bool trusted);
+ void disconnect();
+ void setProperties(const QMap<QString,QVariant> &properties);
+ void setConnectAfterPairing(bool value);
+
+ private Q_SLOTS:
+ void slotPropertiesChanged(const QString &interface, const QVariantMap &changedProperties,
+ const QStringList &invalidatedProperties);
+ void slotMakeTrustedDone(QDBusPendingCallWatcher *call);
+
+ private:
+ void initDevice(const QString &path, QDBusConnection &bus);
+ void updateProperties(QSharedPointer<QDBusInterface>);
+ void updateProperty(const QString &key, const QVariant &value);
+ static Type getTypeFromClass(quint32 bluetoothClass);
+ Device::Strength getStrengthFromRssi(int rssi);
+ void connectAfterPairing();
+};
+
+Q_DECLARE_METATYPE(Device*)
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Device::Connections)
+
+#endif // USS_BLUETOOTH_DEVICE_H
diff --git a/rockworkd/libpebble/jskit/typedarray.js b/rockworkd/libpebble/jskit/typedarray.js
index d4e00c6..eec78a2 100644
--- a/rockworkd/libpebble/jskit/typedarray.js
+++ b/rockworkd/libpebble/jskit/typedarray.js
@@ -61,7 +61,7 @@
return Object(v);
}
function ToInt32(v) { return v >> 0; }
- function ToUint32(v) { return v >> 0; } //ROCKWORK HACK ALERT: it appears that QT doesn't do the >>> properly, using >> here instead (should be close enough)
+ function ToUint32(v) { return v >>> 0; }
// Snapshot intrinsics
var LN2 = Math.LN2,
@@ -135,21 +135,23 @@
function packU8Clamped(n) { n = round(Number(n)); return [n < 0 ? 0 : n > 0xff ? 0xff : n & 0xff]; }
- function packI16(n) { return [n & 0xff, (n >> 8) & 0xff]; }
- function unpackI16(bytes) { return as_signed(bytes[1] << 8 | bytes[0], 16); }
+ function packI16(n) { return [(n >> 8) & 0xff, n & 0xff]; }
+ function unpackI16(bytes) { return as_signed(bytes[0] << 8 | bytes[1], 16); }
- function packU16(n) { return [n & 0xff, (n >> 8) & 0xff]; }
- function unpackU16(bytes) { return as_unsigned(bytes[1] << 8 | bytes[0], 16); }
+ function packU16(n) { return [(n >> 8) & 0xff, n & 0xff]; }
+ function unpackU16(bytes) { return as_unsigned(bytes[0] << 8 | bytes[1], 16); }
- function packI32(n) { return [n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]; }
- function unpackI32(bytes) { return as_signed(bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0], 32); }
+ function packI32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; }
+ function unpackI32(bytes) { return as_signed(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); }
- function packU32(n) { return [n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]; }
- function unpackU32(bytes) { return as_unsigned(bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0], 32); }
+ function packU32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; }
+ function unpackU32(bytes) { return as_unsigned(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); }
function packIEEE754(v, ebits, fbits) {
- var bias = (1 << (ebits - 1)) - 1;
+ var bias = (1 << (ebits - 1)) - 1,
+ s, e, f, ln,
+ i, bits, str, bytes;
function roundToEven(n) {
var w = floor(n), f = n - w;
@@ -161,7 +163,6 @@
}
// Compute sign, exponent, fraction
- var s, e, f;
if (v !== v) {
// NaN
// http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
@@ -175,28 +176,20 @@
v = abs(v);
if (v >= pow(2, 1 - bias)) {
- // Normalized
e = min(floor(log(v) / LN2), 1023);
- var significand = v / pow(2, e);
- if (significand < 1) {
- e -= 1;
- significand *= 2;
+ f = roundToEven(v / pow(2, e) * pow(2, fbits));
+ if (f / pow(2, fbits) >= 2) {
+ e = e + 1;
+ f = 1;
}
- if (significand >= 2) {
- e += 1;
- significand /= 2;
- }
- var d = pow(2, fbits);
- f = roundToEven(significand * d) - d;
- e += bias;
- if (f / d >= 1) {
- e += 1;
- f = 0;
- }
- if (e > 2 * bias) {
+ if (e > bias) {
// Overflow
e = (1 << ebits) - 1;
f = 0;
+ } else {
+ // Normalized
+ e = e + bias;
+ f = f - pow(2, fbits);
}
} else {
// Denormalized
@@ -206,17 +199,17 @@
}
// Pack sign, exponent, fraction
- var bits = [], i;
+ bits = [];
for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = floor(f / 2); }
for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = floor(e / 2); }
bits.push(s ? 1 : 0);
bits.reverse();
- var str = bits.join('');
+ str = bits.join('');
// Bits to bytes
- var bytes = [];
+ bytes = [];
while (str.length) {
- bytes.unshift(parseInt(str.substring(0, 8), 2));
+ bytes.push(parseInt(str.substring(0, 8), 2));
str = str.substring(8);
}
return bytes;
@@ -227,8 +220,8 @@
var bits = [], i, j, b, str,
bias, s, e, f;
- for (i = 0; i < bytes.length; ++i) {
- b = bytes[i];
+ for (i = bytes.length; i; i -= 1) {
+ b = bytes[i - 1];
for (j = 8; j; j -= 1) {
bits.push(b % 2 ? 1 : 0); b = b >> 1;
}
diff --git a/rockworkd/libpebble/pebble.cpp b/rockworkd/libpebble/pebble.cpp
index 0f76097..d2e44f5 100644
--- a/rockworkd/libpebble/pebble.cpp
+++ b/rockworkd/libpebble/pebble.cpp
@@ -134,7 +134,7 @@ bool Pebble::connected() const
void Pebble::connect()
{
- qDebug() << "Connecting to Pebble:" << m_name << m_address;
+ qDebug() << "Connecting to Pebble:" << m_name << m_address.toString();
m_connection->connectPebble(m_address);
}
diff --git a/rockworkd/libpebble/watchconnection.cpp b/rockworkd/libpebble/watchconnection.cpp
index 0778a1d..dabacf4 100644
--- a/rockworkd/libpebble/watchconnection.cpp
+++ b/rockworkd/libpebble/watchconnection.cpp
@@ -32,7 +32,7 @@ UploadManager *WatchConnection::uploadManager() const
void WatchConnection::scheduleReconnect()
{
- if (m_connectionAttempts == 0) {
+ if (m_connectionAttempts < 2) {
reconnect();
} else if (m_connectionAttempts < 25) {
qDebug() << "Attempting to reconnect in 10 seconds";
@@ -49,21 +49,27 @@ void WatchConnection::scheduleReconnect()
void WatchConnection::reconnect()
{
QBluetoothLocalDevice localBtDev;
+ qDebug() << "Reconnection";
if (localBtDev.pairingStatus(m_pebbleAddress) == QBluetoothLocalDevice::Unpaired) {
// Try again in one 10 secs, give the user some time to pair it
+ qDebug() << "Unpaired.";
m_connectionAttempts = 1;
scheduleReconnect();
return;
}
if (m_socket) {
+ qDebug() << "Socket exists.";
if (m_socket->state() == QBluetoothSocket::ConnectedState) {
qDebug() << "Already connected.";
return;
}
- delete m_socket;
+ m_socket->deleteLater();
}
+ m_connectionAttempts++;
+
+ qDebug() << "Creating socket.";
m_socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this);
connect(m_socket, &QBluetoothSocket::connected, this, &WatchConnection::pebbleConnected);
connect(m_socket, &QBluetoothSocket::readyRead, this, &WatchConnection::readyRead);
@@ -71,7 +77,6 @@ void WatchConnection::reconnect()
connect(m_socket, &QBluetoothSocket::disconnected, this, &WatchConnection::pebbleDisconnected);
//connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(onBytesWritten(qint64)));
- m_connectionAttempts++;
// FIXME: Assuming port 1 (with Pebble)
m_socket->connectToService(m_pebbleAddress, 1);
@@ -141,8 +146,12 @@ void WatchConnection::pebbleConnected()
void WatchConnection::pebbleDisconnected()
{
qDebug() << "Disconnected";
- m_socket->close();
+
emit watchDisconnected();
+ QBluetoothSocket *socket = qobject_cast<QBluetoothSocket *>(sender());
+ if (!socket) return;
+
+ socket->deleteLater();
if (!m_reconnectTimer.isActive()) {
scheduleReconnect();
}
@@ -152,7 +161,6 @@ void WatchConnection::socketError(QBluetoothSocket::SocketError error)
{
Q_UNUSED(error); // We seem to get UnknownError anyways all the time
qDebug() << "SocketError" << error;
- m_socket->close();
emit watchConnectionFailed();
if (!m_reconnectTimer.isActive()) {
scheduleReconnect();
diff --git a/rockworkd/pebblemanager.cpp b/rockworkd/pebblemanager.cpp
index 126000e..842dff0 100644
--- a/rockworkd/pebblemanager.cpp
+++ b/rockworkd/pebblemanager.cpp
@@ -26,8 +26,8 @@ QList<Pebble *> PebbleManager::pebbles() const
void PebbleManager::loadPebbles()
{
- QList<Device> pairedPebbles = m_bluezClient->pairedPebbles();
- foreach (const Device &device, pairedPebbles) {
+ QList<BluezDevice> pairedPebbles = m_bluezClient->pairedPebbles();
+ foreach (const BluezDevice &device, pairedPebbles) {
qDebug() << "loading pebble" << device.address.toString();
Pebble *pebble = get(device.address);
if (!pebble) {
@@ -46,7 +46,7 @@ void PebbleManager::loadPebbles()
QList<Pebble*> pebblesToRemove;
foreach (Pebble *pebble, m_pebbles) {
bool found = false;
- foreach (const Device &dev, pairedPebbles) {
+ foreach (const BluezDevice &dev, pairedPebbles) {
if (dev.address == pebble->address()) {
found = true;
break;
@@ -59,7 +59,7 @@ void PebbleManager::loadPebbles()
while (!pebblesToRemove.isEmpty()) {
Pebble *pebble = pebblesToRemove.takeFirst();
- qDebug() << "Removing pebble" << pebble->address();
+ qDebug() << "Removing pebble" << pebble->address().toString();
m_pebbles.removeOne(pebble);
emit pebbleRemoved(pebble);
pebble->deleteLater();
diff --git a/rockworkd/platformintegration/sailfish/callchannelobserver.cpp b/rockworkd/platformintegration/sailfish/callchannelobserver.cpp
new file mode 100644
index 0000000..a9f41f3
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/callchannelobserver.cpp
@@ -0,0 +1,166 @@
+#include "callchannelobserver.h"
+
+#include <TelepathyQt/Contact>
+#include <TelepathyQt/PendingContactInfo>
+
+#include <QContactFetchRequest>
+#include <QContactPhoneNumber>
+#include <QContactFilter>
+#include <QContactDetail>
+#include <QContactDisplayLabel>
+
+QTCONTACTS_USE_NAMESPACE
+
+TelepathyMonitor::TelepathyMonitor(QObject *parent):
+ QObject(parent)
+{
+ Tp::registerTypes();
+ QTimer::singleShot(0, this, SLOT(accountManagerSetup()));
+ QMap<QString, QString> parameters;
+ parameters.insert(QString::fromLatin1("mergePresenceChanges"), QString::fromLatin1("false"));
+ m_contactManager = new QContactManager("", parameters, this);
+}
+
+void TelepathyMonitor::hangupCall(uint cookie)
+{
+ if (m_currentCalls.contains(cookie)) {
+ m_currentCalls.value(cookie)->hangup();
+ }
+}
+
+void TelepathyMonitor::accountManagerSetup()
+{
+ m_accountManager = Tp::AccountManager::create(Tp::AccountFactory::create(QDBusConnection::sessionBus(),
+ Tp::Account::FeatureCore),
+ Tp::ConnectionFactory::create(QDBusConnection::sessionBus(),
+ Tp::Connection::FeatureCore));
+ connect(m_accountManager->becomeReady(),
+ SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(accountManagerReady(Tp::PendingOperation*)));
+}
+
+void TelepathyMonitor::accountManagerReady(Tp::PendingOperation* operation)
+{
+ if (operation->isError()) {
+ qDebug() << "TelepathyMonitor: accountManager init error.";
+ QTimer::singleShot(1000, this, SLOT(accountManagerSetup())); // again
+ return;
+ }
+ qDebug() << "Telepathy account manager ready";
+
+ foreach (const Tp::AccountPtr& account, m_accountManager->allAccounts()) {
+ connect(account->becomeReady(Tp::Account::FeatureCapabilities),
+ SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(accountReady(Tp::PendingOperation*)));
+ }
+
+ connect(m_accountManager.data(), SIGNAL(newAccount(Tp::AccountPtr)), SLOT(newAccount(Tp::AccountPtr)));
+}
+
+void TelepathyMonitor::newAccount(const Tp::AccountPtr& account)
+{
+ connect(account->becomeReady(Tp::Account::FeatureCapabilities),
+ SIGNAL(finished(Tp::PendingOperation*)),
+ SLOT(accountReady(Tp::PendingOperation*)));
+}
+
+void TelepathyMonitor::accountReady(Tp::PendingOperation* operation)
+{
+ if (operation->isError()) {
+ qDebug() << "TelepathyAccount: Operation failed (accountReady)";
+ return;
+ }
+
+ Tp::PendingReady* pendingReady = qobject_cast<Tp::PendingReady*>(operation);
+ if (pendingReady == 0) {
+ qDebug() << "Rejecting account because could not understand ready status";
+ return;
+ }
+ checkAndAddAccount(Tp::AccountPtr::qObjectCast(pendingReady->proxy()));
+}
+
+void TelepathyMonitor::onCallStarted(Tp::CallChannelPtr callChannel)
+{
+ // Haven't figured how to send outgoing calls to pebble yet... discard it
+ if (callChannel->initiatorContact()->id().isEmpty()) {
+ qWarning() << "ignoring phone call. looks like it's an outgoing one";
+ return;
+ }
+
+ m_cookie++;
+ m_currentCalls.insert(m_cookie, callChannel.data());
+ m_currentCallStates.insert(m_cookie, Tp::CallStateInitialising);
+
+ callChannel->becomeReady(Tp::CallChannel::FeatureCallState);
+
+ connect(callChannel.data(), &Tp::CallChannel::callStateChanged, this, &TelepathyMonitor::callStateChanged);
+
+ QString number = callChannel->initiatorContact()->id();
+ qDebug() << "call started" << number;
+
+ // try to match the contact info
+ QContactFetchRequest *request = new QContactFetchRequest(this);
+ request->setFilter(QContactPhoneNumber::match(number));
+
+ // lambda function to update the notification
+ QObject::connect(request, &QContactAbstractRequest::stateChanged, [this, request, number](QContactAbstractRequest::State state) {
+ qDebug() << "request returned";
+ if (!request || state != QContactAbstractRequest::FinishedState) {
+ qDebug() << "error fetching contact" << state;
+ return;
+ }
+
+ QContact contact;
+
+ // create the snap decision only after the contact match finishes
+ if (request->contacts().size() > 0) {
+ // use the first match
+ contact = request->contacts().at(0);
+
+ qDebug() << "have contact" << contact.detail<QContactDisplayLabel>().label();
+ emit this->incomingCall(m_cookie, number, contact.detail<QContactDisplayLabel>().label());
+ } else {
+ qDebug() << "unknown contact" << number;
+ emit this->incomingCall(m_cookie, number, QString());
+ }
+ });
+
+ request->setManager(m_contactManager);
+ request->start();
+}
+
+void TelepathyMonitor::callStateChanged(Tp::CallState state)
+{
+ qDebug() << "call state changed1";
+ Tp::CallChannel *channel = qobject_cast<Tp::CallChannel*>(sender());
+ uint cookie = m_currentCalls.key(channel);
+
+ qDebug() << "call state changed2" << state << "cookie:" << cookie;
+
+ switch (state) {
+ case Tp::CallStateActive:
+ emit callStarted(cookie);
+ m_currentCallStates[cookie] = Tp::CallStateActive;
+ break;
+ case Tp::CallStateEnded: {
+ Tp::CallState oldState = m_currentCallStates.value(cookie);
+ emit callEnded(cookie, oldState != Tp::CallStateActive);
+ m_currentCalls.take(cookie);
+ m_currentCallStates.take(cookie);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void TelepathyMonitor::checkAndAddAccount(const Tp::AccountPtr& account)
+{
+ Tp::ConnectionCapabilities caps = account->capabilities();
+ // TODO: Later on we will need to filter for the right capabilities, and also allow dynamic account detection
+ // Don't check caps for now as a workaround for https://bugs.launchpad.net/ubuntu/+source/media-hub/+bug/1409125
+ // at least until we are able to find out the root cause of it (check rev 107 for the caps check)
+ auto tcm = new TelepathyCallMonitor(account);
+ connect(tcm, &TelepathyCallMonitor::callStarted, this, &TelepathyMonitor::onCallStarted);
+ m_callMonitors.append(tcm);
+}
diff --git a/rockworkd/platformintegration/sailfish/callchannelobserver.h b/rockworkd/platformintegration/sailfish/callchannelobserver.h
new file mode 100644
index 0000000..ba3415d
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/callchannelobserver.h
@@ -0,0 +1,74 @@
+#ifndef CALLCHANNELOBSERVER_H
+#define CALLCHANNELOBSERVER_H
+
+#include <TelepathyQt/AccountManager>
+#include <TelepathyQt/SimpleCallObserver>
+#include <TelepathyQt/PendingOperation>
+#include <TelepathyQt/PendingReady>
+#include <TelepathyQt/PendingAccount>
+#include <TelepathyQt/CallChannel>
+
+#include <QContactManager>
+
+QTCONTACTS_USE_NAMESPACE
+
+class TelepathyCallMonitor : public QObject
+{
+ Q_OBJECT
+public:
+ TelepathyCallMonitor(const Tp::AccountPtr& account):
+ mAccount(account),
+ mCallObserver(Tp::SimpleCallObserver::create(mAccount)) {
+ connect(mCallObserver.data(), SIGNAL(callStarted(Tp::CallChannelPtr)), SIGNAL(callStarted(Tp::CallChannelPtr)));
+// connect(mCallObserver.data(), SIGNAL(callEnded(Tp::CallChannelPtr,QString,QString)), SIGNAL(callEnded()));
+// connect(mCallObserver.data(), SIGNAL(streamedMediaCallStarted(Tp::StreamedMediaChannelPtr)), SIGNAL(offHook()));
+// connect(mCallObserver.data(), SIGNAL(streamedMediaCallEnded(Tp::StreamedMediaChannelPtr,QString,QString)), SIGNAL(onHook()));
+ }
+
+signals:
+ void callStarted(Tp::CallChannelPtr callChannel);
+ void callEnded();
+
+private:
+ Tp::AccountPtr mAccount;
+ Tp::SimpleCallObserverPtr mCallObserver;
+};
+
+class TelepathyMonitor: public QObject
+{
+ Q_OBJECT
+public:
+ TelepathyMonitor(QObject *parent = 0);
+
+ void hangupCall(uint cookie);
+
+private slots:
+ void accountManagerSetup();
+ void accountManagerReady(Tp::PendingOperation* operation);
+
+ void newAccount(const Tp::AccountPtr& account);
+ void accountReady(Tp::PendingOperation* operation);
+
+ void onCallStarted(Tp::CallChannelPtr callChannel);
+ void callStateChanged(Tp::CallState state);
+
+signals:
+ void incomingCall(uint cookie, const QString &number, const QString &name);
+ void callStarted(uint cookie);
+ void callEnded(uint cookie, bool missed);
+
+private:
+ void checkAndAddAccount(const Tp::AccountPtr& account);
+
+private:
+ Tp::AccountManagerPtr m_accountManager;
+ QList<TelepathyCallMonitor*> m_callMonitors;
+ QContactManager *m_contactManager;
+
+ QHash<uint, Tp::CallChannel*> m_currentCalls;
+ QHash<uint, Tp::CallState> m_currentCallStates;
+
+ uint m_cookie = 0;
+};
+
+#endif // CALLCHANNELOBSERVER_H
diff --git a/rockworkd/platformintegration/sailfish/organizeradapter.cpp b/rockworkd/platformintegration/sailfish/organizeradapter.cpp
new file mode 100644
index 0000000..416aad2
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/organizeradapter.cpp
@@ -0,0 +1,97 @@
+#include "organizeradapter.h"
+
+#include <QOrganizerItemFetchRequest>
+#include <QDebug>
+#include <QOrganizerEventOccurrence>
+#include <QOrganizerItemDetail>
+# include <extendedcalendar.h>
+# include <extendedstorage.h>
+
+QTORGANIZER_USE_NAMESPACE
+
+#define MANAGER "eds"
+#define MANAGER_FALLBACK "memory"
+
+OrganizerAdapter::OrganizerAdapter(QObject *parent) : QObject(parent)
+{
+ QString envManager(qgetenv("ALARM_BACKEND"));
+ if (envManager.isEmpty())
+ envManager = MANAGER;
+ if (!QOrganizerManager::availableManagers().contains(envManager)) {
+ envManager = MANAGER_FALLBACK;
+ }
+ m_manager = new QOrganizerManager(envManager);
+ m_manager->setParent(this);
+ connect(m_manager, &QOrganizerManager::dataChanged, this, &OrganizerAdapter::refresh);
+
+ mKCal::ExtendedCalendar::Ptr calendar = mKCal::ExtendedCalendar::Ptr ( new mKCal::ExtendedCalendar( QLatin1String( "UTC" ) ) );
+ mKCal::ExtendedStorage::Ptr storage = mKCal::ExtendedCalendar::defaultStorage( calendar );
+ if (storage->open()) {
+ mKCal::Notebook::List notebooks = storage->notebooks();
+ qDebug()<< "Notebooks: " + notebooks.count();
+ for (int ii = 0; ii < notebooks.count(); ++ii) {
+ if (!notebooks.at(ii)->isReadOnly()) {
+ m_calendars << CalendarInfo(normalizeCalendarName(notebooks.at(ii)->name()), notebooks.at(ii)->uid());
+ qDebug()<< "Notebook: " << notebooks.at(ii)->name() << notebooks.at(ii)->uid();
+ }
+ }
+ }
+}
+
+QString OrganizerAdapter::normalizeCalendarName(QString name)
+{
+ if (name == "qtn_caln_personal_caln") {
+ return tr("Personal");
+ }
+
+ return name;
+}
+
+void OrganizerAdapter::refresh()
+{
+ QList<CalendarEvent> items;
+ foreach (const QOrganizerItem &item, m_manager->items()) {
+ QOrganizerEvent organizerEvent(item);
+ if (organizerEvent.displayLabel().isEmpty()) {
+ continue;
+ }
+ CalendarEvent event;
+ event.setId(organizerEvent.id().toString());
+ event.setTitle(organizerEvent.displayLabel());
+ event.setDescription(organizerEvent.description());
+ event.setStartTime(organizerEvent.startDateTime());
+ event.setEndTime(organizerEvent.endDateTime());
+ event.setLocation(organizerEvent.location());
+ event.setComment(organizerEvent.comments().join(";"));
+ QStringList attendees;
+ foreach (const QOrganizerItemDetail &attendeeDetail, organizerEvent.details(QOrganizerItemDetail::TypeEventAttendee)) {
+ attendees.append(attendeeDetail.value(QOrganizerItemDetail::TypeEventAttendee + 1).toString());
+ }
+ event.setGuests(attendees);
+ event.setRecurring(organizerEvent.recurrenceRules().count() > 0);
+
+ items.append(event);
+
+ quint64 startTimestamp = QDateTime::currentMSecsSinceEpoch();
+ startTimestamp -= (1000 * 60 * 60 * 24 * 7);
+
+ foreach (const QOrganizerItem &occurranceItem, m_manager->itemOccurrences(item, QDateTime::fromMSecsSinceEpoch(startTimestamp), QDateTime::currentDateTime().addDays(7))) {
+ QOrganizerEventOccurrence organizerOccurrance(occurranceItem);
+ event.setId(organizerOccurrance.id().toString());
+ event.setStartTime(organizerOccurrance.startDateTime());
+ event.setEndTime(organizerOccurrance.endDateTime());
+ items.append(event);
+ }
+ }
+
+ if (m_items != items) {
+ m_items = items;
+ emit itemsChanged(m_items);
+ }
+
+}
+
+QList<CalendarEvent> OrganizerAdapter::items() const
+{
+ return m_items;
+}
diff --git a/rockworkd/platformintegration/sailfish/organizeradapter.h b/rockworkd/platformintegration/sailfish/organizeradapter.h
new file mode 100644
index 0000000..04ebfa3
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/organizeradapter.h
@@ -0,0 +1,44 @@
+#ifndef ORGANIZERADAPTER_H
+#define ORGANIZERADAPTER_H
+
+#include "libpebble/calendarevent.h"
+
+#include <QObject>
+
+#include <QOrganizerManager>
+#include <QOrganizerAbstractRequest>
+#include <QOrganizerEvent>
+
+QTORGANIZER_USE_NAMESPACE
+
+struct CalendarInfo
+{
+ QString name;
+ QString notebookUID;
+
+ CalendarInfo(const QString &name, const QString &notebookUID = QString())
+ : name(name), notebookUID(notebookUID) {}
+};
+
+class OrganizerAdapter : public QObject
+{
+ Q_OBJECT
+public:
+ explicit OrganizerAdapter(QObject *parent = 0);
+
+ QList<CalendarEvent> items() const;
+ QString normalizeCalendarName(QString name);
+
+public slots:
+ void refresh();
+
+signals:
+ void itemsChanged(const QList<CalendarEvent> &items);
+
+private:
+ QOrganizerManager *m_manager;
+ QList<CalendarEvent> m_items;
+ QList<CalendarInfo> m_calendars;
+};
+
+#endif // ORGANIZERADAPTER_H
diff --git a/rockworkd/platformintegration/sailfish/sailfishplatform.cpp b/rockworkd/platformintegration/sailfish/sailfishplatform.cpp
new file mode 100644
index 0000000..09e1426
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/sailfishplatform.cpp
@@ -0,0 +1,313 @@
+#include "sailfishplatform.h"
+
+#include "callchannelobserver.h"
+#include "organizeradapter.h"
+#include "syncmonitorclient.h"
+
+#include <QDBusConnection>
+#include <QDBusConnectionInterface>
+#include <QDebug>
+
+SailfishPlatform::SailfishPlatform(QObject *parent):
+ PlatformInterface(parent),
+ _pulseBus(NULL),
+ _maxVolume(0)
+{
+ // Notifications
+ QDBusConnection::sessionBus().registerObject("/org/freedesktop/Notifications", this, QDBusConnection::ExportAllSlots);
+ m_iface = new QDBusInterface("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus");
+ m_iface->call("AddMatch", "interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'");
+ m_iface->call("AddMatch", "interface='org.freedesktop.Notifications',member='CloseNotification',type='method_call',eavesdrop='true'");
+
+ // Music
+ QDBusConnectionInterface *iface = QDBusConnection::sessionBus().interface();
+ const QStringList &services = iface->registeredServiceNames();
+ foreach (QString service, services) {
+ if (service.startsWith("org.mpris.MediaPlayer2.")) {
+ qDebug() << "have mpris service" << service;
+ m_mprisService = service;
+ fetchMusicMetadata();
+ QDBusConnection::sessionBus().connect(m_mprisService, "/org/mpris/MediaPlayer2", "", "PropertiesChanged", this, SLOT(mediaPropertiesChanged(QString,QVariantMap,QStringList)));
+ break;
+ }
+ }
+
+ QDBusMessage call = QDBusMessage::createMethodCall("org.PulseAudio1", "/org/pulseaudio/server_lookup1", "org.freedesktop.DBus.Properties", "Get" );
+ call << "org.PulseAudio.ServerLookup1" << "Address";
+ QDBusReply<QDBusVariant> lookupReply = QDBusConnection::sessionBus().call(call);
+ if (lookupReply.isValid()) {
+ //
+ qDebug() << "PulseAudio Bus address: " << lookupReply.value().variant().toString();
+ _pulseBus = new QDBusConnection(QDBusConnection::connectToPeer(lookupReply.value().variant().toString(), "org.PulseAudio1"));
+ }
+ // Query max volume
+ call = QDBusMessage::createMethodCall("com.Meego.MainVolume2", "/com/meego/mainvolume2",
+ "org.freedesktop.DBus.Properties", "Get");
+ call << "com.Meego.MainVolume2" << "StepCount";
+ QDBusReply<QDBusVariant> volumeMaxReply = _pulseBus->call(call);
+ if (volumeMaxReply.isValid()) {
+ _maxVolume = volumeMaxReply.value().variant().toUInt();
+ qDebug() << "Max volume: " << _maxVolume;
+ }
+ else {
+ qWarning() << "Could not read volume max, cannot adjust volume: " << volumeMaxReply.error().message();
+ }
+
+ // Calls
+ m_telepathyMonitor = new TelepathyMonitor(this);
+ connect(m_telepathyMonitor, &TelepathyMonitor::incomingCall, this, &SailfishPlatform::incomingCall);
+ connect(m_telepathyMonitor, &TelepathyMonitor::callStarted, this, &SailfishPlatform::callStarted);
+ connect(m_telepathyMonitor, &TelepathyMonitor::callEnded, this, &SailfishPlatform::callEnded);
+
+ // Organizer
+ m_organizerAdapter = new OrganizerAdapter(this);
+ m_organizerAdapter->refresh();
+ connect(m_organizerAdapter, &OrganizerAdapter::itemsChanged, this, &SailfishPlatform::organizerItemsChanged);
+ m_syncMonitorClient = new SyncMonitorClient(this);
+ connect(m_syncMonitorClient, &SyncMonitorClient::stateChanged, [this]() { if (m_syncMonitorClient->state() == "idle") m_organizerAdapter->refresh();});
+ m_syncTimer.start(1000 * 60 * 60);
+ connect(&m_syncTimer, &QTimer::timeout, [this]() { m_syncMonitorClient->sync({"calendar"});});
+ m_syncMonitorClient->sync({"calendar"});
+}
+
+QDBusInterface *SailfishPlatform::interface() const
+{
+ return m_iface;
+}
+
+uint SailfishPlatform::Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expire_timeout)
+{
+ qDebug() << "Notification received" << app_name << replaces_id << app_icon << summary << body << actions << hints << expire_timeout;
+ QString owner = hints.value("x-nemo-owner", "").toString();
+
+ // Look up the notification category and its parameters
+ QString category = hints.value("category", "").toString();
+ QHash<QString, QString> categoryParams = this->getCategoryParams(category);
+
+ // Ignore transient and hidden notifications (notif hints override category hints)
+ // Hack this to accept transient -preview and -summary notifications, as we don't know how to decode the actual notifs yet
+ if (hints.value("transient", categoryParams.value("transient", "false")).toString() == "true") {
+ qDebug() << "Ignoring transient notification from " << owner;
+ return 0;
+ }
+ else if (hints.value("x-nemo-hidden", "false").toString() == "true" ) {
+ qDebug() << "Ignoring hidden notification from " << owner;
+ return 0;
+ }
+
+ Notification n(app_name);
+ if (owner == "twitter-notifications-client") {
+ n.setType(Notification::NotificationTypeTwitter);
+ n.setSourceName("Twitter");
+ } else if (category == "x-nemo.email") {
+ if (app_name.toLower().contains("gmail")) {
+ n.setType(Notification::NotificationTypeGMail);
+ n.setSourceName("GMail");
+ }
+ else {
+ n.setType(Notification::NotificationTypeEmail);
+ n.setSubject(app_name);
+ }
+ } else if (owner == "facebook-notifications-client") {
+ n.setType(Notification::NotificationTypeFacebook);
+ n.setSourceName("Facebook");
+ } else if (hints.value("x-nemo-origin-package").toString() == "org.telegram.messenger"
+ || category.startsWith("harbour.sailorgram")) {
+ n.setType(Notification::NotificationTypeTelegram);
+ n.setSourceName("Telegram");
+ } else if (hints.value("x-nemo-origin-package").toString() == "com.google.android.apps.babel"
+ || owner == "harbour-hangish") {
+ n.setType(Notification::NotificationTypeHangout);
+ n.setSourceName("Hangouts");
+ } else if (hints.value("x-nemo-origin-package").toString() == "com.whatsapp"
+ || owner.toLower().contains("whatsup")) {
+ n.setType(Notification::NotificationTypeWhatsApp);
+ n.setSourceName("Whatsapp");
+ } else if (app_name.contains("indicator-datetime")) {
+ n.setType(Notification::NotificationTypeReminder);
+ n.setSourceName("reminders");
+ } else {
+ n.setType(Notification::NotificationTypeGeneric);
+ }
+ n.setSender(summary);
+ n.setBody(body);
+ foreach (const QString &action, actions) {
+ if (action == "default") {
+ n.setActToken(hints.value("x-nemo-remote-action-default").toString());
+ break;
+ }
+ }
+ qDebug() << "have act token" << n.actToken();
+
+ emit notificationReceived(n);
+ // We never return something. We're just snooping in...
+ setDelayedReply(true);
+ return 0;
+}
+
+ QHash<QString, QString> SailfishPlatform::getCategoryParams(QString category)
+ {
+ if (!category.isEmpty()) {
+ QString categoryConfigFile = QString("/usr/share/lipstick/notificationcategories/%1.conf").arg(category);
+ QFile testFile(categoryConfigFile);
+ if (testFile.exists()) {
+ QHash<QString, QString> categories;
+ QSettings settings(categoryConfigFile, QSettings::IniFormat);
+ const QStringList settingKeys = settings.allKeys();
+ foreach (const QString &settingKey, settingKeys) {
+ categories[settingKey] = settings.value(settingKey).toString();
+ }
+ return categories;
+ }
+ }
+ return QHash<QString, QString>();
+ }
+
+void SailfishPlatform::sendMusicControlCommand(MusicControlButton controlButton)
+{
+ QString method;
+ switch (controlButton) {
+ case MusicControlPlayPause:
+ method = "PlayPause";
+ break;
+ case MusicControlSkipBack:
+ method = "Previous";
+ break;
+ case MusicControlSkipNext:
+ method = "Next";
+ break;
+ default:
+ ;
+ }
+
+ if (!method.isEmpty()) {
+ QDBusMessage call = QDBusMessage::createMethodCall(m_mprisService, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player", method);
+ QDBusError err = QDBusConnection::sessionBus().call(call);
+
+ if (err.isValid()) {
+ qWarning() << "Error calling mpris method on" << m_mprisService << ":" << err.message();
+ }
+ return;
+ }
+
+ if (controlButton == MusicControlVolumeUp || controlButton == MusicControlVolumeDown) {
+ QDBusMessage call = QDBusMessage::createMethodCall("com.Meego.MainVolume2", "/com/meego/mainvolume2",
+ "org.freedesktop.DBus.Properties", "Get");
+ call << "com.Meego.MainVolume2" << "CurrentStep";
+
+ QDBusReply<QDBusVariant> volumeReply = _pulseBus->call(call);
+ if (volumeReply.isValid()) {
+ // Decide the new value for volume, taking limits into account
+ uint volume = volumeReply.value().variant().toUInt();
+ uint newVolume;
+ qDebug() << "Current volume: " << volumeReply.value().variant().toUInt();
+ if (controlButton == MusicControlVolumeUp && volume < _maxVolume-1 ) {
+ newVolume = volume + 1;
+ }
+ else if (controlButton == MusicControlVolumeDown && volume > 0) {
+ newVolume = volume - 1;
+ }
+ else {
+ qDebug() << "Volume already at limit";
+ newVolume = volume;
+ }
+
+ // If we have a new volume level, change it
+ if (newVolume != volume) {
+ qDebug() << "Setting volume: " << newVolume;
+
+ call = QDBusMessage::createMethodCall("com.Meego.MainVolume2", "/com/meego/mainvolume2",
+ "org.freedesktop.DBus.Properties", "Set");
+ call << "com.Meego.MainVolume2" << "CurrentStep" << QVariant::fromValue(QDBusVariant(newVolume));
+
+ QDBusError err = _pulseBus->call(call);
+ if (err.isValid()) {
+ qWarning() << err.message();
+ }
+ }
+ }
+ }
+}
+
+MusicMetaData SailfishPlatform::musicMetaData() const
+{
+ return m_musicMetaData;
+}
+
+void SailfishPlatform::hangupCall(uint cookie)
+{
+ m_telepathyMonitor->hangupCall(cookie);
+}
+
+QList<CalendarEvent> SailfishPlatform::organizerItems() const
+{
+ return m_organizerAdapter->items();
+}
+
+void SailfishPlatform::actionTriggered(const QString &actToken)
+{
+ QVariantMap action;
+ // Extract the element of the DBus call
+ QStringList elements(actToken.split(' ', QString::SkipEmptyParts));
+ if (elements.size() <= 3) {
+ qWarning() << "Unable to decode invalid remote action:" << actToken;
+ } else {
+ int index = 0;
+ action.insert(QStringLiteral("service"), elements.at(index++));
+ action.insert(QStringLiteral("path"), elements.at(index++));
+ action.insert(QStringLiteral("iface"), elements.at(index++));
+ action.insert(QStringLiteral("method"), elements.at(index++));
+
+ if (index < elements.size()) {
+ QVariantList args;
+ while (index < elements.size()) {
+ const QString &arg(elements.at(index++));
+ const QByteArray buffer(QByteArray::fromBase64(arg.toUtf8()));
+
+ QDataStream stream(buffer);
+ QVariant var;
+ stream >> var;
+ args.append(var);
+ }
+ action.insert(QStringLiteral("arguments"), args);
+ }
+ qDebug() << "Calling: " << action;
+ QDBusMessage call = QDBusMessage::createMethodCall(action.value("service").toString(), action.value("path").toString(), action.value("iface").toString(), action.value("method").toString());
+ if (action.contains("arguments")) call.setArguments(action.value("arguments").toList());
+ QDBusConnection::sessionBus().call(call);
+ }
+}
+
+void SailfishPlatform::fetchMusicMetadata()
+{
+ if (!m_mprisService.isEmpty()) {
+ QDBusMessage call = QDBusMessage::createMethodCall(m_mprisService, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get");
+ call << "org.mpris.MediaPlayer2.Player" << "Metadata";
+ QDBusPendingCall pcall = QDBusConnection::sessionBus().asyncCall(call);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
+ connect(watcher, &QDBusPendingCallWatcher::finished, this, &SailfishPlatform::fetchMusicMetadataFinished);
+ }
+}
+
+void SailfishPlatform::fetchMusicMetadataFinished(QDBusPendingCallWatcher *watcher)
+{
+ watcher->deleteLater();
+ QDBusReply<QDBusVariant> reply = watcher->reply();
+ if (reply.isValid()) {
+ QVariantMap curMetadata = qdbus_cast<QVariantMap>(reply.value().variant().value<QDBusArgument>());
+ m_musicMetaData.artist = curMetadata.value("xesam:artist").toString();
+ m_musicMetaData.album = curMetadata.value("xesam:album").toString();
+ m_musicMetaData.title = curMetadata.value("xesam:title").toString();
+ emit musicMetadataChanged(m_musicMetaData);
+ } else {
+ qWarning() << reply.error().message();
+ }
+}
+
+void SailfishPlatform::mediaPropertiesChanged(const QString &interface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
+{
+ Q_UNUSED(interface)
+ Q_UNUSED(changedProps)
+ Q_UNUSED(invalidatedProps)
+ fetchMusicMetadata();
+}
diff --git a/rockworkd/platformintegration/sailfish/sailfishplatform.h b/rockworkd/platformintegration/sailfish/sailfishplatform.h
new file mode 100644
index 0000000..e18b986
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/sailfishplatform.h
@@ -0,0 +1,58 @@
+#ifndef SAILFISHPLATFORM_H
+#define SAILFISHPLATFORM_H
+
+#include "libpebble/platforminterface.h"
+#include "libpebble/enums.h"
+
+#include <QDBusInterface>
+#include <TelepathyQt/AbstractClientObserver>
+
+class QDBusPendingCallWatcher;
+class TelepathyMonitor;
+class OrganizerAdapter;
+class SyncMonitorClient;
+
+class SailfishPlatform : public PlatformInterface, public QDBusContext
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Notifications")
+ Q_PROPERTY(QDBusInterface* interface READ interface)
+
+
+public:
+ SailfishPlatform(QObject *parent = 0);
+ QDBusInterface* interface() const;
+
+ void sendMusicControlCommand(MusicControlButton controlButton) override;
+ MusicMetaData musicMetaData() const override;
+ void hangupCall(uint cookie) override;
+ QHash<QString, QString> getCategoryParams(QString category);
+
+ QList<CalendarEvent> organizerItems() const override;
+
+ void actionTriggered(const QString &actToken) override;
+
+public slots:
+ uint Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expire_timeout);
+
+
+private slots:
+ void fetchMusicMetadata();
+ void fetchMusicMetadataFinished(QDBusPendingCallWatcher *watcher);
+ void mediaPropertiesChanged(const QString &interface, const QVariantMap &changedProps, const QStringList &invalidatedProps);
+
+private:
+ QDBusInterface *m_iface;
+
+ QString m_mprisService;
+ MusicMetaData m_musicMetaData;
+ QDBusConnection *_pulseBus;
+ uint _maxVolume;
+
+ TelepathyMonitor *m_telepathyMonitor;
+ OrganizerAdapter *m_organizerAdapter;
+ SyncMonitorClient *m_syncMonitorClient;
+ QTimer m_syncTimer;
+};
+
+#endif // SAILFISHPLATFORM_H
diff --git a/rockworkd/platformintegration/sailfish/syncmonitorclient.cpp b/rockworkd/platformintegration/sailfish/syncmonitorclient.cpp
new file mode 100644
index 0000000..b43509e
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/syncmonitorclient.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This file is part of sync-monitor.
+ *
+ * sync-monitor 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; version 3.
+ *
+ * contact-service-app 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 <QDebug>
+#include <QTimer>
+
+#include "syncmonitorclient.h"
+
+#define SYNCMONITOR_DBUS_SERVICE_NAME "com.canonical.SyncMonitor"
+#define SYNCMONITOR_DBUS_OBJECT_PATH "/com/canonical/SyncMonitor"
+#define SYNCMONITOR_DBUS_INTERFACE "com.canonical.SyncMonitor"
+
+
+SyncMonitorClient::SyncMonitorClient(QObject *parent)
+ : QObject(parent),
+ m_iface(0)
+{
+ m_iface = new QDBusInterface(SYNCMONITOR_DBUS_SERVICE_NAME,
+ SYNCMONITOR_DBUS_OBJECT_PATH,
+ SYNCMONITOR_DBUS_INTERFACE);
+ if (m_iface->lastError().isValid()) {
+ qWarning() << "Fail to connect with sync monitor:" << m_iface->lastError();
+ return;
+ }
+
+ connect(m_iface, SIGNAL(stateChanged()), SIGNAL(stateChanged()));
+ connect(m_iface, SIGNAL(enabledServicesChanged()), SIGNAL(enabledServicesChanged()));
+ m_iface->call("attach");
+}
+
+SyncMonitorClient::~SyncMonitorClient()
+{
+ if (m_iface) {
+ m_iface->call("detach");
+ delete m_iface;
+ m_iface = 0;
+ }
+}
+
+QString SyncMonitorClient::state() const
+{
+ if (m_iface) {
+ return m_iface->property("state").toString();
+ } else {
+ return "";
+ }
+}
+
+QStringList SyncMonitorClient::enabledServices() const
+{
+ if (m_iface) {
+ return m_iface->property("enabledServices").toStringList();
+ } else {
+ return QStringList();
+ }
+}
+
+/*!
+ Start a new sync for specified services
+*/
+void SyncMonitorClient::sync(const QStringList &services)
+{
+ if (m_iface) {
+ qDebug() << "starting sync!";
+ m_iface->call("sync", services);
+ }
+}
+
+/*!
+ Cancel current sync for specified services
+*/
+void SyncMonitorClient::cancel(const QStringList &services)
+{
+ if (m_iface) {
+ m_iface->call("cancel", services);
+ }
+}
+
+/*!
+ Chek if a specific service is enabled or not
+*/
+bool SyncMonitorClient::serviceIsEnabled(const QString &service)
+{
+ return enabledServices().contains(service);
+}
diff --git a/rockworkd/platformintegration/sailfish/syncmonitorclient.h b/rockworkd/platformintegration/sailfish/syncmonitorclient.h
new file mode 100644
index 0000000..1587ba5
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/syncmonitorclient.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2014 Canonical Ltd.
+ *
+ * This file is part of sync-monitor.
+ *
+ * sync-monitor 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; version 3.
+ *
+ * contact-service-app 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/>.
+ */
+
+#ifndef SYNCMONITOR_QML_H
+#define SYNCMONITOR_QML_H
+
+#include <QObject>
+#include <QDBusInterface>
+
+class SyncMonitorClient : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString state READ state NOTIFY stateChanged)
+ Q_PROPERTY(QStringList enabledServices READ enabledServices NOTIFY enabledServicesChanged)
+
+public:
+ SyncMonitorClient(QObject *parent = 0);
+ ~SyncMonitorClient();
+
+ QString state() const;
+ QStringList enabledServices() const;
+
+Q_SIGNALS:
+ void stateChanged();
+ void enabledServicesChanged();
+
+public Q_SLOTS:
+ void sync(const QStringList &services);
+ void cancel(const QStringList &services);
+ bool serviceIsEnabled(const QString &service);
+
+private:
+ QDBusInterface *m_iface;
+};
+
+#endif
diff --git a/rockworkd/platformintegration/sailfish/voicecallhandler.cpp b/rockworkd/platformintegration/sailfish/voicecallhandler.cpp
new file mode 100644
index 0000000..2ae5087
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallhandler.cpp
@@ -0,0 +1,372 @@
+#include "voicecallhandler.h"
+
+#include <QDebug>
+#include <QDBusInterface>
+#include <QDBusPendingReply>
+#include <QDBusReply>
+#include <QVariantMap>
+
+/*!
+ \class VoiceCallHandler
+ \brief This is the D-Bus proxy for communicating with the voice call manager
+ from a declarative context, this interface specifically interfaces with
+ the managers' voice call handler instances.
+*/
+class VoiceCallHandlerPrivate
+{
+ Q_DECLARE_PUBLIC(VoiceCallHandler)
+
+public:
+ VoiceCallHandlerPrivate(VoiceCallHandler *q, const QString &pHandlerId)
+ : q_ptr(q), handlerId(pHandlerId), interface(NULL)
+ , duration(0), status(0), emergency(false), incoming(false)
+ , multiparty(false) , forwarded(false), remoteHeld(false)
+ { /* ... */ }
+
+ VoiceCallHandler *q_ptr;
+
+ QString handlerId;
+
+ QDBusInterface *interface;
+
+ int duration;
+ int status;
+ QString statusText;
+ QString lineId;
+ QString providerId;
+ QDateTime startedAt;
+ bool emergency;
+ bool incoming;
+ bool multiparty;
+ bool forwarded;
+ bool remoteHeld;
+};
+
+/*!
+ Constructs a new proxy interface for the provided voice call handlerId.
+*/
+VoiceCallHandler::VoiceCallHandler(const QString &handlerId, QObject *parent)
+ : QObject(parent), l(metaObject()->className()), d_ptr(new VoiceCallHandlerPrivate(this, handlerId))
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << QString("Creating D-Bus interface to: ") + handlerId;
+ d->interface = new QDBusInterface("org.nemomobile.voicecall",
+ "/calls/" + handlerId,
+ "org.nemomobile.voicecall.VoiceCall",
+ QDBusConnection::sessionBus(),
+ this);
+ this->initialize(true);
+}
+
+VoiceCallHandler::~VoiceCallHandler()
+{
+ Q_D(VoiceCallHandler);
+ delete d;
+}
+
+void VoiceCallHandler::initialize(bool notifyError)
+{
+ Q_D(VoiceCallHandler);
+
+ if (d->interface->isValid()) {
+ if (getProperties()) {
+ emit durationChanged();
+ emit statusChanged();
+ emit lineIdChanged();
+ emit startedAtChanged();
+ emit multipartyChanged();
+ emit emergencyChanged();
+ emit forwardedChanged();
+
+ connect(d->interface, SIGNAL(error(QString)), SIGNAL(error(QString)));
+ connect(d->interface, SIGNAL(statusChanged(int, QString)), SLOT(onStatusChanged(int, QString)));
+ connect(d->interface, SIGNAL(lineIdChanged(QString)), SLOT(onLineIdChanged(QString)));
+ connect(d->interface, SIGNAL(durationChanged(int)), SLOT(onDurationChanged(int)));
+ connect(d->interface, SIGNAL(startedAtChanged(QDateTime)), SLOT(onStartedAtChanged(QDateTime)));
+ connect(d->interface, SIGNAL(emergencyChanged(bool)), SLOT(onEmergencyChanged(bool)));
+ connect(d->interface, SIGNAL(multipartyChanged(bool)), SLOT(onMultipartyChanged(bool)));
+ connect(d->interface, SIGNAL(forwardedChanged(bool)), SLOT(onForwardedChanged(bool)));
+ connect(d->interface, SIGNAL(remoteHeldChanged(bool)), SLOT(onRemoteHeldChanged(bool)));
+ }
+ else {
+ if (notifyError) emit this->error("Failed to get VoiceCall properties from VCM D-Bus service.");
+ }
+ }
+ else {
+ qCCritical(l) << d->interface->lastError().name() << d->interface->lastError().message();
+ }
+}
+
+bool VoiceCallHandler::getProperties()
+{
+ Q_D(VoiceCallHandler);
+
+ QDBusInterface props(d->interface->service(), d->interface->path(),
+ "org.freedesktop.DBus.Properties", d->interface->connection());
+
+ QDBusReply<QVariantMap> reply = props.call("GetAll", d->interface->interface());
+ if (reply.isValid()) {
+ QVariantMap props = reply.value();
+ qCDebug(l) << props;
+ d->providerId = props["providerId"].toString();
+ d->duration = props["duration"].toInt();
+ d->status = props["status"].toInt();
+ d->statusText = props["statusText"].toString();
+ d->lineId = props["lineId"].toString();
+ d->startedAt = QDateTime::fromMSecsSinceEpoch(props["startedAt"].toULongLong());
+ d->multiparty = props["isMultiparty"].toBool();
+ d->emergency = props["isEmergency"].toBool();
+ d->forwarded = props["isForwarded"].toBool();
+ d->incoming = props["isIncoming"].toBool();
+ d->remoteHeld = props["isIncoming"].toBool();
+ return true;
+ }
+ else {
+ qCCritical(l) << "Failed to get VoiceCall properties from VCM D-Bus service.";
+ return false;
+ }
+}
+
+void VoiceCallHandler::onDurationChanged(int duration)
+{
+ Q_D(VoiceCallHandler);
+ //qCDebug(l) <<"onDurationChanged"<<duration;
+ d->duration = duration;
+ emit durationChanged();
+}
+
+void VoiceCallHandler::onStatusChanged(int status, QString statusText)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) <<"onStatusChanged" << status << statusText;
+ d->status = status;
+ d->statusText = statusText;
+ if (status) getProperties(); // make sure all properties are present
+ emit statusChanged();
+}
+
+void VoiceCallHandler::onLineIdChanged(QString lineId)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onLineIdChanged" << lineId;
+ d->lineId = lineId;
+ emit lineIdChanged();
+}
+
+void VoiceCallHandler::onStartedAtChanged(const QDateTime &startedAt)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onStartedAtChanged" << startedAt;
+ d->startedAt = d->interface->property("startedAt").toDateTime();
+ emit startedAtChanged();
+}
+
+void VoiceCallHandler::onEmergencyChanged(bool isEmergency)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onEmergencyChanged" << isEmergency;
+ d->emergency = isEmergency;
+ emit emergencyChanged();
+}
+
+void VoiceCallHandler::onMultipartyChanged(bool isMultiparty)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onMultipartyChanged" << isMultiparty;
+ d->multiparty = isMultiparty;
+ emit multipartyChanged();
+}
+
+void VoiceCallHandler::onForwardedChanged(bool isForwarded)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onForwardedChanged" << isForwarded;
+ d->forwarded = isForwarded;
+ emit forwardedChanged();
+}
+
+void VoiceCallHandler::onRemoteHeldChanged(bool isRemoteHeld)
+{
+ Q_D(VoiceCallHandler);
+ qCDebug(l) << "onRemoteHeldChanged" << isRemoteHeld;
+ d->forwarded = isRemoteHeld;
+ emit remoteHeldChanged();
+}
+
+/*!
+ Returns this voice calls' handler id.
+ */
+QString VoiceCallHandler::handlerId() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->handlerId;
+}
+
+/*!
+ Returns this voice calls' provider id.
+ */
+QString VoiceCallHandler::providerId() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->providerId;
+}
+
+/*!
+ Returns this voice calls' call status.
+ */
+int VoiceCallHandler::status() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->status;
+}
+
+/*!
+ Returns this voice calls' call status as a symbolic string.
+ */
+QString VoiceCallHandler::statusText() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->statusText;
+}
+
+/*!
+ Returns this voice calls' remote end-point line id.
+ */
+QString VoiceCallHandler::lineId() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->lineId;
+}
+
+/*!
+ Returns this voice calls' started at property.
+ */
+QDateTime VoiceCallHandler::startedAt() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->startedAt;
+}
+
+/*!
+ Returns this voice calls' duration property.
+ */
+int VoiceCallHandler::duration() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->duration;
+}
+
+/*!
+ Returns this voice calls' incoming call flag property.
+ */
+bool VoiceCallHandler::isIncoming() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->incoming;
+}
+
+/*!
+ Returns this voice calls' multiparty flag property.
+ */
+bool VoiceCallHandler::isMultiparty() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->multiparty;
+}
+
+/*!
+ Returns this voice calls' forwarded flag property.
+ */
+bool VoiceCallHandler::isForwarded() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->forwarded;
+}
+
+/*!
+ Returns this voice calls' emergency flag property.
+ */
+bool VoiceCallHandler::isEmergency() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->emergency;
+}
+
+/*!
+ Returns this voice calls' remoteHeld flag property.
+ */
+bool VoiceCallHandler::isRemoteHeld() const
+{
+ Q_D(const VoiceCallHandler);
+ return d->remoteHeld;
+}
+
+/*!
+ Initiates answering this call, if the call is an incoming call.
+ */
+void VoiceCallHandler::answer()
+{
+ Q_D(VoiceCallHandler);
+ QDBusPendingCall call = d->interface->asyncCall("answer");
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*)));
+}
+
+/*!
+ Initiates droping the call, unless the call is disconnected.
+ */
+void VoiceCallHandler::hangup()
+{
+ Q_D(VoiceCallHandler);
+ QDBusPendingCall call = d->interface->asyncCall("hangup");
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*)));
+}
+
+/*!
+ Initiates holding the call, unless the call is disconnected.
+ */
+void VoiceCallHandler::hold(bool on)
+{
+ Q_D(VoiceCallHandler);
+ QDBusPendingCall call = d->interface->asyncCall("hold", on);
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*)));
+}
+
+/*!
+ Initiates deflecting the call to the provided target phone number.
+ */
+void VoiceCallHandler::deflect(const QString &target)
+{
+ Q_D(VoiceCallHandler);
+ QDBusPendingCall call = d->interface->asyncCall("deflect", target);
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*)));
+}
+
+void VoiceCallHandler::sendDtmf(const QString &tones)
+{
+ Q_D(VoiceCallHandler);
+ QDBusPendingCall call = d->interface->asyncCall("sendDtmf", tones);
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*)));
+}
+
+void VoiceCallHandler::onPendingCallFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<bool> reply = *watcher;
+
+ if (reply.isError()) {
+ qCCritical(l) << QString::fromLatin1("Received error reply for member: %1 (%2)").arg(reply.reply().member()).arg(reply.error().message());
+ emit this->error(reply.error().message());
+ watcher->deleteLater();
+ } else {
+ qCDebug(l) << QString::fromLatin1("Received successful reply for member: %1").arg(reply.reply().member());
+ }
+}
diff --git a/rockworkd/platformintegration/sailfish/voicecallhandler.h b/rockworkd/platformintegration/sailfish/voicecallhandler.h
new file mode 100644
index 0000000..e718abb
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallhandler.h
@@ -0,0 +1,96 @@
+#ifndef VOICECALLHANDLER_H
+#define VOICECALLHANDLER_H
+
+#include <QObject>
+#include <QDateTime>
+#include <QDBusPendingCallWatcher>
+#include <QLoggingCategory>
+
+class VoiceCallHandler : public QObject
+{
+ Q_OBJECT
+ QLoggingCategory l;
+
+ Q_ENUMS(VoiceCallStatus)
+
+ Q_PROPERTY(QString handlerId READ handlerId CONSTANT)
+ Q_PROPERTY(QString providerId READ providerId CONSTANT)
+ Q_PROPERTY(int status READ status NOTIFY statusChanged)
+ Q_PROPERTY(QString statusText READ statusText NOTIFY statusChanged)
+ Q_PROPERTY(QString lineId READ lineId NOTIFY lineIdChanged)
+ Q_PROPERTY(QDateTime startedAt READ startedAt NOTIFY startedAtChanged)
+ Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(bool isIncoming READ isIncoming CONSTANT)
+ Q_PROPERTY(bool isEmergency READ isEmergency NOTIFY emergencyChanged)
+ Q_PROPERTY(bool isMultiparty READ isMultiparty NOTIFY multipartyChanged)
+ Q_PROPERTY(bool isForwarded READ isForwarded NOTIFY forwardedChanged)
+ Q_PROPERTY(bool isRemoteHeld READ isRemoteHeld NOTIFY remoteHeldChanged)
+
+public:
+ enum VoiceCallStatus {
+ STATUS_NULL,
+ STATUS_ACTIVE,
+ STATUS_HELD,
+ STATUS_DIALING,
+ STATUS_ALERTING,
+ STATUS_INCOMING,
+ STATUS_WAITING,
+ STATUS_DISCONNECTED
+ };
+
+ explicit VoiceCallHandler(const QString &handlerId, QObject *parent = 0);
+ ~VoiceCallHandler();
+
+ QString handlerId() const;
+ QString providerId() const;
+ int status() const;
+ QString statusText() const;
+ QString lineId() const;
+ QDateTime startedAt() const;
+ int duration() const;
+ bool isIncoming() const;
+ bool isMultiparty() const;
+ bool isEmergency() const;
+ bool isForwarded() const;
+ bool isRemoteHeld() const;
+
+Q_SIGNALS:
+ void error(const QString &error);
+ void statusChanged();
+ void lineIdChanged();
+ void durationChanged();
+ void startedAtChanged();
+ void emergencyChanged();
+ void multipartyChanged();
+ void forwardedChanged();
+ void remoteHeldChanged();
+
+public Q_SLOTS:
+ void answer();
+ void hangup();
+ void hold(bool on);
+ void deflect(const QString &target);
+ void sendDtmf(const QString &tones);
+
+protected Q_SLOTS:
+ void initialize(bool notifyError = false);
+ bool getProperties();
+
+ void onPendingCallFinished(QDBusPendingCallWatcher *watcher);
+ void onDurationChanged(int duration);
+ void onStatusChanged(int status, QString statusText);
+ void onLineIdChanged(QString lineId);
+ void onStartedAtChanged(const QDateTime &startedAt);
+ void onEmergencyChanged(bool isEmergency);
+ void onMultipartyChanged(bool isMultiparty);
+ void onForwardedChanged(bool isForwarded);
+ void onRemoteHeldChanged(bool isRemoteHeld);
+
+private:
+ class VoiceCallHandlerPrivate *d_ptr;
+
+ Q_DISABLE_COPY(VoiceCallHandler)
+ Q_DECLARE_PRIVATE(VoiceCallHandler)
+};
+
+#endif // VOICECALLHANDLER_H
diff --git a/rockworkd/platformintegration/sailfish/voicecallmanager.cpp b/rockworkd/platformintegration/sailfish/voicecallmanager.cpp
new file mode 100644
index 0000000..afb3629
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallmanager.cpp
@@ -0,0 +1,315 @@
+#include "voicecallmanager.h"
+
+#include <QDebug>
+#include <QTimer>
+#include <QDBusInterface>
+#include <QDBusPendingReply>
+
+class VoiceCallManagerPrivate
+{
+ Q_DECLARE_PUBLIC(VoiceCallManager)
+
+public:
+ VoiceCallManagerPrivate(VoiceCallManager *q)
+ : q_ptr(q),
+ interface(NULL),
+ activeVoiceCall(NULL),
+ connected(false)
+ { /*...*/ }
+
+ VoiceCallManager *q_ptr;
+
+ QDBusInterface *interface;
+
+ QList<VoiceCallHandler*> voicecalls;
+ QHash<QString,VoiceCallProviderData> providers;
+
+ VoiceCallHandler* activeVoiceCall;
+
+ bool connected;
+};
+
+VoiceCallManager::VoiceCallManager(Settings *settings, QObject *parent)
+ : QObject(parent), l(metaObject()->className()), d_ptr(new VoiceCallManagerPrivate(this)), settings(settings)
+{
+ this->initialize();
+}
+
+VoiceCallManager::~VoiceCallManager()
+{
+ Q_D(VoiceCallManager);
+ delete d;
+}
+
+void VoiceCallManager::initialize(bool notifyError)
+{
+ Q_D(VoiceCallManager);
+ bool success = false;
+
+ delete d->interface;
+ d->interface = new QDBusInterface("org.nemomobile.voicecall",
+ "/",
+ "org.nemomobile.voicecall.VoiceCallManager",
+ QDBusConnection::sessionBus(),
+ this);
+
+ if(d->interface->isValid())
+ {
+ success = true;
+ success &= (bool)QObject::connect(d->interface, SIGNAL(error(QString)), SIGNAL(error(QString)));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(voiceCallsChanged()), SLOT(onVoiceCallsChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(providersChanged()), SLOT(onProvidersChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(activeVoiceCallChanged()), SLOT(onActiveVoiceCallChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(audioModeChanged()), SIGNAL(audioModeChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(audioRoutedChanged()), SIGNAL(audioRoutedChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(microphoneMutedChanged()), SIGNAL(microphoneMutedChanged()));
+ success &= (bool)QObject::connect(d->interface, SIGNAL(speakerMutedChanged()), SIGNAL(speakerMutedChanged()));
+
+ onVoiceCallsChanged();
+ onActiveVoiceCallChanged();
+ }
+
+ if(!(d->connected = success))
+ {
+ QTimer::singleShot(2000, this, SLOT(initialize()));
+ if(notifyError) emit this->error("Failed to connect to VCM D-Bus service.");
+ }
+}
+
+QDBusInterface* VoiceCallManager::interface() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface;
+}
+
+VoiceCallHandlerList VoiceCallManager::voiceCalls() const
+{
+ Q_D(const VoiceCallManager);
+ return d->voicecalls;
+}
+
+VoiceCallProviderHash VoiceCallManager::providers() const
+{
+ Q_D(const VoiceCallManager);
+ return d->providers;
+}
+
+QString VoiceCallManager::defaultProviderId() const
+{
+ Q_D(const VoiceCallManager);
+ if(d->providers.count() == 0) {
+ qCDebug(l) << Q_FUNC_INFO << "No provider added";
+ return QString::null;
+ }
+
+ QStringList keys = d->providers.keys();
+ qSort(keys);
+
+ VoiceCallProviderData provider = d->providers.value(keys.value(0));
+ return provider.id;
+}
+
+VoiceCallHandler* VoiceCallManager::activeVoiceCall() const
+{
+ Q_D(const VoiceCallManager);
+ return d->activeVoiceCall;
+}
+
+QString VoiceCallManager::audioMode() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("audioMode").toString();
+}
+
+bool VoiceCallManager::isAudioRouted() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("isAudioRouted").toBool();
+}
+
+bool VoiceCallManager::isMicrophoneMuted() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("isMicrophoneMuted").toBool();
+}
+
+bool VoiceCallManager::isSpeakerMuted() const
+{
+ Q_D(const VoiceCallManager);
+ return d->interface->property("isSpeakerMuted").toBool();
+}
+
+void VoiceCallManager::dial(const QString &provider, const QString &msisdn)
+{
+ Q_D(VoiceCallManager);
+ QDBusPendingCall call = d->interface->asyncCall("dial", provider, msisdn);
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingCallFinished(QDBusPendingCallWatcher*)));
+}
+
+void VoiceCallManager::hangupAll()
+{
+ foreach (VoiceCallHandler* handler, voiceCalls()) {
+ handler->hangup();
+ }
+}
+
+void VoiceCallManager::silenceRingtone()
+{
+ Q_D(const VoiceCallManager);
+ QDBusPendingCall call = d->interface->asyncCall("silenceRingtone");
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(onPendingSilenceFinished(QDBusPendingCallWatcher*)));
+}
+
+/*
+ - Use of method calls instead of property setters to allow status checking.
+ */
+bool VoiceCallManager::setAudioMode(const QString &mode)
+{
+ Q_D(const VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setAudioMode", mode);
+ return reply.isError() ? false : reply.value();
+}
+
+bool VoiceCallManager::setAudioRouted(bool on)
+{
+ Q_D(const VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setAudioRouted", on);
+ return reply.isError() ? false : reply.value();
+}
+
+bool VoiceCallManager::setMuteMicrophone(bool on)
+{
+ Q_D(VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setMuteMicrophone", on);
+ return reply.isError() ? false : reply.value();
+}
+
+bool VoiceCallManager::setMuteSpeaker(bool on)
+{
+ Q_D(VoiceCallManager);
+ QDBusPendingReply<bool> reply = d->interface->call("setMuteSpeaker", on);
+ return reply.isError() ? false : reply.value();
+}
+
+void VoiceCallManager::onVoiceCallsChanged()
+{
+ Q_D(VoiceCallManager);
+ QStringList nIds = d->interface->property("voiceCalls").toStringList();
+ QStringList oIds;
+
+ QStringList added;
+ QStringList removed;
+
+ // Map current call handlers to handler ids for easy indexing.
+ foreach(VoiceCallHandler *handler, d->voicecalls)
+ {
+ oIds.append(handler->handlerId());
+ }
+
+ // Index new handlers to be added.
+ foreach(QString nId, nIds)
+ {
+ if(!oIds.contains(nId)) added.append(nId);
+ }
+
+ // Index old handlers to be removed.
+ foreach(QString oId, oIds)
+ {
+ if(!nIds.contains(oId)) removed.append(oId);
+ }
+
+ // Remove handlers that need to be removed.
+ foreach(QString removeId, removed)
+ {
+ for (int i = 0; i < d->voicecalls.count(); ++i) {
+ VoiceCallHandler *handler = d->voicecalls.at(i);
+ if(handler->handlerId() == removeId)
+ {
+ handler->disconnect(this);
+ d->voicecalls.removeAt(i);
+ handler->deleteLater();
+ break;
+ }
+ }
+ }
+
+ // Add handlers that need to be added.
+ foreach(QString addId, added)
+ {
+ VoiceCallHandler *handler = new VoiceCallHandler(addId, this);
+ d->voicecalls.append(handler);
+ }
+
+ emit this->voiceCallsChanged();
+}
+
+void VoiceCallManager::onProvidersChanged()
+{
+ Q_D(VoiceCallManager);
+ d->providers.clear();
+ foreach(QString provider, d->interface->property("providers").toStringList())
+ {
+ QStringList parts = provider.split(':');
+ d->providers.insert(parts.first(), VoiceCallProviderData(parts.first(),
+ parts.last(),
+ parts.first()));
+ }
+
+ emit this->providersChanged();
+}
+
+void VoiceCallManager::onActiveVoiceCallChanged()
+{
+ Q_D(VoiceCallManager);
+ QString voiceCallId = d->interface->property("activeVoiceCall").toString();
+
+ if(d->voicecalls.count() == 0 || voiceCallId.isNull() || voiceCallId.isEmpty())
+ {
+ d->activeVoiceCall = NULL;
+ }
+ else
+ {
+ bool found = false;
+ d->activeVoiceCall = NULL;
+ foreach(VoiceCallHandler* handler, d->voicecalls)
+ {
+ if(handler->handlerId() == voiceCallId)
+ {
+ d->activeVoiceCall = handler;
+ found = true;
+ }
+ if(!found) d->activeVoiceCall = NULL;
+ }
+ }
+
+ emit this->activeVoiceCallChanged();
+}
+
+void VoiceCallManager::onPendingCallFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<bool> reply = *watcher;
+
+ if (reply.isError()) {
+ emit this->error(reply.error().message());
+ } else {
+ qCDebug(l) << QString("Received successful reply for member: ") + reply.reply().member();
+ }
+
+ watcher->deleteLater();
+}
+
+void VoiceCallManager::onPendingSilenceFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<> reply = *watcher;
+
+ if (reply.isError()) {
+ emit this->error(reply.error().message());
+ } else {
+ qCDebug(l) << QString("Received successful reply for member: ") + reply.reply().member();
+ }
+
+ watcher->deleteLater();
+}
diff --git a/rockworkd/platformintegration/sailfish/voicecallmanager.h b/rockworkd/platformintegration/sailfish/voicecallmanager.h
new file mode 100644
index 0000000..ec51230
--- /dev/null
+++ b/rockworkd/platformintegration/sailfish/voicecallmanager.h
@@ -0,0 +1,111 @@
+#ifndef VOICECALLMANAGER_H
+#define VOICECALLMANAGER_H
+
+#include "voicecallhandler.h"
+#include "settings.h"
+
+#include <QObject>
+#include <QDBusInterface>
+#include <QDBusPendingCallWatcher>
+#include <QLoggingCategory>
+
+class VoiceCallProviderData
+{
+public:
+ VoiceCallProviderData() {/*..*/}
+ VoiceCallProviderData(const QString &pId, const QString &pType, const QString &pLabel)
+ : id(pId), type(pType), label(pLabel) {/*...*/}
+
+ QString id;
+ QString type;
+ QString label;
+};
+
+typedef QHash<QString,VoiceCallProviderData> VoiceCallProviderHash;
+
+typedef QList<VoiceCallHandler*> VoiceCallHandlerList;
+
+class VoiceCallManager : public QObject
+{
+ Q_OBJECT
+ QLoggingCategory l;
+
+ Q_PROPERTY(QDBusInterface* interface READ interface)
+
+ Q_PROPERTY(VoiceCallHandlerList voiceCalls READ voiceCalls NOTIFY voiceCallsChanged)
+ Q_PROPERTY(VoiceCallProviderHash providers READ providers NOTIFY providersChanged)
+
+ Q_PROPERTY(QString defaultProviderId READ defaultProviderId NOTIFY defaultProviderChanged)
+
+ Q_PROPERTY(VoiceCallHandler* activeVoiceCall READ activeVoiceCall NOTIFY activeVoiceCallChanged)
+
+ Q_PROPERTY(QString audioMode READ audioMode WRITE setAudioMode NOTIFY audioModeChanged)
+ Q_PROPERTY(bool isAudioRouted READ isAudioRouted WRITE setAudioRouted NOTIFY audioRoutedChanged)
+ Q_PROPERTY(bool isMicrophoneMuted READ isMicrophoneMuted WRITE setMuteMicrophone NOTIFY microphoneMutedChanged)
+ Q_PROPERTY(bool isSpeakerMuted READ isSpeakerMuted WRITE setMuteSpeaker NOTIFY speakerMutedChanged)
+
+public:
+ explicit VoiceCallManager(Settings *settings, QObject *parent = 0);
+ ~VoiceCallManager();
+
+ QDBusInterface* interface() const;
+
+ VoiceCallHandlerList voiceCalls() const;
+ VoiceCallProviderHash providers() const;
+
+ QString defaultProviderId() const;
+
+ VoiceCallHandler* activeVoiceCall() const;
+
+ QString audioMode() const;
+ bool isAudioRouted() const;
+
+ bool isMicrophoneMuted() const;
+ bool isSpeakerMuted() const;
+
+Q_SIGNALS:
+ void error(const QString &message);
+
+ void providersChanged();
+ void voiceCallsChanged();
+
+ void defaultProviderChanged();
+
+ void activeVoiceCallChanged();
+
+ void audioModeChanged();
+ void audioRoutedChanged();
+ void microphoneMutedChanged();
+ void speakerMutedChanged();
+
+public Q_SLOTS:
+ void dial(const QString &providerId, const QString &msisdn);
+ void hangupAll();
+
+ void silenceRingtone();
+
+ bool setAudioMode(const QString &mode);
+ bool setAudioRouted(bool on);
+ bool setMuteMicrophone(bool on = true);
+ bool setMuteSpeaker(bool on = true);
+
+protected Q_SLOTS:
+ void initialize(bool notifyError = false);
+
+ void onProvidersChanged();
+ void onVoiceCallsChanged();
+ void onActiveVoiceCallChanged();
+
+ void onPendingCallFinished(QDBusPendingCallWatcher *watcher);
+ void onPendingSilenceFinished(QDBusPendingCallWatcher *watcher);
+
+private:
+ class VoiceCallManagerPrivate *d_ptr;
+
+ Settings *settings;
+
+ Q_DISABLE_COPY(VoiceCallManager)
+ Q_DECLARE_PRIVATE(VoiceCallManager)
+};
+
+#endif // VOICECALLMANAGER_H
diff --git a/rockworkd/rockpoold.service b/rockworkd/rockpoold.service
new file mode 100644
index 0000000..8f87f15
--- /dev/null
+++ b/rockworkd/rockpoold.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Rockpool daemon
+Requires=dbus.socket bluetooth.target
+After=pre-user-session.target lipstick.service dbus.socket bluetooth.target
+
+[Service]
+ExecStart=/usr/bin/rockworkd
+Restart=always
+
+[Install]
+WantedBy=user-session.target
diff --git a/rockworkd/rockworkd.pro b/rockworkd/rockworkd.pro
index edb97f9..53e37ff 100644
--- a/rockworkd/rockworkd.pro
+++ b/rockworkd/rockworkd.pro
@@ -1,3 +1,147 @@
+<<<<<<< HEAD
+QT += core bluetooth dbus network contacts qml location organizer
+QT -= gui
+
+include(../version.pri)
+
+TARGET = rockpoold
+
+CONFIG += c++11
+CONFIG += console
+CONFIG += link_pkgconfig
+
+INCLUDEPATH += /usr/include/telepathy-qt5/ $$[QT_HOST_PREFIX]/include/quazip/
+LIBS += -lquazip -ltelepathy-qt5
+
+PKGCONFIG += libmkcal-qt5 libkcalcoren-qt5
+INCLUDEPATH += /usr/include/mkcal-qt5 /usr/include/kcalcoren-qt5
+
+SOURCES += main.cpp \
+ libpebble/watchconnection.cpp \
+ libpebble/pebble.cpp \
+ libpebble/watchdatareader.cpp \
+ libpebble/watchdatawriter.cpp \
+ libpebble/notificationendpoint.cpp \
+ libpebble/musicendpoint.cpp \
+ libpebble/phonecallendpoint.cpp \
+ libpebble/musicmetadata.cpp \
+ libpebble/jskit/jskitmanager.cpp \
+ libpebble/jskit/jskitconsole.cpp \
+ libpebble/jskit/jskitgeolocation.cpp \
+ libpebble/jskit/jskitlocalstorage.cpp \
+ libpebble/jskit/jskitpebble.cpp \
+ libpebble/jskit/jskitxmlhttprequest.cpp \
+ libpebble/jskit/jskittimer.cpp \
+ libpebble/jskit/jskitperformance.cpp \
+ libpebble/appinfo.cpp \
+ libpebble/appmanager.cpp \
+ libpebble/appmsgmanager.cpp \
+ libpebble/uploadmanager.cpp \
+ libpebble/bluez/bluezclient.cpp \
+ libpebble/bluez/bluez_agentmanager1.cpp \
+ libpebble/bluez/bluez_adapter1.cpp \
+ libpebble/bluez/bluez_device1.cpp \
+ libpebble/bluez/freedesktop_objectmanager.cpp \
+ libpebble/bluez/freedesktop_properties.cpp \
+ libpebble/bluez/device.cpp \
+ core.cpp \
+ pebblemanager.cpp \
+ dbusinterface.cpp \
+# Platform integration part
+ platformintegration/sailfish/sailfishplatform.cpp \
+ platformintegration/sailfish/callchannelobserver.cpp \
+# platformintegration/sailfish/voicecallmanager.cpp \
+# platformintegration/sailfish/voicecallhandler.cpp \
+ libpebble/blobdb.cpp \
+ libpebble/timelineitem.cpp \
+ libpebble/notification.cpp \
+ platformintegration/sailfish/organizeradapter.cpp \
+ libpebble/calendarevent.cpp \
+ platformintegration/sailfish/syncmonitorclient.cpp \
+ libpebble/appmetadata.cpp \
+ libpebble/appdownloader.cpp \
+ libpebble/screenshotendpoint.cpp \
+ libpebble/firmwaredownloader.cpp \
+ libpebble/bundle.cpp \
+ libpebble/watchlogendpoint.cpp \
+ libpebble/ziphelper.cpp \
+ libpebble/healthparams.cpp \
+ libpebble/dataloggingendpoint.cpp
+
+HEADERS += \
+ libpebble/watchconnection.h \
+ libpebble/pebble.h \
+ libpebble/watchdatareader.h \
+ libpebble/watchdatawriter.h \
+ libpebble/notificationendpoint.h \
+ libpebble/musicendpoint.h \
+ libpebble/musicmetadata.h \
+ libpebble/phonecallendpoint.h \
+ libpebble/platforminterface.h \
+ libpebble/jskit/jskitmanager.h \
+ libpebble/jskit/jskitconsole.h \
+ libpebble/jskit/jskitgeolocation.h \
+ libpebble/jskit/jskitlocalstorage.h \
+ libpebble/jskit/jskitpebble.h \
+ libpebble/jskit/jskitxmlhttprequest.h \
+ libpebble/jskit/jskittimer.h \
+ libpebble/jskit/jskitperformance.h \
+ libpebble/appinfo.h \
+ libpebble/appmanager.h \
+ libpebble/appmsgmanager.h \
+ libpebble/uploadmanager.h \
+ libpebble/bluez/bluezclient.h \
+ libpebble/bluez/bluez_agentmanager1.h \
+ libpebble/bluez/bluez_adapter1.h \
+ libpebble/bluez/bluez_device1.h \
+ libpebble/bluez/freedesktop_objectmanager.h \
+ libpebble/bluez/freedesktop_properties.h \
+ libpebble/bluez/device.h \
+ core.h \
+ pebblemanager.h \
+ dbusinterface.h \
+# Platform integration part
+ platformintegration/sailfish/sailfishplatform.h \
+ platformintegration/sailfish/callchannelobserver.h \
+# platformintegration/sailfish/voicecallmanager.h \
+# platformintegration/sailfish/voicecallhandler.h \
+ libpebble/blobdb.h \
+ libpebble/timelineitem.h \
+ libpebble/notification.h \
+ platformintegration/sailfish/organizeradapter.h \
+ libpebble/calendarevent.h \
+ platformintegration/sailfish/syncmonitorclient.h \
+ libpebble/appmetadata.h \
+ libpebble/appdownloader.h \
+ libpebble/enums.h \
+ libpebble/screenshotendpoint.h \
+ libpebble/firmwaredownloader.h \
+ libpebble/bundle.h \
+ libpebble/watchlogendpoint.h \
+ libpebble/ziphelper.h \
+ libpebble/healthparams.h \
+ libpebble/dataloggingendpoint.h
+
+testing: {
+ SOURCES += platformintegration/testing/testingplatform.cpp
+ HEADERS += platformintegration/testing/testingplatform.h
+ RESOURCES += platformintegration/testing/testui.qrc
+ DEFINES += ENABLE_TESTING
+ QT += qml quick
+}
+
+INSTALLS += target systemd
+
+systemd.files = $${TARGET}.service
+systemd.path = /usr/lib/systemd/user
+
+# Default rules for deployment.
+target.path = /usr/bin
+
+RESOURCES += \
+ libpebble/jskit/jsfiles.qrc
+
+=======
QT += core bluetooth dbus network contacts qml location organizer websockets
QT -= gui
@@ -146,3 +290,4 @@ QMAKE_POST_LINK = sed -i s/@VERSION@/$$VERSION/g $$OUT_PWD/../manifest.json || e
RESOURCES += \
libpebble/jskit/jsfiles.qrc
+>>>>>>> refs/heads/rockwork
diff --git a/rpm/rockpool.changes b/rpm/rockpool.changes
new file mode 100644
index 0000000..fee8c03
--- /dev/null
+++ b/rpm/rockpool.changes
@@ -0,0 +1,2 @@
+* Thu Jan 21 2016 Andrew Branson <andrew@andrewbranson.net> 0.1
+- Initial Merge of pebbled and rockwork
diff --git a/rpm/rockpool.spec b/rpm/rockpool.spec
new file mode 100644
index 0000000..57e470b
--- /dev/null
+++ b/rpm/rockpool.spec
@@ -0,0 +1,97 @@
+#
+# Do NOT Edit the Auto-generated Part!
+# Generated by: spectacle version 0.27
+#
+
+Name: rockpool
+
+# >> macros
+# << macros
+
+%{!?qtc_qmake:%define qtc_qmake %qmake}
+%{!?qtc_qmake5:%define qtc_qmake5 %qmake5}
+%{!?qtc_make:%define qtc_make make}
+%{?qtc_builddir:%define _builddir %qtc_builddir}
+Summary: Support for Pebble watches in SailfishOS
+Version: 0.1
+Release: 1
+Group: Qt/Qt
+License: GPL3
+URL: http://getpebble.com/
+Source0: %{name}-%{version}.tar.xz
+Source100: rockpool.yaml
+Requires: sailfishsilica-qt5 >= 0.10.9
+Requires: systemd-user-session-targets
+Requires: nemo-qml-plugin-dbus-qt5
+Requires: quazip
+BuildRequires: pkgconfig(Qt5DBus)
+BuildRequires: pkgconfig(Qt5Bluetooth)
+BuildRequires: pkgconfig(Qt5Contacts)
+BuildRequires: pkgconfig(Qt5Quick)
+BuildRequires: pkgconfig(Qt5Qml)
+BuildRequires: pkgconfig(Qt5Core)
+BuildRequires: pkgconfig(Qt5Network)
+BuildRequires: pkgconfig(Qt5Location)
+BuildRequires: pkgconfig(Qt5Organizer)
+BuildRequires: pkgconfig(mlite5)
+BuildRequires: pkgconfig(sailfishapp) >= 0.0.10
+BuildRequires: pkgconfig(icu-i18n)
+BuildRequires: pkgconfig(zlib)
+BuildRequires: pkgconfig(libmkcal-qt5)
+BuildRequires: pkgconfig(libkcalcoren-qt5)
+BuildRequires: desktop-file-utils
+
+%description
+Support for Pebble watch on SailfishOS devices.
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+# >> setup
+# << setup
+
+%build
+# >> build pre
+# << build pre
+
+%qtc_qmake5 \
+ VERSION='%{version}-%{release}'
+
+%qtc_make %{?_smp_mflags}
+
+# >> build post
+# << build post
+
+%install
+rm -rf %{buildroot}
+# >> install pre
+# << install pre
+%qmake5_install
+
+# >> install post
+mkdir -p %{buildroot}%{_libdir}/systemd/user/user-session.target.wants
+ln -s ../rockpoold.service %{buildroot}%{_libdir}/systemd/user/user-session.target.wants/
+# << install post
+
+desktop-file-install --delete-original \
+ --dir %{buildroot}%{_datadir}/applications \
+ %{buildroot}%{_datadir}/applications/*.desktop
+
+%post
+# >> post
+su nemo -c 'systemctl --user daemon-reload'
+su nemo -c 'systemctl --user try-restart rockpoold.service'
+update-desktop-database
+# << post
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}
+%{_datadir}/%{name}/qml
+%{_datadir}/applications/%{name}.desktop
+%{_datadir}/icons/hicolor/86x86/apps/%{name}.png
+%{_libdir}/systemd/user/%{name}d.service
+%{_libdir}/systemd/user/user-session.target.wants/%{name}d.service
+# >> files
+# << files
diff --git a/rpm/rockpool.yaml b/rpm/rockpool.yaml
new file mode 100644
index 0000000..6d17a53
--- /dev/null
+++ b/rpm/rockpool.yaml
@@ -0,0 +1,43 @@
+Name: rockpool
+Summary: Support for Pebble watches in SailfishOS
+Version: 0.1
+Release: 1
+Group: Qt/Qt
+URL: http://getpebble.com/
+License: GPL3
+Sources:
+- '%{name}-%{version}.tar.xz'
+Description: |
+ Support for Pebble watch on SailfishOS devices.
+Configure: none
+Builder: qtc5
+QMakeOptions:
+- VERSION='%{version}-%{release}'
+PkgConfigBR:
+- Qt5DBus
+- Qt5Bluetooth
+- Qt5Contacts
+- Qt5Quick
+- Qt5Qml
+- Qt5Core
+- Qt5Network
+- Qt5Location
+- Qt5Organizer
+- mlite5
+- sailfishapp >= 0.0.10
+- icu-i18n
+- zlib
+- libmkcal-qt5
+- libkcalcoren-qt5
+Requires:
+- sailfishsilica-qt5 >= 0.10.9
+- systemd-user-session-targets
+- nemo-qml-plugin-dbus-qt5
+- quazip
+Files:
+- '%{_bindir}'
+- '%{_datadir}/%{name}/qml'
+- '%{_datadir}/applications/%{name}.desktop'
+- '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png'
+- '%{_libdir}/systemd/user/%{name}d.service'
+- '%{_libdir}/systemd/user/user-session.target.wants/%{name}d.service'