diff options
54 files changed, 1429 insertions, 443 deletions
diff --git a/libsowatch/configkey.cpp b/libsowatch/configkey.cpp new file mode 100644 index 0000000..176b411 --- /dev/null +++ b/libsowatch/configkey.cpp @@ -0,0 +1,8 @@ +#include "configkey.h" + +using namespace sowatch; + +ConfigKey::ConfigKey(QObject *parent) +{ + Q_UNUSED(parent); +} diff --git a/libsowatch/configkey.h b/libsowatch/configkey.h new file mode 100644 index 0000000..ef7665e --- /dev/null +++ b/libsowatch/configkey.h @@ -0,0 +1,52 @@ +#ifndef SOWATCH_CONFIGKEY_H +#define SOWATCH_CONFIGKEY_H + +#include <QtCore/QObject> +#include <QtCore/QVariant> +#include <QtCore/QStringList> +#include "sowatch_global.h" + +namespace sowatch +{ + +class SOWATCH_EXPORT ConfigKey : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString key READ key CONSTANT) + Q_PROPERTY(QVariant value READ value WRITE set RESET unset NOTIFY changed USER true) + Q_PROPERTY(QStringList dirs READ dirs) + Q_PROPERTY(QStringList keys READ keys) + +public: + ConfigKey(QObject *parent = 0); + + virtual QString key() const = 0; + + virtual QVariant value() const = 0; + virtual void set(const QVariant& value) = 0; + virtual void unset() = 0; + virtual bool isSet() const = 0; + virtual bool isDir() const = 0; + + virtual QVariant value(const QString& subkey) const = 0; + virtual QVariant value(const QString& subkey, const QVariant& def) const = 0; + virtual void set(const QString& subkey, const QVariant& value) = 0; + virtual void unset(const QString& subkey) = 0; + virtual bool isSet(const QString& subkey) const = 0; + virtual bool isDir(const QString& subkey) const = 0; + + virtual QStringList dirs() const = 0; + virtual QStringList keys() const = 0; + + virtual void recursiveUnset() = 0; + + virtual ConfigKey* getSubkey(const QString& subkey, QObject *parent = 0) const = 0; + +signals: + void changed(); + void subkeyChanged(const QString& subkey); +}; + +} + +#endif // SOWATCH_CONFIGKEY_H diff --git a/libsowatch/gconfkey.cpp b/libsowatch/gconfkey.cpp new file mode 100644 index 0000000..b47deb5 --- /dev/null +++ b/libsowatch/gconfkey.cpp @@ -0,0 +1,294 @@ +#include <QtCore/QDebug> + +#include <gconf/gconf-client.h> +#include <gconf/gconf-value.h> + +#include "gconfkey.h" + +using namespace sowatch; + +static GConfClient* g_client = NULL; + +static GConfClient* get_client() { + if (!g_client) { + g_client = gconf_client_get_default(); + } + return g_client; +} + +static QVariant convert_value(GConfValue *gval) +{ + switch (gval->type) { + case GCONF_VALUE_STRING: + return QVariant(QString::fromUtf8(gconf_value_get_string(gval))); + case GCONF_VALUE_INT: + return QVariant(gconf_value_get_int(gval)); + case GCONF_VALUE_FLOAT: + return QVariant(gconf_value_get_float(gval)); + case GCONF_VALUE_BOOL: + return QVariant(gconf_value_get_bool(gval) ? true : false); + case GCONF_VALUE_LIST: + if (gconf_value_get_list_type(gval) == GCONF_VALUE_STRING) { + QStringList r; + for (GSList *l = gconf_value_get_list(gval); l; l = l->next) { + GConfValue* lgval = (GConfValue *) l->data; + r.append(QString::fromUtf8(gconf_value_get_string(lgval))); + } + return QVariant::fromValue(r); + } else { + QVariantList r; + for (GSList *l = gconf_value_get_list(gval); l; l = l->next) { + GConfValue* lgval = (GConfValue *) l->data; + r.append(convert_value(lgval)); + } + return QVariant::fromValue(r); + } + default: + return QVariant(); + } +} + +static GConfValue * convert_value(const QVariant& v) +{ + GConfValue *gval; + switch (v.type()) { + case QVariant::String: + gval = gconf_value_new(GCONF_VALUE_STRING); + gconf_value_set_string(gval, v.toString().toUtf8().constData()); + break; + case QVariant::Int: + gval = gconf_value_new(GCONF_VALUE_INT); + gconf_value_set_int(gval, v.toInt()); + break; + case QVariant::Double: + gval = gconf_value_new(GCONF_VALUE_FLOAT); + gconf_value_set_float(gval, v.toDouble()); + break; + case QVariant::Bool: + gval = gconf_value_new(GCONF_VALUE_BOOL); + gconf_value_set_bool(gval, v.toBool()); + break; + case QVariant::StringList: { + QStringList sl = v.toStringList(); + GSList *glist = NULL; + gval = gconf_value_new(GCONF_VALUE_LIST); + gconf_value_set_list_type(gval, GCONF_VALUE_STRING); + foreach (const QString& s, sl) { + GConfValue *lgval = gconf_value_new(GCONF_VALUE_STRING); + gconf_value_set_string(lgval, s.toUtf8().constData()); + glist = g_slist_prepend(glist, lgval); + } + gconf_value_set_list_nocopy(gval, g_slist_reverse(glist)); + } + break; + // TODO: QVariantList, anything else. + default: + gval = NULL; + break; + } + + return gval; +} + +static QByteArray convert_key(const QString &key) +{ + return key.toAscii(); +} + +static QString convert_key(const gchar *key) +{ + return QString::fromAscii(key); +} + +static void notify_func(GConfClient* client, guint cnxn_id, GConfEntry *entry, gpointer user_data) +{ + Q_UNUSED(client); + Q_UNUSED(cnxn_id); + GConfKey* key = static_cast<GConfKey*>(user_data); + key->notifyChanged(convert_key(entry->key)); +} + +static QString get_basename(const QString& path) +{ + int pos = path.lastIndexOf('/'); + if (pos >= 0) { + return path.mid(pos+1); + } else { + return path; + } +} + +GConfKey::GConfKey(const QString& key, QObject *parent) : + ConfigKey(parent), _key(key), _notify(0) +{ + if (_key.endsWith("/")) { + _key.chop(1); + } +} + +GConfKey::~GConfKey() +{ + if (_notify) { + GConfClient* client = get_client(); + gconf_client_remove_dir(client, getNativeKey(), NULL); + gconf_client_notify_remove(client, _notify); + } +} + +QString GConfKey::key() const +{ + return _key; +} + +QVariant GConfKey::value() const +{ + return value(QString()); +} + +void GConfKey::set(const QVariant &value) +{ + set(QString(), value); +} + +void GConfKey::unset() +{ + unset(QString()); +} + +bool GConfKey::isSet() const +{ + return isSet(QString()); +} + +bool GConfKey::isDir() const +{ + return isDir(QString()); +} + +QVariant GConfKey::value(const QString &subkey) const +{ + const QString path = fullpath(subkey); + GConfValue *gval = gconf_client_get(get_client(), convert_key(path), NULL); + if (!gval) { + return QVariant(); + } + QVariant v = convert_value(gval); + gconf_value_free(gval); + return v; +} + +QVariant GConfKey::value(const QString &subkey, const QVariant &def) const +{ + const QString path = fullpath(subkey); + GConfValue *gval = gconf_client_get_without_default(get_client(), convert_key(path), NULL); + if (!gval) { + return def; + } + QVariant v = convert_value(gval); + gconf_value_free(gval); + return v; +} + +void GConfKey::set(const QString &subkey, const QVariant &value) +{ + const QString path = fullpath(subkey); + GConfValue *gval = convert_value(value); + gconf_client_set(get_client(), convert_key(path), gval, NULL); + gconf_value_free(gval); +} + +void GConfKey::unset(const QString &subkey) +{ + const QString path = fullpath(subkey); + gconf_client_unset(get_client(), convert_key(path), NULL); +} + +bool GConfKey::isSet(const QString &subkey) const +{ + const QString path = fullpath(subkey); + GConfValue *gval = gconf_client_get_without_default(get_client(), convert_key(path), NULL); + if (gval) { + gconf_value_free(gval); + return true; + } else { + return false; + } +} + +bool GConfKey::isDir(const QString &subkey) const +{ + const QString path = fullpath(subkey); + return gconf_client_dir_exists(get_client(), convert_key(path), NULL); +} + +QStringList GConfKey::dirs() const +{ + QStringList r; + GSList *l = gconf_client_all_dirs(get_client(), getNativeKey(), NULL); + for (GSList *i = l; i; i = i->next) { + QString path = QString::fromAscii(static_cast<char*>(i->data)); + r.append(get_basename(path)); + g_free(i->data); + } + g_slist_free(l); + return r; +} + +QStringList GConfKey::keys() const +{ + QStringList r; + GSList *l = gconf_client_all_entries(get_client(), getNativeKey(), NULL); + for (GSList *i = l; i; i = i->next) { + GConfEntry *e = static_cast<GConfEntry*>(i->data); + QString path = QString::fromAscii(e->key); + r.append(get_basename(path)); + gconf_entry_free(e); + } + g_slist_free(l); + return r; +} + +void GConfKey::recursiveUnset() +{ + gconf_client_recursive_unset(get_client(), getNativeKey(), + static_cast<GConfUnsetFlags>(0), NULL); +} + +ConfigKey* GConfKey::getSubkey(const QString &subkey, QObject *parent) const +{ + return new GConfKey(fullpath(subkey), parent); +} + +void GConfKey::notifyChanged(const QString& key) +{ + if (key == _key) { + emit changed(); + } else if (key.startsWith(_key + '/')) { + emit subkeyChanged(key.mid(_key.size() + 1)); + } +} + +void GConfKey::connectNotify(const char *signal) +{ + Q_UNUSED(signal); + if (!_notify) { + GConfClient* client = get_client(); + gconf_client_add_dir(client, getNativeKey(), GCONF_CLIENT_PRELOAD_NONE, NULL); + _notify = gconf_client_notify_add(client, getNativeKey(), notify_func, + this, NULL, NULL); + } +} + +QString GConfKey::fullpath(const QString &child) const +{ + if (child.isEmpty()) { + return _key; + } else { + return _key + '/' + child; + } +} + +QByteArray GConfKey::getNativeKey() const +{ + return convert_key(_key); +} diff --git a/libsowatch/gconfkey.h b/libsowatch/gconfkey.h new file mode 100644 index 0000000..c9074ea --- /dev/null +++ b/libsowatch/gconfkey.h @@ -0,0 +1,54 @@ +#ifndef SOWATCH_GCONFKEY_H +#define SOWATCH_GCONFKEY_H + +#include "configkey.h" + +namespace sowatch +{ + +class SOWATCH_EXPORT GConfKey : public ConfigKey +{ + Q_OBJECT + +public: + GConfKey(const QString& key, QObject *parent = 0); + ~GConfKey(); + + QString key() const; + + QVariant value() const; + void set(const QVariant& value); + void unset(); + bool isSet() const; + bool isDir() const; + + QVariant value(const QString& subkey) const; + QVariant value(const QString& subkey, const QVariant& def) const; + void set(const QString& subkey, const QVariant& value); + void unset(const QString& subkey); + bool isSet(const QString& subkey) const; + bool isDir(const QString& subkey) const; + + QStringList dirs() const; + QStringList keys() const; + + void recursiveUnset(); + + ConfigKey* getSubkey(const QString& subkey, QObject *parent = 0) const; + + void notifyChanged(const QString& key); + +protected: + void connectNotify(const char *signal); + +private: + QString _key; + uint _notify; + + QString fullpath(const QString& subkey = QString()) const; + QByteArray getNativeKey() const; +}; + +} + +#endif // SOWATCH_CONFIGKEY_H diff --git a/libsowatch/libsowatch.pro b/libsowatch/libsowatch.pro index 6f657c8..7a5b8eb 100644 --- a/libsowatch/libsowatch.pro +++ b/libsowatch/libsowatch.pro @@ -4,11 +4,14 @@ # #------------------------------------------------- -QT += gui declarative +QT += gui declarative -TARGET = sowatch -TEMPLATE = lib -VERSION = 1.0.0 +CONFIG += link_pkgconfig +PKGCONFIG += gconf-2.0 + +TARGET = sowatch +TEMPLATE = lib +VERSION = 1.0.0 DEFINES += SOWATCH_LIBRARY @@ -27,7 +30,10 @@ SOURCES += \ notificationplugininterface.cpp \ notificationprovider.cpp \ watchletplugininterface.cpp \ - registry.cpp + registry.cpp \ + watchscanner.cpp \ + configkey.cpp \ + gconfkey.cpp HEADERS += \ watchsimulator.h \ @@ -46,26 +52,18 @@ HEADERS += \ notificationplugininterface.h \ notificationprovider.h \ watchletplugininterface.h \ - registry.h + registry.h \ + watchscanner.h \ + configkey.h \ + gconfkey.h install_headers.files = $$HEADERS -symbian { - MMP_RULES += EXPORTUNFROZEN - TARGET.UID3 = 0xE6B95AFF - TARGET.CAPABILITY = - TARGET.EPOCALLOWDLLDATA = 1 - addFiles.sources = libsowatch.dll - addFiles.path = !:/sys/bin - DEPLOYMENT += addFiles +install_headers.path = /usr/include/sowatch +!isEmpty(MEEGO_VERSION_MAJOR)|maemo5 { + target.path = /opt/sowatch/lib +} else { + target.path = /usr/lib } -unix:!symbian { - install_headers.path = /usr/include/sowatch - !isEmpty(MEEGO_VERSION_MAJOR)|maemo5 { - target.path = /opt/sowatch/lib - } else { - target.path = /usr/lib - } - INSTALLS += install_headers target -} +INSTALLS += install_headers target diff --git a/libsowatch/notificationplugininterface.h b/libsowatch/notificationplugininterface.h index b6c16f7..d753afc 100644 --- a/libsowatch/notificationplugininterface.h +++ b/libsowatch/notificationplugininterface.h @@ -9,6 +9,7 @@ namespace sowatch { +class ConfigKey; class Notification; class NotificationProvider; @@ -18,7 +19,7 @@ public: virtual ~NotificationPluginInterface(); virtual QStringList providers() = 0; - virtual NotificationProvider* getProvider(const QString& driver, QSettings& settings, QObject *parent = 0) = 0; + virtual NotificationProvider* getProvider(const QString& driver, ConfigKey *settings, QObject *parent = 0) = 0; }; } diff --git a/libsowatch/registry.cpp b/libsowatch/registry.cpp index 7ade260..5cbc464 100644 --- a/libsowatch/registry.cpp +++ b/libsowatch/registry.cpp @@ -21,99 +21,228 @@ Registry* Registry::registry() return singleRegistry; } +Registry::~Registry() +{ +} + Registry::Registry() + : _watcher(new QFileSystemWatcher(this)) { + _watcher->addPath(SOWATCH_DRIVERS_DIR); + _watcher->addPath(SOWATCH_NOTIFICATIONS_DIR); + _watcher->addPath(SOWATCH_WATCHLETS_DIR); + loadDrivers(); loadNotificationProviders(); loadWatchlets(); + + connect(_watcher, SIGNAL(directoryChanged(QString)), + this, SLOT(handlePluginDirectoryChanged(QString))); + connect(_watcher, SIGNAL(fileChanged(QString)), + this, SLOT(handlePluginFileChanged(QString))); } void Registry::loadDrivers() { QDir dir(SOWATCH_DRIVERS_DIR); - foreach (QString file, dir.entryList(QDir::Files)) { -#if defined(Q_OS_UNIX) - // Temporary workaround for QtC deploy plugin issues - if (!file.endsWith(".so")) continue; -#endif - QPluginLoader loader(dir.absoluteFilePath(file)); - QObject *pluginObj = loader.instance(); - if (pluginObj) { - WatchPluginInterface *plugin = qobject_cast<WatchPluginInterface*>(pluginObj); - if (plugin) { - QStringList drivers = plugin->drivers(); - foreach (const QString& driver, drivers) { - _drivers[driver] = plugin; - } - } else { - qWarning() << "Invalid plugin" << file; - loader.unload(); - } - } else { - qWarning() << "Invalid plugin" << file << loader.errorString(); - loader.unload(); - } + foreach (QString entry, dir.entryList(QDir::Files)) { + QString file = dir.absoluteFilePath(entry); + loadDriver(file); } - qDebug() << "loaded drivers" << _drivers.keys(); + qDebug() << "loaded drivers" << _driverIds.keys(); } void Registry::loadNotificationProviders() { QDir dir(SOWATCH_NOTIFICATIONS_DIR); - foreach (QString file, dir.entryList(QDir::Files)) { -#if defined(Q_OS_UNIX) - // Temporary workaround for QtC deploy plugin issues - if (!file.endsWith(".so")) continue; -#endif - QPluginLoader loader(dir.absoluteFilePath(file)); - QObject *pluginObj = loader.instance(); - if (pluginObj) { - NotificationPluginInterface *plugin = qobject_cast<NotificationPluginInterface*>(pluginObj); - if (plugin) { - QStringList providers = plugin->providers(); - foreach (const QString& provider, providers) { - _providers[provider] = plugin; - } - } else { - qWarning() << "Invalid plugin" << file; - loader.unload(); + foreach (QString entry, dir.entryList(QDir::Files)) { + QString file = dir.absoluteFilePath(entry); + loadNotificationProvider(file); + } + + qDebug() << "loaded notification providers" << _providerIds.keys(); +} + +void Registry::loadWatchlets() +{ + QDir dir(SOWATCH_WATCHLETS_DIR); + foreach (QString entry, dir.entryList(QDir::Files)) { + QString file = dir.absoluteFilePath(entry); + loadWatchlet(file); + } + + qDebug() << "loaded watchlets" << _watchletIds.keys(); +} + +void Registry::loadDriver(const QString &file) +{ + QPluginLoader* loader = new QPluginLoader(file, this); + QObject *pluginObj = loader->instance(); + if (pluginObj) { + WatchPluginInterface *plugin = qobject_cast<WatchPluginInterface*>(pluginObj); + if (plugin) { + _driverFiles[file] = loader; + _drivers += plugin; + QStringList drivers = plugin->drivers(); + foreach (const QString& driver, drivers) { + _driverIds[driver] = plugin; } + _watcher->addPath(file); } else { - qWarning() << "Invalid plugin" << file << loader.errorString(); - loader.unload(); + qWarning() << "Invalid plugin" << file; + loader->unload(); + delete loader; } + } else { + qWarning() << "Invalid plugin" << file << loader->errorString(); + loader->unload(); + delete loader; } +} - qDebug() << "loaded notification providers" << _providers.keys(); +void Registry::loadNotificationProvider(const QString &file) +{ + QPluginLoader* loader = new QPluginLoader(file, this); + QObject *pluginObj = loader->instance(); + if (pluginObj) { + NotificationPluginInterface *plugin = qobject_cast<NotificationPluginInterface*>(pluginObj); + if (plugin) { + _providerFiles[file] = loader; + _providers += plugin; + QStringList providers = plugin->providers(); + foreach (const QString& provider, providers) { + _providerIds[provider] = plugin; + } + _watcher->addPath(file); + } else { + qWarning() << "Invalid plugin" << file; + loader->unload(); + delete loader; + } + } else { + qWarning() << "Invalid plugin" << file << loader->errorString(); + loader->unload(); + delete loader; + } } -void Registry::loadWatchlets() +void Registry::loadWatchlet(const QString &file) { - QDir dir(SOWATCH_WATCHLETS_DIR); - foreach (QString file, dir.entryList(QDir::Files)) { -#if defined(Q_OS_UNIX) - // Temporary workaround for QtC deploy plugin issues - if (!file.endsWith(".so")) continue; -#endif - QPluginLoader loader(dir.absoluteFilePath(file)); - QObject *pluginObj = loader.instance(); - if (pluginObj) { - WatchletPluginInterface *plugin = qobject_cast<WatchletPluginInterface*>(pluginObj); - if (plugin) { - QStringList watchlets = plugin->watchlets(); - foreach (const QString& watchlet, watchlets) { - _watchlets[watchlet] = plugin; - } - } else { - qWarning() << "Invalid plugin" << file; - loader.unload(); + QPluginLoader* loader = new QPluginLoader(file, this); + QObject *pluginObj = loader->instance(); + if (pluginObj) { + WatchletPluginInterface *plugin = qobject_cast<WatchletPluginInterface*>(pluginObj); + if (plugin) { + _watchletFiles[file] = loader; + _watchlets += plugin; + QStringList watchlets = plugin->watchlets(); + foreach (const QString& watchlet, watchlets) { + _watchletIds[watchlet] = plugin; } + _watcher->addPath(file); } else { - qWarning() << "Invalid plugin" << file << loader.errorString(); - loader.unload(); + qWarning() << "Invalid plugin" << file; + loader->unload(); + delete loader; } + } else { + qWarning() << "Invalid plugin" << file << loader->errorString(); + loader->unload(); + delete loader; } +} + +void Registry::unloadDriver(QPluginLoader *loader) +{ + QString file = loader->fileName(); + + WatchPluginInterface *plugin = qobject_cast<WatchPluginInterface*>(loader->instance()); + QStringList drivers = plugin->drivers(); - qDebug() << "loaded watchlets" << _watchlets.keys(); + foreach (const QString& driver, drivers) { + _driverIds.remove(driver); + } + + _drivers.removeAll(plugin); + _driverFiles.remove(file); + _watcher->removePath(file); + + // loader->unload(); + // TODO : Signal loss of a plugin so that servers can remove it before + // we unload it. +} + +void Registry::unloadNotificationProvider(QPluginLoader *loader) +{ + QString file = loader->fileName(); + NotificationPluginInterface *plugin = qobject_cast<NotificationPluginInterface*>(loader->instance()); + QStringList providers = plugin->providers(); + + foreach (const QString& provider, providers) { + _providerIds.remove(provider); + } + + _providers.removeAll(plugin); + _providerFiles.remove(file); + _watcher->removePath(file); +} + +void Registry::unloadWatchlet(QPluginLoader *loader) +{ + QString file = loader->fileName(); + WatchletPluginInterface *plugin = qobject_cast<WatchletPluginInterface*>(loader->instance()); + QStringList watchlets = plugin->watchlets(); + + foreach (const QString& watchlet, watchlets) { + _watchletIds.remove(watchlet); + } + + _watchlets.removeAll(plugin); + _watchletFiles.remove(file); + _watcher->removePath(file); +} + +void Registry::handlePluginDirectoryChanged(const QString &path) +{ + // If the directory changed, rescan it to load new discover new plugins. + if (path == SOWATCH_DRIVERS_DIR) { + QDir dir(path); + foreach (QString entry, dir.entryList(QDir::Files)) { + QString file = dir.absoluteFilePath(entry); + if (!_driverFiles.contains(file)) { + loadDriver(file); + } + } + } else if (path == SOWATCH_NOTIFICATIONS_DIR) { + QDir dir(path); + foreach (QString entry, dir.entryList(QDir::Files)) { + QString file = dir.absoluteFilePath(entry); + if (!_providerFiles.contains(file)) { + loadNotificationProvider(file); + } + } + } else if (path == SOWATCH_WATCHLETS_DIR) { + QDir dir(path); + foreach (QString entry, dir.entryList(QDir::Files)) { + QString file = dir.absoluteFilePath(entry); + if (!_watchletFiles.contains(file)) { + loadWatchlet(file); + } + } + } +} + +void Registry::handlePluginFileChanged(const QString &file) +{ + QFile f(file); + if (_driverFiles.contains(file)) { + unloadDriver(_driverFiles[file]); + } + if (_providerFiles.contains(file)) { + unloadNotificationProvider(_providerFiles[file]); + } + if (_watchletFiles.contains(file)) { + unloadWatchlet(_watchletFiles[file]); + } } diff --git a/libsowatch/registry.h b/libsowatch/registry.h index ca7252a..74e9388 100644 --- a/libsowatch/registry.h +++ b/libsowatch/registry.h @@ -1,8 +1,10 @@ #ifndef SOWATCH_REGISTRY_H #define SOWATCH_REGISTRY_H +#include <QtCore/QPluginLoader> #include <QtCore/QString> #include <QtCore/QMap> +#include <QtCore/QFileSystemWatcher> #include "sowatch_global.h" namespace sowatch @@ -12,21 +14,35 @@ class WatchPluginInterface; class NotificationPluginInterface; class WatchletPluginInterface; -class SOWATCH_EXPORT Registry +class SOWATCH_EXPORT Registry : public QObject { + Q_OBJECT + public: static Registry* registry(); + inline QList<WatchPluginInterface*> getWatchPlugins() { + return _drivers; + } + + inline QList<NotificationPluginInterface*> getNotificationPlugins() { + return _providers; + } + + inline QList<WatchletPluginInterface*> getWatchletPlugins() { + return _watchlets; + } + inline WatchPluginInterface* getWatchPlugin(const QString& id) { - return _drivers.value(id, 0); + return _driverIds.value(id, 0); } inline NotificationPluginInterface* getNotificationPlugin(const QString& id) { - return _providers.value(id, 0); + return _providerIds.value(id, 0); } inline WatchletPluginInterface* getWatchletPlugin(const QString& id) { - return _watchlets.value(id, 0); + return _watchletIds.value(id, 0); } protected: @@ -36,13 +52,35 @@ protected: private: static Registry* singleRegistry; - QMap<QString, WatchPluginInterface*> _drivers; - QMap<QString, NotificationPluginInterface*> _providers; - QMap<QString, WatchletPluginInterface*> _watchlets; + QFileSystemWatcher* _watcher; + + QList<WatchPluginInterface*> _drivers; + QList<NotificationPluginInterface*> _providers; + QList<WatchletPluginInterface*> _watchlets; + + QMap<QString, QPluginLoader*> _driverFiles; + QMap<QString, QPluginLoader*> _providerFiles; + QMap<QString, QPluginLoader*> _watchletFiles; + + QMap<QString, WatchPluginInterface*> _driverIds; + QMap<QString, NotificationPluginInterface*> _providerIds; + QMap<QString, WatchletPluginInterface*> _watchletIds; void loadDrivers(); void loadNotificationProviders(); void loadWatchlets(); + + void loadDriver(const QString& file); + void loadNotificationProvider(const QString& file); + void loadWatchlet(const QString& file); + + void unloadDriver(QPluginLoader* loader); + void unloadNotificationProvider(QPluginLoader* loader); + void unloadWatchlet(QPluginLoader* loader); + +private slots: + void handlePluginDirectoryChanged(const QString& path); + void handlePluginFileChanged(const QString& file); }; } diff --git a/libsowatch/sowatch.h b/libsowatch/sowatch.h index b0aa999..efc5ee8 100644 --- a/libsowatch/sowatch.h +++ b/libsowatch/sowatch.h @@ -3,9 +3,13 @@ #include "sowatch_global.h" +#include "configkey.h" +#include "gconfkey.h" + #include "watch.h" #include "watchserver.h" #include "watchsimulator.h" +#include "watchscanner.h" #include "watchplugininterface.h" #include "notification.h" diff --git a/libsowatch/sowatch_global.h b/libsowatch/sowatch_global.h index 510a38a..9c6cf73 100644 --- a/libsowatch/sowatch_global.h +++ b/libsowatch/sowatch_global.h @@ -10,7 +10,11 @@ # define SOWATCH_EXPORT Q_DECL_IMPORT #endif -#if defined(MEEGO_VERSION_MAJOR) || defined(Q_WS_MAEMO_5) +#if defined(QT_SIMULATOR) || !defined(QT_NO_DEBUG) +# define SOWATCH_PLUGINS_DIR ".." +# define SOWATCH_RESOURCES_DIR ".." +# define SOWATCH_QML_DIR ".." +#elif defined(MEEGO_VERSION_MAJOR) || defined(Q_WS_MAEMO_5) # define SOWATCH_PLUGINS_DIR "/opt/sowatch/lib" # define SOWATCH_RESOURCES_DIR "/opt/sowatch/share" # define SOWATCH_QML_DIR "/opt/sowatch/qml" diff --git a/libsowatch/watchlet.cpp b/libsowatch/watchlet.cpp index 15e0b6c..9b3567e 100644 --- a/libsowatch/watchlet.cpp +++ b/libsowatch/watchlet.cpp @@ -6,7 +6,7 @@ using namespace sowatch; Watchlet::Watchlet(WatchServer *server, const QString& id) : QObject(server), _id(id), _active(false), _server(server) { - _server->registerWatchlet(this); + } Watchlet::~Watchlet() diff --git a/libsowatch/watchletplugininterface.h b/libsowatch/watchletplugininterface.h index 4f525f2..ef03d81 100644 --- a/libsowatch/watchletplugininterface.h +++ b/libsowatch/watchletplugininterface.h @@ -9,6 +9,7 @@ namespace sowatch { +class ConfigKey; class Watchlet; class WatchServer; @@ -18,7 +19,7 @@ public: virtual ~WatchletPluginInterface(); virtual QStringList watchlets() = 0; - virtual Watchlet* getWatchlet(const QString& id, QSettings& settings, WatchServer *server) = 0; + virtual Watchlet* getWatchlet(const QString& id, ConfigKey *settings, WatchServer *server) = 0; }; } diff --git a/libsowatch/watchplugininterface.h b/libsowatch/watchplugininterface.h index c027c47..804f7f5 100644 --- a/libsowatch/watchplugininterface.h +++ b/libsowatch/watchplugininterface.h @@ -2,7 +2,7 @@ #define SOWATCH_WATCHPLUGININTERFACE_H #include <QtPlugin> -#include <QtCore/QSettings> +#include <QtCore/QVariantMap> #include <QtCore/QStringList> #include "sowatch_global.h" @@ -10,6 +10,8 @@ namespace sowatch { class Watch; +class WatchScanner; +class ConfigKey; class SOWATCH_EXPORT WatchPluginInterface { @@ -17,7 +19,8 @@ public: virtual ~WatchPluginInterface(); virtual QStringList drivers() = 0; - virtual Watch* getWatch(const QString& driver, QSettings& settings, QObject *parent = 0) = 0; + virtual WatchScanner* getScanner(QObject *parent = 0) = 0; + virtual Watch* getWatch(const QString& driver, ConfigKey* settings, QObject *parent = 0) = 0; }; } diff --git a/libsowatch/watchscanner.cpp b/libsowatch/watchscanner.cpp new file mode 100644 index 0000000..f744a25 --- /dev/null +++ b/libsowatch/watchscanner.cpp @@ -0,0 +1,12 @@ +#include "watchscanner.h" + +using namespace sowatch; + +WatchScanner::WatchScanner(QObject *parent) : + QObject(parent) +{ +} + +WatchScanner::~WatchScanner() +{ +} diff --git a/libsowatch/watchscanner.h b/libsowatch/watchscanner.h new file mode 100644 index 0000000..c74761e --- /dev/null +++ b/libsowatch/watchscanner.h @@ -0,0 +1,32 @@ +#ifndef SOWATCH_WATCHSCANNER_H +#define SOWATCH_WATCHSCANNER_H + +#include <QtCore/QObject> +#include <QtCore/QVariant> + +namespace sowatch +{ + + +class WatchScanner : public QObject +{ + Q_OBJECT + +protected: + explicit WatchScanner(QObject *parent = 0); + +public: + virtual ~WatchScanner(); + +signals: + void started(); + void finished(); + void watchFound(const QVariantMap& info); + +public slots: + virtual void start() = 0; +}; + +} + +#endif // SOWATCH_WATCHSCANNER_H diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp index da7d282..540eeea 100644 --- a/libsowatch/watchserver.cpp +++ b/libsowatch/watchserver.cpp @@ -56,6 +56,17 @@ void WatchServer::addProvider(NotificationProvider *provider) connect(provider, SIGNAL(incomingNotification(Notification*)), SLOT(postNotification(Notification*))); } +void WatchServer::addWatchlet(Watchlet *watchlet) +{ + // A watchlet is best not reparented; just look that the parent is correct + Q_ASSERT(watchlet->_server == this); + _watchlets.append(watchlet); + QString id = watchlet->id(); + if (!_watchletIds.contains(id)) { + _watchletIds[id] = watchlet; + } +} + QList<Notification*> WatchServer::liveNotifications() { QList<Notification*> notifications; @@ -67,17 +78,24 @@ QList<Notification*> WatchServer::liveNotifications() return notifications; } -void WatchServer::runWatchlet(const QString& id) +void WatchServer::runWatchlet(Watchlet *watchlet) { + Q_ASSERT(watchlet->_server == this); if (_currentWatchlet && _currentWatchletActive) { deactivateCurrentWatchlet(); } - _currentWatchlet = _watchlets[id]; + _currentWatchlet = watchlet; if (_watch->isConnected()) { reactivateCurrentWatchlet(); } } +void WatchServer::runWatchlet(const QString& id) +{ + Q_ASSERT(_watchletIds.contains(id)); + runWatchlet(_watchletIds[id]); +} + void WatchServer::closeWatchlet() { if (_currentWatchlet) { @@ -91,15 +109,6 @@ void WatchServer::closeWatchlet() } } -void WatchServer::registerWatchlet(Watchlet *watchlet) -{ - Q_ASSERT(watchlet->_server == this); - QString id = watchlet->id(); - _watchlets[id] = watchlet; - _watchletIds.append(id); -} - - void WatchServer::deactivateCurrentWatchlet() { Q_ASSERT(_currentWatchlet != 0); @@ -123,11 +132,11 @@ void WatchServer::nextWatchlet() { qDebug() << "current watchlet index" << _currentWatchletIndex; _currentWatchletIndex++; - if (_currentWatchletIndex >= _watchletIds.size() || _currentWatchletIndex < 0) { + if (_currentWatchletIndex >= _watchlets.size() || _currentWatchletIndex < 0) { _currentWatchletIndex = -1; closeWatchlet(); } else { - QString watchlet = _watchletIds.at(_currentWatchletIndex); + Watchlet* watchlet = _watchlets.at(_currentWatchletIndex); runWatchlet(watchlet); } } diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h index d73b56b..3995bc6 100644 --- a/libsowatch/watchserver.h +++ b/libsowatch/watchserver.h @@ -32,6 +32,7 @@ public: QString nextWatchletButton() const; void setNextWatchletButton(const QString& value); + void addWatchlet(Watchlet* watchlet); void addProvider(NotificationProvider* provider); /** Get a list of all current live notifications. */ @@ -41,6 +42,7 @@ public slots: void postNotification(Notification *notification); void nextNotification(); + void runWatchlet(Watchlet* watchlet); void runWatchlet(const QString& id); void closeWatchlet(); void nextWatchlet(); @@ -55,10 +57,10 @@ private: /** The amount of seconds that have to pass for a notification to be considered "outdated" and not shown. */ int _oldNotificationThreshold; - /** A list of watchlets in order, for use by nextWatchlet() */ - QStringList _watchletIds; - /** Actual Watchlet child objects by id. */ - QMap<QString, Watchlet*> _watchlets; + /** A list of watchlets, in order. */ + QList<Watchlet*> _watchlets; + /** Stores all the watchlets with a given watchled id. */ + QMap<QString, Watchlet*> _watchletIds; /** Stores current live notifications, classified by type. */ QList<Notification*> _notifications[Notification::TypeCount]; @@ -79,9 +81,6 @@ private: /** Used for periodic watch time syncing. */ QTimer* _syncTimeTimer; - /** Called by Watchlet constructor to register itself as a child. */ - void registerWatchlet(Watchlet *watchlet); - /** Counts all notifications from a given type. */ uint getNotificationCount(Notification::Type type); @@ -97,8 +96,6 @@ private slots: void notificationChanged(); void notificationDismissed(); - -friend class Watchlet; }; } diff --git a/metawatch/metawatch.cpp b/metawatch/metawatch.cpp index a9718ec..fe080e4 100644 --- a/metawatch/metawatch.cpp +++ b/metawatch/metawatch.cpp @@ -78,8 +78,9 @@ const quint16 MetaWatch::crcTable[256] = { } #endif -MetaWatch::MetaWatch(const QBluetoothAddress& address, QSettings* settings, QObject* parent) : - Watch(parent), +MetaWatch::MetaWatch(ConfigKey* settings, QObject* parent) : + Watch(parent), + _settings(settings->getSubkey(QString(), this)), _idleTimer(new QTimer(this)), _ringTimer(new QTimer(this)), _watchTime(), _watchBattery(0), _watchBatteryAverage(0), _watchCharging(false), _currentMode(IdleMode), _paintMode(IdleMode), @@ -87,14 +88,15 @@ MetaWatch::MetaWatch(const QBluetoothAddress& address, QSettings* settings, QObj _connectRetries(0), _connected(false), _connectTimer(new QTimer(this)), _connectAlignedTimer(new QSystemAlignedTimer(this)), - _address(address), _socket(0), + _socket(0), _sendTimer(new QTimer(this)) { - if (settings) { - _notificationTimeout = settings->value("NotificationTimeout", 15).toInt(); - _24hMode = settings->value("24hMode", false).toBool(); - _dayMonthOrder = settings->value("DayMonthOrder", false).toBool(); - } + connect(_settings, SIGNAL(subkeyChanged(QString)), SLOT(settingChanged(QString))); + + _address = QBluetoothAddress(settings->value("address").toString()); + _notificationTimeout = settings->value("notification-timeout", 15).toInt(); + _24hMode = settings->value("24h-mode", false).toBool(); + _dayMonthOrder = settings->value("day-month-order", false).toBool(); _buttonNames << "A" << "B" << "C" << "D" << "E" << "F"; @@ -656,6 +658,27 @@ void MetaWatch::handleBatteryVoltageMessage(const Message &msg) emit batteryLevelChanged(); } +void MetaWatch::settingChanged(const QString &key) +{ + qDebug() << "Metawatch setting changed:" << key; + + if (key == "address") { + _address = QBluetoothAddress(_settings->value(key).toString()); + } else if (key == "notification-timeout") { + _notificationTimeout = _settings->value(key, 15).toInt(); + } else if (key == "day-month-order") { + _dayMonthOrder = _settings->value(key, false).toBool(); + if (isConnected()) { + nvalWrite(DateFormat, _dayMonthOrder ? 1 : 0); + } + } else if (key == "24h-mode") { + _24hMode = _settings->value(key, false).toBool(); + if (isConnected()) { + nvalWrite(TimeFormat, _24hMode ? 1 : 0); + } + } +} + void MetaWatch::socketConnected() { if (!_connected) { diff --git a/metawatch/metawatch.h b/metawatch/metawatch.h index 5a42b8d..760752b 100644 --- a/metawatch/metawatch.h +++ b/metawatch/metawatch.h @@ -7,7 +7,7 @@ #include <QtConnectivity/QBluetoothAddress> #include <QtConnectivity/QBluetoothSocket> #include <QtSystemInfo/QSystemAlignedTimer> -#include "watch.h" +#include <sowatch.h> using QTM_PREPEND_NAMESPACE(QBluetoothSocket); using QTM_PREPEND_NAMESPACE(QBluetoothAddress); @@ -23,7 +23,7 @@ class MetaWatch : public Watch Q_OBJECT public: - explicit MetaWatch(const QBluetoothAddress& address, QSettings* settings = 0, QObject *parent = 0); + explicit MetaWatch(ConfigKey *settings, QObject *parent = 0); ~MetaWatch(); static const int DelayBetweenMessages = 10; @@ -134,6 +134,8 @@ public: void ungrabButton(Mode mode, Button button); protected: + ConfigKey *_settings; + // Some configurable stuff. short _notificationTimeout; bool _24hMode : 1; @@ -229,6 +231,7 @@ protected: virtual void handleWatchConnected() = 0; private slots: + void settingChanged(const QString& key); void socketConnected(); void socketDisconnected(); void socketData(); diff --git a/metawatch/metawatch.pro b/metawatch/metawatch.pro index 9e99da1..9331665 100644 --- a/metawatch/metawatch.pro +++ b/metawatch/metawatch.pro @@ -17,7 +17,8 @@ SOURCES += metawatchplugin.cpp \ metawatchpaintengine.cpp \ metawatch.cpp \ metawatchdigital.cpp \ - metawatchanalog.cpp + metawatchanalog.cpp \ + metawatchscanner.cpp HEADERS += metawatchplugin.h \ metawatchsimulatorform.h \ @@ -25,7 +26,8 @@ HEADERS += metawatchplugin.h \ metawatchpaintengine.h \ metawatch.h \ metawatchdigital.h \ - metawatchanalog.h + metawatchanalog.h \ + metawatchscanner.h FORMS += \ metawatchsimulatorform.ui @@ -33,34 +35,19 @@ FORMS += \ res_files.files += res/graphics res/fonts qml_files.files += qml/com -win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libsowatch/release/ -lsowatch -else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libsowatch/debug/ -lsowatch -else:symbian: LIBS += -lsowatch -else:unix: LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch +LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch INCLUDEPATH += $$PWD/../libsowatch DEPENDPATH += $$PWD/../libsowatch -symbian { - MMP_RULES += EXPORTUNFROZEN - TARGET.UID3 = 0xE4DC26B0 - TARGET.CAPABILITY = - TARGET.EPOCALLOWDLLDATA = 1 - addFiles.sources = metawatchdriver.dll - addFiles.path = !:/sys/bin - DEPLOYMENT += addFiles -} - -unix:!symbian { - !isEmpty(MEEGO_VERSION_MAJOR)|maemo5 { - QMAKE_RPATHDIR += /opt/sowatch/lib - target.path = /opt/sowatch/lib/drivers - res_files.path = /opt/sowatch/share/metawatch - qml_files.path = /opt/sowatch/qml - } else { - target.path = /usr/lib/sowatch/drivers - res_files.path = /usr/share/sowatch/metawatch - qml_files.path = /usr/share/sowatch/qml - } - INSTALLS += target res_files qml_files +!isEmpty(MEEGO_VERSION_MAJOR)|maemo5 { + QMAKE_RPATHDIR += /opt/sowatch/lib + target.path = /opt/sowatch/lib/drivers + res_files.path = /opt/sowatch/share/metawatch + qml_files.path = /opt/sowatch/qml +} else { + target.path = /usr/lib/sowatch/drivers + res_files.path = /usr/share/sowatch/metawatch + qml_files.path = /usr/share/sowatch/qml } +INSTALLS += target res_files qml_files diff --git a/metawatch/metawatchanalog.cpp b/metawatch/metawatchanalog.cpp index 60993d4..5d35266 100644 --- a/metawatch/metawatchanalog.cpp +++ b/metawatch/metawatchanalog.cpp @@ -6,8 +6,8 @@ using namespace sowatch; // TODO : Figure out how the OLED screen protocol works, including scrolling // TODO : Idle and Notification screens for the Analog Metawatch -MetaWatchAnalog::MetaWatchAnalog(const QBluetoothAddress& address, QSettings* settings, QObject *parent) : - MetaWatch(address, settings, parent) +MetaWatchAnalog::MetaWatchAnalog(ConfigKey* settings, QObject *parent) : + MetaWatch(settings, parent) { } diff --git a/metawatch/metawatchanalog.h b/metawatch/metawatchanalog.h index ff941c5..a0a4db2 100644 --- a/metawatch/metawatchanalog.h +++ b/metawatch/metawatchanalog.h @@ -10,7 +10,7 @@ class MetaWatchAnalog : public MetaWatch { Q_OBJECT public: - explicit MetaWatchAnalog(const QBluetoothAddress& address, QSettings* settings = 0, QObject *parent = 0); + explicit MetaWatchAnalog(ConfigKey *settings, QObject *parent = 0); static const int screenWidth = 80; static const int screenHeight = 16*2; diff --git a/metawatch/metawatchdigital.cpp b/metawatch/metawatchdigital.cpp index befdaea..3029613 100644 --- a/metawatch/metawatchdigital.cpp +++ b/metawatch/metawatchdigital.cpp @@ -2,8 +2,8 @@ using namespace sowatch; -MetaWatchDigital::MetaWatchDigital(const QBluetoothAddress& address, QSettings* settings, QObject *parent) : - MetaWatch(address, settings, parent), +MetaWatchDigital::MetaWatchDigital(ConfigKey* settings, QObject *parent) : + MetaWatch(settings, parent), _nMails(0), _nCalls(0), _nIms(0), _nSms(0), _nMms(0), _wForecast(WeatherNotification::UnknownWeather) { diff --git a/metawatch/metawatchdigital.h b/metawatch/metawatchdigital.h index 7ce195b..4fd6ae6 100644 --- a/metawatch/metawatchdigital.h +++ b/metawatch/metawatchdigital.h @@ -10,7 +10,7 @@ class MetaWatchDigital : public MetaWatch { Q_OBJECT public: - explicit MetaWatchDigital(const QBluetoothAddress& address, QSettings* settings = 0, QObject *parent = 0); + explicit MetaWatchDigital(ConfigKey *settings, QObject *parent = 0); static const int screenWidth = 96; static const int screenHeight = 96; diff --git a/metawatch/metawatchplugin.cpp b/metawatch/metawatchplugin.cpp index 523230b..72713ec 100644 --- a/metawatch/metawatchplugin.cpp +++ b/metawatch/metawatchplugin.cpp @@ -3,6 +3,7 @@ #include "metawatchdigital.h" #include "metawatchanalog.h" #include "metawatchsimulator.h" +#include "metawatchscanner.h" #include "metawatchplugin.h" using namespace sowatch; @@ -33,14 +34,17 @@ QStringList MetaWatchPlugin::drivers() return d; } -Watch* MetaWatchPlugin::getWatch(const QString& driver, QSettings& settings, QObject *parent) +WatchScanner* MetaWatchPlugin::getScanner(QObject *parent) +{ + return new MetaWatchScanner(parent); +} + +Watch* MetaWatchPlugin::getWatch(const QString& driver, ConfigKey* settings, QObject *parent) { if (driver == "metawatch-digital") { - QBluetoothAddress address(settings.value("address").toString()); - return new MetaWatchDigital(address, &settings, parent); + return new MetaWatchDigital(settings, parent); } else if (driver == "metawatch-analog") { - QBluetoothAddress address(settings.value("address").toString()); - return new MetaWatchAnalog(address, &settings, parent); + return new MetaWatchAnalog(settings, parent); } else { return 0; } diff --git a/metawatch/metawatchplugin.h b/metawatch/metawatchplugin.h index 4ea0e5f..964aa04 100644 --- a/metawatch/metawatchplugin.h +++ b/metawatch/metawatchplugin.h @@ -15,7 +15,8 @@ public: ~MetaWatchPlugin(); virtual QStringList drivers(); - virtual Watch* getWatch(const QString& driver, QSettings& settings, QObject* parent = 0); + virtual WatchScanner* getScanner(QObject *parent); + virtual Watch* getWatch(const QString& driver, ConfigKey *settings, QObject *parent); private: static bool fontsLoaded; diff --git a/metawatch/metawatchscanner.cpp b/metawatch/metawatchscanner.cpp new file mode 100644 index 0000000..418500c --- /dev/null +++ b/metawatch/metawatchscanner.cpp @@ -0,0 +1,48 @@ +#include <QtConnectivity/QBluetoothDeviceInfo> +#include <QtConnectivity/QBluetoothAddress> + +#include "metawatchscanner.h" + +QTM_USE_NAMESPACE +using namespace sowatch; + +MetaWatchScanner::MetaWatchScanner(QObject *parent) : + WatchScanner(parent), + _agent(new QBluetoothServiceDiscoveryAgent(this)) +{ + _agent->setUuidFilter(QBluetoothUuid::SerialPort); + connect(_agent, SIGNAL(finished()), this, SIGNAL(finished())); + connect(_agent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), + this, SLOT(handleDiscoveredService(QBluetoothServiceInfo))); +} + +void MetaWatchScanner::start() +{ + if (_agent->isActive()) { + _agent->stop(); + } + _agent->start(); + qDebug() << "started metawatch bluetooth scan"; + emit started(); +} + +void MetaWatchScanner::handleDiscoveredService(const QBluetoothServiceInfo &info) +{ + const QBluetoothDeviceInfo dev = info.device(); + QString deviceName = dev.name(); + if (deviceName.contains("MetaWatch", Qt::CaseInsensitive)) { + QVariantMap foundInfo; + foundInfo["address"] = dev.address().toString(); + foundInfo["name"] = deviceName; + qDebug() << "metawatch bluetooth scan found" << deviceName; + if (deviceName.contains("Digital", Qt::CaseInsensitive)) { + foundInfo["driver"] = QString("metawatch-digital"); + emit watchFound(foundInfo); + } else if (deviceName.contains("Analog", Qt::CaseInsensitive)) { + foundInfo["driver"] = QString("metawatch-analog"); + emit watchFound(foundInfo); + } else { + qWarning() << "Unknown MetaWatch device found:" << deviceName; + } + } +} diff --git a/metawatch/metawatchscanner.h b/metawatch/metawatchscanner.h new file mode 100644 index 0000000..c98bf1a --- /dev/null +++ b/metawatch/metawatchscanner.h @@ -0,0 +1,30 @@ +#ifndef METAWATCHSCANNER_H +#define METAWATCHSCANNER_H + +#include <sowatch.h> +#include <QtConnectivity/QBluetoothServiceDiscoveryAgent> + +using QTM_PREPEND_NAMESPACE(QBluetoothServiceDiscoveryAgent); +using QTM_PREPEND_NAMESPACE(QBluetoothServiceInfo); + +namespace sowatch +{ + +class MetaWatchScanner : public WatchScanner +{ + Q_OBJECT +public: + explicit MetaWatchScanner(QObject *parent = 0); + + void start(); + +private: + QBluetoothServiceDiscoveryAgent *_agent; + +private slots: + void handleDiscoveredService(const QBluetoothServiceInfo& info); +}; + +} + +#endif // METAWATCHSCANNER_H diff --git a/notificationswatchlet/notificationswatchletplugin.cpp b/notificationswatchlet/notificationswatchletplugin.cpp index a3ebbd7..5f4875f 100644 --- a/notificationswatchlet/notificationswatchletplugin.cpp +++ b/notificationswatchlet/notificationswatchletplugin.cpp @@ -19,7 +19,7 @@ QStringList NotificationsWatchletPlugin::watchlets() return l; } -Watchlet* NotificationsWatchletPlugin::getWatchlet(const QString& driver, QSettings& settings, WatchServer *server) +Watchlet* NotificationsWatchletPlugin::getWatchlet(const QString& driver, ConfigKey *settings, WatchServer *server) { Q_UNUSED(driver); Q_UNUSED(settings); diff --git a/notificationswatchlet/notificationswatchletplugin.h b/notificationswatchlet/notificationswatchletplugin.h index e417aea..bc305fc 100644 --- a/notificationswatchlet/notificationswatchletplugin.h +++ b/notificationswatchlet/notificationswatchletplugin.h @@ -16,7 +16,7 @@ public: ~NotificationsWatchletPlugin(); QStringList watchlets(); - Watchlet* getWatchlet(const QString& driver, QSettings& settings, WatchServer* server); + Watchlet* getWatchlet(const QString& driver, ConfigKey *settings, WatchServer* server); }; } diff --git a/sowatch.pro b/sowatch.pro index ee778d0..9a89759 100644 --- a/sowatch.pro +++ b/sowatch.pro @@ -1,23 +1,29 @@ TEMPLATE = subdirs SUBDIRS = libsowatch -SUBDIRS += sowatchd +# The MetaWatch driver plugin SUBDIRS += metawatch -SUBDIRS += sowatchui -SUBDIRS += notificationswatchlet sysinfowatchlet -SUBDIRS += qmsgwatchlet qmapwatchlet - -sowatchd.depends = libsowatch metawatch.depends = libsowatch -sowatchui.depends = libsowatch sowatchd + +# Some watchlets +SUBDIRS += notificationswatchlet sysinfowatchlet +#SUBDIRS += qmsgwatchlet qmapwatchlet notificationswatchlet.depends = libsowatch sysinfowatchlet.depends = libsowatch qmsgwatchlet.depends = libsowatch qmapwatchlet.depends = libsowatch +unix { + SUBDIRS += sowatchd + SUBDIRS += sowatchui + + sowatchd.depends = libsowatch + sowatchui.depends = libsowatch sowatchd +} + contains(MEEGO_EDITION,harmattan) { - SUBDIRS += meegohandsetnotification ckitcallnotification harmaccuweather - SUBDIRS += qmafwwatchlet +# SUBDIRS += meegohandsetnotification ckitcallnotification harmaccuweather +# SUBDIRS += qmafwwatchlet meegohandsetnotification.depends = libsowatch ckitcallnotification.depends = libsowatch diff --git a/sowatchd/allscanner.cpp b/sowatchd/allscanner.cpp new file mode 100644 index 0000000..a3e7d33 --- /dev/null +++ b/sowatchd/allscanner.cpp @@ -0,0 +1,40 @@ +#include "allscanner.h" + +using namespace sowatch; + +AllScanner::AllScanner(QObject *parent) : + WatchScanner(parent), _finishedCount(0) +{ + QList<WatchPluginInterface*> plugins = Registry::registry()->getWatchPlugins(); + foreach (WatchPluginInterface* driver, plugins) { + WatchScanner* scanner = driver->getScanner(this); + if (scanner) { + _scanners += scanner; + connect(scanner, SIGNAL(finished()), this, SLOT(handleFinished())); + connect(scanner, SIGNAL(watchFound(QVariantMap)), + this, SIGNAL(watchFound(QVariantMap))); + } + } +} + +void AllScanner::start() +{ + if (_scanners.empty()) { + emit finished(); + } else { + foreach (WatchScanner* scanner, _scanners) { + scanner->start(); + } + emit started(); + } +} + +void AllScanner::handleFinished() +{ + qDebug() << "one finished"; + _finishedCount++; + if (_finishedCount >= _scanners.length()) { + qDebug() << "all finished"; + emit finished(); + } +} diff --git a/sowatchd/allscanner.h b/sowatchd/allscanner.h new file mode 100644 index 0000000..6a7160f --- /dev/null +++ b/sowatchd/allscanner.h @@ -0,0 +1,29 @@ +#ifndef ALLSCANNER_H +#define ALLSCANNER_H + +#include <QtCore/QObject> +#include <QtCore/QList> + +#include <sowatch.h> + +namespace sowatch +{ + +class AllScanner : public WatchScanner +{ + Q_OBJECT +public: + explicit AllScanner(QObject *parent = 0); + void start(); + +private: + QList<WatchScanner*> _scanners; + int _finishedCount; + +private slots: + void handleFinished(); +}; + +} + +#endif // ALLSCANNER_H diff --git a/sowatchd/com.javispedro.sowatch.service.sowatch-service.service b/sowatchd/com.javispedro.sowatch.service.sowatch-service.service deleted file mode 100644 index 714d1c4..0000000 --- a/sowatchd/com.javispedro.sowatch.service.sowatch-service.service +++ /dev/null @@ -1,3 +0,0 @@ -[D-BUS Service] -Name=com.nokia.qtmobility.sfw.sowatch-service -Exec=/opt/sowatch/bin/sowatchd diff --git a/sowatchd/daemon.cpp b/sowatchd/daemon.cpp index 3cbfb64..61144de 100644 --- a/sowatchd/daemon.cpp +++ b/sowatchd/daemon.cpp @@ -6,74 +6,123 @@ using namespace sowatch; Daemon::Daemon(QObject *parent) : QObject(parent), - _registry(Registry::registry()) + _registry(Registry::registry()), + _settings(new GConfKey("/apps/sowatch", this)) { - initWatches(); + connect(_settings, SIGNAL(subkeyChanged(QString)), SLOT(settingsChanged(QString))); + QStringList activeWatches = _settings->value("active-watches").toStringList(); + foreach (const QString& s, activeWatches) { + startWatch(s); + } } -void Daemon::initWatches() +QString Daemon::getWatchStatus(const QString &name) { - QSettings settings; - int size = settings.beginReadArray("watches"); - - for (int i = 0; i < size; i++) { - settings.setArrayIndex(i); - QString driver = settings.value("driver").toString().toLower(); - WatchPluginInterface *plugin = _registry->getWatchPlugin(driver); - if (plugin) { - Watch *watch = plugin->getWatch(driver, settings, this); - if (watch) { - initWatch(watch, settings); - } else { - qWarning() << "Driver" << driver << "refused to getWatch"; - } + if (_servers.contains(name)) { + WatchServer* server = _servers[name]; + Watch* watch = server->watch(); + if (watch->isConnected()) { + return QLatin1String("connected"); } else { - qWarning() << "Invalid driver" << driver; + return QLatin1String("enabled"); } + } else { + return QLatin1String("disabled"); } +} - settings.endArray(); - qDebug() << "handling" << _servers.size() << "watches"; +void Daemon::terminate() +{ + QApplication::quit(); } -void Daemon::initWatch(Watch* watch, QSettings& settings) +void Daemon::startWatch(const QString &name) { - int size; + qDebug() << "Starting watch" << name; + QScopedPointer<ConfigKey> watchSettings(_settings->getSubkey(name)); + + const QString driver = watchSettings->value("driver").toString().toLower(); + if (driver.isEmpty()) { + qWarning() << "Watch" << name << "has no driver setting"; + return; + } + + WatchPluginInterface *watchPlugin = _registry->getWatchPlugin(driver); + if (!watchPlugin) { + qWarning() << "Invalid driver" << driver; + return; + } + + // Create the watch object from the plugin + Watch *watch = watchPlugin->getWatch(driver, watchSettings.data(), this); + if (!watch) { + qWarning() << "Driver" << driver << "failed to initiate watch"; + } // Create the server WatchServer* server = new WatchServer(watch, this); - _servers.append(server); + _servers[name] = server; // Configure the server - server->setNextWatchletButton(settings.value("nextWatchletButton").toString()); + server->setNextWatchletButton(watchSettings->value("next-watchlet-button").toString()); // Initialize providers - size = settings.beginReadArray("notifications"); - for (int i = 0; i < size; i++) { - settings.setArrayIndex(i); - QString id = settings.value("provider").toString().toLower(); + QStringList list; + list = watchSettings->value("active-notifications").toStringList(); + foreach (const QString& s, list) { + QScopedPointer<ConfigKey> settings(watchSettings->getSubkey(s)); + QString id = settings->value("id").toString().toLower(); NotificationPluginInterface *plugin = _registry->getNotificationPlugin(id); if (plugin) { - NotificationProvider *provider = plugin->getProvider(id, settings, server); + NotificationProvider *provider = plugin->getProvider(id, settings.data(), server); server->addProvider(provider); } else { qWarning() << "Unknown notification provider" << id; } } - settings.endArray(); // Initialize watchlets - size = settings.beginReadArray("watchlets"); - for (int i = 0; i < size; i++) { - settings.setArrayIndex(i); - QString id = settings.value("id").toString().toLower(); + list = watchSettings->value("active-watchlets").toStringList(); + foreach (const QString& s, list) { + QScopedPointer<ConfigKey> settings(watchSettings->getSubkey(s)); + QString id = settings->value("id").toString().toLower(); WatchletPluginInterface *plugin = _registry->getWatchletPlugin(id); if (plugin) { - plugin->getWatchlet(id, settings, server); - // Watchlets are associated to server via parent-child relationship. + Watchlet *watchlet = plugin->getWatchlet(id, settings.data(), server); + server->addWatchlet(watchlet); } else { qWarning() << "Unknown watchlet" << id; } } - settings.endArray(); +} + +void Daemon::stopWatch(const QString &name) +{ + qDebug() << "Stopping watch" << name; +} + +#if TODO +void Daemon::initWatch(Watch* watch, QSettings& settings) +{ + int size; + + +} +#endif + +void Daemon::settingsChanged(const QString &subkey) +{ + qDebug() << "Daemon settings changed" << subkey; + if (subkey == "active-watches") { + QSet<QString> confActiveWatches = _settings->value("active-watches").toStringList().toSet(); + QSet<QString> curActiveWatches = _servers.keys().toSet(); + QSet<QString> removed = curActiveWatches - confActiveWatches; + QSet<QString> added = confActiveWatches - curActiveWatches; + foreach (const QString& s, removed) { + stopWatch(s); + } + foreach (const QString& s, added) { + startWatch(s); + } + } } diff --git a/sowatchd/daemon.h b/sowatchd/daemon.h index 249f525..ba62585 100644 --- a/sowatchd/daemon.h +++ b/sowatchd/daemon.h @@ -2,9 +2,7 @@ #define WATCHDAEMON_H #include <QtCore/QObject> -#include <QtCore/QList> #include <QtCore/QMap> -#include <QtCore/QSettings> #include <sowatch.h> @@ -17,12 +15,21 @@ class Daemon : public QObject public: explicit Daemon(QObject *parent = 0); -protected: + Q_INVOKABLE QString getWatchStatus(const QString& name); + +public slots: + void terminate(); + +private: Registry* _registry; - QList<WatchServer*> _servers; + ConfigKey* _settings; + QMap<QString, WatchServer*> _servers; + + void startWatch(const QString& name); + void stopWatch(const QString& name); - void initWatches(); - void initWatch(Watch* watch, QSettings& settings); +private slots: + void settingsChanged(const QString& subkey); }; } diff --git a/sowatchd/daemon.xml b/sowatchd/daemon.xml new file mode 100644 index 0000000..0a08913 --- /dev/null +++ b/sowatchd/daemon.xml @@ -0,0 +1,10 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="com.javispedro.sowatch.Daemon"> + <method name="GetWatchStatus"> + <arg name="watch" type="s" direction="in" /> + <arg name="status" type="s" direction="out" /> + </method> + <method name="Terminate" /> + </interface> +</node> diff --git a/sowatchd/daemonadaptor.cpp b/sowatchd/daemonadaptor.cpp new file mode 100644 index 0000000..c8a322a --- /dev/null +++ b/sowatchd/daemonadaptor.cpp @@ -0,0 +1,49 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c DaemonAdaptor -a daemonadaptor daemon.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. + */ + +#include "daemonadaptor.h" +#include <QtCore/QMetaObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> + +/* + * Implementation of adaptor class DaemonAdaptor + */ + +DaemonAdaptor::DaemonAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +DaemonAdaptor::~DaemonAdaptor() +{ + // destructor +} + +QString DaemonAdaptor::GetWatchStatus(const QString &watch) +{ + // handle method call com.javispedro.sowatch.Daemon.GetWatchStatus + QString status; + QMetaObject::invokeMethod(parent(), "getWatchStatus", Q_RETURN_ARG(QString, status), Q_ARG(QString, watch)); + return status; +} + +void DaemonAdaptor::Terminate() +{ + // handle method call com.javispedro.sowatch.Daemon.Terminate + QMetaObject::invokeMethod(parent(), "terminate"); +} + diff --git a/sowatchd/daemonadaptor.h b/sowatchd/daemonadaptor.h new file mode 100644 index 0000000..d16cb99 --- /dev/null +++ b/sowatchd/daemonadaptor.h @@ -0,0 +1,51 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c DaemonAdaptor -a daemonadaptor daemon.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. + */ + +#ifndef DAEMONADAPTOR_H_1335395583 +#define DAEMONADAPTOR_H_1335395583 + +#include <QtCore/QObject> +#include <QtDBus/QtDBus> +class QByteArray; +template<class T> class QList; +template<class Key, class Value> class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface com.javispedro.sowatch.Daemon + */ +class DaemonAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.javispedro.sowatch.Daemon") + Q_CLASSINFO("D-Bus Introspection", "" +" <interface name=\"com.javispedro.sowatch.Daemon\">\n" +" <method name=\"GetWatchStatus\">\n" +" <arg direction=\"in\" type=\"s\" name=\"watch\"/>\n" +" <arg direction=\"out\" type=\"s\" name=\"status\"/>\n" +" </method>\n" +" <method name=\"Terminate\"/>\n" +" </interface>\n" + "") +public: + DaemonAdaptor(QObject *parent); + virtual ~DaemonAdaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + QString GetWatchStatus(const QString &watch); + void Terminate(); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/sowatchd/main.cpp b/sowatchd/main.cpp index 22e63a2..29eee28 100644 --- a/sowatchd/main.cpp +++ b/sowatchd/main.cpp @@ -1,10 +1,12 @@ +#include <QtCore/QDebug> #include <QtGui/QApplication> -#include <QtServiceFramework/QServiceManager> -#include <QtServiceFramework/QRemoteServiceRegister> +#include <QtDBus/QDBusConnection> #include <sowatch.h> #include "global.h" -#include "service.h" +#include "allscanner.h" +#include "daemonadaptor.h" +#include "scanneradaptor.h" namespace sowatch { @@ -12,68 +14,32 @@ namespace sowatch } using namespace sowatch; -QTM_USE_NAMESPACE - - -static QString adjustPath(const QString &path) -{ -#ifdef Q_OS_UNIX -#ifdef Q_OS_MAC - if (!QDir::isAbsolutePath(path)) - return QCoreApplication::applicationDirPath() - + QLatin1String("/../Resources/") + path; -#else - QString pathInInstallDir; - const QString applicationDirPath = QCoreApplication::applicationDirPath(); - pathInInstallDir = QString::fromAscii("%1/../%2").arg(applicationDirPath, path); - - if (QFileInfo(pathInInstallDir).exists()) - return pathInInstallDir; -#endif -#endif - return path; -} - -static void unregisterService() -{ - QServiceManager m; - m.removeService("sowatch-service"); -} - -static void registerService() -{ - unregisterService(); - QServiceManager m; - QString path = adjustPath("xml/service.xml"); - if (!m.addService(path)) { - qWarning() << "Cannot register sowatch-service" << m.error() << "from" << path; - } -} int main(int argc, char *argv[]) { - QApplication a(argc, argv); // Some plugins might require a UI. + // Some plugins might require a user interface, so use QApplication instead + // of QCoreApplication + QApplication a(argc, argv); QApplication::setOrganizationDomain("com.javispedro.sowatch"); QApplication::setOrganizationName("sowatch"); QApplication::setApplicationName("sowatchd"); - sowatch::daemon = new Daemon(); - - registerService(); - - QRemoteServiceRegister *serviceRegister = new QRemoteServiceRegister(); - QRemoteServiceRegister::Entry entry = - serviceRegister->createEntry<Service>("sowatch-service", - "com.javispedro.sowatch.service", "1.0"); - entry.setInstantiationType(QRemoteServiceRegister::PrivateInstance); + sowatch::daemon = new Daemon(&a); + new DaemonAdaptor(sowatch::daemon); + AllScanner *scanner = new AllScanner(&a); + new ScannerAdaptor(scanner); - serviceRegister->setQuitOnLastInstanceClosed(false); - serviceRegister->publishEntries("sowatchd"); - - int res = a.exec(); + QDBusConnection connection = QDBusConnection::sessionBus(); + if (!connection.registerService("com.javispedro.sowatchd")) { + qCritical("Could not register D-Bus service"); + } - delete serviceRegister; - delete sowatch::daemon; + if (!connection.registerObject("/com/javispedro/sowatch/allscanner", scanner)) { + qCritical("Could not register scanner object"); + } + if (!connection.registerObject("/com/javispedro/sowatch/daemon", sowatch::daemon)) { + qCritical("Could not register daemon object"); + } - return res; + return a.exec(); } diff --git a/sowatchd/scanner.xml b/sowatchd/scanner.xml new file mode 100644 index 0000000..948ce0b --- /dev/null +++ b/sowatchd/scanner.xml @@ -0,0 +1,12 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="com.javispedro.sowatch.WatchScanner"> + <method name="Start" /> + <signal name="Started" /> + <signal name="Finished" /> + <signal name="WatchFound"> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantMap" /> + <arg name="info" type="a{sv}" /> + </signal> + </interface> +</node> diff --git a/sowatchd/scanneradaptor.cpp b/sowatchd/scanneradaptor.cpp new file mode 100644 index 0000000..a3d9ad1 --- /dev/null +++ b/sowatchd/scanneradaptor.cpp @@ -0,0 +1,43 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c ScannerAdaptor -a scanneradaptor 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. + */ + +#include "scanneradaptor.h" +#include <QtCore/QMetaObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> + +/* + * Implementation of adaptor class ScannerAdaptor + */ + +ScannerAdaptor::ScannerAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + connect(parent, SIGNAL(started()), this, SIGNAL(Started())); + connect(parent, SIGNAL(finished()), this, SIGNAL(Finished())); + connect(parent, SIGNAL(watchFound(QVariantMap)), + this, SIGNAL(WatchFound(QVariantMap))); +} + +ScannerAdaptor::~ScannerAdaptor() +{ + // destructor +} + +void ScannerAdaptor::Start() +{ + // handle method call com.javispedro.sowatch.WatchScanner.Start + QMetaObject::invokeMethod(parent(), "start"); +} diff --git a/sowatchd/scanneradaptor.h b/sowatchd/scanneradaptor.h new file mode 100644 index 0000000..17ffe54 --- /dev/null +++ b/sowatchd/scanneradaptor.h @@ -0,0 +1,55 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c ScannerAdaptor -a scanneradaptor 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. + */ + +#ifndef SCANNERADAPTOR_H_1335303169 +#define SCANNERADAPTOR_H_1335303169 + +#include <QtCore/QObject> +#include <QtDBus/QtDBus> +class QByteArray; +template<class T> class QList; +template<class Key, class Value> class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface com.javispedro.sowatch.WatchScanner + */ +class ScannerAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.javispedro.sowatch.WatchScanner") + Q_CLASSINFO("D-Bus Introspection", "" +" <interface name=\"com.javispedro.sowatch.WatchScanner\">\n" +" <method name=\"Start\"/>\n" +" <signal name=\"Started\"/>\n" +" <signal name=\"Finished\"/>\n" +" <signal name=\"WatchFound\">\n" +" <annotation value=\"QVariantMap\" name=\"com.trolltech.QtDBus.QtTypeName.In0\"/>\n" +" <arg type=\"a{sv}\" name=\"info\"/>\n" +" </signal>\n" +" </interface>\n" + "") +public: + ScannerAdaptor(QObject *parent); + virtual ~ScannerAdaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Start(); +Q_SIGNALS: // SIGNALS + void Finished(); + void Started(); + void WatchFound(const QVariantMap &info); +}; + +#endif diff --git a/sowatchd/service.cpp b/sowatchd/service.cpp deleted file mode 100644 index 0b3777c..0000000 --- a/sowatchd/service.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "global.h" -#include "service.h" - -using namespace sowatch; - -Service::Service(QObject *parent) : - QObject(parent) -{ - -} - -void Service::terminate() -{ - QCoreApplication::exit(0); -} diff --git a/sowatchd/service.h b/sowatchd/service.h deleted file mode 100644 index 797dc3d..0000000 --- a/sowatchd/service.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SERVICE_H -#define SERVICE_H - -#include <QtCore/QObject> -#include <QtCore/QList> -#include <QtCore/QSettings> - -#include <sowatch.h> - -namespace sowatch -{ - -class Service : public QObject -{ - Q_OBJECT -public: - explicit Service(QObject *parent = 0); - -public slots: - void terminate(); - -}; - -} - -#endif // SERVICE_H diff --git a/sowatchd/service.xml b/sowatchd/service.xml deleted file mode 100644 index b2ebc06..0000000 --- a/sowatchd/service.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<SFW version="1.1"> -<service> - <name>sowatch-service</name> - <ipcaddress>sowatchd</ipcaddress> - <description>Sowatch Service</description> - <interface> - <name>com.javispedro.sowatch.service</name> - <version>1.0</version> - <description></description> - <capabilities></capabilities> - </interface> -</service> -</SFW> diff --git a/sowatchd/sowatchd.pro b/sowatchd/sowatchd.pro index 5c195c6..0794c2c 100644 --- a/sowatchd/sowatchd.pro +++ b/sowatchd/sowatchd.pro @@ -1,45 +1,33 @@ -TEMPLATE = app - TARGET = sowatchd -QT += core gui -CONFIG -= app_bundle - -# Qt Mobility 1.2 -maemo5 { - CONFIG += mobility12 -} else { - CONFIG += mobility -} -MOBILITY += serviceframework - -SOURCES += main.cpp daemon.cpp service.cpp +TEMPLATE = app -HEADERS += global.h daemon.h service.h +QT += core gui dbus +CONFIG -= app_bundle -win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libsowatch/release/ -lsowatch -else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libsowatch/debug/ -lsowatch -else:symbian: LIBS += -lsowatch -else:unix: LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch +SOURCES += main.cpp daemon.cpp allscanner.cpp scanneradaptor.cpp daemonadaptor.cpp +HEADERS += global.h daemon.h allscanner.h scanneradaptor.h daemonadaptor.h +LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch INCLUDEPATH += $$PWD/../libsowatch DEPENDPATH += $$PWD/../libsowatch xml.files = service.xml INSTALLS += xml -unix { - !isEmpty(MEEGO_VERSION_MAJOR)|maemo5 { - QMAKE_RPATHDIR += /opt/sowatch/lib - target.path = /opt/sowatch/bin - xml.path = /opt/sowatch/xml - } else { - target.path = /usr/bin - xml.path = /usr/share/sowatch/xml - } - INSTALLS += target - - dbus.path = /usr/share/dbus-1/services - dbus.files = com.javispedro.sowatch.service.sowatch-service.service - INSTALLS += dbus +!isEmpty(MEEGO_VERSION_MAJOR)|maemo5 { + QMAKE_RPATHDIR += /opt/sowatch/lib + target.path = /opt/sowatch/bin + xml.path = /opt/sowatch/xml +} else { + target.path = /usr/bin + xml.path = /usr/share/sowatch/xml } +INSTALLS += target + +dbus.path = /usr/share/dbus-1/services +dbus.files = com.javispedro.sowatch.service.sowatch-service.service +INSTALLS += dbus + +OTHER_FILES += scanner.xml \ + daemon.xml diff --git a/sowatchui/qml/MainPage.qml b/sowatchui/qml/MainPage.qml index 45b72f3..a7ba7d7 100644 --- a/sowatchui/qml/MainPage.qml +++ b/sowatchui/qml/MainPage.qml @@ -1,9 +1,67 @@ import QtQuick 1.1 import com.nokia.meego 1.0 -import "sowatch.js" as Sowatch - Page { + id: mainPage tools: commonTools + ListModel { + id: testModel + ListElement { + name: "one" + } + ListElement { + name: "two" + } + } + + Flickable { + anchors.fill: parent + contentWidth: mainPage.width + contentHeight: mainColumn.height + 100 + + Column { + id: mainColumn + + width: mainPage.width + height: childrenRect.height + spacing: 8 + + 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() + } + } + } } diff --git a/sowatchui/qml/ServiceLoader.qml b/sowatchui/qml/ServiceLoader.qml deleted file mode 100644 index 8128ca7..0000000 --- a/sowatchui/qml/ServiceLoader.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 1.1 -import QtMobility.serviceframework 1.1 - -Service { - id: sowatch - interfaceName: "com.javispedro.sowatch.service" -} diff --git a/sowatchui/qml/main.qml b/sowatchui/qml/main.qml index 8697b6d..eb4c081 100644 --- a/sowatchui/qml/main.qml +++ b/sowatchui/qml/main.qml @@ -1,8 +1,6 @@ import QtQuick 1.1 import com.nokia.meego 1.0 -import "sowatch.js" as Sowatch - PageStackWindow { id: appWindow @@ -18,7 +16,7 @@ PageStackWindow { ToolIcon { platformIconId: "toolbar-view-menu" anchors.right: (parent === undefined) ? undefined : parent.right - onClicked: (myMenu.status == DialogStatus.Closed) ? myMenu.open() : myMenu.close() + onClicked: (myMenu.status === DialogStatus.Closed) ? myMenu.open() : myMenu.close() } } diff --git a/sowatchui/qml/sowatch.js b/sowatchui/qml/sowatch.js deleted file mode 100644 index f2d48dd..0000000 --- a/sowatchui/qml/sowatch.js +++ /dev/null @@ -1,29 +0,0 @@ -var service = null; - -function getService() { - var component = Qt.createComponent("ServiceLoader.qml"); - if (component.status == Component.Ready) { - var loader = component.createObject(null); - service = loader.serviceObject; - } -} - -function checkService() { - if (service === null) { - getService(); - } -} - -function start() { - getService(); -} - -function stop() { - checkService(); - service.terminate(); -} - -function restart() { - stop(); - start(); -} diff --git a/sowatchui/sowatchui.pro b/sowatchui/sowatchui.pro index 2265ad6..c73875c 100644 --- a/sowatchui/sowatchui.pro +++ b/sowatchui/sowatchui.pro @@ -1,4 +1,6 @@ -TARGET=sowatch +TARGET = sowatch + +QT += dbus # Add more folders to ship with the application, here qml_folder.source = qml @@ -8,38 +10,23 @@ DEPLOYMENTFOLDERS = qml_folder # Additional import path used to resolve QML modules in Creator's code model QML_IMPORT_PATH = -symbian:TARGET.UID3 = 0xE5EBE65C - -# Smart Installer package's UID -# This UID is from the protected range and therefore the package will -# fail to install if self-signed. By default qmake uses the unprotected -# range value if unprotected UID is defined for the application and -# 0x2002CCCF value if protected UID is given to the application -#symbian:DEPLOYMENT.installer_header = 0x2002CCCF - -# Allow network access on Symbian -symbian:TARGET.CAPABILITY += NetworkServices - -# If your application uses the Qt Mobility libraries, uncomment the following -# lines and add the respective components to the MOBILITY variable. -CONFIG += mobility -MOBILITY += serviceframework - # Speed up launching on MeeGo/Harmattan when using applauncherd daemon CONFIG += qdeclarative-boostable -# Add dependency to Symbian components -# CONFIG += qt-components +# Dependency to the main Sowatch library +LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch +INCLUDEPATH += $$PWD/../libsowatch +DEPENDPATH += $$PWD/../libsowatch -# The .cpp file which was generated for your project. Feel free to hack it. +# Source files SOURCES += main.cpp -# Please do not modify the following two lines. Required for deployment. -include(qmlapplicationviewer/qmlapplicationviewer.pri) -qtcAddDeployment() - OTHER_FILES += \ qml/MainPage.qml \ qml/main.qml \ sowatch_harmattan.desktop \ sowatch.desktop + +# Please do not modify the following two lines. Required for deployment. +include(qmlapplicationviewer/qmlapplicationviewer.pri) +qtcAddDeployment() diff --git a/sysinfowatchlet/sysinfoplugin.cpp b/sysinfowatchlet/sysinfoplugin.cpp index fc862c0..f24b23e 100644 --- a/sysinfowatchlet/sysinfoplugin.cpp +++ b/sysinfowatchlet/sysinfoplugin.cpp @@ -19,7 +19,7 @@ QStringList SysInfoPlugin::watchlets() return l; } -Watchlet* SysInfoPlugin::getWatchlet(const QString& driver, QSettings& settings, WatchServer *server) +Watchlet* SysInfoPlugin::getWatchlet(const QString& driver, ConfigKey *settings, WatchServer *server) { Q_UNUSED(driver); Q_UNUSED(settings); diff --git a/sysinfowatchlet/sysinfoplugin.h b/sysinfowatchlet/sysinfoplugin.h index 4e24b9e..b341614 100644 --- a/sysinfowatchlet/sysinfoplugin.h +++ b/sysinfowatchlet/sysinfoplugin.h @@ -16,7 +16,7 @@ public: ~SysInfoPlugin(); QStringList watchlets(); - Watchlet* getWatchlet(const QString& driver, QSettings& settings, WatchServer* server); + Watchlet* getWatchlet(const QString& driver, ConfigKey *settings, WatchServer* server); }; } |