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 --- harmaccuweather/harmaccuplugin.cpp | 30 +++++++++ harmaccuweather/harmaccuplugin.h | 24 +++++++ harmaccuweather/harmaccuprovider.cpp | 29 +++++++++ harmaccuweather/harmaccuprovider.h | 29 +++++++++ harmaccuweather/harmaccuweather.cpp | 109 ++++++++++++++++++++++++++++++++ harmaccuweather/harmaccuweather.h | 48 ++++++++++++++ harmaccuweather/harmaccuweather.pro | 33 ++++++++++ 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 +++++++++++ metawatch/metawatch.cpp | 6 ++ metawatch/metawatch.h | 1 + metawatch/metawatchdigital.cpp | 53 ++++++++++++++-- metawatch/metawatchdigital.h | 4 +- sowatch.pro | 2 +- sowatchd/daemon.cpp | 105 ++----------------------------- sowatchd/daemon.h | 8 +-- 25 files changed, 631 insertions(+), 124 deletions(-) create mode 100644 harmaccuweather/harmaccuplugin.cpp create mode 100644 harmaccuweather/harmaccuplugin.h create mode 100644 harmaccuweather/harmaccuprovider.cpp create mode 100644 harmaccuweather/harmaccuprovider.h create mode 100644 harmaccuweather/harmaccuweather.cpp create mode 100644 harmaccuweather/harmaccuweather.h create mode 100644 harmaccuweather/harmaccuweather.pro create mode 100644 libsowatch/registry.cpp create mode 100644 libsowatch/registry.h create mode 100644 libsowatch/weathernotification.cpp create mode 100644 libsowatch/weathernotification.h diff --git a/harmaccuweather/harmaccuplugin.cpp b/harmaccuweather/harmaccuplugin.cpp new file mode 100644 index 0000000..9ea94bd --- /dev/null +++ b/harmaccuweather/harmaccuplugin.cpp @@ -0,0 +1,30 @@ +#include "harmaccuprovider.h" +#include "harmaccuplugin.h" + +using namespace sowatch; + +HarmAccuPlugin::HarmAccuPlugin(QObject *parent) : + QObject(parent) +{ +} + +HarmAccuPlugin::~HarmAccuPlugin() +{ +} + +QStringList HarmAccuPlugin::providers() +{ + QStringList providers; + providers << "harmaccu"; + return providers; +} + +NotificationProvider* HarmAccuPlugin::getProvider(const QString& id, QSettings& settings, QObject *parent) +{ + if (id != "harmaccu") return 0; + int updateTime = settings.value("updateTime").toInt(); + if (updateTime <= 0) updateTime = 2 * 3600; // Two hours by default + return new HarmAccuProvider(updateTime, parent); +} + +Q_EXPORT_PLUGIN2(harmaccuweather, HarmAccuPlugin) diff --git a/harmaccuweather/harmaccuplugin.h b/harmaccuweather/harmaccuplugin.h new file mode 100644 index 0000000..16198ad --- /dev/null +++ b/harmaccuweather/harmaccuplugin.h @@ -0,0 +1,24 @@ +#ifndef CKITCALLPLUGIN_H +#define CKITCALLPLUGIN_H + +#include + +namespace sowatch +{ + +class HarmAccuPlugin : public QObject, public NotificationPluginInterface +{ + Q_OBJECT + Q_INTERFACES(sowatch::NotificationPluginInterface) + +public: + HarmAccuPlugin(QObject *parent = 0); + ~HarmAccuPlugin(); + + QStringList providers(); + NotificationProvider* getProvider(const QString& driver, QSettings& settings, QObject *parent = 0); +}; + +} + +#endif // CKITCALLPLUGIN_H diff --git a/harmaccuweather/harmaccuprovider.cpp b/harmaccuweather/harmaccuprovider.cpp new file mode 100644 index 0000000..af4a8d0 --- /dev/null +++ b/harmaccuweather/harmaccuprovider.cpp @@ -0,0 +1,29 @@ +#include +#include +#include "harmaccuweather.h" +#include "harmaccuprovider.h" + +using namespace sowatch; + +HarmAccuProvider::HarmAccuProvider(int updateTime, QObject *parent) : + NotificationProvider(parent), + _updateTime(updateTime) +{ + // Give some time to send the notification + QTimer::singleShot(2000, this, SLOT(generateNotification())); +} + +HarmAccuProvider::~HarmAccuProvider() +{ + +} + +void HarmAccuProvider::generateNotification() +{ + QSettings* s = HarmAccuWeather::getAccuweatherData(); + if (s->contains("LastUpdate")) { + qDebug() << "generate harmaccuweather notification"; + emit incomingNotification(new HarmAccuWeather(_updateTime, this)); + } + delete s; +} diff --git a/harmaccuweather/harmaccuprovider.h b/harmaccuweather/harmaccuprovider.h new file mode 100644 index 0000000..44942ad --- /dev/null +++ b/harmaccuweather/harmaccuprovider.h @@ -0,0 +1,29 @@ +#ifndef CKITCALLPROVIDER_H +#define CKITCALLPROVIDER_H + +#include +#include + +namespace sowatch +{ + +class HarmAccuWeather; + +class HarmAccuProvider : public NotificationProvider +{ + Q_OBJECT + +public: + explicit HarmAccuProvider(int updateTime, QObject *parent = 0); + ~HarmAccuProvider(); + +public slots: + void generateNotification(); + +private: + int _updateTime; +}; + +} + +#endif // CKITCALLPROVIDER_H diff --git a/harmaccuweather/harmaccuweather.cpp b/harmaccuweather/harmaccuweather.cpp new file mode 100644 index 0000000..9d7a00d --- /dev/null +++ b/harmaccuweather/harmaccuweather.cpp @@ -0,0 +1,109 @@ +#include "harmaccuweather.h" + +using namespace sowatch; + +HarmAccuWeather::HarmAccuWeather(int updateTime, QObject *parent) : + WeatherNotification(parent), + _updateTimer(new QTimer(this)), + _lastUpdate(QDateTime::fromTime_t(0)) +{ + connect(_updateTimer, SIGNAL(timeout()), SLOT(update())); + _updateTimer->setInterval(updateTime * 1000); + _updateTimer->start(); + update(); +} + +QSettings* HarmAccuWeather::getAccuweatherData() +{ + return new QSettings("AccuWeather, Inc.", "awxapp"); +} + +Notification::Type HarmAccuWeather::type() const +{ + return Notification::WeatherNotification; +} + +uint HarmAccuWeather::count() const +{ + return 1; +} + +QDateTime HarmAccuWeather::dateTime() const +{ + return _lastUpdate; +} + +QString HarmAccuWeather::title() const +{ + return _lastLocation; +} + +QString HarmAccuWeather::body() const +{ + switch (_lastWxCode) { + case 33: + return tr("Clear"); + case 6: + case 38: + return tr("Mostly cloudy"); + case 35: + return tr("Part. cloudy"); + case 7: + return tr("Cloudy"); + default: + return QString("%1").arg(_lastWxCode); + } +} + +WeatherNotification::WeatherType HarmAccuWeather::forecast() +{ + switch (_lastWxCode) { + case 33: + return Sunny; + case 6: + case 7: + case 35: + case 38: + return Cloudy; + default: + return UnknownWeather; + } +} + +int HarmAccuWeather::temperature() +{ + return _lastTemp; +} + +WeatherNotification::Unit HarmAccuWeather::temperatureUnits() +{ + return _metric ? Celsius : Fahrenheit; +} + +void HarmAccuWeather::activate() +{ + // Launch accuweather? +} + +void HarmAccuWeather::dismiss() +{ + // Do nothing +} + +void HarmAccuWeather::update() +{ + QSettings* s = getAccuweatherData(); + + QDateTime lastUpdate = s->value("LastUpdate").toDateTime(); + if (lastUpdate > _lastUpdate) { + qDebug() << "updated weather info"; + _lastUpdate = lastUpdate; + _metric = s->value("useMetric").toBool(); + _lastTemp = s->value("LastTemp").toInt(); + _lastLocation = s->value("LastLocation").toString(); + _lastWxCode = s->value("LastWxCode").toInt(); + emit changed(); + } + + delete s; +} diff --git a/harmaccuweather/harmaccuweather.h b/harmaccuweather/harmaccuweather.h new file mode 100644 index 0000000..bac08e2 --- /dev/null +++ b/harmaccuweather/harmaccuweather.h @@ -0,0 +1,48 @@ +#ifndef HARMACCUWEATHER_H +#define HARMACCUWEATHER_H + +#include +#include +#include + +namespace sowatch +{ + +class HarmAccuWeather : public WeatherNotification +{ + Q_OBJECT + +public: + explicit HarmAccuWeather(int updateTime, QObject *parent = 0); + + static QSettings* getAccuweatherData(); + + Type type() const; + uint count() const; + QDateTime dateTime() const; + QString title() const; + QString body() const; + + WeatherType forecast(); + int temperature(); + Unit temperatureUnits(); + + void activate(); + void dismiss(); + +private slots: + void update(); + +private: + QTimer* _updateTimer; + bool _metric; + QDateTime _lastUpdate; + QString _lastLocation; + int _lastTemp; + int _lastWxCode; + +}; + +} + +#endif // HARMACCUWEATHER_H diff --git a/harmaccuweather/harmaccuweather.pro b/harmaccuweather/harmaccuweather.pro new file mode 100644 index 0000000..7c9bfe5 --- /dev/null +++ b/harmaccuweather/harmaccuweather.pro @@ -0,0 +1,33 @@ +TARGET = harmaccuweather +TEMPLATE = lib +# CONFIG += plugin # Qt creator doesn't want to deploy plugins +CONFIG += mobility +MOBILITY += systeminfo + +SOURCES += harmaccuplugin.cpp harmaccuprovider.cpp \ + harmaccuweather.cpp + +HEADERS += harmaccuplugin.h harmaccuprovider.h \ + harmaccuweather.h + +unix: LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch + +INCLUDEPATH += $$PWD/../libsowatch +DEPENDPATH += $$PWD/../libsowatch + +unix:!symbian { + maemo5 { + target.path = /opt/sowatch/notifications + } else { + target.path = /usr/lib/sowatch/notifications + } + INSTALLS += target +} + + + + + + + + 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 diff --git a/metawatch/metawatch.cpp b/metawatch/metawatch.cpp index 9ca4b2d..b79f6fc 100644 --- a/metawatch/metawatch.cpp +++ b/metawatch/metawatch.cpp @@ -226,6 +226,12 @@ void MetaWatch::updateNotificationCount(Notification::Type type, int count) // Default implementation does nothing } +void MetaWatch::updateWeather(WeatherNotification *weather) +{ + Q_UNUSED(weather); + // Default implementation does nothing +} + void MetaWatch::displayIdleScreen() { _currentMode = IdleMode; diff --git a/metawatch/metawatch.h b/metawatch/metawatch.h index 8f0d52e..685b2a7 100644 --- a/metawatch/metawatch.h +++ b/metawatch/metawatch.h @@ -105,6 +105,7 @@ public: void ungrabButton(int button); void updateNotificationCount(Notification::Type type, int count); + void updateWeather(WeatherNotification *weather); void displayIdleScreen(); void displayNotification(Notification *notification); diff --git a/metawatch/metawatchdigital.cpp b/metawatch/metawatchdigital.cpp index a4bb833..ae13e49 100644 --- a/metawatch/metawatchdigital.cpp +++ b/metawatch/metawatchdigital.cpp @@ -73,6 +73,13 @@ void MetaWatchDigital::updateNotificationCount(Notification::Type type, int coun } } +void MetaWatchDigital::updateWeather(WeatherNotification *weather) +{ + if (isConnected()) { + renderIdleWeather(weather); + } +} + void MetaWatchDigital::displayIdleScreen() { qDebug() << "displaying idle screen"; @@ -152,20 +159,54 @@ void MetaWatchDigital::renderIdleScreen() renderIdleCounts(); } -void MetaWatchDigital::renderIdleWeather() +void MetaWatchDigital::renderIdleWeather(WeatherNotification* w) { _paintMode = IdleMode; - QFont f("MetaWatch Small caps 8pt", 6); - QImage rain(QString(":/metawatch/graphics/weather_rain.bmp")); + QFont sf("MetaWatch Small caps 8pt", 6); + QFont lf("MetaWatch Large 16pt"); QPainter p(this); - p.setFont(f); - p.drawText(30, systemAreaHeight + 14, "No data!"); - p.drawImage(screenWidth - 26, systemAreaHeight + 6, rain); + sf.setPixelSize(8); + lf.setPixelSize(16); + + p.fillRect(0, systemAreaHeight + 6, screenWidth, systemAreaHeight - 12, Qt::white); + + if (w) { + QImage icon = iconForWeather(w); + bool metric = w->temperatureUnits() == WeatherNotification::Celsius; + QString unit = QString::fromUtf8(metric ? "°C" : "°F"); + QRect bodyRect(4, systemAreaHeight + 6, 36, systemAreaHeight - 10); + p.setFont(sf); + p.drawText(bodyRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, w->body()); + p.drawImage(36, systemAreaHeight + 6, icon); + p.setFont(lf); + p.drawText(64, systemAreaHeight + 22, QString("%1 %2").arg(w->temperature()).arg(unit)); + } else { + p.setFont(sf); + p.drawText(32, systemAreaHeight + 18, tr("No data")); + } _paintMode = _currentMode; } +QImage MetaWatchDigital::iconForWeather(WeatherNotification *w) +{ + switch (w->forecast()) { + case WeatherNotification::Sunny: + return QImage(QString(":/metawatch/graphics/weather_sunny.bmp")); + case WeatherNotification::Cloudy: + return QImage(QString(":/metawatch/graphics/weather_cloudy.bmp")); + case WeatherNotification::Rain: + return QImage(QString(":/metawatch/graphics/weather_rain.bmp")); + case WeatherNotification::Snow: + return QImage(QString(":/metawatch/graphics/weather_snow.bmp")); + case WeatherNotification::Thunderstorm: + return QImage(QString(":/metawatch/graphics/weather_thunderstorm.bmp")); + default: + return QImage(); + } +} + void MetaWatchDigital::renderIdleCounts() { _paintMode = IdleMode; diff --git a/metawatch/metawatchdigital.h b/metawatch/metawatchdigital.h index 0754242..a528eb2 100644 --- a/metawatch/metawatchdigital.h +++ b/metawatch/metawatchdigital.h @@ -21,6 +21,7 @@ public: QString model() const; void updateNotificationCount(Notification::Type type, int count); + void updateWeather(WeatherNotification *weather); void displayIdleScreen(); void displayNotification(Notification *notification); @@ -36,7 +37,8 @@ protected: void handleWatchConnected(); void renderIdleScreen(); - void renderIdleWeather(); + void renderIdleWeather(WeatherNotification *w = 0); + QImage iconForWeather(WeatherNotification *w); void renderIdleCounts(); void renderNotification(Notification *n); diff --git a/sowatch.pro b/sowatch.pro index e4c3107..367bd36 100644 --- a/sowatch.pro +++ b/sowatch.pro @@ -6,7 +6,7 @@ SUBDIRS = libsowatch \ sysinfowatchlet !isEmpty(MEEGO_VERSION_MAJOR) { - SUBDIRS += meegohandsetnotification ckitcallnotification qmafwwatchlet qmapwatchlet + SUBDIRS += meegohandsetnotification ckitcallnotification harmaccuweather qmafwwatchlet qmapwatchlet } unix:!symbian { diff --git a/sowatchd/daemon.cpp b/sowatchd/daemon.cpp index 0cc6c05..3cbfb64 100644 --- a/sowatchd/daemon.cpp +++ b/sowatchd/daemon.cpp @@ -1,81 +1,16 @@ #include -#include -#include -#include #include #include "daemon.h" using namespace sowatch; Daemon::Daemon(QObject *parent) : - QObject(parent) + QObject(parent), + _registry(Registry::registry()) { - loadDrivers(); - loadProviders(); - loadWatchlets(); initWatches(); } -void Daemon::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 Daemon::loadProviders() -{ - 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 providers" << _providers.keys(); -} - void Daemon::initWatches() { QSettings settings; @@ -84,7 +19,7 @@ void Daemon::initWatches() for (int i = 0; i < size; i++) { settings.setArrayIndex(i); QString driver = settings.value("driver").toString().toLower(); - WatchPluginInterface *plugin = _drivers[driver]; + WatchPluginInterface *plugin = _registry->getWatchPlugin(driver); if (plugin) { Watch *watch = plugin->getWatch(driver, settings, this); if (watch) { @@ -117,7 +52,7 @@ void Daemon::initWatch(Watch* watch, QSettings& settings) for (int i = 0; i < size; i++) { settings.setArrayIndex(i); QString id = settings.value("provider").toString().toLower(); - NotificationPluginInterface *plugin = _providers[id]; + NotificationPluginInterface *plugin = _registry->getNotificationPlugin(id); if (plugin) { NotificationProvider *provider = plugin->getProvider(id, settings, server); server->addProvider(provider); @@ -132,7 +67,7 @@ void Daemon::initWatch(Watch* watch, QSettings& settings) for (int i = 0; i < size; i++) { settings.setArrayIndex(i); QString id = settings.value("id").toString().toLower(); - WatchletPluginInterface *plugin = _watchlets[id]; + WatchletPluginInterface *plugin = _registry->getWatchletPlugin(id); if (plugin) { plugin->getWatchlet(id, settings, server); // Watchlets are associated to server via parent-child relationship. @@ -142,33 +77,3 @@ void Daemon::initWatch(Watch* watch, QSettings& settings) } settings.endArray(); } - -void Daemon::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/sowatchd/daemon.h b/sowatchd/daemon.h index 8885d6f..48125fb 100644 --- a/sowatchd/daemon.h +++ b/sowatchd/daemon.h @@ -18,15 +18,9 @@ public: explicit Daemon(QObject *parent = 0); protected: - QMap _drivers; - QMap _providers; - QMap _watchlets; + Registry* _registry; QList _servers; - void loadDrivers(); - void loadProviders(); - void loadWatchlets(); - void initWatches(); void initWatch(Watch* watch, QSettings& settings); }; -- cgit v1.2.3