Messagelib

pane.h
1/*
2 SPDX-FileCopyrightText: 2009 Kevin Ottens <ervin@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#pragma once
8
9#include "messagelist/enums.h"
10#include "messagelist/view.h"
11#include <QHash>
12#include <QList>
13#include <QTabWidget>
14
15#include "messagelist_export.h"
16#include <Akonadi/Collection>
17#include <Akonadi/Item>
18#include <KMime/Message>
19
20class KXMLGUIClient;
23class QItemSelection;
24
25namespace KPIM
26{
27class MessageStatus;
28}
29
30namespace MessageList
31{
32class Widget;
33class StorageModel;
34
35/**
36 * This is the main MessageList panel for Akonadi applications.
37 * It contains multiple MessageList::Widget tabs
38 * so it can actually display multiple folder sets at once.
39 *
40 * When a KXmlGuiWindow is passed to setXmlGuiClient, the XMLGUI
41 * defined context menu @c akonadi_messagelist_contextmenu is
42 * used if available.
43 *
44 */
45class MESSAGELIST_EXPORT Pane : public QTabWidget
46{
48
49public:
50 /**
51 * Create a Pane wrapping the specified model and selection.
52 */
53 explicit Pane(bool restoreSession, QAbstractItemModel *model, QItemSelectionModel *selectionModel, QWidget *parent = nullptr);
54 ~Pane() override;
55
56 virtual MessageList::StorageModel *createStorageModel(QAbstractItemModel *model, QItemSelectionModel *selectionModel, QObject *parent);
57
58 virtual void writeConfig(bool restoreSession);
59
60 /**
61 * Sets the XML GUI client which the pane is used in.
62 *
63 * This is needed if you want to use the built-in context menu.
64 * Passing 0 is ok and will disable the builtin context menu.
65 *
66 * @param xmlGuiClient The KXMLGUIClient the view is used in.
67 */
68 void setXmlGuiClient(KXMLGUIClient *xmlGuiClient);
69
70 /**
71 * Returns the current message for the list as Akonadi::Item.
72 * May return an invalid Item if there is no current message or no current folder.
73 */
74 [[nodiscard]] Akonadi::Item currentItem() const;
75
76 /**
77 * Returns the current message for the list as KMime::Message::Ptr.
78 * May return 0 if there is no current message or no current folder.
79 */
81
82 /**
83 * Returns the currently selected KMime::Message::Ptr (bound to current StorageModel).
84 * The list may be empty if there are no selected messages or no StorageModel.
85 *
86 * If includeCollapsedChildren is true then the children of the selected but
87 * collapsed items are also added to the list.
88 *
89 * The returned list is guaranteed to be valid only until you return control
90 * to the main even loop. Don't store it for any longer. If you need to reference
91 * this set of messages at a later stage then take a look at createPersistentSet().
92 */
93 [[nodiscard]] QList<KMime::Message::Ptr> selectionAsMessageList(bool includeCollapsedChildren = true) const;
94
95 /**
96 * Returns the currently selected Items (bound to current StorageModel).
97 * The list may be empty if there are no selected messages or no StorageModel.
98 *
99 * If includeCollapsedChildren is true then the children of the selected but
100 * collapsed items are also added to the list.
101 *
102 * The returned list is guaranteed to be valid only until you return control
103 * to the main even loop. Don't store it for any longer. If you need to reference
104 * this set of messages at a later stage then take a look at createPersistentSet().
105 */
106 [[nodiscard]] Akonadi::Item::List selectionAsMessageItemList(bool includeCollapsedChildren = true) const;
107
108 /**
109 * Returns the currently selected Items id(bound to current StorageModel).
110 * The list may be empty if there are no selected messages or no StorageModel.
111 *
112 * If includeCollapsedChildren is true then the children of the selected but
113 * collapsed items are also added to the list.
114 *
115 * The returned list is guaranteed to be valid only until you return control
116 * to the main even loop. Don't store it for any longer. If you need to reference
117 * this set of messages at a later stage then take a look at createPersistentSet().
118 */
119 [[nodiscard]] QList<qlonglong> selectionAsMessageItemListId(bool includeCollapsedChildren = true) const;
120
121 [[nodiscard]] QList<Akonadi::Item::Id> selectionAsListMessageId(bool includeCollapsedChildren = true) const;
122
123 /**
124 * Returns the Akonadi::Item bound to the current StorageModel that
125 * are part of the current thread. The current thread is the thread
126 * that contains currentMessageItem().
127 * The list may be empty if there is no currentMessageItem() or no StorageModel.
128 *
129 * The returned list is guaranteed to be valid only until you return control
130 * to the main even loop. Don't store it for any longer. If you need to reference
131 * this set of messages at a later stage then take a look at createPersistentSet().
132 */
134
135 /**
136 * Selects the next message item in the view.
137 *
138 * messageTypeFilter can be used to restrict the selection to only certain message types.
139 *
140 * existingSelectionBehaviour specifies how the existing selection
141 * is manipulated. It may be cleared, expanded or grown/shrunk.
142 *
143 * If centerItem is true then the specified item will be positioned
144 * at the center of the view, if possible.
145 * If loop is true then the "next" algorithm will restart from the beginning
146 * of the list if the end is reached, otherwise it will just stop returning false.
147 */
148 [[nodiscard]] bool selectNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter,
149 MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
150 bool centerItem,
151 bool loop);
152
153 /**
154 * Selects the previous message item in the view.
155 * If centerItem is true then the specified item will be positioned
156 * at the center of the view, if possible.
157 *
158 * messageTypeFilter can be used to restrict the selection to only certain message types.
159 *
160 * existingSelectionBehaviour specifies how the existing selection
161 * is manipulated. It may be cleared, expanded or grown/shrunk.
162 *
163 * If loop is true then the "previous" algorithm will restart from the end
164 * of the list if the beginning is reached, otherwise it will just stop returning false.
165 */
166 [[nodiscard]] bool selectPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter,
167 MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
168 bool centerItem,
169 bool loop);
170
171 /**
172 * Focuses the next message item in the view without actually selecting it.
173 *
174 * messageTypeFilter can be used to restrict the selection to only certain message types.
175 *
176 * If centerItem is true then the specified item will be positioned
177 * at the center of the view, if possible.
178 * If loop is true then the "next" algorithm will restart from the beginning
179 * of the list if the end is reached, otherwise it will just stop returning false.
180 */
181 [[nodiscard]] bool focusNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop);
182
183 /**
184 * Focuses the previous message item in the view without actually selecting it.
185 *
186 * messageTypeFilter can be used to restrict the selection to only certain message types.
187 *
188 * If centerItem is true then the specified item will be positioned
189 * at the center of the view, if possible.
190 * If loop is true then the "previous" algorithm will restart from the end
191 * of the list if the beginning is reached, otherwise it will just stop returning false.
192 */
193 [[nodiscard]] bool focusPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop);
194
195 /**
196 * Selects the currently focused message item. May do nothing if the
197 * focused message item is already selected (which is very likely).
198 * If centerItem is true then the specified item will be positioned
199 * at the center of the view, if possible.
200 */
201 void selectFocusedMessageItem(bool centerItem);
202
203 /**
204 * Selects the first message item in the view that matches the specified Core::MessageTypeFilter.
205 * If centerItem is true then the specified item will be positioned
206 * at the center of the view, if possible.
207 *
208 * If the current view is already loaded then the request will
209 * be satisfied immediately (well... if an unread message exists at all).
210 * If the current view is still loading then the selection of the first
211 * message will be scheduled to be executed when loading terminates.
212 *
213 * So this function doesn't actually guarantee that an unread or new message
214 * was selected when the call returns. Take care :)
215 *
216 * The function returns true if a message was selected and false otherwise.
217 */
218 [[nodiscard]] bool selectFirstMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem);
219
220 /**
221 * Selects the last message item in the view that matches the specified Core::MessageTypeFilter.
222 * If centerItem is true then the specified item will be positioned
223 * at the center of the view, if possible.
224 *
225 * The function returns true if a message was selected and false otherwise.
226 */
227 [[nodiscard]] bool selectLastMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem);
228
229 /**
230 * If expand is true then it expands the current thread, otherwise
231 * collapses it.
232 */
233 void setCurrentThreadExpanded(bool expand);
234
235 /**
236 * If expand is true then it expands all the threads, otherwise
237 * collapses them.
238 */
239 void setAllThreadsExpanded(bool expand);
240
241 /**
242 * If expand is true then it expands all the groups (only the toplevel
243 * group item: inner threads are NOT expanded). If expand is false
244 * then it collapses all the groups. If no grouping is in effect
245 * then this function does nothing.
246 */
247 void setAllGroupsExpanded(bool expand);
248
249 /**
250 * Sets the focus on the quick search line of the currently active tab.
251 */
252 void focusQuickSearch(const QString &selectedText = QString());
253
254 /**
255 * Returns the Akonadi::MessageStatus in the current quicksearch field.
256 */
258
259 /**
260 * Returns the search term in the current quicksearch field.
261 */
262 [[nodiscard]] QString currentFilterSearchString() const;
263
264 /**
265 * Returns true if the current Aggregation is threaded, false otherwise
266 * (or if there is no current Aggregation).
267 */
268 [[nodiscard]] bool isThreaded() const;
269
270 /**
271 * Fast function that determines if the selection is empty
272 */
273 [[nodiscard]] bool selectionEmpty() const;
274 /**
275 * Fills the lists of the selected message serial numbers and of the selected+visible ones.
276 * Returns true if the returned stats are valid (there is a current folder after all)
277 * and false otherwise. This is called by KMMainWidget in a single place so we optimize by
278 * making it a single sweep on the selection.
279 *
280 * If includeCollapsedChildren is true then the children of the selected but
281 * collapsed items are also included in the stats
282 */
283 [[nodiscard]] bool getSelectionStats(Akonadi::Item::List &selectedItems,
284 Akonadi::Item::List &selectedVisibleItems,
285 bool *allSelectedBelongToSameThread,
286 bool includeCollapsedChildren = true) const;
287 /**
288 * Deletes the persistent set pointed by the specified reference.
289 * If the set does not exist anymore, nothing happens.
290 */
291 void deletePersistentSet(MessageList::Core::MessageItemSetReference ref);
292
293 /**
294 * If bMark is true this function marks the messages as "about to be removed"
295 * so they appear dimmer and aren't selectable in the view.
296 * If bMark is false then this function clears the "about to be removed" state
297 * for the specified MessageItems.
298 */
299 void markMessageItemsAsAboutToBeRemoved(MessageList::Core::MessageItemSetReference ref, bool bMark);
300
301 /**
302 * Return Akonadi::Item from messageItemReference
303 */
304 [[nodiscard]] Akonadi::Item::List itemListFromPersistentSet(MessageList::Core::MessageItemSetReference ref);
305
306 /**
307 * Return a persistent set from current selection
308 */
309 [[nodiscard]] MessageList::Core::MessageItemSetReference selectionAsPersistentSet(bool includeCollapsedChildren = true) const;
310
311 /**
312 * Return a persistent set from current thread
313 */
314 [[nodiscard]] MessageList::Core::MessageItemSetReference currentThreadAsPersistentSet() const;
315 /**
316 * Sets the focus on the view of the currently active tab.
317 */
318 void focusView();
319
320 /**
321 * Reloads global configuration and eventually reloads all the views.
322 */
324
325 /**
326 * Returns the QItemSelectionModel for the currently displayed tab.
327 */
329
330 /**
331 * Sets the current folder to be displayed by this Pane.
332 * If the specified folder is already open in one of the tabs
333 * then that tab is made current (and no reloading happens).
334 * If the specified folder is not open yet then behaviour
335 * depends on the preferEmptyTab value as follows.
336 *
337 * @param etmIndex the index for the collection in the EntityTreeModel (source model)
338 *
339 * If preferEmptyTab is set to false then the (new) folder is loaded
340 * in the current tab. If preferEmptyTab is set to true then the (new) folder is
341 * loaded in the first empty tab (or a new one if there are no empty ones).
342 *
343 * Pre-selection is the action of automatically selecting a message just after the folder
344 * has finished loading. See Model::setStorageModel() for more information.
345 *
346 * If overrideLabel is not empty then it's used as the tab text for the
347 * specified folder. This is useful to signal a particular folder state
348 * like "loading..."
349 */
351 const QModelIndex &etmIndex,
352 bool preferEmptyTab = false,
353 MessageList::Core::PreSelectionMode preSelectionMode = MessageList::Core::PreSelectLastSelected,
354 const QString &overrideLabel = QString());
355
356 void resetModelStorage();
357
358 void setPreferEmptyTab(bool emptyTab);
359
360 void updateTabIconText(const Akonadi::Collection &collection, const QString &label, const QIcon &icon);
361
362 void saveCurrentSelection();
363
364 void updateTagComboBox();
365
366 bool searchEditHasFocus() const;
367
368 void setQuickSearchClickMessage(const QString &msg);
369
370 void populateStatusFilterCombo();
371
372 Core::SearchMessageByButtons::SearchOptions currentOptions() const;
373
374 [[nodiscard]] Akonadi::Collection currentFolder() const;
375
376 [[nodiscard]] QList<MessageList::Core::SearchLineCommand::SearchLineInfo> searchLineCommands() const;
377public Q_SLOTS:
378 /**
379 * Selects all the items in the current folder.
380 */
381 void selectAll();
382
383 /**
384 * Add a new tab to the Pane and select it.
385 */
387
388 void sortOrderMenuAboutToShow();
389
390 void aggregationMenuAboutToShow();
391
392 void themeMenuAboutToShow();
393
395 /**
396 * Emitted when a message is selected (that is, single clicked and thus made current in the view)
397 * Note that this message CAN be 0 (when the current item is cleared, for example).
398 *
399 * This signal is emitted when a SINGLE message is selected in the view, probably
400 * by clicking on it or by simple keyboard navigation. When multiple items
401 * are selected at once (by shift+clicking, for example) then you will get
402 * this signal only for the last clicked message (or at all, if the last shift+clicked
403 * thing is a group header...). You should handle selection changed in this case.
404 */
406
407 /**
408 * Emitted when a message is doubleclicked or activated by other input means
409 */
411
412 /**
413 * Emitted when the selection in the view changes.
414 */
416
417 /**
418 * Emitted when a message wants its status to be changed
419 */
421
422 /**
423 * Notify the outside when updating the status bar with a message
424 * could be useful
425 */
426 void statusMessage(const QString &message);
427
428 /**
429 * Emitted when the current tab has changed. Clients using the
430 * selection model from currentItemSelectionModel() should
431 * ask for it again, as it may be different now.
432 */
434
435 void forceLostFocus();
436
437private:
438 MESSAGELIST_NO_EXPORT void restoreHeaderSettings(int index, bool restoreSession);
439 MESSAGELIST_NO_EXPORT void readConfig(bool restoreSession);
440
441 bool eventFilter(QObject *obj, QEvent *event) override;
442
443 class PanePrivate;
444 std::unique_ptr<PanePrivate> const d;
445};
446} // namespace MessageList
QList< Item > List
QSharedPointer< Message > Ptr
Pane(bool restoreSession, QAbstractItemModel *model, QItemSelectionModel *selectionModel, QWidget *parent=nullptr)
Create a Pane wrapping the specified model and selection.
Definition pane.cpp:94
void messageActivated(const Akonadi::Item &item)
Emitted when a message is doubleclicked or activated by other input means.
QString currentFilterSearchString() const
Returns the search term in the current quicksearch field.
Definition pane.cpp:1016
bool getSelectionStats(Akonadi::Item::List &selectedItems, Akonadi::Item::List &selectedVisibleItems, bool *allSelectedBelongToSameThread, bool includeCollapsedChildren=true) const
Fills the lists of the selected message serial numbers and of the selected+visible ones.
Definition pane.cpp:1052
bool selectLastMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem)
Selects the last message item in the view that matches the specified Core::MessageTypeFilter.
Definition pane.cpp:405
QItemSelectionModel * currentItemSelectionModel()
Returns the QItemSelectionModel for the currently displayed tab.
Definition pane.cpp:1099
bool focusNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop)
Focuses the next message item in the view without actually selecting it.
Definition pane.cpp:347
bool selectPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop)
Selects the previous message item in the view.
Definition pane.cpp:329
Akonadi::Item::List itemListFromPersistentSet(MessageList::Core::MessageItemSetReference ref)
Return Akonadi::Item from messageItemReference.
Definition pane.cpp:973
MessageList::Core::MessageItemSetReference selectionAsPersistentSet(bool includeCollapsedChildren=true) const
Return a persistent set from current selection.
Definition pane.cpp:1065
QList< qlonglong > selectionAsMessageItemListId(bool includeCollapsedChildren=true) const
Returns the currently selected Items id(bound to current StorageModel).
Definition pane.cpp:955
void focusQuickSearch(const QString &selectedText=QString())
Sets the focus on the quick search line of the currently active tab.
Definition pane.cpp:472
void messageSelected(const Akonadi::Item &item)
Emitted when a message is selected (that is, single clicked and thus made current in the view) Note t...
void setCurrentThreadExpanded(bool expand)
If expand is true then it expands the current thread, otherwise collapses it.
Definition pane.cpp:433
QItemSelectionModel * createNewTab()
Add a new tab to the Pane and select it.
Definition pane.cpp:807
bool selectionEmpty() const
Fast function that determines if the selection is empty.
Definition pane.cpp:1043
void deletePersistentSet(MessageList::Core::MessageItemSetReference ref)
Deletes the persistent set pointed by the specified reference.
Definition pane.cpp:982
QList< KMime::Message::Ptr > selectionAsMessageList(bool includeCollapsedChildren=true) const
Returns the currently selected KMime::Message::Ptr (bound to current StorageModel).
Definition pane.cpp:928
void reloadGlobalConfiguration()
Reloads global configuration and eventually reloads all the views.
Definition pane.cpp:1094
void markMessageItemsAsAboutToBeRemoved(MessageList::Core::MessageItemSetReference ref, bool bMark)
If bMark is true this function marks the messages as "about to be removed" so they appear dimmer and ...
Definition pane.cpp:990
void selectAll()
Selects all the items in the current folder.
Definition pane.cpp:420
void setCurrentFolder(const Akonadi::Collection &fld, const QModelIndex &etmIndex, bool preferEmptyTab=false, MessageList::Core::PreSelectionMode preSelectionMode=MessageList::Core::PreSelectLastSelected, const QString &overrideLabel=QString())
Sets the current folder to be displayed by this Pane.
Definition pane.cpp:772
MessageList::Core::MessageItemSetReference currentThreadAsPersistentSet() const
Return a persistent set from current thread.
Definition pane.cpp:1074
void setAllThreadsExpanded(bool expand)
If expand is true then it expands all the threads, otherwise collapses them.
Definition pane.cpp:446
void selectionChanged()
Emitted when the selection in the view changes.
void currentTabChanged()
Emitted when the current tab has changed.
bool isThreaded() const
Returns true if the current Aggregation is threaded, false otherwise (or if there is no current Aggre...
Definition pane.cpp:1034
Akonadi::Item currentItem() const
Returns the current message for the list as Akonadi::Item.
Definition pane.cpp:906
bool selectNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop)
Selects the next message item in the view.
Definition pane.cpp:311
void statusMessage(const QString &message)
Notify the outside when updating the status bar with a message could be useful.
void setXmlGuiClient(KXMLGUIClient *xmlGuiClient)
Sets the XML GUI client which the pane is used in.
Definition pane.cpp:196
bool focusPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop)
Focuses the previous message item in the view without actually selecting it.
Definition pane.cpp:362
void focusView()
Sets the focus on the view of the currently active tab.
Definition pane.cpp:1083
void selectFocusedMessageItem(bool centerItem)
Selects the currently focused message item.
Definition pane.cpp:377
KMime::Message::Ptr currentMessage() const
Returns the current message for the list as KMime::Message::Ptr.
Definition pane.cpp:917
Akonadi::Item::List currentThreadAsMessageList() const
Returns the Akonadi::Item bound to the current StorageModel that are part of the current thread.
Definition pane.cpp:964
void setAllGroupsExpanded(bool expand)
If expand is true then it expands all the groups (only the toplevel group item: inner threads are NOT...
Definition pane.cpp:459
bool selectFirstMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem)
Selects the first message item in the view that matches the specified Core::MessageTypeFilter.
Definition pane.cpp:390
void messageStatusChangeRequest(const Akonadi::Item &item, const Akonadi::MessageStatus &set, const Akonadi::MessageStatus &clear)
Emitted when a message wants its status to be changed.
QList< Akonadi::MessageStatus > currentFilterStatus() const
Returns the Akonadi::MessageStatus in the current quicksearch field.
Definition pane.cpp:998
Akonadi::Item::List selectionAsMessageItemList(bool includeCollapsedChildren=true) const
Returns the currently selected Items (bound to current StorageModel).
Definition pane.cpp:937
The Akonadi specific implementation of the Core::StorageModel.
The Akonadi specific implementation of the Core::Widget.
Definition widget.h:33
ExistingSelectionBehaviour
This enum is used in the view message selection functions (for instance View::selectNextMessage())
PreSelectionMode
Pre-selection is the action of automatically selecting a message just after the folder has finished l...
MessageTypeFilter
This enum is used in the view message selection functions (for instance View::nextMessageItem()).
QObject(QObject *parent)
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
QObject * parent() const const
QTabWidget(QWidget *parent)
void clear()
virtual bool event(QEvent *ev) override
QWidget(QWidget *parent, Qt::WindowFlags f)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 21 2025 11:47:09 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.