From 4da9bced6a27b92d49b9fc9392946510b8519d82 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Sun, 16 Oct 2011 04:42:30 +0200 Subject: Initial implementation of weather --- libsowatch/libsowatch.pro | 8 ++- libsowatch/notification.h | 1 + libsowatch/registry.cpp | 119 +++++++++++++++++++++++++++++++++++++ libsowatch/registry.h | 50 ++++++++++++++++ libsowatch/sowatch.h | 3 + libsowatch/sowatch_global.h | 12 ++-- libsowatch/watch.h | 4 ++ libsowatch/watchserver.cpp | 29 ++++++++- libsowatch/watchserver.h | 3 + libsowatch/weathernotification.cpp | 8 +++ libsowatch/weathernotification.h | 37 ++++++++++++ 11 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 libsowatch/registry.cpp create mode 100644 libsowatch/registry.h create mode 100644 libsowatch/weathernotification.cpp create mode 100644 libsowatch/weathernotification.h (limited to 'libsowatch') 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 +#include +#include +#include + +#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(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(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(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 +#include +#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 _drivers; + QMap _providers; + QMap _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 #include #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(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(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(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 _notifications[Notification::TypeCount]; /** A list of notifications that are yet to be shown to the user. */ QQueue _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 -- cgit v1.2.3