From 6662f40aff76e0700d82237261774758981bf784 Mon Sep 17 00:00:00 2001
From: Javier <dev.git@javispedro.com>
Date: Tue, 21 Apr 2015 00:47:30 +0200
Subject: forward some types of notification icons

---
 saltoqd/cardmanager.cpp         | 37 +++++++++++++++++++++++++++++++++++++
 saltoqd/cardmanager.h           | 17 ++++++++++++++++-
 saltoqd/cardmanageradaptor.cpp  | 20 ++++++++++++++++++++
 saltoqd/cardmanageradaptor.h    | 30 ++++++++++++++++++++++++++++++
 saltoqd/msolimageiohandler.cpp  | 26 ++++++++++++++++++++++++++
 saltoqd/msolimageiohandler.h    |  3 +++
 saltoqd/notificationmanager.cpp | 25 +++++++++++++++++++++++++
 saltoqd/notificationmanager.h   |  1 +
 saltoqd/notificationmonitor.cpp | 10 ++++++++++
 saltoqd/notificationmonitor.h   |  5 +++++
 saltoqd/obexconnection.cpp      |  4 +++-
 saltoqd/saltoqd.pro             |  6 ++++--
 saltoqd/toqmanageradaptor.cpp   | 10 +++-------
 13 files changed, 183 insertions(+), 11 deletions(-)
 create mode 100644 saltoqd/cardmanageradaptor.cpp
 create mode 100644 saltoqd/cardmanageradaptor.h

diff --git a/saltoqd/cardmanager.cpp b/saltoqd/cardmanager.cpp
index ab3a0bc..070a53c 100644
--- a/saltoqd/cardmanager.cpp
+++ b/saltoqd/cardmanager.cpp
@@ -1,4 +1,7 @@
+#include <QtCore/QFile>
 #include <QtCore/QRegularExpression>
+#include "msolimageiohandler.h"
+#include "cardmanageradaptor.h"
 #include "cardmanager.h"
 
 Card::Card(const QString &id, QObject *parent) :
@@ -64,6 +67,26 @@ void Card::setDateTime(const QDateTime &dt)
 	}
 }
 
+QString Card::icon() const
+{
+	return _icon;
+}
+
+void Card::setIcon(const QString &url)
+{
+	_icon = url;
+}
+
+QString Card::picture() const
+{
+	return _picture;
+}
+
+void Card::setPicture(const QString &url)
+{
+	_picture = url;
+}
+
 bool Card::isVibrate() const
 {
 	return _vibrate;
@@ -217,6 +240,10 @@ CardManager::CardManager(FmsManager *fms, ToqManager *toq) :
 	QObject(toq), _toq(toq), _fms(fms)
 {
 	_toq->setEndpointListener(ToqConnection::AppMessagingEndpoint, this);
+
+	new CardManagerAdaptor(this);
+	QDBusConnection::sessionBus().registerObject("/com/javispedro/saltoq/CardManager", this,
+												 QDBusConnection::ExportAdaptors | QDBusConnection::ExportChildObjects);
 }
 
 void CardManager::handleMessage(const ToqConnection::Message &msg)
@@ -274,6 +301,13 @@ void CardManager::uninstallDeck(CardDeck *deck)
 	disconnect(deck, 0, this, 0);
 }
 
+QString CardManager::sendImage(CardDeck *deck, const QString &iconName, const QImage &image)
+{
+	QString remoteFile = QString("/packages/%1/%2.img").arg(deck->package()).arg(iconName);
+	_fms->updateFile(remoteFile, convertImageToMsol(image));
+	return QString("fms:/%1.img").arg(iconName);
+}
+
 QString CardManager::escapeString(const QString &s)
 {
 	QString e(s);
@@ -300,6 +334,9 @@ QString CardManager::generateCardDescription(const QString &verb, Card *card) co
 	if (!card->info().isEmpty()) {
 		desc += QString("info = \"%1\", ").arg(escapeString(card->info()));
 	}
+	if (!card->icon().isEmpty()) {
+		desc += QString("icon = \"%1\", ").arg(escapeString(card->icon()));
+	}
 	if (!card->isVibrate()) {
 		desc += QString("suppressvibe = \"true\", ");
 	}
diff --git a/saltoqd/cardmanager.h b/saltoqd/cardmanager.h
index e4ffc2a..858c655 100644
--- a/saltoqd/cardmanager.h
+++ b/saltoqd/cardmanager.h
@@ -1,6 +1,7 @@
 #ifndef CARDMANAGER_H
 #define CARDMANAGER_H
 
+#include <QtGui/QImage>
 #include "fmsmanager.h"
 
 class CardManager;
@@ -15,10 +16,12 @@ class Card : public QObject
 	Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
 	Q_PROPERTY(QString info READ info WRITE setInfo NOTIFY infoChanged)
 	Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged)
-	// TODO card events, divider, icon, picture
+	Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
+	Q_PROPERTY(QString picture READ picture WRITE setPicture NOTIFY pictureChanged)
 	Q_PROPERTY(bool vibrate READ isVibrate WRITE setVibrate NOTIFY vibrateChanged)
 	Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
 	Q_PROPERTY(QStringList menuOptions READ menuOptions WRITE setMenuOptions NOTIFY menuOptionsChanged)
+	// TODO card events, divider
 	Q_PROPERTY(bool open READ isOpen NOTIFY openChanged)
 	Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged)
 
@@ -39,6 +42,12 @@ public:
 	QDateTime dateTime() const;
 	void setDateTime(const QDateTime &dt);
 
+	QString icon() const;
+	void setIcon(const QString &url);
+
+	QString picture() const;
+	void setPicture(const QString &url);
+
 	bool isVibrate() const;
 	void setVibrate(bool vibrate);
 
@@ -59,6 +68,8 @@ signals:
 	void titleChanged();
 	void infoChanged();
 	void dateTimeChanged();
+	void iconChanged();
+	void pictureChanged();
 	void vibrateChanged();
 	void textChanged();
 	void menuOptionsChanged();
@@ -73,6 +84,8 @@ private:
 	QString _title;
 	QString _info;
 	QDateTime _dateTime;
+	QString _icon;
+	QString _picture;
 	bool _vibrate;
 	QString _text;
 	QStringList _options;
@@ -131,6 +144,8 @@ public slots:
 	void installDeck(CardDeck *deck);
 	void uninstallDeck(CardDeck *deck);
 
+	QString sendImage(CardDeck *deck, const QString &iconName, const QImage &image);
+
 private:
 	static QString escapeString(const QString &s);
 	QString generateCardDescription(const QString &verb, Card * card) const;
diff --git a/saltoqd/cardmanageradaptor.cpp b/saltoqd/cardmanageradaptor.cpp
new file mode 100644
index 0000000..02ab4a8
--- /dev/null
+++ b/saltoqd/cardmanageradaptor.cpp
@@ -0,0 +1,20 @@
+#include "cardmanageradaptor.h"
+
+CardManagerAdaptor::CardManagerAdaptor(CardManager *parent)
+	: QDBusAbstractAdaptor(parent),
+	  _conn(QDBusConnection::sessionBus()),
+	  _mgr(parent)
+{
+	setAutoRelaySignals(true);
+}
+
+QDBusObjectPath CardManagerAdaptor::CreateDeck(const QString &application, const QDBusMessage &msg)
+{
+	QString sender = msg.service();
+	CardDeck *deck = new CardDeck(sender, application, _mgr);
+	QDBusObjectPath path("/com/javispedro/saltoq/CardManager/" + application);
+	deck->setObjectName(application);
+	_mgr->installDeck(deck);
+	_decks.insert(path, deck);
+	return path;
+}
diff --git a/saltoqd/cardmanageradaptor.h b/saltoqd/cardmanageradaptor.h
new file mode 100644
index 0000000..e0f613d
--- /dev/null
+++ b/saltoqd/cardmanageradaptor.h
@@ -0,0 +1,30 @@
+#ifndef CARDMANAGERADAPTOR_H
+#define CARDMANAGERADAPTOR_H
+
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusAbstractAdaptor>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusObjectPath>
+
+#include "cardmanager.h"
+
+class CardManagerAdaptor : public QDBusAbstractAdaptor
+{
+	Q_OBJECT
+	Q_CLASSINFO("D-Bus Interface", "com.javispedro.saltoq.CardManager")
+
+public:
+	explicit CardManagerAdaptor(CardManager *parent = 0);
+
+signals:
+
+public slots:
+	QDBusObjectPath CreateDeck(const QString &application, const QDBusMessage &msg);
+
+private:
+	QDBusConnection _conn;
+	CardManager *_mgr;
+	QHash<QDBusObjectPath, CardDeck*> _decks;
+};
+
+#endif // CARDMANAGERADAPTOR_H
diff --git a/saltoqd/msolimageiohandler.cpp b/saltoqd/msolimageiohandler.cpp
index c921c20..e6a9065 100644
--- a/saltoqd/msolimageiohandler.cpp
+++ b/saltoqd/msolimageiohandler.cpp
@@ -1,4 +1,5 @@
 #include <QtCore/QtEndian>
+#include <QtCore/QBuffer>
 #include <QtCore/QVariant>
 #include <QtCore/QDebug>
 #include <QtGui/QImage>
@@ -160,3 +161,28 @@ void MSOLImageIOHandler::setOption(ImageOption option, const QVariant &value)
 {
 
 }
+
+QByteArray convertImageToMsol(const QImage &img)
+{
+	MSOLImageIOHandler msolio;
+	QBuffer msolImg;
+	msolImg.open(QBuffer::WriteOnly);
+	msolio.setDevice(&msolImg);
+	if (!msolio.write(img)) {
+		return QByteArray();
+	}
+	return msolImg.data();
+}
+
+QImage convertMsolToImage(const QByteArray &msol)
+{
+	MSOLImageIOHandler msolio;
+	QBuffer msolImg;
+	QImage img;
+	msolImg.setData(msol);
+	msolImg.open(QBuffer::ReadOnly);
+	if (!msolio.read(&img)) {
+		return QImage();
+	}
+	return img;
+}
diff --git a/saltoqd/msolimageiohandler.h b/saltoqd/msolimageiohandler.h
index 992c68e..fbfb1b5 100644
--- a/saltoqd/msolimageiohandler.h
+++ b/saltoqd/msolimageiohandler.h
@@ -17,4 +17,7 @@ public:
 	void setOption(ImageOption option, const QVariant &value) Q_DECL_OVERRIDE;
 };
 
+QByteArray convertImageToMsol(const QImage &img);
+QImage convertMsolToImage(const QByteArray &msol);
+
 #endif // MSOLIMAGEIOHANDLER_H
diff --git a/saltoqd/notificationmanager.cpp b/saltoqd/notificationmanager.cpp
index 30414ce..35b5c00 100644
--- a/saltoqd/notificationmanager.cpp
+++ b/saltoqd/notificationmanager.cpp
@@ -1,3 +1,4 @@
+#include <QtCore/QFileInfo>
 #include "notificationmanager.h"
 #include "notificationmonitor.h"
 
@@ -29,6 +30,18 @@ void NotificationManager::handleNotification(MonitoredNotification *n)
 	card->setDateTime(n->timestamp());
 	card->setVibrate(true);
 
+	if (!n->icon().isEmpty()) {
+		QFileInfo imgFile(n->icon());
+		QImage img(imgFile.absoluteFilePath());
+		if (!img.isNull()) {
+			card->setIcon(_card->sendImage(_deck, imgFile.completeBaseName(), img.scaled(48, 48, Qt::KeepAspectRatio)));
+		} else {
+			qDebug() << "Could not read icon from notification: " << imgFile.absoluteFilePath();
+		}
+	}
+
+	connect(n, &MonitoredNotification::bodyChanged,
+			this, &NotificationManager::handleNotificationBodyChanged);
 	connect(n, &MonitoredNotification::closed,
 			this, &NotificationManager::handleClosedNotification);
 
@@ -36,6 +49,18 @@ void NotificationManager::handleNotification(MonitoredNotification *n)
 	_deck->insertCard(0, card);
 }
 
+void NotificationManager::handleNotificationBodyChanged()
+{
+	MonitoredNotification *n = static_cast<MonitoredNotification*>(sender());
+	uint notificationId = n->id();
+	Card *card = _cards.take(notificationId);
+	if (card) {
+		card->setText(n->body());
+	} else {
+		qDebug() << "Notification" << notificationId << "does not have an attached card";
+	}
+}
+
 void NotificationManager::handleClosedNotification()
 {
 	MonitoredNotification *n = static_cast<MonitoredNotification*>(sender());
diff --git a/saltoqd/notificationmanager.h b/saltoqd/notificationmanager.h
index ce27a7d..2e8398a 100644
--- a/saltoqd/notificationmanager.h
+++ b/saltoqd/notificationmanager.h
@@ -15,6 +15,7 @@ public:
 
 private slots:
 	void handleNotification(MonitoredNotification *n);
+	void handleNotificationBodyChanged();
 	void handleClosedNotification();
 
 private:
diff --git a/saltoqd/notificationmonitor.cpp b/saltoqd/notificationmonitor.cpp
index 83d9820..31f2dfa 100644
--- a/saltoqd/notificationmonitor.cpp
+++ b/saltoqd/notificationmonitor.cpp
@@ -133,6 +133,10 @@ QVariantHash parse_notify_call(DBusMessage *msg)
 	r.insert("summary", QString::fromUtf8(summary));
 	r.insert("body", QString::fromUtf8(body));
 
+	if (strlen(app_icon) > 0) {
+		r.insert("icon", QString::fromLocal8Bit(app_icon));
+	}
+
 	return r;
 }
 
@@ -277,6 +281,11 @@ void NotificationMonitor::processIncomingNotification(quint32 id, const QVariant
 			n->_body = s;
 			emit n->bodyChanged();
 		}
+		s = content["icon"].toString();
+		if (n->_icon != s) {
+			n->_icon = s;
+			emit n->iconChanged();
+		}
 		QDateTime dt = content["timestamp"].toDateTime();
 		if (dt.isValid() && n->_timestamp != dt) {
 			n->_timestamp = dt;
@@ -289,6 +298,7 @@ void NotificationMonitor::processIncomingNotification(quint32 id, const QVariant
 		n->_summary = content["summary"].toString();
 		n->_body = content["body"].toString();
 		n->_timestamp = content["timestamp"].toDateTime();
+		n->_icon = content["icon"].toString();
 
 		if (!n->_timestamp.isValid()) {
 			n->_timestamp = QDateTime::currentDateTime();
diff --git a/saltoqd/notificationmonitor.h b/saltoqd/notificationmonitor.h
index f617817..8a71b0b 100644
--- a/saltoqd/notificationmonitor.h
+++ b/saltoqd/notificationmonitor.h
@@ -4,6 +4,7 @@
 #include <QtCore/QObject>
 #include <QtCore/QMap>
 #include <QtCore/QDateTime>
+#include <QtGui/QIcon>
 
 class MonitoredNotification : public QObject
 {
@@ -13,6 +14,7 @@ class MonitoredNotification : public QObject
 	Q_PROPERTY(QString summary READ summary NOTIFY summaryChanged)
 	Q_PROPERTY(QString body READ body NOTIFY bodyChanged)
 	Q_PROPERTY(QDateTime timestamp READ timestamp NOTIFY timestampChanged)
+	Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)
 
 	explicit MonitoredNotification(QObject *parent = 0);
 
@@ -22,11 +24,13 @@ public:
 	inline QString summary() const { return _summary; }
 	inline QString body() const { return _body; }
 	inline QDateTime timestamp() const { return _timestamp; }
+	inline QString icon() const { return _icon; }
 
 signals:
 	void summaryChanged();
 	void bodyChanged();
 	void timestampChanged();
+	void iconChanged();
 
 	void closed(int reason);
 
@@ -38,6 +42,7 @@ private:
 	QString _summary;
 	QString _body;
 	QDateTime _timestamp;
+	QString _icon;
 };
 
 class NotificationMonitor : public QObject
diff --git a/saltoqd/obexconnection.cpp b/saltoqd/obexconnection.cpp
index 4b34dc3..40c373a 100644
--- a/saltoqd/obexconnection.cpp
+++ b/saltoqd/obexconnection.cpp
@@ -59,7 +59,9 @@ ObexTransfer * ObexConnection::put(const QString &name, const QByteArray &data)
 
 	_pending.push_back(transfer);
 
-	handleNextPending();
+	// Delay actual start of the transfer in order to give time for caller
+	// to connect to signals of the returned transfer object.
+	QMetaObject::invokeMethod(this, "handleNextPending", Qt::QueuedConnection);
 
 	return transfer;
 }
diff --git a/saltoqd/saltoqd.pro b/saltoqd/saltoqd.pro
index b154491..18322b0 100644
--- a/saltoqd/saltoqd.pro
+++ b/saltoqd/saltoqd.pro
@@ -27,7 +27,8 @@ SOURCES += main.cpp \
     settings.cpp \
     settingsmanager.cpp \
     toqmanageradaptor.cpp \
-    msolimageiohandler.cpp
+    msolimageiohandler.cpp \
+    cardmanageradaptor.cpp
 
 HEADERS += \
     toqconnection.h \
@@ -48,7 +49,8 @@ HEADERS += \
     settings.h \
     settingsmanager.h \
     toqmanageradaptor.h \
-    msolimageiohandler.h
+    msolimageiohandler.h \
+    cardmanageradaptor.h
 
 DBUS_INTERFACES += com.nokia.profiled.xml org.nemomobile.voicecall.VoiceCallManager.xml org.nemomobile.voicecall.VoiceCall.xml
 QDBUSXML2CPP_INTERFACE_HEADER_FLAGS = -i voicecallmanager.h
diff --git a/saltoqd/toqmanageradaptor.cpp b/saltoqd/toqmanageradaptor.cpp
index 5ec11c2..14cbc14 100644
--- a/saltoqd/toqmanageradaptor.cpp
+++ b/saltoqd/toqmanageradaptor.cpp
@@ -1,5 +1,4 @@
 #include <QtCore/QFile>
-#include <QtCore/QBuffer>
 #include <QtGui/QImage>
 
 #include "toqmanageradaptor.h"
@@ -45,15 +44,12 @@ void ToqManagerAdaptor::PutImage(const QString &localFile, const QString &remote
 		_conn.send(reply);
 		return;
 	}
-	MSOLImageIOHandler msolio;
-	QBuffer msolImg;
-	msolImg.open(QBuffer::WriteOnly);
-	msolio.setDevice(&msolImg);
-	if (!msolio.write(image)) {
+	QByteArray msol = convertImageToMsol(image);
+	if (msol.isEmpty()) {
 		QDBusMessage reply = msg.createErrorReply("com.javispedro.saltoq.InvalidImage", "Cannot convert this image");
 		_conn.send(reply);
 		return;
 	}
 
-	_fms->updateFile(remoteFile, msolImg.data());
+	_fms->updateFile(remoteFile, msol);
 }
-- 
cgit v1.2.3