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

KDE's Doxygen guidelines are available online.