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>
33 class QAbstractItemModel
;
34 class QAbstractProxyModel
;
35 class QItemSelectionModel
;
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
65 class MESSAGELIST_EXPORT Pane
: public QTabWidget
71 * Create a Pane wrapping the specified model and selection.
73 explicit Pane( QAbstractItemModel
*model
, QItemSelectionModel
*selectionModel
, QWidget
*parent
= 0 );
77 virtual MessageList::StorageModel
*createStorageModel( QAbstractItemModel
*model
, QItemSelectionModel
*selectionModel
, QObject
*parent
);
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
);
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;
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
,
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
,
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
232 void setCurrentThreadExpanded( bool expand
);
235 * If expand is true then it expands all the threads, otherwise
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.
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
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()
358 * Selects all the items in the current folder.
363 * Add a new tab to the Pane and select it.
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
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();
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())
426 } // namespace MessageList
428 #endif //!__MESSAGELIST_PANE_H__