1/*
2 kopetemessage.h - Base class for Kopete messages
3
4 Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org>
5 Copyright (c) 2002-2004 by Olivier Goffart <ogoffart@kde.org>
6 Copyright (c) 2006-2007 by Charles Connell <charles@connells.org>
7 Copyright (c) 2007 by Michaël Larouche <larouche@kde.org>
8 Copyright (c) 2008 by Roman Jarosz <kedgedev@centrum.cz>
9
10 Kopete (c) 2002-2008 by the Kopete developers <kopete-devel@kde.org>
11
12 *************************************************************************
13 * *
14 * This library is free software; you can redistribute it and/or *
15 * modify it under the terms of the GNU Lesser General Public *
16 * License as published by the Free Software Foundation; either *
17 * version 2 of the License, or (at your option) any later version. *
18 * *
19 *************************************************************************
20*/
21
22#ifndef KOPETEMESSAGE_H
23#define KOPETEMESSAGE_H
24
25#include <QtCore/QSharedData>
26#include <QtCore/QList>
27#include <QtCore/Qt>
28
29#include "kopete_export.h"
30
31class QByteArray;
32class QColor;
33class QDateTime;
34class QFont;
35class QTextCodec;
36class QTextDocument;
37class QStringList;
38class QPixmap;
39
40namespace Kopete {
41
42
43class ChatSession;
44class Contact;
45
46
47/**
48 * @brief Representation of a message in Kopete
49 *
50 * @author Martijn Klingens <klingens@kde.org>
51 * @author Olivier Goffart <ogoffart@kde.org>
52 * @author Charles Connell <charles@connells.org>
53 * @author Michaël Larouche <larouche@kde.org>
54 *
55 * Message represents any kind of messages shown on a chat view.
56 * The message may contain a simple plain text string, or a rich text HTML
57 * message. Also, Message can use a QTextDocument to structure the message.
58 *
59 * Message in plain text can however have a color or a specific font. You can
60 * set color with setForegroundColor() and setBackgroundColor() and change the font
61 * with setFont()
62 *
63 * Message have a direction from where the message come from. By default, the direction
64 * is Internal but it is strongly advised to set the direction explicitly.
65 *
66 * @section plainMessage Creating a plain text message
67 * @code
68Kopete::Message newMessage(sourceContact, destionationContact);
69newMessage.setPlainBody( QString("A plain text message") );
70newMessage.setDirection( Kopete::Message::Inbound );
71 * @endcode
72 *
73 * @section richTextMessage Creating a complete rich text message
74 * @code
75Kopete::Message richTextMessage(sourceContact, destinationContactList);
76richTextMessage.setTimestamp( QDateTime::currentDateTime() );
77richTextMessage.setDirection( Kopete::Message::Outbound );
78richTextMessage.setSubject( QString("Kopete API documentation thread") );
79richTextMessage.setHtmlBody( QString("<b>A bold text</b>") );
80 * @endcode
81 */
82class KOPETE_EXPORT Message
83{
84public:
85 /**
86 * Direction of a message.
87 */
88 enum MessageDirection
89 {
90 Inbound = 0, ///< Message is from the chat partner
91 Outbound = 1, ///< Message sent by the user
92 Internal= 2 ///< (Default) Message which are not sent via the network. This is just a notification a plugin can show in a chat view
93 };
94
95 /**
96 * Specifies the type of the message.
97 */
98 enum MessageType
99 {
100 TypeNormal, ///< A typical message
101 TypeAction, ///< An IRC-style action.
102 TypeFileTransferRequest, ///< A incoming file transfer request message
103 TypeVoiceClipRequest ///< A incoming voice clip message
104 };
105
106 /**
107 * Specifies the type of notification that will be sent with this message
108 */
109 enum MessageImportance
110 {
111 Low = 0, ///< almost no notifications. automatically used in groupChat
112 Normal = 1, ///< Default notification, for normal message
113 Highlight = 2 ///< Highlight notification, for most important messages, which require particular attentions.
114 };
115
116 enum MessageState
117 {
118 StateUnknown = 0, ///< state of message isn't known (e.g. protocol doesn't support message acknowledgment)
119 StateSending = 1, ///< message was sent but not yet delivered.
120 StateSent = 2, ///< message was delivered
121 StateError = 3 ///< message has not been delivered
122 };
123
124 /**
125 * Constructs a new empty message
126 */
127 explicit Message();
128
129 /**
130 * Deref and clean private object if refcount == 0
131 */
132 ~Message();
133
134 /**
135 * @brief Constructs a new message with a from and to contact
136 *
137 * This constructor is a convience of the constructor who
138 * take a list of contacts for destination
139 * @param fromKC Contact who send the message
140 * @param toKC Contact which the message is destined.
141 */
142 explicit Message( const Contact *fromKC, const Contact *toKC );
143 /**
144 * @brief Constructs a new message with many contacts as the destination.
145 * @param fromKC Contact who send the message
146 * @param contacts List of Contact to send the message
147 */
148 explicit Message( const Contact *fromKC, const QList<Contact*> &contacts);
149
150 /**
151 * Copy constructor.
152 * Just adds a reference, doesn't actually copy.
153 */
154 Message( const Message &other );
155
156 /**
157 * Assignment operator
158 * Just like the copy constructor it just refs and doesn't copy.
159 */
160 Message & operator=( const Message &other );
161
162 /**
163 * @brief Get unique message id.
164 * @return message id
165 */
166 uint id() const;
167
168 /**
169 * @brief Get next unique message id.
170 * @return next id
171 */
172 static uint nextId();
173
174 /**
175 * @brief Accessor method for the timestamp of the message
176 * @return The message's timestamp
177 */
178 QDateTime timestamp() const;
179
180 /**
181 * @brief Set the message timestamp
182 * @param timestamp timestamp as QDateTime. By default the current date and time.
183 */
184 void setTimestamp(const QDateTime &timestamp);
185
186 /**
187 * @brief Accessor method for the "delayed" attribute of the message
188 * @return true if the message was delayed (for example because it has
189 * been stored on a server while the intended recipient was offline or
190 * because the message is contained in the history of a group chat room).
191 */
192 bool delayed() const;
193
194 /**
195 * @brief Set the "delayed" attribute of the message
196 * @param delay whether the message was delayed, see delayed()
197 */
198 void setDelayed(bool delay);
199
200 /**
201 * @brief Accessor method for the Contact that sent this message
202 * @return The Contact who sent this message
203 */
204 const Contact * from() const;
205
206 /**
207 * @brief Accessor method for the Contacts that this message was sent to
208 * @return Pointer list of the Contacts this message was sent to
209 */
210 QList<Contact*> to() const;
211
212 /**
213 * @brief Accessor method for the message type
214 * @return The type of the message
215 * @see MessageType
216 */
217 MessageType type() const;
218
219 /**
220 * @brief Set message type
221 * @param type The type of the message
222 * @see MessageType
223 */
224 void setType(MessageType type);
225
226 /**
227 * @brief Accessor method for the preferred plugin
228 * If null, Kopete will use the user's preferred plugin.
229 * @return The preferred plugin
230 */
231 QString requestedPlugin() const;
232
233 /**
234 * @brief Set a view plugin which will display the message
235 *
236 * This is used mostly by Jabber plugin to select between
237 * the email window or the chat window depending of the
238 * type of message.
239 * @param requesedPlugin View plugin name
240 */
241 void setRequestedPlugin(const QString &requestedPlugin);
242
243 /**
244 * @brief Accessor method for the foreground color
245 * @return The message's foreground color
246 */
247 QColor foregroundColor() const;
248
249 /**
250 * @brief Accessor method for the background color of the message
251 * @return The message's background color
252 */
253 QColor backgroundColor() const;
254
255 /**
256 * @brief Accesssor method for the direction of the text based on what language it is in
257 * @return The message text's direction
258 */
259 bool isRightToLeft() const;
260
261 /**
262 * returns QStringList with regexp patterns
263 * will be used to look for links in the message
264 */
265 const QStringList regexpPatterns();
266
267 /**
268 * @brief Accessor method for the font of the message
269 * @return The message's font
270 */
271 QFont font() const;
272
273 /**
274 * @brief Accessor method for the subject of the message
275 * @return The message subject
276 */
277 QString subject() const;
278
279 /**
280 * @brief Set message subject
281 * @param subject Message's subject
282 */
283 void setSubject(const QString &subject);
284
285 /**
286 * @brief Accessor method for the body of the message
287 * This is used internaly, to modify it make a copy of it with QTextDocument::clone()
288 * @return The message body
289 */
290 const QTextDocument *body() const;
291
292 /**
293 * @brief Accessor method for the format of the message
294 * @return The message format
295 */
296 Qt::TextFormat format() const;
297
298 /**
299 * @brief Accessor method for the direction of the message
300 * @return The message direction
301 */
302 MessageDirection direction() const;
303
304 /**
305 * @brief Set the message direction
306 * @param direction The message direction
307 * @see MessageDirection
308 */
309 void setDirection(MessageDirection direction);
310
311 /**
312 * @brief Accessor method for the importance
313 * @see setImportance
314 * @return The message importance (low/normal/highlight)
315 */
316 MessageImportance importance() const;
317
318 /**
319 * @brief Set the importance.
320 * @see importance and @see MessageImportance
321 * @param importance The message importance to set
322 */
323 void setImportance(MessageImportance importance);
324
325 /**
326 * @brief Accessor method for the state
327 * @return The message state (unknown/sending/sent/error)
328 */
329 MessageState state() const;
330
331 /**
332 * @brief Set the state of message.
333 * @see MessageState
334 * @param state The message state to set
335 */
336 void setState(MessageState state);
337
338 /**
339 * @brief Sets the foreground color for the message
340 * @see foregroundColor
341 * @param color The color
342 */
343 void setForegroundColor( const QColor &color );
344
345 /**
346 * @brief Sets the background color for the message
347 * @see backgroundColor
348 * @param color The color
349 */
350 void setBackgroundColor( const QColor &color );
351
352 /**
353 * @brief Sets the font for the message
354 * @see font
355 * @param font The font
356 */
357 void setFont( const QFont &font );
358
359 /**
360 * @brief Sets the body of the message
361 *
362 * @param body The body, intpreted as plain text
363 */
364 void setPlainBody( const QString &body);
365
366 /**
367 * @brief Sets the body of the message
368 *
369 * @param body The body, interpreted as HTML
370 */
371 void setHtmlBody( const QString &body);
372
373 /**
374 * @brief Sets the body of the message, which is used even if formatting is overridden
375 *
376 * @param body The body, interpreted as HTML
377 */
378 void setForcedHtmlBody( const QString &body);
379
380 /**
381 * @brief Sets the body of the message
382 * The format is changed to RichText automatically
383 * @param body The body
384 */
385 void setBody( const QTextDocument *body);
386
387 /**
388 * @brief Get the message body back as plain text
389 * @return The message body as plain text
390 */
391 QString plainBody() const;
392
393 /**
394 * @brief Get the message body as escaped (X)HTML format.
395 * That means every HTML special char (\>, \<, \&, ...) is escaped to the HTML entity (\&lt;, \&gt;, ...)
396 * and newlines (\\n) are converted to \<br /\>
397 * Just because you set an HTML body doesn't mean you'll get the same string back here, but it will
398 * be equivalent in meaning
399 * @return The message body as escaped text
400 */
401 QString escapedBody() const;
402
403 /**
404 * @brief Get the message body as parsed HTML with Emoticons, and URL parsed
405 * This should be ready to be shown in the chatwindow.
406 * @return The HTML and Emoticon parsed message body
407 */
408 QString parsedBody() const;
409
410 /**
411 * Get the related message manager.
412 * If it is not set, returns 0L.
413 *
414 * The @ref ChatSession is only set if the message is already passed by the manager.
415 * We should trust this only in aboutToSend/aboutToReceive signals
416 */
417 ChatSession *manager() const ;
418
419 /**
420 * @brief Set the messagemanager for this message.
421 * Should be only used by the manager itself. @see manager
422 * @param manager The chat session
423 */
424 void setManager(ChatSession * manager);
425
426 /**
427 * @brief Does nothing
428 */
429 void KDE_DEPRECATED setBackgroundOverride( bool enable );
430
431 /**
432 * @brief Does nothing
433 */
434 void KDE_DEPRECATED setForegroundOverride( bool enable );
435
436 /**
437 * @brief Does nothing
438 */
439 void KDE_DEPRECATED setRichTextOverride( bool enable );
440
441 /**
442 * @brief Ignores peer's formatting
443 */
444 void setFormattingOverride( bool enable );
445
446 /**
447 * @brief Return HTML style attribute for this message.
448 * @return A string formatted like this: "style=attr"
449 */
450 QString getHtmlStyleAttribute() const;
451
452 /**
453 * @brief Set the state of incoming file transfer
454 * @param disabled flag to indicate if the file transfer request should be enabled or disabled.
455 */
456 void setFileTransferDisabled( bool disabled );
457
458 /**
459 * @brief Accessor method for the file transfer state
460 * @return if file transfer request should be enable or disable
461 */
462 bool fileTransferDisabled() const;
463
464 /**
465 * @brief Set file name of incoming file transfer
466 * @param fileName file name
467 */
468 void setFileName( const QString &fileName );
469
470 /**
471 * @brief Accessor method for the file name of incoming file transfer
472 * @return file name of incoming file transfer
473 */
474 QString fileName() const;
475
476 /**
477 * @brief Set file transfer size
478 * @param size file transfer size
479 */
480 void setFileSize( unsigned long size );
481
482 /**
483 * @brief Accessor method for the file transfer size
484 * @return file transfer size
485 */
486 unsigned long fileSize() const;
487
488 /**
489 * @brief Set file preview icon for file transfer
490 * @param preview file preview icon
491 */
492 void setFilePreview( const QPixmap &preview );
493
494 /**
495 * @brief Accessor method for the file preview icon
496 * @return file preview icon
497 */
498 QPixmap filePreview() const;
499
500 /**
501 * @return The list of classes
502 * Class are used to give different notification on a message. They are also used in the chatwindow as an HTML class
503 */
504 QStringList classes() const;
505
506 /**
507 * @brief Add a class
508 * @see classes
509 * @param class class to add
510 */
511 void addClass(const QString& classe);
512
513 /**
514 * @brief Set the classes
515 * @see classes
516 * @param classes The new classes
517 */
518 void setClasses(const QStringList &classes);
519
520public: /* static helpers */
521
522 /**
523 * Unescapes a string, removing XML entity references and returns a plain text.
524 *
525 * Note that this method is *VERY* expensive when called on rich text bodies,
526 * use with care!
527 *
528 */
529 static QString unescape( const QString &xml );
530
531 /**
532 * @brief Transform a plaintext message into HTML.
533 * it escape main entity like &gt; &lt; add some &lt;br /&gt; or &amp;nbsp;
534 */
535 static QString escape( const QString & );
536
537#if 0
538 //candidate for removal!
539 /**
540 * Helper function to decode a string. Whatever returned here is *nearly guaranteed* to
541 * be parseable by the XML engine.
542 *
543 * @param message The string you are trying to decode
544 * @param providedCodec A codec you want to try to decode with
545 * @param success Optional pointer to a bool you want updated on success. "Success"
546 * is defined as a successful decoding using either UTF8 or the codec you
547 * provided. If a guess has to be taken, success will be false.
548 * @return The decoded string
549
550 */
551 static QString decodeString( const QByteArray &message,
552 const QTextCodec *providedCodec = 0L, bool *success = 0L );
553#endif
554
555private:
556 class Private;
557 QSharedDataPointer<Private> d;
558
559 /**
560 * Called internally by @ref setBody() and the constructor
561 * Basically @ref setBody() without detach
562 * @internal
563 */
564 void doSetBody( QString body, Qt::TextFormat format = Qt::PlainText );
565
566 /**
567 * Called internally by @ref setBody() and the constructor
568 * Basically @ref setBody() without detach
569 * @internal
570 */
571 void doSetBody (const QTextDocument *body, Qt::TextFormat format = Qt::PlainText);
572
573 /**
574 * Called internally in rich text handling
575 * @internal
576 */
577 static QString parseLinks( const QString &message, Qt::TextFormat format );
578};
579
580}
581
582#endif
583
584// vim: set noet ts=4 sts=4 sw=4:
585
586