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/irc/ircsignalhandler.h

340 lines
9.7 KiB

/*
ircsignalhandler.h - Maps signals from the IRC engine to contacts
Copyright (c) 2004 by Jason Keirstead <jason@keirstead.org>
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. *
* *
*************************************************************************
*/
#ifndef _IRC_SIGNAL_HANDLER_H
#define _IRC_SIGNAL_HANDLER_H
#include <tqobject.h>
#include <tqstringlist.h>
#include <tqdatetime.h>
#include <kdebug.h>
#include "ircaccount.h"
#include "irccontactmanager.h"
/***
* IRC Signal handler. Mapps a KIRC engine signal to the right contact. Avoids
* Having a signal connected to 500+ slots where only one is valid, instead
* uses the contact dictionary.
*
* Warning: This file has a lot of black magic in it. Avoid it if
* you don't want your eyes to bleed. More below...
*
* Define some templated classes and methods to map a KIRC signal to the
* right contact. Having these templates greatly cuts down *A LOT* on the amount of
* code that would need to be in the signal mapper, at the expense of some readability.
*
* There are four IRCSignalMapping classes, one each for signals with 0, 1, 2,
* and 3 arguments ( plus the contact ID ). The classes take the signal, look
* up the contact it is for, and call the function passed into the class by the
* mapping function.
*
* Since TQObjects cannot be inside templates, the QMember classes that connect
* to the slots are seperate.
*/
/*** Pre-declare mapping types for the TQObjects **/
struct IRCSignalMappingBase{};
struct IRCSignalMappingT : IRCSignalMappingBase
{
virtual void exec( const TQString & ) = 0;
virtual ~IRCSignalMappingT() {};
};
struct IRCSignalMappingSingleT : IRCSignalMappingBase
{
virtual void exec( const TQString &, const TQString & ) = 0;
virtual ~IRCSignalMappingSingleT() {};
};
struct IRCSignalMappingDoubleT : IRCSignalMappingBase
{
virtual void exec( const TQString &, const TQString &, const TQString & ) = 0;
virtual ~IRCSignalMappingDoubleT() {};
};
struct IRCSignalMappingTripleT : IRCSignalMappingBase
{
virtual void exec( const TQString &, const TQString &, const TQString &, const TQString & ) = 0;
virtual ~IRCSignalMappingTripleT() {};
};
/***
TQObject members, these connect to the KIRC signals and call
the Mapping functions when they emit.
**/
class QMember : public TQObject
{
Q_OBJECT
TQ_OBJECT
public:
QMember( IRCSignalMappingT *m, TQObject *p ) : TQObject( p ), mapping( m ){};
public slots:
void slotEmit( const TQString &id )
{
//kdDebug(14120) << k_funcinfo << id << endl;
mapping->exec(id);
}
private:
IRCSignalMappingT *mapping;
};
class QMemberSingle : public TQObject
{
Q_OBJECT
TQ_OBJECT
public:
QMemberSingle( IRCSignalMappingSingleT *m, TQObject *p ) : TQObject( p ), mapping( m ){}
public slots:
void slotEmit( const TQString &id, const TQString &arg )
{
//kdDebug(14120) << k_funcinfo << id << " : " << arg << endl;
mapping->exec(id,arg);
}
private:
IRCSignalMappingSingleT *mapping;
};
class QMemberDouble : public TQObject
{
Q_OBJECT
TQ_OBJECT
public:
QMemberDouble( IRCSignalMappingDoubleT *m, TQObject *p ) : TQObject( p ), mapping( m ){}
public slots:
void slotEmit( const TQString &id, const TQString &arg, const TQString &arg2 )
{
//kdDebug(14120) << k_funcinfo << id << " : " << arg << " : " << arg2 << endl;
mapping->exec(id,arg,arg2);
}
private:
IRCSignalMappingDoubleT *mapping;
};
class QMemberTriple : public TQObject
{
Q_OBJECT
TQ_OBJECT
public:
QMemberTriple( IRCSignalMappingTripleT *m, TQObject *p ) : TQObject( p ), mapping( m ){}
public slots:
void slotEmit( const TQString &id, const TQString &arg, const TQString &arg2, const TQString &arg3 )
{
//kdDebug(14120) << k_funcinfo << id << " : " << arg << " : " << arg2 << " : " << arg3 << endl;
mapping->exec(id,arg,arg2,arg3);
}
private:
IRCSignalMappingTripleT *mapping;
};
/***
Mapping classes. These contain pointers to the functions to call. We first
look up the right contact in the contact manager's dictionary, and then
call the method
**/
template <class TClass>
class IRCSignalMapping : public IRCSignalMappingT
{
public:
IRCSignalMapping( IRCContactManager *mgr, const char * /*signal*/,
void (TClass::*m)() ) : manager(mgr), method(m){}
void exec( const TQString &id )
{
TClass *c = (TClass*)manager->findContact( id );
if( c )
{
void (TClass::*tmp)() = (void (TClass::*)())method;
(*c.*tmp)();
}
}
private:
IRCContactManager *manager;
void (TClass::*method)();
};
template <class TClass>
class IRCSignalMappingSingle : public IRCSignalMappingSingleT
{
public:
IRCSignalMappingSingle<TClass>( IRCContactManager *mgr, const char * /*signal*/,
void (TClass::*m)(const TQString&) ) : manager(mgr), method(m){}
void exec( const TQString &id, const TQString &arg )
{
TClass *c = (TClass*)manager->findContact( id );
if( c )
{
void (TClass::*tmp)(const TQString&) = (void (TClass::*)(const TQString&))method;
(*c.*tmp)( arg );
}
}
private:
IRCContactManager *manager;
void (TClass::*method)(const TQString &);
};
template <class TClass>
class IRCSignalMappingDouble : public IRCSignalMappingDoubleT
{
public:
IRCSignalMappingDouble<TClass>( IRCContactManager *mgr, const char * /*signal*/,
void (TClass::*m)(const TQString&,const TQString&) ) : manager(mgr), method(m){}
void exec( const TQString &id,const TQString &arg, const TQString &arg2 )
{
TClass *c = (TClass*)manager->findContact( id );
if( c )
{
void (TClass::*tmp)(const TQString&,const TQString&) =
(void (TClass::*)(const TQString&,const TQString&))method;
(*c.*tmp)(arg,arg2);
}
}
private:
IRCContactManager *manager;
void (TClass::*method)(const TQString &,const TQString &);
};
template <class TClass>
class IRCSignalMappingTriple : public IRCSignalMappingTripleT
{
public:
IRCSignalMappingTriple<TClass>( IRCContactManager *mgr, const char * /*signal*/,
void (TClass::*m)(const TQString&,const TQString&,const TQString&) )
: manager(mgr), method(m){}
void exec( const TQString &id,const TQString&arg, const TQString &arg2, const TQString &arg3 )
{
TClass *c = (TClass*)manager->findContact( id );
if( c )
{
void (TClass::*tmp)(const TQString&,const TQString&,const TQString&) =
(void (TClass::*)(const TQString&,const TQString&,const TQString&))method;
(*c.*tmp)(arg,arg2,arg3);
}
}
private:
IRCContactManager *manager;
void (TClass::*method)(const TQString &,const TQString &,const TQString &);
};
class IRCSignalHandler : public TQObject
{
Q_OBJECT
TQ_OBJECT
public:
IRCSignalHandler( IRCContactManager *manager );
~IRCSignalHandler();
private slots:
/****
Slots for signals with non-TQString types
*/
//Channel contact slots
void slotNamesList( const TQString &, const TQStringList & );
void slotEndOfNames( const TQString & );
void slotTopicUser( const TQString &, const TQString&, const TQDateTime &);
//User contact slots
void slotNewWhoIsIdle(const TQString &, unsigned long );
void slotNewWhoReply(const TQString &, const TQString &, const TQString &, const TQString &,
const TQString &, bool , const TQString &, uint , const TQString & );
private:
IRCContactManager *manager;
TQValueList<IRCSignalMappingBase*> mappings;
/****
Signal mapping functions
*/
template <class TClass>
inline void map( IRCContactManager *m, const char* signal, void (TClass::*method)() )
{
IRCSignalMappingT *mapping = new IRCSignalMapping<TClass>( m, signal, method );
mappings.append(mapping);
TQObject::connect( static_cast<IRCAccount*>( m->mySelf()->account() )->engine(), signal,
new QMember( mapping, this),
TQT_SLOT( slotEmit( const TQString &) )
);
}
template <class TClass>
inline void mapSingle( IRCContactManager *m,
const char* signal, void (TClass::*method)(const TQString&) )
{
IRCSignalMappingSingleT *mapping = new IRCSignalMappingSingle<TClass>( m, signal, method );
mappings.append(mapping);
TQObject::connect( static_cast<IRCAccount*>( m->mySelf()->account() )->engine(), signal,
new QMemberSingle( mapping, this),
TQT_SLOT( slotEmit( const TQString &, const TQString &) )
);
}
template <class TClass>
inline void mapDouble( IRCContactManager *m,
const char* signal, void (TClass::*method)(const TQString&,const TQString&) )
{
IRCSignalMappingDoubleT *mapping = new IRCSignalMappingDouble<TClass>( m, signal, method );
mappings.append(mapping);
TQObject::connect( static_cast<IRCAccount*>( m->mySelf()->account() )->engine(), signal,
new QMemberDouble( mapping, this),
TQT_SLOT( slotEmit( const TQString &, const TQString &,const TQString &) )
);
}
template <class TClass>
inline void mapTriple( IRCContactManager *m,
const char* signal,
void (TClass::*method)(const TQString&,const TQString &, const TQString &) )
{
IRCSignalMappingTripleT *mapping = new IRCSignalMappingTriple<TClass>( m, signal, method );
mappings.append(mapping);
TQObject::connect( static_cast<IRCAccount*>( m->mySelf()->account() )->engine(), signal,
new QMemberTriple( mapping, this),
TQT_SLOT( slotEmit( const TQString &, const TQString &,const TQString &,const TQString &) )
);
}
};
#endif