From bcb704366cb5e333a626c18c308c7e0448a8e69f Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kopete/protocols/irc/ircsignalhandler.h | 334 ++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 kopete/protocols/irc/ircsignalhandler.h (limited to 'kopete/protocols/irc/ircsignalhandler.h') diff --git a/kopete/protocols/irc/ircsignalhandler.h b/kopete/protocols/irc/ircsignalhandler.h new file mode 100644 index 00000000..a87f814c --- /dev/null +++ b/kopete/protocols/irc/ircsignalhandler.h @@ -0,0 +1,334 @@ + +/* + ircsignalhandler.h - Maps signals from the IRC engine to contacts + + Copyright (c) 2004 by Jason Keirstead + + Kopete (c) 2002-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. * + * * + ************************************************************************* +*/ + +#ifndef _IRC_SIGNAL_HANDLER_H +#define _IRC_SIGNAL_HANDLER_H + +#include +#include +#include + +#include + +#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 QObjects cannot be inside templates, the QMember classes that connect +* to the slots are seperate. +*/ + +/*** Pre-declare mapping types for the QObjects **/ +struct IRCSignalMappingBase{}; + +struct IRCSignalMappingT : IRCSignalMappingBase +{ + virtual void exec( const QString & ) = 0; + virtual ~IRCSignalMappingT() {}; +}; + +struct IRCSignalMappingSingleT : IRCSignalMappingBase +{ + virtual void exec( const QString &, const QString & ) = 0; + virtual ~IRCSignalMappingSingleT() {}; +}; + +struct IRCSignalMappingDoubleT : IRCSignalMappingBase +{ + virtual void exec( const QString &, const QString &, const QString & ) = 0; + virtual ~IRCSignalMappingDoubleT() {}; +}; + +struct IRCSignalMappingTripleT : IRCSignalMappingBase +{ + virtual void exec( const QString &, const QString &, const QString &, const QString & ) = 0; + virtual ~IRCSignalMappingTripleT() {}; +}; + +/*** +QObject members, these connect to the KIRC signals and call +the Mapping functions when they emit. +**/ + +class QMember : public QObject +{ + Q_OBJECT + + public: + QMember( IRCSignalMappingT *m, QObject *p ) : QObject( p ), mapping( m ){}; + + public slots: + void slotEmit( const QString &id ) + { + //kdDebug(14120) << k_funcinfo << id << endl; + mapping->exec(id); + } + + private: + IRCSignalMappingT *mapping; +}; + +class QMemberSingle : public QObject +{ + Q_OBJECT + + public: + QMemberSingle( IRCSignalMappingSingleT *m, QObject *p ) : QObject( p ), mapping( m ){} + + public slots: + void slotEmit( const QString &id, const QString &arg ) + { + //kdDebug(14120) << k_funcinfo << id << " : " << arg << endl; + mapping->exec(id,arg); + } + + private: + IRCSignalMappingSingleT *mapping; +}; + +class QMemberDouble : public QObject +{ + Q_OBJECT + + public: + QMemberDouble( IRCSignalMappingDoubleT *m, QObject *p ) : QObject( p ), mapping( m ){} + + public slots: + void slotEmit( const QString &id, const QString &arg, const QString &arg2 ) + { + //kdDebug(14120) << k_funcinfo << id << " : " << arg << " : " << arg2 << endl; + mapping->exec(id,arg,arg2); + } + + private: + IRCSignalMappingDoubleT *mapping; +}; + +class QMemberTriple : public QObject +{ + Q_OBJECT + + public: + QMemberTriple( IRCSignalMappingTripleT *m, QObject *p ) : QObject( p ), mapping( m ){} + + public slots: + void slotEmit( const QString &id, const QString &arg, const QString &arg2, const QString &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 IRCSignalMapping : public IRCSignalMappingT +{ + public: + IRCSignalMapping( IRCContactManager *mgr, const char * /*signal*/, + void (TClass::*m)() ) : manager(mgr), method(m){} + + void exec( const QString &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 IRCSignalMappingSingle : public IRCSignalMappingSingleT +{ + public: + IRCSignalMappingSingle( IRCContactManager *mgr, const char * /*signal*/, + void (TClass::*m)(const QString&) ) : manager(mgr), method(m){} + + void exec( const QString &id, const QString &arg ) + { + TClass *c = (TClass*)manager->findContact( id ); + if( c ) + { + void (TClass::*tmp)(const QString&) = (void (TClass::*)(const QString&))method; + (*c.*tmp)( arg ); + } + } + + private: + IRCContactManager *manager; + void (TClass::*method)(const QString &); +}; + +template +class IRCSignalMappingDouble : public IRCSignalMappingDoubleT +{ + public: + IRCSignalMappingDouble( IRCContactManager *mgr, const char * /*signal*/, + void (TClass::*m)(const QString&,const QString&) ) : manager(mgr), method(m){} + + void exec( const QString &id,const QString &arg, const QString &arg2 ) + { + TClass *c = (TClass*)manager->findContact( id ); + if( c ) + { + void (TClass::*tmp)(const QString&,const QString&) = + (void (TClass::*)(const QString&,const QString&))method; + (*c.*tmp)(arg,arg2); + } + } + + private: + IRCContactManager *manager; + void (TClass::*method)(const QString &,const QString &); +}; + +template +class IRCSignalMappingTriple : public IRCSignalMappingTripleT +{ + public: + IRCSignalMappingTriple( IRCContactManager *mgr, const char * /*signal*/, + void (TClass::*m)(const QString&,const QString&,const QString&) ) + : manager(mgr), method(m){} + + void exec( const QString &id,const QString&arg, const QString &arg2, const QString &arg3 ) + { + TClass *c = (TClass*)manager->findContact( id ); + if( c ) + { + void (TClass::*tmp)(const QString&,const QString&,const QString&) = + (void (TClass::*)(const QString&,const QString&,const QString&))method; + (*c.*tmp)(arg,arg2,arg3); + } + } + + private: + IRCContactManager *manager; + void (TClass::*method)(const QString &,const QString &,const QString &); +}; + +class IRCSignalHandler : public QObject +{ + Q_OBJECT + + public: + IRCSignalHandler( IRCContactManager *manager ); + ~IRCSignalHandler(); + + private slots: + + /**** + Slots for signals with non-QString types + */ + + //Channel contact slots + void slotNamesList( const QString &, const QStringList & ); + void slotEndOfNames( const QString & ); + void slotTopicUser( const QString &, const QString&, const QDateTime &); + + //User contact slots + void slotNewWhoIsIdle(const QString &, unsigned long ); + void slotNewWhoReply(const QString &, const QString &, const QString &, const QString &, + const QString &, bool , const QString &, uint , const QString & ); + + private: + IRCContactManager *manager; + QValueList mappings; + + /**** + Signal mapping functions + */ + + template + inline void map( IRCContactManager *m, const char* signal, void (TClass::*method)() ) + { + IRCSignalMappingT *mapping = new IRCSignalMapping( m, signal, method ); + mappings.append(mapping); + QObject::connect( static_cast( m->mySelf()->account() )->engine(), signal, + new QMember( mapping, this), + SLOT( slotEmit( const QString &) ) + ); + } + + template + inline void mapSingle( IRCContactManager *m, + const char* signal, void (TClass::*method)(const QString&) ) + { + IRCSignalMappingSingleT *mapping = new IRCSignalMappingSingle( m, signal, method ); + mappings.append(mapping); + QObject::connect( static_cast( m->mySelf()->account() )->engine(), signal, + new QMemberSingle( mapping, this), + SLOT( slotEmit( const QString &, const QString &) ) + ); + } + + template + inline void mapDouble( IRCContactManager *m, + const char* signal, void (TClass::*method)(const QString&,const QString&) ) + { + IRCSignalMappingDoubleT *mapping = new IRCSignalMappingDouble( m, signal, method ); + mappings.append(mapping); + QObject::connect( static_cast( m->mySelf()->account() )->engine(), signal, + new QMemberDouble( mapping, this), + SLOT( slotEmit( const QString &, const QString &,const QString &) ) + ); + } + + template + inline void mapTriple( IRCContactManager *m, + const char* signal, + void (TClass::*method)(const QString&,const QString &, const QString &) ) + { + IRCSignalMappingTripleT *mapping = new IRCSignalMappingTriple( m, signal, method ); + mappings.append(mapping); + QObject::connect( static_cast( m->mySelf()->account() )->engine(), signal, + new QMemberTriple( mapping, this), + SLOT( slotEmit( const QString &, const QString &,const QString &,const QString &) ) + ); + } +}; + +#endif -- cgit v1.2.1