From e51448532f837d3ac28ea3c9b03f711df1940803 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Fri, 16 Apr 2010 16:09:23 +0100
Subject: Slighly better rendering for the Event view.


diff --git a/Swift/QtUI/EventViewer/EventDelegate.cpp b/Swift/QtUI/EventViewer/EventDelegate.cpp
index 61a9fbd..8bdeb46 100644
--- a/Swift/QtUI/EventViewer/EventDelegate.cpp
+++ b/Swift/QtUI/EventViewer/EventDelegate.cpp
@@ -6,9 +6,54 @@
 
 #include "EventDelegate.h"
 
+#include <QDebug>
+
+#include "Swiften/Events/MessageEvent.h"
+#include "Swiften/Events/ErrorEvent.h"
+#include "Swiften/Events/SubscriptionRequestEvent.h"
+
 namespace Swift {
 
-EventDelegate::EventDelegate() : QStyledItemDelegate() {
+EventDelegate::EventDelegate() : QStyledItemDelegate(), messageDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false), subscriptionDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true), errorDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true) {
+
+}
+
+QSize EventDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
+	QtEvent* item = static_cast<QtEvent*>(index.internalPointer());
+	if (!item) {
+		return QStyledItemDelegate::sizeHint(option, index);
+	}
+	switch (getEventType(item->getEvent())) {
+	case MessageEventType: return messageDelegate_.sizeHint(option, item);
+	case SubscriptionEventType: return subscriptionDelegate_.sizeHint(option, item);
+	case ErrorEventType: return errorDelegate_.sizeHint(option, item);
+	default: return QStyledItemDelegate::sizeHint(option, index);
+	}
+}
+
+void EventDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+	QtEvent* item = static_cast<QtEvent*>(index.internalPointer());
+	if (!item) {
+		QStyledItemDelegate::paint(painter, option, index);
+		return;
+	}
+	switch (getEventType(item->getEvent())) {
+	case MessageEventType: messageDelegate_.paint(painter, option, item);break;
+	case SubscriptionEventType: subscriptionDelegate_.paint(painter, option, item);break;
+	case ErrorEventType: errorDelegate_.paint(painter, option, item);break;
+	default: QStyledItemDelegate::paint(painter, option, index);
+	}
+}
+
+EventType EventDelegate::getEventType(boost::shared_ptr<StanzaEvent> event) const {
+	boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event);
+	if (messageEvent) return MessageEventType;
+	boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event);
+	if (subscriptionEvent) return SubscriptionEventType;
+	boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event);
+	if (errorEvent) return ErrorEventType;
+	//I don't know what this is.
+	assert(false);
 
 }
 
diff --git a/Swift/QtUI/EventViewer/EventDelegate.h b/Swift/QtUI/EventViewer/EventDelegate.h
index 4343a96..2ad741c 100644
--- a/Swift/QtUI/EventViewer/EventDelegate.h
+++ b/Swift/QtUI/EventViewer/EventDelegate.h
@@ -8,11 +8,23 @@
 
 #include <QStyledItemDelegate>
 
+#include "Swift/QtUI/Roster/DelegateCommons.h"
+#include "Swift/QtUI/EventViewer/TwoLineDelegate.h"
+
 namespace Swift {
+	enum EventType {MessageEventType, SubscriptionEventType, ErrorEventType};
 	class EventDelegate : public QStyledItemDelegate {
 		Q_OBJECT
 		public:
 			EventDelegate();
+			QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+			void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+		private:
+			EventType getEventType(boost::shared_ptr<StanzaEvent> event) const;
+			DelegateCommons common_;
+			TwoLineDelegate messageDelegate_;
+			TwoLineDelegate subscriptionDelegate_;
+			TwoLineDelegate errorDelegate_;
 	};
 }
 
diff --git a/Swift/QtUI/EventViewer/EventModel.cpp b/Swift/QtUI/EventViewer/EventModel.cpp
index 065c3eb..a19027a 100644
--- a/Swift/QtUI/EventViewer/EventModel.cpp
+++ b/Swift/QtUI/EventViewer/EventModel.cpp
@@ -39,6 +39,17 @@ QVariant EventModel::data(const QModelIndex& index, int role) const {
 	return result;
 }
 
+/*
+ * We only reimplement this to get the pointers inside the indices.
+ */
+QModelIndex EventModel::index(int row, int column, const QModelIndex & parent) const {
+	if (!hasIndex(row, column, parent) || parent.isValid()) {
+		return QModelIndex();
+	}
+
+	return row < rowCount() ? createIndex(row, column, getItem(row)) : QModelIndex();
+}
+
 int EventModel::rowCount(const QModelIndex& parent) const {
 	/* Invalid parent = root, valid parent = child, and we're a list not a tree.*/
 	int count = parent.isValid() ? 0 : activeEvents_.size() + inactiveEvents_.size();
diff --git a/Swift/QtUI/EventViewer/EventModel.h b/Swift/QtUI/EventViewer/EventModel.h
index 0f9d070..f031c0b 100644
--- a/Swift/QtUI/EventViewer/EventModel.h
+++ b/Swift/QtUI/EventViewer/EventModel.h
@@ -17,19 +17,21 @@
 
 namespace Swift {
 class EventModel : public QAbstractListModel {
-Q_OBJECT
-public:
-	EventModel();
-	~EventModel();
-	void addEvent(boost::shared_ptr<StanzaEvent> event, bool active);
-	void removeEvent(boost::shared_ptr<StanzaEvent> event);
-	QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-	int rowCount(const QModelIndex& parent = QModelIndex()) const;
-	QtEvent* getItem(int row) const;
-	int getNewEventCount();
-private:
-	QList<QtEvent*> activeEvents_;
-	QList<QtEvent*> inactiveEvents_;
+	Q_OBJECT
+	public:
+		EventModel();
+		~EventModel();
+		void addEvent(boost::shared_ptr<StanzaEvent> event, bool active);
+		void removeEvent(boost::shared_ptr<StanzaEvent> event);
+		QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+		int rowCount(const QModelIndex& parent = QModelIndex()) const;
+		QtEvent* getItem(int row) const;
+		int getNewEventCount();
+	protected:
+		QModelIndex	index ( int row, int column = 0, const QModelIndex & parent = QModelIndex() ) const;
+	private:
+		QList<QtEvent*> activeEvents_;
+		QList<QtEvent*> inactiveEvents_;
 };
 
 }
diff --git a/Swift/QtUI/EventViewer/QtEvent.cpp b/Swift/QtUI/EventViewer/QtEvent.cpp
index 76875ae..844a7f7 100644
--- a/Swift/QtUI/EventViewer/QtEvent.cpp
+++ b/Swift/QtUI/EventViewer/QtEvent.cpp
@@ -24,6 +24,7 @@ QVariant QtEvent::data(int role) {
 		case Qt::DisplayRole: return QVariant(text());
 		case Qt::TextColorRole: return active_ ? Qt::black : Qt::darkGray;
 		case Qt::BackgroundColorRole: return active_ ? Qt::white : Qt::lightGray;
+		case SenderRole: return QVariant(sender());
 			/*case StatusTextRole: return statusText_;
 		case AvatarRole: return avatar_;
 		case PresenceIconRole: return getPresenceIcon();*/
@@ -31,6 +32,22 @@ QVariant QtEvent::data(int role) {
 	}
 }
 
+QString QtEvent::sender() {
+	boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event_);
+	if (messageEvent) {
+		return P2QSTRING(messageEvent->getStanza()->getFrom().toString());
+	}
+	boost::shared_ptr<SubscriptionRequestEvent> subscriptionRequestEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event_);
+	if (subscriptionRequestEvent) {
+		return P2QSTRING(subscriptionRequestEvent->getJID().toBare().toString());
+	}
+	boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event_);
+	if (errorEvent) {
+		return P2QSTRING(errorEvent->getJID().toBare().toString());
+	}
+	return "";
+}
+
 QString QtEvent::text() {
 	boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event_);
 	if (messageEvent) {
diff --git a/Swift/QtUI/EventViewer/QtEvent.h b/Swift/QtUI/EventViewer/QtEvent.h
index f429b4a..be036dd 100644
--- a/Swift/QtUI/EventViewer/QtEvent.h
+++ b/Swift/QtUI/EventViewer/QtEvent.h
@@ -18,8 +18,14 @@ namespace Swift {
 			QtEvent(boost::shared_ptr<StanzaEvent> event, bool active);
 			QVariant data(int role);
 			boost::shared_ptr<StanzaEvent> getEvent() { return event_; };
+			enum EventRoles {
+				SenderRole = Qt::UserRole
+
+			};
+
 		private:
 			QString text();
+			QString sender();
 			boost::shared_ptr<StanzaEvent> event_;
 			bool active_;
 	};
diff --git a/Swift/QtUI/EventViewer/TwoLineDelegate.cpp b/Swift/QtUI/EventViewer/TwoLineDelegate.cpp
new file mode 100644
index 0000000..2437a44
--- /dev/null
+++ b/Swift/QtUI/EventViewer/TwoLineDelegate.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "TwoLineDelegate.h"
+
+#include <QPen>
+#include <QPainter>
+#include <QDebug>
+
+namespace Swift {
+TwoLineDelegate::TwoLineDelegate(int firstRole, int secondRole, bool wrap) {
+	firstRole_ = firstRole;
+	secondRole_ = secondRole;
+	wrap_ = wrap;
+}
+
+TwoLineDelegate::~TwoLineDelegate() {
+
+}
+
+QSize TwoLineDelegate::sizeHint(const QStyleOptionViewItem& /*option*/, QtEvent* /*event*/ ) const {
+	QFontMetrics nameMetrics(common_.nameFont);
+	QFontMetrics statusMetrics(common_.detailFont);
+	int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
+	return QSize(150, sizeByText);
+}
+
+void TwoLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, QtEvent* event) const {
+	painter->save();
+	QRect fullRegion(option.rect);
+	if ( option.state & QStyle::State_Selected ) {
+		painter->fillRect(fullRegion, option.palette.highlight());
+		painter->setPen(option.palette.highlightedText().color());
+	} else {
+		QColor nameColor = event->data(Qt::TextColorRole).value<QColor>();
+		painter->setPen(QPen(nameColor));
+	}
+
+	QFontMetrics nameMetrics(common_.nameFont);
+	painter->setFont(common_.nameFont);
+	int extraFontWidth = nameMetrics.width("H");
+	int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
+	QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
+	
+	int nameHeight = nameMetrics.height() + common_.verticalMargin;
+	QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
+	
+	painter->drawText(nameRegion, Qt::AlignTop, event->data(firstRole_).toString());
+	
+	painter->setFont(common_.detailFont);
+	painter->setPen(QPen(QColor(160,160,160)));
+	
+	QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+	painter->drawText(detailRegion, Qt::AlignTop, event->data(secondRole_).toString());
+	
+	painter->restore();
+}
+
+}
diff --git a/Swift/QtUI/EventViewer/TwoLineDelegate.h b/Swift/QtUI/EventViewer/TwoLineDelegate.h
new file mode 100644
index 0000000..15a4476
--- /dev/null
+++ b/Swift/QtUI/EventViewer/TwoLineDelegate.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <QStyledItemDelegate>
+
+#include "Swift/QtUI/Roster/DelegateCommons.h"
+#include "QtEvent.h"
+
+namespace Swift {
+	class TwoLineDelegate {
+		public:
+			TwoLineDelegate(int firstRole, int secondRole, bool wrap);
+			~TwoLineDelegate();
+			QSize sizeHint(const QStyleOptionViewItem& option, QtEvent* event) const;
+			void paint(QPainter* painter, const QStyleOptionViewItem& option, QtEvent* event) const;
+		private:
+			DelegateCommons common_;
+			int firstRole_;
+			int secondRole_;
+			bool wrap_;
+	};
+
+}
+
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index b88e217..151cc3a 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -84,6 +84,7 @@ sources = [
     "Roster/DelegateCommons.cpp",
     "EventViewer/EventModel.cpp",
     "EventViewer/EventDelegate.cpp",
+    "EventViewer/TwoLineDelegate.cpp",
     "EventViewer/QtEventWindowFactory.cpp",
     "EventViewer/QtEventWindow.cpp",
     "EventViewer/QtEvent.cpp",
-- 
cgit v0.10.2-6-g49f6