summaryrefslogtreecommitdiffstats
path: root/kopete/libkopete/kopetemessagehandler.h
blob: a222ba2b45ad9b1b2d48a5171bc8f1ceb69c7283 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
    kopetemessagehandler.h - Kopete Message Filtering

    Copyright (c) 2004      by Richard Smith         <kde@metafoo.co.uk>
    Kopete    (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#ifndef KOPETEMESSAGEHANDLER_H
#define KOPETEMESSAGEHANDLER_H

#include <tqobject.h>
//#include <kdemacros.h>
#include "kopete_export.h"

//FIXME: Message::MessageDirection could be moved into namespace Kopete
// to avoid this being included everywhere
#include "kopetemessage.h"

#include <tqvaluelist.h>

namespace Kopete
{

class MessageEvent;
class ChatSession;

/**
 * @author Richard Smith       <kde@metafoo.co.uk>
 *
 * An object which sits between the protocol and the chat window which
 * intercepts and processes messages on their way through.
 *
 * This class implements Handler role in the Chain of Responsibility pattern.
 * The Client role will be filled by the Kopete::MessageHandlerChain class.
 */
class KOPETE_EXPORT MessageHandler : public TQObject
{
	Q_OBJECT
  
public:
	MessageHandler();
	virtual ~MessageHandler() = 0;

	/**
	 * @return the next handler in the chain
	 */
	MessageHandler *next();
	// FIXME: remove?
	void setNext( MessageHandler *next );

	/**
	 * @brief Gets the rich-text capabilities of this message handling object
	 *
	 * The default implementation returns next()->capabilities().
	 */
	virtual int capabilities();

	/**
	 * @brief Performs any processing necessary on the message
	 *
	 * @param event The message event to process. Should not be null.
	 * 
	 * Overriders of this handler @em must cause (possibly asynchronously)
	 * one of the following to happen:
	 *  - @p event->discard() to be called
	 *  - @p event->continue() to be called
	 *  - this base class implementation to be called (equivalent to event->continue() but faster)
	 * 
	 * The base class implementation passes the event on to the next
	 * handler in the chain.
	 * 
	 * @note If you store @p event, be aware that it could be deleted at any time, and either
	 *       connect to the its discarded(Kopete::MessageEvent*) signal or store it in a TQGuardedPtr.
	 */
	virtual void handleMessage( MessageEvent *event );

	/** @internal */
	void handleMessageInternal( MessageEvent *event );
private slots:
	/**
	 * @internal The message has been accepted. Pass it on to the next handler.
	 */
	void messageAccepted( Kopete::MessageEvent *event );

private:
	class Private;
	Private *d;
};

/**
 * @author Richard Smith       <kde@metafoo.co.uk>
 *
 * A factory for creating MessageHandlers. Instantiate a class derived from MessageHandlerFactory
 * in order to make your MessageHandler be automatically added to the list of handlers used
 * when constructing handler chains.
 * 
 * @note If you construct a handler for an Inbound chain, it may still be asked to process Outbound
 * messages. This is because when a message is being sent it first passes through the Outbound
 * chain to the protocol, then (when it has been delivered) it passes back through the Inbound
 * chain to the chat window to be displayed.
 */
class KOPETE_EXPORT MessageHandlerFactory
{
public:
	/**
	 * Constructs a MessageHandlerFactory, and adds it to the list of factories considered when
	 * creating a MessageHandlerChain for a ChatSession.
	 * 
	 * @note Since the factory is added to the list of possible factories before the object is
	 * finished being constructed, it is not safe to call any function from a derived class's
	 * constructor which may cause a MessageHandlerChain to be created.
	 */
	MessageHandlerFactory();
	/**
	 * Destroys the MessageHandlerFactory and removes it from the list of factories.
	 */
	virtual ~MessageHandlerFactory();
	
	typedef TQValueList<MessageHandlerFactory*> FactoryList;
	/**
	 * @return the list of registered message handler factories
	 */
	static FactoryList messageHandlerFactories();
	
	/**
	 * @brief Creates a message handler for a given manager in a given direction.
	 * @param manager The manager whose message handler chain the message handler is for
	 * @param direction The direction of the chain that is being created.
	 * @return the @ref MessageHandler object to put in the chain, or 0 if none is needed.
	 */
	virtual MessageHandler *create( ChatSession *manager, Message::MessageDirection direction ) = 0;
	
	/**
	 * Special stages usable with any message direction
	 */
	enum SpecialStage
	{
		StageDoNotCreate = -10000, ///< do not create a filter for this stage
		StageStart = 0,            ///< start of processing
		StageEnd = 10000           ///< end of processing
	};
	
	/**
	 * Processing stages for handlers in inbound message handler chains
	 */
	enum InboundStage
	{
		InStageStart = 0,        ///< message was just received
		InStageToSent = 2000,    ///< convert from received format to sent format
		InStageToDesired = 5000, ///< convert to how the user wants the message
		InStageFormat = 7000,    ///< decorate the message without changing the content
		InStageEnd = 10000       ///< message ready for display
	};
	
	/**
	 * Processing stages for handlers in outbound message handler chains
	 */
	enum OutboundStage
	{
		OutStageStart = 0,        ///< user just hit Send
		OutStageParse = 2000,     ///< process commands
		OutStageToDesired = 4000, ///< convert to how the user wanted to send
		OutStageFormat = 6000,    ///< decorate the message without changing the content
		OutStageToSent = 8000,    ///< convert to the format to send in
		OutStageEnd = 10000       ///< message ready for sending
	};
	
	/**
	 * Processing stages for handlers in internal message handler chains
	 */
	enum InternalStage
	{
		IntStageStart = 0,  ///< some component just created the message
		IntStageEnd = 10000 ///< message ready for display
	};
	
	/**
	 * Offsets within a processing stage. Using these values allows finer
	 * control over where in a chain a message handler will be added. Add
	 * one of these values to values from the various Stage enumerations
	 * to form a filter position.
	 */
	enum Offset
	{
		OffsetBefore = -90,
		OffsetVeryEarly = -60,
		OffsetEarly = -30,
		OffsetNormal = 0,
		OffsetLate = 30,
		OffsetVeryLate = 60,
		OffsetAfter = 90
	};
	
	/**
	 * @brief Returns the position in the message handler chain to put this factory's handlers
	 * @param manager The manager whose message handler chain the message handler is for
	 * @param direction The direction of the chain that is being created.
	 * @return a member of the InboundStage, OutboundStage or InternalStage enumeration, as
	 *         appropriate, optionally combined with a member of the Offset enumeration.
	 * @retval StageDoNotCreate No filter should be created for this chain.
	 */
	virtual int filterPosition( ChatSession *manager, Message::MessageDirection direction ) = 0;
	
private:
	// noncopyable
	MessageHandlerFactory(const MessageHandlerFactory &);
	void operator=(const MessageHandlerFactory &);
	
	class Private;
	Private *d;
};

}

#endif