You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/kopete/protocols/oscar/oscarcontact.cpp

237 lines
7.1 KiB

/*
oscarcontact.cpp - Oscar Protocol Plugin
Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
Kopete (c) 2002-2003 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 "oscarcontact.h"
#include <time.h>
#include <tqapplication.h>
#include <tqtextcodec.h>
#include <tdeaction.h>
#include <kdebug.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <tdeversion.h>
#include "kopeteaccount.h"
#include "kopetechatsessionmanager.h"
#include "kopetemetacontact.h"
#include "kopetecontactlist.h"
#include "kopetegroup.h"
#include "kopeteuiglobal.h"
#include <kopeteglobal.h>
#include "oscaraccount.h"
#include "client.h"
#include "ssimanager.h"
#include "oscarutils.h"
#include <assert.h>
OscarContact::OscarContact( Kopete::Account* account, const TQString& name,
Kopete::MetaContact* parent, const TQString& icon, const SSI& ssiItem )
: Kopete::Contact( account, name, parent, icon )
{
mAccount = static_cast<OscarAccount*>(account);
mName = name;
mMsgManager = 0L;
m_ssiItem = ssiItem;
connect( this, TQT_SIGNAL( updatedSSI() ), this, TQT_SLOT( updateSSIItem() ) );
}
OscarContact::~OscarContact()
{
}
void OscarContact::serialize(TQMap<TQString, TQString> &serializedData,
TQMap<TQString, TQString> &/*addressBookData*/)
{
serializedData["ssi_name"] = m_ssiItem.name();
serializedData["ssi_type"] = TQString::number( m_ssiItem.type() );
serializedData["ssi_gid"] = TQString::number( m_ssiItem.gid() );
serializedData["ssi_bid"] = TQString::number( m_ssiItem.bid() );
serializedData["ssi_alias"] = m_ssiItem.alias();
serializedData["ssi_waitingAuth"] = m_ssiItem.waitingAuth() ? TQString::fromLatin1( "true" ) : TQString::fromLatin1( "false" );
}
bool OscarContact::isOnServer() const
{
SSIManager* serverList = mAccount->engine()->ssiManager();
SSI ssi = serverList->findContact( Oscar::normalize( contactId() ) );
return ( ssi && ssi.type() != 0xFFFF );
}
void OscarContact::setSSIItem( const Oscar::SSI& ssiItem )
{
m_ssiItem = ssiItem;
if ( !m_ssiItem.alias().isEmpty() )
setProperty( Kopete::Global::Properties::self()->nickName(), m_ssiItem.alias() );
emit updatedSSI();
}
Oscar::SSI OscarContact::ssiItem() const
{
return m_ssiItem;
}
Kopete::ChatSession* OscarContact::manager( CanCreateFlags canCreate )
{
if ( !mMsgManager && canCreate )
{
/*kdDebug(14190) << k_funcinfo <<
"Creating new ChatSession for contact '" << displayName() << "'" << endl;*/
TQPtrList<Kopete::Contact> theContact;
theContact.append(this);
mMsgManager = Kopete::ChatSessionManager::self()->create(account()->myself(), theContact, protocol());
// This is for when the user types a message and presses send
connect(mMsgManager, TQT_SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession * ) ),
this, TQT_SLOT( slotSendMsg( Kopete::Message&, Kopete::ChatSession * ) ) );
// For when the message manager is destroyed
connect(mMsgManager, TQT_SIGNAL( destroyed() ),
this, TQT_SLOT( chatSessionDestroyed() ) );
connect(mMsgManager, TQT_SIGNAL( myselfTyping( bool ) ),
this, TQT_SLOT( slotTyping( bool ) ) );
}
return mMsgManager;
}
void OscarContact::deleteContact()
{
mAccount->engine()->removeContact( contactId() );
deleteLater();
}
void OscarContact::chatSessionDestroyed()
{
mMsgManager = 0L;
}
// Called when the metacontact owning this contact has changed groups
void OscarContact::sync(unsigned int flags)
{
/*
* If the contact has changed groups, then we update the server
* adding the group if it doesn't exist, changing the ssi item
* contained in the client and updating the contact's ssi item
* Otherwise, we don't do much
*/
if( !metaContact() || metaContact()->isTemporary() )
return;
if ( (flags & Kopete::Contact::MovedBetweenGroup) == Kopete::Contact::MovedBetweenGroup )
{
kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "Moving a contact between groups" << endl;
SSIManager* ssiManager = mAccount->engine()->ssiManager();
SSI oldGroup = ssiManager->findGroup( m_ssiItem.gid() );
Kopete::Group* newGroup = metaContact()->groups().first();
if ( newGroup->displayName() == oldGroup.name() )
return; //we didn't really move
if ( m_ssiItem.isValid() )
mAccount->changeContactGroupInSSI( contactId(), newGroup->displayName(), true );
else
mAccount->addContactToSSI( contactId(), newGroup->displayName(), true );
}
return;
}
void OscarContact::userInfoUpdated( const TQString& contact, const UserDetails& details )
{
Q_UNUSED( contact );
setProperty( Kopete::Global::Properties::self()->onlineSince(), details.onlineSinceTime() );
setIdleTime( details.idleTime() );
m_warningLevel = details.warningLevel();
m_details.merge( details );
TQStringList capList;
// Append client name and version in case we found one
if ( m_details.userClass() & 0x0080 /* WIRELESS */ )
capList << i18n( "Mobile AIM Client" );
else
{
if ( !m_details.clientName().isEmpty() )
{
capList << i18n( "Translators: client name and version",
"%1").arg( m_details.clientName() );
}
}
// and now for some general informative capabilities
if ( m_details.hasCap( CAP_BUDDYICON ) )
capList << i18n( "Buddy icons" );
if ( m_details.hasCap( CAP_UTF8 ) )
capList << i18n( "UTF-8" );
if ( m_details.hasCap( CAP_RTFMSGS ) )
capList << i18n( "Rich text messages" );
if ( m_details.hasCap( CAP_CHAT ) )
capList << i18n( "Group chat" );
if ( m_details.hasCap( CAP_VOICE ) )
capList << i18n( "Voice chat" );
if ( m_details.hasCap( CAP_IMIMAGE ) )
capList << i18n( "DirectIM/IMImage" );
if ( m_details.hasCap( CAP_SENDBUDDYLIST ) )
capList << i18n( "Send buddy list" );
if ( m_details.hasCap( CAP_SENDFILE ) )
capList << i18n( "File transfers" );
if ( m_details.hasCap( CAP_GAMES ) || m_details.hasCap( CAP_GAMES2 ) )
capList << i18n( "Games" );
if ( m_details.hasCap( CAP_TRILLIAN ) )
capList << i18n( "Trillian user" );
m_clientFeatures = capList.join( ", " );
emit featuresUpdated();
}
void OscarContact::startedTyping()
{
if ( mMsgManager )
mMsgManager->receivedTypingMsg( this, true );
}
void OscarContact::stoppedTyping()
{
if ( mMsgManager )
mMsgManager->receivedTypingMsg( this, false );
}
void OscarContact::slotTyping( bool typing )
{
if ( this != account()->myself() )
account()->engine()->sendTyping( contactId(), typing );
}
TQTextCodec* OscarContact::contactCodec() const
{
if ( hasProperty( "contactEncoding" ) )
return TQTextCodec::codecForMib( property( "contactEncoding" ).value().toInt() );
else
return mAccount->defaultCodec();
}
#include "oscarcontact.moc"