summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vrátil <[email protected]>2017-08-07 16:20:54 +0200
committerDaniel Vrátil <[email protected]>2017-08-07 16:22:00 +0200
commit427550866b40293c2f19c9112bbaf979a9937381 (patch)
tree48012b1ba31eda2c6e5a08e38cabdd95fc666bc2
parentd1a3ad6fa951680f7ee0cfce717459c9883baa80 (diff)
Add folder-level 'Apply filter' actions to KMail
This adds 'Apply Filters on Folder' and 'Apply Filters on Folder and its Subfolders' actions to KMail main menu. This allows to simply execute any filter (or all filters) on an entire folder with a single click. This change also extends the Mail Filter Agent DBus API to allow callers to pass Collection IDs to the Agent and the Agent will resolve the Items itself, instead of the caller having to first obtain the Items and then pass all of them via DBus.
-rw-r--r--CMakeLists.txt2
-rw-r--r--agents/mailfilteragent/mailfilteragent.cpp27
-rw-r--r--agents/mailfilteragent/mailfilteragent.h2
-rw-r--r--agents/mailfilteragent/org.freedesktop.Akonadi.MailFilterAgent.xml10
-rw-r--r--src/kmail_part.rc13
-rw-r--r--src/kmkernel.cpp29
-rw-r--r--src/kmkernel.h6
-rw-r--r--src/kmmainwidget.cpp202
-rw-r--r--src/kmmainwidget.h16
-rw-r--r--src/kmmainwin.rc13
10 files changed, 258 insertions, 62 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fe13b7d..5d94d05 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,7 +63,7 @@ option(KDEPIM_ENTERPRISE_BUILD "Enable features specific to the enterprise branc
find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED DBus Network Test Widgets WebEngine WebEngineWidgets Xml)
set(LIBGRAVATAR_VERSION_LIB "5.6.40")
-set(MAILCOMMON_LIB_VERSION_LIB "5.6.41")
+set(MAILCOMMON_LIB_VERSION_LIB "5.6.42")
set(KDEPIM_APPS_LIB_VERSION_LIB "5.6.40")
set(MESSAGELIB_LIB_VERSION_LIB "5.6.41")
set(LIBKLEO_LIB_VERSION_LIB "5.6.40")
diff --git a/agents/mailfilteragent/mailfilteragent.cpp b/agents/mailfilteragent/mailfilteragent.cpp
index 560622c..a53c7fd 100644
--- a/agents/mailfilteragent/mailfilteragent.cpp
+++ b/agents/mailfilteragent/mailfilteragent.cpp
@@ -313,6 +313,18 @@ void MailFilterAgent::filterItems(const QList< qint64 > &itemIds, int filterSet)
m_filterManager->applyFilters(items, static_cast<FilterManager::FilterSet>(filterSet));
}
+void MailFilterAgent::filterCollections(const QList<qint64> &collections, int filterSet)
+{
+ for (qint64 id: collections) {
+ auto ifj = new Akonadi::ItemFetchJob{ Akonadi::Collection{ id }, this };
+ ifj->setDeliveryOption(Akonadi::ItemFetchJob::EmitItemsInBatches);
+ connect(ifj, &Akonadi::ItemFetchJob::itemsReceived,
+ this, [=](const Akonadi::Item::List &items) {
+ m_filterManager->applyFilters(items, static_cast<FilterManager::FilterSet>(filterSet));
+ });
+ }
+}
+
void MailFilterAgent::applySpecificFilters(const QList< qint64 > &itemIds, int requires, const QStringList &listFilters)
{
Akonadi::Item::List items;
@@ -324,6 +336,21 @@ void MailFilterAgent::applySpecificFilters(const QList< qint64 > &itemIds, int r
m_filterManager->applySpecificFilters(items, static_cast<MailCommon::SearchRule::RequiredPart>(requires), listFilters);
}
+void MailFilterAgent::applySpecificFiltersOnCollections(const QList<qint64> &colIds, const QStringList &listFilters)
+{
+ // TODO: Actually calculate this based on the listFilters' requirements
+ const auto requires = MailCommon::SearchRule::CompleteMessage;
+
+ for (qint64 id : colIds) {
+ auto ifj = new Akonadi::ItemFetchJob{ Akonadi::Collection{ id }, this };
+ ifj->setDeliveryOption(Akonadi::ItemFetchJob::EmitItemsInBatches);
+ connect(ifj, &Akonadi::ItemFetchJob::itemsReceived,
+ this, [=](const Akonadi::Item::List &items) {
+ m_filterManager->applySpecificFilters(items, requires, listFilters);
+ });
+ }
+}
+
void MailFilterAgent::filterItem(qint64 item, int filterSet, const QString &resourceId)
{
m_filterManager->filter(Akonadi::Item(item), static_cast<FilterManager::FilterSet>(filterSet), resourceId);
diff --git a/agents/mailfilteragent/mailfilteragent.h b/agents/mailfilteragent/mailfilteragent.h
index 27b1e10..0478f3b 100644
--- a/agents/mailfilteragent/mailfilteragent.h
+++ b/agents/mailfilteragent/mailfilteragent.h
@@ -50,7 +50,9 @@ public:
void filterItem(qint64 item, int filterSet, const QString &resourceId);
void filter(qint64 item, const QString &filterIdentifier, const QString &resourceId);
+ void filterCollections(const QList<qint64> &collections, int filterSet);
void applySpecificFilters(const QList< qint64 > &itemIds, int requires, const QStringList &listFilters);
+ void applySpecificFiltersOnCollections(const QList<qint64> &colIds, const QStringList &listFilters);
void reload();
diff --git a/agents/mailfilteragent/org.freedesktop.Akonadi.MailFilterAgent.xml b/agents/mailfilteragent/org.freedesktop.Akonadi.MailFilterAgent.xml
index 399b352..baa5c63 100644
--- a/agents/mailfilteragent/org.freedesktop.Akonadi.MailFilterAgent.xml
+++ b/agents/mailfilteragent/org.freedesktop.Akonadi.MailFilterAgent.xml
@@ -26,6 +26,16 @@
<arg name="filterSet" type="i" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const QList&lt;qint64&gt; &amp;"/>
</method>
+ <method name="filterCollections">
+ <arg name="collections" type="ax" direction="in"/>
+ <arg name="filterSet" type="i" direction="in"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const QList&lt;qint64&gt; &amp;"/>
+ </method>
+ <method name="applySpecificFiltersOnCollections">
+ <arg name="collections" type="ax" direction="in"/>
+ <arg name="listFilters" type="as" direction="in"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const QList&lt;qint64&gt; &amp;"/>
+ </method>
<method name="reload"/>
<method name="showFilterLogDialog">
<arg direction="in" type="x" name="windowId" />
diff --git a/src/kmail_part.rc b/src/kmail_part.rc
index 80cdf07..4584091 100644
--- a/src/kmail_part.rc
+++ b/src/kmail_part.rc
@@ -2,7 +2,7 @@
the same menu entries at the same place in KMail and Kontact -->
<!DOCTYPE gui>
-<gui version="523" name="kmmainwin" translationDomain="kmail">
+<gui version="524" name="kmmainwin" translationDomain="kmail">
<MenuBar>
<Menu noMerge="1" name="file" >
<text>&amp;File</text>
@@ -124,7 +124,16 @@
<Action name="akonadi_remove_duplicates" />
<Action name="remove_duplicate_recursive" />
<Separator/>
- <Action name="apply_filters_on_folder" />
+ <Menu name="apply_filters_folder_actions">
+ <text>Apply Filters on Folder</text>
+ <Action name="apply_filters_folder" />
+ <ActionList name="menu_filter_folder_actions" />
+ </Menu>
+ <Menu name="apply_filters_folder_recursive_actions">
+ <text>Apply Filters on Folder and all its Subfolders</text>
+ <Action name="apply_filters_folder_recursive" />
+ <ActionList name="menu_filter_folder_recursive_actions" />
+ </Menu>
<Separator/>
<Action name="display_format_message" />
<Action name="prefer_html_external_refs" />
diff --git a/src/kmkernel.cpp b/src/kmkernel.cpp
index d8bac4f..7d30499 100644
--- a/src/kmkernel.cpp
+++ b/src/kmkernel.cpp
@@ -1405,16 +1405,18 @@ void KMKernel::slotRunBackgroundTasks() // called regularly by timer
static Akonadi::Collection::List collect_collections(const QAbstractItemModel *model, const QModelIndex &parent)
{
Akonadi::Collection::List collections;
- const int numberOfCollection(model->rowCount(parent));
- for (int i = 0; i < numberOfCollection; ++i) {
- const QModelIndex child = model->index(i, 0, parent);
- Akonadi::Collection collection
- = model->data(child, Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
- if (collection.isValid()) {
- collections << collection;
+ QStack<QModelIndex> stack;
+ stack.push(parent);
+ while (!stack.isEmpty()) {
+ const auto idx = stack.pop();
+ if (idx.isValid()) {
+ collections << model->data(idx, Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
+ }
+ for (int i = model->rowCount(idx) - 1; i >= 0; --i) {
+ stack.push(idx.child(i, 0));
}
- collections += collect_collections(model, child);
}
+
return collections;
}
@@ -1423,6 +1425,17 @@ Akonadi::Collection::List KMKernel::allFolders() const
return collect_collections(collectionModel(), QModelIndex());
}
+Akonadi::Collection::List KMKernel::subfolders(const Akonadi::Collection &col) const
+{
+ const auto idx = collectionModel()->match({}, Akonadi::EntityTreeModel::CollectionRole,
+ QVariant::fromValue(col), 1, Qt::MatchExactly);
+ if (!idx.isEmpty()) {
+ return collect_collections(collectionModel(), idx[0]);
+ }
+
+ return {};
+}
+
void KMKernel::expireAllFoldersNow() // called by the GUI
{
mFolderCollectionMonitor->expireAllFolders(true /*immediate*/, entityTreeModel());
diff --git a/src/kmkernel.h b/src/kmkernel.h
index 35a2acf..149a4ce 100644
--- a/src/kmkernel.h
+++ b/src/kmkernel.h
@@ -383,6 +383,12 @@ public:
* is empty at startup.
*/
Akonadi::Collection::List allFolders() const;
+
+ /**
+ * Includes all subfolders of @p col, including the @p col itself.
+ */
+ Akonadi::Collection::List subfolders(const Akonadi::Collection &col) const;
+
//
void selectCollectionFromId(Akonadi::Collection::Id id);
diff --git a/src/kmmainwidget.cpp b/src/kmmainwidget.cpp
index 98730f1..0310cb4 100644
--- a/src/kmmainwidget.cpp
+++ b/src/kmmainwidget.cpp
@@ -2192,20 +2192,32 @@ void KMMainWidget::slotApplyFilters()
applyFilters(selectedMessages);
}
-void KMMainWidget::slotApplyFiltersOnFolder()
+void KMMainWidget::slotApplyFiltersOnFolder(bool recursive)
{
if (mCurrentCollection.isValid()) {
- Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(mCurrentCollection, this);
- connect(job, &Akonadi::ItemFetchJob::result, this, &KMMainWidget::slotFetchItemsForFolderDone);
+ Akonadi::Collection::List cols;
+ if (recursive) {
+ cols = KMKernel::self()->subfolders(mCurrentCollection);
+ } else {
+ cols << mCurrentCollection;
+ }
+ applyFilters(cols);
}
}
-void KMMainWidget::slotFetchItemsForFolderDone(KJob *job)
+void KMMainWidget::slotApplyFilterOnFolder(bool recursive)
{
- Akonadi::ItemFetchJob *fjob = qobject_cast<Akonadi::ItemFetchJob *>(job);
- Q_ASSERT(fjob);
- Akonadi::Item::List items = fjob->items();
- applyFilters(items);
+ if (mCurrentCollection.isValid()) {
+ Akonadi::Collection::List cols;
+ if (recursive) {
+ cols = KMKernel::self()->subfolders(mCurrentCollection);
+ } else {
+ cols << mCurrentCollection;
+ }
+
+ QAction *action = qobject_cast<QAction*>(sender());
+ applyFilter(cols, action->property("filter_id").toString());
+ }
}
void KMMainWidget::applyFilters(const Akonadi::Item::List &selectedMessages)
@@ -2217,6 +2229,22 @@ void KMMainWidget::applyFilters(const Akonadi::Item::List &selectedMessages)
MailCommon::FilterManager::instance()->filter(selectedMessages);
}
+void KMMainWidget::applyFilters(const Akonadi::Collection::List &selectedCols)
+{
+#ifndef QT_NO_CURSOR
+ KPIM::KCursorSaver busy(KPIM::KBusyPtr::busy());
+#endif
+ MailCommon::FilterManager::instance()->filter(selectedCols);
+}
+
+void KMMainWidget::applyFilter(const Akonadi::Collection::List &selectedCols, const QString &filter)
+{
+#ifndef QT_NO_CURSOR
+ KPIM::KCursorSaver busy(KPIM::KBusyPtr::busy());
+#endif
+ MailCommon::FilterManager::instance()->filter(selectedCols, { filter });
+}
+
//-----------------------------------------------------------------------------
void KMMainWidget::slotCheckVacation()
{
@@ -3375,10 +3403,27 @@ void KMMainWidget::setupActions()
}
{
- mApplyFiltersOnFolder = new QAction(QIcon::fromTheme(QStringLiteral("view-filter")), i18n("Appl&y All Filters On Folder"), this);
- actionCollection()->addAction(QStringLiteral("apply_filters_on_folder"), mApplyFiltersOnFolder);
- connect(mApplyFiltersOnFolder, &QAction::triggered,
- this, &KMMainWidget::slotApplyFiltersOnFolder);
+ mApplyAllFiltersFolderAction = new QAction(QIcon::fromTheme(QStringLiteral("view-filter")), i18n("Apply All Filters"), this);
+ actionCollection()->addAction(QStringLiteral("apply_filters_folder"), mApplyAllFiltersFolderAction);
+ connect(mServerSideSubscription, &QAction::triggered,
+ this, [this] { slotApplyFiltersOnFolder(/* recursive */ false); });
+ }
+
+ {
+ mApplyAllFiltersFolderRecursiveAction = new QAction(QIcon::fromTheme(QStringLiteral("view-filter")), i18n("Apply All Filters"), this);
+ actionCollection()->addAction(QStringLiteral("apply_filters_folder_recursive"), mApplyAllFiltersFolderRecursiveAction);
+ connect(mServerSideSubscription, &QAction::triggered,
+ this, [this] { slotApplyFiltersOnFolder(/* recursive */ true); });
+ }
+
+ {
+ mApplyFilterFolderActionsMenu = new KActionMenu(i18n("Apply Filters on Folder"), this);
+ actionCollection()->addAction(QStringLiteral("apply_filters_on_folder_actions"), mApplyFilterFolderActionsMenu);
+ }
+
+ {
+ mApplyFilterFolderRecursiveActionsMenu = new KActionMenu(i18n("Apply Filters on Folder and all its Subfolders"), this);
+ actionCollection()->addAction(QStringLiteral("apply_filters_on_folder_recursive_actions"), mApplyFilterFolderRecursiveActionsMenu);
}
{
@@ -3692,7 +3737,8 @@ void KMMainWidget::updateMessageActionsDelayed()
currentMessage = Akonadi::Item();
}
- mApplyFiltersOnFolder->setEnabled(currentFolderSettingsIsValid);
+ mApplyFilterActionsMenu->setEnabled(currentFolderSettingsIsValid);
+ mApplyFilterFolderRecursiveActionsMenu->setEnabled(currentFolderSettingsIsValid);
//
// Here we have:
@@ -3973,7 +4019,9 @@ void KMMainWidget::updateFolderMenu()
return;
}
- const bool folderWithContent = mCurrentFolderSettings && !mCurrentFolderSettings->isStructural();
+ const bool folderWithContent = mCurrentFolderSettings
+ && !mCurrentFolderSettings->isStructural()
+ && mCurrentFolderSettings->isValid();
bool multiFolder = false;
if (mFolderTreeWidget) {
multiFolder = mFolderTreeWidget->selectedCollections().count() > 1;
@@ -4024,7 +4072,6 @@ void KMMainWidget::updateFolderMenu()
updateHtmlMenuEntry();
mShowFolderShortcutDialogAction->setEnabled(!multiFolder && folderWithContent);
-
actionlist << akonadiStandardAction(Akonadi::StandardActionManager::ManageLocalSubscriptions);
bool imapFolderIsOnline = false;
if (mCurrentFolderSettings && PimCommon::MailUtil::isImapFolder(mCurrentCollection, imapFolderIsOnline)) {
@@ -4035,6 +4082,17 @@ void KMMainWidget::updateFolderMenu()
mGUIClient->unplugActionList(QStringLiteral("collectionview_actionlist"));
mGUIClient->plugActionList(QStringLiteral("collectionview_actionlist"), actionlist);
+
+ const bool folderIsValid = folderWithContent && !multiFolder;
+ mApplyAllFiltersFolderAction->setEnabled(folderIsValid);
+ mApplyFilterFolderActionsMenu->setEnabled(folderIsValid);
+ mApplyFilterFolderRecursiveActionsMenu->setEnabled(folderIsValid);
+ for (auto a : qAsConst(mFilterFolderMenuActions)) {
+ a->setEnabled(folderIsValid);
+ }
+ for (auto a : qAsConst(mFilterFolderMenuRecursiveActions)) {
+ a->setEnabled(folderIsValid);
+ }
}
//-----------------------------------------------------------------------------
@@ -4119,25 +4177,38 @@ void KMMainWidget::slotUpdateUndo()
//-----------------------------------------------------------------------------
void KMMainWidget::clearFilterActions()
{
- if (!mFilterTBarActions.isEmpty()) {
- if (mGUIClient->factory()) {
+ if (mGUIClient->factory()) {
+ if (!mFilterTBarActions.isEmpty()) {
mGUIClient->unplugActionList(QStringLiteral("toolbar_filter_actions"));
}
- }
-
- if (!mFilterMenuActions.isEmpty()) {
- if (mGUIClient->factory()) {
+ if (!mFilterMenuActions.isEmpty()) {
mGUIClient->unplugActionList(QStringLiteral("menu_filter_actions"));
}
+ if (!mFilterFolderMenuActions.isEmpty()) {
+ mGUIClient->unplugActionList(QStringLiteral("menu_filter_folder_actions"));
+ }
+ if (!mFilterFolderMenuRecursiveActions.isEmpty()) {
+ mGUIClient->unplugActionList(QStringLiteral("menu_filter_folder_recursive_actions"));
+ }
}
for (QAction *a : qAsConst(mFilterMenuActions)) {
actionCollection()->removeAction(a);
}
+ for (QAction *a : qAsConst(mFilterFolderMenuActions)) {
+ actionCollection()->removeAction(a);
+ }
+ for (QAction *a : qAsConst(mFilterFolderMenuRecursiveActions)) {
+ actionCollection()->removeAction(a);
+ }
mApplyFilterActionsMenu->menu()->clear();
+ mApplyFilterFolderActionsMenu->menu()->clear();
+ mApplyFilterFolderRecursiveActionsMenu->menu()->clear();
mFilterTBarActions.clear();
mFilterMenuActions.clear();
+ mFilterFolderMenuActions.clear();
+ mFilterFolderMenuRecursiveActions.clear();
qDeleteAll(mFilterCommands);
mFilterCommands.clear();
@@ -4148,11 +4219,32 @@ void KMMainWidget::initializePluginActions()
KMailPluginInterface::self()->initializePluginActions(QStringLiteral("kmail"), mGUIClient);
}
+QAction *KMMainWidget::filterToAction(MailCommon::MailFilter *filter)
+{
+ QString displayText = i18n("Filter %1", filter->name());
+ QString icon = filter->icon();
+ if (icon.isEmpty()) {
+ icon = QStringLiteral("system-run");
+ }
+ QAction *filterAction = new QAction(QIcon::fromTheme(icon), displayText, actionCollection());
+ filterAction->setProperty("filter_id", filter->identifier());
+ filterAction->setIconText(filter->toolbarName());
+
+ // The shortcut configuration is done in the filter dialog.
+ // The shortcut set in the shortcut dialog would not be saved back to
+ // the filter settings correctly.
+ actionCollection()->setShortcutsConfigurable(filterAction, false);
+
+ return filterAction;
+}
+
//-----------------------------------------------------------------------------
void KMMainWidget::initializeFilterActions()
{
clearFilterActions();
mApplyFilterActionsMenu->menu()->addAction(mApplyAllFiltersAction);
+ mApplyFilterFolderActionsMenu->menu()->addAction(mApplyAllFiltersFolderAction);
+ mApplyFilterFolderRecursiveActionsMenu->menu()->addAction(mApplyAllFiltersFolderRecursiveAction);
bool addedSeparator = false;
const QList<MailFilter *> lstFilters = MailCommon::FilterManager::instance()->filters();
@@ -4163,43 +4255,61 @@ void KMMainWidget::initializeFilterActions()
if (action(normalizedName)) {
continue;
}
- KMMetaFilterActionCommand *filterCommand = new KMMetaFilterActionCommand(filter->identifier(), this);
- mFilterCommands.append(filterCommand);
- QString displayText = i18n("Filter %1", filter->name());
- QString icon = filter->icon();
- if (icon.isEmpty()) {
- icon = QStringLiteral("system-run");
- }
- QAction *filterAction = new QAction(QIcon::fromTheme(icon), displayText, actionCollection());
- filterAction->setIconText(filter->toolbarName());
-
- // The shortcut configuration is done in the filter dialog.
- // The shortcut set in the shortcut dialog would not be saved back to
- // the filter settings correctly.
- actionCollection()->setShortcutsConfigurable(filterAction, false);
- actionCollection()->addAction(normalizedName,
- filterAction);
- connect(filterAction, &QAction::triggered,
- filterCommand, &KMMetaFilterActionCommand::start);
- actionCollection()->setDefaultShortcut(filterAction, filter->shortcut());
+
if (!addedSeparator) {
QAction *a = mApplyFilterActionsMenu->menu()->addSeparator();
mFilterMenuActions.append(a);
+ a = mApplyFilterFolderActionsMenu->menu()->addSeparator();
+ mFilterFolderMenuActions.append(a);
+ a = mApplyFilterFolderRecursiveActionsMenu->menu()->addSeparator();
+ mFilterFolderMenuRecursiveActions.append(a);
addedSeparator = true;
}
+
+ KMMetaFilterActionCommand *filterCommand = new KMMetaFilterActionCommand(filter->identifier(), this);
+ mFilterCommands.append(filterCommand);
+
+ auto filterAction = filterToAction(filter);
+ actionCollection()->addAction(normalizedName, filterAction);
+ connect(filterAction, &QAction::triggered,
+ filterCommand, &KMMetaFilterActionCommand::start);
+ actionCollection()->setDefaultShortcut(filterAction, filter->shortcut());
mApplyFilterActionsMenu->menu()->addAction(filterAction);
mFilterMenuActions.append(filterAction);
if (filter->configureToolbar()) {
mFilterTBarActions.append(filterAction);
}
+
+ filterAction = filterToAction(filter);
+ actionCollection()->addAction(normalizedName + QStringLiteral("___folder"), filterAction);
+ connect(filterAction, &QAction::triggered,
+ this, [this] { slotApplyFilterOnFolder(/* recursive */ false); });
+ mApplyFilterFolderActionsMenu->menu()->addAction(filterAction);
+ mFilterFolderMenuActions.append(filterAction);
+
+ filterAction = filterToAction(filter);
+ actionCollection()->addAction(normalizedName + QStringLiteral("___folder_recursive"), filterAction);
+ connect(filterAction, &QAction::triggered,
+ this, [this] { slotApplyFilterOnFolder(/* recursive */ true); });
+ mApplyFilterFolderRecursiveActionsMenu->menu()->addAction(filterAction);
+ mFilterFolderMenuRecursiveActions.append(filterAction);
}
}
- if (!mFilterMenuActions.isEmpty() && mGUIClient->factory()) {
- mGUIClient->plugActionList(QStringLiteral("menu_filter_actions"), mFilterMenuActions);
- }
- if (!mFilterTBarActions.isEmpty() && mGUIClient->factory()) {
- mFilterTBarActions.prepend(mToolbarActionSeparator);
- mGUIClient->plugActionList(QStringLiteral("toolbar_filter_actions"), mFilterTBarActions);
+
+ if (mGUIClient->factory()) {
+ if (!mFilterMenuActions.isEmpty()) {
+ mGUIClient->plugActionList(QStringLiteral("menu_filter_actions"), mFilterMenuActions);
+ }
+ if (!mFilterTBarActions.isEmpty()) {
+ mFilterTBarActions.prepend(mToolbarActionSeparator);
+ mGUIClient->plugActionList(QStringLiteral("toolbar_filter_actions"), mFilterTBarActions);
+ }
+ if (!mFilterFolderMenuActions.isEmpty()) {
+ mGUIClient->plugActionList(QStringLiteral("menu_filter_folder_actions"), mFilterFolderMenuActions);
+ }
+ if (!mFilterFolderMenuRecursiveActions.isEmpty()) {
+ mGUIClient->plugActionList(QStringLiteral("menu_filter_folder_recursive_actions"), mFilterFolderMenuRecursiveActions);
+ }
}
// Our filters have changed, now enable/disable them
diff --git a/src/kmmainwidget.h b/src/kmmainwidget.h
index d7a1829..60a89ee 100644
--- a/src/kmmainwidget.h
+++ b/src/kmmainwidget.h
@@ -86,6 +86,7 @@ class VacationManager;
namespace MailCommon {
class FolderSelectionDialog;
class FavoriteCollectionWidget;
+class MailFilter;
}
class KMAIL_EXPORT KMMainWidget : public QWidget
@@ -359,7 +360,8 @@ protected Q_SLOTS:
void slotCheckVacation();
void slotDebugSieve();
void slotApplyFilters();
- void slotApplyFiltersOnFolder();
+ void slotApplyFiltersOnFolder(bool recursive);
+ void slotApplyFilterOnFolder(bool recursive);
void slotExpandThread();
void slotExpandAllThreads();
void slotCollapseThread();
@@ -490,6 +492,8 @@ private:
void setCurrentThreadStatus(const Akonadi::MessageStatus &status, bool toggle);
void applyFilters(const Akonadi::Item::List &selectedMessages);
+ void applyFilters(const Akonadi::Collection::List &selectedCols);
+ void applyFilter(const Akonadi::Collection::List &selectedCols, const QString &filter);
/**
* Internal helper that creates the folder selection dialog used for the
@@ -540,7 +544,6 @@ private Q_SLOTS:
void itemsFetchDone(KJob *job);
void slotServerSideSubscription();
- void slotFetchItemsForFolderDone(KJob *job);
void slotServerStateChanged(Akonadi::ServerManager::State state);
void slotArchiveMails();
void slotChangeDisplayMessageFormat(MessageViewer::Viewer::DisplayFormatMessage format);
@@ -563,6 +566,8 @@ private:
void slotPageIsScrolledToBottom(bool isAtBottom);
void printCurrentMessage(bool preview);
void replyCurrentMessageCommand(MessageComposer::ReplyStrategy strategy);
+ QAction *filterToAction(MailCommon::MailFilter *filter);
+
// Message actions
QAction *mDeleteAction;
QAction *mTrashThreadAction;
@@ -582,7 +587,10 @@ private:
// Filter actions
KActionMenu *mFilterMenu;
QAction *mExpireConfigAction;
- QAction *mApplyFiltersOnFolder;
+ KActionMenu *mApplyFilterFolderActionsMenu;
+ KActionMenu *mApplyFilterFolderRecursiveActionsMenu;
+ QAction *mApplyAllFiltersFolderAction;
+ QAction *mApplyAllFiltersFolderRecursiveAction;
// Custom template actions menu
KActionMenu *mTemplateMenu;
@@ -635,6 +643,8 @@ private:
QVBoxLayout *mTopLayout;
bool mDestructed;
QList<QAction *> mFilterMenuActions;
+ QList<QAction *> mFilterFolderMenuActions;
+ QList<QAction *> mFilterFolderMenuRecursiveActions;
QList<QAction *> mFilterTBarActions;
QList<KMMetaFilterActionCommand *> mFilterCommands;
diff --git a/src/kmmainwin.rc b/src/kmmainwin.rc
index 80cdf07..78ea72d 100644
--- a/src/kmmainwin.rc
+++ b/src/kmmainwin.rc
@@ -2,7 +2,7 @@
the same menu entries at the same place in KMail and Kontact -->
<!DOCTYPE gui>
-<gui version="523" name="kmmainwin" translationDomain="kmail">
+<gui version="524" name="kmmainwin" translationDomain="kmail">
<MenuBar>
<Menu noMerge="1" name="file" >
<text>&amp;File</text>
@@ -124,7 +124,16 @@
<Action name="akonadi_remove_duplicates" />
<Action name="remove_duplicate_recursive" />
<Separator/>
- <Action name="apply_filters_on_folder" />
+ <Menu name="apply_filters_folder_actions">
+ <text>Apply Filters on Folder</text>
+ <Action name="apply_filters_folder" />
+ <ActionList name="menu_filter_folder_actions" />
+ </Menu>
+ <Menu name="apply_filters_folder_recursive_actions">
+ <text>Apply Filters on Folder and all its Subfolders</text>
+ <Action name="apply_filters_folder_recursive" />
+ <ActionList name="menu_filter_folder_recursive_actions" />
+ </Menu>
<Separator/>
<Action name="display_format_message" />
<Action name="prefer_html_external_refs" />