2
kopetemessagehandlerchain.h - Kopete Message Handler Chain
4
Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk>
5
Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
7
*************************************************************************
9
* This library is free software; you can redistribute it and/or *
10
* modify it under the terms of the GNU Lesser General Public *
11
* License as published by the Free Software Foundation; either *
12
* version 2 of the License, or (at your option) any later version. *
14
*************************************************************************
17
#include "kopetemessagehandlerchain.h"
18
#include "kopetemessagehandler.h"
19
#include "kopetemessageevent.h"
20
#include "kopetechatsession.h"
31
class MessageHandlerChainTerminator : public MessageHandler
34
void handleMessage( MessageEvent *event )
36
kError( 14010 ) << "message got to end of chain!" << endl;
41
kError( 14010 ) << "request got to end of chain!" << endl;
46
// BEGIN MessageHandlerChain
48
class MessageHandlerChain::Private
51
Private() : first(0) {}
52
MessageHandler *first;
55
MessageHandlerChain::Ptr MessageHandlerChain::create( ChatSession *manager, Message::MessageDirection direction )
57
// create the handler chain
58
MessageHandlerChain *chain = new MessageHandlerChain;
60
// grab the list of handler factories
61
typedef MessageHandlerFactory::FactoryList FactoryList;
62
FactoryList factories = MessageHandlerFactory::messageHandlerFactories();
64
// create a sorted list of handlers
65
typedef QList<MessageHandler*> HandlerList;
66
typedef QMap<int,HandlerList> HandlerMap;
69
for( FactoryList::Iterator it = factories.begin(); it != factories.end(); ++it )
71
int position = (*it)->filterPosition( manager, direction );
72
if ( position == MessageHandlerFactory::StageDoNotCreate )
74
MessageHandler *handler = (*it)->create( manager, direction );
78
handlers[ position ].append( handler );
82
kDebug(14010) << "got " << count << " handlers for chain";
84
// add the handlers to the chain
85
MessageHandler *curr = 0;
86
for( HandlerMap::Iterator it = handlers.begin(); it != handlers.end(); ++it )
88
for ( HandlerList::Iterator handlerIt = (*it).begin(); handlerIt != (*it).end(); ++handlerIt )
91
curr->setNext( *handlerIt );
93
chain->d->first = *handlerIt;
98
// add a terminator to avoid crashes if the message somehow manages to get to the
99
// end of the chain. maybe we should use a MessageHandlerFactory for this too?
100
MessageHandler *terminator = new MessageHandlerChainTerminator;
102
curr->setNext( terminator );
103
else // empty chain: might happen for dir == Internal
104
chain->d->first = terminator;
106
return MessageHandlerChain::Ptr(chain);
109
MessageHandlerChain::MessageHandlerChain()
110
: QObject( 0 ), d( new Private )
114
MessageHandlerChain::~MessageHandlerChain()
117
MessageHandler *handler = d->first;
120
MessageHandler *next = handler->next();
128
ProcessMessageTask *MessageHandlerChain::processMessage( const Message &message )
130
MessageEvent *event = new MessageEvent( message );
131
return new ProcessMessageTask( MessageHandlerChain::Ptr(this), event );
134
int MessageHandlerChain::capabilities()
136
return d->first->capabilities();
139
// END MessageHandlerChain
141
// BEGIN ProcessMessageTask
143
class ProcessMessageTask::Private
146
Private( MessageHandlerChain::Ptr chain, MessageEvent *event ) : chain(chain), event(event) {}
147
MessageHandlerChain::Ptr chain;
151
ProcessMessageTask::ProcessMessageTask( MessageHandlerChain::Ptr chain, MessageEvent *event )
152
: d( new Private(chain, event) )
154
QTimer::singleShot( 0, this, SLOT(start()) );
155
connect( event, SIGNAL(done(Kopete::MessageEvent*)), this, SLOT(slotDone()) );
156
event->message().manager()->ref();
159
ProcessMessageTask::~ProcessMessageTask()
164
void ProcessMessageTask::start()
166
d->chain->d->first->handleMessageInternal( d->event );
169
void ProcessMessageTask::slotDone()
171
if ( d->event->message().manager() ) // In case manager was deleted during exit
172
d->event->message().manager()->deref();
177
void ProcessMessageTask::kill(bool quite)
183
MessageEvent *ProcessMessageTask::event()
188
//END ProcessMessageTask
192
#include "kopetemessagehandlerchain.moc"
194
// vim: set noet ts=4 sts=4 sw=4: