From a7a2f6124fd733926a0effe486cffee03bf9fde0 Mon Sep 17 00:00:00 2001
From: Mateusz Piekos <mateuszpiekos@gmail.com>
Date: Tue, 7 Aug 2012 19:52:36 +0200
Subject: "Chats" tab shows opened whiteboard sessions


diff --git a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
index 6ac8d4a..5bbd490 100644
--- a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
+++ b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
@@ -16,6 +16,8 @@ namespace Swift {
 			virtual ~MockChatListWindow() {};
 			void addMUCBookmark(const MUCBookmark& /*bookmark*/) {}
 			void removeMUCBookmark(const MUCBookmark& /*bookmark*/) {}
+			void addWhiteboardSession(const ChatListWindow::Chat& /*chat*/) {};
+			void removeWhiteboardSession(const JID& /*jid*/) {};
 			void setBookmarksEnabled(bool /*enabled*/) {}
 			void setRecents(const std::list<ChatListWindow::Chat>& /*recents*/) {}
 			void setUnreadCount(int /*unread*/) {}
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index c1cc055..c9c4773 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -321,7 +321,7 @@ void MainController::handleConnected() {
 		userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_);
 		userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_);
 		adHocManager_ = new AdHocManager(JID(boundJID_.getDomain()), uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow());
-		whiteboardManager_ = new WhiteboardManager(uiFactory_, uiEventStream_, client_->getNickResolver(), client_->getWhiteboardSessionManager());
+		whiteboardManager_ = new WhiteboardManager(uiFactory_, uiFactory_, uiEventStream_, client_->getNickResolver(), client_->getAvatarManager(), client_->getWhiteboardSessionManager());
 	}
 	loginWindow_->setIsLoggingIn(false);
 
diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.h b/Swift/Controllers/UIInterfaces/ChatListWindow.h
index d047f8c..cb55bb3 100644
--- a/Swift/Controllers/UIInterfaces/ChatListWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatListWindow.h
@@ -48,6 +48,8 @@ namespace Swift {
 
 			virtual void setBookmarksEnabled(bool enabled) = 0;
 			virtual void addMUCBookmark(const MUCBookmark& bookmark) = 0;
+			virtual void addWhiteboardSession(const ChatListWindow::Chat& chat) = 0;
+			virtual void removeWhiteboardSession(const JID& jid) = 0;
 			virtual void removeMUCBookmark(const MUCBookmark& bookmark) = 0;
 			virtual void setRecents(const std::list<Chat>& recents) = 0;
 			virtual void setUnreadCount(int unread) = 0;
@@ -55,6 +57,7 @@ namespace Swift {
 
 			boost::signal<void (const MUCBookmark&)> onMUCBookmarkActivated;
 			boost::signal<void (const Chat&)> onRecentActivated;
+			boost::signal<void (const JID&)> onWhiteboardActivated;
 			boost::signal<void ()> onClearRecentsRequested;
 	};
 }
diff --git a/Swift/Controllers/WhiteboardManager.cpp b/Swift/Controllers/WhiteboardManager.cpp
index 1aa238e..bb73ae3 100644
--- a/Swift/Controllers/WhiteboardManager.cpp
+++ b/Swift/Controllers/WhiteboardManager.cpp
@@ -13,14 +13,20 @@
 #include <Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h>
 #include <Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h>
 #include <Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h>
+#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
 #include "Swiften/Client/NickResolver.h"
 #include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/Avatars/AvatarManager.h>
 #include <Swiften/Whiteboard/WhiteboardSessionManager.h>
 
 namespace Swift {
 	typedef std::pair<JID, WhiteboardWindow*> JIDWhiteboardWindowPair;
 
-	WhiteboardManager::WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager) : whiteboardWindowFactory_(whiteboardWindowFactory), uiEventStream_(uiEventStream), nickResolver_(nickResolver), whiteboardSessionManager_(whiteboardSessionManager) {
+	WhiteboardManager::WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, ChatListWindowFactory* chatListWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, AvatarManager* avatarManager, WhiteboardSessionManager* whiteboardSessionManager) : whiteboardWindowFactory_(whiteboardWindowFactory), uiEventStream_(uiEventStream), nickResolver_(nickResolver), avatarManager_(avatarManager), whiteboardSessionManager_(whiteboardSessionManager) {
+		chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_);
+		chatListWindow_->onWhiteboardActivated.connect(boost::bind(&WhiteboardManager::activateWindow, this, _1));
+		whiteboardSessionManager_->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccepted, this, _1));
+		whiteboardSessionManager_->onSessionTerminate.connect(boost::bind(&WhiteboardManager::handleSessionTerminated, this, _1));
 		uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&WhiteboardManager::handleUIEvent, this, _1));
 	}
 
@@ -66,10 +72,7 @@ namespace Swift {
 		}
 		boost::shared_ptr<ShowWhiteboardUIEvent> showWindowEvent = boost::dynamic_pointer_cast<ShowWhiteboardUIEvent>(event);
 		if (showWindowEvent) {
-			WhiteboardWindow* window = findWhiteboardWindow(showWindowEvent->getContact());
-			if (window != NULL) {
-				window->activateWindow();
-			}
+			activateWindow(showWindowEvent->getContact());
 		}
 	}
 
@@ -93,4 +96,25 @@ namespace Swift {
 			session->cancel();
 		}
 	}
+
+	void WhiteboardManager::handleSessionAccepted(const JID& from) {
+		boost::filesystem::path path;
+		JID bareJID = from.toBare();
+		if (avatarManager_) {
+			path = avatarManager_->getAvatarPath(bareJID);
+		}
+		ChatListWindow::Chat chat(bareJID, nickResolver_->jidToNick(bareJID), "", 0, StatusShow::None, path, false);
+ 		chatListWindow_->addWhiteboardSession(chat);
+	}
+
+	void WhiteboardManager::handleSessionTerminated(const JID& from) {
+		chatListWindow_->removeWhiteboardSession(from.toBare());
+	}
+
+	void WhiteboardManager::activateWindow(const JID& jid) {
+		WhiteboardWindow* window = findWhiteboardWindow(jid);
+		if (window != NULL) {
+			window->activateWindow();
+		}
+	}
 }
diff --git a/Swift/Controllers/WhiteboardManager.h b/Swift/Controllers/WhiteboardManager.h
index a2c75dd..98ee1cd 100644
--- a/Swift/Controllers/WhiteboardManager.h
+++ b/Swift/Controllers/WhiteboardManager.h
@@ -20,26 +20,34 @@
 
 namespace Swift {
 	class WhiteboardSessionManager;
+	class ChatListWindowFactory;
+	class ChatListWindow;
 	class NickResolver;
+	class AvatarManager;
 
 	class WhiteboardManager {
 	public:
-		WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager);
+		WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, ChatListWindowFactory* chatListWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, AvatarManager* avatarManager, WhiteboardSessionManager* whiteboardSessionManager);
 		~WhiteboardManager();
 
 		WhiteboardWindow* createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session);
 
 	private:
 		void handleUIEvent(boost::shared_ptr<UIEvent> event);
+		void handleSessionAccepted(const JID& from);
+		void handleSessionTerminated(const JID& from);
 		void acceptSession(const JID& from);
 		void cancelSession(const JID& from);
 		WhiteboardWindow* findWhiteboardWindow(const JID& contact);
+		void activateWindow(const JID& jid);
 
 	private:
 		std::map<JID, WhiteboardWindow*> whiteboardWindows_;
 		WhiteboardWindowFactory* whiteboardWindowFactory_;
+		ChatListWindow* chatListWindow_;
 		UIEventStream* uiEventStream_;
 		NickResolver* nickResolver_;
+		AvatarManager* avatarManager_;
 		boost::bsignals::scoped_connection uiEventConnection_;
 		WhiteboardSessionManager* whiteboardSessionManager_;
 	};
diff --git a/Swift/QtUI/ChatList/ChatListDelegate.cpp b/Swift/QtUI/ChatList/ChatListDelegate.cpp
index bcd1585..5b879df 100644
--- a/Swift/QtUI/ChatList/ChatListDelegate.cpp
+++ b/Swift/QtUI/ChatList/ChatListDelegate.cpp
@@ -12,6 +12,7 @@
 #include "Swift/QtUI/ChatList/ChatListItem.h"
 #include "Swift/QtUI/ChatList/ChatListMUCItem.h"
 #include "Swift/QtUI/ChatList/ChatListRecentItem.h"
+#include "Swift/QtUI/ChatList/ChatListWhiteboardItem.h"
 #include "Swift/QtUI/ChatList/ChatListGroupItem.h"
 
 namespace Swift {
@@ -38,6 +39,9 @@ QSize ChatListDelegate::sizeHint(const QStyleOptionViewItem& option, const QMode
 	}
 	else if (item && dynamic_cast<ChatListGroupItem*>(item)) {
 		return groupDelegate_->sizeHint(option, index);
+	}
+	else if (item && dynamic_cast<ChatListWhiteboardItem*>(item)) {
+		return common_.contactSizeHint(option, index, compact_);
 	} 
 	return QStyledItemDelegate::sizeHint(option, index);
 }
@@ -65,6 +69,9 @@ void ChatListDelegate::paint(QPainter* painter, const QStyleOptionViewItem& opti
 		ChatListGroupItem* group = dynamic_cast<ChatListGroupItem*>(item);
 		groupDelegate_->paint(painter, option, group->data(Qt::DisplayRole).toString(), group->rowCount(), option.state & QStyle::State_Open); 
 	}
+	else if (item && dynamic_cast<ChatListWhiteboardItem*>(item)) {
+		paintWhiteboard(painter, option, dynamic_cast<ChatListWhiteboardItem*>(item));
+	}
 	else {
 		QStyledItemDelegate::paint(painter, option, index);
 	}
@@ -116,4 +123,19 @@ void ChatListDelegate::paintRecent(QPainter* painter, const QStyleOptionViewItem
 	common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, item->getChat().unreadCount, compact_);
 }
 
+void ChatListDelegate::paintWhiteboard(QPainter* painter, const QStyleOptionViewItem& option, ChatListWhiteboardItem* item) const {
+	QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
+	QString avatarPath;
+	if (item->data(ChatListWhiteboardItem::AvatarRole).isValid() && !item->data(ChatListWhiteboardItem::AvatarRole).value<QString>().isNull()) {
+		avatarPath = item->data(ChatListWhiteboardItem::AvatarRole).value<QString>();
+	}
+	QIcon presenceIcon;/* = item->data(ChatListWhiteboardItem::PresenceIconRole).isValid() && !item->data(ChatListWhiteboardItem::PresenceIconRole).value<QIcon>().isNull()
+			? item->data(ChatListWhiteboardItem::PresenceIconRole).value<QIcon>()
+			: QIcon(":/icons/offline.png");*/
+	QString name = item->data(Qt::DisplayRole).toString();
+	//qDebug() << "Avatar for " << name << " = " << avatarPath;
+	QString statusText = item->data(ChatListWhiteboardItem::DetailTextRole).toString();
+	common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, item->getChat().unreadCount, compact_);
+}
+
 }
diff --git a/Swift/QtUI/ChatList/ChatListDelegate.h b/Swift/QtUI/ChatList/ChatListDelegate.h
index 5ac45ce..9460c28 100644
--- a/Swift/QtUI/ChatList/ChatListDelegate.h
+++ b/Swift/QtUI/ChatList/ChatListDelegate.h
@@ -13,6 +13,7 @@
 namespace Swift {
 	class ChatListMUCItem;
 	class ChatListRecentItem;
+	class ChatListWhiteboardItem;
 	class ChatListDelegate : public QStyledItemDelegate {
 		public:
 			ChatListDelegate(bool compact);
@@ -24,6 +25,7 @@ namespace Swift {
 		private:
 			void paintMUC(QPainter* painter, const QStyleOptionViewItem& option, ChatListMUCItem* item) const;
 			void paintRecent(QPainter* painter, const QStyleOptionViewItem& option, ChatListRecentItem* item) const;
+			void paintWhiteboard(QPainter* painter, const QStyleOptionViewItem& option, ChatListWhiteboardItem* item) const;
 			QSize mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
 			QSize recentSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
 
diff --git a/Swift/QtUI/ChatList/ChatListModel.cpp b/Swift/QtUI/ChatList/ChatListModel.cpp
index 681c1c2..15f4dfe 100644
--- a/Swift/QtUI/ChatList/ChatListModel.cpp
+++ b/Swift/QtUI/ChatList/ChatListModel.cpp
@@ -8,6 +8,7 @@
 
 #include <Swift/QtUI/ChatList/ChatListMUCItem.h>
 #include <Swift/QtUI/ChatList/ChatListRecentItem.h>
+#include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h>
 
 namespace Swift {
 
@@ -15,8 +16,10 @@ ChatListModel::ChatListModel() {
 	root_ = new ChatListGroupItem("", NULL, false);
 	mucBookmarks_ = new ChatListGroupItem(tr("Bookmarked Rooms"), root_);
 	recents_ = new ChatListGroupItem(tr("Recent Chats"), root_, false);
+	whiteboards_ = new ChatListGroupItem(tr("Opened Whiteboards"), root_, false);
 	root_->addItem(recents_);
 	root_->addItem(mucBookmarks_);
+	root_->addItem(whiteboards_);
 }
 
 void ChatListModel::clearBookmarks() {
@@ -46,11 +49,30 @@ void ChatListModel::removeMUCBookmark(const Swift::MUCBookmark& bookmark) {
 	}
 }
 
+void ChatListModel::addWhiteboardSession(const ChatListWindow::Chat& chat) {
+	emit layoutAboutToBeChanged();
+	whiteboards_->addItem(new ChatListWhiteboardItem(chat, whiteboards_));
+	emit layoutChanged();
+}
+
+void ChatListModel::removeWhiteboardSession(const JID& jid) {
+	for (int i = 0; i < whiteboards_->rowCount(); i++) {
+		ChatListWhiteboardItem* item = dynamic_cast<ChatListWhiteboardItem*>(whiteboards_->item(i));
+		if (item->getChat().jid == jid) {
+			emit layoutAboutToBeChanged();
+			whiteboards_->remove(i);
+			emit layoutChanged();
+			break;
+		}
+	}
+}
+
 void ChatListModel::setRecents(const std::list<ChatListWindow::Chat>& recents) {
 	emit layoutAboutToBeChanged();
 	recents_->clear();
 	foreach (const ChatListWindow::Chat chat, recents) {
 		recents_->addItem(new ChatListRecentItem(chat, recents_));
+//whiteboards_->addItem(new ChatListRecentItem(chat, whiteboards_));
 	}
 	emit layoutChanged();
 }
diff --git a/Swift/QtUI/ChatList/ChatListModel.h b/Swift/QtUI/ChatList/ChatListModel.h
index 8e7828c..e384a04 100644
--- a/Swift/QtUI/ChatList/ChatListModel.h
+++ b/Swift/QtUI/ChatList/ChatListModel.h
@@ -23,6 +23,8 @@ namespace Swift {
 			ChatListModel();
 			void addMUCBookmark(const MUCBookmark& bookmark);
 			void removeMUCBookmark(const MUCBookmark& bookmark);
+			void addWhiteboardSession(const ChatListWindow::Chat& chat);
+			void removeWhiteboardSession(const JID& jid);
 			int columnCount(const QModelIndex& parent = QModelIndex()) const;
 			QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
 			QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
@@ -34,6 +36,7 @@ namespace Swift {
 		private:
 			ChatListGroupItem* mucBookmarks_;
 			ChatListGroupItem* recents_;
+			ChatListGroupItem* whiteboards_;
 			ChatListGroupItem* root_;
 	};
 
diff --git a/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp b/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp
new file mode 100644
index 0000000..41648b6
--- /dev/null
+++ b/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 Mateusz Piękos
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+	ChatListWhiteboardItem::ChatListWhiteboardItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent) : ChatListItem(parent), chat_(chat) {
+
+	}
+
+	const ChatListWindow::Chat& ChatListWhiteboardItem::getChat() const {
+		return chat_;
+	}
+
+	QVariant ChatListWhiteboardItem::data(int role) const {
+		switch (role) {
+		case Qt::DisplayRole: return P2QSTRING(chat_.chatName);
+		case DetailTextRole: return P2QSTRING(chat_.activity);
+			/*case Qt::TextColorRole: return textColor_;
+			  case Qt::BackgroundColorRole: return backgroundColor_;
+			  case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant();
+			  case StatusTextRole: return statusText_;*/
+		case AvatarRole: return QVariant(QString(chat_.avatarPath.string().c_str()));
+		case PresenceIconRole: return getPresenceIcon();
+		default: return QVariant();
+		}
+	}
+
+	QIcon ChatListWhiteboardItem::getPresenceIcon() const {
+		QString iconString;
+		switch (chat_.statusType) {
+	 	case StatusShow::Online: iconString = "online";break;
+	 	case StatusShow::Away: iconString = "away";break;
+	 	case StatusShow::XA: iconString = "away";break;
+	 	case StatusShow::FFC: iconString = "online";break;
+	 	case StatusShow::DND: iconString = "dnd";break;
+	 	case StatusShow::None: iconString = "offline";break;
+		}
+		return QIcon(":/icons/" + iconString + ".png");
+	}
+}
+
diff --git a/Swift/QtUI/ChatList/ChatListWhiteboardItem.h b/Swift/QtUI/ChatList/ChatListWhiteboardItem.h
new file mode 100644
index 0000000..2dc6255
--- /dev/null
+++ b/Swift/QtUI/ChatList/ChatListWhiteboardItem.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <QList>
+#include <QIcon>
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/MUC/MUCBookmark.h>
+#include <Swift/Controllers/UIInterfaces/ChatListWindow.h>
+
+#include <Swift/QtUI/ChatList/ChatListItem.h>
+
+namespace Swift {
+	class ChatListWhiteboardItem : public ChatListItem {
+		public:
+			enum RecentItemRoles {
+				DetailTextRole = Qt::UserRole,
+				AvatarRole = Qt::UserRole + 1,
+				PresenceIconRole = Qt::UserRole + 2/*,
+				StatusShowTypeRole = Qt::UserRole + 3*/
+			};
+			ChatListWhiteboardItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent);
+			const ChatListWindow::Chat& getChat() const;
+			QVariant data(int role) const;
+		private:
+			QIcon getPresenceIcon() const;
+			ChatListWindow::Chat chat_;
+	};
+}
diff --git a/Swift/QtUI/ChatList/QtChatListWindow.cpp b/Swift/QtUI/ChatList/QtChatListWindow.cpp
index 42eb43b..7561820 100644
--- a/Swift/QtUI/ChatList/QtChatListWindow.cpp
+++ b/Swift/QtUI/ChatList/QtChatListWindow.cpp
@@ -13,6 +13,7 @@
 
 #include <Swift/QtUI/ChatList/ChatListMUCItem.h>
 #include <Swift/QtUI/ChatList/ChatListRecentItem.h>
+#include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h>
 #include <Swift/QtUI/QtAddBookmarkWindow.h>
 #include <Swift/QtUI/QtEditBookmarkWindow.h>
 #include <Swift/QtUI/QtUISettingConstants.h>
@@ -97,6 +98,11 @@ void QtChatListWindow::handleItemActivated(const QModelIndex& index) {
 			onRecentActivated(recentItem->getChat());
 		}
 	}
+	else if (ChatListWhiteboardItem* whiteboardItem = dynamic_cast<ChatListWhiteboardItem*>(item)) {
+		if (!whiteboardItem->getChat().isMUC || bookmarksEnabled_) {
+			onWhiteboardActivated(whiteboardItem->getChat().jid);
+		}
+	}
 }
 
 void QtChatListWindow::clearBookmarks() {
@@ -111,6 +117,14 @@ void QtChatListWindow::removeMUCBookmark(const MUCBookmark& bookmark) {
 	model_->removeMUCBookmark(bookmark);
 }
 
+void QtChatListWindow::addWhiteboardSession(const ChatListWindow::Chat& chat) {
+	model_->addWhiteboardSession(chat);
+}
+
+void QtChatListWindow::removeWhiteboardSession(const JID& jid) {
+	model_->removeWhiteboardSession(jid);
+}
+
 void QtChatListWindow::setRecents(const std::list<ChatListWindow::Chat>& recents) {
 	model_->setRecents(recents);
 }
diff --git a/Swift/QtUI/ChatList/QtChatListWindow.h b/Swift/QtUI/ChatList/QtChatListWindow.h
index 33131ce..ef4ce0f 100644
--- a/Swift/QtUI/ChatList/QtChatListWindow.h
+++ b/Swift/QtUI/ChatList/QtChatListWindow.h
@@ -22,6 +22,8 @@ namespace Swift {
 			virtual ~QtChatListWindow();
 			void addMUCBookmark(const MUCBookmark& bookmark);
 			void removeMUCBookmark(const MUCBookmark& bookmark);
+			void addWhiteboardSession(const ChatListWindow::Chat& chat);
+			void removeWhiteboardSession(const JID& jid);
 			void setBookmarksEnabled(bool enabled);
 			void setRecents(const std::list<ChatListWindow::Chat>& recents);
 			void setUnreadCount(int unread);
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 5b70fc9..0ffe2fe 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -127,6 +127,7 @@ sources = [
     "ChatList/ChatListDelegate.cpp",
     "ChatList/ChatListMUCItem.cpp",
     "ChatList/ChatListRecentItem.cpp",
+    "ChatList/ChatListWhiteboardItem.cpp",
     "MUCSearch/QtMUCSearchWindow.cpp",
     "MUCSearch/MUCSearchModel.cpp",
     "MUCSearch/MUCSearchRoomItem.cpp",
diff --git a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp
index ae69a9d..d0da375 100644
--- a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp
+++ b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp
@@ -23,6 +23,7 @@ namespace Swift {
 		boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionAccept);
 		boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_);
 		request->send();
+		onRequestAccepted(toJID_);
 	}
 
 	std::string IncomingWhiteboardSession::getClientID() const {
diff --git a/Swiften/Whiteboard/WhiteboardSession.h b/Swiften/Whiteboard/WhiteboardSession.h
index abfdd32..1b5d93f 100644
--- a/Swiften/Whiteboard/WhiteboardSession.h
+++ b/Swiften/Whiteboard/WhiteboardSession.h
@@ -44,7 +44,6 @@ namespace Swift {
 
 	private:
 		virtual void handleIncomingOperation(WhiteboardOperation::ref operation) = 0;
-		//virtual void handleSendOperationRequest(WhiteboardOperation::ref operation) = 0;
 
 	protected:
 		void sendPayload(boost::shared_ptr<WhiteboardPayload> payload);
diff --git a/Swiften/Whiteboard/WhiteboardSessionManager.cpp b/Swiften/Whiteboard/WhiteboardSessionManager.cpp
index a3985be..effdc4b 100644
--- a/Swiften/Whiteboard/WhiteboardSessionManager.cpp
+++ b/Swiften/Whiteboard/WhiteboardSessionManager.cpp
@@ -63,6 +63,7 @@ namespace Swift {
 		sessions_[session->getTo().toBare()] = session;
 		session->onSessionTerminateReceived.connect(boost::bind(&WhiteboardSessionManager::handleSessionTerminate, this, _1));
 		session->onSessionCancelled.connect(boost::bind(&WhiteboardSessionManager::handleSessionCancel, this, _1));
+		session->onRequestAccepted.connect(boost::bind(&WhiteboardSessionManager::handleSessionAccept, this, _1));
 		onSessionRequest(session->getTo(), false);
 	}
 
-- 
cgit v0.10.2-6-g49f6