summaryrefslogtreecommitdiff
path: root/sowatchui
diff options
context:
space:
mode:
Diffstat (limited to 'sowatchui')
-rw-r--r--sowatchui/main.cpp16
-rw-r--r--sowatchui/qml/MainPage.qml79
-rw-r--r--sowatchui/qml/NewWatchSheet.qml43
-rw-r--r--sowatchui/qml/WatchPage.qml36
-rw-r--r--sowatchui/qml/main.qml22
-rw-r--r--sowatchui/scannerproxy.cc26
-rw-r--r--sowatchui/scannerproxy.h58
-rw-r--r--sowatchui/scanwatchesmodel.cc102
-rw-r--r--sowatchui/scanwatchesmodel.h49
-rw-r--r--sowatchui/sowatchui.pro17
-rw-r--r--sowatchui/watchesmodel.cc136
-rw-r--r--sowatchui/watchesmodel.h40
12 files changed, 548 insertions, 76 deletions
diff --git a/sowatchui/main.cpp b/sowatchui/main.cpp
index 54a65fa..f306fa9 100644
--- a/sowatchui/main.cpp
+++ b/sowatchui/main.cpp
@@ -1,11 +1,27 @@
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
+#include <sowatch.h>
+
+#include "watchesmodel.h"
+#include "scanwatchesmodel.h"
+
+static sowatch::Registry *registry;
+static WatchesModel *watches;
+static ScanWatchesModel *watchScanner;
+
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
+ registry = sowatch::Registry::registry();
+ watches = new WatchesModel(app.data());
+ watchScanner = new ScanWatchesModel(app.data());
+
+ viewer->rootContext()->setContextProperty("watches", watches);
+ viewer->rootContext()->setContextProperty("watchScanner", watchScanner);
+
viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer->setMainQmlFile(QLatin1String("qml/main.qml"));
viewer->showExpanded();
diff --git a/sowatchui/qml/MainPage.qml b/sowatchui/qml/MainPage.qml
index a7ba7d7..b660161 100644
--- a/sowatchui/qml/MainPage.qml
+++ b/sowatchui/qml/MainPage.qml
@@ -1,67 +1,38 @@
import QtQuick 1.1
-import com.nokia.meego 1.0
+import com.nokia.meego 1.1
+import com.nokia.extras 1.1
Page {
id: mainPage
- tools: commonTools
+ anchors.leftMargin: UiConstants.DefaultMargin
+ anchors.rightMargin: UiConstants.DefaultMargin
- ListModel {
- id: testModel
- ListElement {
- name: "one"
- }
- ListElement {
- name: "two"
+ tools: ToolBarLayout {
+ ToolIcon {
+ platformIconId: "toolbar-add"
+ anchors.right: parent.right
+ onClicked: newWatchSheet.open()
}
}
- Flickable {
- anchors.fill: parent
- contentWidth: mainPage.width
- contentHeight: mainColumn.height + 100
-
- Column {
- id: mainColumn
+ NewWatchSheet {
+ id: newWatchSheet
+ }
- width: mainPage.width
- height: childrenRect.height
- spacing: 8
+ ListView {
+ id: watchesListView
+ anchors.fill: parent
+ model: watches
- ListView {
- model: testModel
- width: mainPage.width
- height: 50*model.count
- clip: true
- interactive: false
- delegate: Rectangle {
- height: 50
- width: mainPage.width
- color: "red"
- Text {
- text: name
- }
- }
- }
- ListView {
- model: testModel
- width: mainPage.width
- height: 50*model.count
- clip: true
- interactive: false
- delegate: Rectangle {
- height: 50
- width: mainPage.width
- color: "green"
- Text {
- text: name
- }
- }
- }
- Button {
- anchors.horizontalCenter: parent.horizontalCenter
- text: qsTr("Refresh")
- onClicked: Sowatch.refreshWatches()
- }
+ delegate: ListDelegate {
+ Image {
+ source: "image://theme/icon-m-common-drilldown-arrow" + (theme.inverted ? "-inverse" : "")
+ anchors.right: parent.right;
+ anchors.verticalCenter: parent.verticalCenter
+ }
}
}
+ ScrollDecorator {
+ flickableItem: watchesListView
+ }
}
diff --git a/sowatchui/qml/NewWatchSheet.qml b/sowatchui/qml/NewWatchSheet.qml
new file mode 100644
index 0000000..1028bd5
--- /dev/null
+++ b/sowatchui/qml/NewWatchSheet.qml
@@ -0,0 +1,43 @@
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import com.nokia.extras 1.1
+
+Sheet {
+ id: sheet
+ anchors.margins: UiConstants.DefaultMargin
+
+ rejectButtonText: qsTr("Cancel")
+
+ title: BusyIndicator {
+ anchors.centerIn: parent;
+ running: watchScanner.active
+ }
+
+ Binding {
+ target: watchScanner
+ property: "enabled"
+ value: sheet.status === DialogStatus.Open
+ }
+
+ content: ListView {
+ id: listView
+ anchors.fill: parent
+ anchors.margins: UiConstants.DefaultMargin
+
+ flickableDirection: Flickable.VerticalFlick
+
+ model: watchScanner
+
+ delegate: ListDelegate {
+ onClicked: {
+ watches.addFoundWatch(object);
+ close();
+ accepted();
+ }
+ }
+
+ ScrollDecorator {
+ flickableItem: listView
+ }
+ }
+}
diff --git a/sowatchui/qml/WatchPage.qml b/sowatchui/qml/WatchPage.qml
new file mode 100644
index 0000000..fb7011c
--- /dev/null
+++ b/sowatchui/qml/WatchPage.qml
@@ -0,0 +1,36 @@
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import com.nokia.extras 1.1
+
+Page {
+ id: watchPage
+ anchors.leftMargin: UiConstants.DefaultMargin
+ anchors.rightMargin: UiConstants.DefaultMargin
+
+ tools: ToolBarLayout {
+ ToolIcon {
+ platformIconId: "toolbar-back"
+ anchors.left: parent.left
+ onClicked: pageStack.pop()
+ }
+ }
+
+ ListView {
+ id: emptyListView
+ anchors.fill: parent
+ model: ListModel {
+
+ }
+
+ delegate: ListDelegate {
+ Image {
+ source: "image://theme/icon-m-common-drilldown-arrow" + (theme.inverted ? "-inverse" : "")
+ anchors.right: parent.right;
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ }
+ ScrollDecorator {
+ flickableItem: watchesListView
+ }
+}
diff --git a/sowatchui/qml/main.qml b/sowatchui/qml/main.qml
index eb4c081..ca838a2 100644
--- a/sowatchui/qml/main.qml
+++ b/sowatchui/qml/main.qml
@@ -1,5 +1,5 @@
import QtQuick 1.1
-import com.nokia.meego 1.0
+import com.nokia.meego 1.1
PageStackWindow {
id: appWindow
@@ -10,30 +10,14 @@ PageStackWindow {
id: mainPage
}
- ToolBarLayout {
- id: commonTools
- visible: true
- ToolIcon {
- platformIconId: "toolbar-view-menu"
- anchors.right: (parent === undefined) ? undefined : parent.right
- onClicked: (myMenu.status === DialogStatus.Closed) ? myMenu.open() : myMenu.close()
- }
- }
-
Menu {
id: myMenu
visualParent: pageStack
MenuLayout {
MenuItem {
- text: qsTr("Start service")
- onClicked: {
- Sowatch.start();
- }
- }
- MenuItem {
- text: qsTr("Stop service")
+ text: qsTr("Crap")
onClicked: {
- Sowatch.stop();
+ console.log("Crap")
}
}
}
diff --git a/sowatchui/scannerproxy.cc b/sowatchui/scannerproxy.cc
new file mode 100644
index 0000000..cfa4365
--- /dev/null
+++ b/sowatchui/scannerproxy.cc
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -c ScannerProxy -p scannerproxy ../sowatchd/scanner.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "scannerproxy.h"
+
+/*
+ * Implementation of interface class ScannerProxy
+ */
+
+ScannerProxy::ScannerProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+ScannerProxy::~ScannerProxy()
+{
+}
+
diff --git a/sowatchui/scannerproxy.h b/sowatchui/scannerproxy.h
new file mode 100644
index 0000000..3b1b9c8
--- /dev/null
+++ b/sowatchui/scannerproxy.h
@@ -0,0 +1,58 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -c ScannerProxy -p scannerproxy ../sowatchd/scanner.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef SCANNERPROXY_H_1344446154
+#define SCANNERPROXY_H_1344446154
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface com.javispedro.sowatch.WatchScanner
+ */
+class ScannerProxy: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "com.javispedro.sowatch.WatchScanner"; }
+
+public:
+ ScannerProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~ScannerProxy();
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<> Start()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Start"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+ void Finished();
+ void Started();
+ void WatchFound(const QVariantMap &info);
+};
+
+namespace com {
+ namespace javispedro {
+ namespace sowatch {
+ typedef ::ScannerProxy WatchScanner;
+ }
+ }
+}
+#endif
diff --git a/sowatchui/scanwatchesmodel.cc b/sowatchui/scanwatchesmodel.cc
new file mode 100644
index 0000000..5b7c331
--- /dev/null
+++ b/sowatchui/scanwatchesmodel.cc
@@ -0,0 +1,102 @@
+#include <QtDebug>
+
+#include "scanwatchesmodel.h"
+
+ScanWatchesModel::ScanWatchesModel(QObject *parent) :
+ QAbstractListModel(parent),
+ _scanner(new ScannerProxy("com.javispedro.sowatchd", "/com/javispedro/sowatch/allscanner", QDBusConnection::sessionBus())),
+ _timer(new QTimer(this)),
+ _enabled(false), _active(false)
+{
+ QHash<int, QByteArray> roles = roleNames();
+ roles[Qt::DisplayRole] = QByteArray("title");
+ roles[Qt::StatusTipRole] = QByteArray("subtitle");
+ roles[ObjectRole] = QByteArray("object");
+ setRoleNames(roles);
+
+ _timer->setSingleShot(true);
+ _timer->setInterval(3000);
+
+ connect(_scanner, SIGNAL(WatchFound(QVariantMap)), SLOT(handleWatchFound(QVariantMap)));
+ connect(_scanner, SIGNAL(Started()), SLOT(handleStarted()));
+ connect(_scanner, SIGNAL(Finished()), SLOT(handleFinished()));
+ connect(_timer, SIGNAL(timeout()), SLOT(handleTimeout()));
+}
+
+ScanWatchesModel::~ScanWatchesModel()
+{
+}
+
+bool ScanWatchesModel::enabled() const
+{
+ return _enabled;
+}
+
+void ScanWatchesModel::setEnabled(bool enabled)
+{
+ _timer->stop();
+
+ _enabled = enabled;
+
+ if (_enabled && !_active) {
+ _scanner->Start();
+ }
+}
+
+bool ScanWatchesModel::active() const
+{
+ return _active;
+}
+
+int ScanWatchesModel::rowCount(const QModelIndex &parent) const
+{
+ return _list.count();
+}
+
+QVariant ScanWatchesModel::data(const QModelIndex &index, int role) const
+{
+ qDebug() << "Asked for data" << index.row() << index.column() << role;
+ const QVariantMap &info = _list.at(index.row());
+ switch (role) {
+ case Qt::DisplayRole:
+ return info["name"];
+ case Qt::StatusTipRole:
+ return info["address"];
+ case ObjectRole:
+ return QVariant::fromValue(info);
+ }
+ return QVariant();
+}
+
+void ScanWatchesModel::handleWatchFound(const QVariantMap &info)
+{
+ qDebug() << "Watch found" << info << endl;
+ if (!_list.contains(info)) {
+ int count = _list.count();
+ beginInsertRows(QModelIndex(), count, count);
+ _list.append(info);
+ endInsertRows();
+ }
+}
+
+void ScanWatchesModel::handleStarted()
+{
+ _active = true;
+ emit activeChanged();
+}
+
+void ScanWatchesModel::handleFinished()
+{
+ qDebug() << "Scan finished";
+ _active = false;
+ if (_enabled) {
+ _timer->start();
+ }
+ emit activeChanged();
+}
+
+void ScanWatchesModel::handleTimeout()
+{
+ qDebug() << "Restarting scan";
+ _scanner->Start();
+}
diff --git a/sowatchui/scanwatchesmodel.h b/sowatchui/scanwatchesmodel.h
new file mode 100644
index 0000000..424ded4
--- /dev/null
+++ b/sowatchui/scanwatchesmodel.h
@@ -0,0 +1,49 @@
+#ifndef SCANWATCHESMODEL_H
+#define SCANWATCHESMODEL_H
+
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QTimer>
+#include <sowatch.h>
+
+#include "scannerproxy.h"
+
+class ScanWatchesModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
+ Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+
+public:
+ explicit ScanWatchesModel(QObject *parent = 0);
+ ~ScanWatchesModel();
+
+ enum DataRoles {
+ ObjectRole = Qt::UserRole
+ };
+
+ bool enabled() const;
+ void setEnabled(bool enabled);
+
+ bool active() const;
+
+ int rowCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+
+signals:
+ void activeChanged();
+
+private slots:
+ void handleWatchFound(const QVariantMap& info);
+ void handleStarted();
+ void handleFinished();
+ void handleTimeout();
+
+private:
+ ScannerProxy *_scanner;
+ QList<QVariantMap> _list;
+ QTimer *_timer;
+ bool _enabled;
+ bool _active;
+};
+
+#endif // SCANWATCHESMODEL_H
diff --git a/sowatchui/sowatchui.pro b/sowatchui/sowatchui.pro
index c73875c..e02afcc 100644
--- a/sowatchui/sowatchui.pro
+++ b/sowatchui/sowatchui.pro
@@ -9,6 +9,10 @@ DEPLOYMENTFOLDERS = qml_folder
# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =
+simulator {
+ QML_IMPORT_PATH += $$[QT_INSTALL_PREFIX]/imports/simulatorHarmattan
+ DEFINES += QT_INSTALL_PREFIX=\\\"$$[QT_INSTALL_PREFIX]\\\"
+}
# Speed up launching on MeeGo/Harmattan when using applauncherd daemon
CONFIG += qdeclarative-boostable
@@ -19,11 +23,18 @@ INCLUDEPATH += $$PWD/../libsowatch
DEPENDPATH += $$PWD/../libsowatch
# Source files
-SOURCES += main.cpp
+SOURCES += main.cpp \
+ watchesmodel.cc \
+ scanwatchesmodel.cc scannerproxy.cc
-OTHER_FILES += \
+HEADERS += \
+ watchesmodel.h \
+ scanwatchesmodel.h scannerproxy.h
+
+OTHER_FILES += qml/main.qml \
qml/MainPage.qml \
- qml/main.qml \
+ qml/NewWatchSheet.qml \
+ qml/WatchPage.qml \
sowatch_harmattan.desktop \
sowatch.desktop
diff --git a/sowatchui/watchesmodel.cc b/sowatchui/watchesmodel.cc
new file mode 100644
index 0000000..d12e7db
--- /dev/null
+++ b/sowatchui/watchesmodel.cc
@@ -0,0 +1,136 @@
+#include <QtDebug>
+
+#include "watchesmodel.h"
+
+using namespace sowatch;
+
+WatchesModel::WatchesModel(QObject *parent) :
+ QAbstractListModel(parent),
+ _config(new GConfKey("/apps/sowatch", this)),
+ _active_watches(_config->getSubkey("active-watches", this))
+{
+ QHash<int, QByteArray> roles = roleNames();
+ roles[Qt::DisplayRole] = QByteArray("title");
+ roles[Qt::StatusTipRole] = QByteArray("subtitle");
+ roles[ObjectRole] = QByteArray("object");
+ setRoleNames(roles);
+
+ connect(_config, SIGNAL(changed()),
+ this, SLOT(handleConfigChanged()));
+ connect(_config, SIGNAL(subkeyChanged(QString)),
+ this, SLOT(handleSubkeyChanged(QString)));
+ qDebug() << "connects";
+
+ reload();
+}
+
+WatchesModel::~WatchesModel()
+{
+}
+
+int WatchesModel::rowCount(const QModelIndex &parent) const
+{
+ return _list.count();
+}
+
+QVariant WatchesModel::data(const QModelIndex &index, int role) const
+{
+ qDebug() << "Asked for data" << index.row() << index.column() << role;
+ ConfigKey *config = _list[index.row()];
+ switch (role) {
+ case Qt::DisplayRole:
+ return config->value("name");
+ case Qt::StatusTipRole:
+ return QVariant(tr("Configured"));
+ }
+ return QVariant();
+}
+
+bool WatchesModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+
+}
+
+void WatchesModel::addFoundWatch(const QVariantMap &info)
+{
+ QStringList existing = _config->dirs();
+ QString base = "watch%1";
+ QString name = base.arg("");
+ int num = 1;
+
+ while (existing.contains(name)) {
+ num++;
+ name = base.arg(num);
+ }
+
+ ConfigKey* newkey = _config->getSubkey(name);
+ foreach (const QString& key, info.keys()) {
+ newkey->set(key, info[key]);
+ }
+
+ // Now add to active watches
+ QStringList active = _active_watches->value().toStringList();
+ active << name;
+ _active_watches->set(active);
+}
+
+void WatchesModel::reload()
+{
+ QStringList dirs = _config->dirs();
+
+ beginResetModel();
+ foreach (ConfigKey* conf, _list) {
+ conf->deleteLater();
+ }
+ _list.clear();
+ foreach (const QString& s, dirs) {
+ _list.append(_config->getSubkey(s, this));
+ }
+ endResetModel();
+
+ qDebug() << "Found" << _list.count() << "configured watches";
+}
+
+void WatchesModel::handleConfigChanged()
+{
+ qDebug() << "Key changed";
+}
+
+void WatchesModel::handleSubkeyChanged(const QString &subkey)
+{
+ QRegExp nameexp("^([^/]+)/name");
+ if (nameexp.exactMatch(subkey)) {
+ qDebug() << "Name key changed:" << subkey;
+ QString id = nameexp.cap(1);
+ int i = findRowByWatchId(id);
+ if (i != -1) {
+ if (_config->value(subkey).isNull()) {
+ beginRemoveRows(QModelIndex(), i, i);
+ _list[i]->deleteLater();
+ _list.removeAt(i);
+ qDebug() << "Removing" << i;
+ endRemoveRows();
+ } else {
+ emit dataChanged(createIndex(i, 0), createIndex(i, 0));
+ qDebug() << "Changing" << i;
+ }
+ } else {
+ i = _list.size();
+ qDebug() << "Inserting" << i;
+ beginInsertRows(QModelIndex(), i, i);
+ _list.append(_config->getSubkey(id, this));
+ endInsertRows();
+ }
+ }
+}
+
+int WatchesModel::findRowByWatchId(const QString &id)
+{
+ QString pattern(_config->key() + "/" + id);
+ for (int i = 0; i < _list.size(); i++) {
+ if (_list[i]->key().endsWith("/" + id)) {
+ return i;
+ }
+ }
+ return -1;
+}
diff --git a/sowatchui/watchesmodel.h b/sowatchui/watchesmodel.h
new file mode 100644
index 0000000..cc6c9af
--- /dev/null
+++ b/sowatchui/watchesmodel.h
@@ -0,0 +1,40 @@
+#ifndef WATCHESMODEL_H
+#define WATCHESMODEL_H
+
+#include <QAbstractListModel>
+
+#include <sowatch.h>
+
+class WatchesModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ explicit WatchesModel(QObject *parent = 0);
+ ~WatchesModel();
+
+ enum DataRoles {
+ ObjectRole = Qt::UserRole
+ };
+
+ int rowCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ bool removeRows(int row, int count, const QModelIndex &parent);
+
+public slots:
+ void addFoundWatch(const QVariantMap& info);
+
+private slots:
+ void reload();
+ void handleConfigChanged();
+ void handleSubkeyChanged(const QString& subkey);
+
+private:
+ int findRowByWatchId(const QString& id);
+
+private:
+ sowatch::ConfigKey *_config;
+ sowatch::ConfigKey *_active_watches;
+ QList<sowatch::ConfigKey*> _list;
+};
+
+#endif // WATCHESMODEL_H