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.
298 lines
8.1 KiB
298 lines
8.1 KiB
15 years ago
|
/*
|
||
|
irccontactmanager.cpp - Manager of IRC Contacts
|
||
|
|
||
|
Copyright (c) 2003 by Michel Hermier <michel.hermier@wanadoo.fr>
|
||
|
|
||
|
Kopete (c) 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 "ircusercontact.h"
|
||
|
#include "ircaccount.h"
|
||
|
#include "irccontactmanager.h"
|
||
|
#include "ircprotocol.h"
|
||
|
#include "ircsignalhandler.h"
|
||
|
|
||
|
#include "ircservercontact.h"
|
||
|
#include "ircchannelcontact.h"
|
||
|
|
||
|
#include "kircengine.h"
|
||
|
|
||
|
#include <kopeteaccountmanager.h>
|
||
|
#include <kopetemetacontact.h>
|
||
|
#include <kopetecontactlist.h>
|
||
|
#include <kopeteview.h>
|
||
|
|
||
|
#include <kconfig.h>
|
||
|
#include <kstandarddirs.h>
|
||
|
|
||
|
#include <qtimer.h>
|
||
|
|
||
|
IRCContactManager::IRCContactManager(const QString &nickName, IRCAccount *account, const char *name)
|
||
|
: QObject(account, name),
|
||
|
m_channels( QDict<IRCChannelContact>( 17, false ) ),
|
||
|
m_users( QDict<IRCUserContact>( 577, false ) ),
|
||
|
m_account( account )
|
||
|
{
|
||
|
m_mySelf = findUser(nickName);
|
||
|
|
||
|
Kopete::MetaContact *m = new Kopete::MetaContact();
|
||
|
// m->setTemporary( true );
|
||
|
m_myServer = new IRCServerContact(this, account->networkName(), m);
|
||
|
|
||
|
QObject::connect(account->engine(), SIGNAL(incomingMessage(const QString &, const QString &, const QString &)),
|
||
|
this, SLOT(slotNewMessage(const QString &, const QString &, const QString &)));
|
||
|
|
||
|
QObject::connect(account->engine(), SIGNAL(incomingPrivMessage(const QString &, const QString &, const QString &)),
|
||
|
this, SLOT(slotNewPrivMessage(const QString &, const QString &, const QString &)));
|
||
|
|
||
|
QObject::connect(account->engine(), SIGNAL(incomingNickChange(const QString &, const QString &)),
|
||
|
this, SLOT( slotNewNickChange(const QString&, const QString&)));
|
||
|
|
||
|
QObject::connect(account->engine(), SIGNAL(successfullyChangedNick(const QString &, const QString &)),
|
||
|
this, SLOT( slotNewNickChange(const QString &, const QString &)));
|
||
|
|
||
|
QObject::connect(account->engine(), SIGNAL(incomingUserOnline(const QString &)),
|
||
|
this, SLOT( slotIsonRecieved()));
|
||
|
|
||
|
QObject::connect(Kopete::ContactList::self(), SIGNAL(metaContactAdded( Kopete::MetaContact * )),
|
||
|
this, SLOT( slotContactAdded( Kopete::MetaContact* )));
|
||
|
|
||
|
socketTimeout = 15000;
|
||
|
QString timeoutPath = locate( "config", "kioslaverc" );
|
||
|
if( !timeoutPath.isEmpty() )
|
||
|
{
|
||
|
KConfig config( timeoutPath );
|
||
|
socketTimeout = config.readNumEntry( "ReadTimeout", 15 ) * 1000;
|
||
|
}
|
||
|
|
||
|
m_NotifyTimer = new QTimer(this);
|
||
|
QObject::connect(m_NotifyTimer, SIGNAL(timeout()),
|
||
|
this, SLOT(checkOnlineNotifyList()));
|
||
|
m_NotifyTimer->start(30000); // check online every 30sec
|
||
|
|
||
|
new IRCSignalHandler(this);
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::slotNewNickChange(const QString &oldnick, const QString &newnick)
|
||
|
{
|
||
|
IRCUserContact *c = m_users[ oldnick ];
|
||
|
if( c )
|
||
|
{
|
||
|
m_users.insert(newnick, c);
|
||
|
m_users.remove(oldnick);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::slotNewMessage(const QString &originating, const QString &channel, const QString &message)
|
||
|
{
|
||
|
IRCContact *from = findUser(originating);
|
||
|
IRCChannelContact *to = findChannel(channel);
|
||
|
emit privateMessage(from, to, message);
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::slotNewPrivMessage(const QString &originating, const QString &user, const QString &message)
|
||
|
{
|
||
|
IRCContact *from = findUser(originating);
|
||
|
IRCUserContact *to = findUser(user);
|
||
|
emit privateMessage(from, to, message);
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::unregister(Kopete::Contact *contact)
|
||
|
{
|
||
|
unregisterChannel(contact, true);
|
||
|
unregisterUser(contact, true);
|
||
|
}
|
||
|
|
||
|
QValueList<IRCChannelContact*> IRCContactManager::findChannelsByMember( IRCUserContact *contact )
|
||
|
{
|
||
|
QValueList<IRCChannelContact*> retVal;
|
||
|
for( QDictIterator<IRCChannelContact> it(m_channels); it.current(); ++it )
|
||
|
{
|
||
|
if( it.current()->manager(Kopete::Contact::CannotCreate) )
|
||
|
{
|
||
|
if( contact == m_mySelf )
|
||
|
retVal.push_back( it.current() );
|
||
|
else
|
||
|
{
|
||
|
bool c = true;
|
||
|
|
||
|
Kopete::ContactPtrList members = it.current()->manager()->members();
|
||
|
for( QPtrListIterator<Kopete::Contact> it2( members ); c && it2.current(); ++it2 )
|
||
|
{
|
||
|
if( it2.current() == contact )
|
||
|
{
|
||
|
retVal.push_back( it.current() );
|
||
|
c = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
IRCChannelContact *IRCContactManager::findChannel(const QString &name, Kopete::MetaContact *m)
|
||
|
{
|
||
|
IRCChannelContact *channel = m_channels[ name ];
|
||
|
|
||
|
if ( !channel )
|
||
|
{
|
||
|
if( !m )
|
||
|
{
|
||
|
m = new Kopete::MetaContact();
|
||
|
m->setTemporary( true );
|
||
|
}
|
||
|
|
||
|
channel = new IRCChannelContact(this, name, m);
|
||
|
m_channels.insert( name, channel );
|
||
|
QObject::connect(channel, SIGNAL(contactDestroyed(Kopete::Contact *)),
|
||
|
this, SLOT(unregister(Kopete::Contact *)));
|
||
|
}
|
||
|
|
||
|
return channel;
|
||
|
}
|
||
|
|
||
|
IRCChannelContact *IRCContactManager::existChannel( const QString &channel ) const
|
||
|
{
|
||
|
return m_channels[ channel ];
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::unregisterChannel(Kopete::Contact *contact, bool force )
|
||
|
{
|
||
|
IRCChannelContact *channel = (IRCChannelContact*)contact;
|
||
|
if( force || (
|
||
|
channel!=0 &&
|
||
|
!channel->isChatting() &&
|
||
|
channel->metaContact()->isTemporary() ) )
|
||
|
{
|
||
|
m_channels.remove( channel->nickName() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IRCUserContact *IRCContactManager::findUser(const QString &name, Kopete::MetaContact *m)
|
||
|
{
|
||
|
IRCUserContact *user = m_users[name.section('!', 0, 0)];
|
||
|
|
||
|
if ( !user )
|
||
|
{
|
||
|
if( !m )
|
||
|
{
|
||
|
m = new Kopete::MetaContact();
|
||
|
m->setTemporary( true );
|
||
|
}
|
||
|
|
||
|
user = new IRCUserContact(this, name, m);
|
||
|
m_users.insert( name, user );
|
||
|
QObject::connect(user, SIGNAL(contactDestroyed(Kopete::Contact *)),
|
||
|
this, SLOT(unregister(Kopete::Contact *)));
|
||
|
}
|
||
|
|
||
|
return user;
|
||
|
}
|
||
|
|
||
|
IRCUserContact *IRCContactManager::existUser( const QString &user ) const
|
||
|
{
|
||
|
return m_users[user];
|
||
|
}
|
||
|
|
||
|
IRCContact *IRCContactManager::findContact( const QString &id, Kopete::MetaContact *m )
|
||
|
{
|
||
|
if( KIRC::Entity::isChannel(id) )
|
||
|
return findChannel( id, m );
|
||
|
else
|
||
|
return findUser( id, m );
|
||
|
}
|
||
|
|
||
|
IRCContact *IRCContactManager::existContact( const KIRC::Engine *engine, const QString &id )
|
||
|
{
|
||
|
QDict<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts( IRCProtocol::protocol() );
|
||
|
QDictIterator<Kopete::Account> it(accounts);
|
||
|
for( ; it.current(); ++it )
|
||
|
{
|
||
|
IRCAccount *account = (IRCAccount *)it.current();
|
||
|
if( account && account->engine() == engine )
|
||
|
return account->contactManager()->existContact(id);
|
||
|
}
|
||
|
return 0L;
|
||
|
}
|
||
|
|
||
|
IRCContact *IRCContactManager::existContact( const QString &id ) const
|
||
|
{
|
||
|
if( KIRC::Entity::isChannel(id) )
|
||
|
return existChannel( id );
|
||
|
else
|
||
|
return existUser( id );
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::unregisterUser(Kopete::Contact *contact, bool force )
|
||
|
{
|
||
|
IRCUserContact *user = (IRCUserContact *)contact;
|
||
|
if( force || (
|
||
|
user!=0 &&
|
||
|
user!=mySelf() &&
|
||
|
!user->isChatting() &&
|
||
|
user->metaContact()->isTemporary() ) )
|
||
|
{
|
||
|
m_users.remove( user->nickName() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::slotContactAdded( Kopete::MetaContact *contact )
|
||
|
{
|
||
|
for( QPtrListIterator<Kopete::Contact> it( contact->contacts() ); it.current(); ++it )
|
||
|
{
|
||
|
if( it.current()->account() == m_account )
|
||
|
{
|
||
|
addToNotifyList( static_cast<IRCContact*>( it.current() )->nickName() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::addToNotifyList(const QString &nick)
|
||
|
{
|
||
|
if (!m_NotifyList.contains(nick.lower()))
|
||
|
{
|
||
|
m_NotifyList.append(nick);
|
||
|
checkOnlineNotifyList();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::removeFromNotifyList(const QString &nick)
|
||
|
{
|
||
|
if (m_NotifyList.contains(nick.lower()))
|
||
|
m_NotifyList.remove(nick.lower());
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::checkOnlineNotifyList()
|
||
|
{
|
||
|
if( m_account->engine()->isConnected() )
|
||
|
{
|
||
|
isonRecieved = false;
|
||
|
m_account->engine()->ison( m_NotifyList );
|
||
|
//QTimer::singleShot( socketTimeout, this, SLOT( slotIsonTimeout() ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::slotIsonRecieved()
|
||
|
{
|
||
|
isonRecieved = true;
|
||
|
}
|
||
|
|
||
|
void IRCContactManager::slotIsonTimeout()
|
||
|
{
|
||
|
if( !isonRecieved )
|
||
|
m_account->engine()->quit("", true);
|
||
|
}
|
||
|
|
||
|
#include "irccontactmanager.moc"
|