Messagelib

sortorder.cpp
1 /******************************************************************************
2  *
3  * SPDX-FileCopyrightText: 2009 Thomas McGuire <[email protected]>
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  *
7  *******************************************************************************/
8 #include "core/sortorder.h"
9 
10 #include "messagelistutil_p.h"
11 
12 #include <KLocalizedString>
13 
14 #include <QMetaEnum>
15 
16 using namespace MessageList::Core;
17 
18 SortOrder::SortOrder() = default;
19 
21 {
22  return mGroupSorting;
23 }
24 
26 {
27  mGroupSorting = gs;
28 }
29 
31 {
32  return mGroupSortDirection;
33 }
34 
36 {
37  mGroupSortDirection = groupSortDirection;
38 }
39 
41 {
42  return mMessageSorting;
43 }
44 
46 {
47  mMessageSorting = ms;
48 }
49 
51 {
52  return mMessageSortDirection;
53 }
54 
56 {
57  mMessageSortDirection = messageSortDirection;
58 }
59 
61 {
63  ret.append({i18n("None (Storage Order)"), SortOrder::NoMessageSorting});
64  ret.append({i18n("By Date/Time"), SortOrder::SortMessagesByDateTime});
65  if (t != Aggregation::NoThreading) {
66  ret.append({i18n("By Date/Time of Most Recent in Subtree"), SortOrder::SortMessagesByDateTimeOfMostRecent});
67  }
68  ret.append({i18n("By Sender"), SortOrder::SortMessagesBySender});
69  ret.append({i18n("By Receiver"), SortOrder::SortMessagesByReceiver});
70  ret.append({i18n("By Smart Sender/Receiver"), SortOrder::SortMessagesBySenderOrReceiver});
71  ret.append({i18n("By Subject"), SortOrder::SortMessagesBySubject});
72  ret.append({i18n("By Size"), SortOrder::SortMessagesBySize});
73  ret.append({i18n("By Action Item Status"), SortOrder::SortMessagesByActionItemStatus});
74  ret.append({i18n("By Unread Status"), SortOrder::SortMessagesByUnreadStatus});
75  ret.append({i18n("By Important Status"), SortOrder::SortMessagesByImportantStatus});
76  ret.append({i18n("By Attachment Status"), SortOrder::SortMessagesByAttachmentStatus});
77  return ret;
78 }
79 
81 {
83  if (ms == SortOrder::NoMessageSorting) {
84  return ret;
85  }
86 
88  ret.append({i18n("Least Recent on Top"), SortOrder::Ascending});
89  ret.append({i18n("Most Recent on Top"), SortOrder::Descending});
90  return ret;
91  }
92 
93  ret.append({i18nc("Sort order for messages", "Ascending"), SortOrder::Ascending});
94  ret.append({i18nc("Sort order for messages", "Descending"), SortOrder::Descending});
95  return ret;
96 }
97 
99 {
101  if (g == Aggregation::NoGrouping) {
102  return ret;
103  }
105  ret.append({i18n("by Date/Time"), SortOrder::SortGroupsByDateTime});
106  } else {
107  ret.append({i18n("None (Storage Order)"), SortOrder::NoGroupSorting});
108  ret.append({i18n("by Date/Time of Most Recent Message in Group"), SortOrder::SortGroupsByDateTimeOfMostRecent});
109  }
110 
112  ret.append({i18n("by Sender/Receiver"), SortOrder::SortGroupsBySenderOrReceiver});
113  } else if (g == Aggregation::GroupBySender) {
114  ret.append({i18n("by Sender"), SortOrder::SortGroupsBySender});
115  } else if (g == Aggregation::GroupByReceiver) {
116  ret.append({i18n("by Receiver"), SortOrder::SortGroupsByReceiver});
117  }
118 
119  return ret;
120 }
121 
123 {
126  return ret;
127  }
128 
130  ret.append({i18n("Least Recent on Top"), SortOrder::Ascending});
131  ret.append({i18n("Most Recent on Top"), SortOrder::Descending});
132  return ret;
133  }
134  ret.append({i18nc("Sort order for mail groups", "Ascending"), SortOrder::Ascending});
135  ret.append({i18nc("Sort order for mail groups", "Descending"), SortOrder::Descending});
136  return ret;
137 }
138 
140 static bool optionListHasOption(const OptionList &optionList, int optionValue, int defaultOptionValue)
141 {
142  for (const auto &pair : optionList) {
143  if (pair.second == optionValue) {
144  return true;
145  }
146  }
147  if (optionValue != defaultOptionValue) {
148  return false;
149  } else {
150  return true;
151  }
152 }
153 
154 bool SortOrder::validForAggregation(const Aggregation *aggregation) const
155 {
156  OptionList messageSortings = enumerateMessageSortingOptions(aggregation->threading());
157  OptionList messageSortDirections = enumerateMessageSortDirectionOptions(mMessageSorting);
158  OptionList groupSortings = enumerateGroupSortingOptions(aggregation->grouping());
159  OptionList groupSortDirections = enumerateGroupSortDirectionOptions(aggregation->grouping(), mGroupSorting);
160  SortOrder defaultSortOrder = defaultForAggregation(aggregation, SortOrder());
161  bool messageSortingOk = optionListHasOption(messageSortings, mMessageSorting, defaultSortOrder.messageSorting());
162  bool messageSortDirectionOk = optionListHasOption(messageSortDirections, mMessageSortDirection, defaultSortOrder.messageSortDirection());
163 
164  bool groupSortingOk = optionListHasOption(groupSortings, mGroupSorting, defaultSortOrder.groupSorting());
165  bool groupSortDirectionOk = optionListHasOption(groupSortDirections, mGroupSortDirection, defaultSortOrder.groupSortDirection());
166  return messageSortingOk && messageSortDirectionOk && groupSortingOk && groupSortDirectionOk;
167 }
168 
170 {
171  SortOrder newSortOrder;
172 
173  //
174  // First check if we can adopt the message sorting and the message sort direction from
175  // the old sort order. This is mostly true, except, for example, when the old message sorting
176  // was "by most recent in subtree", and the aggregation doesn't use threading.
177  //
178  OptionList messageSortings = enumerateMessageSortingOptions(aggregation->threading());
179  bool messageSortingOk = optionListHasOption(messageSortings, oldSortOrder.messageSorting(), SortOrder().messageSorting());
180  bool messageSortDirectionOk = false;
181  if (messageSortingOk) {
182  const OptionList messageSortDirections = enumerateMessageSortDirectionOptions(oldSortOrder.messageSorting());
183  messageSortDirectionOk = optionListHasOption(messageSortDirections, oldSortOrder.messageSortDirection(), SortOrder().messageSortDirection());
184  newSortOrder.setMessageSorting(oldSortOrder.messageSorting());
185  } else {
187  }
188  if (messageSortDirectionOk) {
189  newSortOrder.setMessageSortDirection(oldSortOrder.messageSortDirection());
190  } else {
191  newSortOrder.setMessageSortDirection(Descending);
192  }
193 
194  //
195  // Now set the group sorting and group sort direction, depending on the aggregation.
196  //
197  Aggregation::Grouping grouping = aggregation->grouping();
198  if (grouping == Aggregation::GroupByDate || grouping == Aggregation::GroupByDateRange) {
199  newSortOrder.setGroupSortDirection(Descending);
201  } else if (grouping == Aggregation::GroupByReceiver || grouping == Aggregation::GroupBySender || grouping == Aggregation::GroupBySenderOrReceiver) {
202  newSortOrder.setGroupSortDirection(Descending);
203  switch (grouping) {
206  break;
208  newSortOrder.setGroupSorting(SortGroupsBySender);
209  break;
212  break;
213  default:
214  break;
215  }
216  }
217 
218  return newSortOrder;
219 }
220 
221 bool SortOrder::readConfigHelper(KConfigGroup &conf, const QString &id)
222 {
223  if (!conf.hasKey(id + MessageList::Util::messageSortingConfigName())) {
224  return false;
225  }
226  mMessageSorting = messageSortingForName(conf.readEntry(id + MessageList::Util::messageSortingConfigName()));
227  mMessageSortDirection = sortDirectionForName(conf.readEntry(id + MessageList::Util::messageSortDirectionConfigName()));
228  mGroupSorting = groupSortingForName(conf.readEntry(id + MessageList::Util::groupSortingConfigName()));
229  mGroupSortDirection = sortDirectionForName(conf.readEntry(id + MessageList::Util::groupSortDirectionConfigName()));
230  return true;
231 }
232 
233 void SortOrder::readConfig(KConfigGroup &conf, const QString &storageId, bool *storageUsesPrivateSortOrder)
234 {
235  SortOrder privateSortOrder;
236  SortOrder globalSortOrder;
237  globalSortOrder.readConfigHelper(conf, QStringLiteral("GlobalSortOrder"));
238  *storageUsesPrivateSortOrder = privateSortOrder.readConfigHelper(conf, storageId);
239  if (*storageUsesPrivateSortOrder) {
240  *this = privateSortOrder;
241  } else {
242  *this = globalSortOrder;
243  }
244 }
245 
246 void SortOrder::writeConfig(KConfigGroup &conf, const QString &storageId, bool storageUsesPrivateSortOrder) const
247 {
248  QString id = storageId;
249  if (!storageUsesPrivateSortOrder) {
250  id = QStringLiteral("GlobalSortOrder");
251  conf.deleteEntry(storageId + MessageList::Util::messageSortingConfigName());
252  conf.deleteEntry(storageId + MessageList::Util::messageSortDirectionConfigName());
253  conf.deleteEntry(storageId + MessageList::Util::groupSortingConfigName());
254  conf.deleteEntry(storageId + MessageList::Util::groupSortDirectionConfigName());
255  }
256 
257  conf.writeEntry(id + MessageList::Util::messageSortingConfigName(), nameForMessageSorting(mMessageSorting));
258  conf.writeEntry(id + MessageList::Util::messageSortDirectionConfigName(), nameForSortDirection(mMessageSortDirection));
259  conf.writeEntry(id + MessageList::Util::groupSortingConfigName(), nameForGroupSorting(mGroupSorting));
260  conf.writeEntry(id + MessageList::Util::groupSortDirectionConfigName(), nameForSortDirection(mGroupSortDirection));
261 }
262 
264 {
265  switch (ms) {
276  case SortOrder::SortMessagesByImportantStatus:
278  // ok
279  break;
280  default:
281  // b0rken
282  return false;
283  }
284 
285  return true;
286 }
287 
288 const QString SortOrder::nameForSortDirection(SortDirection sortDirection)
289 {
290  int index = staticMetaObject.indexOfEnumerator("SortDirection");
291  return QLatin1String(staticMetaObject.enumerator(index).valueToKey(sortDirection));
292 }
293 
294 const QString SortOrder::nameForMessageSorting(MessageSorting messageSorting)
295 {
296  int index = staticMetaObject.indexOfEnumerator("MessageSorting");
297  return QLatin1String(staticMetaObject.enumerator(index).valueToKey(messageSorting));
298 }
299 
300 const QString SortOrder::nameForGroupSorting(GroupSorting groupSorting)
301 {
302  int index = staticMetaObject.indexOfEnumerator("GroupSorting");
303  return QLatin1String(staticMetaObject.enumerator(index).valueToKey(groupSorting));
304 }
305 
306 SortOrder::SortDirection SortOrder::sortDirectionForName(const QString &name)
307 {
308  int index = staticMetaObject.indexOfEnumerator("SortDirection");
309  return static_cast<SortDirection>(staticMetaObject.enumerator(index).keyToValue(name.toLatin1().constData()));
310 }
311 
312 SortOrder::MessageSorting SortOrder::messageSortingForName(const QString &name)
313 {
314  int index = staticMetaObject.indexOfEnumerator("MessageSorting");
315  return static_cast<MessageSorting>(staticMetaObject.enumerator(index).keyToValue(name.toLatin1().constData()));
316 }
317 
318 SortOrder::GroupSorting SortOrder::groupSortingForName(const QString &name)
319 {
320  int index = staticMetaObject.indexOfEnumerator("GroupSorting");
321  return static_cast<GroupSorting>(staticMetaObject.enumerator(index).keyToValue(name.toLatin1().constData()));
322 }
323 
324 #include "moc_sortorder.cpp"
void setGroupSortDirection(SortDirection groupSortDirection)
Sets the SortDirection for the groups.
Definition: sortorder.cpp:35
@ SortMessagesByDateTime
Sort the messages by date and time.
Definition: sortorder.h:80
@ GroupBySenderOrReceiver
Group by sender (incoming) or receiver (outgoing) field.
Definition: aggregation.h:40
QString readEntry(const char *key, const char *aDefault=nullptr) const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
@ SortGroupsByReceiver
Sort groups by receiver (makes sense only with GroupByReceiver)
Definition: sortorder.h:65
@ GroupBySender
Group by sender, always.
Definition: aggregation.h:41
void deleteEntry(const char *key, WriteConfigFlags pFlags=Normal)
void setMessageSortDirection(SortDirection messageSortDirection)
Sets the SortDirection for the message.
Definition: sortorder.cpp:55
SortDirection
The "generic" sort direction: used for groups and for messages If you add values here please look at ...
Definition: sortorder.h:68
void writeConfig(KConfigGroup &conf, const QString &storageId, bool storageUsesPrivateSortOrder) const
Writes the sort order to a config group.
Definition: sortorder.cpp:246
@ SortMessagesByReceiver
Sort the messages by receiver.
Definition: sortorder.h:84
@ SortMessagesByActionItemStatus
Sort the messages by the "Action Item" flag of status.
Definition: sortorder.h:87
@ NoGroupSorting
Don't sort the groups at all, add them as they come in.
Definition: sortorder.h:60
MessageSorting messageSorting() const
Returns the current message sorting option.
Definition: sortorder.cpp:40
void append(const T &value)
@ SortGroupsByDateTimeOfMostRecent
Sort groups by date/time of the most recent message.
Definition: sortorder.h:62
@ NoThreading
Perform no threading at all.
Definition: aggregation.h:66
static QVector< QPair< QString, int > > enumerateGroupSortDirectionOptions(Aggregation::Grouping g, GroupSorting groupSorting)
Enumerates the group sort direction options compatible with the specified Grouping and GroupSorting.
Definition: sortorder.cpp:122
QByteArray toLatin1() const const
static SortOrder defaultForAggregation(const Aggregation *aggregation, SortOrder oldSortOrder)
Returns the default sort order for the given aggregation.
Definition: sortorder.cpp:169
void setGroupSorting(GroupSorting gs)
Sets the GroupSorting option.
Definition: sortorder.cpp:25
void setMessageSorting(MessageSorting ms)
Sets the current message sorting option.
Definition: sortorder.cpp:45
static QVector< QPair< QString, int > > enumerateGroupSortingOptions(Aggregation::Grouping g)
Enumerates the group sorting options compatible with the specified Grouping.
Definition: sortorder.cpp:98
@ GroupByDate
Group the messages by the date of the thread leader.
Definition: aggregation.h:38
bool validForAggregation(const Aggregation *aggregation) const
Checks if this sort order can be used in combination with the given aggregation.
Definition: sortorder.cpp:154
@ SortMessagesBySender
Sort the messages by sender.
Definition: sortorder.h:83
SortDirection groupSortDirection() const
Returns the current group SortDirection.
Definition: sortorder.cpp:30
Grouping grouping() const
Returns the currently set Grouping option.
Definition: aggregation.cpp:38
@ NoGrouping
Don't group messages at all.
Definition: aggregation.h:37
QString i18n(const char *text, const TYPE &arg...)
static QVector< QPair< QString, int > > enumerateMessageSortingOptions(Aggregation::Threading t)
Enumerates the message sorting options compatible with the specified Threading setting.
Definition: sortorder.cpp:60
@ NoMessageSorting
Don't sort the messages at all.
Definition: sortorder.h:79
@ GroupByReceiver
Group by receiver, always.
Definition: aggregation.h:42
A class which holds information about sorting, e.g.
Definition: sortorder.h:34
MessageSorting
The available message sorting options.
Definition: sortorder.h:78
@ SortMessagesBySize
Sort the messages by size.
Definition: sortorder.h:86
bool hasKey(const char *key) const
SortDirection
@ SortGroupsBySenderOrReceiver
Sort groups by sender or receiver (makes sense only with GroupBySenderOrReceiver)
Definition: sortorder.h:63
@ SortMessagesByUnreadStatus
Sort the messages by the "Unread" flags of status.
Definition: sortorder.h:88
Threading
The available threading methods.
Definition: aggregation.h:65
SortDirection messageSortDirection() const
Returns the current message SortDirection.
Definition: sortorder.cpp:50
const char * constData() const const
@ SortMessagesByAttachmentStatus
Sort the messages By "Important" flags of status.
Definition: sortorder.h:90
QString name(StandardShortcut id)
@ SortMessagesBySubject
Sort the messages by subject.
Definition: sortorder.h:85
QString i18nc(const char *context, const char *text, const TYPE &arg...)
@ SortMessagesByDateTimeOfMostRecent
Sort the messages by date and time of the most recent message in subtree.
Definition: sortorder.h:81
GroupSorting
How to sort the groups If you add values here please look at the implementations of the enumerate* fu...
Definition: sortorder.h:53
GroupSorting groupSorting() const
Returns the GroupSorting.
Definition: sortorder.cpp:20
@ SortGroupsByDateTime
Sort groups by date/time of the group.
Definition: sortorder.h:61
static bool isValidMessageSorting(SortOrder::MessageSorting ms)
Returns true if the ms parameter specifies a valid MessageSorting option.
Definition: sortorder.cpp:263
@ SortMessagesBySenderOrReceiver
Sort the messages by sender or receiver.
Definition: sortorder.h:82
@ SortGroupsBySender
Sort groups by sender (makes sense only with GroupBySender)
Definition: sortorder.h:64
void readConfig(KConfigGroup &conf, const QString &storageId, bool *storageUsesPrivateSortOrder)
Reads the sort order from a config group.
Definition: sortorder.cpp:233
static QVector< QPair< QString, int > > enumerateMessageSortDirectionOptions(MessageSorting ms)
Enumerates the available message sorting directions for the specified MessageSorting option.
Definition: sortorder.cpp:80
Threading threading() const
Returns the current threading method.
Definition: aggregation.h:185
A set of aggregation options that can be applied to the MessageList::Model in a single shot.
Definition: aggregation.h:28
@ GroupByDateRange
Use smart (thread leader) date ranges ("Today","Yesterday","Last Week"...)
Definition: aggregation.h:39
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Jan 28 2023 04:09:56 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.