25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/kopete/kopete/chatwindow/chatmemberslistwidget.cpp

264 lines
8.2 KiB

/*
chatmemberslistwidget.cpp - Chat Members List Widget
Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk>
Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
*************************************************************************
* *
* 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 <tdeabc/stdaddressbook.h>
#include <tdeabc/addressee.h>
#include <tdeabc/vcardconverter.h>
#include <kdebug.h>
#include <tdemultipledrag.h>
#include <tdepopupmenu.h>
#include <tqheader.h>
#include <tqtooltip.h>
//BEGIN ChatMembersListWidget::ToolTip
class ChatMembersListWidget::ToolTip : public TQToolTip
{
public:
ToolTip( TDEListView *parent )
: TQToolTip( parent->viewport() ), m_listView ( parent )
{
}
virtual ~ToolTip()
{
remove( m_listView->viewport() );
}
void maybeTip( const TQPoint &pos )
{
if( TQListViewItem *item = m_listView->itemAt( pos ) )
{
TQRect itemRect = m_listView->itemRect( item );
if( itemRect.contains( pos ) )
tip( itemRect, static_cast<ContactItem*>( item )->contact()->toolTip() );
}
}
private:
TDEListView *m_listView;
};
//END ChatMembersListWidget::ToolTip
//BEGIN ChatMembersListWidget::ContactItem
ChatMembersListWidget::ContactItem::ContactItem( ChatMembersListWidget *parent, Kopete::Contact *contact )
: TDEListViewItem( parent ), m_contact( contact )
{
TQString 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, TQT_SIGNAL( propertyChanged( Kopete::Contact *, const TQString &, const TQVariant &, const TQVariant & ) ),
this, TQT_SLOT( slotPropertyChanged( Kopete::Contact *, const TQString &, const TQVariant &, const TQVariant & ) ) ) ;
setStatus( parent->session()->contactOnlineStatus(m_contact) );
reposition();
}
void ChatMembersListWidget::ContactItem::slotPropertyChanged( Kopete::Contact*,
const TQString &key, const TQVariant&, const TQVariant &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()
{
// TQt'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();
TQListViewItem *after = 0;
for ( TQListViewItem *it = TDEListViewItem::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( Kopete::ChatSession *session, TQWidget *parent, const char *name )
: TDEListView( parent, name ), m_session( session )
{
// use our own custom tooltips
setShowToolTips( false );
m_toolTip = new ToolTip( this );
// set up display: no header
setAllColumnsShowFocus( true );
addColumn( TQString(), -1 );
header()->setStretchEnabled( true, 0 );
header()->hide();
// list is sorted by us, not by TQt
setSorting( -1 );
// add chat members
slotContactAdded( session->myself() );
for ( TQPtrListIterator<Kopete::Contact> it( session->members() ); it.current(); ++it )
slotContactAdded( *it );
connect( this, TQT_SIGNAL( contextMenu( TDEListView*, TQListViewItem *, const TQPoint &) ),
TQT_SLOT( slotContextMenu(TDEListView*, TQListViewItem *, const TQPoint & ) ) );
connect( this, TQT_SIGNAL( executed( TQListViewItem* ) ),
TQT_SLOT( slotExecute( TQListViewItem * ) ) );
connect( session, TQT_SIGNAL( contactAdded(const Kopete::Contact*, bool) ),
this, TQT_SLOT( slotContactAdded(const Kopete::Contact*) ) );
connect( session, TQT_SIGNAL( contactRemoved(const Kopete::Contact*, const TQString&, Kopete::Message::MessageFormat, bool) ),
this, TQT_SLOT( slotContactRemoved(const Kopete::Contact*) ) );
connect( session, TQT_SIGNAL( onlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus & , const Kopete::OnlineStatus &) ),
this, TQT_SLOT( slotContactStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus & ) ) );
}
ChatMembersListWidget::~ChatMembersListWidget()
{
}
void ChatMembersListWidget::slotContextMenu( TDEListView*, TQListViewItem *item, const TQPoint &point )
{
if ( ContactItem *contactItem = dynamic_cast<ContactItem*>(item) )
{
TDEPopupMenu *p = contactItem->contact()->popupMenu( session() );
connect( p, TQT_SIGNAL( aboutToHide() ), p, TQT_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 )
{
kdDebug(14000) << k_funcinfo << endl;
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( TQListViewItem *item )
{
if ( ContactItem *contactItem = dynamic_cast<ContactItem*>(item ) )
{
Kopete::Contact *contact=contactItem->contact();
if(!contact || contact == contact->account()->myself())
return;
contact->execute();
}
}
TQDragObject *ChatMembersListWidget::dragObject()
{
TQListViewItem *currentLVI = currentItem();
if( !currentLVI )
return 0L;
ContactItem *lvi = dynamic_cast<ContactItem*>( currentLVI );
if( !lvi )
return 0L;
Kopete::Contact *c = lvi->contact();
KMultipleDrag *drag = new KMultipleDrag( this );
drag->addDragObject( new TQStoredDrag("application/x-qlistviewitem", 0L ) );
TQStoredDrag *d = new TQStoredDrag("kopete/x-contact", 0L );
d->setEncodedData( TQString( c->protocol()->pluginId()+TQChar( 0xE000 )+c->account()->accountId()+TQChar( 0xE000 )+ c->contactId() ).utf8() );
drag->addDragObject( d );
KABC::Addressee address = KABC::StdAddressBook::self()->findByUid(c->metaContact()->metaContactId());
if( !address.isEmpty() )
{
drag->addDragObject( new TQTextDrag( address.fullEmail(), 0L ) );
KABC::VCardConverter converter;
TQString vcard = converter.createVCard( address );
if( !vcard.isNull() )
{
TQStoredDrag *vcardDrag = new TQStoredDrag("text/x-vcard", 0L );
vcardDrag->setEncodedData( vcard.utf8() );
drag->addDragObject( vcardDrag );
}
}
drag->setPixmap( c->onlineStatus().iconFor(c, 12) );
return drag;
}
//END ChatMembersListWidget
#include "chatmemberslistwidget.moc"
// vim: set noet ts=4 sts=4 sw=4: