From cf5d24b94d96b722c6d76c2225293a56a50d3c2b Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Sun, 25 Sep 2011 04:53:46 +0200 Subject: watchlets working! --- libsowatch/declarativewatchlet.cpp | 10 ++++++++ libsowatch/declarativewatchlet.h | 4 +++ libsowatch/notification.cpp | 19 +++++++++++++++ libsowatch/notification.h | 1 + libsowatch/watchletplugininterface.h | 2 +- libsowatch/watchserver.cpp | 20 +++++++++------ libsowatch/watchserver.h | 5 ++-- metawatch/metawatch.cpp | 45 ++++++++++++++++++++++++---------- sowatch.pro | 5 ++-- sowatchd/daemon.cpp | 31 +++++++++++++++-------- sowatchd/daemon.h | 1 + sysinfowatchlet/metawatch-digital.qml | 46 +++++++++++++++++++++++++++++++++++ sysinfowatchlet/sysinfoplugin.cpp | 29 ++++++++++++++++++++++ sysinfowatchlet/sysinfoplugin.h | 24 ++++++++++++++++++ sysinfowatchlet/sysinfowatchlet.cpp | 26 ++++++++++++++++++++ sysinfowatchlet/sysinfowatchlet.h | 29 ++++++++++++++++++++++ sysinfowatchlet/sysinfowatchlet.pro | 44 +++++++++++++++++++++++++++++++++ sysinfowatchlet/sysinfowatchlet.qrc | 5 ++++ 18 files changed, 311 insertions(+), 35 deletions(-) create mode 100644 sysinfowatchlet/metawatch-digital.qml create mode 100644 sysinfowatchlet/sysinfoplugin.cpp create mode 100644 sysinfowatchlet/sysinfoplugin.h create mode 100644 sysinfowatchlet/sysinfowatchlet.cpp create mode 100644 sysinfowatchlet/sysinfowatchlet.h create mode 100644 sysinfowatchlet/sysinfowatchlet.pro create mode 100644 sysinfowatchlet/sysinfowatchlet.qrc diff --git a/libsowatch/declarativewatchlet.cpp b/libsowatch/declarativewatchlet.cpp index 7e6768e..60538f8 100644 --- a/libsowatch/declarativewatchlet.cpp +++ b/libsowatch/declarativewatchlet.cpp @@ -54,6 +54,16 @@ void DeclarativeWatchlet::setSource(const QUrl &url) } } +QDeclarativeEngine* DeclarativeWatchlet::engine() +{ + return _engine; +} + +QDeclarativeContext* DeclarativeWatchlet::rootContext() +{ + return _engine->rootContext(); +} + void DeclarativeWatchlet::activate() { Watchlet::activate(); diff --git a/libsowatch/declarativewatchlet.h b/libsowatch/declarativewatchlet.h index 2cc4655..0dd7e23 100644 --- a/libsowatch/declarativewatchlet.h +++ b/libsowatch/declarativewatchlet.h @@ -2,6 +2,7 @@ #define SOWATCH_DECLARATIVEWATCHLET_H #include +#include #include #include #include "graphicswatchlet.h" @@ -20,6 +21,9 @@ public: void setSource(const QUrl& url); + QDeclarativeEngine* engine(); + QDeclarativeContext* rootContext(); + protected slots: void handleComponentStatus(QDeclarativeComponent::Status status); diff --git a/libsowatch/notification.cpp b/libsowatch/notification.cpp index b4c97b2..e321b58 100644 --- a/libsowatch/notification.cpp +++ b/libsowatch/notification.cpp @@ -11,6 +11,25 @@ Notification::~Notification() { } +QString Notification::displayTime() const +{ + QDateTime dt = dateTime(); + int secsDiff = dt.secsTo(QDateTime::currentDateTime()); + if (secsDiff < 1) { + return ""; + } else if (secsDiff < 60) { + return tr("%n second(s) ago", "", secsDiff); + } else if (secsDiff < 60*60) { + int n = secsDiff / 60; + return tr("%n minute(s) ago", "", n); + } else if (secsDiff < 60*60*24) { + int n = secsDiff / 3600; + return tr("%n hour(s) ago", "", n); + } else { + return dt.toString(Qt::SystemLocaleShortDate); + } +} + QImage Notification::image() const { return QImage(); diff --git a/libsowatch/notification.h b/libsowatch/notification.h index 8e58653..3505c44 100644 --- a/libsowatch/notification.h +++ b/libsowatch/notification.h @@ -33,6 +33,7 @@ public: virtual Type type() const = 0; virtual uint count() const = 0; virtual QDateTime dateTime() const = 0; + virtual QString displayTime() const; virtual QString title() const = 0; virtual QString body() const = 0; virtual QImage image() const; diff --git a/libsowatch/watchletplugininterface.h b/libsowatch/watchletplugininterface.h index ad83dd4..4f525f2 100644 --- a/libsowatch/watchletplugininterface.h +++ b/libsowatch/watchletplugininterface.h @@ -18,7 +18,7 @@ public: virtual ~WatchletPluginInterface(); virtual QStringList watchlets() = 0; - virtual Watchlet* getProvider(const QString& id, QSettings& settings, WatchServer *server) = 0; + virtual Watchlet* getWatchlet(const QString& id, QSettings& settings, WatchServer *server) = 0; }; } diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp index 39802f9..07e4609 100644 --- a/libsowatch/watchserver.cpp +++ b/libsowatch/watchserver.cpp @@ -11,6 +11,7 @@ using namespace sowatch; WatchServer::WatchServer(Watch* watch, QObject* parent) : QObject(parent), _watch(watch), _nextWatchletButton(-1), + _oldNotificationThreshold(300), _currentWatchlet(0), _currentWatchletIndex(-1) { connect(_watch, SIGNAL(connected()), SLOT(watchConnected())); @@ -55,7 +56,7 @@ void WatchServer::addProvider(NotificationProvider *provider) void WatchServer::runWatchlet(const QString& id) { if (_currentWatchlet) { - closeWatchlet(); + _currentWatchlet->deactivate(); } qDebug() << "activating watchlet" << id; _currentWatchlet = _watchlets[id]; @@ -67,11 +68,9 @@ void WatchServer::runWatchlet(const QString& id) void WatchServer::closeWatchlet() { if (_currentWatchlet) { - if (_watch->isConnected()) { - _currentWatchlet->deactivate(); - } + _currentWatchlet->deactivate(); _currentWatchlet = 0; - if (_pendingNotifications.empty()) { + if (_watch->isConnected() && _pendingNotifications.empty()) { goToIdle(); } } @@ -94,7 +93,6 @@ void WatchServer::nextWatchlet() { QStringList watchlets = _watchlets.keys(); _currentWatchletIndex++; - qDebug() << "next watchlet" << _currentWatchletIndex; if (_currentWatchletIndex >= watchlets.size()) { _currentWatchletIndex = -1; closeWatchlet(); @@ -165,6 +163,7 @@ void WatchServer::watchIdling() void WatchServer::watchButtonPress(int button) { if (button == _nextWatchletButton) { + qDebug() << "next watchlet button pressed"; if (_pendingNotifications.empty()) { // No notifications: either app or idle mode. nextWatchlet(); @@ -187,6 +186,12 @@ void WatchServer::notificationReceived(Notification *notification) qDebug() << "notification received" << notification->title() << notification->count(); _watch->updateNotificationCount(type, getNotificationCount(type)); + + QDateTime oldThreshold = QDateTime::currentDateTime().addSecs(-_oldNotificationThreshold); + if (notification->dateTime() < oldThreshold) { + return; // Do not care about that old notifications... + } + if (_pendingNotifications.isEmpty()) { _pendingNotifications.enqueue(notification); nextNotification(); @@ -226,7 +231,8 @@ void WatchServer::notificationCleared() qDebug() << "notification deleted" << n->title() << n->count(); _watch->updateNotificationCount(type, getNotificationCount(type)); - if (!_pendingNotifications.isEmpty() && _pendingNotifications.head() == n) { + + if (!_pendingNotifications.isEmpty() && _pendingNotifications.head() == n) {qDebug() << "removing top notification"; _pendingNotifications.removeAll(n); nextNotification(); } else { diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h index 681c758..a3e0593 100644 --- a/libsowatch/watchserver.h +++ b/libsowatch/watchserver.h @@ -37,7 +37,8 @@ public: protected: Watch* _watch; - char _nextWatchletButton; + int _nextWatchletButton; + int _oldNotificationThreshold; QMap _watchlets; @@ -46,7 +47,7 @@ protected: QQueue _pendingNotifications; Watchlet* _currentWatchlet; - char _currentWatchletIndex; + unsigned char _currentWatchletIndex; void registerWatchlet(Watchlet *watchlet); void reactivateCurrentWatchlet(); diff --git a/metawatch/metawatch.cpp b/metawatch/metawatch.cpp index a429083..1ad7159 100644 --- a/metawatch/metawatch.cpp +++ b/metawatch/metawatch.cpp @@ -112,7 +112,7 @@ MetaWatch::MetaWatch(const QBluetoothAddress& address, QSettings* settings, QObj _idleTimer->setSingleShot(true); connect(_idleTimer, SIGNAL(timeout()), SIGNAL(idling())); - _ringTimer->setInterval(2000); + _ringTimer->setInterval(2500); connect(_ringTimer, SIGNAL(timeout()), SLOT(timedRing())); _connectTimer->setSingleShot(true); @@ -228,20 +228,29 @@ void MetaWatch::displayIdleScreen() void MetaWatch::displayNotification(Notification *n) { + const bool shouldRing = n->type() == Notification::CallNotification; _currentMode = NotificationMode; _paintMode = NotificationMode; - const bool shouldRing = n->type() == Notification::CallNotification; configureWatchMode(NotificationMode, shouldRing ? 60 : 10); + QPainter p; - QFont lf("MetaWatch Large 16pt", 14); - QFont mf("MetaWatch Large 16pt", 10); + QFont sf("MetaWatch Small caps 8pt"); + QFont lf("MetaWatch Large 16pt"); + QFont mf("MetaWatch Large 16pt"); QImage icon = iconForNotification(n); - const int x = 4; - const int iconY = 4; - const int titleY = 8 + icon.height(); + const int iconW = icon.width(), iconH = icon.height(); + const int margin = 4; + const int x = margin; + const int iconY = margin; + const int titleY = margin*2 + iconH; + const int dateX = x + iconW + margin; int textFlags; QString text; + sf.setPixelSize(8); + mf.setPixelSize(16); + lf.setPixelSize(18); + qDebug() << "displayNotification" << n->title() << n->body(); p.begin(this); @@ -250,6 +259,13 @@ void MetaWatch::displayNotification(Notification *n) p.drawImage(x, iconY, icon); p.setPen(Qt::black); + + p.setFont(sf); + textFlags = Qt::AlignRight | Qt::AlignVCenter | Qt::TextWordWrap; + text = n->displayTime(); + QRect dateRect(dateX, iconY, (screenWidth - dateX) - margin, iconH); + p.drawText(dateRect, textFlags, text); + p.setFont(lf); textFlags = Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere; text = n->title(); @@ -261,7 +277,6 @@ void MetaWatch::displayNotification(Notification *n) titleRect = p.boundingRect(titleMaxRect, textFlags, text); } - qDebug() << titleMaxRect << titleRect; p.drawText(titleMaxRect, textFlags, text); p.setFont(mf); @@ -276,7 +291,7 @@ void MetaWatch::displayNotification(Notification *n) if (bodyRect.width() > bodyMaxRect.width()) { textFlags = Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere; } - qDebug() << bodyMaxRect << bodyRect; + p.drawText(bodyMaxRect, textFlags, text); p.end(); @@ -332,10 +347,13 @@ void MetaWatch::updateNotificationCount(Notification::Type type, int count) break; default: // Ignore + return; break; } - renderIdleCounts(); + if (isConnected()) { + renderIdleCounts(); + } } MetaWatch::Mode MetaWatch::currentMode() const @@ -609,6 +627,8 @@ void MetaWatch::updateLines(Mode mode, const QImage& image, const QVector& } } } + + } void MetaWatch::configureWatchMode(Mode mode, int timeout, bool invert) @@ -669,8 +689,7 @@ void MetaWatch::disableButton(Mode mode, Button button, ButtonPress press) void MetaWatch::handleStatusChange(const Message &msg) { - QString s; - qDebug() << "watch status changed" << s.sprintf("0x%hx", msg.options) << s.sprintf("0x%hx", msg.data.at(0)); + Q_UNUSED(msg); } void MetaWatch::handleButtonEvent(const Message &msg) @@ -852,7 +871,7 @@ void MetaWatch::timedSend() void MetaWatch::timedRing() { - setVibrateMode(true, 200, 200, 3); + setVibrateMode(true, 250, 250, 3); } void MetaWatch::realSend(const Message &msg) diff --git a/sowatch.pro b/sowatch.pro index db0228b..6d850ef 100644 --- a/sowatch.pro +++ b/sowatch.pro @@ -1,10 +1,11 @@ TEMPLATE = subdirs SUBDIRS = libsowatch \ metawatch \ - sowatchd + sowatchd \ + sysinfowatchlet !isEmpty(MEEGO_VERSION_MAJOR) { - #SUBDIRS += meegohandsetnotification ckitcallnotification + SUBDIRS += meegohandsetnotification ckitcallnotification } unix:!symbian { diff --git a/sowatchd/daemon.cpp b/sowatchd/daemon.cpp index 26cbad0..0cc6c05 100644 --- a/sowatchd/daemon.cpp +++ b/sowatchd/daemon.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "daemon.h" using namespace sowatch; @@ -13,6 +12,7 @@ Daemon::Daemon(QObject *parent) : { loadDrivers(); loadProviders(); + loadWatchlets(); initWatches(); } @@ -121,12 +121,25 @@ void Daemon::initWatch(Watch* watch, QSettings& settings) if (plugin) { NotificationProvider *provider = plugin->getProvider(id, settings, server); server->addProvider(provider); + } else { + qWarning() << "Unknown notification provider" << id; } } + settings.endArray(); - // Initialize test watchlets - new TestWatchlet(server); - + // Initialize watchlets + size = settings.beginReadArray("watchlets"); + for (int i = 0; i < size; i++) { + settings.setArrayIndex(i); + QString id = settings.value("id").toString().toLower(); + WatchletPluginInterface *plugin = _watchlets[id]; + if (plugin) { + plugin->getWatchlet(id, settings, server); + // Watchlets are associated to server via parent-child relationship. + } else { + qWarning() << "Unknown watchlet" << id; + } + } settings.endArray(); } @@ -141,23 +154,21 @@ void Daemon::loadWatchlets() QPluginLoader loader(dir.absoluteFilePath(file)); QObject *pluginObj = loader.instance(); if (pluginObj) { -#if 0 WatchletPluginInterface *plugin = qobject_cast(pluginObj); if (plugin) { - QStringList providers = plugin->providers(); - foreach (const QString& provider, providers) { - _providers[provider] = plugin; + QStringList watchlets = plugin->watchlets(); + foreach (const QString& watchlet, watchlets) { + _watchlets[watchlet] = plugin; } } else { qWarning() << "Invalid plugin" << file; loader.unload(); } -#endif } else { qWarning() << "Invalid plugin" << file << loader.errorString(); loader.unload(); } } - qDebug() << "loaded watchlets"; + qDebug() << "loaded watchlets" << _watchlets.keys(); } diff --git a/sowatchd/daemon.h b/sowatchd/daemon.h index 607e887..8885d6f 100644 --- a/sowatchd/daemon.h +++ b/sowatchd/daemon.h @@ -20,6 +20,7 @@ public: protected: QMap _drivers; QMap _providers; + QMap _watchlets; QList _servers; void loadDrivers(); diff --git a/sysinfowatchlet/metawatch-digital.qml b/sysinfowatchlet/metawatch-digital.qml new file mode 100644 index 0000000..65e9a7d --- /dev/null +++ b/sysinfowatchlet/metawatch-digital.qml @@ -0,0 +1,46 @@ +import QtQuick 1.0 + +Rectangle { + width: 96 + height: 96 + + color: "white" + + Column { + anchors.fill: parent + spacing: 4 + + Text { + text: "Battery: " + batteryLevel + "%" + } + + Rectangle { + id: battery + x: 12 + width: 72 + height: 16 + + border.color: "black" + border.width: 1 + + Rectangle { + width: (batteryLevel / 100) * parent.width + height: parent.height + + color: "black" + } + } + + Text { + width: parent.width + text: "Connected to:" + } + + Text { + width: parent.width + text: networkName + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + } + } +} diff --git a/sysinfowatchlet/sysinfoplugin.cpp b/sysinfowatchlet/sysinfoplugin.cpp new file mode 100644 index 0000000..fc862c0 --- /dev/null +++ b/sysinfowatchlet/sysinfoplugin.cpp @@ -0,0 +1,29 @@ +#include "sysinfowatchlet.h" +#include "sysinfoplugin.h" + +using namespace sowatch; + +SysInfoPlugin::SysInfoPlugin(QObject *parent) : + QObject(parent) +{ +} + +SysInfoPlugin::~SysInfoPlugin() +{ +} + +QStringList SysInfoPlugin::watchlets() +{ + QStringList l; + l << "com.javispedro.sowatch.sysinfo"; + return l; +} + +Watchlet* SysInfoPlugin::getWatchlet(const QString& driver, QSettings& settings, WatchServer *server) +{ + Q_UNUSED(driver); + Q_UNUSED(settings); + return new SysInfoWatchlet(server); +} + +Q_EXPORT_PLUGIN2(sysinfowatchlet, SysInfoPlugin) diff --git a/sysinfowatchlet/sysinfoplugin.h b/sysinfowatchlet/sysinfoplugin.h new file mode 100644 index 0000000..4e24b9e --- /dev/null +++ b/sysinfowatchlet/sysinfoplugin.h @@ -0,0 +1,24 @@ +#ifndef CKITCALLPLUGIN_H +#define CKITCALLPLUGIN_H + +#include + +namespace sowatch +{ + +class SysInfoPlugin : public QObject, public WatchletPluginInterface +{ + Q_OBJECT + Q_INTERFACES(sowatch::WatchletPluginInterface) + +public: + SysInfoPlugin(QObject *parent = 0); + ~SysInfoPlugin(); + + QStringList watchlets(); + Watchlet* getWatchlet(const QString& driver, QSettings& settings, WatchServer* server); +}; + +} + +#endif // CKITCALLPLUGIN_H diff --git a/sysinfowatchlet/sysinfowatchlet.cpp b/sysinfowatchlet/sysinfowatchlet.cpp new file mode 100644 index 0000000..c9f44c2 --- /dev/null +++ b/sysinfowatchlet/sysinfowatchlet.cpp @@ -0,0 +1,26 @@ +#include "sysinfowatchlet.h" + +using namespace sowatch; +QTM_USE_NAMESPACE + +SysInfoWatchlet::SysInfoWatchlet(WatchServer* server) : + DeclarativeWatchlet(server, "com.javispedro.sowatch.sysinfo"), + _devInfo(new QSystemDeviceInfo(this)), + _netMgr(new QNetworkConfigurationManager(this)) +{ + rootContext()->setContextProperty("batteryLevel", 0); + rootContext()->setContextProperty("networkName", ""); + setSource(QUrl("qrc:/sysinfowatchlet/" + server->watch()->model() + ".qml")); + connect(this, SIGNAL(activated()), SLOT(handleActivated())); +} + +void SysInfoWatchlet::handleActivated() +{ + QList cfgs = _netMgr->allConfigurations(QNetworkConfiguration::Active); + rootContext()->setContextProperty("batteryLevel", _devInfo->batteryLevel()); + if (cfgs.size() > 0) { + rootContext()->setContextProperty("networkName", cfgs[0].name()); + } else { + rootContext()->setContextProperty("networkName", ""); + } +} diff --git a/sysinfowatchlet/sysinfowatchlet.h b/sysinfowatchlet/sysinfowatchlet.h new file mode 100644 index 0000000..25d8f57 --- /dev/null +++ b/sysinfowatchlet/sysinfowatchlet.h @@ -0,0 +1,29 @@ +#ifndef SOWATCH_TESTDECLARATIVEWATCHLET_H +#define SOWATCH_TESTDECLARATIVEWATCHLET_H + +#include +#include +#include + +using QTM_PREPEND_NAMESPACE(QSystemDeviceInfo); + +namespace sowatch +{ + +class SysInfoWatchlet : public DeclarativeWatchlet +{ + Q_OBJECT +public: + explicit SysInfoWatchlet(WatchServer* server); + +private slots: + void handleActivated(); + +private: + QSystemDeviceInfo *_devInfo; + QNetworkConfigurationManager *_netMgr; +}; + +} + +#endif // SOWATCH_TESTDECLARATIVEWATCHLET_H diff --git a/sysinfowatchlet/sysinfowatchlet.pro b/sysinfowatchlet/sysinfowatchlet.pro new file mode 100644 index 0000000..8c87ad8 --- /dev/null +++ b/sysinfowatchlet/sysinfowatchlet.pro @@ -0,0 +1,44 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2011-09-24T00:00:03 +# +#------------------------------------------------- + +TARGET = sysinfowatchlet +TEMPLATE = lib +# CONFIG += plugin # Stupid Qt creator doesn't want to deploy plugins +QT += network +CONFIG += mobility +MOBILITY += systeminfo + +SOURCES += sysinfoplugin.cpp sysinfowatchlet.cpp + +HEADERS += sysinfoplugin.h sysinfowatchlet.h + +unix: LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch + +INCLUDEPATH += $$PWD/../libsowatch +DEPENDPATH += $$PWD/../libsowatch + +unix:!symbian { + maemo5 { + target.path = /opt/sowatch/watchlets + } else { + target.path = /usr/lib/sowatch/watchlets + } + INSTALLS += target +} + +OTHER_FILES += \ + metawatch-digital.qml + +RESOURCES += \ + sysinfowatchlet.qrc + + + + + + + + diff --git a/sysinfowatchlet/sysinfowatchlet.qrc b/sysinfowatchlet/sysinfowatchlet.qrc new file mode 100644 index 0000000..62142b0 --- /dev/null +++ b/sysinfowatchlet/sysinfowatchlet.qrc @@ -0,0 +1,5 @@ + + + metawatch-digital.qml + + -- cgit v1.2.3