From 7af21fdd59af3b3112cff69996301605859af84c Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Thu, 9 Jul 2015 10:30:11 +0200
Subject: Create notice events for incoming file-transfers

Test-Information:

Send a file from one Swift instance to another. The UX is similar to
that of a MUC invite, clicking the notice will bring the relevant chat
in front.

Change-Id: Ief3cd7371ae01b2b38b6d1af36189df961eacef4

diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 7595d44..f39f503 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -61,6 +61,7 @@
 #include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
 #include <Swift/Controllers/WhiteboardManager.h>
 #include <Swift/Controllers/XMPPEvents/EventController.h>
+#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
 
 BOOST_CLASS_VERSION(Swift::ChatListWindow::Chat, 1)
 
@@ -929,6 +930,9 @@ void ChatsManager::handleNewFileTransferController(FileTransferController* ftc)
 	ChatController* chatController = getChatControllerOrCreate(ftc->getOtherParty());
 	chatController->handleNewFileTransferController(ftc);
 	chatController->activateChatWindow();
+	if (ftc->isIncoming()) {
+		eventController_->handleIncomingEvent(boost::make_shared<IncomingFileTransferEvent>(ftc->getOtherParty()));
+	}
 }
 
 void ChatsManager::handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf) {
diff --git a/Swift/Controllers/XMPPEvents/EventController.cpp b/Swift/Controllers/XMPPEvents/EventController.cpp
index 1561905..bbe7356 100644
--- a/Swift/Controllers/XMPPEvents/EventController.cpp
+++ b/Swift/Controllers/XMPPEvents/EventController.cpp
@@ -1,20 +1,23 @@
 /*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
 #include <Swift/Controllers/XMPPEvents/EventController.h>
 
+#include <algorithm>
+
 #include <boost/bind.hpp>
 #include <boost/numeric/conversion/cast.hpp>
-#include <algorithm>
 
 #include <Swiften/Base/foreach.h>
-#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
+
 #include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
-#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
+#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
 #include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
+#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
+#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
 
 namespace Swift {
 
@@ -32,6 +35,7 @@ void EventController::handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceE
 	boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(sourceEvent);
 	boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(sourceEvent);
 	boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(sourceEvent);
+	boost::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(sourceEvent);
 
 	/* If it's a duplicate subscription request, remove the previous request first */
 	if (subscriptionEvent) {
@@ -46,7 +50,7 @@ void EventController::handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceE
 		}
 	}
 
-	if ((messageEvent && messageEvent->isReadable()) || subscriptionEvent || errorEvent || mucInviteEvent) {
+	if ((messageEvent && messageEvent->isReadable()) || subscriptionEvent || errorEvent || mucInviteEvent || incomingFileTransferEvent) {
 		events_.push_back(sourceEvent);
 		sourceEvent->onConclusion.connect(boost::bind(&EventController::handleEventConcluded, this, sourceEvent));
 		onEventQueueLengthChange(boost::numeric_cast<int>(events_.size()));
diff --git a/Swift/Controllers/XMPPEvents/EventController.h b/Swift/Controllers/XMPPEvents/EventController.h
index 026d03e..35938ac 100644
--- a/Swift/Controllers/XMPPEvents/EventController.h
+++ b/Swift/Controllers/XMPPEvents/EventController.h
@@ -1,25 +1,24 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
-#ifndef SWIFTEN_EventController_H
-#define SWIFTEN_EventController_H
+#pragma once
 
+#include <vector>
 
-#include "Swiften/Base/boost_bsignals.h"
 #include <boost/shared_ptr.hpp>
-#include <vector>
 
-#include "Swift/Controllers/XMPPEvents/StanzaEvent.h"
-#include "Swift/Controllers/XMPPEvents/MessageEvent.h"
+#include <Swiften/Base/boost_bsignals.h>
+
+#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
 
 namespace Swift {
 	typedef std::vector<boost::shared_ptr<StanzaEvent> > EventList;
 	class EventController {
 		public:
-
 			EventController();
 			~EventController();
 
@@ -35,6 +34,3 @@ namespace Swift {
 			EventList events_;
 	};
 }
-#endif
-
-
diff --git a/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h b/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h
new file mode 100644
index 0000000..24af640
--- /dev/null
+++ b/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
+
+namespace Swift {
+	class IncomingFileTransferEvent : public StanzaEvent {
+		public:
+			typedef boost::shared_ptr<IncomingFileTransferEvent> ref;
+
+			IncomingFileTransferEvent(const JID& sender) : sender_(sender) {}
+
+			const JID& getSender() const {
+				return sender_;
+			}
+
+		private:
+			JID sender_;
+	};
+}
+
diff --git a/Swift/QtUI/EventViewer/EventDelegate.cpp b/Swift/QtUI/EventViewer/EventDelegate.cpp
index 7bbfee2..cd657b8 100644
--- a/Swift/QtUI/EventViewer/EventDelegate.cpp
+++ b/Swift/QtUI/EventViewer/EventDelegate.cpp
@@ -1,21 +1,27 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
-#include "EventDelegate.h"
+#include <Swift/QtUI/EventViewer/EventDelegate.h>
 
 #include <QDebug>
 
-#include "Swift/Controllers/XMPPEvents/MessageEvent.h"
-#include "Swift/Controllers/XMPPEvents/ErrorEvent.h"
-#include "Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h"
-#include "Swift/Controllers/XMPPEvents/MUCInviteEvent.h"
+#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
+#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
+#include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
+#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
+#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
 
 namespace Swift {
 
-EventDelegate::EventDelegate() : QStyledItemDelegate(), messageDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false), subscriptionDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true), errorDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true), mucInviteDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false) {
+EventDelegate::EventDelegate() : QStyledItemDelegate(),
+	messageDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false),
+	subscriptionDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true),
+	errorDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true),
+	mucInviteDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false),
+	incomingFileTransferDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false) {
 
 }
 
@@ -29,6 +35,7 @@ QSize EventDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIn
 		case SubscriptionEventType: return subscriptionDelegate_.sizeHint(option, item);
 		case ErrorEventType: return errorDelegate_.sizeHint(option, item);
 		case MUCInviteEventType: return mucInviteDelegate_.sizeHint(option, item);
+		case IncomingFileTransferEventType: return incomingFileTransferDelegate_.sizeHint(option, item);
 	}
 	assert(false);
 	return QSize();
@@ -45,6 +52,7 @@ void EventDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
 		case SubscriptionEventType: subscriptionDelegate_.paint(painter, option, item);break;
 		case ErrorEventType: errorDelegate_.paint(painter, option, item);break;
 		case MUCInviteEventType: mucInviteDelegate_.paint(painter, option, item);break;
+		case IncomingFileTransferEventType: incomingFileTransferDelegate_.paint(painter, option, item);break;
 	}
 }
 
@@ -65,6 +73,10 @@ EventType EventDelegate::getEventType(boost::shared_ptr<StanzaEvent> event) cons
 	if (mucInviteEvent) {
 		return MUCInviteEventType;
 	}
+	boost::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event);
+	if (incomingFileTransferEvent) {
+		return IncomingFileTransferEventType;
+	}
 	//I don't know what this is.
 	assert(false);
 	return MessageEventType;
diff --git a/Swift/QtUI/EventViewer/EventDelegate.h b/Swift/QtUI/EventViewer/EventDelegate.h
index f5dd196..6ab96e4 100644
--- a/Swift/QtUI/EventViewer/EventDelegate.h
+++ b/Swift/QtUI/EventViewer/EventDelegate.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -8,11 +8,11 @@
 
 #include <QStyledItemDelegate>
 
-#include "Swift/QtUI/Roster/DelegateCommons.h"
-#include "Swift/QtUI/EventViewer/TwoLineDelegate.h"
+#include <Swift/QtUI/EventViewer/TwoLineDelegate.h>
+#include <Swift/QtUI/Roster/DelegateCommons.h>
 
 namespace Swift {
-	enum EventType {MessageEventType, SubscriptionEventType, ErrorEventType, MUCInviteEventType};
+	enum EventType {MessageEventType, SubscriptionEventType, ErrorEventType, MUCInviteEventType, IncomingFileTransferEventType};
 	class EventDelegate : public QStyledItemDelegate {
 		Q_OBJECT
 		public:
@@ -26,6 +26,7 @@ namespace Swift {
 			TwoLineDelegate subscriptionDelegate_;
 			TwoLineDelegate errorDelegate_;
 			TwoLineDelegate mucInviteDelegate_;
+			TwoLineDelegate incomingFileTransferDelegate_;
 	};
 }
 
diff --git a/Swift/QtUI/EventViewer/QtEvent.cpp b/Swift/QtUI/EventViewer/QtEvent.cpp
index a84a440..4d90bd9 100644
--- a/Swift/QtUI/EventViewer/QtEvent.cpp
+++ b/Swift/QtUI/EventViewer/QtEvent.cpp
@@ -1,18 +1,19 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
-#include "Swift/QtUI/EventViewer/QtEvent.h"
+#include <Swift/QtUI/EventViewer/QtEvent.h>
 
-#include <QDateTime>
 #include <QColor>
+#include <QDateTime>
 
-#include "Swift/Controllers/XMPPEvents/MessageEvent.h"
-#include "Swift/Controllers/XMPPEvents/ErrorEvent.h"
-#include "Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h"
-#include "Swift/Controllers/XMPPEvents/MUCInviteEvent.h"
+#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
+#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
+#include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
+#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
+#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
 
 #include "Swift/QtUI/QtSwiftUtil.h"
 
@@ -53,6 +54,10 @@ QString QtEvent::sender() {
 	if (mucInviteEvent) {
 		return P2QSTRING(mucInviteEvent->getInviter().toString());
 	}
+	boost::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event_);
+	if (incomingFTEvent) {
+		return P2QSTRING(incomingFTEvent->getSender().toString());
+	}
 	return "";
 }
 
@@ -82,6 +87,11 @@ QString QtEvent::text() {
 		QString message = QString(QObject::tr("%1 has invited you to enter the %2 room.")).arg(P2QSTRING(mucInviteEvent->getInviter().toBare().toString())).arg(P2QSTRING(mucInviteEvent->getRoomJID().toString()));
 		return message;
 	}
+	boost::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event_);
+	if (incomingFTEvent) {
+		QString message = QString(QObject::tr("%1 would like to send a file to you.")).arg(P2QSTRING(incomingFTEvent->getSender().toBare().toString()));
+		return message;
+	}
 	return "";
 }
 
diff --git a/Swift/QtUI/EventViewer/QtEventWindow.cpp b/Swift/QtUI/EventViewer/QtEventWindow.cpp
index 3072497..f92cd07 100644
--- a/Swift/QtUI/EventViewer/QtEventWindow.cpp
+++ b/Swift/QtUI/EventViewer/QtEventWindow.cpp
@@ -1,27 +1,27 @@
-
 /*
  * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
-#include "Swift/QtUI/EventViewer/QtEventWindow.h"
+#include <Swift/QtUI/EventViewer/QtEventWindow.h>
 
-#include <QtDebug>
 #include <QBoxLayout>
-#include <QPushButton>
 #include <QMessageBox>
+#include <QPushButton>
+#include <QtDebug>
 
-#include "Swift/Controllers/XMPPEvents/MessageEvent.h"
-#include "Swift/Controllers/XMPPEvents/ErrorEvent.h"
-#include "Swift/QtUI/QtSubscriptionRequestWindow.h"
-#include "Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h"
-#include "Swift/Controllers/XMPPEvents/MUCInviteEvent.h"
-#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
-#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
+#include <Swiften/Base/Platform.h>
 
+#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
+#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
+#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
+#include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
+#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
+#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
 
-#include "Swiften/Base/Platform.h"
+#include <Swift/QtUI/QtSubscriptionRequestWindow.h>
 
 namespace Swift {
 
@@ -76,6 +76,7 @@ void QtEventWindow::handleItemActivated(const QModelIndex& item) {
 	boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event->getEvent());
 	boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event->getEvent());
 	boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event->getEvent());
+	boost::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event->getEvent());
 	boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event->getEvent());
 
 	if (messageEvent) {
@@ -90,6 +91,9 @@ void QtEventWindow::handleItemActivated(const QModelIndex& item) {
 	} else if (mucInviteEvent) {
 		eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(mucInviteEvent->getInviter())));
 		mucInviteEvent->conclude();
+	} else if (incomingFTEvent) {
+		eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(incomingFTEvent->getSender())));
+		incomingFTEvent->conclude();
 	} else {
 		if (errorEvent) {
 			errorEvent->conclude();
-- 
cgit v0.10.2-6-g49f6