<commit_before>/*
  icqontact.cpp  -  Oscar Protocol Plugin

  Copyright (c) 2003      by <NAME>  <metz AT gehn.net>
  Copyright (c) 2003      by <NAME>
  Kopete    (c) 2003-2004 by the Kopete developers  <<EMAIL>>

  *************************************************************************
  *                                                                       *
  * 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 "icqcontact.h"

#include <qtimer.h>

#include <kaction.h>
#include <kactionclasses.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <knotifyclient.h>
#include <kpassivepopup.h>
#include <kinputdialog.h>

#include "kopetechatsessionmanager.h"
#include "kopeteuiglobal.h"
#include "kopetemetacontact.h"

#include "icquserinfo.h"
#include "icqreadaway.h"
#include "icqprotocol.h"
#include "icqaccount.h"
#include "icqpresence.h"
#include "icquserinfowidget.h"
#include "icqauthreplydialog.h"

#include "oscarutils.h"

ICQContact::ICQContact( ICQAccount *account, const QString &name, Kopete::MetaContact *parent,
						const QString& icon, const Oscar::SSI& ssiItem )
: OscarContact( account, name, parent, icon, ssiItem )
{
	mProtocol = static_cast<ICQProtocol *>(protocol());
	m_infoWidget = 0L;
	
	if ( ssiItem.waitingAuth() )
		setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );
	else 
		setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() );

	QObject::connect( mAccount->engine(), SIGNAL( loggedIn() ), this, SLOT( loggedIn() ) );
	//QObject::connect( mAccount->engine(), SIGNAL( userIsOnline( const QString& ) ), this, SLOT( userOnline( const QString&, UserDetails ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( userIsOffline( const QString& ) ), this, SLOT( userOffline( const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( authRequestReceived( const QString&, const QString& ) ),
	                  this, SLOT( slotGotAuthRequest( const QString&, const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( authReplyReceived( const QString&, const QString&, bool ) ),
	                  this, SLOT( slotGotAuthReply(const QString&, const QString&, bool ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( receivedIcqShortInfo( const QString& ) ),
	                  this, SLOT( receivedShortInfo( const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( receivedIcqLongInfo( const QString& ) ),
	                  this, SLOT( receivedLongInfo( const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( receivedUserInfo( const QString&, const UserDetails& ) ),
	                  this, SLOT( userInfoUpdated( const QString&, const UserDetails& ) ) );
	QObject::connect( this, SIGNAL( featuresUpdated() ), this, SLOT( updateFeatures() ) );

}

ICQContact::~ICQContact()
{
	delete m_infoWidget;
}

void ICQContact::updateSSIItem()
{
	//kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << endl;
	if ( m_ssiItem.waitingAuth() )
		setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );
	
	if ( m_ssiItem.type() != 0xFFFF && m_ssiItem.waitingAuth() == false &&
	     onlineStatus() == Kopete::OnlineStatus::Unknown )
	{
		//make sure they're offline
		setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() );
	}
}


void ICQContact::userInfoUpdated( const QString& contact, const UserDetails& details )
{
	//kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << contact << contactId() << endl;
	if ( Oscar::normalize( contact  ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug( OSCAR_ICQ_DEBUG ) << k_funcinfo << "extendedStatus is " << details.extendedStatus() << endl;
	ICQ::Presence presence = ICQ::Presence::fromOscarStatus( details.extendedStatus() & 0xffff );
	setOnlineStatus( presence.toOnlineStatus() );
	
	if ( details.dcExternalIp().isUnspecified() )
		removeProperty( mProtocol->ipAddress );
	else
		setProperty( mProtocol->ipAddress, details.dcExternalIp().toString() );
	
	if ( details.clientName().isEmpty() )
		removeProperty( mProtocol->clientFeatures );
	else
		setProperty( mProtocol->clientFeatures, details.clientName() );
	
	OscarContact::userInfoUpdated( contact, details );
}

void ICQContact::userOnline( const QString& userId )
{
	if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug(OSCAR_ICQ_DEBUG) << "Setting " << userId << " online" << endl;
	ICQ::Presence online = mProtocol->statusManager()->presenceOf( ICQ::Presence::Online );
	//mAccount->engine()->requestStatusInfo( contactId() );
}

void ICQContact::userOffline( const QString& userId )
{
	if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug(OSCAR_ICQ_DEBUG) << "Setting " << userId << " offline" << endl;
	ICQ::Presence offline = mProtocol->statusManager()->presenceOf( ICQ::Presence::Offline );
	setOnlineStatus( mProtocol->statusManager()->onlineStatusOf( offline ) );
}

void ICQContact::loggedIn()
{
	if ( metaContact()->isTemporary() )
		return;
	
	if ( m_ssiItem.waitingAuth() )
		setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );

	if ( nickName().isEmpty() ) 
	{
		int time = ( KApplication::random() % 20 ) * 1000;
		kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "updating nickname in " << time/1000 << " seconds" << endl;
		QTimer::singleShot( time, this, SLOT( requestShortInfo() ) );
	}

}

void ICQContact::requestShortInfo()
{
	if ( mAccount->isConnected() )
		mAccount->engine()->requestShortInfo( contactId() );
}<commit_msg>backport from trunk:<commit_after>/*
  icqontact.cpp  -  Oscar Protocol Plugin

  Copyright (c) 2003      by <NAME>  <metz AT gehn.net>
  Copyright (c) 2003      by <NAME>
  Kopete    (c) 2003-2004 by the Kopete developers  <<EMAIL>>

  *************************************************************************
  *                                                                       *
  * 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 "icqcontact.h"

#include <qtimer.h>

#include <kaction.h>
#include <kactionclasses.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <knotifyclient.h>
#include <kpassivepopup.h>
#include <kinputdialog.h>

#include "kopetechatsessionmanager.h"
#include "kopeteuiglobal.h"
#include "kopetemetacontact.h"

#include "icquserinfo.h"
#include "icqreadaway.h"
#include "icqprotocol.h"
#include "icqaccount.h"
#include "icqpresence.h"
#include "icquserinfowidget.h"
#include "icqauthreplydialog.h"

#include "oscarutils.h"

ICQContact::ICQContact( ICQAccount *account, const QString &name, Kopete::MetaContact *parent,
						const QString& icon, const Oscar::SSI& ssiItem )
: OscarContact( account, name, parent, icon, ssiItem )
{
	mProtocol = static_cast<ICQProtocol *>(protocol());
	m_infoWidget = 0L;
	
	if ( ssiItem.waitingAuth() )
		setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );
	else 
		setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() );

	QObject::connect( mAccount->engine(), SIGNAL( loggedIn() ), this, SLOT( loggedIn() ) );
	//QObject::connect( mAccount->engine(), SIGNAL( userIsOnline( const QString& ) ), this, SLOT( userOnline( const QString&, UserDetails ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( userIsOffline( const QString& ) ), this, SLOT( userOffline( const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( authRequestReceived( const QString&, const QString& ) ),
	                  this, SLOT( slotGotAuthRequest( const QString&, const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( authReplyReceived( const QString&, const QString&, bool ) ),
	                  this, SLOT( slotGotAuthReply(const QString&, const QString&, bool ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( receivedIcqShortInfo( const QString& ) ),
	                  this, SLOT( receivedShortInfo( const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( receivedIcqLongInfo( const QString& ) ),
	                  this, SLOT( receivedLongInfo( const QString& ) ) );
	QObject::connect( mAccount->engine(), SIGNAL( receivedUserInfo( const QString&, const UserDetails& ) ),
	                  this, SLOT( userInfoUpdated( const QString&, const UserDetails& ) ) );
	QObject::connect( this, SIGNAL( featuresUpdated() ), this, SLOT( updateFeatures() ) );

}

ICQContact::~ICQContact()
{
	delete m_infoWidget;
}

void ICQContact::updateSSIItem()
{
	//kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << endl;
	if ( m_ssiItem.waitingAuth() )
		setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );
	
	if ( m_ssiItem.type() != 0xFFFF && m_ssiItem.waitingAuth() == false &&
	     onlineStatus() == Kopete::OnlineStatus::Unknown )
	{
		//make sure they're offline
		setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() );
	}
}


void ICQContact::userInfoUpdated( const QString& contact, const UserDetails& details )
{
	//kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << contact << contactId() << endl;
	if ( Oscar::normalize( contact  ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug( OSCAR_ICQ_DEBUG ) << k_funcinfo << "extendedStatus is " << details.extendedStatus() << endl;
	ICQ::Presence presence = ICQ::Presence::fromOscarStatus( details.extendedStatus() & 0xffff );
	setOnlineStatus( presence.toOnlineStatus() );
	
	if ( details.dcExternalIp().isUnspecified() )
		removeProperty( mProtocol->ipAddress );
	else
		setProperty( mProtocol->ipAddress, details.dcExternalIp().toString() );
	
	if ( details.clientName().isEmpty() )
		removeProperty( mProtocol->clientFeatures );
	else
		setProperty( mProtocol->clientFeatures, details.clientName() );
	
	OscarContact::userInfoUpdated( contact, details );
}

void ICQContact::userOnline( const QString& userId )
{
	if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug(OSCAR_ICQ_DEBUG) << "Setting " << userId << " online" << endl;
	ICQ::Presence online = mProtocol->statusManager()->presenceOf( ICQ::Presence::Online );
	//mAccount->engine()->requestStatusInfo( contactId() );
}

void ICQContact::userOffline( const QString& userId )
{
	if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) )
		return;

	kdDebug(OSCAR_ICQ_DEBUG) << "Setting " << userId << " offline" << endl;
	ICQ::Presence offline = mProtocol->statusManager()->presenceOf( ICQ::Presence::Offline );
	setOnlineStatus( mProtocol->statusManager()->onlineStatusOf( offline ) );
}

void ICQContact::loggedIn()
{
	if ( metaContact()->isTemporary() )
		return;
	
	if ( m_ssiItem.waitingAuth() )
		setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );

	if ( hasProperty( "nickName" ) )
	{
		int time = ( KApplication::random() % 20 ) * 1000;
		kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "updating nickname in " << time/1000 << " seconds" << endl;
		QTimer::singleShot( time, this, SLOT( requestShortInfo() ) );
	}

}

void ICQContact::requestShortInfo()
{
	if ( mAccount->isConnected() )
		mAccount->engine()->requestShortInfo( contactId() );
}
{'fraction_non_alphanumeric': 0.16848778046542665, 'fraction_numerical': 0.005004587538577029, 'mean_word_length': 4.293598233995585, 'pattern_counts': {'":': 0, '<': 129, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7201712', 'n_tokens_mistral': 3971, 'n_tokens_neox': 3724, 'n_words': 829}