1 /******************************************************************************
2  *
3  *  SPDX-FileCopyrightText: 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *
7  *******************************************************************************/
8 
9 #pragma once
10 
11 #include "core/item.h"
12 #include "core/modelinvariantindex.h"
13 
14 #include "theme.h"
15 #include <QColor>
16 #include <QFont>
17 #include <QPixmap>
18 #include <QString>
19 #include <messagelist_export.h>
20 
21 namespace Akonadi
22 {
23 class Item;
24 }
25 
26 namespace MessageList
27 {
28 namespace Core
29 {
30 class MessageItemPrivate;
31 /**
32  * @brief The MessageItem class
33  */
34 class MESSAGELIST_EXPORT MessageItem : public Item, public ModelInvariantIndex
35 {
36 public:
37     class MESSAGELIST_EXPORT Tag
38     {
39     public:
40         explicit Tag(const QPixmap &pix, const QString &tagName, const QString &tagId);
41         ~Tag();
42         const QPixmap &pixmap() const;
43         const QString &name() const;
44         const QString &id() const;
45         const QColor &textColor() const;
46         const QColor &backgroundColor() const;
47         const QFont &font() const;
48         int priority() const;
49 
50         void setTextColor(const QColor &textColor);
51         void setBackgroundColor(const QColor &backgroundColor);
52         void setFont(const QFont &font);
53         void setPriority(int priority);
54 
55     private:
56         class TagPrivate;
57         std::unique_ptr<TagPrivate> const d;
58     };
59 
60     enum ThreadingStatus {
61         PerfectParentFound, ///< this message found a perfect parent to attach to
62         ImperfectParentFound, ///< this message found an imperfect parent to attach to (might be fixed later)
63         ParentMissing, ///< this message might belong to a thread but its parent is actually missing
64         NonThreadable ///< this message does not look as being threadable
65     };
66 
67     enum EncryptionState { NotEncrypted, PartiallyEncrypted, FullyEncrypted, EncryptionStateUnknown };
68 
69     enum SignatureState { NotSigned, PartiallySigned, FullySigned, SignatureStateUnknown };
70 
71     explicit MessageItem();
72     ~MessageItem() override;
73 
74 public:
75     /// Returns the list of tags for this item.
76     virtual QList<Tag *> tagList() const;
77 
78     /// Returns true if this message has an annotation.
79     virtual bool hasAnnotation() const;
80 
81     /// Returns the annotation of the message, given that hasAnnotation() is true
82     Q_REQUIRED_RESULT QString annotation() const;
83 
84     /// Shows a dialog to edit or delete the annotation
85     void editAnnotation(QWidget *parent);
86 
87     /**
88      * Returns Tag associated to this message that has the specified id or 0
89      * if no such tag exists. mTagList will be 0 in 99% of the cases.
90      */
91     const Tag *findTag(const QString &szTagId) const;
92 
93     Q_REQUIRED_RESULT QString tagListDescription() const;
94 
95     /// Deletes all cached tags. The next time someone asks this item for the tags, they are
96     /// fetched again
97     void invalidateTagCache();
98 
99     /// Same as invalidateTagCache(), only for the annotation
100     void invalidateAnnotationCache();
101 
102     const QColor &textColor() const;
103 
104     const QColor &backgroundColor() const;
105 
isBold()106     Q_REQUIRED_RESULT bool isBold() const
107     {
108         return font().bold();
109     }
110 
isItalic()111     Q_REQUIRED_RESULT bool isItalic() const
112     {
113         return font().italic();
114     }
115 
116     Q_REQUIRED_RESULT SignatureState signatureState() const;
117 
118     void setSignatureState(SignatureState state);
119 
120     Q_REQUIRED_RESULT EncryptionState encryptionState() const;
121 
122     void setEncryptionState(EncryptionState state);
123 
124     Q_REQUIRED_RESULT QByteArray messageIdMD5() const;
125 
126     void setMessageIdMD5(const QByteArray &md5);
127 
128     Q_REQUIRED_RESULT QByteArray inReplyToIdMD5() const;
129 
130     void setInReplyToIdMD5(const QByteArray &md5);
131 
132     Q_REQUIRED_RESULT QByteArray referencesIdMD5() const;
133 
134     void setReferencesIdMD5(const QByteArray &md5);
135 
136     void setSubjectIsPrefixed(bool subjectIsPrefixed);
137 
138     Q_REQUIRED_RESULT bool subjectIsPrefixed() const;
139 
140     Q_REQUIRED_RESULT QByteArray strippedSubjectMD5() const;
141 
142     void setStrippedSubjectMD5(const QByteArray &md5);
143 
144     Q_REQUIRED_RESULT bool aboutToBeRemoved() const;
145 
146     void setAboutToBeRemoved(bool aboutToBeRemoved);
147 
148     Q_REQUIRED_RESULT ThreadingStatus threadingStatus() const;
149 
150     void setThreadingStatus(ThreadingStatus threadingStatus);
151 
152     Q_REQUIRED_RESULT unsigned long uniqueId() const;
153 
154     Akonadi::Item akonadiItem() const;
155     void setAkonadiItem(const Akonadi::Item &item);
156 
157     MessageItem *topmostMessage();
158 
159     QString accessibleText(const MessageList::Core::Theme *theme, int columnIndex);
160 
161     /**
162      * Appends the whole subtree originating at this item
163      * to the specified list. This item is included!
164      */
165     void subTreeToList(QVector<MessageItem *> &list);
166 
167     //
168     // Colors and fonts shared by all message items.
169     // textColor() and font() will take the message status into account and return
170     // one of these.
171     // Call these setters only once when reading the colors from the config file.
172     //
173     static void setUnreadMessageColor(const QColor &color);
174     static void setImportantMessageColor(const QColor &color);
175     static void setToDoMessageColor(const QColor &color);
176     static void setGeneralFont(const QFont &font);
177     static void setUnreadMessageFont(const QFont &font);
178     static void setImportantMessageFont(const QFont &font);
179     static void setToDoMessageFont(const QFont &font);
180 
181 protected:
182     explicit MessageItem(MessageItemPrivate *dd);
183 
184 private:
185     const QFont &font() const;
186 
187     QString accessibleTextForField(Theme::ContentItem::Type field);
188 
189     Q_DECLARE_PRIVATE(MessageItem)
190 };
191 
192 class FakeItemPrivate;
193 
194 /// A message item that can have a fake tag list and a fake annotation
195 class FakeItem : public MessageItem
196 {
197 public:
198     explicit FakeItem();
199     ~FakeItem() override;
200 
201     /// Reimplemented to return the fake tag list
202     QList<Tag *> tagList() const override;
203 
204     /// Sets a list of fake tags for this item
205     void setFakeTags(const QList<Tag *> &tagList);
206 
207     /// Reimplemented to always return true
208     bool hasAnnotation() const override;
209 
210 private:
211     Q_DECLARE_PRIVATE(FakeItem)
212 };
213 } // namespace Core
214 } // namespace MessageList
215 
216