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 <QAbstractItemModel>
12 #include <QVector>
13 namespace Akonadi
14 {
15 class MessageStatus;
16 }
17 
18 namespace MessageList
19 {
20 namespace Core
21 {
22 class MessageItem;
23 
24 /**
25  * The QAbstractItemModel based interface that you need
26  * to provide for your storage to work with MessageList.
27  */
28 class StorageModel : public QAbstractItemModel
29 {
30     Q_OBJECT
31 
32 public:
33     explicit StorageModel(QObject *parent = nullptr);
34     ~StorageModel() override;
35 
36     /**
37      * Returns an unique id for this Storage collection.
38      * FIXME: This could be embedded in "name()" ?
39      */
40     virtual QString id() const = 0;
41 
42     /**
43      * Returns the unique id of the last selected message for this StorageModel.
44      * Returns 0 if this value isn't stored in the configuration.
45      */
46     unsigned long preSelectedMessage() const;
47 
48     /**
49      * Stores in the unique id of the last selected message for the specified StorageModel.
50      * The uniqueIdOfMessage may be 0 (which means that no selection shall be stored in the configuration).
51      */
52     void savePreSelectedMessage(unsigned long uniqueIdOfMessage);
53 
54     /**
55      * Returns true if this StorageModel (folder) contains outbound messages and false otherwise.
56      */
57     virtual bool containsOutboundMessages() const = 0;
58 
59     /**
60      * Returns (a guess for) the number of unread messages: must be pessimistic (i.e. if you
61      * have no idea just return rowCount(), which is also what the default implementation does).
62      * This must be (and is) queried ONLY when the folder is first opened. It doesn't actually need
63      * to keep the number of messages in sync as they later arrive to the storage.
64      */
65     virtual int initialUnreadRowCountGuess() const;
66 
67     /**
68      * This method should use the inner model implementation to fill in the
69      * base data for the specified MessageItem from the underlying storage slot at
70      * the specified row index. Must return true if the data fetch was successful
71      * and false otherwise. For base data we intend: subject, sender, receiver,
72      * senderOrReceiver, size, date, encryption state, signature state and status.
73      * If bUseReceiver is true then the "senderOrReceiver"
74      * field must be set to the receiver, otherwise it must be set to the sender.
75      */
76     virtual bool initializeMessageItem(MessageItem *it, int row, bool bUseReceiver) const = 0;
77 
78     enum ThreadingDataSubset {
79         PerfectThreadingOnly, ///< Only the data for messageIdMD5 and inReplyToMD5 is needed
80         PerfectThreadingPlusReferences, ///< messageIdMD5, inReplyToMD5, referencesIdMD5
81         PerfectThreadingReferencesAndSubject ///< All of the above plus subject stuff
82     };
83 
84     /**
85      * This method should use the inner model implementation to fill in the specified subset of
86      * threading data for the specified MessageItem from the underlying storage slot at
87      * the specified row index.
88      */
89     virtual void fillMessageItemThreadingData(MessageItem *mi, int row, ThreadingDataSubset subset) const = 0;
90 
91     /**
92      * This method should use the inner model implementation to re-fill the date, the status,
93      * the encryption state, the signature state and eventually update the min/max dates
94      * for the specified MessageItem from the underlying storage slot at the specified row index.
95      */
96     virtual void updateMessageItemData(MessageItem *mi, int row) const = 0;
97 
98     /**
99      * This method should use the inner model implementation to associate the new status
100      * to the specified message item. The new status should be stored (but doesn't need
101      * to be set as mi->status() itself as the caller is responsible for this).
102      */
103     virtual void setMessageItemStatus(MessageItem *mi, int row, Akonadi::MessageStatus status) = 0;
104 
105     /**
106      * The implementation-specific mime data for this list of items.
107      *    Called when the user initiates a drag from the messagelist.
108      */
109     virtual QMimeData *mimeData(const QVector<MessageItem *> &) const = 0;
110     using QAbstractItemModel::mimeData;
111 };
112 } // namespace Core
113 } // namespace MessageList
114 
115