diff options
author | Javier S. Pedro <dev.git@javispedro.com> | 2014-09-15 01:53:44 +0200 |
---|---|---|
committer | Javier S. Pedro <dev.git@javispedro.com> | 2014-09-15 01:53:44 +0200 |
commit | d9f140ec45f91a8567b6d8e2ce69fe853ae8b3a9 (patch) | |
tree | 8ba1186f98da2e5c06363c2dd44f65b5f6901bc7 /src | |
parent | 9af5d200411adf947fdc1876bc76ce22789dde00 (diff) | |
download | salmeta-d9f140ec45f91a8567b6d8e2ce69fe853ae8b3a9.tar.gz salmeta-d9f140ec45f91a8567b6d8e2ce69fe853ae8b3a9.zip |
minimal notifications
Diffstat (limited to 'src')
-rw-r--r-- | src/controller.cpp | 21 | ||||
-rw-r--r-- | src/controller.h | 1 | ||||
-rw-r--r-- | src/metawatch.cpp | 52 | ||||
-rw-r--r-- | src/metawatch.h | 17 | ||||
-rw-r--r-- | src/notification.cpp | 6 | ||||
-rw-r--r-- | src/notification.h | 17 | ||||
-rw-r--r-- | src/notificationmonitor.cpp | 23 | ||||
-rw-r--r-- | src/notificationmonitor.h | 9 | ||||
-rw-r--r-- | src/org.freedesktop.Notifications.xml | 17 | ||||
-rw-r--r-- | src/salmeta.cpp | 8 |
10 files changed, 122 insertions, 49 deletions
diff --git a/src/controller.cpp b/src/controller.cpp index f4a2b09..bd2b68b 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1,5 +1,8 @@ #include <QtCore/QDebug> #include <QtCore/QDateTime> +#include <QtGui/QPainter> + +#include <sailfishapp.h> #include "controller.h" @@ -25,6 +28,7 @@ Controller::Controller(const QString &settingsPrefix, QQuickView *view, QObject _curPage = _settings->value(setting_cur_page).toInt(); connect(_settings, &MDConfGroup::valueChanged, this, &Controller::handleSettingChanged); + connect(_monitor, &NotificationMonitor::incomingNotification, this, &Controller::handleIncomingNotification); connect(_widgets, &QAbstractItemModel::dataChanged, this, &Controller::handleWidgetChanged); connectToAddress(_settings->value(setting_address).toString()); @@ -189,6 +193,23 @@ void Controller::handleMetaWatchBatteryStatus(bool charging, int charge) } } +void Controller::handleIncomingNotification(const QString &sender, const QIcon &icon, const QString &summary, const QString &body) +{ + QImage image(96, 96, QImage::Format_MonoLSB); + QPainter p(&image); + + p.drawImage(0, 0, QImage(SailfishApp::pathTo("qml/watch/notification.png").toLocalFile())); + icon.paint(&p, 0, 96 - 24, 24, 24, Qt::AlignLeft | Qt::AlignBottom); + + p.drawText(QRect(2, 26, 92, 55), Qt::AlignLeft | Qt::AlignTop, body); + + image.invertPixels(); + + _metawatch->sendModeImage(MetaWatch::WatchModeNotification, image); + _metawatch->updateLcdDisplayMode(MetaWatch::WatchModeNotification); + _metawatch->setVibrateMode(true, 500, 500, 2); +} + void Controller::handleWidgetChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) { if (roles.indexOf(WidgetInfoModel::UrlRole) >= 0) { diff --git a/src/controller.h b/src/controller.h index f4d4513..a375247 100644 --- a/src/controller.h +++ b/src/controller.h @@ -46,6 +46,7 @@ private slots: void handleMetaWatchConnected(); void handleMetaWatchModeChange(MetaWatch::WatchMode mode, int page); void handleMetaWatchBatteryStatus(bool charging, int charge); + void handleIncomingNotification(const QString &sender, const QIcon &icon, const QString &summary, const QString &body); void handleWidgetChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles); private: diff --git a/src/metawatch.cpp b/src/metawatch.cpp index b6042af..9b0bae2 100644 --- a/src/metawatch.cpp +++ b/src/metawatch.cpp @@ -1,6 +1,8 @@ #include <QtCore/QDataStream> #include <QtCore/QDateTime> #include <QtCore/QDebug> +#include <QtCore/QThread> +#include <QtGui/QImage> #include "metawatch.h" #include "metawatchbletransport.h" @@ -16,15 +18,16 @@ MetaWatch::MetaWatch(const QString &btAddr, QObject *parent) : connect(_transport, &MetaWatchTransport::messageReceived, this, &MetaWatch::handleTransportMessage); } -QList<QUrl> MetaWatch::availableClocks() +void MetaWatch::setVibrateMode(bool enable, int on_duration, int off_duration, int cycles) { - QList<QUrl> clocks; + QByteArray data; + QDataStream s(&data, QIODevice::WriteOnly); + s.setByteOrder(QDataStream::LittleEndian); - for (int i = 0; i < 6; i++) { - clocks << QUrl("clock://" + QString::number(i)); - } + s << quint8(enable ? 1 : 0); + s << quint16(on_duration) << quint16(off_duration) << quint8(cycles); - return clocks; + _transport->sendMessage(MessageSetVibrateMode, 0, data); } void MetaWatch::setDateTime(const QDateTime &dt) @@ -34,6 +37,7 @@ void MetaWatch::setDateTime(const QDateTime &dt) QByteArray data; QDataStream s(&data, QIODevice::WriteOnly); s.setByteOrder(QDataStream::BigEndian); + s << quint16(date.year()) << quint8(date.month()) << quint8(date.day()); s << quint8(date.dayOfWeek() % 7); s << quint8(time.hour()) << quint8(time.minute()) << quint8(time.second()); @@ -71,6 +75,14 @@ void MetaWatch::updateLcdDisplayPage(int page) QByteArray()); } +void MetaWatch::updateLcdDisplayMode(WatchMode mode) +{ + Q_ASSERT(mode != WatchModeIdle); // TODO + _transport->sendMessage(MessageUpdateLcdDisplay, + (mode & 0x3), + QByteArray()); +} + void MetaWatch::updateWidgetList(const QList<WidgetInfo> &widgets) { int num_widgets = 0; @@ -143,6 +155,22 @@ void MetaWatch::updateWidgetList(const QList<WidgetInfo> &widgets) } } +void MetaWatch::sendModeImage(WatchMode mode, const QImage &image) +{ + Q_ASSERT(image.width() == 96 && image.height() == 96); + Q_ASSERT(image.bytesPerLine() == 12); + QByteArray data(1 + image.bytesPerLine(), '\0');//Qt::Uninitialized); + + for (int i = 0; i < image.height(); i++) { + data[0] = i; + memcpy(data.data() + 1, image.scanLine(i), image.bytesPerLine()); + + _transport->sendMessage(MessageWriteLcdBuffer, + 0x10 | (mode & 0x3), + data); + } +} + void MetaWatch::connectDevice() { _transport->connectDevice(); @@ -153,18 +181,6 @@ void MetaWatch::disconnectDevice() _transport->disconnectDevice(); } -int MetaWatch::clockUrlToClockId(const QUrl &url) -{ - if (url.scheme() != "clock") - return -1; - - QString host = url.host(); - if (!host.startsWith("clock")) - return -1; - - return host.mid(5).toInt(); -} - void MetaWatch::handleTransportMessage(quint8 type, quint8 options, const QByteArray &payload) { switch (type) { diff --git a/src/metawatch.h b/src/metawatch.h index 6b50ead..a83ad0c 100644 --- a/src/metawatch.h +++ b/src/metawatch.h @@ -22,6 +22,8 @@ public: MessageGetDeviceType = 0x01, MessageGetDeviceTypeResponse = 0x02, + MessageSetVibrateMode = 0x23, + MessageSetRealTimeClock = 0x26, MessageWatchPropertyOperation = 0x30, @@ -29,6 +31,8 @@ public: MessageModeChangeIndication = 0x33, + MessageWriteLcdBuffer = 0x40, + MessageUpdateLcdDisplay = 0x43, MessageGetBatteryStatus = 0x56, @@ -50,7 +54,8 @@ public: }; enum WatchMode { - WatchModeIdle = 0 + WatchModeIdle = 0, + WatchModeNotification = 2 }; enum WatchProperty { @@ -72,8 +77,7 @@ public: UiGen2 = 1 }; - static QList<QUrl> availableClocks(); - + void setVibrateMode(bool enable, int on_duration, int off_duration, int cycles); void setDateTime(const QDateTime &dt); void configure(WatchProperties props); @@ -83,8 +87,12 @@ public: void updateLcdDisplay(); /** Goes to idle mode and a specific page */ void updateLcdDisplayPage(int page); + /** Goes to a specific mode. */ + void updateLcdDisplayMode(WatchMode mode); void updateWidgetList(const QList<WidgetInfo>& widgets); + void sendModeImage(WatchMode mode, const QImage &image); + signals: void connected(); void disconnected(); @@ -97,9 +105,6 @@ public slots: void connectDevice(); void disconnectDevice(); -private: - static int clockUrlToClockId(const QUrl &url); - private slots: void handleTransportMessage(quint8 type, quint8 options, const QByteArray &payload); diff --git a/src/notification.cpp b/src/notification.cpp deleted file mode 100644 index 00d66ad..0000000 --- a/src/notification.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "notification.h" - -Notification::Notification(QObject *parent) : - QObject(parent) -{ -} diff --git a/src/notification.h b/src/notification.h deleted file mode 100644 index 899a9aa..0000000 --- a/src/notification.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef NOTIFICATION_H -#define NOTIFICATION_H - -#include <QObject> - -class Notification : public QObject -{ -public: - explicit Notification(QObject *parent = 0); - -signals: - -public slots: - -}; - -#endif // NOTIFICATION_H diff --git a/src/notificationmonitor.cpp b/src/notificationmonitor.cpp index 50b2e3e..c937b02 100644 --- a/src/notificationmonitor.cpp +++ b/src/notificationmonitor.cpp @@ -1,7 +1,9 @@ #include <QtCore/QDebug> +#include <QtGui/QIcon> #include <QtDBus/QDBusConnection> #include <QtDBus/QDBusConnectionInterface> #include "notificationmonitor.h" +#include "notifications_adaptor.h" static NotificationMonitor *global_monitor = 0; @@ -12,6 +14,8 @@ NotificationMonitor::NotificationMonitor(QObject *parent) : QDBusConnectionInterface *dbus = bus.interface(); dbus->call("AddMatch", "interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'"); + new NotificationsAdaptor(this); + bus.registerObject("/org/freedesktop/Notifications", this); } NotificationMonitor::~NotificationMonitor() @@ -29,3 +33,22 @@ NotificationMonitor *NotificationMonitor::instance() } return global_monitor; } + +void NotificationMonitor::Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expire_timeout) +{ + qDebug() << "Got notification" << app_name << app_icon << summary << body; + QIcon icon; + + if (app_icon.startsWith("/")) { + icon = QIcon(app_icon); + } else if (app_icon.startsWith("file:")) { + QUrl url(app_icon); + icon = QIcon(url.toLocalFile()); + } else { + icon = QIcon::fromTheme(app_icon); + } + + qDebug() << "Icon:" << icon.availableSizes(); + + emit incomingNotification(app_name, icon, summary, body); +} diff --git a/src/notificationmonitor.h b/src/notificationmonitor.h index e8b6501..cfa0e17 100644 --- a/src/notificationmonitor.h +++ b/src/notificationmonitor.h @@ -3,8 +3,6 @@ #include <QtCore/QObject> -#include "notification.h" - class NotificationMonitor : public QObject { Q_OBJECT @@ -14,8 +12,15 @@ public: static NotificationMonitor *instance(); +signals: + void incomingNotification(const QString &sender, const QIcon &icon, const QString &summary, const QString &body); + private: explicit NotificationMonitor(QObject *parent = 0); + +private slots: + friend class NotificationsAdaptor; + void Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expire_timeout); }; #endif // NOTIFICATIONMONITOR_H diff --git a/src/org.freedesktop.Notifications.xml b/src/org.freedesktop.Notifications.xml new file mode 100644 index 0000000..456fd42 --- /dev/null +++ b/src/org.freedesktop.Notifications.xml @@ -0,0 +1,17 @@ +<!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="org.freedesktop.Notifications"> + <!-- (Partial) Desktop Notification Specification interface --> + <method name="Notify"> + <arg name="app_name" type="s" direction="in"/> + <arg name="replaces_id" type="u" direction="in"/> + <arg name="app_icon" type="s" direction="in"/> + <arg name="summary" type="s" direction="in"/> + <arg name="body" type="s" direction="in"/> + <arg name="actions" type="as" direction="in"/> + <arg name="hints" type="a{sv}" direction="in"/> + <arg name="expire_timeout" type="i" direction="in"/> + <!-- Not needed for eavesdropping: <arg name="id" type="u" direction="out"/> --> + <annotation name="org.qtproject.QtDBus.QtTypeName.In6" value="QVariantHash"/> + </method> +</node> diff --git a/src/salmeta.cpp b/src/salmeta.cpp index 46e4e89..914f117 100644 --- a/src/salmeta.cpp +++ b/src/salmeta.cpp @@ -1,4 +1,5 @@ #include <QtCore/QDebug> +#include <QtGui/QFontDatabase> #include <sailfishapp.h> #include "controller.h" @@ -29,6 +30,13 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType<WidgetInfo>("com.javispedro.salmeta", 1, 0, "WidgetInfo", "Use the models, not this"); + QFontDatabase::addApplicationFont(SailfishApp::pathTo("qml/watch/metawatch_8pt_5pxl_CAPS.ttf").toLocalFile()); + QFontDatabase::addApplicationFont(SailfishApp::pathTo("qml/watch/metawatch_8pt_5pxl_Numerals.ttf").toLocalFile()); + QFontDatabase::addApplicationFont(SailfishApp::pathTo("qml/watch/metawatch_8pt_6pxl_Numerals.ttf").toLocalFile()); + QFontDatabase::addApplicationFont(SailfishApp::pathTo("qml/watch/metawatch_8pt_7pxl_CAPS.ttf").toLocalFile()); + QFontDatabase::addApplicationFont(SailfishApp::pathTo("qml/watch/metawatch_16pt_11pxl.ttf").toLocalFile()); + QFontDatabase::addApplicationFont(SailfishApp::pathTo("qml/watch/MetaWatch-Large-16pt-Sync.ttf").toLocalFile()); + if (launch_daemon) { qDebug() << "Starting salmeta (daemon) with settings from" << settings_key_prefix; |