1 | /* |
2 | kmime_content.h |
3 | |
4 | KMime, the KDE Internet mail/usenet news message library. |
5 | Copyright (c) 2001 the KMime authors. |
6 | See file AUTHORS for details |
7 | Copyright (c) 2006 Volker Krause <vkrause@kde.org> |
8 | Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com> |
9 | |
10 | This library is free software; you can redistribute it and/or |
11 | modify it under the terms of the GNU Library General Public |
12 | License as published by the Free Software Foundation; either |
13 | version 2 of the License, or (at your option) any later version. |
14 | |
15 | This library is distributed in the hope that it will be useful, |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | Library General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Library General Public License |
21 | along with this library; see the file COPYING.LIB. If not, write to |
22 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
23 | Boston, MA 02110-1301, USA. |
24 | */ |
25 | /** |
26 | @file |
27 | This file is part of the API for handling @ref MIME data and |
28 | defines the Content class. |
29 | |
30 | @brief |
31 | Defines the Content class. |
32 | |
33 | @authors the KMime authors (see AUTHORS file), |
34 | Volker Krause \<vkrause@kde.org\> |
35 | |
36 | TODO: possible glossary terms: |
37 | content |
38 | encoding, transfer type, disposition, description |
39 | header |
40 | body |
41 | attachment |
42 | charset |
43 | article |
44 | string representation |
45 | broken-down object representation |
46 | */ |
47 | |
48 | #ifndef __KMIME_CONTENT_H__ |
49 | #define __KMIME_CONTENT_H__ |
50 | |
51 | #include "kmime_export.h" |
52 | #include "kmime_contentindex.h" |
53 | #include "kmime_util.h" |
54 | #include "kmime_headers.h" |
55 | |
56 | #include <QtCore/QTextStream> |
57 | #include <QtCore/QByteArray> |
58 | #include <QtCore/QList> |
59 | |
60 | #include <boost/shared_ptr.hpp> |
61 | |
62 | |
63 | namespace KMime { |
64 | |
65 | class ContentPrivate; |
66 | class Message; |
67 | |
68 | /** |
69 | @brief |
70 | A class that encapsulates @ref MIME encoded Content. |
71 | |
72 | A Content object holds two representations of a content: |
73 | - the string representation: This is the content encoded as a string ready |
74 | for transport. Accessible through the encodedContent() method. |
75 | - the broken-down representation: This is the tree of objects (headers, |
76 | sub-Contents and (if present) the encapsulated message) that this Content is made of. |
77 | Accessible through methods like header(), contents() and bodyAsMessage(). |
78 | |
79 | The parse() function updates the broken-down representation of the Content |
80 | from its string representation. Calling it is necessary to access the |
81 | headers, sub-Contents or the encapsulated message of this Content. |
82 | |
83 | The assemble() function updates the string representation of the Content |
84 | from its broken-down representation. Calling it is necessary for |
85 | encodedContent() to reflect any changes made to the broken-down representation of the Content. |
86 | |
87 | There are two basic types of a Content: |
88 | - A leaf Content: This is a content that is neither a multipart content nor an encapsulated |
89 | message. Because of this, it will not have any children, it has no sub-contents |
90 | and is therefore a leaf content. |
91 | Only leaf contents have a body that is not empty, i.e. functions that operate |
92 | on the body, such as body(), size() and decodedContent(), will work only on |
93 | leaf contents. |
94 | - A non-leaf Content: This is a content that itself doesn't have any body, but that does have |
95 | sub-contents. |
96 | This is the case for contents that are of mimetype multipart/ or of mimetype |
97 | message/rfc822. In case of a multipart content, contents() will return the |
98 | multipart child contents. In case of an encapsulated message, the message |
99 | can be accessed with bodyAsMessage(), and contents() will have one entry |
100 | that is the message as well. |
101 | On a non-leaf content, body() will have an empty return value and other |
102 | functions working on the body will not work. |
103 | A call to parse() is required before the child multipart contents or the |
104 | encapsulated message is created. |
105 | */ |
106 | /* |
107 | KDE5: |
108 | * Do not convert singlepart <-> multipart automatically. |
109 | * A bunch of methods probably don't need to be virtual (since they're not needed |
110 | in either Message or NewsArticle). |
111 | */ |
112 | class KMIME_EXPORT Content |
113 | { |
114 | public: |
115 | |
116 | /** |
117 | Describes a list of Content objects. |
118 | */ |
119 | typedef QList<KMime::Content*> List; |
120 | |
121 | /** |
122 | Creates an empty Content object. |
123 | */ |
124 | Content(); |
125 | |
126 | /** |
127 | Creates an empty Content object with a specified parent. |
128 | @param parent the parent Content object |
129 | @since 4.3 |
130 | */ |
131 | explicit Content( Content* parent ); // KDE5: Merge with the above. |
132 | |
133 | /** |
134 | Creates a Content object containing the given raw data. |
135 | |
136 | @param head is a QByteArray containing the header data. |
137 | @param body is a QByteArray containing the body data. |
138 | */ |
139 | Content( const QByteArray &head, const QByteArray &body ); |
140 | |
141 | /** |
142 | Creates a Content object containing the given raw data. |
143 | |
144 | @param head is a QByteArray containing the header data. |
145 | @param body is a QByteArray containing the body data. |
146 | @param parent the parent Content object |
147 | @since 4.3 |
148 | */ |
149 | // KDE5: Merge with the above. |
150 | Content( const QByteArray &head, const QByteArray &body, Content *parent ); |
151 | |
152 | /** |
153 | Destroys this Content object. |
154 | */ |
155 | virtual ~Content(); |
156 | |
157 | /** |
158 | Returns true if this Content object is not empty. |
159 | */ |
160 | bool hasContent() const; |
161 | |
162 | /** |
163 | Sets the Content to the given raw data, containing the Content head and |
164 | body separated by two linefeeds. |
165 | |
166 | This method operates on the string representation of the Content. Call |
167 | parse() if you want to access individual headers, sub-Contents or the |
168 | encapsulated message. |
169 | |
170 | @param l is a list of the raw Content data, split by lines. |
171 | */ |
172 | void setContent( const QList<QByteArray> &l ); |
173 | |
174 | /** |
175 | Sets the Content to the given raw data, containing the Content head and |
176 | body separated by two linefeeds. |
177 | |
178 | This method operates on the string representation of the Content. Call |
179 | parse() if you want to access individual headers, sub-Contents or the |
180 | encapsulated message. |
181 | |
182 | @note The passed data must not contain any CRLF sequences, only LF. |
183 | Use CRLFtoLF for conversion before passing in the data. |
184 | |
185 | @param s is a QByteArray containing the raw Content data. |
186 | */ |
187 | void setContent( const QByteArray &s ); |
188 | |
189 | /** |
190 | * Parses the Content. |
191 | * |
192 | * This means the broken-down object representation of the Content is |
193 | * updated from the string representation of the Content. |
194 | * |
195 | * Call this if you want to access or change headers, sub-Contents or the encapsulated |
196 | * message. |
197 | * |
198 | * @note Calling parse() twice will not work for multipart contents or for contents of which |
199 | * the body is an encapsulated message. The reason is that the first parse() will delete |
200 | * the body, so there is no body to work on for the second call of parse(). |
201 | * |
202 | * @note Calling this will reset the message returned by bodyAsMessage(), as |
203 | * the message is re-parsed as well. |
204 | * Also, all old sub-contents will be deleted, so any old Content pointer will become |
205 | * invalid. |
206 | */ |
207 | virtual void parse(); |
208 | |
209 | /** |
210 | Returns whether this Content is frozen. |
211 | A frozen content is immutable, i.e. calling assemble() will never modify |
212 | its head or body, and encodedContent() will return the same data before |
213 | and after parsing. |
214 | |
215 | @since 4.4. |
216 | @see setFrozen(). |
217 | */ |
218 | bool isFrozen() const; |
219 | |
220 | /** |
221 | Freezes this Content if @p frozen is true; otherwise unfreezes it. |
222 | @param frozen freeze content if @c true, otherwise unfreeze |
223 | @since 4.4 |
224 | @see isFrozen(). |
225 | */ |
226 | void setFrozen( bool frozen = true ); |
227 | |
228 | /** |
229 | Generates the MIME content. |
230 | This means the string representation of this Content is updated from the |
231 | broken-down object representation. |
232 | Call this if you have made changes to the content, and want |
233 | encodedContent() to reflect those changes. |
234 | |
235 | @note assemble() has no effect if the Content isFrozen(). You may want |
236 | to freeze, for instance, signed sub-Contents, to make sure they are kept |
237 | unmodified. |
238 | |
239 | @note If this content is an encapsulated message, i.e. bodyIsMessage() returns true, |
240 | then calling assemble() will also assemble the message returned by bodyAsMessage(). |
241 | |
242 | @warning assemble() may change the order of the headers, and other |
243 | details such as where folding occurs. This may break things like |
244 | signature verification, so you should *ONLY* call assemble() when you |
245 | have actually modified the content. |
246 | */ |
247 | virtual void assemble(); |
248 | |
249 | /** |
250 | Clears the content, deleting all headers and sub-Contents. |
251 | */ |
252 | // KDE5: make non-virtual. |
253 | virtual void clear(); |
254 | |
255 | /** |
256 | Removes all sub-Contents from this content. Deletes them if @p del is true. |
257 | This is different from calling removeContent() on each sub-Content, because |
258 | removeContent() will convert this to a single-part Content if only one |
259 | sub-Content is left. Calling clearContents() does NOT make this Content |
260 | single-part. |
261 | |
262 | @param del Whether to delete the sub-Contents. |
263 | @see removeContent() |
264 | @since 4.4 |
265 | */ |
266 | void clearContents( bool del = true ); |
267 | |
268 | /** |
269 | Returns the Content header raw data. |
270 | |
271 | @see setHead(). |
272 | */ |
273 | QByteArray head() const; |
274 | |
275 | /** |
276 | Sets the Content header raw data. |
277 | |
278 | This method operates on the string representation of the Content. Call |
279 | parse() if you want to access individual headers. |
280 | |
281 | @param head is a QByteArray containing the header data. |
282 | |
283 | @see head(). |
284 | */ |
285 | void ( const QByteArray &head ); |
286 | |
287 | /** |
288 | Extracts and removes the next header from @p head. |
289 | The caller is responsible for deleting the returned header. |
290 | |
291 | @deprecated Use KMime::HeaderParsing::extractFirstHeader(). |
292 | @param head is a QByteArray containing the header data. |
293 | */ |
294 | KMIME_DEPRECATED Headers::Generic *( QByteArray &head ); |
295 | |
296 | /** |
297 | Extracts and removes the next header from @p head. |
298 | The caller is responsible for deleting the returned header. |
299 | @since 4.2 |
300 | @deprecated Use KMime::HeaderParsing::extractFirstHeader(). |
301 | @param head is a QByteArray containing the header data. |
302 | */ |
303 | // KDE5: Remove this. This method has nothing to do with *this object. |
304 | KMIME_DEPRECATED Headers::Generic *( QByteArray &head ); |
305 | |
306 | /** |
307 | Tries to find a @p type header in the Content and returns it. |
308 | @param type the header type to find |
309 | @deprecated Use headerByType( const char * ) |
310 | */ |
311 | // KDE5: Make non-virtual. |
312 | KMIME_DEPRECATED virtual Headers::Base *( const char *type ); |
313 | |
314 | /** |
315 | Returns the first header of type @p type, if it exists. Otherwise returns 0. |
316 | Note that the returned header may be empty. |
317 | @param type the header type to find |
318 | @since 4.2 |
319 | */ |
320 | // KDE5: Make non-virtual. |
321 | virtual Headers::Base *( const char *type ); |
322 | |
323 | /** |
324 | Returns the first header of type T, if it exists. |
325 | If the header does not exist and @p create is true, creates an empty header |
326 | and returns it. Otherwise returns 0. |
327 | Note that the returned header may be empty. |
328 | @param create Whether to create the header if it does not exist. |
329 | @since 4.4. |
330 | |
331 | KDE5: BIC: FIXME: Why is the default argument false here? That is inconsistent with the |
332 | methods in KMime::Message! |
333 | */ |
334 | template <typename T> T *header( bool create = false ); |
335 | |
336 | /** |
337 | Returns all @p type headers in the Content. |
338 | Take care that this result is not cached, so could be slow. |
339 | @param type the header type to find |
340 | @since 4.2 |
341 | */ |
342 | virtual QList<Headers::Base*> ( const char *type ); |
343 | |
344 | /** |
345 | Sets the specified header to this Content. |
346 | Any previous header of the same type is removed. |
347 | If you need multiple headers of the same type, use appendHeader() or |
348 | prependHeader(). |
349 | |
350 | @param h The header to set. |
351 | @see appendHeader() |
352 | @see removeHeader() |
353 | @since 4.4 |
354 | */ |
355 | // KDE5: make non-virtual. |
356 | virtual void ( Headers::Base *h ); |
357 | |
358 | /** |
359 | Appends the specified header to the headers of this Content. |
360 | @param h The header to append. |
361 | @since 4.4 |
362 | */ |
363 | void ( Headers::Base *h ); |
364 | |
365 | /** |
366 | Prepends the specified header to the headers of this Content. |
367 | @param h The header to prepend. |
368 | @since 4.4 |
369 | */ |
370 | void ( Headers::Base *h ); |
371 | |
372 | /** |
373 | Searches for the first header of type @p type, and deletes it, removing |
374 | it from this Content. |
375 | @param type The type of the header to look for. |
376 | @return true if a header was found and removed. |
377 | */ |
378 | // TODO probably provide removeHeader<T>() too. |
379 | // KDE5: make non-virtual. |
380 | virtual bool ( const char *type ); |
381 | |
382 | /** |
383 | @return true if this Content has a header of type @p type. |
384 | @param type The type of the header to look for. |
385 | */ |
386 | // TODO probably provide hasHeader<T>() too. |
387 | // TODO: KDE5: make const |
388 | bool ( const char *type ); |
389 | |
390 | /** |
391 | Returns the Content-Type header. |
392 | |
393 | @param create If true, create the header if it doesn't exist yet. |
394 | */ |
395 | Headers::ContentType *contentType( bool create = true ); |
396 | |
397 | /** |
398 | Returns the Content-Transfer-Encoding header. |
399 | |
400 | @param create If true, create the header if it doesn't exist yet. |
401 | */ |
402 | Headers::ContentTransferEncoding *contentTransferEncoding( bool create = true ); |
403 | |
404 | /** |
405 | Returns the Content-Disposition header. |
406 | |
407 | @param create If true, create the header if it doesn't exist yet. |
408 | */ |
409 | Headers::ContentDisposition *contentDisposition( bool create = true ); |
410 | |
411 | /** |
412 | Returns the Content-Description header. |
413 | |
414 | @param create If true, create the header if it doesn't exist yet. |
415 | */ |
416 | Headers::ContentDescription *contentDescription( bool create = true ); |
417 | |
418 | /** |
419 | Returns the Content-Location header. |
420 | |
421 | @param create If true, create the header if it doesn't exist yet. |
422 | @since 4.2 |
423 | */ |
424 | Headers::ContentLocation *contentLocation( bool create = true ); |
425 | |
426 | /** |
427 | Returns the Content-ID header. |
428 | @param create if true, create the header if it does not exist yet. |
429 | @since 4.4 |
430 | */ |
431 | Headers::ContentID *contentID( bool create = true ); |
432 | |
433 | /** |
434 | Returns the size of the Content body after encoding. |
435 | (If the encoding is quoted-printable, this is only an approximate size.) |
436 | This will return 0 for multipart contents or for encapsulated messages. |
437 | */ |
438 | int size(); |
439 | |
440 | /** |
441 | Returns the size of this Content and all sub-Contents. |
442 | */ |
443 | int storageSize() const; |
444 | |
445 | /** |
446 | Line count of this Content and all sub-Contents. |
447 | */ |
448 | int lineCount() const; |
449 | |
450 | /** |
451 | Returns the Content body raw data. |
452 | |
453 | Note that this will be empty for multipart contents or for encapsulated messages, |
454 | after parse() has been called. |
455 | |
456 | @see setBody(). |
457 | */ |
458 | QByteArray body() const; |
459 | |
460 | /** |
461 | Sets the Content body raw data. |
462 | |
463 | This method operates on the string representation of the Content. Call |
464 | parse() if you want to access individual sub-Contents or the encapsulated message. |
465 | |
466 | @param body is a QByteArray containing the body data. |
467 | |
468 | @see body(). |
469 | */ |
470 | void setBody( const QByteArray &body ); |
471 | |
472 | /** |
473 | Returns the MIME preamble. |
474 | |
475 | @return a QByteArray containing the MIME preamble. |
476 | |
477 | @since 4.9 |
478 | */ |
479 | QByteArray preamble() const; |
480 | |
481 | /** |
482 | Sets the MIME preamble. |
483 | |
484 | @param preamble a QByteArray containing what will be used as the |
485 | MIME preamble. |
486 | |
487 | @since 4.9 |
488 | */ |
489 | |
490 | void setPreamble( const QByteArray &preamble ); |
491 | |
492 | /** |
493 | Returns the MIME preamble. |
494 | |
495 | @return a QByteArray containing the MIME epilogue. |
496 | |
497 | @since 4.9 |
498 | */ |
499 | QByteArray epilogue() const; |
500 | |
501 | /** |
502 | Sets the MIME preamble. |
503 | |
504 | @param epilogue a QByteArray containing what will be used as the |
505 | MIME epilogue. |
506 | |
507 | @since 4.9 |
508 | */ |
509 | void setEpilogue( const QByteArray &epilogue ); |
510 | |
511 | /** |
512 | Returns a QByteArray containing the encoded Content, including the |
513 | Content header and all sub-Contents. |
514 | |
515 | If you make changes to the broken-down representation of the message, be |
516 | sure to first call assemble() before calling encodedContent(), otherwise |
517 | the result will not be up-to-date. |
518 | |
519 | If this content is an encapsulated message, i.e. bodyIsMessage() returns true, |
520 | then encodedContent() will use the message returned by bodyAsMessage() as the |
521 | body of the result, calling encodedContent() on the message. |
522 | |
523 | @param useCrLf If true, use @ref CRLF instead of @ref LF for linefeeds. |
524 | */ |
525 | QByteArray encodedContent( bool useCrLf = false ); |
526 | |
527 | /** |
528 | * Like encodedContent(), with the difference that only the body will be returned, i.e. the |
529 | * headers are excluded. |
530 | * |
531 | * @since 4.6 |
532 | */ |
533 | QByteArray encodedBody(); |
534 | |
535 | /** |
536 | * Returns the decoded Content body. |
537 | * |
538 | * Note that this will be empty for multipart contents or for encapsulated messages, |
539 | * after parse() has been called. |
540 | */ |
541 | // TODO: KDE5: BIC: Rename this to decodedBody(), since only the body is returned. |
542 | // In contrast, setContent() sets the head and the body! |
543 | // Also, try to make this const. |
544 | QByteArray decodedContent(); |
545 | |
546 | /** |
547 | Returns the decoded text. Additional to decodedContent(), this also |
548 | applies charset decoding. If this is not a text Content, decodedText() |
549 | returns an empty QString. |
550 | |
551 | @param trimText If true, then the decoded text will have all trailing |
552 | whitespace removed. |
553 | @param removeTrailingNewlines If true, then the decoded text will have |
554 | all consecutive trailing newlines removed. |
555 | |
556 | The last trailing new line of the decoded text is always removed. |
557 | |
558 | */ |
559 | // TODO: KDE5: BIC: Convert to enums. Also, what if trimText = true but removeTrailingNewlines |
560 | // is false? |
561 | QString decodedText( bool trimText = false, |
562 | bool removeTrailingNewlines = false ); |
563 | |
564 | /** |
565 | Sets the Content body to the given string using charset of the content type. |
566 | |
567 | If the charset can not be found, the system charset is taken and the content type header is |
568 | changed to that charset. |
569 | The charset of the content type header should be set to a charset that can encode the given |
570 | string before calling this method. |
571 | |
572 | This method does not set the content transfer encoding automatically, it needs to be set |
573 | to a suitable value that can encode the given string before calling this method. |
574 | |
575 | This method only makes sense for single-part contents, do not try to pass a multipart body |
576 | or an encapsulated message here, that wouldn't work. |
577 | |
578 | @param s Unicode-encoded string. |
579 | */ |
580 | void fromUnicodeString( const QString &s ); |
581 | |
582 | /** |
583 | Returns the first Content with mimetype text/. |
584 | */ |
585 | Content *textContent(); |
586 | |
587 | /** |
588 | Returns a list of attachments. |
589 | |
590 | @param incAlternatives If true, include multipart/alternative parts. |
591 | */ |
592 | List attachments( bool incAlternatives = false ); |
593 | |
594 | /** |
595 | * For multipart contents, this will return a list of all multipart child contents. |
596 | * For contents that are of mimetype message/rfc822, this will return a list with one entry, |
597 | * and that entry is the encapsulated message, as it would be returned by bodyAsMessage(). |
598 | */ |
599 | List contents() const; |
600 | |
601 | /** |
602 | Adds a new sub-Content. If the sub-Content is already part of another |
603 | Content object, it is removed from there and its parent is updated. |
604 | If the current Content object is single-part, it is converted to |
605 | multipart/mixed first. |
606 | |
607 | @warning If the single-part to multipart conversion happens, all |
608 | pointers you may have into this object (such as headers) will become |
609 | invalid! |
610 | |
611 | @param content The new sub-Content. |
612 | @param prepend If true, prepend to the Content list; otherwise append. |
613 | to the Content list. |
614 | |
615 | @see removeContent(). |
616 | */ |
617 | // KDE5: Do not convert single-part->multipart automatically. |
618 | void addContent( Content *content, bool prepend = false ); |
619 | |
620 | /** |
621 | Removes the given sub-Content. If only one sub-Content is left, the |
622 | current Content object is converted into a single-part Content. |
623 | |
624 | @warning If the multipart to single-part conversion happens, the head |
625 | and body of the single remaining sub-Content are copied over, and the |
626 | sub-Content is deleted. All pointers to it or into it (such as headers) |
627 | will become invalid! |
628 | |
629 | @param content The Content to remove. |
630 | @param del If true, delete the removed Content object. Otherwise set its |
631 | parent to 0. |
632 | |
633 | @see addContent(). |
634 | @see clearContents(). |
635 | */ |
636 | // KDE5: Do not convert multipart->single-part automatically. |
637 | void removeContent( Content *content, bool del = false ); |
638 | |
639 | /** |
640 | Changes the encoding of this Content to @p e. If the Content is binary, |
641 | this actually re-encodes the data to use the new encoding. |
642 | |
643 | @param e The new encoding to use. |
644 | */ |
645 | void ( Headers::contentEncoding e ); |
646 | |
647 | /** |
648 | Saves the encoded Content to the given textstream |
649 | |
650 | @param ts is the stream where the Content should be written to. |
651 | @param scrambleFromLines: If true, replace "\nFrom " with "\n>From " |
652 | in the stream. This is needed to avoid problem with mbox-files |
653 | */ |
654 | void toStream( QTextStream &ts, bool scrambleFromLines = false ); |
655 | |
656 | // NOTE: The charset methods below are accessed by the headers which |
657 | // have this Content as a parent. |
658 | |
659 | /** |
660 | Returns the charset that is used to decode RFC2047 strings in all headers and to decode |
661 | the body if the charset is not declared explictly. |
662 | It is also used as the charset when encoding RFC2047 strings in headers. |
663 | |
664 | @see setDefaultCharset() |
665 | */ |
666 | // TODO: Split this up into a charset for encoding and one for decoding, and make the one for |
667 | // encoding UTF-8 by default. |
668 | QByteArray defaultCharset() const; |
669 | |
670 | /** |
671 | Sets the default charset. |
672 | |
673 | @param cs is a QByteArray containing the new default charset. |
674 | |
675 | @see defaultCharset(). |
676 | */ |
677 | void setDefaultCharset( const QByteArray &cs ); |
678 | |
679 | /** |
680 | Use the default charset even if a different charset is |
681 | declared in the article. |
682 | |
683 | @see setForceDefaultCharset(). |
684 | */ |
685 | bool forceDefaultCharset() const; |
686 | |
687 | /** |
688 | Enables/disables the force mode, housekeeping. |
689 | works correctly only when the article is completely empty or |
690 | completely loaded. |
691 | |
692 | @param b If true, force the default charset to be used. |
693 | |
694 | @see forceDefaultCharset(). |
695 | */ |
696 | virtual void setForceDefaultCharset( bool b ); |
697 | |
698 | /** |
699 | Returns the Content specified by the given index. |
700 | If the index does not point to a Content, 0 is returned. If the index |
701 | is invalid (empty), this Content is returned. |
702 | |
703 | @param index The Content index. |
704 | */ |
705 | Content *content( const ContentIndex &index ) const; |
706 | |
707 | /** |
708 | Returns the ContentIndex for the given Content, or an invalid index |
709 | if the Content is not found within the hierarchy. |
710 | @param content the Content object to search. |
711 | */ |
712 | ContentIndex indexForContent( Content *content ) const; |
713 | |
714 | /** |
715 | Returns true if this is the top-level node in the MIME tree. The top-level node is always |
716 | a Message or NewsArticle. However, a node can be a Message without being a top-level node when |
717 | it is an encapsulated message. |
718 | */ |
719 | virtual bool isTopLevel() const; |
720 | |
721 | /** |
722 | * Sets a new parent to the Content and add to its contents list. If it already had a parent, it is removed from the |
723 | * old parents contents list. |
724 | * @param parent the new parent |
725 | * @since 4.3 |
726 | */ |
727 | void setParent( Content *parent ); |
728 | |
729 | /** |
730 | * Returns the parent content object, or 0 if the content doesn't have a parent. |
731 | * @since 4.3 |
732 | */ |
733 | Content* parent() const; |
734 | |
735 | /** |
736 | * Returns the toplevel content object, 0 if there is no such object. |
737 | * @since 4.3 |
738 | */ |
739 | Content* topLevel() const; |
740 | |
741 | /** |
742 | * Returns the index of this Content based on the topLevel() object. |
743 | * @since 4.3 |
744 | */ |
745 | ContentIndex index() const; |
746 | |
747 | /** |
748 | * @return true if this content is an encapsulated message, i.e. if it has the mimetype |
749 | * message/rfc822. |
750 | * |
751 | * @since 4.5 |
752 | */ |
753 | //AK_REVIEW: move to MessageViewer/ObjectTreeParser |
754 | bool bodyIsMessage() const; |
755 | |
756 | /** |
757 | * If this content is an encapsulated message, in which case bodyIsMessage() will return |
758 | * true, the message represented by the body of this content will be returned. |
759 | * The returned message is already fully parsed. |
760 | * Calling this method is the aquivalent of calling contents().first() and casting the result |
761 | * to a KMime::Message*. bodyAsMessage() has the advantage that it will return a shared pointer |
762 | * that will not be destroyed when the container message is destroyed or re-parsed. |
763 | * |
764 | * The message that is returned here is created when calling parse(), so make sure to call |
765 | * parse() first. Since each parse() creates a new message object, a different message object |
766 | * will be returned each time you call parse(). |
767 | * |
768 | * If you make changes to the returned message, you need to call assemble() on this content |
769 | * or on the message if you want that encodedContent() reflects these changes. This also means |
770 | * that calling assemble() on this content will assemble the returned message. |
771 | * |
772 | * @since 4.5 |
773 | */ |
774 | //AK_REVIEW: move to MessageViewer/ObjectTreeParser |
775 | boost::shared_ptr<Message> bodyAsMessage() const; |
776 | |
777 | protected: |
778 | /** |
779 | Reimplement this method if you need to assemble additional headers in a |
780 | derived class. Don't forget to call the implementation of the base class. |
781 | @return The raw, assembled headers. |
782 | */ |
783 | virtual QByteArray (); |
784 | |
785 | /** |
786 | Returns the raw string representing the header of type @p name. |
787 | @param name the header type to find |
788 | @deprecated Use KMime::extractHeader() directly instead. |
789 | */ |
790 | KMIME_DEPRECATED QByteArray ( const char *name ) const; |
791 | |
792 | /** |
793 | Returns a list of raw strings representing all header of type @p name. |
794 | @deprecated Use KMime::extractHeaders() directly instead. |
795 | */ |
796 | KMIME_DEPRECATED QList<QByteArray> ( const char *name ) const; |
797 | |
798 | /** |
799 | Returns whether this object holds text content. |
800 | */ |
801 | // KDE5: Not needed outside. Move to Private class. |
802 | bool decodeText(); |
803 | |
804 | /** |
805 | Returns the first header of type T, if it exists. |
806 | @deprecated Use header() instead. |
807 | */ |
808 | template <class T> KMIME_DEPRECATED T *headerInstance( T *ptr, bool create ); |
809 | |
810 | /** |
811 | The list of headers in this Content. |
812 | Do not use this directly. |
813 | */ |
814 | // KDE5: Not needed outside. Move to Private class. |
815 | Headers::Base::List h_eaders; |
816 | |
817 | //@cond PRIVATE |
818 | ContentPrivate *d_ptr; |
819 | explicit Content( ContentPrivate *d ); |
820 | //@endcond |
821 | |
822 | private: |
823 | Q_DECLARE_PRIVATE( Content ) |
824 | Q_DISABLE_COPY( Content ) |
825 | }; |
826 | |
827 | // some compilers (for instance Compaq C++) need template inline functions |
828 | // here rather than in the *.cpp file |
829 | |
830 | template <class T> T *Content::( T */*ptr*/, bool create ) |
831 | { |
832 | return header<T>( create ); |
833 | } |
834 | |
835 | template <typename T> T *Content::( bool create ) |
836 | { |
837 | Headers::Base *h = headerByType( T::staticType() ); |
838 | if ( h ) { |
839 | // Make sure the header is actually of the right type. |
840 | Q_ASSERT( dynamic_cast<T*>( h ) ); |
841 | } else if ( create ) { |
842 | h = new T( this ); |
843 | setHeader( h ); |
844 | } |
845 | return static_cast<T*>( h ); |
846 | } |
847 | |
848 | } // namespace KMime |
849 | |
850 | #endif // __KMIME_CONTENT_H__ |
851 | |