Allow specializations to decide when re-indexing is necessary.
[kdepim.git] / messagelist / pane.h
blobe686109bee2091588fa9211cbf25317e502eafc4
1 /*
2 Copyright (c) 2009 Kevin Ottens <ervin@kde.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #ifndef __MESSAGELIST_PANE_H__
20 #define __MESSAGELIST_PANE_H__
22 #include <messagelist/core/enums.h>
23 #include <messagelist/core/view.h>
24 #include <QtCore/QHash>
25 #include <QtGui/QTabWidget>
27 #include <kmime/kmime_message.h>
28 #include <akonadi/collection.h>
29 #include <akonadi/item.h>
30 #include <messagelist/messagelist_export.h>
32 class KXMLGUIClient;
33 class QAbstractItemModel;
34 class QAbstractProxyModel;
35 class QItemSelectionModel;
36 class QItemSelection;
37 class QToolButton;
39 namespace KPIM
41 class MessageStatus;
44 namespace Akonadi
46 class Item;
49 namespace MessageList
52 class Widget;
54 /**
55 * This is the main MessageList panel for Akonadi applications.
56 * It contains multiple MessageList::Widget tabs
57 * so it can actually display multiple folder sets at once.
59 * When a KXmlGuiWindow is passed to setXmlGuiClient, the XMLGUI
60 * defined context menu @c akonadi_messagelist_contextmenu is
61 * used if available.
64 class MESSAGELIST_EXPORT Pane : public QTabWidget
66 Q_OBJECT
68 public:
69 /**
70 * Create a Pane wrapping the specified model and selection.
72 explicit Pane( QAbstractItemModel *model, QItemSelectionModel *selectionModel, QWidget *parent = 0 );
73 ~Pane();
75 /**
76 * Sets the XML GUI client which the pane is used in.
78 * This is needed if you want to use the built-in context menu.
79 * Passing 0 is ok and will disable the builtin context menu.
81 * @param xmlGuiClient The KXMLGUIClient the view is used in.
83 void setXmlGuiClient( KXMLGUIClient *xmlGuiClient );
85 /**
86 * Returns the current message for the list as Akonadi::Item.
87 * May return an invalid Item if there is no current message or no current folder.
89 Akonadi::Item currentItem() const;
91 /**
92 * Returns the current message for the list as KMime::Message::Ptr.
93 * May return 0 if there is no current message or no current folder.
95 KMime::Message::Ptr currentMessage() const;
98 /**
99 * Returns the currently selected KMime::Message::Ptr (bound to current StorageModel).
100 * The list may be empty if there are no selected messages or no StorageModel.
102 * If includeCollapsedChildren is true then the children of the selected but
103 * collapsed items are also added to the list.
105 * The returned list is guaranteed to be valid only until you return control
106 * to the main even loop. Don't store it for any longer. If you need to reference
107 * this set of messages at a later stage then take a look at createPersistentSet().
109 QList<KMime::Message::Ptr > selectionAsMessageList( bool includeCollapsedChildren = true ) const;
112 * Returns the currently selected Items (bound to current StorageModel).
113 * The list may be empty if there are no selected messages or no StorageModel.
115 * If includeCollapsedChildren is true then the children of the selected but
116 * collapsed items are also added to the list.
118 * The returned list is guaranteed to be valid only until you return control
119 * to the main even loop. Don't store it for any longer. If you need to reference
120 * this set of messages at a later stage then take a look at createPersistentSet().
122 QList<Akonadi::Item> selectionAsMessageItemList( bool includeCollapsedChildren = true ) const;
125 * Returns the Akonadi::Item bound to the current StorageModel that
126 * are part of the current thread. The current thread is the thread
127 * that contains currentMessageItem().
128 * The list may be empty if there is no currentMessageItem() or no StorageModel.
130 * The returned list is guaranteed to be valid only until you return control
131 * to the main even loop. Don't store it for any longer. If you need to reference
132 * this set of messages at a later stage then take a look at createPersistentSet().
134 QList<Akonadi::Item> currentThreadAsMessageList() const;
138 * Selects the next message item in the view.
140 * messageTypeFilter can be used to restrict the selection to only certain message types.
142 * existingSelectionBehaviour specifies how the existing selection
143 * is manipulated. It may be cleared, expanded or grown/shrinked.
145 * If centerItem is true then the specified item will be positioned
146 * at the center of the view, if possible.
147 * If loop is true then the "next" algorithm will restart from the beginning
148 * of the list if the end is reached, otherwise it will just stop returning false.
150 bool selectNextMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter,
151 MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
152 bool centerItem,
153 bool loop );
156 * Selects the previous message item in the view.
157 * If centerItem is true then the specified item will be positioned
158 * at the center of the view, if possible.
160 * messageTypeFilter can be used to restrict the selection to only certain message types.
162 * existingSelectionBehaviour specifies how the existing selection
163 * is manipulated. It may be cleared, expanded or grown/shrinked.
165 * If loop is true then the "previous" algorithm will restart from the end
166 * of the list if the beginning is reached, otherwise it will just stop returning false.
168 bool selectPreviousMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter,
169 MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
170 bool centerItem,
171 bool loop );
174 * Focuses the next message item in the view without actually selecting it.
176 * messageTypeFilter can be used to restrict the selection to only certain message types.
178 * If centerItem is true then the specified item will be positioned
179 * at the center of the view, if possible.
180 * If loop is true then the "next" algorithm will restart from the beginning
181 * of the list if the end is reached, otherwise it will just stop returning false.
183 bool focusNextMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop );
186 * Focuses the previous message item in the view without actually selecting it.
188 * messageTypeFilter can be used to restrict the selection to only certain message types.
190 * If centerItem is true then the specified item will be positioned
191 * at the center of the view, if possible.
192 * If loop is true then the "previous" algorithm will restart from the end
193 * of the list if the beginning is reached, otherwise it will just stop returning false.
195 bool focusPreviousMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop );
198 * Selects the currently focused message item. May do nothing if the
199 * focused message item is already selected (which is very likely).
200 * If centerItem is true then the specified item will be positioned
201 * at the center of the view, if possible.
203 void selectFocusedMessageItem( bool centerItem );
206 * Selects the first message item in the view that matches the specified Core::MessageTypeFilter.
207 * If centerItem is true then the specified item will be positioned
208 * at the center of the view, if possible.
210 * If the current view is already loaded then the request will
211 * be satisfied immediately (well... if an unread message exists at all).
212 * If the current view is still loading then the selection of the first
213 * message will be scheduled to be executed when loading terminates.
215 * So this function doesn't actually guarantee that an unread or new message
216 * was selected when the call returns. Take care :)
218 * The function returns true if a message was selected and false otherwise.
220 bool selectFirstMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem );
224 * If expand is true then it expands the current thread, otherwise
225 * collapses it.
227 void setCurrentThreadExpanded( bool expand );
230 * If expand is true then it expands all the threads, otherwise
231 * collapses them.
233 void setAllThreadsExpanded( bool expand );
236 * If expand is true then it expands all the groups (only the toplevel
237 * group item: inner threads are NOT expanded). If expand is false
238 * then it collapses all the groups. If no grouping is in effect
239 * then this function does nothing.
241 void setAllGroupsExpanded( bool expand );
244 * Sets the focus on the quick search line of the currently active tab.
246 void focusQuickSearch();
249 * Returns the KPIM::MessageStatus in the current quicksearch field.
251 KPIM::MessageStatus currentFilterStatus() const;
254 * Returns the search term in the current quicksearch field.
256 QString currentFilterSearchString() const;
260 * Returns true if the current Aggregation is threaded, false otherwise
261 * (or if there is no current Aggregation).
263 bool isThreaded() const;
266 * Fast function that determines if the selection is empty
268 bool selectionEmpty() const;
270 * Fills the lists of the selected message serial numbers and of the selected+visible ones.
271 * Returns true if the returned stats are valid (there is a current folder after all)
272 * and false otherwise. This is called by KMMainWidget in a single place so we optimize by
273 * making it a single sweep on the selection.
275 * If includeCollapsedChildren is true then the children of the selected but
276 * collapsed items are also included in the stats
278 bool getSelectionStats( Akonadi::Item::List &selectedItems,
279 Akonadi::Item::List &selectedVisibleItems,
280 bool * allSelectedBelongToSameThread,
281 bool includeCollapsedChildren = true) const;
283 * Deletes the persistent set pointed by the specified reference.
284 * If the set does not exist anymore, nothing happens.
286 void deletePersistentSet( MessageList::Core::MessageItemSetReference ref );
290 * If bMark is true this function marks the messages as "about to be removed"
291 * so they appear dimmer and aren't selectable in the view.
292 * If bMark is false then this function clears the "about to be removed" state
293 * for the specified MessageItems.
295 void markMessageItemsAsAboutToBeRemoved( MessageList::Core::MessageItemSetReference ref, bool bMark );
298 * Return Akonadi::Item from messageItemReference
300 QList<Akonadi::Item> itemListFromPersistentSet( MessageList::Core::MessageItemSetReference ref );
304 * Return a persistent set from current selection
306 MessageList::Core::MessageItemSetReference selectionAsPersistentSet( bool includeCollapsedChildren = true ) const;
309 * Return a persistent set from current thread
311 MessageList::Core::MessageItemSetReference currentThreadAsPersistentSet() const;
313 * Sets the focus on the view of the currently active tab.
315 void focusView();
318 * Reloads global configuration and eventually reloads all the views.
320 void reloadGlobalConfiguration();
323 * Sets the current folder to be displayed by this Pane.
324 * If the specified folder is already open in one of the tabs
325 * then that tab is made current (and no reloading happens).
326 * If the specified folder is not open yet then behaviour
327 * depends on the preferEmptyTab value as follows.
329 * If preferEmptyTab is set to false then the (new) folder is loaded
330 * in the current tab. If preferEmptyTab is set to true then the (new) folder is
331 * loaded in the first empty tab (or a new one if there are no empty ones).
333 * Pre-selection is the action of automatically selecting a message just after the folder
334 * has finished loading. See Model::setStorageModel() for more information.
336 * If overrideLabel is not empty then it's used as the tab text for the
337 * specified folder. This is useful to signal a particular folder state
338 * like "loading..."
340 void setCurrentFolder(
341 const Akonadi::Collection &fld,
342 bool preferEmptyTab = false,
343 MessageList::Core::PreSelectionMode preSelectionMode = MessageList::Core::PreSelectLastSelected,
344 const QString &overrideLabel = QString()
346 public slots:
348 * Selects all the items in the current folder.
350 void selectAll();
353 * Add a new tab to the Pane and select it.
355 void createNewTab();
357 signals:
359 * Emitted when a message is selected (that is, single clicked and thus made current in the view)
360 * Note that this message CAN be 0 (when the current item is cleared, for example).
362 * This signal is emitted when a SINGLE message is selected in the view, probably
363 * by clicking on it or by simple keyboard navigation. When multiple items
364 * are selected at once (by shift+clicking, for example) then you will get
365 * this signal only for the last clicked message (or at all, if the last shift+clicked
366 * thing is a group header...). You should handle selection changed in this case.
368 void messageSelected( const Akonadi::Item &item );
371 * Emitted when a message is doubleclicked or activated by other input means
373 void messageActivated( const Akonadi::Item &item );
376 * Emitted when the selection in the view changes.
378 void selectionChanged();
381 * Emitted when a message wants its status to be changed
383 void messageStatusChangeRequest( const Akonadi::Item &item, const KPIM::MessageStatus &set, const KPIM::MessageStatus &clear );
386 * Emitted when a full search is requested.
388 void fullSearchRequest();
391 * Notify the outside when updating the status bar with a message
392 * could be useful
394 void statusMessage( const QString &message );
397 private:
398 Q_PRIVATE_SLOT(d, void onSelectionChanged( const QItemSelection&, const QItemSelection& ))
399 Q_PRIVATE_SLOT(d, void onNewTabClicked())
400 Q_PRIVATE_SLOT(d, void onCloseTabClicked())
401 Q_PRIVATE_SLOT(d, void onCurrentTabChanged())
402 Q_PRIVATE_SLOT(d, void onTabContextMenuRequest( const QPoint& ))
403 Q_PRIVATE_SLOT(d, void updateTabControls())
405 class Private;
406 Private * const d;
409 } // namespace MessageList
411 #endif //!__MESSAGELIST_PANE_H__