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 class QDataStream;
12 
13 #include <QPair>
14 #include <QString>
15 #include <QVector>
16 
17 #include "core/optionset.h"
18 
19 namespace MessageList
20 {
21 namespace Core
22 {
23 /**
24  * A set of aggregation options that can be applied to the MessageList::Model in a single shot.
25  * The set defines the behaviours related to the population of the model, threading
26  * of messages and grouping.
27  */
28 class Aggregation : public OptionSet
29 {
30 public:
31     /**
32      * Message grouping.
33      * If you add values here please look at the implementations of the enumerate* functions
34      * and add appropriate descriptors.
35      */
36     enum Grouping {
37         NoGrouping, ///< Don't group messages at all
38         GroupByDate, ///< Group the messages by the date of the thread leader
39         GroupByDateRange, ///< Use smart (thread leader) date ranges ("Today","Yesterday","Last Week"...)
40         GroupBySenderOrReceiver, ///< Group by sender (incoming) or receiver (outgoing) field
41         GroupBySender, ///< Group by sender, always
42         GroupByReceiver ///< Group by receiver, always
43         // Never add enum entries in the middle: always add them at the end (numeric values are stored in configuration)
44         // TODO: Group by message status: "Important messages", "Urgent messages", "To reply", "To do" etc...
45         // TODO: Group by message unread status: "Unread messages", "Read messages" (maybe "New" ?)
46     };
47 
48     /**
49      * The available group expand policies.
50      * If you add values here please look at the implementations of the enumerate* functions
51      * and add appropriate descriptors.
52      */
53     enum GroupExpandPolicy {
54         NeverExpandGroups, ///< Never expand groups during a view fill algorithm
55         ExpandRecentGroups, ///< Makes sense only with GroupByDate or GroupByDateRange
56         AlwaysExpandGroups ///< All groups are expanded as they are inserted
57         // Never add enum entries in the middle: always add them at the end (numeric values are stored in configuration)
58     };
59 
60     /**
61      * The available threading methods.
62      * If you add values here please look at the implementations of the enumerate* functions
63      * and add appropriate descriptors.
64      */
65     enum Threading {
66         NoThreading, ///< Perform no threading at all
67         PerfectOnly, ///< Thread by "In-Reply-To" field only
68         PerfectAndReferences, ///< Thread by "In-Reply-To" and "References" fields
69         PerfectReferencesAndSubject ///< Thread by all of the above and try to match subjects too
70         // Never add enum entries in the middle: always add them at the end (numeric values are stored in configuration)
71     };
72 
73     /**
74      * The available thread leading options. Meaningless when threading is set to NoThreading.
75      * If you add values here please look at the implementations of the enumerate* functions
76      * and add appropriate descriptors.
77      */
78     enum ThreadLeader {
79         TopmostMessage, ///< The thread grouping is computed from the topmost message (very similar to least recent, but might be different if timezones or
80                         ///< machine clocks are screwed)
81         MostRecentMessage ///< The thread grouping is computed from the most recent message
82         // Never add enum entries in the middle: always add them at the end (numeric values are stored in configuration)
83     };
84 
85     /**
86      * The available thread expand policies. Meaningless when threading is set to NoThreading.
87      * If you add values here please look at the implementations of the enumerate* functions
88      * and add appropriate descriptors.
89      */
90     enum ThreadExpandPolicy {
91         NeverExpandThreads, ///< Never expand any thread, this is fast
92         ExpandThreadsWithNewMessages, ///< DEPRECATED. New message status no longer exists.
93         ExpandThreadsWithUnreadMessages, ///< Expand threads with unread messages (this includes new)
94         AlwaysExpandThreads, ///< Expand all threads (this might be very slow)
95         ExpandThreadsWithUnreadOrImportantMessages ///< Expand threads with "hot" messages (this includes new, unread, important, todo)
96         // Never add enum entries in the middle: always add them at the end (numeric values are stored in configuration)
97     };
98 
99     /**
100      * The available fill view strategies.
101      * If you add values here please look at the implementations of the enumerate* functions
102      * and add appropriate descriptors.
103      */
104     enum FillViewStrategy {
105         FavorInteractivity, ///< Do small chunks of work, small intervals between chunks to allow for UI event processing
106         FavorSpeed, ///< Do larger chunks of work, zero intervals between chunks
107         BatchNoInteractivity ///< Do one large chunk, no interactivity at all
108         // Warning: Never add enum entries in the middle: always add them at the end (numeric values are stored in configuration)
109     };
110 
111 private:
112     Grouping mGrouping;
113     GroupExpandPolicy mGroupExpandPolicy;
114     Threading mThreading;
115     ThreadLeader mThreadLeader;
116     ThreadExpandPolicy mThreadExpandPolicy;
117     FillViewStrategy mFillViewStrategy;
118 
119 public:
120     explicit Aggregation();
121     explicit Aggregation(const Aggregation &opt);
122     explicit Aggregation(const QString &name,
123                          const QString &description,
124                          Grouping grouping,
125                          GroupExpandPolicy groupExpandPolicy,
126                          Threading threading,
127                          ThreadLeader threadLeader,
128                          ThreadExpandPolicy threadExpandPolicy,
129                          FillViewStrategy fillViewStrategy,
130                          bool readOnly);
compareName(Aggregation * agg1,Aggregation * agg2)131     Q_REQUIRED_RESULT static bool compareName(Aggregation *agg1, Aggregation *agg2)
132     {
133         return agg1->name() < agg2->name();
134     }
135 
136 public:
137     /**
138      * Returns the currently set Grouping option.
139      */
140     Q_REQUIRED_RESULT Grouping grouping() const;
141 
142     /**
143      * Sets the Grouping option.
144      */
setGrouping(Grouping g)145     void setGrouping(Grouping g)
146     {
147         mGrouping = g;
148     }
149 
150     /**
151      * Enumerates the available grouping options as a QList of
152      * pairs in that the first item is the localized description of the
153      * option value and the second item is the integer option value itself.
154      */
155     static QVector<QPair<QString, int>> enumerateGroupingOptions();
156 
157     /**
158      * Returns the current GroupExpandPolicy.
159      */
groupExpandPolicy()160     Q_REQUIRED_RESULT GroupExpandPolicy groupExpandPolicy() const
161     {
162         return mGroupExpandPolicy;
163     }
164 
165     /**
166      * Sets the GroupExpandPolicy for the groups.
167      * Note that this option has no meaning if grouping is set to NoGrouping.
168      */
setGroupExpandPolicy(GroupExpandPolicy groupExpandPolicy)169     void setGroupExpandPolicy(GroupExpandPolicy groupExpandPolicy)
170     {
171         mGroupExpandPolicy = groupExpandPolicy;
172     }
173 
174     /**
175      * Enumerates the group sort direction options compatible with the specified Grouping.
176      * The returned descriptors are pairs in that the first item is the localized description
177      * of the option value and the second item is the integer option value itself.
178      * If the returned list is empty then the value of the option is meaningless in the current context.
179      */
180     static QVector<QPair<QString, int>> enumerateGroupExpandPolicyOptions(Grouping g);
181 
182     /**
183      * Returns the current threading method.
184      */
threading()185     Q_REQUIRED_RESULT Threading threading() const
186     {
187         return mThreading;
188     }
189 
190     /**
191      * Sets the threading method option.
192      */
setThreading(Threading t)193     void setThreading(Threading t)
194     {
195         mThreading = t;
196     }
197 
198     /**
199      * Enumerates the available threading method options.
200      * The returned descriptors are pairs in that the first item is the localized description
201      * of the option value and the second item is the integer option value itself.
202      */
203     static QVector<QPair<QString, int>> enumerateThreadingOptions();
204 
205     /**
206      * Returns the current thread leader determination method.
207      */
threadLeader()208     Q_REQUIRED_RESULT ThreadLeader threadLeader() const
209     {
210         return mThreadLeader;
211     }
212 
213     /**
214      * Sets the current thread leader determination method.
215      * Please note that when Threading is set to NoThreading this value is meaningless
216      * and by policy should be set to TopmostMessage.
217      */
setThreadLeader(ThreadLeader tl)218     void setThreadLeader(ThreadLeader tl)
219     {
220         mThreadLeader = tl;
221     }
222 
223     /**
224      * Enumerates the thread leader determination methods compatible with the specified Threading
225      * and the specified Grouping options.
226      * The returned descriptors are pairs in that the first item is the localized description
227      * of the option value and the second item is the integer option value itself.
228      * If the returned list is empty then the value of the option is meaningless in the current context.
229      */
230     static QVector<QPair<QString, int>> enumerateThreadLeaderOptions(Grouping g, Threading t);
231 
232     /**
233      * Returns the current thread expand policy.
234      */
threadExpandPolicy()235     ThreadExpandPolicy threadExpandPolicy() const
236     {
237         return mThreadExpandPolicy;
238     }
239 
240     /**
241      * Sets the current thread expand policy.
242      * Please note that when Threading is set to NoThreading this value is meaningless
243      * and by policy should be set to NeverExpandThreads.
244      */
setThreadExpandPolicy(ThreadExpandPolicy threadExpandPolicy)245     void setThreadExpandPolicy(ThreadExpandPolicy threadExpandPolicy)
246     {
247         mThreadExpandPolicy = threadExpandPolicy;
248     }
249 
250     /**
251      * Enumerates the thread expand policies compatible with the specified Threading option.
252      * The returned descriptors are pairs in that the first item is the localized description
253      * of the option value and the second item is the integer option value itself.
254      * If the returned list is empty then the value of the option is meaningless in the current context.
255      */
256     static QVector<QPair<QString, int>> enumerateThreadExpandPolicyOptions(Threading t);
257 
258     /**
259      * Returns the current fill view strategy.
260      */
fillViewStrategy()261     Q_REQUIRED_RESULT FillViewStrategy fillViewStrategy() const
262     {
263         return mFillViewStrategy;
264     }
265 
266     /**
267      * Sets the current fill view strategy.
268      */
setFillViewStrategy(FillViewStrategy fillViewStrategy)269     void setFillViewStrategy(FillViewStrategy fillViewStrategy)
270     {
271         mFillViewStrategy = fillViewStrategy;
272     }
273 
274     /**
275      * Enumerates the fill view strategies.
276      * The returned descriptors are pairs in that the first item is the localized description
277      * of the option value and the second item is the integer option value itself.
278      */
279     static QVector<QPair<QString, int>> enumerateFillViewStrategyOptions();
280 
281     /**
282      * Pure virtual reimplemented from OptionSet.
283      */
284     void save(QDataStream &stream) const override;
285 
286     /**
287      * Pure virtual reimplemented from OptionSet.
288      */
289     bool load(QDataStream &stream) override;
290 };
291 } // namespace Core
292 } // namespace MessageList
293 
294