Screenshot:

http://img223.imageshack.us/img223/4251/chatwindow1ms7.png

Trying to get the chatwindow back to a usable state, this patch:
 - removes the sidebar (broken, unusable)
 - use a members list based on a dockable widget, but
   without using all features or space. So it is implemented like now but it 
looks like before.
 - use a model over a chat session to show the members (deprecating hundred of 
lines of code with a few of them plus a really small an simple model)
 - port the Q3 stuff to Qt 4 there
 - remove _lot_ of uneeded and non robust code

What is missing:
- The drag and drop part of the members view
From 298f280d39b6b3c09beb72b421a0f71875daecba Mon Sep 17 00:00:00 2001
From: Duncan Mac-Vicar P <[EMAIL PROTECTED]>
Date: Tue, 13 Nov 2007 17:46:02 +0100
Subject: [PATCH] - Make the chat window usable in KDE4 again
 - remove the sidebar
 - use a members list based on a dockable widget, but
   without using all features or space
 - use a model over a chat session to show it
 - port the Q3 stuff to Qt 4 there
 - remove _lot_ of uneeded and non robust code

---
 kopete/kopete/chatwindow/CMakeLists.txt            |    2 +-
 kopete/kopete/chatwindow/chatmemberslistview.cpp   |   66 +++++
 kopete/kopete/chatwindow/chatmemberslistview.h     |   51 ++++
 kopete/kopete/chatwindow/chatmemberslistwidget.cpp |  283 --------------------
 kopete/kopete/chatwindow/chatmemberslistwidget.h   |  127 ---------
 kopete/kopete/chatwindow/chatmessagepart.cpp       |    5 +-
 kopete/kopete/chatwindow/kopetechatwindow.cpp      |   28 ++-
 kopete/kopete/chatwindow/kopetechatwindow.h        |    5 +-
 kopete/kopete/chatwindow/kopetechatwindow.rc       |    2 +-
 kopete/kopete/chatwindow/sidebarwidget.cpp         |  131 ---------
 kopete/kopete/chatwindow/sidebarwidget.h           |   79 ------
 kopete/libkopete/CMakeLists.txt                    |    1 +
 kopete/libkopete/chatsessionmemberslistmodel.cpp   |  151 +++++++++++
 kopete/libkopete/chatsessionmemberslistmodel.h     |   81 ++++++
 14 files changed, 378 insertions(+), 634 deletions(-)
 create mode 100644 kopete/kopete/chatwindow/chatmemberslistview.cpp
 create mode 100644 kopete/kopete/chatwindow/chatmemberslistview.h
 delete mode 100644 kopete/kopete/chatwindow/chatmemberslistwidget.cpp
 delete mode 100644 kopete/kopete/chatwindow/chatmemberslistwidget.h
 delete mode 100644 kopete/kopete/chatwindow/sidebarwidget.cpp
 delete mode 100644 kopete/kopete/chatwindow/sidebarwidget.h
 create mode 100644 kopete/libkopete/chatsessionmemberslistmodel.cpp
 create mode 100644 kopete/libkopete/chatsessionmemberslistmodel.h

diff --git a/kopete/kopete/chatwindow/CMakeLists.txt b/kopete/kopete/chatwindow/CMakeLists.txt
index 575ab0d..77b488e 100644
--- a/kopete/kopete/chatwindow/CMakeLists.txt
+++ b/kopete/kopete/chatwindow/CMakeLists.txt
@@ -39,7 +39,7 @@ install(TARGETS krichtexteditpart  DESTINATION ${PLUGIN_INSTALL_DIR})
 
 ########### next target ###############
 
-set(kopete_chatwindow_PART_SRCS chatview.cpp kopetechatwindow.cpp chatmemberslistwidget.cpp sidebarwidget.cpp)
+set(kopete_chatwindow_PART_SRCS chatview.cpp kopetechatwindow.cpp chatmemberslistview.cpp)
 
 
 kde4_add_plugin(kopete_chatwindow ${kopete_chatwindow_PART_SRCS})
diff --git a/kopete/kopete/chatwindow/chatmemberslistview.cpp b/kopete/kopete/chatwindow/chatmemberslistview.cpp
new file mode 100644
index 0000000..02b5f99
--- /dev/null
+++ b/kopete/kopete/chatwindow/chatmemberslistview.cpp
@@ -0,0 +1,66 @@
+/*
+    ChatMembersListView
+
+    Copyright (c) 2007 by Duncan Mac-Vicar Prett <[EMAIL PROTECTED]>
+   
+    Kopete    (c) 2002-2007 by the Kopete developers  <[email protected]>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+
+#include <QToolTip>
+#include <QHelpEvent>
+#include <QDrag>
+#include <QMimeData>
+
+#include "kdebug.h"
+#include "kmenu.h"
+#include "kopetecontact.h"
+#include "chatmemberslistview.h"
+#include "chatsessionmemberslistmodel.h"
+
+using namespace Kopete;
+
+ChatMembersListView::ChatMembersListView( QWidget *parent )
+	 : QListView( parent )
+{
+	setContextMenuPolicy (Qt::CustomContextMenu);
+	connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(slotContextMenuRequested(const QPoint &)));
+}
+
+void ChatMembersListView::slotContextMenuRequested( const QPoint & pos )
+{
+	kDebug() << "context menu requested";
+	QModelIndex index = indexAt(pos);
+	if ( model() )
+	{
+		ChatSessionMembersListModel *membermodel = dynamic_cast<ChatSessionMembersListModel *>(model());
+		if ( membermodel )
+		{
+			Kopete::Contact *c = membermodel->contactAt(index);
+			
+			if (!c)
+				return;
+	
+			KMenu *p = c->popupMenu( membermodel->session() );
+			connect( p, SIGNAL( aboutToHide() ), p, SLOT( deleteLater() ) );
+			p->popup( mapToGlobal(pos) );
+		}
+	}
+}
+
+ChatMembersListView::~ChatMembersListView()
+{
+}
+
+#include "chatmemberslistview.moc"
+
+// vim: set noet ts=4 sts=4 sw=4:
+
diff --git a/kopete/kopete/chatwindow/chatmemberslistview.h b/kopete/kopete/chatwindow/chatmemberslistview.h
new file mode 100644
index 0000000..54ae029
--- /dev/null
+++ b/kopete/kopete/chatwindow/chatmemberslistview.h
@@ -0,0 +1,51 @@
+/*
+    ChatMembersListView
+
+    Copyright (c) 2007 by Duncan Mac-Vicar Prett <[EMAIL PROTECTED]>
+   
+    Kopete    (c) 2002-2007 by the Kopete developers  <[email protected]>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+
+#ifndef CHATMEMBERSLISTWIDGET_H
+#define CHATMEMBERSLISTWIDGET_H
+
+#include <QListView>
+
+#include <qmap.h>
+
+namespace Kopete
+{
+class ChatSession;
+class Contact;
+class OnlineStatus;
+class PropertyContainer;
+}
+
+/**
+ * @author Duncan Mac-Vicar P. <[EMAIL PROTECTED]>
+ */
+class ChatMembersListView : public QListView
+{
+	Q_OBJECT
+public:
+	explicit ChatMembersListView( QWidget *parent = 0);
+	virtual ~ChatMembersListView();
+
+public slots:
+	void slotContextMenuRequested( const QPoint & pos );
+private:
+};
+
+#endif
+
+// vim: set noet ts=4 sts=4 sw=4:
+
diff --git a/kopete/kopete/chatwindow/chatmemberslistwidget.cpp b/kopete/kopete/chatwindow/chatmemberslistwidget.cpp
deleted file mode 100644
index c43038a..0000000
--- a/kopete/kopete/chatwindow/chatmemberslistwidget.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
-    chatmemberslistwidget.cpp - Chat Members List Widget
-
-    Copyright (c) 2004      by Richard Smith         <[EMAIL PROTECTED]>
-
-    Kopete    (c) 2002-2004 by the Kopete developers <[email protected]>
-
-    *************************************************************************
-    *                                                                       *
-    * This program is free software; you can redistribute it and/or modify  *
-    * it under the terms of the GNU General Public License as published by  *
-    * the Free Software Foundation; either version 2 of the License, or     *
-    * (at your option) any later version.                                   *
-    *                                                                       *
-    *************************************************************************
-*/
-
-#include "chatmemberslistwidget.h"
-
-#include "kopetechatsession.h"
-#include "kopetecontact.h"
-#include "kopeteonlinestatus.h"
-#include "kopeteglobal.h"
-#include "kopeteprotocol.h"
-#include "kopeteaccount.h"
-#include "kopetemetacontact.h"
-
-#include <kabc/stdaddressbook.h>
-#include <kabc/addressee.h>
-#include <kabc/vcardconverter.h>
-#include <kdebug.h>
-#include <k3multipledrag.h>
-
-#include <kmenu.h>
-
-#include <q3header.h>
-
-
-//BEGIN ChatMembersListWidget::ToolTip
-/*
-class ChatMembersListWidget::ToolTip : public QToolTip
-{
-public:
-	ToolTip( K3ListView *parent )
-		: QToolTip( parent->viewport() ), m_listView ( parent )
-	{
-	}
-
-	virtual ~ToolTip()
-	{
-		remove( m_listView->viewport() );
-	}
-
-	void maybeTip( const QPoint &pos )
-	{
-		if( Q3ListViewItem *item = m_listView->itemAt( pos ) )
-		{
-			QRect itemRect = m_listView->itemRect( item );
-			if( itemRect.contains( pos ) )
-				tip( itemRect, static_cast<ContactItem*>( item )->contact()->toolTip() );
-		}
-	}
-
-private:
-	K3ListView *m_listView;
-};
-*/
-//END ChatMembersListWidget::ToolTip
-
-
-//BEGIN ChatMembersListWidget::ContactItem
-
-ChatMembersListWidget::ContactItem::ContactItem( ChatMembersListWidget *parent, Kopete::Contact *contact )
-	: K3ListViewItem( parent ), m_contact( contact )
-{
-	QString nick = m_contact->property(Kopete::Global::Properties::self()->nickName().key()).value().toString();
-	if ( nick.isEmpty() )
-		nick = m_contact->contactId();
-	setText( 0, nick );
-	setDragEnabled(true);
-
-	connect( m_contact, SIGNAL( propertyChanged( Kopete::PropertyContainer *, const QString &, const QVariant &, const QVariant & ) ),
-	         this, SLOT( slotPropertyChanged( Kopete::PropertyContainer *, const QString &, const QVariant &, const QVariant & ) ) ) ;
-
-	setStatus( parent->session()->contactOnlineStatus(m_contact) );
-	reposition();
-}
-
-void ChatMembersListWidget::ContactItem::slotPropertyChanged( Kopete::PropertyContainer*,
-	const QString &key, const QVariant&, const QVariant &newValue  )
-{
-	if ( key == Kopete::Global::Properties::self()->nickName().key() )
-	{
-		setText( 0, newValue.toString() );
-		reposition();
-	}
-}
-
-void ChatMembersListWidget::ContactItem::setStatus( const Kopete::OnlineStatus &status )
-{
-	setPixmap( 0, status.iconFor( m_contact ) );
-	reposition();
-}
-
-void ChatMembersListWidget::ContactItem::reposition()
-{
-	// Qt's listview sorting is pathetic - it's impossible to reposition a single item
-	// when its key changes, without re-sorting the whole list. Plus, the whole list gets
-	// re-sorted whenever an item is added/removed. So, we do manual sorting.
-	// In particular, this makes adding N items O(N^2) not O(N^2 log N).
-	Kopete::ChatSession *session = static_cast<ChatMembersListWidget*>( listView() )->session();
-	int ourWeight = session->contactOnlineStatus(m_contact).weight();
-	Q3ListViewItem *after = 0;
-
-	for ( Q3ListViewItem *it = K3ListViewItem::listView()->firstChild(); it; it = it->nextSibling() )
-	{
-		ChatMembersListWidget::ContactItem *item = static_cast<ChatMembersListWidget::ContactItem*>(it);
-		int theirWeight = session->contactOnlineStatus(item->m_contact).weight();
-
-		if( theirWeight < ourWeight ||
-			(theirWeight == ourWeight && item->text(0).localeAwareCompare( text(0) ) > 0 ) )
-		{
-			break;
-		}
-
-		after = it;
-	}
-
-	moveItem( after );
-}
-
-//END ChatMembersListWidget::ContactItem
-
-
-//BEGIN ChatMembersListWidget
-
-ChatMembersListWidget::ChatMembersListWidget( QWidget *parent, Kopete::ChatSession *session )
-	 : K3ListView( parent ), m_session( session )
-{
-	// use our own custom tooltips
-//	setShowToolTips( false );
-//	m_toolTip = new ToolTip( this );
-
-	// set up display: no header
-	setAllColumnsShowFocus( true );
-	addColumn( QString::null, -1 );	//krazy:exclude=nullstrassign for old broken gcc
-	header()->setStretchEnabled( true, 0 );
-	header()->hide();
-
-	// list is sorted by us, not by Qt
-	setSorting( -1 );
-
-	if ( session )
-		setChatSession( session );
-}
-
-ChatMembersListWidget::~ChatMembersListWidget()
-{
-}
-
-void ChatMembersListWidget::slotContextMenu( K3ListView*, Q3ListViewItem *item, const QPoint &point )
-{
-	if ( ContactItem *contactItem = dynamic_cast<ContactItem*>(item) )
-	{
-		KMenu *p = contactItem->contact()->popupMenu( session() );
-		connect( p, SIGNAL( aboutToHide() ), p, SLOT( deleteLater() ) );
-		p->popup( point );
-	}
-}
-
-void ChatMembersListWidget::slotContactAdded( const Kopete::Contact *contact )
-{
-	if ( !m_members.contains( contact ) )
-		m_members.insert( contact, new ContactItem( this, const_cast<Kopete::Contact*>( contact ) ) );
-}
-
-void ChatMembersListWidget::slotContactRemoved( const Kopete::Contact *contact )
-{
-	kDebug(14000) ;
-	if ( m_members.contains( contact ) && contact != session()->myself() )
-	{
-		delete m_members[ contact ];
-		m_members.remove( contact );
-	}
-}
-
-void ChatMembersListWidget::slotContactStatusChanged( Kopete::Contact *contact, const Kopete::OnlineStatus &status )
-{
-	if ( m_members.contains( contact ) )
-		m_members[contact]->setStatus( status );
-}
-
-void ChatMembersListWidget::slotExecute( Q3ListViewItem *item )
-{
-	if ( ContactItem *contactItem = dynamic_cast<ContactItem*>(item ) )
-	{
-		Kopete::Contact *contact=contactItem->contact();
-
-		if(!contact || contact == contact->account()->myself())
-			return;
-				
-		contact->execute();
-	}
-}
-
-Q3DragObject *ChatMembersListWidget::dragObject()
-{
-	Q3ListViewItem *currentLVI = currentItem();
-	if( !currentLVI )
-		return 0L;
-
-	ContactItem *lvi = dynamic_cast<ContactItem*>( currentLVI );
-	if( !lvi )
-		return 0L;
-
-	Kopete::Contact *c = lvi->contact();
-	K3MultipleDrag *drag = new K3MultipleDrag( this );
-	drag->addDragObject( new Q3StoredDrag("application/x-qlistviewitem", 0L ) );
-
-	Q3StoredDrag *d = new Q3StoredDrag("kopete/x-contact", 0L );
-	d->setEncodedData( QString( c->protocol()->pluginId()+QChar( 0xE000 )+c->account()->accountId()+QChar( 0xE000 )+ c->contactId() ).toUtf8() );
-	drag->addDragObject( d );
-
-	KABC::Addressee address = KABC::StdAddressBook::self()->findByUid(c->metaContact()->metaContactId());
-
-	if( !address.isEmpty() )
-	{
-		drag->addDragObject( new Q3TextDrag( address.fullEmail(), 0L ) );
-		KABC::VCardConverter converter;
-		QString vcard = converter.createVCard( address );
-		if( !vcard.isNull() )
-		{
-			Q3StoredDrag *vcardDrag = new Q3StoredDrag("text/directory", 0L );
-			vcardDrag->setEncodedData( vcard.toUtf8() );
-			drag->addDragObject( vcardDrag );
-		}
-	}
-
-	drag->setPixmap( c->onlineStatus().iconFor(c, 12) );
-
-	return drag;
-	return 0l;
-}
-
-void ChatMembersListWidget::setChatSession(Kopete::ChatSession *session)
-{
-	if (m_session)
-	{
-		// Work on the old session
-		// clear the list (foreach is delete-safe as it works on a copy of the container).
-		foreach ( Kopete::Contact *it, m_session->members() )
-		{
-			slotContactRemoved( it );
-		}
-	}
-
-	// Now work on the new session
-	m_session = session;
-	
-	// add chat members
-	slotContactAdded( session->myself() );
-	foreach ( Kopete::Contact* it ,  session->members() ) 
-		slotContactAdded( it );
-
-
-	connect( this, SIGNAL( contextMenu( K3ListView*, Q3ListViewItem *, const QPoint &) ),
-	         SLOT( slotContextMenu(K3ListView*, Q3ListViewItem *, const QPoint & ) ) );
-	connect( this, SIGNAL( executed( Q3ListViewItem* ) ),
-	         SLOT( slotExecute( Q3ListViewItem * ) ) );
-
-	connect( session, SIGNAL( contactAdded(const Kopete::Contact*, bool) ),
-	         this, SLOT( slotContactAdded(const Kopete::Contact*) ) );
-	connect( session, SIGNAL( contactRemoved(const Kopete::Contact*, const QString&, Qt::TextFormat, bool) ),
-	         this, SLOT( slotContactRemoved(const Kopete::Contact*) ) );
-	connect( session, SIGNAL( onlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus & , const Kopete::OnlineStatus &) ),
-	         this, SLOT( slotContactStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus & ) ) );
-}
-//END ChatMembersListWidget
-
-#include "chatmemberslistwidget.moc"
-
-// vim: set noet ts=4 sts=4 sw=4:
-
diff --git a/kopete/kopete/chatwindow/chatmemberslistwidget.h b/kopete/kopete/chatwindow/chatmemberslistwidget.h
deleted file mode 100644
index 2a40d0c..0000000
--- a/kopete/kopete/chatwindow/chatmemberslistwidget.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-    chatmemberslistwidget.h - Chat Members List Widget
-
-    Copyright (c) 2004      by Richard Smith         <[EMAIL PROTECTED]>
-
-    Kopete    (c) 2002-2004 by the Kopete developers <[email protected]>
-
-    *************************************************************************
-    *                                                                       *
-    * This program is free software; you can redistribute it and/or modify  *
-    * it under the terms of the GNU General Public License as published by  *
-    * the Free Software Foundation; either version 2 of the License, or     *
-    * (at your option) any later version.                                   *
-    *                                                                       *
-    *************************************************************************
-*/
-
-#ifndef CHATMEMBERSLISTWIDGET_H
-#define CHATMEMBERSLISTWIDGET_H
-
-#include <k3listview.h>
-
-#include <qmap.h>
-
-namespace Kopete
-{
-class ChatSession;
-class Contact;
-class OnlineStatus;
-class PropertyContainer;
-}
-
-/**
- * @author Richard Smith <[EMAIL PROTECTED]>
- */
-class ChatMembersListWidget : public K3ListView
-{
-	Q_OBJECT
-public:
-	explicit ChatMembersListWidget( QWidget *parent = 0, Kopete::ChatSession *session = 0);
-	virtual ~ChatMembersListWidget();
-
-	Kopete::ChatSession *session() { return m_session; }
-
-	class ToolTip;
-	class ContactItem;
-
-protected:
-
-	/**
-	 * Start a drag operation
-	 * @return a KMultipleDrag containing:
-	 *	1) A QStoredDrag of type "application/x-qlistviewitem",
-	 *	2) If the contact is associated with a KABC entry,
-	 *		i) a QTextDrag containing their email address, and
-	 *		ii) their vCard representation.
-	 */
-	virtual Q3DragObject *dragObject();
-
-private slots:
-	/**
-	 * Show the context menu for @p item at @p point
-	 */
-	void slotContextMenu( K3ListView*, Q3ListViewItem *item, const QPoint &point );
-
-	/**
-	 * Called when a contact is added to the chat session.
-	 * Adds this contact to the contact list view.
-	 * @param c The contact that joined the chat
-	 */
-	void slotContactAdded( const Kopete::Contact *c );
-
-	/**
-	 * Called when a contact is removed from the chat session.
-	 * Removes this contact from the contact list view.
-	 * @param c The contact that left the chat
-	 */
-	void slotContactRemoved( const Kopete::Contact *c );
-
-	/**
-	 * Called when a contact changes status.
-	 * @param contact The contact who changed status
-	 * @param status The new status of the contact
-	 */
-	void slotContactStatusChanged( Kopete::Contact *contact, const Kopete::OnlineStatus &status );
-
-	/**
-	 * Called when a contact is clicked.
-	 * @param item The list view item representing the clicked contact
-	 */
-	void slotExecute( Q3ListViewItem *contact );
-	
-	/**
-	 * Called when the ChatSession change for this list (eg. when the tab in the KopeteChatWindow is changing)
-	 */
-	void setChatSession(Kopete::ChatSession *session);
-
-private:
-	Kopete::ChatSession *m_session;
-	QMap<const Kopete::Contact*, ContactItem*> m_members;
-	ToolTip *m_toolTip;
-};
-
-class ChatMembersListWidget::ContactItem : public QObject, public K3ListViewItem
-{
-	Q_OBJECT
-public:
-	ContactItem( ChatMembersListWidget *list, Kopete::Contact *contact );
-	Kopete::Contact *contact() const { return m_contact; }
-
-private slots:
-	void slotPropertyChanged( Kopete::PropertyContainer *contact, const QString &key, const QVariant &oldValue, const QVariant &newValue  );
-
-private:
-	friend class ChatMembersListWidget;
-
-	void reposition();
-	void setStatus( const Kopete::OnlineStatus &status );
-
-	Kopete::Contact *m_contact;
-};
-
-
-#endif
-
-// vim: set noet ts=4 sts=4 sw=4:
-
diff --git a/kopete/kopete/chatwindow/chatmessagepart.cpp b/kopete/kopete/chatwindow/chatmessagepart.cpp
index 246e54e..b887960 100644
--- a/kopete/kopete/chatwindow/chatmessagepart.cpp
+++ b/kopete/kopete/chatwindow/chatmessagepart.cpp
@@ -232,8 +232,9 @@ ChatMessagePart::ChatMessagePart( Kopete::ChatSession *mgr, QWidget *parent )
 
 	connect( this, SIGNAL(popupMenu(const QString &, const QPoint &)),
 	         this, SLOT(slotRightClick(const QString &, const QPoint &)) );
-	connect( view()->horizontalScrollBar(), SIGNAL(sliderMoved(int)),
-	         this, SLOT(slotScrollingTo(int)) );
+	// FIXME no longer compiles
+	//connect( view()->horizontalScrollBar(), SIGNAL(sliderMoved(int)),
+	//         this, SLOT(slotScrollingTo(int)) );
 
 	//initActions
 	d->copyAction = KStandardAction::copy( this, SLOT(copy()), actionCollection() );
diff --git a/kopete/kopete/chatwindow/kopetechatwindow.cpp b/kopete/kopete/chatwindow/kopetechatwindow.cpp
index 5a1e34c..f97c87d 100644
--- a/kopete/kopete/chatwindow/kopetechatwindow.cpp
+++ b/kopete/kopete/chatwindow/kopetechatwindow.cpp
@@ -34,6 +34,7 @@
 #include <QLabel>
 #include <QVBoxLayout>
 #include <QMenu>
+#include <QDockWidget>
 
 #ifdef CHRONO
 #include <QTime>
@@ -84,6 +85,8 @@
 #include "kopetestdaction.h"
 #include "kopeteviewmanager.h"
 #include "sidebarwidget.h"
+#include "chatmemberslistview.h"
+#include "chatsessionmemberslistmodel.h"
 
 #include <qtoolbutton.h>
 #include <kxmlguifactory.h>
@@ -93,6 +96,8 @@ typedef QMap<Kopete::Group*,KopeteChatWindow*> GroupMap;
 typedef QMap<Kopete::MetaContact*,KopeteChatWindow*> MetaContactMap;
 typedef QList<KopeteChatWindow*> WindowList;
 
+using Kopete::ChatSessionMembersListModel;
+
 namespace
 {
 	AccountMap accountMap;
@@ -204,13 +209,22 @@ KopeteChatWindow::KopeteChatWindow( QWidget *parent )
 	updateBg = true;
 	m_tabBar = 0L;
 
-	m_sideBar = new SidebarWidget(this);
-	m_sideBar->setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
-	m_sideBar->setObjectName("SideBar"); //object name is required for automatic position and settings save.
+	m_participantsWidget = new QDockWidget(this);
+	m_participantsWidget->setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
+	m_participantsWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
+	m_participantsWidget->setTitleBarWidget(0L);
+	m_participantsWidget->setObjectName("Participants"); //object name is required for automatic position and settings save.
+
+	ChatSessionMembersListModel *members_model = new ChatSessionMembersListModel(this);
+
+	connect(this, SIGNAL(chatSessionChanged(Kopete::ChatSession *)), members_model, SLOT(setChatSession(Kopete::ChatSession *)));
 
+	ChatMembersListView *chatmembers = new ChatMembersListView(m_participantsWidget);
+	chatmembers->setModel(members_model);
+	m_participantsWidget->setWidget(chatmembers);
 	initActions();
 
-	addDockWidget(Qt::RightDockWidgetArea, m_sideBar);
+	addDockWidget(Qt::RightDockWidgetArea, m_participantsWidget);
 
 	KVBox *vBox = new KVBox( this );
 	vBox->setLineWidth( 0 );
@@ -447,9 +461,9 @@ void KopeteChatWindow::initActions(void)
 	toggleAutoSpellCheck->setChecked( true );
 	connect( toggleAutoSpellCheck, SIGNAL(triggered(bool)), this, SLOT(toggleAutoSpellChecking()) );
 
-	QAction *toggleSideBarAction = m_sideBar->toggleViewAction( );
-	toggleSideBarAction->setText( i18n( "Show Sidebar" ) );
-	coll->addAction ( "show_sidebar_widget", toggleSideBarAction );
+	QAction *toggleParticipantsAction = m_participantsWidget->toggleViewAction( );
+	toggleParticipantsAction->setText( i18n( "Show Participants" ) );
+	coll->addAction ( "show_participants_widget", toggleParticipantsAction );
 
 	actionSmileyMenu = new KopeteEmoticonAction( coll );
         coll->addAction( "format_smiley", actionSmileyMenu );
diff --git a/kopete/kopete/chatwindow/kopetechatwindow.h b/kopete/kopete/chatwindow/kopetechatwindow.h
index 733dc45..3aed8d6 100644
--- a/kopete/kopete/chatwindow/kopetechatwindow.h
+++ b/kopete/kopete/chatwindow/kopetechatwindow.h
@@ -48,6 +48,7 @@ class QLabel;
 class KopeteEmoticonAction;
 class ChatView;
 class SidebarWidget;
+class QDockWidget;
 
 namespace Kopete
 {
@@ -133,9 +134,7 @@ private:
 	//why did we ever need this method??
 	//const QString fileContents( const QString &file ) const;
 
-	// Sidebar
-	SidebarWidget *m_sideBar;
-	QTabWidget *m_sideBarTabWidget;
+	QDockWidget *m_participantsWidget;
 
 	//
 	QPointer<ChatView> m_activeView;
diff --git a/kopete/kopete/chatwindow/kopetechatwindow.rc b/kopete/kopete/chatwindow/kopetechatwindow.rc
index 48c6052..459b776 100644
--- a/kopete/kopete/chatwindow/kopetechatwindow.rc
+++ b/kopete/kopete/chatwindow/kopetechatwindow.rc
@@ -32,7 +32,7 @@
 			<text>&amp;Settings</text>
 			<Merge name="StandardToolBarMenuHandler" />
 			<Action name="enable_auto_spell_check" />
-			<Action append="show_merge" name="show_sidebar_widget" />
+			<Action append="show_merge" name="show_participants_widget" />			
 			<Action append="show_merge" name="options_styles"/>
 			<Action append="configure_merge" name="settings_prefs" />
 		</Menu>
diff --git a/kopete/kopete/chatwindow/sidebarwidget.cpp b/kopete/kopete/chatwindow/sidebarwidget.cpp
deleted file mode 100644
index 5301843..0000000
--- a/kopete/kopete/chatwindow/sidebarwidget.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-    chatmemberslistwidget.cpp - Chat Members List Widget
-
-    Copyright (c) 2004      by Richard Smith         <[EMAIL PROTECTED]>
-
-    Kopete    (c) 2002-2004 by the Kopete developers <[email protected]>
-
-    *************************************************************************
-    *                                                                       *
-    * This program is free software; you can redistribute it and/or modify  *
-    * it under the terms of the GNU General Public License as published by  *
-    * the Free Software Foundation; either version 2 of the License, or     *
-    * (at your option) any later version.                                   *
-    *                                                                       *
-    *************************************************************************
-*/
-
-#include <QLayout>
-#include <QTabWidget>
-#include <QList>
-#include <QTextDocument>
-#include <QLabel>
-
-#include "klocale.h"
-#include "kurl.h"
-
-#include "sidebarwidget.h"
-#include "kopetechatsession.h"
-#include "chatmemberslistwidget.h"
-#include "kopetechatwindow.h"
-#include "kopeteemoticons.h"
-#include "kopetemetacontact.h"
-#include "kopetepicture.h"
-
-
-
-SidebarWidget::SidebarWidget( KopeteChatWindow *parent )
-    : QDockWidget( parent )
-    , m_chatWindow(parent)
-{
-	// The sidebar contains a QTabWidget (main widget).
-	m_tabWidget = new QTabWidget(this);
-	setWidget(m_tabWidget);
-	
-	// Here we add the first default page.
-	QWidget *pageInfoZone = new QWidget(this);
-	QVBoxLayout *l = new QVBoxLayout(pageInfoZone);
-	//m_htmlInfoZone = new KHTMLPart(pageInfoZone);
-	m_infoZone = new QLabel(pageInfoZone);
-        m_infoZone->setWordWrap(true);
-	l->addWidget(m_infoZone);
-	
-	m_tabWidget->addTab(pageInfoZone, i18n("Information"));
-
-	// The contact list
-	ChatMembersListWidget *m_membersList = new ChatMembersListWidget(this);
-	m_tabWidget->addTab(m_membersList, i18n("Chat members list"));
-
-	connect(m_chatWindow, SIGNAL(chatSessionChanged(Kopete::ChatSession *)), this, SLOT(setChatSession(Kopete::ChatSession *)));
-	connect(m_chatWindow, SIGNAL(chatSessionChanged(Kopete::ChatSession *)), m_membersList, SLOT(setChatSession(Kopete::ChatSession *)));
-
-	/* Be careful to not initialize here bad things. They generally go in
-	   setChatSession
-	*/
-}
-void SidebarWidget::generateContactDetails()
-{
-	Kopete::ContactPtrList members = m_session->members();
-	Kopete::Contact *contact = members.first();
-	Kopete::MetaContact* metaContact = contact->metaContact();
-
-	QString content = QLatin1String("<html><head></head><body><div style=\"margin-left:10px;margin-right:10px;\"><br>");
-
-	int w = 120;
-
-	if ( ! metaContact->picture().image().isNull() )
-        {
-		QString photoName = QString(QLatin1String("kopete-metacontact-photo:%1")).arg( QLatin1String(QUrl::toPercentEncoding( metaContact->metaContactId()) ));
-		content += QString(QLatin1String("<img src=\"%1\" style=\"margin-bottom:10px;\"><br>")).arg( photoName );
-		 w = ( metaContact->picture().image().width() > 100 ) ? metaContact->picture().image().width() + 20 : 120;
-        }
-
-	QString displayName;
-	Kopete::Emoticons *e = Kopete::Emoticons::self();
-	QList<Kopete::Emoticons::Token> t = e->tokenize( metaContact->displayName());
-	QList<Kopete::Emoticons::Token>::iterator it;
-	for( it = t.begin(); it != t.end(); ++it )
-	{
-		if( (*it).type == Kopete::Emoticons::Image )
-		{
-			displayName += (*it).picHTMLCode;
-		} else if( (*it).type == Kopete::Emoticons::Text )
-		{
-			displayName += Qt::escape( (*it).text );
-		}
-	}
-
-	content += QString(QLatin1String("<b><font size=\"+1\">%1</font></b><br>")).arg( displayName );
-	content += contact->toolTip() + QLatin1String("</div></body><html>");
-
-	// adjust formatting for the rather narrow sidebar
-	content = content.replace( "</b>", "</b><br>&nbsp;" );
-	content = content.replace( "<nobr>", "" );
-	content = content.replace( "</nobr>", "" );
-
-	m_infoZone->setText( content );
-	
-
-
-}
-
-void SidebarWidget::addPage( QWidget *widget, QString& name )
-{
-	m_tabWidget->addTab(widget, name);
-}
-
-void SidebarWidget::setChatSession( Kopete::ChatSession *session )
-{
-	m_session = session;
-	generateContactDetails();
-}
-
-SidebarWidget::~SidebarWidget()
-{
-}
-
-
-#include "sidebarwidget.moc"
-
-// vim: set noet ts=4 sts=4 sw=4:
-
diff --git a/kopete/kopete/chatwindow/sidebarwidget.h b/kopete/kopete/chatwindow/sidebarwidget.h
deleted file mode 100644
index 5dca458..0000000
--- a/kopete/kopete/chatwindow/sidebarwidget.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-    chatmemberslistwidget.h - Chat Members List Widget
-
-    Copyright (c) 2004      by Richard Smith         <[EMAIL PROTECTED]>
-
-    Kopete    (c) 2002-2004 by the Kopete developers <[email protected]>
-
-    *************************************************************************
-    *                                                                       *
-    * This program is free software; you can redistribute it and/or modify  *
-    * it under the terms of the GNU General Public License as published by  *
-    * the Free Software Foundation; either version 2 of the License, or     *
-    * (at your option) any later version.                                   *
-    *                                                                       *
-    *************************************************************************
-*/
-
-#ifndef SIDEBARWIDGET_H
-#define SIDEBARWIDGET_H
-
-#include <QDockWidget>
-
-namespace Kopete
-{
-class ChatSession;
-}
-
-class QTabWidget;
-class KopeteChatWindow;
-class ChatMembersListWidget;
-class QLabel;
-
-/**
- * @author Richard Smith <[EMAIL PROTECTED]>
- */
-class SidebarWidget : public QDockWidget
-{
-	Q_OBJECT
-public:
-	SidebarWidget( KopeteChatWindow *parent = 0 );
-	virtual ~SidebarWidget();
-
-	/**
-	 * Returns the \class Kopete::ChatSession currently linked to the sidebar
-	 * The sidebar is indeed linked to one \class Kopete::Chatsession (the one visible
-	 * in the \class Kopete::ChatWindow
-	 */
-	Kopete::ChatSession *session() { return m_session; }
-	
-	/**
-	 * Adds a page to the QTabWidget
-	 */
-	void addPage( QWidget *widget, QString& name );
-
-private slots:
-	void setChatSession( Kopete::ChatSession *session );
-private:
-	/**
-	 * Generate the HTML page with contact information
-	 */
-	void generateContactDetails();
-
-	// Stores the current session the sidebar is using
-	Kopete::ChatSession *m_session;
-	KopeteChatWindow *m_chatWindow;
-
-	
-	// UI
-	QTabWidget *m_tabWidget;
-	// TabWidget pages :
-	QLabel *m_infoZone;
-	ChatMembersListWidget *m_memberslist;
-};
-
-
-#endif
-
-// vim: set noet ts=4 sts=4 sw=4:
-
diff --git a/kopete/libkopete/CMakeLists.txt b/kopete/libkopete/CMakeLists.txt
index fac09bc..9093ec9 100644
--- a/kopete/libkopete/CMakeLists.txt
+++ b/kopete/libkopete/CMakeLists.txt
@@ -100,6 +100,7 @@ set(kopete_LIB_SRCS
    kopeteutils.cpp
    kopetewalletmanager.cpp
    networkstatuscommon.h
+   chatsessionmemberslistmodel.cpp
 # REMOVED FOR NOW
 #   connectionmanager.cpp
 #   managedconnectionaccount.cpp
diff --git a/kopete/libkopete/chatsessionmemberslistmodel.cpp b/kopete/libkopete/chatsessionmemberslistmodel.cpp
new file mode 100644
index 0000000..23ac5c8
--- /dev/null
+++ b/kopete/libkopete/chatsessionmemberslistmodel.cpp
@@ -0,0 +1,151 @@
+/*
+    ChatSessionMembersListModel
+
+    Copyright (c) 2007 by Duncan Mac-Vicar Prett <[EMAIL PROTECTED]>
+   
+    Kopete    (c) 2002-2007 by the Kopete developers  <[email protected]>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+
+#include "kopetecontact.h"
+#include "kopeteonlinestatus.h"
+#include "chatsessionmemberslistmodel.h"
+
+namespace Kopete
+{
+
+ChatSessionMembersListModel::ChatSessionMembersListModel(QObject * parent)
+	: QAbstractListModel(parent), m_session(0L)
+{
+
+}
+
+void ChatSessionMembersListModel::setChatSession(ChatSession *session)
+{
+	m_session = session;
+
+	connect( session, SIGNAL( contactAdded(const Kopete::Contact*, bool) ),
+ 	         this, SLOT( slotContactAdded(const Kopete::Contact*) ) );
+ 	connect( session, SIGNAL( contactRemoved(const Kopete::Contact*, const QString&, Qt::TextFormat, bool) ),
+ 	         this, SLOT( slotContactRemoved(const Kopete::Contact*) ) );
+ 	connect( session, SIGNAL( onlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus & , const Kopete::OnlineStatus &) ),
+ 	         this, SLOT( slotContactStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus & ) ) );
+	connect( session, SIGNAL( displayNameChanged() ),
+ 	         this, SLOT( slotSessionChanged() ) );
+	connect( session, SIGNAL( photoChanged() ),
+ 	         this, SLOT( slotSessionChanged() ) );
+	reset();
+}
+
+Kopete::Contact * ChatSessionMembersListModel::contactAt( const QModelIndex &index )
+{
+	if ( m_session )
+	{
+		if (!index.isValid())
+			return 0L;
+	
+		if (index.row() >= m_session->members().size() + 1)
+			return 0L;
+
+		if ( index.row() == 0 )
+			return const_cast<Kopete::Contact *>(m_session->myself());
+		else
+			return m_session->members().at(index.row() - 1);
+	}
+
+	return 0L;
+}
+
+int ChatSessionMembersListModel::rowCount(const QModelIndex &parent) const
+{
+	if ( m_session )
+		return m_session->members().count() + 1;
+	
+	return 0;
+}
+
+QVariant ChatSessionMembersListModel::data(const QModelIndex &index, int role) const
+{
+	if ( m_session )
+	{
+		if (!index.isValid())
+			return QVariant();
+	
+		if (index.row() >= m_session->members().size() + 1)
+			return QVariant();
+	
+		const Contact *c;
+		if ( index.row() == 0 )
+			c = m_session->myself();
+		else
+			c = m_session->members().at(index.row() - 1);
+
+		if (role == Qt::DisplayRole)
+		{
+			QString nick = c->property(Kopete::Global::Properties::self()->nickName().key()).value().toString();
+			if ( nick.isEmpty() )
+				nick = c->contactId();
+			
+			return nick;
+		}
+		else if (role == Qt::DecorationRole)
+		{
+			return c->onlineStatus().iconFor(c);
+		}
+		else if (role == Qt::ToolTipRole)
+		{
+			return c->toolTip();
+		}
+		else
+			return QVariant();
+	}
+
+	return QVariant();
+}
+
+QVariant ChatSessionMembersListModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+	if (role != Qt::DisplayRole)
+		return QVariant();
+
+	if (orientation == Qt::Horizontal)
+		return QString("Column %1").arg(section);
+	else
+		return QString("Row %1").arg(section);
+}
+
+void ChatSessionMembersListModel::slotContactAdded( const Kopete::Contact *contact )
+{
+	// NOTE in the future the adding of a contact
+  // could be done just for the contact
+	reset();
+}
+
+void ChatSessionMembersListModel::slotContactRemoved( const Kopete::Contact *contact )
+{
+	// NOTE in the future the removal of a contact
+  // could be done just for the contact
+	reset();
+}
+
+void ChatSessionMembersListModel::slotContactStatusChanged( Kopete::Contact *contact, const Kopete::OnlineStatus &status )
+{
+	// NOTE in the future the change of a contact
+  // could be done just for the contact
+	reset();
+}
+
+void ChatSessionMembersListModel::slotSessionChanged()
+{
+	reset();
+}
+
+}
\ No newline at end of file
diff --git a/kopete/libkopete/chatsessionmemberslistmodel.h b/kopete/libkopete/chatsessionmemberslistmodel.h
new file mode 100644
index 0000000..c47e124
--- /dev/null
+++ b/kopete/libkopete/chatsessionmemberslistmodel.h
@@ -0,0 +1,81 @@
+/*
+    ChatSessionMembersListModel
+
+    Copyright (c) 2007 by Duncan Mac-Vicar Prett <[EMAIL PROTECTED]>
+   
+    Kopete    (c) 2002-2007 by the Kopete developers  <[email protected]>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+
+#include <QAbstractListModel>
+
+#include "kopetechatsession.h"
+#include "kopete_export.h"
+
+class Kopete::Contact;
+
+namespace Kopete
+{
+
+class KOPETE_EXPORT ChatSessionMembersListModel : public QAbstractListModel
+{
+	Q_OBJECT
+public:
+	explicit ChatSessionMembersListModel(QObject * parent = 0);
+
+	// Model methods
+	int rowCount(const QModelIndex &parent = QModelIndex()) const;
+	QVariant data(const QModelIndex &index, int role) const;
+	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+	Kopete::ChatSession *session() { return m_session; }
+
+	Kopete::Contact *contactAt( const QModelIndex &index );
+public slots:
+	/**
+	 * Called when the ChatSession change for this list (eg. when the tab in the KopeteChatWindow is changing)
+	 */
+	void setChatSession(Kopete::ChatSession *session);
+
+private slots:
+	/**
+	 * Called when a contact is added to the chat session.
+	 * Adds this contact to the contact list view.
+	 * @param c The contact that joined the chat
+	 */
+	void slotContactAdded( const Kopete::Contact *c );
+
+	/**
+	 * Called when a contact is removed from the chat session.
+	 * Removes this contact from the contact list view.
+	 * @param c The contact that left the chat
+	 */
+	void slotContactRemoved( const Kopete::Contact *c );
+
+	/**
+	 * Called when a contact changes status.
+	 * @param contact The contact who changed status
+	 * @param status The new status of the contact
+	 */
+	void slotContactStatusChanged( Kopete::Contact *contact, const Kopete::OnlineStatus &status );
+
+	/**
+   * Called when something in the session changed that requires a full
+   * model reset
+	 */
+	void slotSessionChanged();
+
+private:
+	Kopete::ChatSession *m_session;
+};
+
+
+}
+
-- 
1.5.3.2

_______________________________________________
kopete-devel mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/kopete-devel

Reply via email to