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 using MessagePartPtr = QSharedPointer<MessagePart>;
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  // Overload which creates a URL without the query part. Used by MessagePart::makeLink.
154  Q_REQUIRED_RESULT QString asHREF(const KMime::Content *node) const;
155 
156  /**
157  * @return true if this node is a child or an encapsulated message
158  */
159  Q_REQUIRED_RESULT static bool isInEncapsulatedMessage(KMime::Content *node);
160 
161  /**
162  * Returns the charset for the given node. If no charset is specified
163  * for the node, the defaultCharset() is returned.
164  */
165  Q_REQUIRED_RESULT static QByteArray charset(KMime::Content *node);
166 
167  /**
168  * Return a QTextCodec for the specified charset.
169  * This function is a bit more tolerant, than QTextCodec::codecForName
170  */
171  static const QTextCodec *codecForName(const QByteArray &_str);
172 
173  /**
174  * Returns a usable filename for a node, that can be the filename from the
175  * content disposition header, or if that one is empty, the name from the
176  * content type header.
177  */
178  Q_REQUIRED_RESULT static QString fileName(const KMime::Content *node);
179 
180  /**
181  * Fixes an encoding received by a KDE function and returns the proper,
182  * MIME-compliant encoding name instead.
183  * @see encodingForName
184  */
185  Q_REQUIRED_RESULT static QString fixEncoding(const QString &encoding); // TODO(Andras) move to a utility class?
186 
187  /**
188  * Drop-in replacement for KCharsets::encodingForName(). The problem with
189  * the KCharsets function is that it returns "human-readable" encoding names
190  * like "ISO 8859-15" instead of valid encoding names like "ISO-8859-15".
191  * This function fixes this by replacing whitespace with a hyphen.
192  */
193  Q_REQUIRED_RESULT static QString encodingForName(const QString &descriptiveName); // TODO(Andras) move to a utility class?
194 
195  /**
196  * Return a list of the supported encodings
197  * @param usAscii if true, US-Ascii encoding will be prepended to the list.
198  */
199  Q_REQUIRED_RESULT static QStringList supportedEncodings(bool usAscii); // TODO(Andras) move to a utility class?
200 
201  Q_REQUIRED_RESULT QString fromAsString(KMime::Content *node) const;
202 
203  KMime::Content *decryptedNodeForContent(KMime::Content *content) const;
204 
205  /**
206  * This function returns the unencrypted message that is based on @p originalMessage.
207  * All encrypted MIME parts are removed and replaced by their decrypted plain-text versions.
208  * Encrypted parts that are within signed parts are not replaced, since that would invalidate
209  * the signature.
210  *
211  * This only works if the message was run through ObjectTreeParser::parseObjectTree() with the
212  * current NodeHelper before, because parseObjectTree() actually decrypts the message and stores
213  * the decrypted nodes by calling attachExtraContent().
214  *
215  * @return the unencrypted message or an invalid pointer if the original message didn't contain
216  * a part that needed to be modified.
217  */
218  KMime::Message::Ptr unencryptedMessage(const KMime::Message::Ptr &originalMessage);
219 
220  /**
221  * Returns a list of attachments of attached extra content nodes.
222  * This is mainly useful is order to get attachments of encrypted messages.
223  * Note that this does not include attachments from the primary node tree.
224  * @see KMime::Content::attachments().
225  */
226  QVector<KMime::Content *> attachmentsOfExtraContents() const;
227 
228  Q_REQUIRED_RESULT QString extractAttachmentIndex(const QString &path) const;
229 Q_SIGNALS:
230  void update(MimeTreeParser::UpdateMode);
231 
232 private:
233  Q_DISABLE_COPY(NodeHelper)
234  bool unencryptedMessage_helper(KMime::Content *node, QByteArray &resultingData, bool addHeaders, int recursionLevel = 1);
235 
236  MIMETREEPARSER_NO_EXPORT void mergeExtraNodes(KMime::Content *node);
237  MIMETREEPARSER_NO_EXPORT void cleanFromExtraNodes(KMime::Content *node);
238 
239  /** Creates a persistent index string that bridges the gap between the
240  permanent nodes and the temporary ones.
241 
242  Used internally for robust indexing.
243  **/
244  Q_REQUIRED_RESULT QString persistentIndex(const KMime::Content *node) const;
245 
246  /** Translates the persistentIndex into a node back
247 
248  node: any node of the actually message to what the persistentIndex is interpreded
249  **/
250  KMime::Content *contentFromIndex(KMime::Content *node, const QString &persistentIndex) const;
251 
252 private:
253  QList<KMime::Content *> mProcessedNodes;
254  QList<KMime::Content *> mNodesUnderProcess;
257  QSet<KMime::Content *> mDisplayEmbeddedNodes;
258  QSet<KMime::Content *> mDisplayHiddenNodes;
259  QTextCodec *mLocalCodec = nullptr;
264  QPointer<AttachmentTemporaryFilesDirs> mAttachmentFilesDir;
266  QVector<QPointer<AttachmentTemporaryFilesDirs>> mListAttachmentTemporaryDirs;
267  friend class NodeHelperTest;
268 };
269 }
KIMAP2_EXPORT QTextCodec * codecForName(const QString &name)
interface of classes that implement status for BodyPartFormatters.
Definition: bodypart.h:33
QString message
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Jun 4 2023 04:01:57 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.