Forwardport r1147052:
[kdepim.git] / messagelist / pane.h
blob228c77a7e89104f09abfc4cd68b1de40977f4827
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;
53 class StorageModel;
55 /**
56 * This is the main MessageList panel for Akonadi applications.
57 * It contains multiple MessageList::Widget tabs
58 * so it can actually display multiple folder sets at once.
60 * When a KXmlGuiWindow is passed to setXmlGuiClient, the XMLGUI
61 * defined context menu @c akonadi_messagelist_contextmenu is
62 * used if available.
65 class MESSAGELIST_EXPORT Pane : public QTabWidget
67 Q_OBJECT
69 public:
70 /**
71 * Create a Pane wrapping the specified model and selection.
73 explicit Pane( QAbstractItemModel *model, QItemSelectionModel *selectionModel, QWidget *parent = 0 );
74 ~Pane();
77 virtual MessageList::StorageModel *createStorageModel( QAbstractItemModel *model, QItemSelectionModel *selectionModel, QObject *parent );
80 /**
81 * Sets the XML GUI client which the pane is used in.
83 * This is needed if you want to use the built-in context menu.
84 * Passing 0 is ok and will disable the builtin context menu.
86 * @param xmlGuiClient The KXMLGUIClient the view is used in.
88 void setXmlGuiClient( KXMLGUIClient *xmlGuiClient );
90 /**
91 * Returns the current message for the list as Akonadi::Item.
92 * May return an invalid Item if there is no current message or no current folder.
94 Akonadi::Item currentItem() const;
96 /**
97 * Returns the current message for the list as KMime::Message::Ptr.
98 * May return 0 if there is no current message or no current folder.
100 KMime::Message::Ptr currentMessage() const;
104 * Returns the currently selected KMime::Message::Ptr (bound to current StorageModel).
105 * The list may be empty if there are no selected messages or no StorageModel.
107 * If includeCollapsedChildren is true then the children of the selected but
108 * collapsed items are also added to the list.
110 * The returned list is guaranteed to be valid only until you return control
111 * to the main even loop. Don't store it for any longer. If you need to reference
112 * this set of messages at a later stage then take a look at createPersistentSet().
114 QList<KMime::Message::Ptr > selectionAsMessageList( bool includeCollapsedChildren = true ) const;
117 * Returns the currently selected Items (bound to current StorageModel).
118 * The list may be empty if there are no selected messages or no StorageModel.
120 * If includeCollapsedChildren is true then the children of the selected but
121 * collapsed items are also added to the list.
123 * The returned list is guaranteed to be valid only until you return control
124 * to the main even loop. Don't store it for any longer. If you need to reference
125 * this set of messages at a later stage then take a look at createPersistentSet().
127 QList<Akonadi::Item> selectionAsMessageItemList( bool includeCollapsedChildren = true ) const;
130 * Returns the Akonadi::Item bound to the current StorageModel that
131 * are part of the current thread. The current thread is the thread
132 * that contains currentMessageItem().
133 * The list may be empty if there is no currentMessageItem() or no StorageModel.
135 * The returned list is guaranteed to be valid only until you return control
136 * to the main even loop. Don't store it for any longer. If you need to reference
137 * this set of messages at a later stage then take a look at createPersistentSet().
139 QList<Akonadi::Item> currentThreadAsMessageList() const;
143 * Selects the next message item in the view.
145 * messageTypeFilter can be used to restrict the selection to only certain message types.
147 * existingSelectionBehaviour specifies how the existing selection
148 * is manipulated. It may be cleared, expanded or grown/shrinked.
150 * If centerItem is true then the specified item will be positioned
151 * at the center of the view, if possible.
152 * If loop is true then the "next" algorithm will restart from the beginning
153 * of the list if the end is reached, otherwise it will just stop returning false.
155 bool selectNextMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter,
156 MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
157 bool centerItem,
158 bool loop );
161 * Selects the previous message item in the view.
162 * If centerItem is true then the specified item will be positioned
163 * at the center of the view, if possible.
165 * messageTypeFilter can be used to restrict the selection to only certain message types.
167 * existingSelectionBehaviour specifies how the existing selection
168 * is manipulated. It may be cleared, expanded or grown/shrinked.
170 * If loop is true then the "previous" algorithm will restart from the end
171 * of the list if the beginning is reached, otherwise it will just stop returning false.
173 bool selectPreviousMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter,
174 MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour,
175 bool centerItem,
176 bool loop );
179 * Focuses the next message item in the view without actually selecting it.
181 * messageTypeFilter can be used to restrict the selection to only certain message types.
183 * If centerItem is true then the specified item will be positioned
184 * at the center of the view, if possible.
185 * If loop is true then the "next" algorithm will restart from the beginning
186 * of the list if the end is reached, otherwise it will just stop returning false.
188 bool focusNextMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop );
191 * Focuses the previous message item in the view without actually selecting it.
193 * messageTypeFilter can be used to restrict the selection to only certain message types.
195 * If centerItem is true then the specified item will be positioned
196 * at the center of the view, if possible.
197 * If loop is true then the "previous" algorithm will restart from the end
198 * of the list if the beginning is reached, otherwise it will just stop returning false.
200 bool focusPreviousMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop );
203 * Selects the currently focused message item. May do nothing if the
204 * focused message item is already selected (which is very likely).
205 * If centerItem is true then the specified item will be positioned
206 * at the center of the view, if possible.
208 void selectFocusedMessageItem( bool centerItem );
211 * Selects the first message item in the view that matches the specified Core::MessageTypeFilter.
212 * If centerItem is true then the specified item will be positioned
213 * at the center of the view, if possible.
215 * If the current view is already loaded then the request will
216 * be satisfied immediately (well... if an unread message exists at all).
217 * If the current view is still loading then the selection of the first
218 * message will be scheduled to be executed when loading terminates.
220 * So this function doesn't actually guarantee that an unread or new message
221 * was selected when the call returns. Take care :)
223 * The function returns true if a message was selected and false otherwise.
225 bool selectFirstMessageItem( MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem );
229 * If expand is true then it expands the current thread, otherwise
230 * collapses it.
232 void setCurrentThreadExpanded( bool expand );
235 * If expand is true then it expands all the threads, otherwise
236 * collapses them.
238 void setAllThreadsExpanded( bool expand );
241 * If expand is true then it expands all the groups (only the toplevel
242 * group item: inner threads are NOT expanded). If expand is false
243 * then it collapses all the groups. If no grouping is in effect
244 * then this function does nothing.
246 void setAllGroupsExpanded( bool expand );
249 * Sets the focus on the quick search line of the currently active tab.
251 void focusQuickSearch();
254 * Returns the KPIM::MessageStatus in the current quicksearch field.
256 KPIM::MessageStatus currentFilterStatus() const;
259 * Returns the search term in the current quicksearch field.
261 QString currentFilterSearchString() const;
265 * Returns true if the current Aggregation is threaded, false otherwise
266 * (or if there is no current Aggregation).
268 bool isThreaded() const;
271 * Fast function that determines if the selection is empty
273 bool selectionEmpty() const;
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.
280 * If includeCollapsedChildren is true then the children of the selected but
281 * collapsed items are also included in the stats
283 bool getSelectionStats( Akonadi::Item::List &selectedItems,
284 Akonadi::Item::List &selectedVisibleItems,
285 bool * allSelectedBelongToSameThread,
286 bool includeCollapsedChildren = true) const;
288 * Deletes the persistent set pointed by the specified reference.
289 * If the set does not exist anymore, nothing happens.
291 void deletePersistentSet( MessageList::Core::MessageItemSetReference ref );
295 * If bMark is true this function marks the messages as "about to be removed"
296 * so they appear dimmer and aren't selectable in the view.
297 * If bMark is false then this function clears the "about to be removed" state
298 * for the specified MessageItems.
300 void markMessageItemsAsAboutToBeRemoved( MessageList::Core::MessageItemSetReference ref, bool bMark );
303 * Return Akonadi::Item from messageItemReference
305 QList<Akonadi::Item> itemListFromPersistentSet( MessageList::Core::MessageItemSetReference ref );
309 * Return a persistent set from current selection
311 MessageList::Core::MessageItemSetReference selectionAsPersistentSet( bool includeCollapsedChildren = true ) const;
314 * Return a persistent set from current thread
316 MessageList::Core::MessageItemSetReference currentThreadAsPersistentSet() const;
318 * Sets the focus on the view of the currently active tab.
320 void focusView();
323 * Reloads global configuration and eventually reloads all the views.
325 void reloadGlobalConfiguration();
328 * Returns the QItemSelectionModel for the currently displayed tab.
330 QItemSelectionModel* currentItemSelectionModel();
333 * Sets the current folder to be displayed by this Pane.
334 * If the specified folder is already open in one of the tabs
335 * then that tab is made current (and no reloading happens).
336 * If the specified folder is not open yet then behaviour
337 * depends on the preferEmptyTab value as follows.
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).
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.
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..."
350 void setCurrentFolder(
351 const Akonadi::Collection &fld,
352 bool preferEmptyTab = false,
353 MessageList::Core::PreSelectionMode preSelectionMode = MessageList::Core::PreSelectLastSelected,
354 const QString &overrideLabel = QString()
356 public slots:
358 * Selects all the items in the current folder.
360 void selectAll();
363 * Add a new tab to the Pane and select it.
365 void createNewTab();
367 signals:
369 * Emitted when a message is selected (that is, single clicked and thus made current in the view)
370 * Note that this message CAN be 0 (when the current item is cleared, for example).
372 * This signal is emitted when a SINGLE message is selected in the view, probably
373 * by clicking on it or by simple keyboard navigation. When multiple items
374 * are selected at once (by shift+clicking, for example) then you will get
375 * this signal only for the last clicked message (or at all, if the last shift+clicked
376 * thing is a group header...). You should handle selection changed in this case.
378 void messageSelected( const Akonadi::Item &item );
381 * Emitted when a message is doubleclicked or activated by other input means
383 void messageActivated( const Akonadi::Item &item );
386 * Emitted when the selection in the view changes.
388 void selectionChanged();
391 * Emitted when a message wants its status to be changed
393 void messageStatusChangeRequest( const Akonadi::Item &item, const KPIM::MessageStatus &set, const KPIM::MessageStatus &clear );
396 * Emitted when a full search is requested.
398 void fullSearchRequest();
401 * Notify the outside when updating the status bar with a message
402 * could be useful
404 void statusMessage( const QString &message );
407 * Emitted when the current tab has changed. Clients using the
408 * selection model from currentItemSelectionModel() should
409 * ask for it again, as it may be different now.
411 void currentTabChanged();
414 private:
415 Q_PRIVATE_SLOT(d, void onSelectionChanged( const QItemSelection&, const QItemSelection& ))
416 Q_PRIVATE_SLOT(d, void onNewTabClicked())
417 Q_PRIVATE_SLOT(d, void onCloseTabClicked())
418 Q_PRIVATE_SLOT(d, void onCurrentTabChanged())
419 Q_PRIVATE_SLOT(d, void onTabContextMenuRequest( const QPoint& ))
420 Q_PRIVATE_SLOT(d, void updateTabControls())
422 class Private;
423 Private * const d;
426 } // namespace MessageList
428 #endif //!__MESSAGELIST_PANE_H__