/* irccontactmanager.cpp - Manager of IRC Contacts Copyright (c) 2003 by Michel Hermier Kopete (c) 2003 by the Kopete developers ************************************************************************* * * * 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 #include #include #include #include #include #include IRCContactManager::IRCContactManager(const QString &nickName, IRCAccount *account, const char *name) : QObject(account, name), m_channels( QDict( 17, false ) ), m_users( QDict( 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 IRCContactManager::findChannelsByMember( IRCUserContact *contact ) { QValueList retVal; for( QDictIterator 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 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 accounts = Kopete::AccountManager::self()->accounts( IRCProtocol::protocol() ); QDictIterator 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 it( contact->contacts() ); it.current(); ++it ) { if( it.current()->account() == m_account ) { addToNotifyList( static_cast( 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"