Messagelib

mimetreeparser/src/nodehelper.h
1 /*
2  SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected]
3  SPDX-FileCopyrightText: 2009 Andras Mantia <[email protected]>
4 
5  SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #pragma once
9 
10 #include "mimetreeparser_export.h"
11 
12 #include "mimetreeparser/enums.h"
13 #include "mimetreeparser/partmetadata.h"
14 
15 #include <KMime/Headers>
16 #include <KMime/Message>
17 
18 #include <QList>
19 #include <QMap>
20 #include <QPointer>
21 #include <QSet>
22 #include <QVector>
23 
24 class QUrl;
25 class QTextCodec;
26 
27 namespace MimeTreeParser
28 {
29 class AttachmentTemporaryFilesDirs;
30 class MessagePart;
31 typedef QSharedPointer<MessagePart> MessagePartPtr;
32 namespace Interface
33 {
34 class BodyPartMemento;
35 }
36 }
37 
38 namespace MimeTreeParser
39 {
40 /**
41  * @author Andras Mantia <[email protected]>
42  */
43 class MIMETREEPARSER_EXPORT NodeHelper : public QObject
44 {
45  Q_OBJECT
46 public:
47  NodeHelper();
48 
49  ~NodeHelper() override;
50 
51  void setNodeProcessed(KMime::Content *node, bool recurse);
52  void setNodeUnprocessed(KMime::Content *node, bool recurse);
53  Q_REQUIRED_RESULT bool nodeProcessed(KMime::Content *node) const;
54  void clear();
55  void forceCleanTempFiles();
56 
57  void setEncryptionState(const KMime::Content *node, const KMMsgEncryptionState state);
58  Q_REQUIRED_RESULT KMMsgEncryptionState encryptionState(const KMime::Content *node) const;
59 
60  void setSignatureState(const KMime::Content *node, const KMMsgSignatureState state);
61  Q_REQUIRED_RESULT KMMsgSignatureState signatureState(const KMime::Content *node) const;
62 
63  Q_REQUIRED_RESULT KMMsgSignatureState overallSignatureState(KMime::Content *node) const;
64  Q_REQUIRED_RESULT KMMsgEncryptionState overallEncryptionState(KMime::Content *node) const;
65 
66  void setPartMetaData(KMime::Content *node, const PartMetaData &metaData);
67  Q_REQUIRED_RESULT PartMetaData partMetaData(KMime::Content *node);
68 
69  /**
70  * Set the 'Content-Type' by mime-magic from the contents of the body.
71  * If autoDecode is true the decoded body will be used for mime type
72  * determination (this does not change the body itself).
73  */
74  static void magicSetType(KMime::Content *node, bool autoDecode = true);
75 
76  void clearOverrideHeaders();
77  void registerOverrideHeader(KMime::Content *message, MessagePartPtr);
78  Q_REQUIRED_RESULT bool hasMailHeader(const char *header, const KMime::Content *message) const;
79  QVector<MessagePartPtr> messagePartsOfMailHeader(const char *header, const KMime::Content *message) const;
80  KMime::Headers::Base const *mailHeaderAsBase(const char *header, const KMime::Content *message) const;
81  QSharedPointer<KMime::Headers::Generics::AddressList> mailHeaderAsAddressList(const char *header, const KMime::Content *message) const;
82  QVector<KMime::Headers::Base *> headers(const char *header, const KMime::Content *message);
83  Q_REQUIRED_RESULT QDateTime dateHeader(KMime::Content *message) const;
84 
85  /** Attach an extra node to an existing node */
86  void attachExtraContent(KMime::Content *topLevelNode, KMime::Content *content);
87 
88  void cleanExtraContent(KMime::Content *topLevelNode);
89 
90  /** Get the extra nodes attached to the @param topLevelNode and all sub-nodes of @param topLevelNode */
91  Q_REQUIRED_RESULT QVector<KMime::Content *> extraContents(KMime::Content *topLevelNode) const;
92 
93  /** Return a modified message (node tree) starting from @param topLevelNode that has the original nodes and the extra nodes.
94  The caller has the responsibility to delete the new message.
95  */
96  Q_REQUIRED_RESULT KMime::Message *messageWithExtraContent(KMime::Content *topLevelNode);
97 
98  /** Get a QTextCodec suitable for this message part */
99  const QTextCodec *codec(KMime::Content *node);
100 
101  /** Set the charset the user selected for the message to display */
102  void setOverrideCodec(KMime::Content *node, const QTextCodec *codec);
103 
104  Interface::BodyPartMemento *bodyPartMemento(KMime::Content *node, const QByteArray &which) const;
105 
106  void setBodyPartMemento(KMime::Content *node, const QByteArray &which, Interface::BodyPartMemento *memento);
107 
108  // A flag to remember if the node was embedded. This is useful for attachment nodes, the reader
109  // needs to know if they were displayed inline or not.
110  Q_REQUIRED_RESULT bool isNodeDisplayedEmbedded(KMime::Content *node) const;
111  void setNodeDisplayedEmbedded(KMime::Content *node, bool displayedEmbedded);
112 
113  // Same as above, but this time determines if the node was hidden or not
114  Q_REQUIRED_RESULT bool isNodeDisplayedHidden(KMime::Content *node) const;
115  void setNodeDisplayedHidden(KMime::Content *node, bool displayedHidden);
116 
117  /**
118  * Writes the given message part to a temporary file and returns the
119  * name of this file or QString() if writing failed.
120  */
121  QString writeNodeToTempFile(KMime::Content *node);
122 
123  Q_REQUIRED_RESULT QString writeFileToTempFile(KMime::Content *node, const QString &filename);
124 
125  /**
126  * Returns the temporary file path and name where this node was saved, or an empty url
127  * if it wasn't saved yet with writeNodeToTempFile()
128  */
129  Q_REQUIRED_RESULT QUrl tempFileUrlFromNode(const KMime::Content *node);
130 
131  /**
132  * Creates a temporary dir for saving attachments, etc.
133  * Will be automatically deleted when another message is viewed.
134  * @param param Optional part of the directory name.
135  */
136  Q_REQUIRED_RESULT QString createTempDir(const QString &param = QString());
137 
138  /**
139  * Cleanup the attachment temp files
140  */
141  void removeTempFiles();
142 
143  /**
144  * Add a file to the list of managed temporary files
145  */
146  void addTempFile(const QString &file);
147 
148  // Get a href in the form attachment:<nodeId>?place=<place>, used by ObjectTreeParser and
149  // UrlHandlerManager.
150  Q_REQUIRED_RESULT QString asHREF(const KMime::Content *node, const QString &place) const;
151  KMime::Content *fromHREF(const KMime::Message::Ptr &mMessage, const QUrl &href) const;
152 
153  /**
154  * @return true if this node is a child or an encapsulated message
155  */
156  Q_REQUIRED_RESULT static bool isInEncapsulatedMessage(KMime::Content *node);
157 
158  /**
159  * Returns the charset for the given node. If no charset is specified
160  * for the node, the defaultCharset() is returned.
161  */
162  Q_REQUIRED_RESULT static QByteArray charset(KMime::Content *node);
163 
164  /**
165  * Return a QTextCodec for the specified charset.
166  * This function is a bit more tolerant, than QTextCodec::codecForName
167  */
168  static const QTextCodec *codecForName(const QByteArray &_str);
169 
170  /**
171  * Returns a usable filename for a node, that can be the filename from the
172  * content disposition header, or if that one is empty, the name from the
173  * content type header.
174  */
175  Q_REQUIRED_RESULT static QString fileName(const KMime::Content *node);
176 
177  /**
178  * Fixes an encoding received by a KDE function and returns the proper,
179  * MIME-compliant encoding name instead.
180  * @see encodingForName
181  */
182  Q_REQUIRED_RESULT static QString fixEncoding(const QString &encoding); // TODO(Andras) move to a utility class?
183 
184  /**
185  * Drop-in replacement for KCharsets::encodingForName(). The problem with
186  * the KCharsets function is that it returns "human-readable" encoding names
187  * like "ISO 8859-15" instead of valid encoding names like "ISO-8859-15".
188  * This function fixes this by replacing whitespace with a hyphen.
189  */
190  Q_REQUIRED_RESULT static QString encodingForName(const QString &descriptiveName); // TODO(Andras) move to a utility class?
191 
192  /**
193  * Return a list of the supported encodings
194  * @param usAscii if true, US-Ascii encoding will be prepended to the list.
195  */
196  static Q_REQUIRED_RESULT QStringList supportedEncodings(bool usAscii); // TODO(Andras) move to a utility class?
197 
198  Q_REQUIRED_RESULT QString fromAsString(KMime::Content *node) const;
199 
200  KMime::Content *decryptedNodeForContent(KMime::Content *content) const;
201 
202  /**
203  * This function returns the unencrypted message that is based on @p originalMessage.
204  * All encrypted MIME parts are removed and replaced by their decrypted plain-text versions.
205  * Encrypted parts that are within signed parts are not replaced, since that would invalidate
206  * the signature.
207  *
208  * This only works if the message was run through ObjectTreeParser::parseObjectTree() with the
209  * current NodeHelper before, because parseObjectTree() actually decrypts the message and stores
210  * the decrypted nodes by calling attachExtraContent().
211  *
212  * @return the unencrypted message or an invalid pointer if the original message didn't contain
213  * a part that needed to be modified.
214  */
215  KMime::Message::Ptr unencryptedMessage(const KMime::Message::Ptr &originalMessage);
216 
217  /**
218  * Returns a list of attachments of attached extra content nodes.
219  * This is mainly useful is order to get attachments of encrypted messages.
220  * Note that this does not include attachments from the primary node tree.
221  * @see KMime::Content::attachments().
222  */
223  QVector<KMime::Content *> attachmentsOfExtraContents() const;
224 
225  Q_REQUIRED_RESULT QString extractAttachmentIndex(const QString &path) const;
226 Q_SIGNALS:
227  void update(MimeTreeParser::UpdateMode);
228 
229 private:
230  Q_DISABLE_COPY(NodeHelper)
231  bool unencryptedMessage_helper(KMime::Content *node, QByteArray &resultingData, bool addHeaders, int recursionLevel = 1);
232 
233  void mergeExtraNodes(KMime::Content *node);
234  void cleanFromExtraNodes(KMime::Content *node);
235 
236  /** Creates a persistent index string that bridges the gap between the
237  permanent nodes and the temporary ones.
238 
239  Used internally for robust indexing.
240  **/
241  Q_REQUIRED_RESULT QString persistentIndex(const KMime::Content *node) const;
242 
243  /** Translates the persistentIndex into a node back
244 
245  node: any node of the actually message to what the persistentIndex is interpreded
246  **/
247  KMime::Content *contentFromIndex(KMime::Content *node, const QString &persistentIndex) const;
248 
249 private:
250  QList<KMime::Content *> mProcessedNodes;
251  QList<KMime::Content *> mNodesUnderProcess;
254  QSet<KMime::Content *> mDisplayEmbeddedNodes;
255  QSet<KMime::Content *> mDisplayHiddenNodes;
256  QTextCodec *mLocalCodec = nullptr;
261  QPointer<AttachmentTemporaryFilesDirs> mAttachmentFilesDir;
263  QVector<QPointer<AttachmentTemporaryFilesDirs>> mListAttachmentTemporaryDirs;
264  friend class NodeHelperTest;
265 };
266 }
267 
KIMAP_EXPORT QTextCodec * codecForName(const QString &name)
interface of classes that implement status for BodyPartFormatters.
Definition: bodypart.h:33
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Apr 20 2021 23:14:04 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.