[kdepim] upstream filter-rework patch
Rex Dieter
rdieter at fedoraproject.org
Fri Jul 6 00:48:33 UTC 2012
commit af15e326da81c06916e5d1f8d1220afb4268e0f4
Author: Rex Dieter <rdieter at fedoraproject.org>
Date: Thu Jul 5 19:51:45 2012 -0500
upstream filter-rework patch
kdepim-4.8.95-filtering.patch | 2017 +++++++++++++++++++++++++++++++++++++++++
kdepim.spec | 10 +-
2 files changed, 2025 insertions(+), 2 deletions(-)
---
diff --git a/kdepim-4.8.95-filtering.patch b/kdepim-4.8.95-filtering.patch
new file mode 100644
index 0000000..02d60bc
--- /dev/null
+++ b/kdepim-4.8.95-filtering.patch
@@ -0,0 +1,2017 @@
+commit d64d61b470c56b92294f6adee6d74305a217628d
+Author: Andras Mantia <amantia at kde.org>
+Date: Wed Jul 4 18:35:46 2012 +0300
+
+ A biggish refactoring of the filter functionality:
+
+ 1) Do not take the items from the cache only, as they might be incomplete (especially in online imap case, but not only).
+ This should fix the body loss bug on spam filtering.(Bug 287752 and similar ones + countless of reports on user list)
+ Might fix 293768.
+
+ 2) Download only what is really needed for the filter and add safety checks that
+ the mail is not modified if the requested part is missing. So far the distinction
+ was only betwee the body and rest. This should speed up filtering.
+ Also related to 287752, but should fix also 292283, 288109.
+
+ 3) Rename qDebug->kDebug + fix some includes
+
+ 4) The code should also fix the duplicate mails appearing after filtering (some of the duplicates
+ with empty content), eg. 275233
+
+ All bug reporters: in case you still see the bug, reopen the corresponding one.
+ For the reports that were CC'd, but not closed, please try to reproduce and tell
+ the result.
+
+ So far the bug is fixed on master, but might be backported later to 4.9.
+
+ BUG: 287752
+ BUG: 292283
+ BUG: 288109
+ BUG: 286043
+ BUG: 295484
+ BUG: 302337
+ BUG: 295000
+ BUG: 295684
+ CCBUG: 293768
+ CCBUG: 275233
+ CCBUG: 293918
+ CCBUG: 284310
+ CCBUG: 286364
+ CCBUG: 283682
+
+diff --git a/kmail/kmcommands.cpp b/kmail/kmcommands.cpp
+index b6edc27..2c8cc68 100644
+--- a/kmail/kmcommands.cpp
++++ b/kmail/kmcommands.cpp
+@@ -1228,8 +1228,9 @@ KMCommand::Result KMFilterCommand::execute()
+
+ KMFilterActionCommand::KMFilterActionCommand( QWidget *parent,
+ const QVector<qlonglong> &msgListId,
+- const QString &filterId, bool requireBody )
+- : KMCommand( parent ), mMsgListId(msgListId), mFilterId( filterId ), mRequireBody(requireBody)
++ const QString &filterId,
++ MailCommon::SearchRule::RequiredPart requiredPart )
++ : KMCommand( parent ), mMsgListId(msgListId), mFilterId( filterId ), mRequiredPart(requiredPart)
+ {
+ }
+
+@@ -1239,11 +1240,6 @@ KMCommand::Result KMFilterActionCommand::execute()
+ MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
+ #endif
+ int msgCount = 0;
+- MailCommon::FilterManager::FilterRequires filterrequires = MailCommon::FilterManager::Unknown;
+- if( mRequireBody )
+- filterrequires = MailCommon::FilterManager::FullMessage;
+- else
+- filterrequires = MailCommon::FilterManager::HeaderMessage;
+ const int msgCountToFilter = mMsgListId.count();
+ ProgressItem* progressItem =
+ ProgressManager::createProgressItem (
+@@ -1262,7 +1258,7 @@ KMCommand::Result KMFilterActionCommand::execute()
+ }
+
+
+- MailCommon::FilterManager::instance()->filter( id, mFilterId,filterrequires );
++ MailCommon::FilterManager::instance()->filter( id, mFilterId, mRequiredPart );
+ progressItem->incCompletedItems();
+ }
+
+@@ -1272,17 +1268,17 @@ KMCommand::Result KMFilterActionCommand::execute()
+ }
+
+
+-KMMetaFilterActionCommand::KMMetaFilterActionCommand( const QString &filterId, bool requireBody,
++KMMetaFilterActionCommand::KMMetaFilterActionCommand( const QString &filterId, SearchRule::RequiredPart requiredPart,
+ KMMainWidget *main )
+ : QObject( main ),
+- mFilterId( filterId ), mRequireBody(requireBody), mMainWidget( main )
++ mFilterId( filterId ), mRequiredPart(requiredPart), mMainWidget( main )
+ {
+ }
+
+ void KMMetaFilterActionCommand::start()
+ {
+ KMCommand *filterCommand = new KMFilterActionCommand(
+- mMainWidget, mMainWidget->messageListPane()->selectionAsMessageItemListId() , mFilterId, mRequireBody );
++ mMainWidget, mMainWidget->messageListPane()->selectionAsMessageItemListId() , mFilterId, mRequiredPart );
+ filterCommand->start();
+ }
+
+diff --git a/kmail/kmcommands.h b/kmail/kmcommands.h
+index 6dbc2a6..13d1149 100644
+--- a/kmail/kmcommands.h
++++ b/kmail/kmcommands.h
+@@ -4,13 +4,13 @@
+ #define KMCommands_h
+
+ #include "kmail_export.h"
+-#include <kmime/kmime_message.h>
+ #include "messagecomposer/messagefactory.h"
++#include "messagelist/core/view.h"
++#include "searchpattern.h"
+
+ #include <akonadi/kmime/messagestatus.h>
+-#include <messagelist/core/view.h>
+-using Akonadi::MessageStatus;
+ #include <kio/job.h>
++#include <kmime/kmime_message.h>
+
+ #include <QPointer>
+ #include <QList>
+@@ -18,6 +18,8 @@ using Akonadi::MessageStatus;
+ #include <akonadi/itemfetchscope.h>
+ #include <akonadi/collection.h>
+
++using Akonadi::MessageStatus;
++
+ class KProgressDialog;
+ class KMMainWidget;
+
+@@ -463,13 +465,14 @@ class KMAIL_EXPORT KMFilterActionCommand : public KMCommand
+
+ public:
+ KMFilterActionCommand(QWidget *parent,
+- const QVector<qlonglong> &msgListId, const QString &filterId , bool requireBody);
++ const QVector<qlonglong> &msgListId, const QString &filterId,
++ MailCommon::SearchRule::RequiredPart requiredPart);
+
+ private:
+ virtual Result execute();
+ QVector<qlonglong> mMsgListId;
+ QString mFilterId;
+- bool mRequireBody;
++ MailCommon::SearchRule::RequiredPart mRequiredPart;
+ };
+
+
+@@ -478,14 +481,14 @@ class KMAIL_EXPORT KMMetaFilterActionCommand : public QObject
+ Q_OBJECT
+
+ public:
+- KMMetaFilterActionCommand( const QString &filterId, bool requireBody, KMMainWidget *main );
++ KMMetaFilterActionCommand( const QString &filterId, MailCommon::SearchRule::RequiredPart requiredPart, KMMainWidget *main );
+
+ public slots:
+ void start();
+
+ private:
+ QString mFilterId;
+- bool mRequireBody;
++ MailCommon::SearchRule::RequiredPart mRequiredPart;
+ KMMainWidget *mMainWidget;
+ };
+
+diff --git a/kmail/kmmainwidget.cpp b/kmail/kmmainwidget.cpp
+index 3688e55..1cab55a 100644
+--- a/kmail/kmmainwidget.cpp
++++ b/kmail/kmmainwidget.cpp
+@@ -4264,7 +4264,7 @@ void KMMainWidget::initializeFilterActions()
+ if ( action( normalizedName.toUtf8() ) ) {
+ continue;
+ }
+- KMMetaFilterActionCommand *filterCommand = new KMMetaFilterActionCommand( filter->identifier(), filter->requiresBody(), this );
++ KMMetaFilterActionCommand *filterCommand = new KMMetaFilterActionCommand( filter->identifier(), filter->requiredPart(), this );
+ mFilterCommands.append( filterCommand );
+ QString displayText = i18n( "Filter %1", filter->name() );
+ QString icon = filter->icon();
+diff --git a/mailcommon/filter/filteraction.cpp b/mailcommon/filter/filteraction.cpp
+index b4a348a..dbd8798 100644
+--- a/mailcommon/filter/filteraction.cpp
++++ b/mailcommon/filter/filteraction.cpp
+@@ -1,5 +1,6 @@
+ /*
+ * Copyright (c) 1996-1998 Stefan Taferner <taferner at kde.org>
++ * Copyright (C) 2012 Andras Mantia <amantia at kde.org>
+ *
+ * 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
+@@ -50,11 +51,6 @@ QString FilterAction::name() const
+ return mName;
+ }
+
+-bool FilterAction::requiresBody() const
+-{
+- return true;
+-}
+-
+ bool FilterAction::isEmpty() const
+ {
+ return false;
+diff --git a/mailcommon/filter/filteraction.h b/mailcommon/filter/filteraction.h
+index cd6e18c..8480932 100644
+--- a/mailcommon/filter/filteraction.h
++++ b/mailcommon/filter/filteraction.h
+@@ -21,6 +21,7 @@
+ #define MAILCOMMON_FILTERACTION_H
+
+ #include "../mailcommon_export.h"
++#include "../searchpattern.h"
+
+ #include "itemcontext.h"
+
+@@ -66,7 +67,8 @@ class MAILCOMMON_EXPORT FilterAction : public QObject
+ /// (e.g. "disk full").
+ };
+
+- /**
++
++ /**
+ * Creates a new filter action.
+ *
+ * The action is initialized with an identifier @p name and
+@@ -103,10 +105,9 @@ class MAILCOMMON_EXPORT FilterAction : public QObject
+ virtual ReturnCode process( ItemContext &context ) const = 0;
+
+ /**
+- * Determines if the action depends on the body of the message
+- */
+- virtual bool requiresBody() const;
+-
++ * Returns the required part from the item that is needed for the action to
++ * operate. See @ref SearchRule::RequiredPart */
++ virtual SearchRule::RequiredPart requiredPart() const = 0;
+ /**
+ * Determines whether this action is valid. But this is just a
+ * quick test. Eg., actions that have a mail address as parameter
+diff --git a/mailcommon/filter/filteractionaddheader.cpp b/mailcommon/filter/filteractionaddheader.cpp
+index 53f4c2c..282ed30 100644
+--- a/mailcommon/filter/filteractionaddheader.cpp
++++ b/mailcommon/filter/filteractionaddheader.cpp
+@@ -142,6 +142,12 @@ void FilterActionAddHeader::clearParamWidget( QWidget *paramWidget ) const
+ lineEdit->clear();
+ }
+
++SearchRule::RequiredPart FilterActionAddHeader::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
++
+ QString FilterActionAddHeader::argsAsString() const
+ {
+ QString result = mParameter;
+diff --git a/mailcommon/filter/filteractionaddheader.h b/mailcommon/filter/filteractionaddheader.h
+index 4690ca3..76dd342 100644
+--- a/mailcommon/filter/filteractionaddheader.h
++++ b/mailcommon/filter/filteractionaddheader.h
+@@ -38,6 +38,8 @@ class FilterActionAddHeader: public FilterActionWithStringList
+ virtual void applyParamWidgetValue( QWidget *paramWidget );
+ virtual void clearParamWidget( QWidget *paramWidget ) const;
+
++ virtual SearchRule::RequiredPart requiredPart() const;
++
+ virtual QString argsAsString() const;
+ virtual void argsFromString( const QString &argsStr );
+
+diff --git a/mailcommon/filter/filteractionaddtag.cpp b/mailcommon/filter/filteractionaddtag.cpp
+index 55114c9..51cb9b9 100644
+--- a/mailcommon/filter/filteractionaddtag.cpp
++++ b/mailcommon/filter/filteractionaddtag.cpp
+@@ -90,9 +90,9 @@ FilterAction::ReturnCode FilterActionAddTag::process( ItemContext &context ) con
+ return GoOn;
+ }
+
+-bool FilterActionAddTag::requiresBody() const
++SearchRule::RequiredPart FilterActionAddTag::requiredPart() const
+ {
+- return false;
++ return SearchRule::Envelope;
+ }
+
+ void FilterActionAddTag::argsFromString( const QString &argsStr )
+diff --git a/mailcommon/filter/filteractionaddtag.h b/mailcommon/filter/filteractionaddtag.h
+index 7b75a8f..48a6c26 100644
+--- a/mailcommon/filter/filteractionaddtag.h
++++ b/mailcommon/filter/filteractionaddtag.h
+@@ -33,7 +33,7 @@ class FilterActionAddTag: public FilterActionWithStringList
+ public:
+ FilterActionAddTag( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
+- virtual bool requiresBody() const;
++ SearchRule::RequiredPart requiredPart() const;
+
+ static FilterAction* newAction();
+
+diff --git a/mailcommon/filter/filteractionaddtoaddressbook.cpp b/mailcommon/filter/filteractionaddtoaddressbook.cpp
+index f2d56f6..c3eb8f7 100644
+--- a/mailcommon/filter/filteractionaddtoaddressbook.cpp
++++ b/mailcommon/filter/filteractionaddtoaddressbook.cpp
+@@ -19,9 +19,9 @@
+
+ #include "filteractionaddtoaddressbook.h"
+
+-#include <messageviewer/minimumcombobox.h>
++#include "messageviewer/minimumcombobox.h"
+
+-#include <libkdepim/addcontactjob.h>
++#include "libkdepim/addcontactjob.h"
+
+ #include <KDE/Akonadi/CollectionComboBox>
+ #include <KDE/KABC/Addressee>
+@@ -81,12 +81,18 @@ FilterAction::ReturnCode FilterActionAddToAddressBook::process( ItemContext &con
+ contact.insertCategory( mCategory );
+
+ KPIM::AddContactJob *job = new KPIM::AddContactJob( contact, Akonadi::Collection( mCollectionId ) );
+- job->start();
++ job->start();
+ }
+
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionAddToAddressBook::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+ QWidget* FilterActionAddToAddressBook::createParamWidget( QWidget *parent ) const
+ {
+ QWidget *widget = new QWidget( parent );
+diff --git a/mailcommon/filter/filteractionaddtoaddressbook.h b/mailcommon/filter/filteractionaddtoaddressbook.h
+index 61f793f..5647441 100644
+--- a/mailcommon/filter/filteractionaddtoaddressbook.h
++++ b/mailcommon/filter/filteractionaddtoaddressbook.h
+@@ -35,6 +35,8 @@ class FilterActionAddToAddressBook: public FilterActionWithStringList
+ virtual ReturnCode process( ItemContext &context ) const;
+ static FilterAction* newAction();
+
++ virtual SearchRule::RequiredPart requiredPart() const;
++
+ virtual bool isEmpty() const;
+
+ virtual QWidget* createParamWidget( QWidget *parent ) const;
+diff --git a/mailcommon/filter/filteractionbeep.cpp b/mailcommon/filter/filteractionbeep.cpp
+index 0c76ac2..9deb0f7 100644
+--- a/mailcommon/filter/filteractionbeep.cpp
++++ b/mailcommon/filter/filteractionbeep.cpp
+@@ -35,6 +35,13 @@ FilterAction::ReturnCode FilterActionBeep::process( ItemContext &/*context*/ ) c
+ return GoOn;
+ }
+
++
++SearchRule::RequiredPart FilterActionBeep::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+ FilterAction* FilterActionBeep::newAction()
+ {
+ return new FilterActionBeep;
+diff --git a/mailcommon/filter/filteractionbeep.h b/mailcommon/filter/filteractionbeep.h
+index 5dcf5cc..4e9ef42 100644
+--- a/mailcommon/filter/filteractionbeep.h
++++ b/mailcommon/filter/filteractionbeep.h
+@@ -30,6 +30,7 @@ class FilterActionBeep : public FilterActionWithNone
+ FilterActionBeep( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
+ static FilterAction* newAction();
++ virtual SearchRule::RequiredPart requiredPart() const;
+ };
+
+ }
+diff --git a/mailcommon/filter/filteractioncopy.cpp b/mailcommon/filter/filteractioncopy.cpp
+index 699b9ce..50ab146 100644
+--- a/mailcommon/filter/filteractioncopy.cpp
++++ b/mailcommon/filter/filteractioncopy.cpp
+@@ -21,6 +21,7 @@
+
+ #include <KDE/Akonadi/ItemCopyJob>
+ #include <KDE/KLocale>
++// #include <KDE/KMessageBox>
+
+ using namespace MailCommon;
+
+@@ -32,16 +33,32 @@ FilterActionCopy::FilterActionCopy( QObject *parent )
+ FilterAction::ReturnCode FilterActionCopy::process( ItemContext &context ) const
+ {
+ // copy the message 1:1
+- new Akonadi::ItemCopyJob( context.item(), mFolder, 0 ); // TODO handle error
++ Akonadi::ItemCopyJob *job = new Akonadi::ItemCopyJob( context.item(), mFolder, 0 );
++ connect(job, SIGNAL(result(KJob*)), this, SLOT(jobFinished(KJob*)));
+
+ return GoOn;
+ }
+
++void FilterActionCopy::jobFinished(KJob* job)
++{
++ if (job->error()) {
++ kError() << "Error while moving mail: " << job->errorString();
++// KMessageBox::error(0, i18n("<qt>Error while copying the mail.<br/>The error was: <b>%1</b>.</qt>").arg(job->errorString()),
++// i18n("Filter error"));
++ }
++}
++
++
+ bool FilterActionCopy::requiresBody() const
+ {
+ return false;
+ }
+
++SearchRule::RequiredPart FilterActionCopy::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
+ FilterAction* FilterActionCopy::newAction()
+ {
+ return new FilterActionCopy;
+diff --git a/mailcommon/filter/filteractioncopy.h b/mailcommon/filter/filteractioncopy.h
+index 4291a97..21cf84e 100644
+--- a/mailcommon/filter/filteractioncopy.h
++++ b/mailcommon/filter/filteractioncopy.h
+@@ -22,6 +22,8 @@
+
+ #include "filteractionwithfolder.h"
+
++class KJob;
++
+ namespace MailCommon {
+
+ //=============================================================================
+@@ -30,11 +32,16 @@ namespace MailCommon {
+ //=============================================================================
+ class FilterActionCopy: public FilterActionWithFolder
+ {
++ Q_OBJECT
+ public:
+ FilterActionCopy( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
+ virtual bool requiresBody() const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
++
++ protected Q_SLOTS:
++ void jobFinished(KJob* job);
+ };
+
+ }
+diff --git a/mailcommon/filter/filteractiondelete.cpp b/mailcommon/filter/filteractiondelete.cpp
+index e11978e..da0bbb2 100644
+--- a/mailcommon/filter/filteractiondelete.cpp
++++ b/mailcommon/filter/filteractiondelete.cpp
+@@ -37,6 +37,12 @@ FilterAction::ReturnCode FilterActionDelete::process( ItemContext &context ) con
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionDelete::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+ QWidget* FilterActionDelete::createParamWidget( QWidget *parent ) const
+ {
+ QLabel *lab = new QLabel(parent);
+diff --git a/mailcommon/filter/filteractiondelete.h b/mailcommon/filter/filteractiondelete.h
+index 76881cf..7c83892 100644
+--- a/mailcommon/filter/filteractiondelete.h
++++ b/mailcommon/filter/filteractiondelete.h
+@@ -32,6 +32,7 @@ class FilterActionDelete : public FilterActionWithNone
+ public:
+ FilterActionDelete( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ QWidget* createParamWidget( QWidget *parent ) const;
+ };
+diff --git a/mailcommon/filter/filteractionexec.cpp b/mailcommon/filter/filteractionexec.cpp
+index d3d9653..66ee897 100644
+--- a/mailcommon/filter/filteractionexec.cpp
++++ b/mailcommon/filter/filteractionexec.cpp
+@@ -33,6 +33,11 @@ FilterAction::ReturnCode FilterActionExec::process( ItemContext &context ) const
+ return FilterActionWithCommand::genericProcess( context, false ); // ignore output
+ }
+
++SearchRule::RequiredPart FilterActionExec::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
+ FilterAction* FilterActionExec::newAction()
+ {
+ return new FilterActionExec();
+diff --git a/mailcommon/filter/filteractionexec.h b/mailcommon/filter/filteractionexec.h
+index 5436fb0..94b50e8 100644
+--- a/mailcommon/filter/filteractionexec.h
++++ b/mailcommon/filter/filteractionexec.h
+@@ -33,6 +33,7 @@ class FilterActionExec : public FilterActionWithCommand
+ public:
+ FilterActionExec( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ };
+
+diff --git a/mailcommon/filter/filteractionforward.cpp b/mailcommon/filter/filteractionforward.cpp
+index 4da32ff..25288c2 100644
+--- a/mailcommon/filter/filteractionforward.cpp
++++ b/mailcommon/filter/filteractionforward.cpp
+@@ -79,6 +79,11 @@ FilterAction::ReturnCode FilterActionForward::process( ItemContext &context ) co
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionForward::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
+ QWidget* FilterActionForward::createParamWidget( QWidget *parent ) const
+ {
+ QWidget *addressAndTemplate = new QWidget( parent );
+diff --git a/mailcommon/filter/filteractionforward.h b/mailcommon/filter/filteractionforward.h
+index 0051a68..d5b6682 100644
+--- a/mailcommon/filter/filteractionforward.h
++++ b/mailcommon/filter/filteractionforward.h
+@@ -34,6 +34,7 @@ class FilterActionForward: public FilterActionWithAddress
+ FilterActionForward( QObject *parent = 0 );
+ static FilterAction* newAction();
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ virtual QWidget* createParamWidget( QWidget *parent ) const;
+ virtual void applyParamWidgetValue( QWidget *paramWidget );
+ virtual void setParamWidgetValue( QWidget *paramWidget ) const;
+diff --git a/mailcommon/filter/filteractionmove.cpp b/mailcommon/filter/filteractionmove.cpp
+index 3f7d715..165010d 100644
+--- a/mailcommon/filter/filteractionmove.cpp
++++ b/mailcommon/filter/filteractionmove.cpp
+@@ -53,3 +53,9 @@ bool FilterActionMove::requiresBody() const
+ {
+ return false;
+ }
++
++SearchRule::RequiredPart FilterActionMove::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
+diff --git a/mailcommon/filter/filteractionmove.h b/mailcommon/filter/filteractionmove.h
+index 22f4541..aa9ab16 100644
+--- a/mailcommon/filter/filteractionmove.h
++++ b/mailcommon/filter/filteractionmove.h
+@@ -30,10 +30,12 @@ namespace MailCommon {
+ //=============================================================================
+ class FilterActionMove: public FilterActionWithFolder
+ {
++ Q_OBJECT
+ public:
+ FilterActionMove( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
+ virtual bool requiresBody() const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ };
+
+diff --git a/mailcommon/filter/filteractionpipethrough.cpp b/mailcommon/filter/filteractionpipethrough.cpp
+index 0313a20..20a7c1b 100644
+--- a/mailcommon/filter/filteractionpipethrough.cpp
++++ b/mailcommon/filter/filteractionpipethrough.cpp
+@@ -37,3 +37,9 @@ FilterAction::ReturnCode FilterActionPipeThrough::process( ItemContext &context
+ {
+ return FilterActionWithCommand::genericProcess( context, true ); // use output
+ }
++
++SearchRule::RequiredPart FilterActionPipeThrough::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
+diff --git a/mailcommon/filter/filteractionpipethrough.h b/mailcommon/filter/filteractionpipethrough.h
+index 5135fa9..382d107 100644
+--- a/mailcommon/filter/filteractionpipethrough.h
++++ b/mailcommon/filter/filteractionpipethrough.h
+@@ -34,6 +34,7 @@ class FilterActionPipeThrough: public FilterActionWithCommand
+ public:
+ FilterActionPipeThrough( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ };
+
+diff --git a/mailcommon/filter/filteractionplaysound.cpp b/mailcommon/filter/filteractionplaysound.cpp
+index f3ad74c..faa7113 100644
+--- a/mailcommon/filter/filteractionplaysound.cpp
++++ b/mailcommon/filter/filteractionplaysound.cpp
+@@ -72,6 +72,12 @@ bool FilterActionPlaySound::requiresBody() const
+ return false;
+ }
+
++SearchRule::RequiredPart FilterActionPlaySound::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+ bool FilterActionPlaySound::argsFromStringInteractive( const QString &argsStr, const QString &filterName )
+ {
+ bool needUpdate = false;
+diff --git a/mailcommon/filter/filteractionplaysound.h b/mailcommon/filter/filteractionplaysound.h
+index 6e12a83..456b3a2 100644
+--- a/mailcommon/filter/filteractionplaysound.h
++++ b/mailcommon/filter/filteractionplaysound.h
+@@ -36,11 +36,13 @@ namespace MailCommon {
+ //=============================================================================
+ class FilterActionPlaySound : public FilterActionWithTest
+ {
++ Q_OBJECT
+ public:
+ FilterActionPlaySound( );
+ ~FilterActionPlaySound();
+ virtual ReturnCode process( ItemContext &context ) const;
+ virtual bool requiresBody() const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ virtual bool argsFromStringInteractive( const QString &argsStr, const QString &filterName );
+
+diff --git a/mailcommon/filter/filteractionredirect.cpp b/mailcommon/filter/filteractionredirect.cpp
+index 5f6f586..7498b3a 100644
+--- a/mailcommon/filter/filteractionredirect.cpp
++++ b/mailcommon/filter/filteractionredirect.cpp
+@@ -64,3 +64,8 @@ FilterAction::ReturnCode FilterActionRedirect::process( ItemContext &context ) c
+
+ return GoOn;
+ }
++
++SearchRule::RequiredPart FilterActionRedirect::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
+diff --git a/mailcommon/filter/filteractionredirect.h b/mailcommon/filter/filteractionredirect.h
+index 48a823c..c21c27e 100644
+--- a/mailcommon/filter/filteractionredirect.h
++++ b/mailcommon/filter/filteractionredirect.h
+@@ -33,6 +33,7 @@ class FilterActionRedirect: public FilterActionWithAddress
+ public:
+ FilterActionRedirect( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ };
+
+diff --git a/mailcommon/filter/filteractionremoveheader.cpp b/mailcommon/filter/filteractionremoveheader.cpp
+index 90315ba..2490f6b 100644
+--- a/mailcommon/filter/filteractionremoveheader.cpp
++++ b/mailcommon/filter/filteractionremoveheader.cpp
+@@ -19,8 +19,8 @@
+
+ #include "filteractionremoveheader.h"
+
++#include "messageviewer/minimumcombobox.h"
+
+-#include <messageviewer/minimumcombobox.h>
+ #include <KDE/KLocale>
+
+ using namespace MailCommon;
+@@ -73,6 +73,11 @@ FilterAction::ReturnCode FilterActionRemoveHeader::process( ItemContext &context
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionRemoveHeader::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
+ void FilterActionRemoveHeader::setParamWidgetValue( QWidget *paramWidget ) const
+ {
+ MessageViewer::MinimumComboBox *comboBox = dynamic_cast<MessageViewer::MinimumComboBox*>(paramWidget );
+diff --git a/mailcommon/filter/filteractionremoveheader.h b/mailcommon/filter/filteractionremoveheader.h
+index 77365fc..a1031c3 100644
+--- a/mailcommon/filter/filteractionremoveheader.h
++++ b/mailcommon/filter/filteractionremoveheader.h
+@@ -33,6 +33,7 @@ class FilterActionRemoveHeader: public FilterActionWithStringList
+ public:
+ FilterActionRemoveHeader( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ virtual QWidget* createParamWidget( QWidget *parent ) const;
+ virtual void setParamWidgetValue( QWidget *paramWidget ) const;
+
+diff --git a/mailcommon/filter/filteractionreplyto.cpp b/mailcommon/filter/filteractionreplyto.cpp
+index 97502bd..073f689 100644
+--- a/mailcommon/filter/filteractionreplyto.cpp
++++ b/mailcommon/filter/filteractionreplyto.cpp
+@@ -51,3 +51,9 @@ FilterAction::ReturnCode FilterActionReplyTo::process( ItemContext &context ) co
+
+ return GoOn;
+ }
++
++SearchRule::RequiredPart FilterActionReplyTo::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
+diff --git a/mailcommon/filter/filteractionreplyto.h b/mailcommon/filter/filteractionreplyto.h
+index f8655d9..2bf53c6 100644
+--- a/mailcommon/filter/filteractionreplyto.h
++++ b/mailcommon/filter/filteractionreplyto.h
+@@ -33,6 +33,7 @@ class FilterActionReplyTo: public FilterActionWithAddress
+ public:
+ FilterActionReplyTo( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ };
+
+diff --git a/mailcommon/filter/filteractionrewriteheader.cpp b/mailcommon/filter/filteractionrewriteheader.cpp
+index 6d7c3e4..eea7865 100644
+--- a/mailcommon/filter/filteractionrewriteheader.cpp
++++ b/mailcommon/filter/filteractionrewriteheader.cpp
+@@ -83,6 +83,12 @@ FilterAction::ReturnCode FilterActionRewriteHeader::process( ItemContext &contex
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionRewriteHeader::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
++
+ QWidget* FilterActionRewriteHeader::createParamWidget( QWidget *parent ) const
+ {
+ QWidget *widget = new QWidget( parent );
+diff --git a/mailcommon/filter/filteractionrewriteheader.h b/mailcommon/filter/filteractionrewriteheader.h
+index 825e82d..30a00f4 100644
+--- a/mailcommon/filter/filteractionrewriteheader.h
++++ b/mailcommon/filter/filteractionrewriteheader.h
+@@ -35,6 +35,7 @@ class FilterActionRewriteHeader: public FilterActionWithStringList
+ public:
+ FilterActionRewriteHeader( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ virtual QWidget* createParamWidget( QWidget *parent ) const;
+ virtual void setParamWidgetValue( QWidget *paramWidget ) const;
+ virtual void applyParamWidgetValue( QWidget *paramWidget );
+diff --git a/mailcommon/filter/filteractionsendfakedisposition.cpp b/mailcommon/filter/filteractionsendfakedisposition.cpp
+index 4225f57..f614898 100644
+--- a/mailcommon/filter/filteractionsendfakedisposition.cpp
++++ b/mailcommon/filter/filteractionsendfakedisposition.cpp
+@@ -85,6 +85,12 @@ FilterAction::ReturnCode FilterActionSendFakeDisposition::process( ItemContext &
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionSendFakeDisposition::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
++
+ void FilterActionSendFakeDisposition::argsFromString( const QString &argsStr )
+ {
+ if ( argsStr.length() == 1 ) {
+diff --git a/mailcommon/filter/filteractionsendfakedisposition.h b/mailcommon/filter/filteractionsendfakedisposition.h
+index be25071..0d27ba1 100644
+--- a/mailcommon/filter/filteractionsendfakedisposition.h
++++ b/mailcommon/filter/filteractionsendfakedisposition.h
+@@ -33,6 +33,7 @@ class FilterActionSendFakeDisposition: public FilterActionWithStringList
+ public:
+ FilterActionSendFakeDisposition( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+
+ static FilterAction* newAction();
+
+diff --git a/mailcommon/filter/filteractionsendreceipt.cpp b/mailcommon/filter/filteractionsendreceipt.cpp
+index 3728555..13b3408 100644
+--- a/mailcommon/filter/filteractionsendreceipt.cpp
++++ b/mailcommon/filter/filteractionsendreceipt.cpp
+@@ -22,8 +22,8 @@
+ #include "../mailkernel.h"
+ #include "../mailutil.h"
+
+-#include <messagecomposer/messagefactory.h>
+-#include <messagecomposer/messagesender.h>
++#include "messagecomposer/messagefactory.h"
++#include "messagecomposer/messagesender.h"
+
+ #include <KDE/KLocale>
+
+@@ -53,6 +53,12 @@ FilterAction::ReturnCode FilterActionSendReceipt::process( ItemContext &context
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionSendReceipt::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
++
+ FilterAction* FilterActionSendReceipt::newAction()
+ {
+ return new FilterActionSendReceipt;
+diff --git a/mailcommon/filter/filteractionsendreceipt.h b/mailcommon/filter/filteractionsendreceipt.h
+index bab1294..2d554fd 100644
+--- a/mailcommon/filter/filteractionsendreceipt.h
++++ b/mailcommon/filter/filteractionsendreceipt.h
+@@ -33,6 +33,7 @@ class FilterActionSendReceipt : public FilterActionWithNone
+ public:
+ FilterActionSendReceipt( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction* newAction();
+ };
+
+diff --git a/mailcommon/filter/filteractionsetidentity.cpp b/mailcommon/filter/filteractionsetidentity.cpp
+index 8405964..5b5e9e6 100644
+--- a/mailcommon/filter/filteractionsetidentity.cpp
++++ b/mailcommon/filter/filteractionsetidentity.cpp
+@@ -74,6 +74,12 @@ FilterAction::ReturnCode FilterActionSetIdentity::process( ItemContext &context
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionSetIdentity::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
++
+ QWidget* FilterActionSetIdentity::createParamWidget( QWidget *parent ) const
+ {
+ KPIMIdentities::IdentityCombo *comboBox = new KPIMIdentities::IdentityCombo( KernelIf->identityManager(), parent );
+diff --git a/mailcommon/filter/filteractionsetidentity.h b/mailcommon/filter/filteractionsetidentity.h
+index c054a1e..654675f 100644
+--- a/mailcommon/filter/filteractionsetidentity.h
++++ b/mailcommon/filter/filteractionsetidentity.h
+@@ -33,6 +33,7 @@ class FilterActionSetIdentity: public FilterActionWithUOID
+ public:
+ FilterActionSetIdentity( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ virtual bool argsFromStringInteractive( const QString &argsStr, const QString &filterName );
+ static FilterAction* newAction();
+
+diff --git a/mailcommon/filter/filteractionsetstatus.cpp b/mailcommon/filter/filteractionsetstatus.cpp
+index 3da6102..b257499 100644
+--- a/mailcommon/filter/filteractionsetstatus.cpp
++++ b/mailcommon/filter/filteractionsetstatus.cpp
+@@ -60,3 +60,9 @@ FilterAction::ReturnCode FilterActionSetStatus::process( ItemContext &context )
+ }
+
+
++SearchRule::RequiredPart FilterActionSetStatus::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+diff --git a/mailcommon/filter/filteractionsetstatus.h b/mailcommon/filter/filteractionsetstatus.h
+index 53f64ba..a283950 100644
+--- a/mailcommon/filter/filteractionsetstatus.h
++++ b/mailcommon/filter/filteractionsetstatus.h
+@@ -32,6 +32,7 @@ class FilterActionSetStatus: public FilterActionStatus
+ public:
+ FilterActionSetStatus( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+
+ static FilterAction* newAction();
+
+diff --git a/mailcommon/filter/filteractionsettransport.cpp b/mailcommon/filter/filteractionsettransport.cpp
+index 601db46..d37db8c 100644
+--- a/mailcommon/filter/filteractionsettransport.cpp
++++ b/mailcommon/filter/filteractionsettransport.cpp
+@@ -90,6 +90,12 @@ FilterAction::ReturnCode FilterActionSetTransport::process( ItemContext &context
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionSetTransport::requiredPart() const
++{
++ return SearchRule::CompleteMessage;
++}
++
++
+ void FilterActionSetTransport::applyParamWidgetValue( QWidget *paramWidget )
+ {
+ const MailTransport::TransportComboBox *comboBox = dynamic_cast<MailTransport::TransportComboBox*>( paramWidget );
+diff --git a/mailcommon/filter/filteractionsettransport.h b/mailcommon/filter/filteractionsettransport.h
+index 5c8b063..7cad943 100644
+--- a/mailcommon/filter/filteractionsettransport.h
++++ b/mailcommon/filter/filteractionsettransport.h
+@@ -33,6 +33,7 @@ class FilterActionSetTransport: public FilterAction
+ public:
+ FilterActionSetTransport( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ static FilterAction *newAction();
+ virtual QWidget *createParamWidget( QWidget *parent ) const;
+ /**
+diff --git a/mailcommon/filter/filteractionstatus.cpp b/mailcommon/filter/filteractionstatus.cpp
+index f99b28a..5787485 100644
+--- a/mailcommon/filter/filteractionstatus.cpp
++++ b/mailcommon/filter/filteractionstatus.cpp
+@@ -63,6 +63,11 @@ bool FilterActionStatus::requiresBody() const
+ return false;
+ }
+
++SearchRule::RequiredPart FilterActionStatus::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
+ bool FilterActionStatus::isEmpty() const
+ {
+ return false;
+diff --git a/mailcommon/filter/filteractionstatus.h b/mailcommon/filter/filteractionstatus.h
+index 7867235..1172062 100644
+--- a/mailcommon/filter/filteractionstatus.h
++++ b/mailcommon/filter/filteractionstatus.h
+@@ -25,9 +25,11 @@ namespace MailCommon {
+
+ class FilterActionStatus : public FilterActionWithStringList
+ {
++ Q_OBJECT
+ public:
+ FilterActionStatus(const char *name, const QString &label, QObject *parent = 0);
+ virtual bool requiresBody() const;
++ virtual SearchRule::RequiredPart requiredPart() const;
+ virtual bool isEmpty() const;
+ virtual void argsFromString( const QString &argsStr );
+ virtual QString argsAsString() const;
+diff --git a/mailcommon/filter/filteractionunsetstatus.cpp b/mailcommon/filter/filteractionunsetstatus.cpp
+index 7413aa0..cb0d7d5 100644
+--- a/mailcommon/filter/filteractionunsetstatus.cpp
++++ b/mailcommon/filter/filteractionunsetstatus.cpp
+@@ -17,6 +17,7 @@
+ */
+
+ #include "filteractionunsetstatus.h"
++
+ #include <KDE/KLocale>
+ using namespace MailCommon;
+
+@@ -30,8 +31,6 @@ FilterActionUnsetStatus::FilterActionUnsetStatus( QObject *parent )
+ {
+ }
+
+-
+-
+ FilterAction::ReturnCode FilterActionUnsetStatus::process( ItemContext &context ) const
+ {
+ const int index = mParameterList.indexOf( mParameter );
+@@ -48,3 +47,7 @@ FilterAction::ReturnCode FilterActionUnsetStatus::process( ItemContext &context
+ return GoOn;
+ }
+
++SearchRule::RequiredPart FilterActionUnsetStatus::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
+diff --git a/mailcommon/filter/filteractionunsetstatus.h b/mailcommon/filter/filteractionunsetstatus.h
+index df5651d..53c8095 100644
+--- a/mailcommon/filter/filteractionunsetstatus.h
++++ b/mailcommon/filter/filteractionunsetstatus.h
+@@ -27,7 +27,8 @@ class FilterActionUnsetStatus: public FilterActionStatus
+ public:
+ FilterActionUnsetStatus( QObject *parent = 0 );
+ virtual ReturnCode process( ItemContext &context ) const;
+-
++ virtual SearchRule::RequiredPart requiredPart() const;
++
+ static FilterAction* newAction();
+ };
+ }
+diff --git a/mailcommon/filter/filterimporter/filterimporterevolution.cpp b/mailcommon/filter/filterimporter/filterimporterevolution.cpp
+index ca996ab..edeb69f 100644
+--- a/mailcommon/filter/filterimporter/filterimporterevolution.cpp
++++ b/mailcommon/filter/filterimporter/filterimporterevolution.cpp
+@@ -128,7 +128,7 @@ void FilterImporterEvolution::parsePartAction( const QDomElement &ruleFilter,
+ kDebug() << " parttype part : name : not implemented :" << name;
+ }
+ if(fieldName.isEmpty()) {
+- qDebug()<<" parttype part : name : not implemented :" << name;
++ kDebug()<<" parttype part : name : not implemented :" << name;
+ continue;
+ }
+ QString contents;
+@@ -146,7 +146,7 @@ void FilterImporterEvolution::parsePartAction( const QDomElement &ruleFilter,
+ if(name==QLatin1String("flag")) {
+
+ const QString flag = valueFilter.attribute( "value" );
+- qDebug()<<" flag :"<<flag;
++ kDebug()<<" flag :"<<flag;
+ if(flag==QLatin1String("Seen")) {
+ contents = QLatin1String("Read");
+ } else if(flag==QLatin1String("Answered")) {
+@@ -158,7 +158,7 @@ void FilterImporterEvolution::parsePartAction( const QDomElement &ruleFilter,
+ } else if(flag==QLatin1String("Junk")) {
+ contents = QLatin1String("Spam");
+ } else {
+- qDebug()<<" unknown status flags "<<flag;
++ kDebug()<<" unknown status flags "<<flag;
+ }
+ }
+ kDebug() << " value filter name :" << name;
+@@ -195,7 +195,7 @@ void FilterImporterEvolution::parsePartAction( const QDomElement &ruleFilter,
+ }
+ if ( valueFilter.hasAttribute( "value" ) ) {
+ const QString value = valueFilter.attribute( "value" );
+- qDebug() << " value filter value :" << name;
++ kDebug() << " value filter value :" << name;
+ if ( value == QLatin1String( "contains" ) ) {
+ functionName = SearchRule::FuncContains;
+ } else if ( value == QLatin1String( "not contains" ) ) {
+diff --git a/mailcommon/filter/filterimporter/filterimporterprocmail.cpp b/mailcommon/filter/filterimporter/filterimporterprocmail.cpp
+index 67055b0..ea23216 100644
+--- a/mailcommon/filter/filterimporter/filterimporterprocmail.cpp
++++ b/mailcommon/filter/filterimporter/filterimporterprocmail.cpp
+@@ -87,7 +87,7 @@ MailCommon::MailFilter *FilterImporterProcmail::parseLine( QTextStream &stream,
+ line.remove( QLatin1String( "^(To|Cc):" ) );
+ fieldName = "<recipients>";
+ } else {
+- qDebug()<<" line condition not parsed :"<<line;
++ kDebug()<<" line condition not parsed :"<<line;
+ }
+ SearchRule::Ptr rule = SearchRule::createInstance( fieldName, functionName, line );
+ filter->pattern()->append( rule );
+diff --git a/mailcommon/filter/filterimporter/filterimportersylpheed.cpp b/mailcommon/filter/filterimporter/filterimportersylpheed.cpp
+index d23e14f..0e1eb41 100644
+--- a/mailcommon/filter/filterimporter/filterimportersylpheed.cpp
++++ b/mailcommon/filter/filterimporter/filterimportersylpheed.cpp
+@@ -136,7 +136,7 @@ void FilterImporterSylpheed::parseConditions( const QDomElement &e, MailCommon::
+ kDebug() << " tag not recognize " << nexttag;
+ }
+ if(fieldName.isEmpty()) {
+- qDebug()<<" field not implemented "<<nexttag;
++ kDebug()<<" field not implemented "<<nexttag;
+ }
+
+ if ( ruleFilter.hasAttribute( "type" ) ) {
+diff --git a/mailcommon/filter/filtermanager.cpp b/mailcommon/filter/filtermanager.cpp
+index 0f4101b..34ab576 100644
+--- a/mailcommon/filter/filtermanager.cpp
++++ b/mailcommon/filter/filtermanager.cpp
+@@ -142,7 +142,7 @@ void FilterManager::filter( const Akonadi::Item &item, const QString &identifier
+ d->mMailFilterAgentInterface->filter( item.id(), identifier, 0 /*FilterManager::FilterRequires::Unknown*/ );
+ }
+
+-void FilterManager::filter(const qlonglong &id, const QString &identifier , FilterRequires requires) const
++void FilterManager::filter(const qlonglong& id, const QString& identifier, SearchRule::RequiredPart requires) const
+ {
+ d->mMailFilterAgentInterface->filter( id, identifier, static_cast<int>(requires) );
+ }
+@@ -163,7 +163,7 @@ void FilterManager::filter( const Akonadi::Item::List &messages, FilterSet set )
+ }
+
+
+-void FilterManager::filter(const Akonadi::Item::List &messages, FilterRequires requires, const QStringList& listFilters) const
++void FilterManager::filter(const Akonadi::Item::List& messages, SearchRule::RequiredPart requires, const QStringList& listFilters) const
+ {
+ QVector<qlonglong> itemIds;
+
+diff --git a/mailcommon/filter/filtermanager.h b/mailcommon/filter/filtermanager.h
+index 4f069dd..9c75e36 100644
+--- a/mailcommon/filter/filtermanager.h
++++ b/mailcommon/filter/filtermanager.h
+@@ -54,12 +54,6 @@ class MAILCOMMON_EXPORT FilterManager : public QObject
+ All = Inbound|BeforeOutbound|Outbound|Explicit
+ };
+
+- enum FilterRequires {
+- Unknown = 0,
+- HeaderMessage = 1,
+- FullMessage = 2
+- };
+-
+ /**
+ * Returns the global filter manager object.
+ */
+@@ -97,7 +91,7 @@ class MAILCOMMON_EXPORT FilterManager : public QObject
+ void filter( const Akonadi::Item &item, const QString &identifier ) const;
+
+ void filter( const qlonglong &id, const QString &identifier,
+- FilterRequires requires = Unknown ) const;
++ SearchRule::RequiredPart requires ) const;
+
+ /**
+ * Process given message item by applying the filter rules one by
+@@ -124,7 +118,7 @@ class MAILCOMMON_EXPORT FilterManager : public QObject
+
+ void filter( const QVector<qlonglong> &itemIds, FilterSet set = Explicit ) const;
+
+- void filter( const Akonadi::Item::List &messages, FilterRequires requires,
++ void filter( const Akonadi::Item::List &messages, SearchRule::RequiredPart requires,
+ const QStringList &listFilters ) const;
+
+ /// Manage filters interface
+diff --git a/mailcommon/filter/itemcontext.cpp b/mailcommon/filter/itemcontext.cpp
+index 43df66a..2ef50c5 100644
+--- a/mailcommon/filter/itemcontext.cpp
++++ b/mailcommon/filter/itemcontext.cpp
+@@ -21,8 +21,9 @@
+
+ using namespace MailCommon;
+
+-ItemContext::ItemContext( const Akonadi::Item &item )
+- : mItem( item ), mNeedsPayloadStore( false ), mNeedsFlagStore( false ), mDeleteItem( false )
++ItemContext::ItemContext( const Akonadi::Item& item, SearchRule::RequiredPart requestedPart )
++ : mItem( item ), mNeedsPayloadStore( false ), mNeedsFlagStore( false ), mDeleteItem( false ),
++ mRequestedPart( requestedPart )
+ {
+ }
+
+@@ -71,3 +72,8 @@ bool ItemContext::deleteItem() const
+ return mDeleteItem;
+ }
+
++
++bool ItemContext::needsFullPayload() const
++{
++ return mRequestedPart != SearchRule::Envelope;
++}
+diff --git a/mailcommon/filter/itemcontext.h b/mailcommon/filter/itemcontext.h
+index bb4f7cc..89659ba 100644
+--- a/mailcommon/filter/itemcontext.h
++++ b/mailcommon/filter/itemcontext.h
+@@ -21,6 +21,7 @@
+ #define MAILCOMMON_ITEMCONTEXT_H
+
+ #include "../mailcommon_export.h"
++#include "../searchpattern.h"
+
+ #include <Akonadi/Collection>
+ #include <Akonadi/Item>
+@@ -40,8 +41,9 @@ class MAILCOMMON_EXPORT ItemContext
+ public:
+ /**
+ * Creates an item context for the given @p item.
++ * @p requestedPart the part requested for the item (Envelope, Header or CompleteMessage)
+ */
+- ItemContext( const Akonadi::Item &item );
++ ItemContext( const Akonadi::Item &item, SearchRule::RequiredPart requestedPart );
+
+ /**
+ * Returns the item of the context.
+@@ -79,6 +81,10 @@ class MAILCOMMON_EXPORT ItemContext
+ */
+ bool needsFlagStore() const;
+
++ /** Returns true if the full payload was requested for the item or not.
++ * Full payload is needed to change the headers or the body */
++ bool needsFullPayload() const;
++
+ void setDeleteItem();
+ bool deleteItem() const;
+
+@@ -88,6 +94,7 @@ class MAILCOMMON_EXPORT ItemContext
+ bool mNeedsPayloadStore;
+ bool mNeedsFlagStore;
+ bool mDeleteItem;
++ SearchRule::RequiredPart mRequestedPart;
+ };
+
+ }
+diff --git a/mailcommon/filter/kmfilterdialog.cpp b/mailcommon/filter/kmfilterdialog.cpp
+index 20b8d91..227f427 100644
+--- a/mailcommon/filter/kmfilterdialog.cpp
++++ b/mailcommon/filter/kmfilterdialog.cpp
+@@ -641,8 +641,8 @@ void KMFilterDialog::slotRunFilters()
+ i18n( "Filters changed." ) );
+ return;
+ }
+- bool requiresBody = false;
+- const QStringList selectedFiltersId = mFilterList->selectedFilterId(requiresBody);
++ SearchRule::RequiredPart requiredPart = SearchRule::Envelope;
++ const QStringList selectedFiltersId = mFilterList->selectedFilterId( requiredPart );
+ if ( selectedFiltersId.isEmpty() ) {
+ KMessageBox::information(
+ this,
+@@ -652,7 +652,7 @@ void KMFilterDialog::slotRunFilters()
+ return;
+ }
+ Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( mFolderRequester->collection(), this );
+- job->setProperty( "requiresBody", QVariant::fromValue( requiresBody ) );
++ job->setProperty( "requiredPart", QVariant::fromValue( requiredPart ) );
+ job->setProperty( "listFilters", QVariant::fromValue( selectedFiltersId ) );
+
+ connect( job, SIGNAL(result(KJob*)),
+@@ -671,14 +671,9 @@ void KMFilterDialog::slotFetchItemsForFolderDone( KJob *job )
+ filtersId = fjob->property( "listFilters" ).toStringList();
+ }
+
+- MailCommon::FilterManager::FilterRequires requires = MailCommon::FilterManager::Unknown;
+- if ( fjob->property( "requiresBody" ).isValid() ) {
+- bool requiresBody = fjob->property( "requiresBody" ).toBool();
+- if ( requiresBody ) {
+- requires = MailCommon::FilterManager::FullMessage;
+- } else {
+- requires = MailCommon::FilterManager::HeaderMessage;
+- }
++ SearchRule::RequiredPart requires = SearchRule::Envelope;
++ if ( fjob->property( "requiredPart" ).isValid() ) {
++ requires = fjob->property( "requiredPart" ).value<SearchRule::RequiredPart>();
+ }
+ Akonadi::Item::List items = fjob->items();
+ mRunNow->setEnabled( true );
+@@ -1352,20 +1347,18 @@ QList<QListWidgetItem*> KMFilterListBox::selectedFilter()
+ return listWidgetItem;
+ }
+
+-QStringList KMFilterListBox::selectedFilterId( bool &requiresBody ) const
++QStringList KMFilterListBox::selectedFilterId( SearchRule::RequiredPart& requiredPart ) const
+ {
+ QStringList listFilterId;
+- requiresBody = false;
++ requiredPart = SearchRule::Envelope;
+ const int numberOfFilters = mListWidget->count();
+ for ( int i = 0; i <numberOfFilters; ++i ) {
+ if ( mListWidget->item(i)->isSelected() && !mListWidget->item(i)->isHidden() ) {
+ const QString id =
+ static_cast<QListWidgetFilterItem*>( mListWidget->item( i ) )->filter()->identifier();
+ listFilterId << id;
+- if ( !requiresBody ) {
+- requiresBody =
+- static_cast<QListWidgetFilterItem*>( mListWidget->item( i ) )->filter()->requiresBody();
+- }
++ requiredPart = qMax(requiredPart,
++ static_cast<QListWidgetFilterItem*>( mListWidget->item( i ) )->filter()->requiredPart());
+ }
+ }
+ return listFilterId;
+diff --git a/mailcommon/filter/kmfilterdialog.h b/mailcommon/filter/kmfilterdialog.h
+index 3247cb4..1b6964e 100644
+--- a/mailcommon/filter/kmfilterdialog.h
++++ b/mailcommon/filter/kmfilterdialog.h
+@@ -27,6 +27,7 @@
+ #include "filteraction.h"
+ #include "filterimporterexporter.h"
+ #include "mailfilter.h"
++#include "searchpattern.h"
+
+ #include <KDialog>
+
+@@ -137,7 +138,7 @@ class MAILCOMMON_EXPORT KMFilterListBox : public QGroupBox
+ */
+ QList<MailCommon::MailFilter *> filtersForSaving( bool closeAfterSaving ) const;
+
+- QStringList selectedFilterId( bool &requiresBody ) const;
++ QStringList selectedFilterId( SearchRule::RequiredPart &requiredPart ) const;
+
+ signals:
+ /**
+diff --git a/mailcommon/filter/mailfilter.cpp b/mailcommon/filter/mailfilter.cpp
+index 594c38b..1cd2b6d 100644
+--- a/mailcommon/filter/mailfilter.cpp
++++ b/mailcommon/filter/mailfilter.cpp
+@@ -1,6 +1,7 @@
+ /* -*- mode: C++; c-file-style: "gnu" -*-
+ * kmail: KDE mail client
+ * Copyright (c) 1996-1998 Stefan Taferner <taferner at kde.org>
++ * Copyright (C) 2012 Andras Mantia <amantia at kde.org>
+ *
+ * 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
+@@ -41,6 +42,10 @@ using MailCommon::FilterLog;
+ #include <kconfiggroup.h>
+ #include <krandom.h>
+
++#include <algorithm>
++#include <boost/bind.hpp>
++
++
+ using namespace MailCommon;
+
+ MailFilter::MailFilter()
+@@ -233,15 +238,27 @@ MailFilter::AccountType MailFilter::applicability() const
+ return mApplicability;
+ }
+
+-bool MailFilter::requiresBody()
++SearchRule::RequiredPart MailFilter::requiredPart() const
+ {
+- if (pattern() && pattern()->requiresBody())
+- return true; // no pattern means always matches?
+- QListIterator<FilterAction*> it( *actions() );
+- while ( it.hasNext() )
+- if ( it.next()->requiresBody() )
+- return true;
+- return false;
++ //find the required message part needed for the filter
++ //this can be either only the Envelope, all Header or the CompleteMessage
++ //Makes the assumption that Envelope < Header < CompleteMessage
++ int requiredPart = SearchRule::Envelope;
++
++ if (pattern())
++ requiredPart = qMax( requiredPart, (int)pattern()->requiredPart() ) ; // no pattern means always matches?
++
++ int requiredPartByActions = SearchRule::Envelope;
++
++ QList<FilterAction*> actionList = *actions();
++ if (!actionList.isEmpty()) {
++ requiredPartByActions = (*std::max_element(actionList.constBegin(), actionList.constEnd(),
++ boost::bind(&MailCommon::FilterAction::requiredPart, _1) <
++ boost::bind(&MailCommon::FilterAction::requiredPart, _2) ))->requiredPart();
++ }
++ requiredPart = qMax( requiredPart, requiredPartByActions);
++
++ return (SearchRule::RequiredPart) requiredPart;
+ }
+
+ bool MailFilter::folderRemoved( const Akonadi::Collection & aFolder, const Akonadi::Collection& aNewFolder )
+diff --git a/mailcommon/filter/mailfilter.h b/mailcommon/filter/mailfilter.h
+index 1444393..c594333 100644
+--- a/mailcommon/filter/mailfilter.h
++++ b/mailcommon/filter/mailfilter.h
+@@ -104,9 +104,10 @@ public:
+ */
+ ReturnCode execActions( ItemContext &context, bool& stopIt ) const ;
+
+- /** Determines if the filter depends on the body of the message
+- */
+- bool requiresBody();
++ /**
++ * Returns the required part from the item that is needed for the filter to
++ * operate. See @ref SearchRule::RequiredPart */
++ SearchRule::RequiredPart requiredPart() const;
+
+ /** Write contents to given config group. */
+ void writeConfig( KConfigGroup& config, bool exportFilter ) const;
+diff --git a/mailcommon/searchpattern.cpp b/mailcommon/searchpattern.cpp
+index e50f253..d600b35 100644
+--- a/mailcommon/searchpattern.cpp
++++ b/mailcommon/searchpattern.cpp
+@@ -1,6 +1,7 @@
+ /* -*- mode: C++; c-file-style: "gnu" -*-
+
+ Author: Marc Mutz <mutz at kde.org>
++ Copyright (C) 2012 Andras Mantia <amantia at kde.org>
+
+ 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
+@@ -57,6 +58,10 @@ using MailCommon::FilterLog;
+ #include <QRegExp>
+ #include <QXmlStreamWriter>
+
++#include <algorithm>
++#include <boost/bind.hpp>
++
++
+ using namespace MailCommon;
+
+ static const char *funcConfigNames[] =
+@@ -274,11 +279,6 @@ const QString SearchRule::asString() const
+ return result;
+ }
+
+-bool SearchRule::requiresBody() const
+-{
+- return true;
+-}
+-
+ #ifndef KDEPIM_NO_NEPOMUK
+
+ Nepomuk::Query::ComparisonTerm::Comparator SearchRule::nepomukComparator() const
+@@ -436,15 +436,24 @@ bool SearchRuleString::isEmpty() const
+ return field().trimmed().isEmpty() || contents().isEmpty();
+ }
+
+-bool SearchRuleString::requiresBody() const
++SearchRule::RequiredPart SearchRuleString::requiredPart() const
+ {
+- if ( !field().startsWith( '<' ) || field() == "<recipients>" ) {
+- return false;
+- }
++ const QByteArray f = field();
++ SearchRule::RequiredPart part = Header;
++ if ( kasciistricmp( f, "<recipients>" ) == 0 ||
++ kasciistricmp( f, "<status>" ) == 0 ||
++ kasciistricmp( f, "<tag>" ) == 0 ||
++ kasciistricmp( f, "Subject" ) == 0 ||
++ kasciistricmp( f, "From" ) == 0 )
++ part = Envelope;
++ if ( kasciistricmp( f, "<message>" ) == 0 ||
++ kasciistricmp( f, "<body>" ) == 0 )
++ part = CompleteMessage;
+
+- return true;
++ return part;
+ }
+
++
+ bool SearchRuleString::matches( const Akonadi::Item &item ) const
+ {
+ const KMime::Message::Ptr msg = item.payload<KMime::Message::Ptr>();
+@@ -943,6 +952,12 @@ bool SearchRuleNumerical::matches( const Akonadi::Item &item ) const
+ return rc;
+ }
+
++SearchRule::RequiredPart SearchRuleNumerical::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+ bool SearchRuleNumerical::matchesInternal( long numericalValue,
+ long numericalMsgContents, const QString & msgContents ) const
+ {
+@@ -1088,6 +1103,12 @@ bool SearchRuleDate::matchesInternal( const QDate& dateValue,
+ return false;
+ }
+
++SearchRule::RequiredPart SearchRuleDate::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+ #ifndef KDEPIM_NO_NEPOMUK
+
+ void SearchRuleDate::addQueryTerms( Nepomuk::Query::GroupTerm &groupTerm ) const
+@@ -1185,6 +1206,12 @@ bool SearchRuleStatus::matches( const Akonadi::Item &item ) const
+ return rc;
+ }
+
++SearchRule::RequiredPart SearchRuleStatus::requiredPart() const
++{
++ return SearchRule::Envelope;
++}
++
++
+ #ifndef KDEPIM_NO_NEPOMUK
+ void SearchRuleStatus::addTagTerm( Nepomuk::Query::GroupTerm &groupTerm,
+ const QString &tagId ) const
+@@ -1273,7 +1300,7 @@ bool SearchPattern::matches( const Akonadi::Item &item, bool ignoreBody ) const
+ switch ( mOperator ) {
+ case OpAnd: // all rules must match
+ for ( it = constBegin(); it != end; ++it ) {
+- if ( !( (*it)->requiresBody() && ignoreBody ) ) {
++ if ( !( (*it)->requiredPart() == SearchRule::CompleteMessage && ignoreBody ) ) {
+ if ( !(*it)->matches( item ) ) {
+ return false;
+ }
+@@ -1283,7 +1310,7 @@ bool SearchPattern::matches( const Akonadi::Item &item, bool ignoreBody ) const
+
+ case OpOr: // at least one rule must match
+ for ( it = constBegin(); it != end; ++it ) {
+- if ( !( (*it)->requiresBody() && ignoreBody ) ) {
++ if ( !( (*it)->requiredPart() == MailCommon::SearchRule::CompleteMessage && ignoreBody ) ) {
+ if ( (*it)->matches( item ) ) {
+ return true;
+ }
+@@ -1299,18 +1326,19 @@ bool SearchPattern::matches( const Akonadi::Item &item, bool ignoreBody ) const
+ }
+ }
+
+-bool SearchPattern::requiresBody() const
++SearchRule::RequiredPart SearchPattern::requiredPart() const
+ {
+- QList<SearchRule::Ptr>::const_iterator it;
+- QList<SearchRule::Ptr>::const_iterator end( constEnd() );
+- for ( it = constBegin(); it != end; ++it ) {
+- if ( (*it)->requiresBody() ) {
+- return true;
+- }
++ SearchRule::RequiredPart reqPart = SearchRule::Envelope;
++
++ if (!isEmpty()) {
++ reqPart = (*std::max_element(constBegin(), constEnd(),
++ boost::bind(&MailCommon::SearchRule::requiredPart, _1) <
++ boost::bind(&MailCommon::SearchRule::requiredPart, _2) ))->requiredPart();
+ }
+- return false;
++ return reqPart;
+ }
+
++
+ void SearchPattern::purify()
+ {
+ QList<SearchRule::Ptr>::iterator it = end();
+diff --git a/mailcommon/searchpattern.h b/mailcommon/searchpattern.h
+index dcda954..f80d3fb 100644
+--- a/mailcommon/searchpattern.h
++++ b/mailcommon/searchpattern.h
+@@ -104,6 +104,12 @@ class MAILCOMMON_EXPORT SearchRule
+ FuncNotEndWith
+ };
+
++ enum RequiredPart {
++ Envelope = 0,
++ Header,
++ CompleteMessage
++ };
++
+ /**
+ * Creates new new search rule.
+ *
+@@ -195,10 +201,9 @@ class MAILCOMMON_EXPORT SearchRule
+ virtual bool isEmpty() const = 0;
+
+ /**
+- * Returns true if the rule depends on a complete message,
+- * otherwise returns false.
+- */
+- virtual bool requiresBody() const;
++ * Returns the required part from the item that is needed for the search to
++ * operate. See @ref RequiredPart */
++ virtual SearchRule::RequiredPart requiredPart() const = 0;
+
+ /**
+ * Saves the object into a given config @p group.
+@@ -356,10 +361,10 @@ class SearchRuleString : public SearchRule
+ virtual bool isEmpty() const ;
+
+ /**
+- * @copydoc SearchRule::requiresBody()
++ * @copydoc SearchRule::requiredPart()
+ */
+- virtual bool requiresBody() const;
+-
++ virtual RequiredPart requiredPart() const;
++
+ /**
+ * @copydoc SearchRule::matches()
+ */
+@@ -424,6 +429,11 @@ class SearchRuleNumerical : public SearchRule
+ */
+ virtual bool matches( const Akonadi::Item &item ) const;
+
++ /**
++ * @copydoc SearchRule::requiredPart()
++ */
++ virtual RequiredPart requiredPart() const;
++
+ // Optimized matching not implemented, will use the unoptimized matching
+ // from SearchRule
+ using SearchRule::matches;
+@@ -473,6 +483,11 @@ class SearchRuleDate : public SearchRule
+ */
+ virtual bool matches( const Akonadi::Item &item ) const;
+
++ /**
++ * @copydoc SearchRule::requiredPart()
++ */
++ virtual RequiredPart requiredPart() const;
++
+ // Optimized matching not implemented, will use the unoptimized matching
+ // from SearchRule
+ using SearchRule::matches;
+@@ -571,6 +586,11 @@ class MAILCOMMON_EXPORT SearchRuleStatus : public SearchRule
+ virtual bool isEmpty() const ;
+ virtual bool matches( const Akonadi::Item &item ) const;
+
++ /**
++ * @copydoc SearchRule::requiredPart()
++ */
++ virtual RequiredPart requiredPart() const;
++
+ #ifndef KDEPIM_NO_NEPOMUK
+ virtual void addQueryTerms( Nepomuk::Query::GroupTerm &groupTerm ) const;
+ #endif
+@@ -660,10 +680,10 @@ class MAILCOMMON_EXPORT SearchPattern : public QList<SearchRule::Ptr>
+ bool matches( const Akonadi::Item &item, bool ignoreBody = false ) const;
+
+ /**
+- * Returns true if the pattern only depends the DwString that backs a message.
+- */
+- bool requiresBody() const;
+-
++ * Returns the required part from the item that is needed for the search to
++ * operate. See @ref RequiredPart */
++ SearchRule::RequiredPart requiredPart() const;
++
+ /**
+ * Removes all empty rules from the list. You should call this
+ * method whenever the user had had control of the rules outside of
+@@ -781,4 +801,7 @@ class MAILCOMMON_EXPORT SearchPattern : public QList<SearchRule::Ptr>
+ };
+
+ }
++
++Q_DECLARE_METATYPE(MailCommon::SearchRule::RequiredPart)
++
+ #endif /* MAILCOMMON_SEARCHPATTERN_H_ */
+diff --git a/mailcommon/tests/searchpatterntest.cpp b/mailcommon/tests/searchpatterntest.cpp
+index 703a572..e5e5462 100644
+--- a/mailcommon/tests/searchpatterntest.cpp
++++ b/mailcommon/tests/searchpatterntest.cpp
+@@ -69,7 +69,7 @@ class SearchPatternTest : public QObject
+ KConfigGroup cfgGroup( &config, "Filter #0" );
+
+ SearchPattern pattern( cfgGroup );
+- qDebug() << pattern.asString();
++ kDebug() << pattern.asString();
+
+ QFile file( sparqlFile );
+ QVERIFY( file.open( QIODevice::ReadOnly ) );
+diff --git a/mailfilteragent/filtermanager.cpp b/mailfilteragent/filtermanager.cpp
+index 142d978..b985925 100644
+--- a/mailfilteragent/filtermanager.cpp
++++ b/mailfilteragent/filtermanager.cpp
+@@ -1,6 +1,22 @@
+ // -*- mode: C++; c-file-style: "gnu" -*-
+-// kmfiltermgr.cpp
+-
++/* Copyright: before 2012: missing, see KMail copyrights
++ * Copyright (C) 2012 Andras Mantia <amantia at kde.org> *
++ *
++ * 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.
++ *
++ */
+ #include "filtermanager.h"
+
+ #include <akonadi/agentmanager.h>
+@@ -43,7 +59,7 @@ class FilterManager::Private
+ public:
+ Private( FilterManager *qq )
+ : q( qq ),
+- mRequiresBody( false ), mInboundFiltersExist( false )
++ mRequiredPart( SearchRule::Envelope ), mInboundFiltersExist( false )
+ {
+ }
+
+@@ -64,7 +80,7 @@ class FilterManager::Private
+ */
+ FilterManager *q;
+ QList<MailCommon::MailFilter *> mFilters;
+- bool mRequiresBody;
++ SearchRule::RequiredPart mRequiredPart;
+ bool mInboundFiltersExist;
+ };
+
+@@ -99,6 +115,8 @@ void FilterManager::Private::slotItemsFetchedForFilter( const Akonadi::Item::Lis
+ if(listMailFilters.isEmpty())
+ listMailFilters = mFilters;
+
++ SearchRule::RequiredPart requestedPart = q->sender()->property( "requiredPart" ).value<SearchRule::RequiredPart>();
++
+ foreach ( const Akonadi::Item &item, items ) {
+ if ( progressItem ) {
+ progressItem->incCompletedItems();
+@@ -115,7 +133,7 @@ void FilterManager::Private::slotItemsFetchedForFilter( const Akonadi::Item::Lis
+ }
+ }
+
+- const int filterResult = q->process( listMailFilters, item, filterSet );
++ const int filterResult = q->process( listMailFilters, item, requestedPart, filterSet );
+ if ( filterResult == 2 ) {
+ // something went horribly wrong (out of space?)
+ //CommonKernel->emergencyExit( i18n( "Unable to process messages: " ) + QString::fromLocal8Bit( strerror( errno ) ) );
+@@ -149,6 +167,8 @@ void FilterManager::Private::itemFetchJobForFilterDone( KJob *job )
+ return;
+ }
+
++ SearchRule::RequiredPart requestedPart = fetchJob->property( "requiredPart" ).value<SearchRule::RequiredPart>();
++
+ if ( job->property( "filterId" ).isValid() ) {
+ const QString filterId = job->property( "filterId" ).toString();
+
+@@ -166,12 +186,12 @@ void FilterManager::Private::itemFetchJobForFilterDone( KJob *job )
+ return;
+ }
+
+- q->process( items.first(), wantedFilter );
++ q->process( items.first(), requestedPart, wantedFilter );
+ } else {
+ const FilterManager::FilterSet set = static_cast<FilterManager::FilterSet>( job->property( "filterSet" ).toInt() );
+ const QString accountId = job->property( "accountId" ).toString();
+
+- q->process( items.first(), set, !accountId.isEmpty(), accountId );
++ q->process( items.first(), requestedPart, set, !accountId.isEmpty(), accountId );
+ }
+ }
+
+@@ -317,9 +337,13 @@ void FilterManager::readConfig()
+ QStringList emptyFilters;
+ d->mFilters = FilterImporterExporter::readFiltersFromConfig( config, emptyFilters );
+
+- // check if at least one filter requires the message body
+- d->mRequiresBody = std::find_if( d->mFilters.constBegin(), d->mFilters.constEnd(),
+- boost::bind( &MailCommon::MailFilter::requiresBody, _1 ) ) != d->mFilters.constEnd();
++ d->mRequiredPart = SearchRule::Envelope;
++ if (!d->mFilters.isEmpty()){
++ QList<MailFilter*>::const_iterator it = std::max_element(d->mFilters.constBegin(), d->mFilters.constEnd(),
++ boost::bind(&MailCommon::MailFilter::requiredPart, _1) < boost::bind(&MailCommon::MailFilter::requiredPart, _2));
++ d->mRequiredPart = (*it)->requiredPart();
++ }
++ qDebug() << "REQUIRED PART: " << d->mRequiredPart;
+ // check if at least one filter is to be applied on inbound mail
+ d->mInboundFiltersExist = std::find_if( d->mFilters.constBegin(), d->mFilters.constEnd(),
+ boost::bind( &MailCommon::MailFilter::applyOnInbound, _1 ) ) != d->mFilters.constEnd();
+@@ -345,36 +369,35 @@ void FilterManager::filter( qlonglong itemId, FilterSet set, const QString &acco
+ Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( Akonadi::Item( itemId ), this );
+ job->setProperty( "filterSet", static_cast<int>(set) );
+ job->setProperty( "accountId", accountId );
+- if ( d->mRequiresBody )
++ if ( d->mRequiredPart == SearchRule::CompleteMessage )
+ job->fetchScope().fetchFullPayload( true );
+- else
++ else if ( d->mRequiredPart == SearchRule::Header )
+ job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
++ else
++ job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Envelope, true );
+ job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
+
+ connect( job, SIGNAL(result(KJob*)), SLOT(itemFetchJobForFilterDone(KJob*)) );
+ }
+
+-void FilterManager::filter(qlonglong itemId, const QString &filterId , FilterRequires requires)
++void FilterManager::filter(qlonglong itemId, const QString& filterId, SearchRule::RequiredPart requires)
+ {
+ Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( Akonadi::Item( itemId ), this );
+ job->setProperty( "filterId", filterId );
+- if( requires == Unknown) {
+- if ( d->mRequiresBody )
+- job->fetchScope().fetchFullPayload( true );
+- else
+- job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
+- } else if( requires == FullMessage ) {
+- job->fetchScope().fetchFullPayload( true );
+- } else if( requires == HeaderMessage ) {
+- job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
+- }
++
++ if ( requires == SearchRule::CompleteMessage )
++ job->fetchScope().fetchFullPayload( true );
++ else if ( requires == SearchRule::Header )
++ job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
++ else
++ job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Envelope, true );
+
+ job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
+
+ connect( job, SIGNAL(result(KJob*)), SLOT(itemFetchJobForFilterDone(KJob*)) );
+ }
+
+-int FilterManager::process( const Akonadi::Item &item, const MailCommon::MailFilter *filter )
++int FilterManager::process( const Akonadi::Item& item, SearchRule::RequiredPart requestedPart, const MailFilter* filter )
+ {
+ if ( !filter->isEnabled() ) {
+ return 1;
+@@ -393,7 +416,7 @@ int FilterManager::process( const Akonadi::Item &item, const MailCommon::MailFil
+ return 1;
+ }
+
+- ItemContext context( item );
++ ItemContext context( item, requestedPart );
+
+ if ( filter->execActions( context, stopIt ) == MailCommon::MailFilter::CriticalError ) {
+ return 2;
+@@ -427,12 +450,18 @@ bool FilterManager::processContextItem( ItemContext context, bool emitSignal, in
+ }
+ } else if ( context.needsPayloadStore() ) {
+ Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( context.item(), this );
++ //The below is a safety check to ignore modifying payloads if it was not requested,
++ //as in that case we might change the payload to an invalid one
++ modifyJob->setIgnorePayload( !context.needsFullPayload() );
+ if(itemCanDelete) {
+ modifyJob->setProperty( "moveTargetCollection", QVariant::fromValue( context.moveTargetCollection() ) );
+ }
+ connect( modifyJob, SIGNAL(result(KJob*)), SLOT(modifyJobResult(KJob*)));
+ } else if ( context.needsFlagStore() ) {
+ Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( context.item(), this );
++ //The below is a safety check to ignore modifying payloads if it was not requested,
++ //as in that case we might change the payload to an invalid one
++ modifyJob->setIgnorePayload( !context.needsFullPayload() );
+ if(itemCanDelete) {
+ modifyJob->setProperty( "moveTargetCollection", QVariant::fromValue( context.moveTargetCollection() ) );
+ modifyJob->setIgnorePayload( true );
+@@ -457,13 +486,18 @@ bool FilterManager::processContextItem( ItemContext context, bool emitSignal, in
+ }
+
+
+-int FilterManager::process( const QList<MailFilter*>& mailFilters, const Akonadi::Item &item, FilterSet set, bool account, const QString &accountId )
++int FilterManager::process(const QList<MailCommon::MailFilter*>& mailFilters, const Akonadi::Item& item, SearchRule::RequiredPart requestedPart, FilterManager::FilterSet set, bool account, const QString& accountId )
+ {
+ if ( set == NoSet ) {
+ kDebug() << "FilterManager: process() called with not filter set selected";
+ emit itemNotMoved( item );
+ return 1;
+ }
++
++ if ( !item.hasPayload<KMime::Message::Ptr>() ) {
++ kError() << "Filter is null or item doesn't have correct payload.";
++ return 1;
++ }
+
+ bool stopIt = false;
+
+@@ -472,7 +506,7 @@ int FilterManager::process( const QList<MailFilter*>& mailFilters, const Akonadi
+ return 1;
+ }
+
+- ItemContext context( item );
++ ItemContext context( item, requestedPart );
+ QList<MailCommon::MailFilter*>::const_iterator end( mailFilters.constEnd() );
+ for ( QList<MailCommon::MailFilter*>::const_iterator it = mailFilters.constBegin();
+ !stopIt && it != end ; ++it ) {
+@@ -511,15 +545,10 @@ int FilterManager::process( const QList<MailFilter*>& mailFilters, const Akonadi
+ }
+
+
+-int FilterManager::process( const Akonadi::Item &item, FilterSet set,
+- bool account, const QString &accountId )
++int FilterManager::process( const Akonadi::Item &item, SearchRule::RequiredPart requestedPart,
++ FilterSet set, bool account, const QString &accountId )
+ {
+- return process( d->mFilters, item, set, account, accountId );
+-}
+-
+-int FilterManager::process( const Akonadi::Item &item, const QList<MailFilter*>& mailFilters )
+-{
+- return process( mailFilters, item );
++ return process( d->mFilters, item, requestedPart, set, account, accountId );
+ }
+
+ QString FilterManager::createUniqueName( const QString &name ) const
+@@ -546,9 +575,9 @@ QString FilterManager::createUniqueName( const QString &name ) const
+ return uniqueName;
+ }
+
+-bool FilterManager::requiresFullMailBody() const
++MailCommon::SearchRule::RequiredPart FilterManager::requiredPart() const
+ {
+- return d->mRequiresBody;
++ return d->mRequiredPart;
+ }
+
+ #ifndef NDEBUG
+@@ -560,7 +589,7 @@ void FilterManager::dump() const
+ }
+ #endif
+
+-void FilterManager::applySpecificFilters(const QList<Akonadi::Item> &selectedMessages, FilterManager::FilterRequires requires, const QStringList& listFilters )
++void FilterManager::applySpecificFilters(const QList<Akonadi::Item> &selectedMessages, SearchRule::RequiredPart requires, const QStringList& listFilters )
+ {
+ const int msgCountToFilter = selectedMessages.size();
+
+@@ -572,20 +601,18 @@ void FilterManager::applySpecificFilters(const QList<Akonadi::Item> &selectedMes
+ progressItem->setTotalItems( msgCountToFilter );
+
+ Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob( selectedMessages, this );
+- if( requires == Unknown) {
+- if ( d->mRequiresBody )
+- itemFetchJob->fetchScope().fetchFullPayload( true );
+- else
+- itemFetchJob->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
+- } else if( requires == FullMessage ) {
++ if( requires == SearchRule::CompleteMessage ) {
+ itemFetchJob->fetchScope().fetchFullPayload( true );
+- } else if( requires == HeaderMessage ) {
++ } else if( requires == SearchRule::Header ) {
+ itemFetchJob->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
++ } else {
++ itemFetchJob->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Envelope, true );
+ }
+
+ itemFetchJob->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
+ itemFetchJob->setProperty( "progressItem", QVariant::fromValue( static_cast<QObject*>( progressItem ) ) );
+ itemFetchJob->setProperty( "listFilters", QVariant::fromValue( listFilters ) );
++ itemFetchJob->setProperty( "requestedPart", QVariant::fromValue(requires) );
+
+ connect( itemFetchJob, SIGNAL(itemsReceived(Akonadi::Item::List)),
+ this, SLOT(slotItemsFetchedForFilter(Akonadi::Item::List)) );
+@@ -605,13 +632,17 @@ void FilterManager::applyFilters( const QList<Akonadi::Item> &selectedMessages,
+ progressItem->setTotalItems( msgCountToFilter );
+
+ Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob( selectedMessages, this );
+- if ( d->mRequiresBody )
++ if ( d->mRequiredPart == SearchRule::CompleteMessage )
+ itemFetchJob->fetchScope().fetchFullPayload( true );
+- else
++ else if ( d->mRequiredPart == SearchRule::Header )
+ itemFetchJob->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
++ else
++ itemFetchJob->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Envelope, true );
++
+ itemFetchJob->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
+ itemFetchJob->setProperty( "progressItem", QVariant::fromValue( static_cast<QObject*>( progressItem ) ) );
+ itemFetchJob->setProperty( "filterSet", QVariant::fromValue( static_cast<int>( filterSet ) ) );
++ itemFetchJob->setProperty( "requestedPart", QVariant::fromValue(d->mRequiredPart) );
+
+ connect( itemFetchJob, SIGNAL(itemsReceived(Akonadi::Item::List)),
+ this, SLOT(slotItemsFetchedForFilter(Akonadi::Item::List)) );
+diff --git a/mailfilteragent/filtermanager.h b/mailfilteragent/filtermanager.h
+index 4b65af0..ad418e3 100644
+--- a/mailfilteragent/filtermanager.h
++++ b/mailfilteragent/filtermanager.h
+@@ -23,6 +23,8 @@
+ #include <akonadi/collection.h>
+ #include <akonadi/item.h>
+
++#include "mailcommon/searchpattern.h"
++
+ namespace MailCommon {
+ class MailFilter;
+ class ItemContext;
+@@ -96,12 +98,12 @@ class FilterManager: public QObject
+ * 0 otherwise. If the caller does not any longer own the message
+ * he *must* not delete the message or do similar stupid things. ;-)
+ */
+- int process( const Akonadi::Item &item, FilterSet set = Inbound,
++ int process( const Akonadi::Item &item, MailCommon::SearchRule::RequiredPart requestedPart,
++ FilterSet set = Inbound,
+ bool account = false, const QString &accountId = QString() );
+
+- int process( const Akonadi::Item &item, const QList<MailCommon::MailFilter*>& mailFilters );
+-
+- int process( const QList<MailCommon::MailFilter*>& mailFilters, const Akonadi::Item &item, FilterSet set = Inbound,
++ int process( const QList<MailCommon::MailFilter*>& mailFilters, const Akonadi::Item &item,
++ MailCommon::SearchRule::RequiredPart requestedPart, FilterSet set = Inbound,
+ bool account = false, const QString &accountId = QString() );
+
+ /**
+@@ -110,12 +112,12 @@ class FilterManager: public QObject
+ * Applies @p filter to message @p item.
+ * Return codes are as with the above method.
+ */
+- int process( const Akonadi::Item &item, const MailCommon::MailFilter *filter );
++ int process( const Akonadi::Item &item, MailCommon::SearchRule::RequiredPart requestedPart, const MailCommon::MailFilter *filter );
+
+ void filter( qlonglong itemId, FilterSet set, const QString &accountId );
+- void filter( qlonglong itemId, const QString &filterId, FilterRequires requires );
++ void filter( qlonglong itemId, const QString &filterId, MailCommon::SearchRule::RequiredPart requires );
+
+- void applySpecificFilters(const QList<Akonadi::Item> &selectedMessages, FilterManager::FilterRequires requires, const QStringList& listFilters );
++ void applySpecificFilters(const QList<Akonadi::Item> &selectedMessages, MailCommon::SearchRule::RequiredPart requires, const QStringList& listFilters );
+
+ /**
+ * Applies the filters on the given @p messages.
+@@ -125,7 +127,7 @@ class FilterManager: public QObject
+ /**
+ * Returns whether the configured filters need the full mail content.
+ */
+- bool requiresFullMailBody() const;
++ MailCommon::SearchRule::RequiredPart requiredPart() const;
+
+
+ void mailCollectionRemoved( const Akonadi::Collection& collection );
+diff --git a/mailfilteragent/mailfilteragent.cpp b/mailfilteragent/mailfilteragent.cpp
+index 13bd323..7220d90 100644
+--- a/mailfilteragent/mailfilteragent.cpp
++++ b/mailfilteragent/mailfilteragent.cpp
+@@ -117,11 +117,13 @@ void MailFilterAgent::initialCollectionFetchingDone( KJob *job )
+ Akonadi::CollectionFetchJob *fetchJob = qobject_cast<Akonadi::CollectionFetchJob*>( job );
+
+ changeRecorder()->itemFetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
+- changeRecorder()->itemFetchScope().setCacheOnly( true );
+- if (m_filterManager->requiresFullMailBody()) {
++ mRequestedPart = m_filterManager->requiredPart();
++ if (mRequestedPart == MailCommon::SearchRule::CompleteMessage) {
+ changeRecorder()->itemFetchScope().fetchFullPayload();
+- } else {
++ } else if (mRequestedPart == MailCommon::SearchRule::Header) {
+ changeRecorder()->itemFetchScope().fetchPayloadPart( Akonadi::MessagePart::Header, true );
++ } else {
++ changeRecorder()->itemFetchScope().fetchPayloadPart( Akonadi::MessagePart::Envelope, true );
+ }
+ changeRecorder()->fetchCollection( true );
+ changeRecorder()->setChangeRecordingEnabled( false );
+@@ -151,7 +153,7 @@ void MailFilterAgent::itemAdded( const Akonadi::Item &item, const Akonadi::Colle
+ if ( status.isRead() || status.isSpam() || status.isIgnored() )
+ return;
+
+- m_filterManager->process( item, FilterManager::Inbound, true, collection.resource() );
++ m_filterManager->process( item, mRequestedPart, FilterManager::Inbound, true, collection.resource() );
+ }
+
+ void MailFilterAgent::mailCollectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection& )
+@@ -193,7 +195,7 @@ void MailFilterAgent::applySpecificFilters( const QVector<qlonglong> &itemIds, i
+ items << Akonadi::Item( id );
+ }
+
+- m_filterManager->applySpecificFilters( items, static_cast<FilterManager::FilterRequires>(requires),listFilters );
++ m_filterManager->applySpecificFilters( items, static_cast<MailCommon::SearchRule::RequiredPart>(requires),listFilters );
+ }
+
+
+@@ -204,7 +206,7 @@ void MailFilterAgent::filterItem( qlonglong item, int filterSet, const QString &
+
+ void MailFilterAgent::filter(qlonglong item, const QString &filterIdentifier , int requires)
+ {
+- m_filterManager->filter( item, filterIdentifier, static_cast<FilterManager::FilterRequires>(requires) );
++ m_filterManager->filter( item, filterIdentifier, static_cast<MailCommon::SearchRule::RequiredPart>(requires) );
+ }
+
+ void MailFilterAgent::reload()
+diff --git a/mailfilteragent/mailfilteragent.h b/mailfilteragent/mailfilteragent.h
+index d44f068..165b4a1 100644
+--- a/mailfilteragent/mailfilteragent.h
++++ b/mailfilteragent/mailfilteragent.h
+@@ -22,6 +22,8 @@
+
+ #include <akonadi/agentbase.h>
+
++#include "mailcommon/searchpattern.h"
++
+ namespace Akonadi {
+ class Monitor;
+ }
+@@ -62,6 +64,7 @@ class MailFilterAgent : public Akonadi::AgentBase, public Akonadi::AgentBase::Ob
+ FilterManager *m_filterManager;
+
+ FilterLogDialog *m_filterLogDialog;
++ MailCommon::SearchRule::RequiredPart mRequestedPart;
+ };
+
+ #endif
diff --git a/kdepim.spec b/kdepim.spec
index bd30032..1d33082 100644
--- a/kdepim.spec
+++ b/kdepim.spec
@@ -2,7 +2,7 @@ Name: kdepim
Summary: KDE PIM (Personal Information Manager) applications
Epoch: 7
Version: 4.8.95
-Release: 1%{?dist}
+Release: 2%{?dist}
License: GPLv2
Group: Applications/Productivity
@@ -21,7 +21,9 @@ Patch0: kdepim-4.5.85-install-headers.patch
# fix KMail migration (kde#283563)
Patch2: kdepim-4.7.2-kmail-migration.patch
-# upstream patches
+## upstream patches
+# https://projects.kde.org/projects/kde/kdepim/repository/revisions/d64d61b470c56b92294f6adee6d74305a217628d
+Patch100: kdepim-4.8.95-filtering.patch
Provides: kdepim4 = %{version}-%{release}
@@ -94,6 +96,7 @@ Requires: %{name} = %{?epoch:%{epoch}:}%{version}-%{release}
%patch0 -p1 -b .install-headers
%patch2 -p1 -b .kmail-migration
+%patch100 -p1 -b .filtering
%build
@@ -223,6 +226,9 @@ rm -rf %{buildroot}
%changelog
+* Thu Jul 05 2012 Rex Dieter <rdieter at fedoraproject.org> 7:4.8.95-2
+- upstream filter-rework patch
+
* Wed Jun 27 2012 Jaroslav Reznik <jreznik at redhat.com> - 7:4.8.95-1
- 4.8.95
More information about the scm-commits
mailing list