summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/oscar/aim/aimcontact.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/oscar/aim/aimcontact.cpp')
-rw-r--r--kopete/protocols/oscar/aim/aimcontact.cpp520
1 files changed, 0 insertions, 520 deletions
diff --git a/kopete/protocols/oscar/aim/aimcontact.cpp b/kopete/protocols/oscar/aim/aimcontact.cpp
deleted file mode 100644
index 2fa79bf1..00000000
--- a/kopete/protocols/oscar/aim/aimcontact.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- aimcontact.cpp - Oscar Protocol Plugin
-
- Copyright (c) 2003 by Will Stephenson
- 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 <time.h>
-
-#include <tqimage.h>
-#include <tqregexp.h>
-#include <tqtimer.h>
-#include <tqtextcodec.h>
-
-#include <tdeapplication.h>
-#include <tdeactionclasses.h>
-#include <tdelocale.h>
-#include <kdebug.h>
-#include <tdemessagebox.h>
-
-#include "kopeteaway.h"
-#include "kopetechatsession.h"
-#include "kopeteuiglobal.h"
-#include "kopetemetacontact.h"
-
-//liboscar
-#include "client.h"
-#include "oscartypes.h"
-#include "oscarutils.h"
-#include "ssimanager.h"
-
-#include "aimprotocol.h"
-#include "aimuserinfo.h"
-#include "aimcontact.h"
-#include "aimaccount.h"
-
-AIMContact::AIMContact( Kopete::Account* account, const TQString& name, Kopete::MetaContact* parent,
- const TQString& icon, const Oscar::SSI& ssiItem )
-: OscarContact(account, name, parent, icon, ssiItem )
-{
- mProtocol=static_cast<AIMProtocol *>(protocol());
- setOnlineStatus( mProtocol->statusOffline );
-
- m_infoDialog = 0L;
- m_warnUserAction = 0L;
- mUserProfile="";
- m_haveAwayMessage = false;
- m_mobile = false;
- // Set the last autoresponse time to the current time yesterday
- m_lastAutoresponseTime = TQDateTime::currentDateTime().addDays(-1);
-
- TQObject::connect( mAccount->engine(), TQT_SIGNAL( receivedUserInfo( const TQString&, const UserDetails& ) ),
- this, TQT_SLOT( userInfoUpdated( const TQString&, const UserDetails& ) ) );
- TQObject::connect( mAccount->engine(), TQT_SIGNAL( userIsOffline( const TQString& ) ),
- this, TQT_SLOT( userOffline( const TQString& ) ) );
- TQObject::connect( mAccount->engine(), TQT_SIGNAL( receivedAwayMessage( const TQString&, const TQString& ) ),
- this, TQT_SLOT( updateAwayMessage( const TQString&, const TQString& ) ) );
- TQObject::connect( mAccount->engine(), TQT_SIGNAL( receivedProfile( const TQString&, const TQString& ) ),
- this, TQT_SLOT( updateProfile( const TQString&, const TQString& ) ) );
- TQObject::connect( mAccount->engine(), TQT_SIGNAL( userWarned( const TQString&, TQ_UINT16, TQ_UINT16 ) ),
- this, TQT_SLOT( gotWarning( const TQString&, TQ_UINT16, TQ_UINT16 ) ) );
- TQObject::connect( mAccount->engine(), TQT_SIGNAL( haveIconForContact( const TQString&, TQByteArray ) ),
- this, TQT_SLOT( haveIcon( const TQString&, TQByteArray ) ) );
- TQObject::connect( mAccount->engine(), TQT_SIGNAL( iconServerConnected() ),
- this, TQT_SLOT( requestBuddyIcon() ) );
- TQObject::connect( this, TQT_SIGNAL( featuresUpdated() ), this, TQT_SLOT( updateFeatures() ) );
-}
-
-AIMContact::~AIMContact()
-{
-}
-
-bool AIMContact::isReachable()
-{
- return true;
-}
-
-TQPtrList<TDEAction> *AIMContact::customContextMenuActions()
-{
-
- TQPtrList<TDEAction> *actionCollection = new TQPtrList<TDEAction>();
- if ( !m_warnUserAction )
- {
- m_warnUserAction = new TDEAction( i18n( "&Warn User" ), 0, this, TQT_SLOT( warnUser() ), this, "warnAction" );
- }
- m_actionVisibleTo = new TDEToggleAction(i18n("Always &Visible To"), "", 0,
- this, TQT_SLOT(slotVisibleTo()), this, "actionVisibleTo");
- m_actionInvisibleTo = new TDEToggleAction(i18n("Always &Invisible To"), "", 0,
- this, TQT_SLOT(slotInvisibleTo()), this, "actionInvisibleTo");
-
- bool on = account()->isConnected();
-
- m_warnUserAction->setEnabled( on );
-
- m_actionVisibleTo->setEnabled(on);
- m_actionInvisibleTo->setEnabled(on);
-
- SSIManager* ssi = account()->engine()->ssiManager();
- m_actionVisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_VISIBLE ));
- m_actionInvisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_INVISIBLE ));
-
- actionCollection->append( m_warnUserAction );
-
- actionCollection->append(m_actionVisibleTo);
- actionCollection->append(m_actionInvisibleTo);
-
-
- return actionCollection;
-}
-
-const TQString AIMContact::awayMessage()
-{
- return property(mProtocol->awayMessage).value().toString();
-}
-
-void AIMContact::setAwayMessage(const TQString &message)
-{
- kdDebug(14152) << k_funcinfo <<
- "Called for '" << contactId() << "', away msg='" << message << "'" << endl;
- TQString filteredMessage = message;
- filteredMessage.replace(
- TQRegExp(TQString::fromLatin1("<[hH][tT][mM][lL].*>(.*)</[hH][tT][mM][lL]>")),
- TQString::fromLatin1("\\1"));
- filteredMessage.replace(
- TQRegExp(TQString::fromLatin1("<[bB][oO][dD][yY].*>(.*)</[bB][oO][dD][yY]>")),
- TQString::fromLatin1("\\1") );
- TQRegExp fontRemover( TQString::fromLatin1("<[fF][oO][nN][tT].*>(.*)</[fF][oO][nN][tT]>") );
- fontRemover.setMinimal(true);
- while ( filteredMessage.find( fontRemover ) != -1 )
- filteredMessage.replace( fontRemover, TQString::fromLatin1("\\1") );
- setProperty(mProtocol->awayMessage, filteredMessage);
-}
-
-int AIMContact::warningLevel() const
-{
- return m_warningLevel;
-}
-
-void AIMContact::updateSSIItem()
-{
- if ( m_ssiItem.type() != 0xFFFF && m_ssiItem.waitingAuth() == false &&
- onlineStatus() == Kopete::OnlineStatus::Unknown )
- {
- //make sure they're offline
- setOnlineStatus( static_cast<AIMProtocol*>( protocol() )->statusOffline );
- }
-}
-
-void AIMContact::slotUserInfo()
-{
- if ( !m_infoDialog)
- {
- m_infoDialog = new AIMUserInfoDialog( this, static_cast<AIMAccount*>( account() ), false, Kopete::UI::Global::mainWidget(), 0 );
- if( !m_infoDialog )
- return;
- connect( m_infoDialog, TQT_SIGNAL( finished() ), this, TQT_SLOT( closeUserInfoDialog() ) );
- m_infoDialog->show();
- if ( mAccount->isConnected() )
- {
- mAccount->engine()->requestAIMProfile( contactId() );
- mAccount->engine()->requestAIMAwayMessage( contactId() );
- }
- }
- else
- m_infoDialog->raise();
-}
-
-void AIMContact::userInfoUpdated( const TQString& contact, const UserDetails& details )
-{
- if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
- return;
-
- kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << contact << endl;
-
- //if they don't have an SSI alias, make sure we use the capitalization from the
- //server so their contact id looks all pretty.
- TQString nickname = property( Kopete::Global::Properties::self()->nickName() ).value().toString();
- if ( nickname.isEmpty() || Oscar::normalize( nickname ) == Oscar::normalize( contact ) )
- setNickName( contact );
-
- ( details.userClass() & CLASS_WIRELESS ) ? m_mobile = true : m_mobile = false;
-
- if ( ( details.userClass() & CLASS_AWAY ) == STATUS_ONLINE )
- {
- if ( m_mobile )
- {
- kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is mobile-online." << endl;
- setOnlineStatus( mProtocol->statusWirelessOnline );
- }
- else
- {
- kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is online." << endl;
- setOnlineStatus( mProtocol->statusOnline ); //we're online
- }
- removeProperty( mProtocol->awayMessage );
- m_haveAwayMessage = false;
- }
- else if ( ( details.userClass() & CLASS_AWAY ) ) // STATUS_AWAY
- {
- if ( m_mobile )
- {
- kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is mobile-away." << endl;
- setOnlineStatus( mProtocol->statusWirelessOnline );
- }
- else
- {
- kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is away." << endl;
- setOnlineStatus( mProtocol->statusAway ); //we're away
- }
- if ( !m_haveAwayMessage ) //prevent cyclic away message requests
- {
- mAccount->engine()->requestAIMAwayMessage( contactId() );
- m_haveAwayMessage = true;
- }
- }
- else
- {
- kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " class " << details.userClass() << " is unhandled... defaulting to away." << endl;
- setOnlineStatus( mProtocol->statusAway ); //we're away
- if ( !m_haveAwayMessage ) //prevent cyclic away message requests
- {
- mAccount->engine()->requestAIMAwayMessage( contactId() );
- m_haveAwayMessage = true;
- }
- }
-
- if ( details.buddyIconHash().size() > 0 && details.buddyIconHash() != m_details.buddyIconHash() )
- {
- if ( !mAccount->engine()->hasIconConnection() )
- mAccount->engine()->requestServerRedirect( 0x0010 );
-
- int time = ( TDEApplication::random() % 10 ) * 1000;
- kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "updating buddy icon in " << time/1000 << " seconds" << endl;
- TQTimer::singleShot( time, this, TQT_SLOT( requestBuddyIcon() ) );
- }
-
- OscarContact::userInfoUpdated( contact, details );
-}
-
-void AIMContact::userOnline( const TQString& userId )
-{
- if ( Oscar::normalize( userId ) == Oscar::normalize( contactId() ) )
- {
- kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Getting more contact info" << endl;
- setOnlineStatus( mProtocol->statusOnline );
- }
-}
-
-void AIMContact::userOffline( const TQString& userId )
-{
- if ( Oscar::normalize( userId ) == Oscar::normalize( contactId() ) )
- {
- setOnlineStatus( mProtocol->statusOffline );
- removeProperty( mProtocol->awayMessage );
- }
-}
-
-void AIMContact::updateAwayMessage( const TQString& contact, const TQString& message )
-{
- if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
- return;
- else
- {
- if ( message.isEmpty() )
- {
- removeProperty( mProtocol->awayMessage );
- if ( !m_mobile )
- setOnlineStatus( mProtocol->statusOnline );
- else
- setOnlineStatus( mProtocol->statusWirelessOnline );
- m_haveAwayMessage = false;
- }
- else
- {
- m_haveAwayMessage = true;
- setAwayMessage( message );
- if ( !m_mobile )
- setOnlineStatus( mProtocol->statusAway );
- else
- setOnlineStatus( mProtocol->statusWirelessAway );
- }
- }
-
- emit updatedProfile();
-}
-
-void AIMContact::updateProfile( const TQString& contact, const TQString& profile )
-{
- if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
- return;
-
- setProperty( mProtocol->clientProfile, profile );
- emit updatedProfile();
-}
-
-void AIMContact::gotWarning( const TQString& contact, TQ_UINT16 increase, TQ_UINT16 newLevel )
-{
- //somebody just got bitchslapped! :O
- Q_UNUSED( increase );
- if ( Oscar::normalize( contact ) == Oscar::normalize( contactId() ) )
- m_warningLevel = newLevel;
-
- //TODO add a KNotify event after merge to HEAD
-}
-
-void AIMContact::requestBuddyIcon()
-{
- kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Updating buddy icon for " << contactId() << endl;
- if ( m_details.buddyIconHash().size() > 0 )
- {
- account()->engine()->requestBuddyIcon( contactId(), m_details.buddyIconHash(),
- m_details.iconCheckSumType() );
- }
-}
-
-void AIMContact::haveIcon( const TQString& user, TQByteArray icon )
-{
- if ( Oscar::normalize( user ) != Oscar::normalize( contactId() ) )
- return;
-
- kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Updating icon for " << contactId() << endl;
- TQImage buddyIcon( icon );
- if ( buddyIcon.isNull() )
- {
- kdWarning(OSCAR_AIM_DEBUG) << k_funcinfo << "Failed to convert buddy icon to TQImage" << endl;
- return;
- }
-
- setProperty( Kopete::Global::Properties::self()->photo(), buddyIcon );
-}
-
-void AIMContact::closeUserInfoDialog()
-{
- m_infoDialog->delayedDestruct();
- m_infoDialog = 0L;
-}
-
-void AIMContact::warnUser()
-{
- TQString nick = property( Kopete::Global::Properties::self()->nickName() ).value().toString();
- TQString message = i18n( "<qt>Would you like to warn %1 anonymously or with your name?<br>" \
- "(Warning a user on AIM will result in a \"Warning Level\"" \
- " increasing for the user you warn. Once this level has reached a" \
- " certain point, they will not be able to sign on. Please do not abuse" \
- " this function, it is meant for legitimate practices.)</qt>" ).arg( nick );
-
-
- int result = KMessageBox::questionYesNoCancel( Kopete::UI::Global::mainWidget(), message,
- i18n( "Warn User %1?" ).arg( nick ),
- i18n( "Warn Anonymously" ), i18n( "Warn" ) );
-
- if ( result == KMessageBox::Yes )
- mAccount->engine()->sendWarning( contactId(), true);
- else if ( result == KMessageBox::No )
- mAccount->engine()->sendWarning( contactId(), false);
-}
-
-void AIMContact::slotVisibleTo()
-{
- account()->engine()->setVisibleTo( contactId(), m_actionVisibleTo->isChecked() );
-}
-
-void AIMContact::slotInvisibleTo()
-{
- account()->engine()->setInvisibleTo( contactId(), m_actionInvisibleTo->isChecked() );
-}
-
-void AIMContact::slotSendMsg(Kopete::Message& message, Kopete::ChatSession *)
-{
- Oscar::Message msg;
- TQString s;
-
- if (message.plainBody().isEmpty()) // no text, do nothing
- return;
- //okay, now we need to change the message.escapedBody from real HTML to aimhtml.
- //looking right now for docs on that "format".
- //looks like everything except for alignment codes comes in the format of spans
-
- //font-style:italic -> <i>
- //font-weight:600 -> <b> (anything > 400 should be <b>, 400 is not bold)
- //text-decoration:underline -> <u>
- //font-family: -> <font face="">
- //font-size:xxpt -> <font ptsize=xx>
-
- s=message.escapedBody();
- s.replace ( TQRegExp( TQString::fromLatin1("<span style=\"([^\"]*)\">([^<]*)</span>")),
- TQString::fromLatin1("<style>\\1;\"\\2</style>"));
-
- s.replace ( TQRegExp( TQString::fromLatin1("<style>([^\"]*)font-style:italic;([^\"]*)\"([^<]*)</style>")),
- TQString::fromLatin1("<i><style>\\1\\2\"\\3</style></i>"));
-
- s.replace ( TQRegExp( TQString::fromLatin1("<style>([^\"]*)font-weight:600;([^\"]*)\"([^<]*)</style>")),
- TQString::fromLatin1("<b><style>\\1\\2\"\\3</style></b>"));
-
- s.replace ( TQRegExp( TQString::fromLatin1("<style>([^\"]*)text-decoration:underline;([^\"]*)\"([^<]*)</style>")),
- TQString::fromLatin1("<u><style>\\1\\2\"\\3</style></u>"));
-
- s.replace ( TQRegExp( TQString::fromLatin1("<style>([^\"]*)font-family:([^;]*);([^\"]*)\"([^<]*)</style>")),
- TQString::fromLatin1("<font face=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
-
- s.replace ( TQRegExp( TQString::fromLatin1("<style>([^\"]*)font-size:([^p]*)pt;([^\"]*)\"([^<]*)</style>")),
- TQString::fromLatin1("<font ptsize=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
-
- s.replace ( TQRegExp( TQString::fromLatin1("<style>([^\"]*)color:([^;]*);([^\"]*)\"([^<]*)</style>")),
- TQString::fromLatin1("<font color=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
-
- s.replace ( TQRegExp( TQString::fromLatin1("<style>([^\"]*)\"([^<]*)</style>")),
- TQString::fromLatin1("\\2"));
-
- //okay now change the <font ptsize="xx"> to <font size="xx">
-
- //0-9 are size 1
- s.replace ( TQRegExp ( TQString::fromLatin1("<font ptsize=\"\\d\">")),
- TQString::fromLatin1("<font size=\"1\">"));
- //10-11 are size 2
- s.replace ( TQRegExp ( TQString::fromLatin1("<font ptsize=\"1[01]\">")),
- TQString::fromLatin1("<font size=\"2\">"));
- //12-13 are size 3
- s.replace ( TQRegExp ( TQString::fromLatin1("<font ptsize=\"1[23]\">")),
- TQString::fromLatin1("<font size=\"3\">"));
- //14-16 are size 4
- s.replace ( TQRegExp ( TQString::fromLatin1("<font ptsize=\"1[456]\">")),
- TQString::fromLatin1("<font size=\"4\">"));
- //17-22 are size 5
- s.replace ( TQRegExp ( TQString::fromLatin1("<font ptsize=\"(?:1[789]|2[012])\">")),
- TQString::fromLatin1("<font size=\"5\">"));
- //23-29 are size 6
- s.replace ( TQRegExp ( TQString::fromLatin1("<font ptsize=\"2[3456789]\">")),TQString::fromLatin1("<font size=\"6\">"));
- //30- (and any I missed) are size 7
- s.replace ( TQRegExp ( TQString::fromLatin1("<font ptsize=\"[^\"]*\">")),TQString::fromLatin1("<font size=\"7\">"));
-
- // strip left over line break
- s.remove(TQRegExp(TQString::fromLatin1("<br\b[^>]*>$")));
-
- s.replace ( TQRegExp ( TQString::fromLatin1("<br[ /]*>")), TQString::fromLatin1("<br>") );
-
- // strip left over line break
- s.remove( TQRegExp( TQString::fromLatin1( "<br>$" ) ) );
-
- kdDebug(14190) << k_funcinfo << "sending "
- << s << endl;
-
- // XXX Need to check for message size?
-
- if ( m_details.hasCap( CAP_UTF8 ) )
- msg.setText( Oscar::Message::UCS2, s );
- else
- msg.setText( Oscar::Message::UserDefined, s, contactCodec() );
-
- msg.setReceiver(mName);
- msg.setTimestamp(message.timestamp());
- msg.setType(0x01);
-
- mAccount->engine()->sendMessage(msg);
-
- // Show the message we just sent in the chat window
- manager(Kopete::Contact::CanCreate)->appendMessage(message);
- manager(Kopete::Contact::CanCreate)->messageSucceeded();
-}
-
-void AIMContact::updateFeatures()
-{
- setProperty( static_cast<AIMProtocol*>(protocol())->clientFeatures, m_clientFeatures );
-}
-
-void AIMContact::sendAutoResponse(Kopete::Message& msg)
-{
- // The target time is 2 minutes later than the last message
- int delta = m_lastAutoresponseTime.secsTo( TQDateTime::currentDateTime() );
- kdDebug(14152) << k_funcinfo << "Last autoresponse time: " << m_lastAutoresponseTime << endl;
- kdDebug(14152) << k_funcinfo << "Current time: " << TQDateTime::currentDateTime() << endl;
- kdDebug(14152) << k_funcinfo << "Difference: " << delta << endl;
- // Check to see if we're past that time
- if(delta > 120)
- {
- kdDebug(14152) << k_funcinfo << "Sending auto response" << endl;
-
- // This code was yoinked straight from OscarContact::slotSendMsg()
- // If only that slot wasn't private, but I'm not gonna change it right now.
- Oscar::Message message;
-
- if ( m_details.hasCap( CAP_UTF8 ) )
- {
- message.setText( Oscar::Message::UCS2, msg.plainBody() );
- }
- else
- {
- TQTextCodec* codec = contactCodec();
- message.setText( Oscar::Message::UserDefined, msg.plainBody(), codec );
- }
-
- message.setTimestamp( msg.timestamp() );
- message.setSender( mAccount->accountId() );
- message.setReceiver( mName );
- message.setType( 0x01 );
-
- // isAuto defaults to false
- mAccount->engine()->sendMessage( message, true);
- kdDebug(14152) << k_funcinfo << "Sent auto response" << endl;
- manager(Kopete::Contact::CanCreate)->appendMessage(msg);
- manager(Kopete::Contact::CanCreate)->messageSucceeded();
- // Update the last autoresponse time
- m_lastAutoresponseTime = TQDateTime::currentDateTime();
- }
- else
- {
- kdDebug(14152) << k_funcinfo << "Not enough time since last autoresponse, NOT sending" << endl;
- }
-}
-#include "aimcontact.moc"
-//kate: tab-width 4; indent-mode csands;