summaryrefslogtreecommitdiff
path: root/libsowatch
diff options
context:
space:
mode:
Diffstat (limited to 'libsowatch')
-rw-r--r--libsowatch/libsowatch.pro8
-rw-r--r--libsowatch/notification.h1
-rw-r--r--libsowatch/registry.cpp119
-rw-r--r--libsowatch/registry.h50
-rw-r--r--libsowatch/sowatch.h3
-rw-r--r--libsowatch/sowatch_global.h12
-rw-r--r--libsowatch/watch.h4
-rw-r--r--libsowatch/watchserver.cpp29
-rw-r--r--libsowatch/watchserver.h3
-rw-r--r--libsowatch/weathernotification.cpp8
-rw-r--r--libsowatch/weathernotification.h37
11 files changed, 265 insertions, 9 deletions
diff --git a/libsowatch/libsowatch.pro b/libsowatch/libsowatch.pro
index 574e1a4..cb77a17 100644
--- a/libsowatch/libsowatch.pro
+++ b/libsowatch/libsowatch.pro
@@ -23,9 +23,11 @@ SOURCES += \
declarativewatchlet.cpp \
watchplugininterface.cpp \
notification.cpp \
+ weathernotification.cpp \
notificationplugininterface.cpp \
notificationprovider.cpp \
- watchletplugininterface.cpp
+ watchletplugininterface.cpp \
+ registry.cpp
HEADERS +=\
watchsimulator.h \
@@ -40,9 +42,11 @@ HEADERS +=\
sowatch_global.h \
watchplugininterface.h \
notification.h \
+ weathernotification.h \
notificationplugininterface.h \
notificationprovider.h \
- watchletplugininterface.h
+ watchletplugininterface.h \
+ registry.h
install_headers.files = $$HEADERS
diff --git a/libsowatch/notification.h b/libsowatch/notification.h
index 758a8b7..8bae4ff 100644
--- a/libsowatch/notification.h
+++ b/libsowatch/notification.h
@@ -32,6 +32,7 @@ public:
ImNotification,
EmailNotification,
CalendarNotification,
+ WeatherNotification,
TypeCount
};
diff --git a/libsowatch/registry.cpp b/libsowatch/registry.cpp
new file mode 100644
index 0000000..7ade260
--- /dev/null
+++ b/libsowatch/registry.cpp
@@ -0,0 +1,119 @@
+#include <QtCore/QDebug>
+#include <QtCore/QPluginLoader>
+#include <QtCore/QSettings>
+#include <QtCore/QDir>
+
+#include "watchplugininterface.h"
+#include "notificationplugininterface.h"
+#include "watchletplugininterface.h"
+#include "registry.h"
+
+using namespace sowatch;
+
+Registry* Registry::singleRegistry = 0;
+
+Registry* Registry::registry()
+{
+ if (!singleRegistry) {
+ singleRegistry = new Registry();
+ }
+
+ return singleRegistry;
+}
+
+Registry::Registry()
+{
+ loadDrivers();
+ loadNotificationProviders();
+ loadWatchlets();
+}
+
+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();
+ }
+ }
+
+ qDebug() << "loaded drivers" << _drivers.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();
+ }
+ } else {
+ qWarning() << "Invalid plugin" << file << loader.errorString();
+ loader.unload();
+ }
+ }
+
+ qDebug() << "loaded notification providers" << _providers.keys();
+}
+
+void Registry::loadWatchlets()
+{
+ 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();
+ }
+ } else {
+ qWarning() << "Invalid plugin" << file << loader.errorString();
+ loader.unload();
+ }
+ }
+
+ qDebug() << "loaded watchlets" << _watchlets.keys();
+}
diff --git a/libsowatch/registry.h b/libsowatch/registry.h
new file mode 100644
index 0000000..ca7252a
--- /dev/null
+++ b/libsowatch/registry.h
@@ -0,0 +1,50 @@
+#ifndef SOWATCH_REGISTRY_H
+#define SOWATCH_REGISTRY_H
+
+#include <QtCore/QString>
+#include <QtCore/QMap>
+#include "sowatch_global.h"
+
+namespace sowatch
+{
+
+class WatchPluginInterface;
+class NotificationPluginInterface;
+class WatchletPluginInterface;
+
+class SOWATCH_EXPORT Registry
+{
+public:
+ static Registry* registry();
+
+ inline WatchPluginInterface* getWatchPlugin(const QString& id) {
+ return _drivers.value(id, 0);
+ }
+
+ inline NotificationPluginInterface* getNotificationPlugin(const QString& id) {
+ return _providers.value(id, 0);
+ }
+
+ inline WatchletPluginInterface* getWatchletPlugin(const QString& id) {
+ return _watchlets.value(id, 0);
+ }
+
+protected:
+ Registry();
+ ~Registry();
+
+private:
+ static Registry* singleRegistry;
+
+ QMap<QString, WatchPluginInterface*> _drivers;
+ QMap<QString, NotificationPluginInterface*> _providers;
+ QMap<QString, WatchletPluginInterface*> _watchlets;
+
+ void loadDrivers();
+ void loadNotificationProviders();
+ void loadWatchlets();
+};
+
+}
+
+#endif // SOWATCH_REGISTRY_H
diff --git a/libsowatch/sowatch.h b/libsowatch/sowatch.h
index d8844bc..b0aa999 100644
--- a/libsowatch/sowatch.h
+++ b/libsowatch/sowatch.h
@@ -9,6 +9,7 @@
#include "watchplugininterface.h"
#include "notification.h"
+#include "weathernotification.h"
#include "notificationprovider.h"
#include "notificationplugininterface.h"
@@ -17,4 +18,6 @@
#include "declarativewatchlet.h"
#include "watchletplugininterface.h"
+#include "registry.h"
+
#endif // SOWATCH_H
diff --git a/libsowatch/sowatch_global.h b/libsowatch/sowatch_global.h
index 977bd53..1afa590 100644
--- a/libsowatch/sowatch_global.h
+++ b/libsowatch/sowatch_global.h
@@ -10,13 +10,13 @@
#endif
#if defined(Q_WS_MAEMO_5)
-# define SOWATCH_DRIVERS_DIR "/opt/sowatch/drivers"
-# define SOWATCH_NOTIFICATIONS_DIR "/opt/sowatch/notifications"
-# define SOWATCH_WATCHLETS_DIR "/opt/sowatch/watchlets"
+# define SOWATCH_PLUGINS_DIR "/opt/sowatch"
#elif defined(Q_OS_LINUX)
-# define SOWATCH_DRIVERS_DIR "/usr/lib/sowatch/drivers"
-# define SOWATCH_NOTIFICATIONS_DIR "/usr/lib/sowatch/notifications"
-# define SOWATCH_WATCHLETS_DIR "/usr/lib/sowatch/watchlets"
+# define SOWATCH_PLUGINS_DIR "/usr/lib/sowatch"
#endif
+#define SOWATCH_DRIVERS_DIR SOWATCH_PLUGINS_DIR "/drivers"
+#define SOWATCH_NOTIFICATIONS_DIR SOWATCH_PLUGINS_DIR "/notifications"
+#define SOWATCH_WATCHLETS_DIR SOWATCH_PLUGINS_DIR "/watchlets"
+
#endif // SOWATCH_GLOBAL_H
diff --git a/libsowatch/watch.h b/libsowatch/watch.h
index 9147f9a..eb572eb 100644
--- a/libsowatch/watch.h
+++ b/libsowatch/watch.h
@@ -7,6 +7,7 @@
#include <QtGui/QPaintDevice>
#include <QtGui/QImage>
#include "notification.h"
+#include "weathernotification.h"
#include "sowatch_global.h"
namespace sowatch
@@ -62,6 +63,9 @@ public:
/** Tells the watch to update the unread notifications count, if visible. */
virtual void updateNotificationCount(Notification::Type type, int count) = 0;
+ /** Tells the watch to update the current weather forecast, if visible. */
+ virtual void updateWeather(WeatherNotification* weather) = 0;
+
public slots:
/** Go back to the idle screen. */
virtual void displayIdleScreen() = 0;
diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp
index 60c410d..4675809 100644
--- a/libsowatch/watchserver.cpp
+++ b/libsowatch/watchserver.cpp
@@ -5,7 +5,6 @@
#include "watchlet.h"
#include "watchserver.h"
-
using namespace sowatch;
WatchServer::WatchServer(Watch* watch, QObject* parent) :
@@ -204,6 +203,14 @@ void WatchServer::postNotification(Notification *notification)
_watch->updateNotificationCount(type, getNotificationCount(type));
+ if (type == Notification::WeatherNotification) {
+ // Weather notifications, we handle differently.
+ WeatherNotification* weather = static_cast<WeatherNotification*>(notification);
+ _weather = weather;
+ _watch->updateWeather(weather);
+ return; // And do not display it the usual way
+ }
+
QDateTime oldThreshold = QDateTime::currentDateTime().addSecs(-_oldNotificationThreshold);
if (notification->dateTime() < oldThreshold) {
return; // Do not care about notifications that old...
@@ -245,8 +252,22 @@ void WatchServer::notificationChanged()
_watch->updateNotificationCount(type, getNotificationCount(type));
if (!_pendingNotifications.isEmpty() && _pendingNotifications.head() == n) {
+ // This is the notification that is being currently signaled on the watch
+ // Therefore, show it again
nextNotification();
}
+ if (type == Notification::WeatherNotification) {
+ WeatherNotification* w = static_cast<WeatherNotification*>(n);
+ if (!_weather || _weather->dateTime() < w->dateTime()) {
+ // Prefer showing the most recent data
+ _weather = w;
+ }
+ if (_weather == w) {
+ // This is the weather notification we are currently displaying on the watch
+ // Therefore, update the displayed information
+ _watch->updateWeather(w);
+ }
+ }
}
}
@@ -269,5 +290,11 @@ void WatchServer::notificationDismissed()
} else {
_pendingNotifications.removeAll(n);
}
+ if (type == Notification::WeatherNotification) {
+ WeatherNotification* w = static_cast<WeatherNotification*>(n);
+ if (_weather == w) {
+ _weather = 0;
+ }
+ }
}
}
diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h
index a773749..53c1a70 100644
--- a/libsowatch/watchserver.h
+++ b/libsowatch/watchserver.h
@@ -16,6 +16,7 @@ namespace sowatch
class Watch;
class Watchlet;
class NotificationProvider;
+class WeatherNotification;
class SOWATCH_EXPORT WatchServer : public QObject
{
@@ -63,6 +64,8 @@ private:
QList<Notification*> _notifications[Notification::TypeCount];
/** A list of notifications that are yet to be shown to the user. */
QQueue<Notification*> _pendingNotifications;
+ /** We store a currently live weather forecast. */
+ WeatherNotification* _weather;
/** Current watchlet. */
Watchlet* _currentWatchlet;
diff --git a/libsowatch/weathernotification.cpp b/libsowatch/weathernotification.cpp
new file mode 100644
index 0000000..fa82f3d
--- /dev/null
+++ b/libsowatch/weathernotification.cpp
@@ -0,0 +1,8 @@
+#include "weathernotification.h"
+
+using namespace sowatch;
+
+WeatherNotification::WeatherNotification(QObject *parent) :
+ Notification(parent)
+{
+}
diff --git a/libsowatch/weathernotification.h b/libsowatch/weathernotification.h
new file mode 100644
index 0000000..0b511b4
--- /dev/null
+++ b/libsowatch/weathernotification.h
@@ -0,0 +1,37 @@
+#ifndef SOWATCH_WEATHERNOTIFICATION_H
+#define SOWATCH_WEATHERNOTIFICATION_H
+
+#include "notification.h"
+
+namespace sowatch
+{
+
+class WeatherNotification : public Notification
+{
+ Q_OBJECT
+public:
+ explicit WeatherNotification(QObject *parent = 0);
+
+ enum WeatherType {
+ UnknownWeather = 0,
+ Sunny,
+ Cloudy,
+ Rain,
+ Snow,
+ Thunderstorm
+ };
+
+ enum Unit {
+ UnknownUnit = 0,
+ Celsius,
+ Fahrenheit
+ };
+
+ virtual WeatherType forecast() = 0;
+ virtual int temperature() = 0;
+ virtual Unit temperatureUnits() = 0;
+};
+
+}
+
+#endif // WEATHERNOTIFICATION_H