diff --git a/messagelist/src/core/widgetbase.h b/messagelist/src/core/widgetbase.h index 5008708a..6fbb6f85 100644 --- a/messagelist/src/core/widgetbase.h +++ b/messagelist/src/core/widgetbase.h @@ -1,269 +1,269 @@ /****************************************************************************** * * Copyright 2008 Szymon Tomasz Stefanek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * *******************************************************************************/ #ifndef MESSAGELIST_CORE_WIDGETBASE_H #define MESSAGELIST_CORE_WIDGETBASE_H #include #include #include -#include -#include +#include +#include class QLineEdit; class QActionGroup; class KComboBox; class QMenu; namespace Akonadi { class Collection; class MessageStatus; } namespace MessageList { namespace Core { class GroupHeaderItem; class MessageItem; class StorageModel; class View; /** * Provides a widget which has the messagelist and the most important helper widgets, * like the search line and the comboboxes for changing status filtering, aggregation etc. */ class Widget : public QWidget { friend class View; Q_OBJECT public: explicit Widget(QWidget *parent); ~Widget(); /** * Sets the storage model for this Widget. * * Pre-selection is the action of automatically selecting a message just after the folder * has finished loading. See Model::setStorageModel() for more information. */ void setStorageModel(StorageModel *storageModel, PreSelectionMode preSelectionMode = PreSelectLastSelected); /** * Returns the StorageModel currently set. May be nullptr. */ StorageModel *storageModel() const; /** * Returns the search line of this widget. Can be nullptr if the quick search * is disabled in the global configuration. */ QLineEdit *quickSearch() const; /** * Returns the View attached to this Widget. Never nullptr. */ View *view() const; /** * Returns the current MessageItem in the current folder. * May return nullptr if there is no current message or no current folder. */ Core::MessageItem *currentMessageItem() const; /** * Returns the Akonadi::MessageStatus in the current quicksearch field. */ QList currentFilterStatus() const; /** * Returns the search term in the current quicksearch field. */ QString currentFilterSearchString() const; /** * Returns the id of the MessageItem::Tag currently set in the quicksearch field. */ QString currentFilterTagId() const; /** * Sets the focus on the quick search line of the currently active tab. */ void focusQuickSearch(const QString &selectedText); /** * Returns true if the current Aggregation is threaded, false otherwise * (or if there is no current Aggregation). */ bool isThreaded() const; /** * Fast function that determines if the selection is empty */ bool selectionEmpty() const; /** * Sets the current folder. */ void setCurrentFolder(const Akonadi::Collection &collection); Akonadi::Collection currentFolder() const; void saveCurrentSelection(); bool searchEditHasFocus() const; void sortOrderMenuAboutToShow(QMenu *menu); void themeMenuAboutToShow(QMenu *menu); void aggregationMenuAboutToShow(QMenu *menu); MessageList::Core::QuickSearchLine::SearchOptions currentOptions() const; public Q_SLOTS: /** * This is called to setup the status filter's KComboBox. */ void populateStatusFilterCombo(); /** * Shows or hides the quicksearch field, the filter combobox and the toolbutton for advanced search. */ void changeQuicksearchVisibility(bool); protected: /** * Called when the "Message Status/Tag" filter menu is opened by the user. * You may override this function in order to add some "custom tag" entries * to the menu. The entries should be placed in a QActionGroup which should be returned * to the caller. The QAction objects associated to the entries should have * the string id of the tag set as data() and the tag icon set as icon(). * The default implementation does nothing. * * Once the tag retrieval is complete call setCurrentStatusFilterItem() */ virtual void fillMessageTagCombo(); void addMessageTagItem(const QPixmap &, const QString &, const QVariant &); /** * Must be called by fillMessageTagCombo() */ void setCurrentStatusFilterItem(); /** * This is called by View when a message is single-clicked (thus selected and made current) */ virtual void viewMessageSelected(MessageItem *msg); /** * This is called by View when a message is double-clicked or activated by other input means */ virtual void viewMessageActivated(MessageItem *msg); /** * This is called by View when selection changes. */ virtual void viewSelectionChanged(); /** * This is called by View when a message is right clicked. */ virtual void viewMessageListContextPopupRequest(const QList< MessageItem * > &selectedItems, const QPoint &globalPos); /** * This is called by View when a group header is right clicked. */ virtual void viewGroupHeaderContextPopupRequest(GroupHeaderItem *group, const QPoint &globalPos); /** * This is called by View when a drag enter event is received */ virtual void viewDragEnterEvent(QDragEnterEvent *e); /** * This is called by View when a drag move event is received */ virtual void viewDragMoveEvent(QDragMoveEvent *e); /** * This is called by View when a drop event is received */ virtual void viewDropEvent(QDropEvent *e); /** * This is called by View when a drag can possibly be started */ virtual void viewStartDragRequest(); /** * This is called by View when a message item is manipulated by the user * in a way that it's status should change. (e.g, by clicking on a status icon, for example). */ virtual void viewMessageStatusChangeRequest(MessageItem *msg, Akonadi::MessageStatus set, Akonadi::MessageStatus clear); void tagIdSelected(const QVariant &data); Q_SIGNALS: /** * Notify the outside when updating the status bar with a message * could be useful */ void statusMessage(const QString &message); protected Q_SLOTS: /** * This is called by Manager when the option sets stored within have changed. */ void aggregationsChanged(); /** * This is called by Manager when the option sets stored within have changed. */ void themesChanged(); void themeMenuAboutToShow(); void aggregationMenuAboutToShow(); void themeSelected(bool); void configureThemes(); void setPrivateSortOrderForStorage(); void aggregationSelected(bool); void statusSelected(int index); void searchEditTextEdited(); void searchTimerFired(); void searchEditClearButtonClicked(); void sortOrderMenuAboutToShow(); void messageSortingSelected(QAction *action); void messageSortDirectionSelected(QAction *action); void groupSortingSelected(QAction *action); void groupSortDirectionSelected(QAction *action); void resetFilter(); /** * Handles header section clicks switching the Aggregation MessageSorting on-the-fly. */ void slotViewHeaderSectionClicked(int logicalIndex); void slotStatusButtonsClicked(); private: class Private; Private *const d; }; } // namespace Core } // namespace MessageList #endif //!__MESSAGELIST_CORE_WIDGET_H diff --git a/messagelist/src/widget.h b/messagelist/src/widget.h index 153471dc..1febd5e7 100644 --- a/messagelist/src/widget.h +++ b/messagelist/src/widget.h @@ -1,413 +1,413 @@ /* Copyright (c) 2009 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MESSAGELIST_WIDGET_H #define MESSAGELIST_WIDGET_H #include #include #include -#include +#include #include #include #include #include class KXMLGUIClient; class QWidget; namespace MessageList { /** * The Akonadi specific implementation of the Core::Widget. * * When a KXmlGuiWindow is passed to setXmlGuiClient, the XMLGUI * defined context menu @c akonadi_messagelist_contextmenu is * used if available. * */ class MESSAGELIST_EXPORT Widget : public MessageList::Core::Widget { Q_OBJECT public: /** * Create a new message list widget. */ explicit Widget(QWidget *parent); ~Widget() override; /** * Sets the XML GUI client which the view is used in. * * This is needed if you want to use the built-in context menu. * Passing 0 is ok and will disable the builtin context menu. * * @param xmlGuiClient The KXMLGUIClient the view is used in. */ void setXmlGuiClient(KXMLGUIClient *xmlGuiClient); /** * Returns the current message for the list as Akonadi::Item. * May return an invalid Item if there is no current message or no current folder. */ Akonadi::Item currentItem() const; /** * Returns the current message for the list as KMime::Message::Ptr. * May return 0 if there is no current message or no current folder. */ KMime::Message::Ptr currentMessage() const; /** * Returns true if this drag can be accepted by the underlying view */ bool canAcceptDrag(const QDropEvent *e); /** * Selects the next message item in the view. * * messageTypeFilter can be used to restrict the selection to only certain message types. * * existingSelectionBehaviour specifies how the existing selection * is manipulated. It may be cleared, expanded or grown/shrinked. * * If centerItem is true then the specified item will be positioned * at the center of the view, if possible. * If loop is true then the "next" algorithm will restart from the beginning * of the list if the end is reached, otherwise it will just stop returning false. */ bool selectNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop); /** * Selects the previous message item in the view. * If centerItem is true then the specified item will be positioned * at the center of the view, if possible. * * messageTypeFilter can be used to restrict the selection to only certain message types. * * existingSelectionBehaviour specifies how the existing selection * is manipulated. It may be cleared, expanded or grown/shrinked. * * If loop is true then the "previous" algorithm will restart from the end * of the list if the beginning is reached, otherwise it will just stop returning false. */ bool selectPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, MessageList::Core::ExistingSelectionBehaviour existingSelectionBehaviour, bool centerItem, bool loop); /** * Focuses the next message item in the view without actually selecting it. * * messageTypeFilter can be used to restrict the selection to only certain message types. * * If centerItem is true then the specified item will be positioned * at the center of the view, if possible. * If loop is true then the "next" algorithm will restart from the beginning * of the list if the end is reached, otherwise it will just stop returning false. */ bool focusNextMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop); /** * Focuses the previous message item in the view without actually selecting it. * * messageTypeFilter can be used to restrict the selection to only certain message types. * * If centerItem is true then the specified item will be positioned * at the center of the view, if possible. * If loop is true then the "previous" algorithm will restart from the end * of the list if the beginning is reached, otherwise it will just stop returning false. */ bool focusPreviousMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem, bool loop); /** * Selects the currently focused message item. May do nothing if the * focused message item is already selected (which is very likely). * If centerItem is true then the specified item will be positioned * at the center of the view, if possible. */ void selectFocusedMessageItem(bool centerItem); /** * Selects the first message item in the view that matches the specified Core::MessageTypeFilter. * If centerItem is true then the specified item will be positioned * at the center of the view, if possible. * * If the current view is already loaded then the request will * be satisfied immediately (well... if an unread message exists at all). * If the current view is still loading then the selection of the first * message will be scheduled to be executed when loading terminates. * * So this function doesn't actually guarantee that an unread or new message * was selected when the call returns. Take care :) * * The function returns true if a message was selected and false otherwise. */ bool selectFirstMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem); /** * Selects the last message item in the view that matches the specified Core::MessageTypeFilter. * If centerItem is true then the specified item will be positioned * at the center of the view, if possible. * * The function returns true if a message was selected and false otherwise. */ bool selectLastMessageItem(MessageList::Core::MessageTypeFilter messageTypeFilter, bool centerItem); /** * Selects all the items in the current folder. */ void selectAll(); /** * If expand is true then it expands the current thread, otherwise * collapses it. */ void setCurrentThreadExpanded(bool expand); /** * If expand is true then it expands all the threads, otherwise * collapses them. */ void setAllThreadsExpanded(bool expand); /** * If expand is true then it expands all the groups (only the toplevel * group item: inner threads are NOT expanded). If expand is false * then it collapses all the groups. If no grouping is in effect * then this function does nothing. */ void setAllGroupsExpanded(bool expand); /** * Sets the focus on the quick search line of the currently active tab. */ void focusQuickSearch(const QString &selectedText); /** * Returns the currently selected KMime::Message::Ptr (bound to current StorageModel). * The list may be empty if there are no selected messages or no StorageModel. * * If includeCollapsedChildren is true then the children of the selected but * collapsed items are also added to the list. * * The returned list is guaranteed to be valid only until you return control * to the main even loop. Don't store it for any longer. If you need to reference * this set of messages at a later stage then take a look at createPersistentSet(). */ QList selectionAsMessageList(bool includeCollapsedChildren = true) const; /** * Returns the currently selected Items (bound to current StorageModel). * The list may be empty if there are no selected messages or no StorageModel. * * If includeCollapsedChildren is true then the children of the selected but * collapsed items are also added to the list. * * The returned list is guaranteed to be valid only until you return control * to the main even loop. Don't store it for any longer. If you need to reference * this set of messages at a later stage then take a look at createPersistentSet(). */ Akonadi::Item::List selectionAsMessageItemList(bool includeCollapsedChildren = true) const; /** * Returns the currently selected Items id (bound to current StorageModel). * The list may be empty if there are no selected messages or no StorageModel. * * If includeCollapsedChildren is true then the children of the selected but * collapsed items are also added to the list. * * The returned list is guaranteed to be valid only until you return control * to the main even loop. Don't store it for any longer. If you need to reference * this set of messages at a later stage then take a look at createPersistentSet(). */ QVector selectionAsMessageItemListId(bool includeCollapsedChildren) const; QList selectionAsListMessageId(bool includeCollapsedChildren) const; /** * Returns the Akonadi::Item bound to the current StorageModel that * are part of the current thread. The current thread is the thread * that contains currentMessageItem(). * The list may be empty if there is no currentMessageItem() or no StorageModel. * * The returned list is guaranteed to be valid only until you return control * to the main even loop. Don't store it for any longer. If you need to reference * this set of messages at a later stage then take a look at createPersistentSet(). */ Akonadi::Item::List currentThreadAsMessageList() const; /** * Returns the Akonadi::MessageStatus in the current quicksearch field. */ QList currentFilterStatus() const; /** * Returns the search term in the current quicksearch field. */ QString currentFilterSearchString() const; /** * Returns true if the current Aggregation is threaded, false otherwise * (or if there is no current Aggregation). */ bool isThreaded() const; /** * Fast function that determines if the selection is empty */ bool selectionEmpty() const; /** * Fills the lists of the selected message serial numbers and of the selected+visible ones. * Returns true if the returned stats are valid (there is a current folder after all) * and false otherwise. This is called by KMMainWidget in a single place so we optimize by * making it a single sweep on the selection. * * If includeCollapsedChildren is true then the children of the selected but * collapsed items are also included in the stats */ bool getSelectionStats(Akonadi::Item::List &selectedSernums, Akonadi::Item::List &selectedVisibleSernums, bool *allSelectedBelongToSameThread, bool includeCollapsedChildren = true) const; /** * Deletes the persistent set pointed by the specified reference. * If the set does not exist anymore, nothing happens. */ void deletePersistentSet(MessageList::Core::MessageItemSetReference ref); /** * If bMark is true this function marks the messages as "about to be removed" * so they appear dimmer and aren't selectable in the view. * If bMark is false then this function clears the "about to be removed" state * for the specified MessageItems. */ void markMessageItemsAsAboutToBeRemoved(MessageList::Core::MessageItemSetReference ref, bool bMark); /** * Return Akonadi::Item from messageItemReference */ Akonadi::Item::List itemListFromPersistentSet(MessageList::Core::MessageItemSetReference ref); /** * Return a persistent set from current selection */ MessageList::Core::MessageItemSetReference selectionAsPersistentSet(bool includeCollapsedChildren = true) const; /** * Return a persistent set from current thread */ MessageList::Core::MessageItemSetReference currentThreadAsPersistentSet() const; Akonadi::Collection currentCollection() const; void setQuickSearchClickMessage(const QString &msg); MessageList::Core::QuickSearchLine::SearchOptions currentOptions() const; protected: /** * Reimplemented from MessageList::Core::Widget */ void fillMessageTagCombo() override; /** * Reimplemented from MessageList::Core::Widget */ void viewMessageSelected(MessageList::Core::MessageItem *msg) override; /** * Reimplemented from MessageList::Core::Widget */ void viewMessageActivated(MessageList::Core::MessageItem *msg) override; /** * Reimplemented from MessageList::Core::Widget */ void viewSelectionChanged() override; /** * Reimplemented from MessageList::Core::Widget */ void viewMessageListContextPopupRequest(const QList< MessageList::Core::MessageItem * > &selectedItems, const QPoint &globalPos) override; /** * Reimplemented from MessageList::Core::Widget */ void viewGroupHeaderContextPopupRequest(MessageList::Core::GroupHeaderItem *group, const QPoint &globalPos) override; /** * Reimplemented from MessageList::Core::Widget */ void viewDragEnterEvent(QDragEnterEvent *e) override; /** * Reimplemented from MessageList::Core::Widget */ void viewDragMoveEvent(QDragMoveEvent *e) override; /** * Reimplemented from MessageList::Core::Widget */ void viewDropEvent(QDropEvent *e) override; /** * Reimplemented from MessageList::Core::Widget */ void viewStartDragRequest() override; /** * Reimplemented from MessageList::Core::Widget */ void viewMessageStatusChangeRequest(MessageList::Core::MessageItem *msg, Akonadi::MessageStatus set, Akonadi::MessageStatus clear) override; private Q_SLOTS: void slotCollapseItem(); void slotExpandItem(); void slotTagsFetched(KJob *job); Q_SIGNALS: /** * Emitted when a message is selected (that is, single clicked and thus made current in the view) * Note that this message CAN be 0 (when the current item is cleared, for example). * * This signal is emitted when a SINGLE message is selected in the view, probably * by clicking on it or by simple keyboard navigation. When multiple items * are selected at once (by shift+clicking, for example) then you will get * this signal only for the last clicked message (or at all, if the last shift+clicked * thing is a group header...). You should handle selection changed in this case. */ void messageSelected(const Akonadi::Item &item); /** * Emitted when a message is doubleclicked or activated by other input means */ void messageActivated(const Akonadi::Item &item); /** * Emitted when the selection in the view changes. */ void selectionChanged(); /** * Emitted when a message wants its status to be changed */ void messageStatusChangeRequest(const Akonadi::Item &item, const Akonadi::MessageStatus &set, const Akonadi::MessageStatus &clear); private: class Private; Private *const d; }; } // namespace MessageList #endif //!__MESSAGELIST_WIDGET_H