From a28d92f3458218d6effbfdd9a42bf8fbe8b8aa72 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 26 Jul 2009 13:39:50 +0100
Subject: Begin to assage Swift model into Qt Model/View.


diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 6328156..2e08adb 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -1,7 +1,7 @@
 #include "QtChatWindow.h"
 #include "QtSwiftUtil.h"
-#include "QtTreeWidget.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidget.h"
+#include "Roster/QtTreeWidgetFactory.h"
 #include "QtChatView.h"
 #include "MessageSnippet.h"
 #include "SystemMessageSnippet.h"
diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp
index 927447c..47c943f 100644
--- a/Swift/QtUI/QtChatWindowFactory.cpp
+++ b/Swift/QtUI/QtChatWindowFactory.cpp
@@ -3,7 +3,7 @@
 #include "QtChatTabs.h"
 #include "QtChatWindow.h"
 #include "QtSwiftUtil.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidgetFactory.h"
 
 
 namespace Swift {
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index a9ffc51..fffd478 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -2,8 +2,8 @@
 
 #include "QtJoinMUCDialog.h"
 #include "QtSwiftUtil.h"
-#include "QtTreeWidgetFactory.h"
-#include "QtTreeWidget.h"
+#include "Roster/QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidget.h"
 #include "QtStatusWidget.h"
 
 #include <QBoxLayout>
diff --git a/Swift/QtUI/QtMainWindowFactory.cpp b/Swift/QtUI/QtMainWindowFactory.cpp
index 288d182..9594ade 100644
--- a/Swift/QtUI/QtMainWindowFactory.cpp
+++ b/Swift/QtUI/QtMainWindowFactory.cpp
@@ -1,6 +1,6 @@
 #include "QtMainWindowFactory.h"
 #include "QtMainWindow.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidgetFactory.h"
 
 namespace Swift {
 
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index e1fac9c..00efc17 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -3,7 +3,7 @@
 #include "QtLoginWindowFactory.h"
 #include "QtChatWindowFactory.h"
 #include "QtMainWindowFactory.h"
-#include "QtTreeWidgetFactory.h"
+#include "Roster/QtTreeWidgetFactory.h"
 #include "QtSystemTray.h"
 #include "QtSoundPlayer.h"
 
diff --git a/Swift/QtUI/QtTreeWidget.cpp b/Swift/QtUI/QtTreeWidget.cpp
deleted file mode 100644
index 66c653e..0000000
--- a/Swift/QtUI/QtTreeWidget.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "QtTreeWidget.h"
-
-#include "Swiften/Base/Platform.h"
-#include "Swiften/Roster/OpenChatRosterAction.h"
-
-namespace Swift {
-
-QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeWidget(parent) {
-	setHeaderHidden(true);
-#ifdef SWIFT_PLATFORM_MACOSX
-	setAlternatingRowColors(true);
-#endif
-	setAnimated(true);
-	setIndentation(0);
-  setRootIsDecorated(true);
-	connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(handleItemActivated(QTreeWidgetItem*, int)));
-}
-
-void QtTreeWidget::handleItemActivated(QTreeWidgetItem* item, int column) {
-	QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
-	if (qtItem) {
-		qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction()));
-	}
-}
-
-void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
-}
-
-}
diff --git a/Swift/QtUI/QtTreeWidget.h b/Swift/QtUI/QtTreeWidget.h
deleted file mode 100644
index e1d83de..0000000
--- a/Swift/QtUI/QtTreeWidget.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef SWIFT_QtTreeWidget_H
-#define SWIFT_QtTreeWidget_H
-
-#include <QTreeWidget>
-
-#include "Swiften/Roster/TreeWidgetFactory.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidget.h"
-
-namespace Swift {
-
-class QtTreeWidget : public QTreeWidget, public TreeWidget {
-	Q_OBJECT
-	public:
-		QtTreeWidget(QWidget* parent = 0);
-	
-	private slots:
-		void handleItemActivated(QTreeWidgetItem*, int);
-
-  private:
-    void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
-};
-
-}
-#endif
-
diff --git a/Swift/QtUI/QtTreeWidgetFactory.cpp b/Swift/QtUI/QtTreeWidgetFactory.cpp
deleted file mode 100644
index e69de29..0000000
diff --git a/Swift/QtUI/QtTreeWidgetFactory.h b/Swift/QtUI/QtTreeWidgetFactory.h
deleted file mode 100644
index e0140d2..0000000
--- a/Swift/QtUI/QtTreeWidgetFactory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef SWIFT_QtTreeWidgetFactory_H
-#define SWIFT_QtTreeWidgetFactory_H
-
-#include "Swiften/Roster/TreeWidgetFactory.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidget.h"
-
-namespace Swift {
-
-class QtTreeWidgetFactory : public TreeWidgetFactory {
-	public:
-		QtTreeWidgetFactory() {
-		}
-
-		TreeWidget* createTreeWidget() {
-			return new QtTreeWidget();
-		}
-
-		TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem* item) {
-			QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
-			assert(qtItem);
-			return new QtTreeWidgetItem(qtItem);
-		}
-
-		TreeWidgetItem* createTreeWidgetItem(TreeWidget* item) {
-			QtTreeWidget* qtItem = dynamic_cast<QtTreeWidget*>(item);
-			assert(qtItem);
-			return new QtTreeWidgetItem(qtItem);
-		}
-};
-
-}
-#endif
-
diff --git a/Swift/QtUI/QtTreeWidgetItem.cpp b/Swift/QtUI/QtTreeWidgetItem.cpp
deleted file mode 100644
index e69de29..0000000
diff --git a/Swift/QtUI/QtTreeWidgetItem.h b/Swift/QtUI/QtTreeWidgetItem.h
deleted file mode 100644
index 34ad93c..0000000
--- a/Swift/QtUI/QtTreeWidgetItem.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef SWIFT_QtTreeWidgetItem_H
-#define SWIFT_QtTreeWidgetItem_H
-
-#include <QColor>
-
-#include "Swiften/Base/String.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidgetItem.h"
-#include "Swift/QtUI/QtTreeWidget.h"
-#include "Swift/QtUI/QtSwiftUtil.h"
-
-namespace Swift {
-
-class QtTreeWidgetItem : public QTreeWidgetItem, public TreeWidgetItem {
-	public:
-		QtTreeWidgetItem(QTreeWidget* parent) : QTreeWidgetItem(parent) {
-		}
-
-		QtTreeWidgetItem(QTreeWidgetItem* parent) : QTreeWidgetItem(parent) {
-		}
-
-		void setText(const String& text) {
-			QTreeWidgetItem::setText(0, P2QSTRING(text));
-		}
-
-		void setTextColor(unsigned long color) {
-			QTreeWidgetItem::setTextColor(0, QColor(
-					((color & 0xFF0000)>>16),
-					((color & 0xFF00)>>8), 
-					(color & 0xFF)));
-		}
-
-		void setBackgroundColor(unsigned long color) {
-			QTreeWidgetItem::setBackgroundColor(0, QColor(
-					((color & 0xFF0000)>>16),
-					((color & 0xFF00)>>8), 
-					(color & 0xFF)));
-		}
-
-		void setExpanded(bool b) {
-			treeWidget()->setItemExpanded(this, b);
-		}
-
-		void hide() {
-			setHidden(true);
-		}
-
-		void show() {
-			setHidden(false);
-		}
-};
-
-}
-#endif
-
diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
new file mode 100644
index 0000000..d40169f
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -0,0 +1,37 @@
+#include "Roster/QtTreeWidget.h"
+
+#include "Swiften/Base/Platform.h"
+#include "Swiften/Roster/OpenChatRosterAction.h"
+
+namespace Swift {
+
+QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent), RosterItem(NULL) {
+	model_ = new RosterModel(this);
+    setModel(model_);
+    //setWindowTitle("A roster");
+    //show();
+	setHeaderHidden(true);
+#ifdef SWIFT_PLATFORM_MACOSX
+	setAlternatingRowColors(true);
+#endif
+	setAnimated(true);
+	setIndentation(0);
+	setRootIsDecorated(true);
+	connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(handleItemActivated(QTreeWidgetItem*, int)));
+}
+
+// void QtTreeWidget::handleItemActivated(QTreeWidgetItem* item, int column) {
+// 	QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
+// 	if (qtItem) {
+// 		qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction()));
+// 	}
+// }
+
+void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
+}
+
+void QtTreeWidget::show() {
+	QWidget::show();
+}
+
+}
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
new file mode 100644
index 0000000..f246e83
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -0,0 +1,32 @@
+#ifndef SWIFT_QtTreeWidget_H
+#define SWIFT_QtTreeWidget_H
+
+#include <QTreeView>
+
+#include "Swiften/Roster/TreeWidgetFactory.h"
+#include "Swiften/Roster/TreeWidget.h"
+#include "Swiften/Roster/TreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
+#include "Swift/QtUI/Roster/RosterModel.h"
+#include "Swift/QtUI/Roster/RosterItem.h"
+
+namespace Swift {
+
+class QtTreeWidget : public QTreeView, public TreeWidget, public RosterItem {
+	Q_OBJECT
+	public:
+		QtTreeWidget(QWidget* parent = 0);
+		void show();
+	//private slots:
+	//	void handleItemActivated(QTreeWidgetItem*, int);
+
+	private:
+		void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
+		RosterModel* model_;
+		
+};
+
+}
+#endif
+
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp b/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp
new file mode 100644
index 0000000..e69de29
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.h b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
new file mode 100644
index 0000000..353f697
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
@@ -0,0 +1,41 @@
+#ifndef SWIFT_QtTreeWidgetFactory_H
+#define SWIFT_QtTreeWidgetFactory_H
+
+#include "Swiften/Roster/TreeWidgetFactory.h"
+#include "Swiften/Roster/TreeWidget.h"
+#include "Swiften/Roster/TreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
+
+namespace Swift {
+
+class QtTreeWidgetFactory : public TreeWidgetFactory {
+	public:
+		QtTreeWidgetFactory() {
+		}
+
+		TreeWidget* createTreeWidget() {
+			return new QtTreeWidget();
+		}
+
+		TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem* item) {
+			QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
+			assert(qtItem);
+			QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
+			qtItem->addChild(newItem);
+			return newItem;
+		}
+
+		TreeWidgetItem* createTreeWidgetItem(TreeWidget* item) {
+			QtTreeWidget* qtItem = dynamic_cast<QtTreeWidget*>(item);
+			assert(qtItem);
+			QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
+			//qtItem->setItemWidget(newItem, 0, newItem->getCollapsedRosterWidget());
+			qtItem->addChild(newItem);
+			return newItem;
+		}
+};
+
+}
+#endif
+
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
new file mode 100644
index 0000000..f65c3bf
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -0,0 +1,17 @@
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
+namespace Swift {
+
+QWidget* QtTreeWidgetItem::getCollapsedRosterWidget() {
+	QWidget* widget = new QWidget();
+	
+	return widget;
+}
+
+QWidget* QtTreeWidgetItem::getExpandedRosterWidget() {
+	QWidget* widget = new QWidget();
+	
+	return widget;
+}
+
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
new file mode 100644
index 0000000..c35a840
--- /dev/null
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -0,0 +1,65 @@
+#ifndef SWIFT_QtTreeWidgetItem_H
+#define SWIFT_QtTreeWidgetItem_H
+
+#include <QColor>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Roster/TreeWidgetFactory.h"
+#include "Swiften/Roster/TreeWidget.h"
+#include "Swiften/Roster/TreeWidgetItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/QtUI/Roster/RosterItem.h"
+
+
+#include "Swift/QtUI/QtSwiftUtil.h"
+
+
+namespace Swift {
+class QtTreeWidget;
+class QtTreeWidgetItem : public TreeWidgetItem, public RosterItem {
+	public:
+		QtTreeWidgetItem(RosterItem* parentItem) : RosterItem(parentItem) {
+
+		}
+
+		void setText(const String& text) {
+			displayName_ = P2QSTRING(text);
+			// QTreeWidgetItem::setText(0, P2QSTRING(text));
+		}
+
+		void setTextColor(unsigned long color) {
+			// QTreeWidgetItem::setTextColor(0, QColor(
+			// 					((color & 0xFF0000)>>16),
+			// 					((color & 0xFF00)>>8), 
+			// 					(color & 0xFF)));
+		}
+
+		void setBackgroundColor(unsigned long color) {
+			// QTreeWidgetItem::setBackgroundColor(0, QColor(
+			// 					((color & 0xFF0000)>>16),
+			// 					((color & 0xFF00)>>8), 
+			// 					(color & 0xFF)));
+		}
+
+		void setExpanded(bool b) {
+			//treeWidget()->setItemExpanded(this, b);
+		}
+
+		void hide() {
+			//setHidden(true);
+		}
+
+		void show() {
+			//setHidden(false);
+		}
+		
+		QWidget* getCollapsedRosterWidget();
+		QWidget* getExpandedRosterWidget();
+		
+	private:
+		QString displayName_;
+};
+
+}
+#endif
+
diff --git a/Swift/QtUI/Roster/Roster.pri b/Swift/QtUI/Roster/Roster.pri
new file mode 100644
index 0000000..56ff472
--- /dev/null
+++ b/Swift/QtUI/Roster/Roster.pri
@@ -0,0 +1,12 @@
+SOURCES += $$PWD/RosterDelegate.cpp \
+	$$PWD/RosterItem.cpp \
+	$$PWD/RosterModel.cpp \
+	$$PWD/QtTreeWidget.cpp \
+	$$PWD/QtTreeWidgetItem.cpp 
+
+HEADERS += $$PWD/RosterDelegate.h \
+	$$PWD/RosterItem.h \
+	$$PWD/RosterModel.h \
+	$$PWD/QtTreeWidget.h \
+	$$PWD/QtTreeWidgetFactory.h \
+	$$PWD/QtTreeWidgetItem.h 
diff --git a/Swift/QtUI/Roster/Roster.pro b/Swift/QtUI/Roster/Roster.pro
new file mode 100644
index 0000000..c829d5c
--- /dev/null
+++ b/Swift/QtUI/Roster/Roster.pro
@@ -0,0 +1,12 @@
+include(Roster.pri)
+SOURCES += main.cpp
+
+DEPENDPATH += ../. ../../.. ../../../3rdParty/Boost
+INCLUDEPATH += ../. ../../.. ../../../3rdParty/Boost
+
+DEFINES += BOOST_SIGNALS_NAMESPACE=bsignals BOOST_ALL_NO_LIB
+
+exists(../config.pri) {
+	LIBS += ../../Controllers/Controllers.a ../../../Swiften/Swiften.a
+	include(../config.pri)
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
new file mode 100644
index 0000000..e69de29
diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h
new file mode 100644
index 0000000..e69de29
diff --git a/Swift/QtUI/Roster/RosterItem.cpp b/Swift/QtUI/Roster/RosterItem.cpp
new file mode 100644
index 0000000..14b4525
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterItem.cpp
@@ -0,0 +1,28 @@
+#include "RosterItem.h"
+
+namespace Swift {
+	
+RosterItem::RosterItem(RosterItem* parent) {
+	parent_ = parent;
+}
+
+RosterItem* RosterItem::getParentItem() {
+	return parent_;
+}
+
+void RosterItem::addChild(RosterItem* child) {
+	children_.append(child);
+}
+
+int RosterItem::rowCount() {
+	return children_.size();
+}
+
+int RosterItem::rowOf(RosterItem* item) {
+	return children_.indexOf(item);;
+}
+	
+RosterItem* RosterItem::getItem(int row) {
+	return children_[row];
+}
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterItem.h b/Swift/QtUI/Roster/RosterItem.h
new file mode 100644
index 0000000..f7cd804
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterItem.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <QList>
+
+namespace Swift {
+	class RosterItem {
+	public:
+		RosterItem(RosterItem* parent);
+		~RosterItem();
+		void addChild(RosterItem* child);
+		RosterItem* getParentItem();
+		int rowCount();
+		int rowOf(RosterItem* item);
+		RosterItem* getItem(int row);
+	private:
+		QList<RosterItem*> children_;
+		RosterItem* parent_;
+	};
+	
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
new file mode 100644
index 0000000..2c9a2cc
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -0,0 +1,56 @@
+#include "RosterModel.h"
+
+namespace Swift {
+
+RosterModel::RosterModel(RosterItem* tree) {
+	tree_ = tree;
+}
+
+RosterModel::~RosterModel() {
+	
+}
+
+int RosterModel::columnCount(const QModelIndex& parent) const {
+	Q_UNUSED(parent);
+	return 1;
+}
+
+QVariant RosterModel::data(const QModelIndex& index, int role) const {
+	if (!index.isValid()) {
+		return QVariant();
+	}
+	return QVariant("bob");
+}
+
+QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
+	RosterItem* parentItem = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : tree_;
+	Q_ASSERT(parentItem);
+	
+	return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
+}
+
+QModelIndex RosterModel::parent(const QModelIndex& index) const {
+	if (!index.isValid()) {
+		return QModelIndex();
+	}
+	
+	RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+	Q_ASSERT(item);
+
+	RosterItem* parentItem = item->getParentItem();
+	return parentItem == tree_ ? QModelIndex() : createIndex(parentItem->getParentItem()->rowOf(parentItem), 0, parentItem);
+
+}
+
+int RosterModel::rowCount(const QModelIndex& parent) const {
+	if (!parent.isValid()) {
+		return 0;
+	}
+	
+	RosterItem* item = static_cast<RosterItem*>(parent.internalPointer());
+	Q_ASSERT(item);
+	
+	return item->rowCount();
+}
+
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
new file mode 100644
index 0000000..a958f0d
--- /dev/null
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "Swift/QtUI/Roster/RosterItem.h"
+
+#include <QAbstractItemModel>
+#include <QList>
+
+namespace Swift {
+class RosterModel : public QAbstractItemModel {
+public:
+	RosterModel(RosterItem* tree);
+	~RosterModel();
+	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;
+	QModelIndex parent(const QModelIndex& index) const;
+	int rowCount(const QModelIndex& parent = QModelIndex()) const;
+private:
+	RosterItem* tree_;
+};
+
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/main.cpp b/Swift/QtUI/Roster/main.cpp
new file mode 100644
index 0000000..f3623ac
--- /dev/null
+++ b/Swift/QtUI/Roster/main.cpp
@@ -0,0 +1,31 @@
+#include <QtGui>
+#include "QtTreeWidget.h"
+#include "QtTreeWidgetFactory.h"
+
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+
+    //Swift::RosterModel model;
+
+    //QTreeView view;
+    //view.setModel(&model);
+    //view.setWindowTitle("A roster");
+    //view.show();
+
+	Swift::QtTreeWidgetFactory treeWidgetFactory;
+	Swift::QtTreeWidget* tree = dynamic_cast<Swift::QtTreeWidget*>(treeWidgetFactory.createTreeWidget());
+	Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
+	group->setText("People");
+	group->setBackgroundColor(0xBBBBBB);
+	Swift::QtTreeWidgetItem* item1 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+	Swift::QtTreeWidgetItem* item2 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+	Swift::QtTreeWidgetItem* item3 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+	Swift::QtTreeWidgetItem* item4 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+	item1->setText("Remko");
+	item2->setText("Kevin");
+	item3->setText("Cath");
+	item4->setText("Kim");
+	tree->show();
+    return app.exec();
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Swift.pro b/Swift/QtUI/Swift.pro
index 0af8216..7c36c07 100644
--- a/Swift/QtUI/Swift.pro
+++ b/Swift/QtUI/Swift.pro
@@ -55,9 +55,6 @@ HEADERS += \
 	QtSettingsProvider.h \
 	QtStatusWidget.h \
 	QtSwift.h \
-	QtTreeWidget.h \
-	QtTreeWidgetFactory.h \
-	QtTreeWidgetItem.h \
 	QtChatView.h \
 	QtChatTabs.h \
 	QtSoundPlayer.h \
@@ -79,7 +76,6 @@ SOURCES += \
 	QtSettingsProvider.cpp \
 	QtStatusWidget.cpp \
 	QtSwift.cpp \
-	QtTreeWidget.cpp \
 	QtChatView.cpp	\
 	QtChatTabs.cpp \
 	QtSoundPlayer.cpp \
@@ -91,6 +87,8 @@ SOURCES += \
 
 FORMS += QtJoinMUCDialog.ui
 
+include(Roster/Roster.pri)
+
 RESOURCES += Swift.qrc DefaultTheme.qrc
 
 win32 {
diff --git a/Swiften/Roster/Roster.cpp b/Swiften/Roster/Roster.cpp
index 61c0286..b51d8eb 100644
--- a/Swiften/Roster/Roster.cpp
+++ b/Swiften/Roster/Roster.cpp
@@ -39,7 +39,7 @@ GroupRosterItem* Roster::getGroup(const String& groupName) {
 	}
 	GroupRosterItem* group = new GroupRosterItem(groupName, treeWidget_, widgetFactory_);
 	children_.push_back(group);
-  items_.push_back(group);
+	items_.push_back(group);
 	return group;
 }
 
@@ -49,7 +49,7 @@ void Roster::handleUserAction(boost::shared_ptr<UserRosterAction> action) {
 
 void Roster::addContact(const JID& jid, const String& name, const String& group) {
 	ContactRosterItem *item = new ContactRosterItem(jid, name, getGroup(group), widgetFactory_);
-  items_.push_back(item);
+	items_.push_back(item);
 	item->onUserAction.connect(boost::bind(&Roster::handleUserAction, this, _1));
 	filterItem(item);
 
-- 
cgit v0.10.2-6-g49f6


From 3d6db73e834b745f2abadd04f8309d96f2b41b9c Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 26 Jul 2009 17:31:58 +0100
Subject: The new roster now renders (badly) the contents.


diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index d40169f..d37bb2a 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -5,10 +5,13 @@
 
 namespace Swift {
 
-QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent), RosterItem(NULL) {
-	model_ = new RosterModel(this);
+QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
+	treeRoot_ = new QtTreeWidgetItem(NULL);
+	model_ = new RosterModel();
+	model_->setRoot(treeRoot_);
     setModel(model_);
-    //setWindowTitle("A roster");
+	//FIXME: just a dummy title.
+    setWindowTitle("A roster");
     //show();
 	setHeaderHidden(true);
 #ifdef SWIFT_PLATFORM_MACOSX
@@ -17,7 +20,15 @@ QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent), RosterItem(NULL
 	setAnimated(true);
 	setIndentation(0);
 	setRootIsDecorated(true);
-	connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(handleItemActivated(QTreeWidgetItem*, int)));
+	//connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(handleItemActivated(QTreeWidgetItem*, int)));
+}
+
+QtTreeWidget::~QtTreeWidget() {
+	delete model_;
+}
+
+QtTreeWidgetItem* QtTreeWidget::getRoot() {
+	return treeRoot_;
 }
 
 // void QtTreeWidget::handleItemActivated(QTreeWidgetItem* item, int column) {
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
index f246e83..559f4e2 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.h
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -13,17 +13,19 @@
 
 namespace Swift {
 
-class QtTreeWidget : public QTreeView, public TreeWidget, public RosterItem {
+class QtTreeWidget : public QTreeView, public TreeWidget {
 	Q_OBJECT
 	public:
 		QtTreeWidget(QWidget* parent = 0);
+		~QtTreeWidget();
 		void show();
+		QtTreeWidgetItem* getRoot();
 	//private slots:
 	//	void handleItemActivated(QTreeWidgetItem*, int);
-
 	private:
 		void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
 		RosterModel* model_;
+		QtTreeWidgetItem* treeRoot_;
 		
 };
 
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.h b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
index 353f697..2ca1e21 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetFactory.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
@@ -27,8 +27,9 @@ class QtTreeWidgetFactory : public TreeWidgetFactory {
 		}
 
 		TreeWidgetItem* createTreeWidgetItem(TreeWidget* item) {
-			QtTreeWidget* qtItem = dynamic_cast<QtTreeWidget*>(item);
-			assert(qtItem);
+			QtTreeWidget* treeItem = dynamic_cast<QtTreeWidget*>(item);
+			assert(treeItem);
+			QtTreeWidgetItem* qtItem = treeItem->getRoot();
 			QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
 			//qtItem->setItemWidget(newItem, 0, newItem->getCollapsedRosterWidget());
 			qtItem->addChild(newItem);
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index c35a840..2a72a83 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -23,8 +23,7 @@ class QtTreeWidgetItem : public TreeWidgetItem, public RosterItem {
 		}
 
 		void setText(const String& text) {
-			displayName_ = P2QSTRING(text);
-			// QTreeWidgetItem::setText(0, P2QSTRING(text));
+			setName(P2QSTRING(text));
 		}
 
 		void setTextColor(unsigned long color) {
diff --git a/Swift/QtUI/Roster/Roster.pro b/Swift/QtUI/Roster/Roster.pro
index c829d5c..086ef41 100644
--- a/Swift/QtUI/Roster/Roster.pro
+++ b/Swift/QtUI/Roster/Roster.pro
@@ -9,4 +9,8 @@ DEFINES += BOOST_SIGNALS_NAMESPACE=bsignals BOOST_ALL_NO_LIB
 exists(../config.pri) {
 	LIBS += ../../Controllers/Controllers.a ../../../Swiften/Swiften.a
 	include(../config.pri)
+}
+
+mac {
+	DEFINES += SWIFT_PLATFORM_MACOSX
 }
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterItem.cpp b/Swift/QtUI/Roster/RosterItem.cpp
index 14b4525..b39a47c 100644
--- a/Swift/QtUI/Roster/RosterItem.cpp
+++ b/Swift/QtUI/Roster/RosterItem.cpp
@@ -1,28 +1,57 @@
 #include "RosterItem.h"
 
+#include <qdebug.h>
+
 namespace Swift {
 	
-RosterItem::RosterItem(RosterItem* parent) {
+RosterItem::RosterItem(RosterItem* parent) : QObject() {
 	parent_ = parent;
 }
 
+RosterItem::~RosterItem() {
+	qDeleteAll(children_);
+}
+
 RosterItem* RosterItem::getParentItem() {
 	return parent_;
 }
 
 void RosterItem::addChild(RosterItem* child) {
+	printf("Boing\n");
 	children_.append(child);
+	connect(child, SIGNAL(changed()), this, SIGNAL(changed()));
+	emit changed();
 }
 
 int RosterItem::rowCount() {
+	qDebug() << "Returning size of " << children_.size() << " for item " << name_;
 	return children_.size();
 }
 
 int RosterItem::rowOf(RosterItem* item) {
 	return children_.indexOf(item);;
 }
-	
+
+int RosterItem::row() {
+	return parent_ ? parent_->rowOf(this) : 0;
+}
+
 RosterItem* RosterItem::getItem(int row) {
+	qDebug() << "Returning row " << row << " from item " << name_;
 	return children_[row];
 }
+
+QVariant RosterItem::data(int role) {
+	if (role != Qt::DisplayRole) {
+		return QVariant();
+	}
+	qDebug() << "Returning name " << name_ << " for role " << role;
+	return name_;
+}
+
+void RosterItem::setName(QString name) {
+	name_ = name;
+	qDebug() << "Name changed to " << name;
+	changed();
+}
 }
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterItem.h b/Swift/QtUI/Roster/RosterItem.h
index f7cd804..e0041d2 100644
--- a/Swift/QtUI/Roster/RosterItem.h
+++ b/Swift/QtUI/Roster/RosterItem.h
@@ -1,9 +1,10 @@
 #pragma once
 
 #include <QList>
-
+#include <QVariant>
 namespace Swift {
-	class RosterItem {
+	class RosterItem : public QObject {
+	Q_OBJECT
 	public:
 		RosterItem(RosterItem* parent);
 		~RosterItem();
@@ -11,10 +12,16 @@ namespace Swift {
 		RosterItem* getParentItem();
 		int rowCount();
 		int rowOf(RosterItem* item);
+		int row();
 		RosterItem* getItem(int row);
+		QVariant data(int role);
+		void setName(QString name);
+	signals:
+		void changed();
 	private:
 		QList<RosterItem*> children_;
 		RosterItem* parent_;
+		QString name_;
 	};
 	
 }
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index 2c9a2cc..4c5954e 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -2,12 +2,25 @@
 
 namespace Swift {
 
-RosterModel::RosterModel(RosterItem* tree) {
-	tree_ = tree;
+RosterModel::RosterModel() {
 }
 
 RosterModel::~RosterModel() {
-	
+	delete tree_;
+}
+
+void RosterModel::setRoot(RosterItem* root) {
+	tree_ = root;
+	connect(tree_, SIGNAL(changed()), this, SLOT(handleItemChanged()));
+}
+							  
+
+void RosterModel::handleItemChanged() {
+	//FIXME: This is just a lazy hack to cause the view to refresh until it works.
+	// Then I'll replace it with the proper implementation.
+	printf("Changed\n");
+	reset();
+	emit layoutChanged();
 }
 
 int RosterModel::columnCount(const QModelIndex& parent) const {
@@ -16,10 +29,8 @@ int RosterModel::columnCount(const QModelIndex& parent) const {
 }
 
 QVariant RosterModel::data(const QModelIndex& index, int role) const {
-	if (!index.isValid()) {
-		return QVariant();
-	}
-	return QVariant("bob");
+	RosterItem* item = index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL;
+	return item ? item->data(role) : QVariant();
 }
 
 QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
@@ -38,16 +49,12 @@ QModelIndex RosterModel::parent(const QModelIndex& index) const {
 	Q_ASSERT(item);
 
 	RosterItem* parentItem = item->getParentItem();
-	return parentItem == tree_ ? QModelIndex() : createIndex(parentItem->getParentItem()->rowOf(parentItem), 0, parentItem);
+	return parentItem == tree_ ? QModelIndex() : createIndex(parentItem->row(), 0, parentItem);
 
 }
 
 int RosterModel::rowCount(const QModelIndex& parent) const {
-	if (!parent.isValid()) {
-		return 0;
-	}
-	
-	RosterItem* item = static_cast<RosterItem*>(parent.internalPointer());
+	RosterItem* item = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : tree_;
 	Q_ASSERT(item);
 	
 	return item->rowCount();
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
index a958f0d..fbede32 100644
--- a/Swift/QtUI/Roster/RosterModel.h
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -7,14 +7,18 @@
 
 namespace Swift {
 class RosterModel : public QAbstractItemModel {
+Q_OBJECT
 public:
-	RosterModel(RosterItem* tree);
+	RosterModel();
 	~RosterModel();
+	void setRoot(RosterItem* tree);
 	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;
 	QModelIndex parent(const QModelIndex& index) const;
 	int rowCount(const QModelIndex& parent = QModelIndex()) const;
+private slots:
+	void handleItemChanged();
 private:
 	RosterItem* tree_;
 };
-- 
cgit v0.10.2-6-g49f6


From 774fb699f967e05e7d3f46987b501c61c01f6687 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 26 Jul 2009 17:44:42 +0100
Subject: Removing the dummy title from the roster.


diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index d37bb2a..0aebc24 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -10,9 +10,6 @@ QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
 	model_ = new RosterModel();
 	model_->setRoot(treeRoot_);
     setModel(model_);
-	//FIXME: just a dummy title.
-    setWindowTitle("A roster");
-    //show();
 	setHeaderHidden(true);
 #ifdef SWIFT_PLATFORM_MACOSX
 	setAlternatingRowColors(true);
-- 
cgit v0.10.2-6-g49f6


From aeab97f48ee6c260a3e2a21bca7a291ed1af8063 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 26 Jul 2009 19:05:52 +0100
Subject: Removing RosterItem and including in QtTreeWidgetItem.


diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
index 559f4e2..73ac86c 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.h
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -9,7 +9,6 @@
 #include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
 #include "Swift/QtUI/Roster/QtTreeWidget.h"
 #include "Swift/QtUI/Roster/RosterModel.h"
-#include "Swift/QtUI/Roster/RosterItem.h"
 
 namespace Swift {
 
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
index f65c3bf..4ac2164 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -1,7 +1,45 @@
 #include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
 #include "Swift/QtUI/Roster/QtTreeWidget.h"
+
+#include <qdebug.h>
+
 namespace Swift {
 
+QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject() {
+	parent_ = parentItem;
+}
+
+void QtTreeWidgetItem::setText(const String& text) {
+	setName(P2QSTRING(text));
+}
+
+void QtTreeWidgetItem::setTextColor(unsigned long color) {
+	// QTreeWidgetItem::setTextColor(0, QColor(
+	// 					((color & 0xFF0000)>>16),
+	// 					((color & 0xFF00)>>8), 
+	// 					(color & 0xFF)));
+}
+
+void QtTreeWidgetItem::setBackgroundColor(unsigned long color) {
+	// QTreeWidgetItem::setBackgroundColor(0, QColor(
+	// 					((color & 0xFF0000)>>16),
+	// 					((color & 0xFF00)>>8), 
+	// 					(color & 0xFF)));
+}
+
+void QtTreeWidgetItem::setExpanded(bool b) {
+	//treeWidget()->setItemExpanded(this, b);
+}
+
+void QtTreeWidgetItem::hide() {
+	//setHidden(true);
+}
+
+void QtTreeWidgetItem::show() {
+	//setHidden(false);
+}
+
+
 QWidget* QtTreeWidgetItem::getCollapsedRosterWidget() {
 	QWidget* widget = new QWidget();
 	
@@ -14,4 +52,51 @@ QWidget* QtTreeWidgetItem::getExpandedRosterWidget() {
 	return widget;
 }
 
+QtTreeWidgetItem::~QtTreeWidgetItem() {
+	qDeleteAll(children_);
+}
+
+QtTreeWidgetItem* QtTreeWidgetItem::getParentItem() {
+	return parent_;
+}
+
+void QtTreeWidgetItem::addChild(QtTreeWidgetItem* child) {
+	printf("Boing\n");
+	children_.append(child);
+	connect(child, SIGNAL(changed()), this, SIGNAL(changed()));
+	emit changed();
+}
+
+int QtTreeWidgetItem::rowCount() {
+	qDebug() << "Returning size of " << children_.size() << " for item " << name_;
+	return children_.size();
+}
+
+int QtTreeWidgetItem::rowOf(QtTreeWidgetItem* item) {
+	return children_.indexOf(item);
+}
+
+int QtTreeWidgetItem::row() {
+	return parent_ ? parent_->rowOf(this) : 0;
+}
+
+QtTreeWidgetItem* QtTreeWidgetItem::getItem(int row) {
+	qDebug() << "Returning row " << row << " from item " << name_;
+	return children_[row];
+}
+
+QVariant QtTreeWidgetItem::data(int role) {
+	if (role != Qt::DisplayRole) {
+		return QVariant();
+	}
+	qDebug() << "Returning name " << name_ << " for role " << role;
+	return name_;
+}
+
+void QtTreeWidgetItem::setName(QString name) {
+	name_ = name;
+	qDebug() << "Name changed to " << name;
+	changed();
+}
+
 }
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index 2a72a83..202c44a 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -8,7 +8,6 @@
 #include "Swiften/Roster/TreeWidget.h"
 #include "Swiften/Roster/TreeWidgetItem.h"
 #include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
-#include "Swift/QtUI/Roster/RosterItem.h"
 
 
 #include "Swift/QtUI/QtSwiftUtil.h"
@@ -16,47 +15,36 @@
 
 namespace Swift {
 class QtTreeWidget;
-class QtTreeWidgetItem : public TreeWidgetItem, public RosterItem {
+class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
+	Q_OBJECT
 	public:
-		QtTreeWidgetItem(RosterItem* parentItem) : RosterItem(parentItem) {
-
-		}
-
-		void setText(const String& text) {
-			setName(P2QSTRING(text));
-		}
-
-		void setTextColor(unsigned long color) {
-			// QTreeWidgetItem::setTextColor(0, QColor(
-			// 					((color & 0xFF0000)>>16),
-			// 					((color & 0xFF00)>>8), 
-			// 					(color & 0xFF)));
-		}
-
-		void setBackgroundColor(unsigned long color) {
-			// QTreeWidgetItem::setBackgroundColor(0, QColor(
-			// 					((color & 0xFF0000)>>16),
-			// 					((color & 0xFF00)>>8), 
-			// 					(color & 0xFF)));
-		}
-
-		void setExpanded(bool b) {
-			//treeWidget()->setItemExpanded(this, b);
-		}
-
-		void hide() {
-			//setHidden(true);
-		}
-
-		void show() {
-			//setHidden(false);
-		}
-		
-		QWidget* getCollapsedRosterWidget();
-		QWidget* getExpandedRosterWidget();
+			~QtTreeWidgetItem();
+			void addChild(QtTreeWidgetItem* child);
+			QtTreeWidgetItem* getParentItem();
+			int rowCount();
+			int rowOf(QtTreeWidgetItem* item);
+			int row();
+			QtTreeWidgetItem* getItem(int row);
+			QVariant data(int role);
+			void setName(QString name);
+			QtTreeWidgetItem(QtTreeWidgetItem* parentItem);
+			void setText(const String& text);
+			void setTextColor(unsigned long color);
+			void setBackgroundColor(unsigned long color);
+			void setExpanded(bool b);
+			void hide();
+			void show();
+
+			QWidget* getCollapsedRosterWidget();
+			QWidget* getExpandedRosterWidget();
 		
-	private:
-		QString displayName_;
+		signals:
+			void changed();
+		private:
+			QList<QtTreeWidgetItem*> children_;
+			QtTreeWidgetItem* parent_;
+			QString name_;
+			QString displayName_;
 };
 
 }
diff --git a/Swift/QtUI/Roster/Roster.pri b/Swift/QtUI/Roster/Roster.pri
index 56ff472..bc14889 100644
--- a/Swift/QtUI/Roster/Roster.pri
+++ b/Swift/QtUI/Roster/Roster.pri
@@ -1,11 +1,11 @@
 SOURCES += $$PWD/RosterDelegate.cpp \
-	$$PWD/RosterItem.cpp \
+#	$$PWD/RosterItem.cpp \
 	$$PWD/RosterModel.cpp \
 	$$PWD/QtTreeWidget.cpp \
 	$$PWD/QtTreeWidgetItem.cpp 
 
 HEADERS += $$PWD/RosterDelegate.h \
-	$$PWD/RosterItem.h \
+#	$$PWD/RosterItem.h \
 	$$PWD/RosterModel.h \
 	$$PWD/QtTreeWidget.h \
 	$$PWD/QtTreeWidgetFactory.h \
diff --git a/Swift/QtUI/Roster/RosterItem.cpp b/Swift/QtUI/Roster/RosterItem.cpp
deleted file mode 100644
index b39a47c..0000000
--- a/Swift/QtUI/Roster/RosterItem.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "RosterItem.h"
-
-#include <qdebug.h>
-
-namespace Swift {
-	
-RosterItem::RosterItem(RosterItem* parent) : QObject() {
-	parent_ = parent;
-}
-
-RosterItem::~RosterItem() {
-	qDeleteAll(children_);
-}
-
-RosterItem* RosterItem::getParentItem() {
-	return parent_;
-}
-
-void RosterItem::addChild(RosterItem* child) {
-	printf("Boing\n");
-	children_.append(child);
-	connect(child, SIGNAL(changed()), this, SIGNAL(changed()));
-	emit changed();
-}
-
-int RosterItem::rowCount() {
-	qDebug() << "Returning size of " << children_.size() << " for item " << name_;
-	return children_.size();
-}
-
-int RosterItem::rowOf(RosterItem* item) {
-	return children_.indexOf(item);;
-}
-
-int RosterItem::row() {
-	return parent_ ? parent_->rowOf(this) : 0;
-}
-
-RosterItem* RosterItem::getItem(int row) {
-	qDebug() << "Returning row " << row << " from item " << name_;
-	return children_[row];
-}
-
-QVariant RosterItem::data(int role) {
-	if (role != Qt::DisplayRole) {
-		return QVariant();
-	}
-	qDebug() << "Returning name " << name_ << " for role " << role;
-	return name_;
-}
-
-void RosterItem::setName(QString name) {
-	name_ = name;
-	qDebug() << "Name changed to " << name;
-	changed();
-}
-}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterItem.h b/Swift/QtUI/Roster/RosterItem.h
deleted file mode 100644
index e0041d2..0000000
--- a/Swift/QtUI/Roster/RosterItem.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <QList>
-#include <QVariant>
-namespace Swift {
-	class RosterItem : public QObject {
-	Q_OBJECT
-	public:
-		RosterItem(RosterItem* parent);
-		~RosterItem();
-		void addChild(RosterItem* child);
-		RosterItem* getParentItem();
-		int rowCount();
-		int rowOf(RosterItem* item);
-		int row();
-		RosterItem* getItem(int row);
-		QVariant data(int role);
-		void setName(QString name);
-	signals:
-		void changed();
-	private:
-		QList<RosterItem*> children_;
-		RosterItem* parent_;
-		QString name_;
-	};
-	
-}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index 4c5954e..147aa67 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -9,7 +9,7 @@ RosterModel::~RosterModel() {
 	delete tree_;
 }
 
-void RosterModel::setRoot(RosterItem* root) {
+void RosterModel::setRoot(QtTreeWidgetItem* root) {
 	tree_ = root;
 	connect(tree_, SIGNAL(changed()), this, SLOT(handleItemChanged()));
 }
@@ -29,12 +29,12 @@ int RosterModel::columnCount(const QModelIndex& parent) const {
 }
 
 QVariant RosterModel::data(const QModelIndex& index, int role) const {
-	RosterItem* item = index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL;
+	QtTreeWidgetItem* item = index.isValid() ? static_cast<QtTreeWidgetItem*>(index.internalPointer()) : NULL;
 	return item ? item->data(role) : QVariant();
 }
 
 QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
-	RosterItem* parentItem = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : tree_;
+	QtTreeWidgetItem* parentItem = parent.isValid() ? static_cast<QtTreeWidgetItem*>(parent.internalPointer()) : tree_;
 	Q_ASSERT(parentItem);
 	
 	return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
@@ -45,16 +45,16 @@ QModelIndex RosterModel::parent(const QModelIndex& index) const {
 		return QModelIndex();
 	}
 	
-	RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+	QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
 	Q_ASSERT(item);
 
-	RosterItem* parentItem = item->getParentItem();
+	QtTreeWidgetItem* parentItem = item->getParentItem();
 	return parentItem == tree_ ? QModelIndex() : createIndex(parentItem->row(), 0, parentItem);
 
 }
 
 int RosterModel::rowCount(const QModelIndex& parent) const {
-	RosterItem* item = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : tree_;
+	QtTreeWidgetItem* item = parent.isValid() ? static_cast<QtTreeWidgetItem*>(parent.internalPointer()) : tree_;
 	Q_ASSERT(item);
 	
 	return item->rowCount();
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
index fbede32..e75bc2f 100644
--- a/Swift/QtUI/Roster/RosterModel.h
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Swift/QtUI/Roster/RosterItem.h"
+#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
 
 #include <QAbstractItemModel>
 #include <QList>
@@ -11,7 +11,7 @@ Q_OBJECT
 public:
 	RosterModel();
 	~RosterModel();
-	void setRoot(RosterItem* tree);
+	void setRoot(QtTreeWidgetItem* tree);
 	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;
@@ -20,7 +20,7 @@ public:
 private slots:
 	void handleItemChanged();
 private:
-	RosterItem* tree_;
+	QtTreeWidgetItem* tree_;
 };
 
 }
\ No newline at end of file
-- 
cgit v0.10.2-6-g49f6


From ce74ccc7c8d2ce4c032a90b1ebc0ebd30b4ea4c8 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 26 Jul 2009 19:18:23 +0100
Subject: Clear down some of the cruft from RosterItem.


diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
index 4ac2164..6ebeb7f 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -10,7 +10,7 @@ QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject() {
 }
 
 void QtTreeWidgetItem::setText(const String& text) {
-	setName(P2QSTRING(text));
+	displayName_ = P2QSTRING(text);
 }
 
 void QtTreeWidgetItem::setTextColor(unsigned long color) {
@@ -68,7 +68,7 @@ void QtTreeWidgetItem::addChild(QtTreeWidgetItem* child) {
 }
 
 int QtTreeWidgetItem::rowCount() {
-	qDebug() << "Returning size of " << children_.size() << " for item " << name_;
+	qDebug() << "Returning size of " << children_.size() << " for item " << displayName_;
 	return children_.size();
 }
 
@@ -81,7 +81,7 @@ int QtTreeWidgetItem::row() {
 }
 
 QtTreeWidgetItem* QtTreeWidgetItem::getItem(int row) {
-	qDebug() << "Returning row " << row << " from item " << name_;
+	qDebug() << "Returning row " << row << " from item " << displayName_;
 	return children_[row];
 }
 
@@ -89,14 +89,7 @@ QVariant QtTreeWidgetItem::data(int role) {
 	if (role != Qt::DisplayRole) {
 		return QVariant();
 	}
-	qDebug() << "Returning name " << name_ << " for role " << role;
-	return name_;
+	qDebug() << "Returning name " << displayName_ << " for role " << role;
+	return displayName_;
 }
-
-void QtTreeWidgetItem::setName(QString name) {
-	name_ = name;
-	qDebug() << "Name changed to " << name;
-	changed();
-}
-
 }
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index 202c44a..daffcc2 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -26,7 +26,6 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			int row();
 			QtTreeWidgetItem* getItem(int row);
 			QVariant data(int role);
-			void setName(QString name);
 			QtTreeWidgetItem(QtTreeWidgetItem* parentItem);
 			void setText(const String& text);
 			void setTextColor(unsigned long color);
@@ -43,7 +42,6 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 		private:
 			QList<QtTreeWidgetItem*> children_;
 			QtTreeWidgetItem* parent_;
-			QString name_;
 			QString displayName_;
 };
 
-- 
cgit v0.10.2-6-g49f6


From 46e59e0e6bfceee216db3414680825cbdae60daf Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 26 Jul 2009 20:17:46 +0100
Subject: Use a (boring) delegate for roster rendering.


diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index 0aebc24..714beb2 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -10,6 +10,8 @@ QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
 	model_ = new RosterModel();
 	model_->setRoot(treeRoot_);
     setModel(model_);
+	delegate_ = new RosterDelegate();
+	setItemDelegate(delegate_);
 	setHeaderHidden(true);
 #ifdef SWIFT_PLATFORM_MACOSX
 	setAlternatingRowColors(true);
@@ -22,6 +24,7 @@ QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
 
 QtTreeWidget::~QtTreeWidget() {
 	delete model_;
+	delete delegate_;
 }
 
 QtTreeWidgetItem* QtTreeWidget::getRoot() {
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
index 73ac86c..b8d3c23 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.h
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -9,6 +9,7 @@
 #include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
 #include "Swift/QtUI/Roster/QtTreeWidget.h"
 #include "Swift/QtUI/Roster/RosterModel.h"
+#include "Swift/QtUI/Roster/RosterDelegate.h"
 
 namespace Swift {
 
@@ -24,6 +25,7 @@ class QtTreeWidget : public QTreeView, public TreeWidget {
 	private:
 		void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
 		RosterModel* model_;
+		RosterDelegate* delegate_;
 		QtTreeWidgetItem* treeRoot_;
 		
 };
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
index 6ebeb7f..2c05053 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -14,17 +14,17 @@ void QtTreeWidgetItem::setText(const String& text) {
 }
 
 void QtTreeWidgetItem::setTextColor(unsigned long color) {
-	// QTreeWidgetItem::setTextColor(0, QColor(
-	// 					((color & 0xFF0000)>>16),
-	// 					((color & 0xFF00)>>8), 
-	// 					(color & 0xFF)));
+	textColor_ = QColor(
+	 					((color & 0xFF0000)>>16),
+	 					((color & 0xFF00)>>8), 
+	 					(color & 0xFF));
 }
 
 void QtTreeWidgetItem::setBackgroundColor(unsigned long color) {
-	// QTreeWidgetItem::setBackgroundColor(0, QColor(
-	// 					((color & 0xFF0000)>>16),
-	// 					((color & 0xFF00)>>8), 
-	// 					(color & 0xFF)));
+	backgroundColor_ = QColor(
+	 					((color & 0xFF0000)>>16),
+	 					((color & 0xFF00)>>8), 
+	 					(color & 0xFF));
 }
 
 void QtTreeWidgetItem::setExpanded(bool b) {
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index daffcc2..017258b 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -43,6 +43,8 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			QList<QtTreeWidgetItem*> children_;
 			QtTreeWidgetItem* parent_;
 			QString displayName_;
+			QColor textColor_;
+			QColor backgroundColor_;
 };
 
 }
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index e69de29..925f66c 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -0,0 +1,16 @@
+#include "RosterDelegate.h"
+
+#include <QPainter>
+
+namespace Swift {
+QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
+	return QSize(100,50);
+}
+
+void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex index) const {
+	painter->save();
+	QStyledItemDelegate::paint(painter, option, index);
+	painter->restore();
+}
+
+}
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h
index e69de29..32bba80 100644
--- a/Swift/QtUI/Roster/RosterDelegate.h
+++ b/Swift/QtUI/Roster/RosterDelegate.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#import <QStyledItemDelegate>
+
+namespace Swift {
+	class RosterDelegate : public QStyledItemDelegate {
+		QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+		void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex index) const;
+	};
+}
\ No newline at end of file
-- 
cgit v0.10.2-6-g49f6


From fed11bbc3bffd383e097ea63bb92442ce2daf6ed Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 26 Jul 2009 21:33:45 +0100
Subject: Now render an ugly default icon and default status text in the
 roster.


diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
index 2c05053..e70983f 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -11,6 +11,11 @@ QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject() {
 
 void QtTreeWidgetItem::setText(const String& text) {
 	displayName_ = P2QSTRING(text);
+	statusText_ = displayName_ + " went away";
+}
+
+void QtTreeWidgetItem::setStatusText(const String& text) {
+	statusText_ = P2QSTRING(text);
 }
 
 void QtTreeWidgetItem::setTextColor(unsigned long color) {
@@ -86,10 +91,15 @@ QtTreeWidgetItem* QtTreeWidgetItem::getItem(int row) {
 }
 
 QVariant QtTreeWidgetItem::data(int role) {
-	if (role != Qt::DisplayRole) {
-		return QVariant();
+ 	switch (role) {
+	 	case Qt::DisplayRole: return displayName_;
+	 	case StatusTextRole: return statusText_;
+	 	default: return QVariant();
 	}
-	qDebug() << "Returning name " << displayName_ << " for role " << role;
-	return displayName_;
 }
+
+bool QtTreeWidgetItem::isContact() {
+	return children_.size() == 0;
+}
+
 }
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index 017258b..2dac2fc 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -14,6 +14,11 @@
 
 
 namespace Swift {
+	enum RosterRoles {
+		StatusTextRole = Qt::UserRole,
+		AvatarRole = Qt::UserRole + 1
+	};
+	
 class QtTreeWidget;
 class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 	Q_OBJECT
@@ -28,11 +33,13 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			QVariant data(int role);
 			QtTreeWidgetItem(QtTreeWidgetItem* parentItem);
 			void setText(const String& text);
+			void setStatusText(const String& text);
 			void setTextColor(unsigned long color);
 			void setBackgroundColor(unsigned long color);
 			void setExpanded(bool b);
 			void hide();
 			void show();
+			bool isContact();
 
 			QWidget* getCollapsedRosterWidget();
 			QWidget* getExpandedRosterWidget();
@@ -43,6 +50,7 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			QList<QtTreeWidgetItem*> children_;
 			QtTreeWidgetItem* parent_;
 			QString displayName_;
+			QString statusText_;
 			QColor textColor_;
 			QColor backgroundColor_;
 };
diff --git a/Swift/QtUI/Roster/Roster.pro b/Swift/QtUI/Roster/Roster.pro
index 086ef41..be0cff3 100644
--- a/Swift/QtUI/Roster/Roster.pro
+++ b/Swift/QtUI/Roster/Roster.pro
@@ -13,4 +13,6 @@ exists(../config.pri) {
 
 mac {
 	DEFINES += SWIFT_PLATFORM_MACOSX
-}
\ No newline at end of file
+}
+
+RESOURCES += ../Swift.qrc
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index 925f66c..b6b9ded 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -1,15 +1,47 @@
 #include "RosterDelegate.h"
 
 #include <QPainter>
+#include <qdebug.h>
+
+#include "QtTreeWidgetItem.h"
 
 namespace Swift {
 QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
-	return QSize(100,50);
+	QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+	if (item && !item->isContact()) {
+		return QStyledItemDelegate::sizeHint(option, index);
+	}
+	//Doesn't work, yay! FIXME: why?
+	QSize size = (option.state & QStyle::State_Selected) ? QSize(200, 50) : QSize(100,50);
+	qDebug() << "Returning size" << size;
+	return size;
 }
 
-void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex index) const {
+void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+	QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+	if (item && !item->isContact()) {
+		QStyledItemDelegate::paint(painter, option, index);
+		return;
+	}
+	qDebug() << "painting" << index.data(Qt::DisplayRole).toString();
 	painter->save();
-	QStyledItemDelegate::paint(painter, option, index);
+	//QStyledItemDelegate::paint(painter, option, index);
+	//initStyleOption(option, index);
+	QRect fullRegion(option.rect);
+	
+	QRect avatarRegion(QPoint(0, fullRegion.top()), QSize(32, 32));
+	QIcon icon = index.data(AvatarRole).isValid() && !index.data(AvatarRole).value<QIcon>().isNull()
+		? index.data(AvatarRole).value<QIcon>()
+		: QIcon(":/icons/avatar.png");
+	icon.paint(painter, avatarRegion, Qt::AlignVCenter | Qt::AlignHCenter);
+	
+	QRect textRegion(fullRegion.adjusted(avatarRegion.width(), 0, 0, 0));
+	QRect nameRegion(textRegion.adjusted(0,0,0,-25));
+	painter->drawText(nameRegion, Qt::AlignVCenter, index.data(Qt::DisplayRole).toString());
+	
+	QRect statusTextRegion(textRegion.adjusted(0, 25, 0, 0));
+	painter->drawText(statusTextRegion, Qt::AlignVCenter, index.data(StatusTextRole).toString());
+	
 	painter->restore();
 }
 
diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h
index 32bba80..a48b30f 100644
--- a/Swift/QtUI/Roster/RosterDelegate.h
+++ b/Swift/QtUI/Roster/RosterDelegate.h
@@ -4,7 +4,8 @@
 
 namespace Swift {
 	class RosterDelegate : public QStyledItemDelegate {
+	public:
 		QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
-		void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex index) const;
+		void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
 	};
 }
\ No newline at end of file
-- 
cgit v0.10.2-6-g49f6


From cd40e329581cb942603140402c9d1970e71ebbd0 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Fri, 31 Jul 2009 21:47:51 +0100
Subject: Render status text italicised, and selection colours.


diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index b6b9ded..aee58fa 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -1,6 +1,8 @@
 #include "RosterDelegate.h"
 
 #include <QPainter>
+#include <QColor>
+#include <QBrush>
 #include <qdebug.h>
 
 #include "QtTreeWidgetItem.h"
@@ -28,17 +30,25 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
 	//QStyledItemDelegate::paint(painter, option, index);
 	//initStyleOption(option, index);
 	QRect fullRegion(option.rect);
-	
+	if ( option.state & QStyle::State_Selected ) {
+		painter->fillRect(fullRegion, option.palette.highlight());
+		painter->setPen(option.palette.highlightedText().color());
+	} 
 	QRect avatarRegion(QPoint(0, fullRegion.top()), QSize(32, 32));
 	QIcon icon = index.data(AvatarRole).isValid() && !index.data(AvatarRole).value<QIcon>().isNull()
 		? index.data(AvatarRole).value<QIcon>()
 		: QIcon(":/icons/avatar.png");
 	icon.paint(painter, avatarRegion, Qt::AlignVCenter | Qt::AlignHCenter);
 	
+	QFont nameFont = painter->font();
+	QFont statusFont = painter->font();
+	statusFont.setStyle(QFont::StyleItalic);
+	//statusFont.setSize(-1);
+	painter->setFont(nameFont);
 	QRect textRegion(fullRegion.adjusted(avatarRegion.width(), 0, 0, 0));
 	QRect nameRegion(textRegion.adjusted(0,0,0,-25));
 	painter->drawText(nameRegion, Qt::AlignVCenter, index.data(Qt::DisplayRole).toString());
-	
+	painter->setFont(statusFont);
 	QRect statusTextRegion(textRegion.adjusted(0, 25, 0, 0));
 	painter->drawText(statusTextRegion, Qt::AlignVCenter, index.data(StatusTextRole).toString());
 	
-- 
cgit v0.10.2-6-g49f6


From cd294437d80978a72a8b7ce9e563afee0a518300 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sat, 1 Aug 2009 15:01:38 +0100
Subject: Sort out the alignments in the roster.


diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index aee58fa..3b3d6fe 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -3,6 +3,7 @@
 #include <QPainter>
 #include <QColor>
 #include <QBrush>
+#include <QFontMetrics>
 #include <qdebug.h>
 
 #include "QtTreeWidgetItem.h"
@@ -14,7 +15,7 @@ QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelI
 		return QStyledItemDelegate::sizeHint(option, index);
 	}
 	//Doesn't work, yay! FIXME: why?
-	QSize size = (option.state & QStyle::State_Selected) ? QSize(200, 50) : QSize(100,50);
+	QSize size = (option.state & QStyle::State_Selected) ? QSize(150, 80) : QSize(150,56);
 	qDebug() << "Returning size" << size;
 	return size;
 }
@@ -34,7 +35,7 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
 		painter->fillRect(fullRegion, option.palette.highlight());
 		painter->setPen(option.palette.highlightedText().color());
 	} 
-	QRect avatarRegion(QPoint(0, fullRegion.top()), QSize(32, 32));
+	QRect avatarRegion(QPoint(4, fullRegion.top() + 4), QSize(48, 48));
 	QIcon icon = index.data(AvatarRole).isValid() && !index.data(AvatarRole).value<QIcon>().isNull()
 		? index.data(AvatarRole).value<QIcon>()
 		: QIcon(":/icons/avatar.png");
@@ -42,15 +43,21 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
 	
 	QFont nameFont = painter->font();
 	QFont statusFont = painter->font();
-	statusFont.setStyle(QFont::StyleItalic);
-	//statusFont.setSize(-1);
+	
 	painter->setFont(nameFont);
-	QRect textRegion(fullRegion.adjusted(avatarRegion.width(), 0, 0, 0));
-	QRect nameRegion(textRegion.adjusted(0,0,0,-25));
-	painter->drawText(nameRegion, Qt::AlignVCenter, index.data(Qt::DisplayRole).toString());
+	QRect textRegion(fullRegion.adjusted(56, 0, 0, 0));
+	
+	QFontMetrics nameMetrics(nameFont);
+	int nameHeight = nameMetrics.height() + 8;
+	QRect nameRegion(textRegion.adjusted(0, 4, 0, -1 * nameHeight));
+	painter->drawText(nameRegion, Qt::AlignTop, index.data(Qt::DisplayRole).toString());
+	
+	statusFont.setStyle(QFont::StyleItalic);
+	statusFont.setPointSize(10);
 	painter->setFont(statusFont);
-	QRect statusTextRegion(textRegion.adjusted(0, 25, 0, 0));
-	painter->drawText(statusTextRegion, Qt::AlignVCenter, index.data(StatusTextRole).toString());
+	painter->setPen(QPen(QColor(160,160,160)));
+	QRect statusTextRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+	painter->drawText(statusTextRegion, Qt::AlignTop, index.data(StatusTextRole).toString());
 	
 	painter->restore();
 }
diff --git a/Swift/resources/icons/avatar.png b/Swift/resources/icons/avatar.png
index 00374a6..4b932b0 100644
Binary files a/Swift/resources/icons/avatar.png and b/Swift/resources/icons/avatar.png differ
-- 
cgit v0.10.2-6-g49f6


From c3b4fc7dcf8475e4dcf7b42b496e332df4a4f7b1 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sat, 1 Aug 2009 15:46:37 +0100
Subject: Resize avatars to 32pix in Roster, change alignments to be relative,
 do item hiding.


diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
index e70983f..bbb5e98 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -7,6 +7,7 @@ namespace Swift {
 
 QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject() {
 	parent_ = parentItem;
+	shown_ = true;
 }
 
 void QtTreeWidgetItem::setText(const String& text) {
@@ -37,13 +38,18 @@ void QtTreeWidgetItem::setExpanded(bool b) {
 }
 
 void QtTreeWidgetItem::hide() {
-	//setHidden(true);
+	shown_ = false;
+	emit changed();
 }
 
 void QtTreeWidgetItem::show() {
-	//setHidden(false);
+	shown_ = true;
+	emit changed();
 }
 
+bool QtTreeWidgetItem::isShown() {
+	return shown_;
+}
 
 QWidget* QtTreeWidgetItem::getCollapsedRosterWidget() {
 	QWidget* widget = new QWidget();
@@ -66,19 +72,28 @@ QtTreeWidgetItem* QtTreeWidgetItem::getParentItem() {
 }
 
 void QtTreeWidgetItem::addChild(QtTreeWidgetItem* child) {
-	printf("Boing\n");
 	children_.append(child);
-	connect(child, SIGNAL(changed()), this, SIGNAL(changed()));
+	connect(child, SIGNAL(changed()), this, SLOT(handleChanged()));
+	handleChanged();
+}
+
+void QtTreeWidgetItem::handleChanged() {
+	shownChildren_.clear();
+	for (int i = 0; i < children_.size(); i++) {
+		if (children_[i]->isShown()) {
+			shownChildren_.append(children_[i]);
+		}
+	}
 	emit changed();
 }
 
 int QtTreeWidgetItem::rowCount() {
 	qDebug() << "Returning size of " << children_.size() << " for item " << displayName_;
-	return children_.size();
+	return shownChildren_.size();
 }
 
 int QtTreeWidgetItem::rowOf(QtTreeWidgetItem* item) {
-	return children_.indexOf(item);
+	return shownChildren_.indexOf(item);
 }
 
 int QtTreeWidgetItem::row() {
@@ -87,7 +102,7 @@ int QtTreeWidgetItem::row() {
 
 QtTreeWidgetItem* QtTreeWidgetItem::getItem(int row) {
 	qDebug() << "Returning row " << row << " from item " << displayName_;
-	return children_[row];
+	return shownChildren_[row];
 }
 
 QVariant QtTreeWidgetItem::data(int role) {
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index 2dac2fc..e3bfff3 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -39,6 +39,7 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			void setExpanded(bool b);
 			void hide();
 			void show();
+			bool isShown();
 			bool isContact();
 
 			QWidget* getCollapsedRosterWidget();
@@ -46,13 +47,17 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 		
 		signals:
 			void changed();
+		private slots:
+			void handleChanged();
 		private:
 			QList<QtTreeWidgetItem*> children_;
+			QList<QtTreeWidgetItem*> shownChildren_;
 			QtTreeWidgetItem* parent_;
 			QString displayName_;
 			QString statusText_;
 			QColor textColor_;
 			QColor backgroundColor_;
+			bool shown_;
 };
 
 }
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index 3b3d6fe..2447e8f 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -15,7 +15,7 @@ QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelI
 		return QStyledItemDelegate::sizeHint(option, index);
 	}
 	//Doesn't work, yay! FIXME: why?
-	QSize size = (option.state & QStyle::State_Selected) ? QSize(150, 80) : QSize(150,56);
+	QSize size = (option.state & QStyle::State_Selected) ? QSize(150, 80) : QSize(150, avatarSize_ + margin_ * 2);
 	qDebug() << "Returning size" << size;
 	return size;
 }
@@ -35,7 +35,7 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
 		painter->fillRect(fullRegion, option.palette.highlight());
 		painter->setPen(option.palette.highlightedText().color());
 	} 
-	QRect avatarRegion(QPoint(4, fullRegion.top() + 4), QSize(48, 48));
+	QRect avatarRegion(QPoint(margin_, fullRegion.top() + margin_), QSize(avatarSize_, avatarSize_));
 	QIcon icon = index.data(AvatarRole).isValid() && !index.data(AvatarRole).value<QIcon>().isNull()
 		? index.data(AvatarRole).value<QIcon>()
 		: QIcon(":/icons/avatar.png");
@@ -45,11 +45,11 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
 	QFont statusFont = painter->font();
 	
 	painter->setFont(nameFont);
-	QRect textRegion(fullRegion.adjusted(56, 0, 0, 0));
+	QRect textRegion(fullRegion.adjusted(avatarSize_ + margin_ * 2, 0, 0, 0));
 	
 	QFontMetrics nameMetrics(nameFont);
-	int nameHeight = nameMetrics.height() + 8;
-	QRect nameRegion(textRegion.adjusted(0, 4, 0, -1 * nameHeight));
+	int nameHeight = nameMetrics.height() + margin_ * 2;
+	QRect nameRegion(textRegion.adjusted(0, margin_, 0, 0));
 	painter->drawText(nameRegion, Qt::AlignTop, index.data(Qt::DisplayRole).toString());
 	
 	statusFont.setStyle(QFont::StyleItalic);
diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h
index a48b30f..4a4ad6b 100644
--- a/Swift/QtUI/Roster/RosterDelegate.h
+++ b/Swift/QtUI/Roster/RosterDelegate.h
@@ -7,5 +7,8 @@ namespace Swift {
 	public:
 		QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
 		void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+	private:
+		static const int avatarSize_ = 32;
+		static const int margin_ = 4;
 	};
 }
\ No newline at end of file
-- 
cgit v0.10.2-6-g49f6


From 9e3d7f4183f515a4d768be8166936340dee5a9b9 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sat, 1 Aug 2009 18:21:06 +0100
Subject: Roster now includes avatars.


diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 77e531e..0f654e4 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -109,8 +109,11 @@ void MainController::handleConnected() {
 	delete nickResolver_;
 	nickResolver_ = new NickResolver(xmppRoster);
 
+	delete avatarManager_;
+	avatarManager_ = new AvatarManager(client_, client_, avatarStorage_, this);
+	
 	delete rosterController_;
-	rosterController_ = new RosterController(xmppRoster, mainWindowFactory_, treeWidgetFactory_);
+	rosterController_ = new RosterController(xmppRoster, avatarManager_, mainWindowFactory_, treeWidgetFactory_);
 	rosterController_->onStartChatRequest.connect(boost::bind(&MainController::handleChatRequest, this, _1));
 	rosterController_->onJoinMUCRequest.connect(boost::bind(&MainController::handleJoinMUCRequest, this, _1, _2));
 	rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
@@ -123,9 +126,6 @@ void MainController::handleConnected() {
 	clientVersionResponder_ = new SoftwareVersionResponder(CLIENT_NAME, CLIENT_VERSION, client_);
 	loginWindow_->morphInto(rosterController_->getWindow());
 
-	delete avatarManager_;
-	avatarManager_ = new AvatarManager(client_, client_, avatarStorage_, this);
-
 	DiscoInfo discoInfo;
 	discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc"));
 	capsInfo_ = boost::shared_ptr<CapsInfo>(new CapsInfo(CapsInfoGenerator(CLIENT_NODE).generateCapsInfo(discoInfo)));
diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index c447602..3662241 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -9,6 +9,7 @@
 #include "Swiften/EventLoop/MainEventLoop.h"
 #include "Swiften/Roster/Roster.h"
 #include "Swiften/Roster/SetPresence.h"
+#include "Swiften/Roster/SetAvatar.h"
 #include "Swiften/Roster/OfflineRosterFilter.h"
 #include "Swiften/Roster/OpenChatRosterAction.h"
 #include "Swiften/Roster/TreeWidgetFactory.h"
@@ -19,9 +20,11 @@ namespace Swift {
 /**
  * The controller does not gain ownership of these parameters.
  */
-RosterController::RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, MainWindowFactory* mainWindowFactory, TreeWidgetFactory* treeWidgetFactory)
+RosterController::RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, TreeWidgetFactory* treeWidgetFactory)
  : xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), treeWidgetFactory_(treeWidgetFactory), mainWindow_(mainWindowFactory_->createMainWindow()), roster_(new Roster(mainWindow_->getTreeWidget(), treeWidgetFactory_)), offlineFilter_(new OfflineRosterFilter()) {
 	roster_->addFilter(offlineFilter_);
+	avatarManager_ = avatarManager;
+	avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1, _2));
 	mainWindow_->onStartChatRequest.connect(boost::bind(&RosterController::handleStartChatRequest, this, _1));
 	mainWindow_->onJoinMUCRequest.connect(boost::bind(&RosterController::handleJoinMUCRequest, this, _1, _2));
 	mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2));
@@ -72,6 +75,11 @@ void RosterController::handleIncomingPresence(boost::shared_ptr<Presence> presen
 	roster_->applyOnItems(SetPresence(presence));
 }
 
+void RosterController::handleAvatarChanged(const JID& jid, const String& hash) {
+	String path = avatarManager_->getAvatarPath(jid).string();
+	roster_->applyOnItems(SetAvatar(jid, path));
+}
+
 void RosterController::handleStartChatRequest(const JID& contact) {
 	onStartChatRequest(contact);
 }
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index 945b068..f9f2258 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -5,6 +5,7 @@
 #include "Swiften/Base/String.h"
 #include "Swiften/Elements/Presence.h"
 #include "Swiften/Roster/UserRosterAction.h"
+#include "Swiften/Avatars/AvatarManager.h"
 
 #include <boost/signals.hpp>
 #include <boost/shared_ptr.hpp>
@@ -20,7 +21,7 @@ namespace Swift {
 
 	class RosterController {
 		public:
-			RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, MainWindowFactory *mainWindowFactory, TreeWidgetFactory *treeWidgetFactory);
+			RosterController(boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory *mainWindowFactory, TreeWidgetFactory *treeWidgetFactory);
 			~RosterController();
 			void showRosterWindow();
 			MainWindow* getWindow() {return mainWindow_;};
@@ -28,6 +29,7 @@ namespace Swift {
 			boost::signal<void (const JID&, const String&)> onJoinMUCRequest;
 			boost::signal<void (StatusShow::Type, const String&)> onChangeStatusRequest;
 			void handleIncomingPresence(boost::shared_ptr<Presence> presence);
+			void handleAvatarChanged(const JID& jid, const String& hash);
 
 		private:
 			void handleOnJIDAdded(const JID &jid);
@@ -42,6 +44,7 @@ namespace Swift {
 			MainWindow* mainWindow_;
 			Roster* roster_;
 			OfflineRosterFilter* offlineFilter_;
+			AvatarManager* avatarManager_;
 	};
 }
 #endif
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
index bbb5e98..aa1836c 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -5,20 +5,24 @@
 
 namespace Swift {
 
-QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject() {
+QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject(), textColor_(0,0,0), backgroundColor_(255,255,255) {
 	parent_ = parentItem;
 	shown_ = true;
 }
 
 void QtTreeWidgetItem::setText(const String& text) {
 	displayName_ = P2QSTRING(text);
-	statusText_ = displayName_ + " went away";
 }
 
 void QtTreeWidgetItem::setStatusText(const String& text) {
 	statusText_ = P2QSTRING(text);
 }
 
+void QtTreeWidgetItem::setAvatarPath(const String& path) {
+	qDebug() << "Setting avatar to " << P2QSTRING(path);
+	avatar_ = QIcon(P2QSTRING(path));
+}
+
 void QtTreeWidgetItem::setTextColor(unsigned long color) {
 	textColor_ = QColor(
 	 					((color & 0xFF0000)>>16),
@@ -48,7 +52,7 @@ void QtTreeWidgetItem::show() {
 }
 
 bool QtTreeWidgetItem::isShown() {
-	return shown_;
+	return isContact() ? shown_ : shownChildren_.size() > 0;
 }
 
 QWidget* QtTreeWidgetItem::getCollapsedRosterWidget() {
@@ -88,7 +92,7 @@ void QtTreeWidgetItem::handleChanged() {
 }
 
 int QtTreeWidgetItem::rowCount() {
-	qDebug() << "Returning size of " << children_.size() << " for item " << displayName_;
+	//qDebug() << "Returning size of " << children_.size() << " for item " << displayName_;
 	return shownChildren_.size();
 }
 
@@ -101,14 +105,18 @@ int QtTreeWidgetItem::row() {
 }
 
 QtTreeWidgetItem* QtTreeWidgetItem::getItem(int row) {
-	qDebug() << "Returning row " << row << " from item " << displayName_;
+	//qDebug() << "Returning row " << row << " from item " << displayName_;
 	return shownChildren_[row];
 }
 
+
 QVariant QtTreeWidgetItem::data(int role) {
  	switch (role) {
 	 	case Qt::DisplayRole: return displayName_;
+		case Qt::TextColorRole: return textColor_;
+		case Qt::BackgroundColorRole: return backgroundColor_;
 	 	case StatusTextRole: return statusText_;
+		case AvatarRole: return avatar_;
 	 	default: return QVariant();
 	}
 }
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index e3bfff3..0a32940 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -2,6 +2,7 @@
 #define SWIFT_QtTreeWidgetItem_H
 
 #include <QColor>
+#include <QVariant>
 
 #include "Swiften/Base/String.h"
 #include "Swiften/Roster/TreeWidgetFactory.h"
@@ -33,6 +34,7 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			QVariant data(int role);
 			QtTreeWidgetItem(QtTreeWidgetItem* parentItem);
 			void setText(const String& text);
+			void setAvatarPath(const String& path);
 			void setStatusText(const String& text);
 			void setTextColor(unsigned long color);
 			void setBackgroundColor(unsigned long color);
@@ -57,6 +59,7 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			QString statusText_;
 			QColor textColor_;
 			QColor backgroundColor_;
+			QVariant avatar_;
 			bool shown_;
 };
 
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index 2447e8f..b05bbb1 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -16,7 +16,7 @@ QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelI
 	}
 	//Doesn't work, yay! FIXME: why?
 	QSize size = (option.state & QStyle::State_Selected) ? QSize(150, 80) : QSize(150, avatarSize_ + margin_ * 2);
-	qDebug() << "Returning size" << size;
+	//qDebug() << "Returning size" << size;
 	return size;
 }
 
@@ -26,7 +26,7 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
 		QStyledItemDelegate::paint(painter, option, index);
 		return;
 	}
-	qDebug() << "painting" << index.data(Qt::DisplayRole).toString();
+	//qDebug() << "painting" << index.data(Qt::DisplayRole).toString();
 	painter->save();
 	//QStyledItemDelegate::paint(painter, option, index);
 	//initStyleOption(option, index);
@@ -48,8 +48,10 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
 	QRect textRegion(fullRegion.adjusted(avatarSize_ + margin_ * 2, 0, 0, 0));
 	
 	QFontMetrics nameMetrics(nameFont);
-	int nameHeight = nameMetrics.height() + margin_ * 2;
+	int nameHeight = nameMetrics.height() + margin_;
 	QRect nameRegion(textRegion.adjusted(0, margin_, 0, 0));
+	QColor nameColor = index.data(Qt::TextColorRole).value<QColor>();
+	painter->setPen(QPen(nameColor));
 	painter->drawText(nameRegion, Qt::AlignTop, index.data(Qt::DisplayRole).toString());
 	
 	statusFont.setStyle(QFont::StyleItalic);
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index 147aa67..f322792 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -18,7 +18,7 @@ void RosterModel::setRoot(QtTreeWidgetItem* root) {
 void RosterModel::handleItemChanged() {
 	//FIXME: This is just a lazy hack to cause the view to refresh until it works.
 	// Then I'll replace it with the proper implementation.
-	printf("Changed\n");
+	//printf("Changed\n");
 	reset();
 	emit layoutChanged();
 }
diff --git a/Swiften/Avatars/AvatarManager.h b/Swiften/Avatars/AvatarManager.h
index 984ce19..3ac4433 100644
--- a/Swiften/Avatars/AvatarManager.h
+++ b/Swiften/Avatars/AvatarManager.h
@@ -32,7 +32,7 @@ namespace Swift {
 			void handlePresenceReceived(boost::shared_ptr<Presence>);
 			void handleVCardReceived(const JID& from, const String& hash, boost::shared_ptr<VCard>, const boost::optional<Error>&);
 			void setAvatarHash(const JID& from, const String& hash);
-      JID getAvatarJID(const JID& o) const;
+			JID getAvatarJID(const JID& o) const;
 
 		private:
 			StanzaChannel* stanzaChannel_;
diff --git a/Swiften/Roster/ContactRosterItem.cpp b/Swiften/Roster/ContactRosterItem.cpp
index f38b0f7..2f2f787 100644
--- a/Swiften/Roster/ContactRosterItem.cpp
+++ b/Swiften/Roster/ContactRosterItem.cpp
@@ -34,6 +34,14 @@ void ContactRosterItem::setStatusShow(StatusShow::Type show) {
 	widget_->setTextColor(colour);
 }
 
+void ContactRosterItem::setStatusText(const String& status) {
+	widget_->setStatusText(status);
+}
+
+void ContactRosterItem::setAvatarPath(const String& path) {
+	widget_->setAvatarPath(path);
+}
+
 const JID& ContactRosterItem::getJID() const {
 	return jid_;
 }
diff --git a/Swiften/Roster/ContactRosterItem.h b/Swiften/Roster/ContactRosterItem.h
index 20f9f65..f1810aa 100644
--- a/Swiften/Roster/ContactRosterItem.h
+++ b/Swiften/Roster/ContactRosterItem.h
@@ -23,6 +23,8 @@ class ContactRosterItem : public RosterItem {
 
 		StatusShow::Type getStatusShow();
 		void setStatusShow(StatusShow::Type show);
+		void setStatusText(const String& status);
+		void setAvatarPath(const String& path);
 		const JID& getJID() const;
 		void show();
 		void hide();
diff --git a/Swiften/Roster/SetAvatar.h b/Swiften/Roster/SetAvatar.h
new file mode 100644
index 0000000..7bc9c37
--- /dev/null
+++ b/Swiften/Roster/SetAvatar.h
@@ -0,0 +1,33 @@
+#ifndef SWIFTEN_SetAvatar_H
+#define SWIFTEN_SetAvatar_H
+
+#include "Swiften/Elements/Presence.h"
+#include "Swiften/JID/JID.h"
+#include "Swiften/Roster/RosterItemOperation.h"
+#include "Swiften/Roster/ContactRosterItem.h"
+
+namespace Swift {
+
+class RosterItem;
+
+class SetAvatar : public RosterItemOperation {
+	public:
+		SetAvatar(const JID& jid, const String& path, JID::CompareType compareType = JID::WithoutResource) : jid_(jid), path_(path), compareType_(compareType) {
+		}
+
+		virtual void operator() (RosterItem* item) const {
+			ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+			if (contact && contact->getJID().equals(jid_, compareType_)) {
+				contact->setAvatarPath(path_);
+			}
+		}
+	
+	private:
+		JID jid_;
+		String path_;
+		JID::CompareType compareType_;
+};
+
+}
+#endif
+
diff --git a/Swiften/Roster/SetPresence.h b/Swiften/Roster/SetPresence.h
index aa36a52..a18ae6d 100644
--- a/Swiften/Roster/SetPresence.h
+++ b/Swiften/Roster/SetPresence.h
@@ -20,8 +20,10 @@ class SetPresence : public RosterItemOperation {
 			if (contact && contact->getJID().equals(presence_->getFrom(), compareType_)) {
 				if (presence_->getType() != Presence::Available) {
 					contact->setStatusShow(StatusShow::None);
+					contact->setStatusText(presence_->getStatus());
 				} else {
 					contact->setStatusShow(presence_->getShow());
+					contact->setStatusText(presence_->getStatus());
 				}
 			}
 		}
diff --git a/Swiften/Roster/TreeWidgetItem.h b/Swiften/Roster/TreeWidgetItem.h
index 5a96a41..4e20050 100644
--- a/Swiften/Roster/TreeWidgetItem.h
+++ b/Swiften/Roster/TreeWidgetItem.h
@@ -13,6 +13,8 @@ class TreeWidgetItem {
 	public:
 		virtual ~TreeWidgetItem() {}
 		virtual void setText(const String& text) = 0;
+		virtual void setStatusText(const String& text) = 0;
+		virtual void setAvatarPath(const String& path) = 0;
 		virtual void setExpanded(bool b) = 0;
 		virtual void setTextColor(unsigned long color) = 0;
 		virtual void setBackgroundColor(unsigned long color) = 0;
-- 
cgit v0.10.2-6-g49f6


From 15e67b8dc1d2ddcbbf84eb5a50681c68012e3250 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 2 Aug 2009 11:29:13 +0100
Subject: Roster clicks now open chats again.


diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index 714beb2..67afd14 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -19,7 +19,7 @@ QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
 	setAnimated(true);
 	setIndentation(0);
 	setRootIsDecorated(true);
-	//connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(handleItemActivated(QTreeWidgetItem*, int)));
+	connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
 }
 
 QtTreeWidget::~QtTreeWidget() {
@@ -31,12 +31,12 @@ QtTreeWidgetItem* QtTreeWidget::getRoot() {
 	return treeRoot_;
 }
 
-// void QtTreeWidget::handleItemActivated(QTreeWidgetItem* item, int column) {
-// 	QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
-// 	if (qtItem) {
-// 		qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction()));
-// 	}
-// }
+void QtTreeWidget::handleItemActivated(const QModelIndex& index) {
+	QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+	if (qtItem) {
+		qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction()));
+	}
+}
 
 void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
 }
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
index b8d3c23..bb8f618 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.h
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -2,7 +2,7 @@
 #define SWIFT_QtTreeWidget_H
 
 #include <QTreeView>
-
+#include <QModelIndex>
 #include "Swiften/Roster/TreeWidgetFactory.h"
 #include "Swiften/Roster/TreeWidget.h"
 #include "Swiften/Roster/TreeWidgetItem.h"
@@ -20,8 +20,8 @@ class QtTreeWidget : public QTreeView, public TreeWidget {
 		~QtTreeWidget();
 		void show();
 		QtTreeWidgetItem* getRoot();
-	//private slots:
-	//	void handleItemActivated(QTreeWidgetItem*, int);
+	private slots:
+		void handleItemActivated(const QModelIndex&);
 	private:
 		void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
 		RosterModel* model_;
diff --git a/Swift/QtUI/Roster/main.cpp b/Swift/QtUI/Roster/main.cpp
index f3623ac..60ee592 100644
--- a/Swift/QtUI/Roster/main.cpp
+++ b/Swift/QtUI/Roster/main.cpp
@@ -15,17 +15,19 @@ int main(int argc, char *argv[])
 
 	Swift::QtTreeWidgetFactory treeWidgetFactory;
 	Swift::QtTreeWidget* tree = dynamic_cast<Swift::QtTreeWidget*>(treeWidgetFactory.createTreeWidget());
-	Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
-	group->setText("People");
-	group->setBackgroundColor(0xBBBBBB);
-	Swift::QtTreeWidgetItem* item1 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
-	Swift::QtTreeWidgetItem* item2 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
-	Swift::QtTreeWidgetItem* item3 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
-	Swift::QtTreeWidgetItem* item4 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
-	item1->setText("Remko");
-	item2->setText("Kevin");
-	item3->setText("Cath");
-	item4->setText("Kim");
+	for (int i = 0; i < 500; i++) {
+		Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
+		group->setText("People");
+		group->setBackgroundColor(0xBBBBBB);
+		Swift::QtTreeWidgetItem* item1 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+		Swift::QtTreeWidgetItem* item2 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+		Swift::QtTreeWidgetItem* item3 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+		Swift::QtTreeWidgetItem* item4 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+		item1->setText("Remko");
+		item2->setText("Kevin");
+		item3->setText("Cath");
+		item4->setText("Kim");
+	}
 	tree->show();
     return app.exec();
 }
\ No newline at end of file
-- 
cgit v0.10.2-6-g49f6


From 40d35626023f12d8ebea3a53672968b1b80f5974 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Thu, 6 Aug 2009 19:00:54 +0000
Subject: Conditional includes to get the QtSoundPlayer to compile on Ubuntu.


diff --git a/Swift/QtUI/QtSoundPlayer.cpp b/Swift/QtUI/QtSoundPlayer.cpp
index 5dd3db3..4aa6b8e 100644
--- a/Swift/QtUI/QtSoundPlayer.cpp
+++ b/Swift/QtUI/QtSoundPlayer.cpp
@@ -1,8 +1,12 @@
 #include "QtSoundPlayer.h"
 
+#ifdef Q_WS_X11
+#include "mediaobject.h"
+#include "audiooutput.h"
+#else
 #include <phonon/MediaObject>
 #include <phonon/AudioOutput>
-
+#endif
 
 namespace Swift{
 	
@@ -33,4 +37,4 @@ void QtSoundPlayer::handleFinished() {
 	messageReceived_->stop();
 }
 
-}
\ No newline at end of file
+}
-- 
cgit v0.10.2-6-g49f6


From 47d75bf5a3f58ce582e5715a9d5ba6e89a38b033 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sat, 8 Aug 2009 15:18:43 +0100
Subject: Plumbing in place for roster group expansion. \nDoesn't work.


diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index 67afd14..18b28d2 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -20,6 +20,7 @@ QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
 	setIndentation(0);
 	setRootIsDecorated(true);
 	connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
+	connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleItemExpanded(const QModelIndex&, bool)));
 }
 
 QtTreeWidget::~QtTreeWidget() {
@@ -38,6 +39,10 @@ void QtTreeWidget::handleItemActivated(const QModelIndex& index) {
 	}
 }
 
+void QtTreeWidget::handleItemExpanded(const QModelIndex& index, bool expanded) {
+	setExpanded(index, expanded);
+}
+
 void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
 }
 
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
index bb8f618..8c76d60 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.h
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -22,6 +22,7 @@ class QtTreeWidget : public QTreeView, public TreeWidget {
 		QtTreeWidgetItem* getRoot();
 	private slots:
 		void handleItemActivated(const QModelIndex&);
+		void handleItemExpanded(const QModelIndex&, bool expanded);
 	private:
 		void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
 		RosterModel* model_;
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.h b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
index 2ca1e21..db20044 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetFactory.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
@@ -33,6 +33,7 @@ class QtTreeWidgetFactory : public TreeWidgetFactory {
 			QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
 			//qtItem->setItemWidget(newItem, 0, newItem->getCollapsedRosterWidget());
 			qtItem->addChild(newItem);
+			newItem->setExpanded(true);
 			return newItem;
 		}
 };
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
index aa1836c..1b77b26 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.cpp
@@ -8,6 +8,7 @@ namespace Swift {
 QtTreeWidgetItem::QtTreeWidgetItem(QtTreeWidgetItem* parentItem) : QObject(), textColor_(0,0,0), backgroundColor_(255,255,255) {
 	parent_ = parentItem;
 	shown_ = true;
+	expanded_ = true;
 }
 
 void QtTreeWidgetItem::setText(const String& text) {
@@ -38,17 +39,18 @@ void QtTreeWidgetItem::setBackgroundColor(unsigned long color) {
 }
 
 void QtTreeWidgetItem::setExpanded(bool b) {
-	//treeWidget()->setItemExpanded(this, b);
+	expanded_ = true;
+	emit changed(this);
 }
 
 void QtTreeWidgetItem::hide() {
 	shown_ = false;
-	emit changed();
+	emit changed(this);
 }
 
 void QtTreeWidgetItem::show() {
 	shown_ = true;
-	emit changed();
+	emit changed(this);
 }
 
 bool QtTreeWidgetItem::isShown() {
@@ -77,18 +79,18 @@ QtTreeWidgetItem* QtTreeWidgetItem::getParentItem() {
 
 void QtTreeWidgetItem::addChild(QtTreeWidgetItem* child) {
 	children_.append(child);
-	connect(child, SIGNAL(changed()), this, SLOT(handleChanged()));
-	handleChanged();
+	connect(child, SIGNAL(changed(QtTreeWidgetItem*)), this, SLOT(handleChanged(QtTreeWidgetItem*)));
+	handleChanged(child);
 }
 
-void QtTreeWidgetItem::handleChanged() {
+void QtTreeWidgetItem::handleChanged(QtTreeWidgetItem* child) {
 	shownChildren_.clear();
 	for (int i = 0; i < children_.size(); i++) {
 		if (children_[i]->isShown()) {
 			shownChildren_.append(children_[i]);
 		}
 	}
-	emit changed();
+	emit changed(child);
 }
 
 int QtTreeWidgetItem::rowCount() {
@@ -106,6 +108,8 @@ int QtTreeWidgetItem::row() {
 
 QtTreeWidgetItem* QtTreeWidgetItem::getItem(int row) {
 	//qDebug() << "Returning row " << row << " from item " << displayName_;
+	Q_ASSERT(row >= 0);
+	Q_ASSERT(row < rowCount());
 	return shownChildren_[row];
 }
 
@@ -125,4 +129,8 @@ bool QtTreeWidgetItem::isContact() {
 	return children_.size() == 0;
 }
 
+bool QtTreeWidgetItem::isExpanded() {
+	return expanded_;
+}
+
 }
\ No newline at end of file
diff --git a/Swift/QtUI/Roster/QtTreeWidgetItem.h b/Swift/QtUI/Roster/QtTreeWidgetItem.h
index 0a32940..73da92f 100644
--- a/Swift/QtUI/Roster/QtTreeWidgetItem.h
+++ b/Swift/QtUI/Roster/QtTreeWidgetItem.h
@@ -43,14 +43,15 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			void show();
 			bool isShown();
 			bool isContact();
+			bool isExpanded();
 
 			QWidget* getCollapsedRosterWidget();
 			QWidget* getExpandedRosterWidget();
 		
 		signals:
-			void changed();
+			void changed(QtTreeWidgetItem*);
 		private slots:
-			void handleChanged();
+			void handleChanged(QtTreeWidgetItem* item);
 		private:
 			QList<QtTreeWidgetItem*> children_;
 			QList<QtTreeWidgetItem*> shownChildren_;
@@ -61,6 +62,7 @@ class QtTreeWidgetItem : public QObject, public TreeWidgetItem {
 			QColor backgroundColor_;
 			QVariant avatar_;
 			bool shown_;
+			bool expanded_;
 };
 
 }
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index f322792..30d8135 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -11,16 +11,23 @@ RosterModel::~RosterModel() {
 
 void RosterModel::setRoot(QtTreeWidgetItem* root) {
 	tree_ = root;
-	connect(tree_, SIGNAL(changed()), this, SLOT(handleItemChanged()));
+	connect(tree_, SIGNAL(changed(QtTreeWidgetItem*)), this, SLOT(handleItemChanged(QtTreeWidgetItem*)));
 }
 							  
 
-void RosterModel::handleItemChanged() {
-	//FIXME: This is just a lazy hack to cause the view to refresh until it works.
-	// Then I'll replace it with the proper implementation.
-	//printf("Changed\n");
+void RosterModel::handleItemChanged(QtTreeWidgetItem* item) {
+	if (!item->isShown()) {
+		return;
+	}
+	//these two lines should be redundant, but...
 	reset();
 	emit layoutChanged();
+	//These lines don't seem to be enough
+	Q_ASSERT(item);
+	QModelIndex modelIndex = index(item);
+	emit itemExpanded(modelIndex, item->isExpanded());
+	emit dataChanged(modelIndex, modelIndex);
+	
 }
 
 int RosterModel::columnCount(const QModelIndex& parent) const {
@@ -40,6 +47,19 @@ QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) c
 	return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
 }
 
+QModelIndex RosterModel::index(QtTreeWidgetItem* item) const {
+	QtTreeWidgetItem* parentItem = item->getParentItem();
+	Q_ASSERT(parentItem);
+	QModelIndex parentIndex = parent(item);
+	return index(item->row(), 0, parentIndex);
+}
+
+QModelIndex RosterModel::parent(QtTreeWidgetItem* item) const {
+	QtTreeWidgetItem* parentItem = item->getParentItem();
+	return parentItem == tree_ ? QModelIndex() : index(parentItem->row(), 0, parent(parentItem));
+}
+
+
 QModelIndex RosterModel::parent(const QModelIndex& index) const {
 	if (!index.isValid()) {
 		return QModelIndex();
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
index e75bc2f..c1d998c 100644
--- a/Swift/QtUI/Roster/RosterModel.h
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -15,10 +15,14 @@ public:
 	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;
+	QModelIndex index(QtTreeWidgetItem* item) const;
 	QModelIndex parent(const QModelIndex& index) const;
+	QModelIndex parent(QtTreeWidgetItem* item) const;
 	int rowCount(const QModelIndex& parent = QModelIndex()) const;
+signals:
+	void itemExpanded(const QModelIndex& item, bool expanded);
 private slots:
-	void handleItemChanged();
+	void handleItemChanged(QtTreeWidgetItem* item);
 private:
 	QtTreeWidgetItem* tree_;
 };
diff --git a/Swift/QtUI/Roster/main.cpp b/Swift/QtUI/Roster/main.cpp
index 60ee592..660dce9 100644
--- a/Swift/QtUI/Roster/main.cpp
+++ b/Swift/QtUI/Roster/main.cpp
@@ -15,6 +15,7 @@ int main(int argc, char *argv[])
 
 	Swift::QtTreeWidgetFactory treeWidgetFactory;
 	Swift::QtTreeWidget* tree = dynamic_cast<Swift::QtTreeWidget*>(treeWidgetFactory.createTreeWidget());
+	tree->show();
 	for (int i = 0; i < 500; i++) {
 		Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
 		group->setText("People");
@@ -26,8 +27,9 @@ int main(int argc, char *argv[])
 		item1->setText("Remko");
 		item2->setText("Kevin");
 		item3->setText("Cath");
+		item4->setText("KimTypo");
 		item4->setText("Kim");
 	}
-	tree->show();
+	
     return app.exec();
 }
\ No newline at end of file
-- 
cgit v0.10.2-6-g49f6


From f948f047401021f3afc8a015991fc81e7d69d6ce Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sat, 8 Aug 2009 15:39:06 +0100
Subject: Group expandedness in roster persists between roster changes.


diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index 30d8135..1df2117 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -19,15 +19,12 @@ void RosterModel::handleItemChanged(QtTreeWidgetItem* item) {
 	if (!item->isShown()) {
 		return;
 	}
-	//these two lines should be redundant, but...
-	reset();
-	emit layoutChanged();
-	//These lines don't seem to be enough
 	Q_ASSERT(item);
 	QModelIndex modelIndex = index(item);
+	Q_ASSERT(modelIndex.isValid());
 	emit itemExpanded(modelIndex, item->isExpanded());
 	emit dataChanged(modelIndex, modelIndex);
-	
+	emit layoutChanged();
 }
 
 int RosterModel::columnCount(const QModelIndex& parent) const {
@@ -48,18 +45,9 @@ QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) c
 }
 
 QModelIndex RosterModel::index(QtTreeWidgetItem* item) const {
-	QtTreeWidgetItem* parentItem = item->getParentItem();
-	Q_ASSERT(parentItem);
-	QModelIndex parentIndex = parent(item);
-	return index(item->row(), 0, parentIndex);
+	return createIndex(item->row(), 0, item);
 }
 
-QModelIndex RosterModel::parent(QtTreeWidgetItem* item) const {
-	QtTreeWidgetItem* parentItem = item->getParentItem();
-	return parentItem == tree_ ? QModelIndex() : index(parentItem->row(), 0, parent(parentItem));
-}
-
-
 QModelIndex RosterModel::parent(const QModelIndex& index) const {
 	if (!index.isValid()) {
 		return QModelIndex();
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
index c1d998c..fc9b1f3 100644
--- a/Swift/QtUI/Roster/RosterModel.h
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -17,7 +17,6 @@ public:
 	QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
 	QModelIndex index(QtTreeWidgetItem* item) const;
 	QModelIndex parent(const QModelIndex& index) const;
-	QModelIndex parent(QtTreeWidgetItem* item) const;
 	int rowCount(const QModelIndex& parent = QModelIndex()) const;
 signals:
 	void itemExpanded(const QModelIndex& item, bool expanded);
-- 
cgit v0.10.2-6-g49f6