[prev in list] [next in list] [prev in thread] [next in thread]
List: kmail-devel
Subject: PATCH imap body search
From: Carsten Burghardt <burghardt () kde ! org>
Date: 2004-09-03 19:32:14
Message-ID: 200409032132.17503.burghardt () kde ! org
[Download RAW message or body]
[Attachment #2 (multipart/signed)]
[Attachment #4 (multipart/mixed)]
Hi folks,
I finally implemented IMAP body search. I extended the normal local search so
that the results are merged with the imap search. I don't download the
messages one by one but use the server. The logic is splitted: searches for
<message> and <body> are send to the server while the rest is done locally. I
don't know if there are any other cases that can't be done with the msgbase
but the cases I checked worked quite well.
Carsten
["imapsearch.diff" (text/x-diff)]
? imapsearch.diff
Index: folderstorage.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/folderstorage.cpp,v
retrieving revision 1.29
diff -u -3 -p -r1.29 folderstorage.cpp
--- folderstorage.cpp 19 Aug 2004 07:03:38 -0000 1.29
+++ folderstorage.cpp 3 Sep 2004 19:30:37 -0000
@@ -46,6 +46,7 @@
#include "listjob.h"
using KMail::ListJob;
#include "kmailicalifaceimpl.h"
+#include "kmsearchpattern.h"
#include <klocale.h>
#include <kconfig.h>
@@ -1006,4 +1007,17 @@ void FolderStorage::setContentsType( KMa
}
}
+//-----------------------------------------------------------------------------
+void FolderStorage::search( KMSearchPattern* pattern )
+{
+ QValueList<Q_UINT32> serNums;
+ for ( int i = 0; i < count(); ++i )
+ {
+ Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder(), i );
+ if ( pattern->matches( serNum ) )
+ serNums.append( serNum );
+ }
+ emit searchDone( folder(), serNums );
+}
+
#include "folderstorage.moc"
Index: folderstorage.h
===================================================================
RCS file: /home/kde/kdepim/kmail/folderstorage.h,v
retrieving revision 1.27
diff -u -3 -p -r1.27 folderstorage.h
--- folderstorage.h 18 Jun 2004 17:04:42 -0000 1.27
+++ folderstorage.h 3 Sep 2004 19:30:38 -0000
@@ -46,6 +46,7 @@
using KMail::FolderJob;
#include "listjob.h"
using KMail::ListJob;
+#include "kmsearchpattern.h"
#include "mimelib/string.h"
@@ -405,6 +406,12 @@ public:
/// @return the type of contents held in this folder (mail, calendar, etc.)
KMail::FolderContentsType contentsType() const { return mContentsType; }
+ /**
+ * Search for messages
+ * The end is signaled with searchDone()
+ */
+ virtual void search( KMSearchPattern* );
+
signals:
/** Emitted when the status, name, or associated accounts of this
folder changed. */
@@ -447,6 +454,12 @@ signals:
/** Emitted when a folder was removed */
void removed(KMFolder*, bool);
+ /**
+ * Emitted when a search is completed
+ * The matching serial numbers are included
+ */
+ void searchDone( KMFolder*, QValueList<Q_UINT32> serNums );
+
public slots:
/** Incrementally update the index if possible else call writeIndex */
virtual int updateIndex() = 0;
Index: kmfldsearch.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfldsearch.cpp,v
retrieving revision 1.133
diff -u -3 -p -r1.133 kmfldsearch.cpp
--- kmfldsearch.cpp 13 Jul 2004 08:48:21 -0000 1.133
+++ kmfldsearch.cpp 3 Sep 2004 19:30:38 -0000
@@ -95,8 +95,6 @@ KMFldSearch::KMFldSearch(KMMainWidget* w
connect(mCbxFolders, SIGNAL(activated(int)),
this, SLOT(slotFolderActivated(int)));
- connect(mCbxFolders, SIGNAL(activated(int)),
- this, SLOT(slotFilterAvailableRules()));
mChkSubFolders = new QCheckBox(i18n("I&nclude sub-folders"), searchWidget);
mChkSubFolders->setChecked(true);
@@ -241,11 +239,6 @@ KMFldSearch::KMFldSearch(KMMainWidget* w
else
kdDebug(5006) << "KMFldSearch: regExpLineEdit not found" << endl;
- // Remove the <message> and <body> rule fields when searching imap folders
- slotFilterAvailableRules();
- connect(mChkbxAllFolders, SIGNAL(toggled(bool)),
- this, SLOT(slotFilterAvailableRules()));
-
//set up actions
KActionCollection *ac = actionCollection();
mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", 0, this,
@@ -365,21 +358,6 @@ void KMFldSearch::slotFolderActivated(in
mBtnSearch->setEnabled(folder);
}
-
-//-----------------------------------------------------------------------------
-void KMFldSearch::slotFilterAvailableRules()
-{
- static bool lastHeadersOnly = false;
- KMFolder* folder = mCbxFolders->getFolder();
- bool headersOnly = folder->folderType() == KMFolderTypeImap;
- if (mChkbxAllFolders->isChecked())
- headersOnly = false;
- if (headersOnly != lastHeadersOnly)
- mPatternEdit->setHeadersOnly( headersOnly );
- lastHeadersOnly = headersOnly;
-}
-
-
//-----------------------------------------------------------------------------
void KMFldSearch::activateFolder(KMFolder *curFolder)
{
Index: kmfldsearch.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfldsearch.h,v
retrieving revision 1.44
diff -u -3 -p -r1.44 kmfldsearch.h
--- kmfldsearch.h 13 Jul 2004 08:48:21 -0000 1.44
+++ kmfldsearch.h 3 Sep 2004 19:30:38 -0000
@@ -69,7 +69,6 @@ protected slots:
virtual void copySelectedToFolder( int menuId );
virtual void moveSelectedToFolder( int menuId );
virtual void slotFolderActivated(int nr);
- virtual void slotFilterAvailableRules();
void slotClearSelection();
void slotReplyToMsg();
void slotReplyAllToMsg();
Index: kmfolderimap.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfolderimap.cpp,v
retrieving revision 1.231
diff -u -3 -p -r1.231 kmfolderimap.cpp
--- kmfolderimap.cpp 28 Aug 2004 12:57:50 -0000 1.231
+++ kmfolderimap.cpp 3 Sep 2004 19:30:39 -0000
@@ -29,6 +29,7 @@
#include "kmfoldertree.h"
#include "undostack.h"
#include "kmfoldermgr.h"
+#include "kmmsgdict.h"
#include "imapjob.h"
using KMail::ImapJob;
#include "attachmentstrategy.h"
@@ -1887,4 +1888,91 @@ void KMFolderImap::slotCreatePendingFold
mFoldersPendingCreation.clear();
}
+//-----------------------------------------------------------------------------
+void KMFolderImap::search( KMSearchPattern* pattern )
+{
+ mLastSearchPattern = pattern;
+
+ // first make sure the folder is complete
+ // needed for local searches and to map the uid to the serial number later
+ connect ( this, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
+ this, SLOT( slotSearch()) );
+ getFolder();
+}
+
+//-----------------------------------------------------------------------------
+void KMFolderImap::slotSearch()
+{
+ disconnect ( this, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
+ this, SLOT( slotSearch()) );
+ if ( !mLastSearchPattern->requiresBody() ||
+ mLastSearchPattern->asImapString().isEmpty() )
+ return FolderStorage::search( mLastSearchPattern );
+
+ // do the IMAP search
+ KURL url = mAccount->getUrl();
+ url.setPath( imapPath() + ";SECTION=" + mLastSearchPattern->asImapString() );
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int) 'E' << url;
+ KIO::SimpleJob *job = KIO::special( url, packedArgs, false );
+ KIO::Scheduler::assignJobToSlave(mAccount->slave(), job);
+ connect( job, SIGNAL(infoMessage(KIO::Job*,const QString&)),
+ SLOT(slotSearchData(KIO::Job*,const QString&)) );
+ connect( job, SIGNAL(result(KIO::Job *)),
+ SLOT(slotSearchResult(KIO::Job *)) );
+}
+
+//-----------------------------------------------------------------------------
+void KMFolderImap::slotSearchData( KIO::Job* job, const QString& data )
+{
+ if ( job->error() )
+ return;
+
+ QValueList<Q_UINT32> serNums;
+ // search for the serial number of the UIDs
+ // data contains all found uids separated by blank
+ if ( mLastSearchPattern->op() == KMSearchPattern::OpAnd )
+ {
+ for ( int i = 0; i < count(); ++i )
+ {
+ KMMsgBase * base = getMsgBase( i );
+ Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder(), i );
+ // merge imap search and local search
+ if ( data.contains( QString::number(base->UID()) ) &&
+ mLastSearchPattern->matches( serNum, true ) )
+ {
+ serNums.append( serNum );
+ }
+ }
+ } else if ( mLastSearchPattern->op() == KMSearchPattern::OpOr )
+ {
+ for ( int i = 0; i < count(); ++i )
+ {
+ KMMsgBase * base = getMsgBase( i );
+ Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder(), i );
+ // either imap search or local search have to match
+ if ( data.contains( QString::number(base->UID()) ) ||
+ mLastSearchPattern->matches( serNum, true ) )
+ {
+ serNums.append( serNum );
+ }
+ }
+ } else
+ kdDebug(5006) << k_funcinfo << "unknown operator" << endl;
+
+ emit searchDone( folder(), serNums );
+}
+
+//-----------------------------------------------------------------------------
+void KMFolderImap::slotSearchResult(KIO::Job *job)
+{
+ if ( job->error() )
+ {
+ QValueList<Q_UINT32> serNums;
+ mAccount->handleJobError( job, i18n("Error while searching.") );
+ emit searchDone( folder(), serNums );
+ }
+}
+
#include "kmfolderimap.moc"
Index: kmfolderimap.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfolderimap.h,v
retrieving revision 1.80
diff -u -3 -p -r1.80 kmfolderimap.h
--- kmfolderimap.h 3 Aug 2004 20:29:57 -0000 1.80
+++ kmfolderimap.h 3 Sep 2004 19:30:39 -0000
@@ -40,6 +40,7 @@ using KMail::ImapAccountBase;
class KMFolderTreeItem;
class KMFolderImap;
+class KMSearchPattern;
namespace KMail {
class FolderJob;
class ImapJob;
@@ -285,6 +286,13 @@ public:
/** Set the user's rights on this folder - called by getUserRights */
void setUserRights( unsigned int userRights );
+ /**
+ * Search for messages
+ * The actual search is done in slotSearch and the end
+ * is signaled with searchDone()
+ */
+ virtual void search( KMSearchPattern* );
+
signals:
void folderComplete(KMFolderImap *folder, bool success);
@@ -417,6 +425,18 @@ protected slots:
*/
void slotCreatePendingFolders();
+ /**
+ * Do an IMAP search
+ * It uses the mLastSearchPattern for this
+ */
+ void slotSearch();
+
+ /**
+ * Is called when the search is done
+ */
+ void slotSearchData( KIO::Job * job, const QString& data );
+ void slotSearchResult( KIO::Job * job );
+
protected:
QString mImapPath;
ulong mLastUid;
@@ -437,6 +457,8 @@ private:
QGuardedPtr<ProgressItem> mMailCheckProgressItem;
ProgressItem *mListDirProgressItem;
QStringList mFoldersPendingCreation;
+ // remember the SearchPattern
+ KMSearchPattern* mLastSearchPattern;
};
#endif // kmfolderimap_h
Index: kmfoldersearch.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfoldersearch.cpp,v
retrieving revision 1.57
diff -u -3 -p -r1.57 kmfoldersearch.cpp
--- kmfoldersearch.cpp 4 Aug 2004 17:09:06 -0000 1.57
+++ kmfoldersearch.cpp 3 Sep 2004 19:30:40 -0000
@@ -55,10 +55,8 @@ KMSearch::KMSearch(QObject * parent, con
:QObject(parent, name)
{
mRemainingFolders = -1;
- mRemainingMessages = -1;
mRecursive = true;
mRunByIndex = mRunning = false;
- mIdle = false;
mRoot = 0;
mSearchPattern = 0;
mSearchedCount = 0;
@@ -90,22 +88,22 @@ bool KMSearch::write(QString location) c
bool KMSearch::read(QString location)
{
- KConfig config(location);
- config.setGroup("Search Folder");
- if (!mSearchPattern)
+ KConfig config( location );
+ config.setGroup( "Search Folder" );
+ if ( !mSearchPattern )
mSearchPattern = new KMSearchPattern();
- mSearchPattern->readConfig(&config);
- QString rootString = config.readEntry("Base");
- mRoot = kmkernel->findFolderById(rootString);
- mRecursive = config.readBoolEntry("Recursive");
+ mSearchPattern->readConfig( &config );
+ QString rootString = config.readEntry( "Base" );
+ mRoot = kmkernel->findFolderById( rootString );
+ mRecursive = config.readBoolEntry( "Recursive" );
return true;
}
void KMSearch::setSearchPattern(KMSearchPattern *searchPattern)
{
- if (running())
+ if ( running() )
stop();
- if (mSearchPattern != searchPattern) {
+ if ( mSearchPattern != searchPattern ) {
delete mSearchPattern;
mSearchPattern = searchPattern;
}
@@ -113,15 +111,15 @@ void KMSearch::setSearchPattern(KMSearch
bool KMSearch::inScope(KMFolder* folder) const
{
- if (mRoot.isNull() || folder == mRoot)
+ if ( mRoot.isNull() || folder == mRoot )
return true;
- if (!recursive())
+ if ( !recursive() )
return false;
KMFolderDir *rootDir = mRoot->child();
KMFolderDir *ancestorDir = folder->parent();
- while (ancestorDir) {
- if (ancestorDir == rootDir)
+ while ( ancestorDir ) {
+ if ( ancestorDir == rootDir )
return true;
ancestorDir = ancestorDir->parent();
}
@@ -130,10 +128,10 @@ bool KMSearch::inScope(KMFolder* folder)
void KMSearch::start()
{
- if (running())
+ if ( running() )
return;
- if (!mSearchPattern) {
+ if ( !mSearchPattern ) {
emit finished(true);
return;
}
@@ -142,198 +140,119 @@ void KMSearch::start()
mFoundCount = 0;
mRunning = true;
mRunByIndex = false;
- if(kmkernel->msgIndex() && kmkernel->msgIndex()->startQuery(this)) {
+ // check if this query can be done with the index
+ if ( kmkernel->msgIndex() && kmkernel->msgIndex()->startQuery( this ) ) {
mRunByIndex = true;
return;
}
- QValueList<QGuardedPtr<KMFolder> > folders;
- folders.append(mRoot);
- if (recursive()) { //Append all descendants to folders
+ mFolders.append( mRoot );
+ if ( recursive() )
+ {
+ //Append all descendants to folders
KMFolderNode* node;
KMFolder* folder;
QValueListConstIterator<QGuardedPtr<KMFolder> > it;
- for (it = folders.begin(); it != folders.end(); ++it) {
+ for ( it = mFolders.begin(); it != mFolders.end(); ++it )
+ {
folder = *it;
KMFolderDir *dir = 0;
- if (folder)
+ if ( folder )
dir = folder->child();
else
dir = &kmkernel->folderMgr()->dir();
- if (!dir)
+ if ( !dir )
continue;
QPtrListIterator<KMFolderNode> it(*dir);
- while ((node = it.current())) {
+ while ( (node = it.current()) ) {
++it;
- if (!node->isDir())
- {
- KMFolder* kmf = dynamic_cast<KMFolder*>(node);
- if (kmf)
- folders.append(kmf);
+ if ( !node->isDir() ) {
+ KMFolder* kmf = dynamic_cast<KMFolder*>( node );
+ if ( kmf )
+ mFolders.append( kmf );
}
}
}
}
-
+
+ mRemainingFolders = mFolders.count();
mLastFolder = QString::null;
- mRemainingFolders = folders.count();
- mRemainingMessages = 0;
- QValueListConstIterator<QGuardedPtr<KMFolder> > it;
- for (it = folders.begin(); it != folders.end(); ++it) {
- KMFolder *folder = *it;
- if (!folder) {
- --mRemainingFolders;
- continue;
- }
- //TODO: Get rid of this protocol check, need a bool KMFolder::isComplete()
- if (folder->folderType() == KMFolderTypeImap) {
- KMFolderImap *imapFolder =
- dynamic_cast<KMFolderImap*>( folder->storage() );
- if (imapFolder && imapFolder->getContentState() ==
- KMFolderImap::imapNoInformation) {
- mIncompleteFolders.append(imapFolder);
- connect(imapFolder, SIGNAL(folderComplete(KMFolderImap*, bool)),
- SLOT(slotFolderComplete(KMFolderImap*, bool)));
- imapFolder->getFolder();
- } else {
- mFolders.append(folder);
- }
- } else {
- mFolders.append(folder);
- }
- }
-
- mProcessNextBatchTimer->start(0, true);
+ mProcessNextBatchTimer->start( 0, true );
}
void KMSearch::stop()
{
- if (!running())
+ if ( !running() )
return;
- if(mRunByIndex) {
- if(kmkernel->msgIndex())
- kmkernel->msgIndex()->stopQuery(this);
+ if ( mRunByIndex ) {
+ if ( kmkernel->msgIndex() )
+ kmkernel->msgIndex()->stopQuery( this );
} else {
- //kill all pending jobs
- QValueListConstIterator<QGuardedPtr<KMFolderImap> > it;
- for (it = mIncompleteFolders.begin();
- it != mIncompleteFolders.end(); ++it) {
- KMFolderImap *aFolder = (*it);
- if (aFolder)
- disconnect(aFolder,
- SIGNAL(folderComplete(KMFolderImap*, bool)),
- this,
- SLOT(slotFolderComplete(KMFolderImap*, bool)));
- }
mIncompleteFolders.clear();
QValueListConstIterator<QGuardedPtr<KMFolder> > jt;
- for (jt = mOpenedFolders.begin(); jt != mOpenedFolders.end(); ++jt) {
+ for ( jt = mOpenedFolders.begin(); jt != mOpenedFolders.end(); ++jt ) {
KMFolder *folder = *jt;
if (folder)
folder->close();
}
}
- mOpenedFolders.clear();
- mRemainingMessages = -1;
mRemainingFolders = -1;
+ mOpenedFolders.clear();
mFolders.clear();
- mLastFolder = "";
+ mLastFolder = QString::null;
mRunByIndex = mRunning = false;
- mIdle = false;
emit finished(false);
}
void KMSearch::slotProcessNextBatch()
{
- if (!running())
+ if ( !running() )
return;
- mIdle = false;
- if (mSerNums.count() != 0) {
- int i = 10;
- QValueListIterator<Q_UINT32> it;
- for (it = mSerNums.begin(); it != mSerNums.end();) {
- if (--i == 0)
- break;
-
- Q_UINT32 serNum = *it;
- it = mSerNums.erase(it);
- --mRemainingMessages;
- ++mSearchedCount;
-
- //TODO: matches should try header rules first and check
- // rule->needsBody() and download imap message if needed
- if (mSearchPattern && !mSearchPattern->matches(serNum))
- continue;
- emit found(serNum);
- ++mFoundCount;
- }
- mProcessNextBatchTimer->start(0, true);
+ if ( mFolders.count() != 0 )
+ {
+ KMFolder *folder = *( mFolders.begin() );
+ mFolders.erase( mFolders.begin() );
+ if ( folder )
+ {
+ mLastFolder = folder->label();
+ folder->open();
+ mOpenedFolders.append( folder );
+ connect( folder->storage(),
+ SIGNAL( searchDone( KMFolder*, QValueList<Q_UINT32> ) ),
+ this,
+ SLOT( slotSearchFolderDone( KMFolder*, QValueList<Q_UINT32> ) ) );
+ folder->storage()->search( mSearchPattern );
+ } else
+ --mRemainingFolders;
+ mProcessNextBatchTimer->start( 0, true );
return;
}
+}
- if (mFolders.count() != 0) {
- --mRemainingFolders;
- KMFolder *folder = *(mFolders.begin());
- if (folder) {
- if (folder->isSystemFolder())
- mLastFolder = i18n(folder->name().utf8());
- else
- mLastFolder = folder->name();
- }
- mFolders.erase(mFolders.begin());
- if (folder) {
- folder->open();
- mOpenedFolders.append(folder);
- for(int i = 0; i < folder->count(); ++i) {
- Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum(folder, i);
- ++mRemainingMessages;
- // Prepend message to the list to search newest mail first.
- mSerNums.prepend(serNum);
- }
- }
- mProcessNextBatchTimer->start(0, true);
- return;
+void KMSearch::slotSearchFolderDone( KMFolder* folder, QValueList<Q_UINT32> serNums )
+{
+ kdDebug(5006) << k_funcinfo << folder->label() << " found " << serNums.count() << endl;
+ --mRemainingFolders;
+ mSearchedCount += folder->count();
+ folder->close();
+ mOpenedFolders.remove( folder );
+ QValueListIterator<Q_UINT32> it;
+ for ( it = serNums.begin(); it != serNums.end(); ++it )
+ {
+ emit found( *it );
+ ++mFoundCount;
}
- if (mRemainingFolders == 0) {
+ if ( mRemainingFolders <= 0 )
+ {
mRunning = false;
- QValueListConstIterator<QGuardedPtr<KMFolder> > it;
- for (it = mOpenedFolders.begin(); it != mOpenedFolders.end(); ++it) {
- KMFolder *folder = *it;
- if (folder)
- folder->close();
- }
- mOpenedFolders.clear();
- mRemainingMessages = -1;
+ mLastFolder = QString::null;
mRemainingFolders = -1;
mFolders.clear();
- mLastFolder = "";
- emit finished(true);
- return;
- }
-
- //wait for imap folders to be retrieved
- mIdle = true;
-}
-
-void KMSearch::slotFolderComplete(KMFolderImap *folder, bool success)
-{
- disconnect(folder, SIGNAL(folderComplete(KMFolderImap*, bool)),
- this, SLOT(slotFolderComplete(KMFolderImap*, bool)));
-
- if (success) {
- //if !(mSearchPattern.hasBodyRules())
- mFolders.append(folder->folder());
- //else
- // get all the bodies of messages in the folder, need kroupware body caching
- if (mIdle)
- mProcessNextBatchTimer->start(0, true);
- } else {
- stop();
+ emit finished( true );
}
}
-
//-----------------------------------------------------------------------------
KMFolderSearch::KMFolderSearch(KMFolder* folder, const char* name)
: FolderStorage(folder, name)
Index: kmfoldersearch.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfoldersearch.h,v
retrieving revision 1.26
diff -u -3 -p -r1.26 kmfoldersearch.h
--- kmfoldersearch.h 10 Jun 2004 16:03:40 -0000 1.26
+++ kmfoldersearch.h 3 Sep 2004 19:30:40 -0000
@@ -63,7 +63,7 @@ signals:
protected slots:
void slotProcessNextBatch();
- void slotFolderComplete(KMFolderImap *folder, bool success);
+ void slotSearchFolderDone( KMFolder*, QValueList<Q_UINT32> );
protected:
friend class KMIndexSearchTarget;
@@ -73,7 +73,6 @@ protected:
void setCurrentFolder(const QString &f) { mLastFolder = f; }
private:
- int mRemainingMessages;
int mRemainingFolders;
bool mRecursive, mRunning, mIdle, mRunByIndex;
QGuardedPtr<KMFolder> mRoot;
Index: kmsearchpattern.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmsearchpattern.cpp,v
retrieving revision 1.70
diff -u -3 -p -r1.70 kmsearchpattern.cpp
--- kmsearchpattern.cpp 31 Jul 2004 13:47:10 -0000 1.70
+++ kmsearchpattern.cpp 3 Sep 2004 19:30:40 -0000
@@ -161,6 +161,25 @@ const QString KMSearchRule::asString() c
return result;
}
+QString KMSearchRule::asImapString() const
+{
+ QString result;
+ if ( mFunction == FuncContainsNot )
+ result = "NOT ";
+ else if ( mFunction != FuncContains )
+ return QString::null;
+
+ if ( mField == "<message>" )
+ result += "TEXT ";
+ else if ( mField == "<body>" )
+ result += "BODY ";
+ else
+ return QString::null;
+
+ result += "\"" + mContents + "\"";
+
+ return result;
+}
//==================================================
@@ -685,7 +704,7 @@ KMSearchPattern::~KMSearchPattern()
{
}
-bool KMSearchPattern::matches( const KMMessage * msg ) const
+bool KMSearchPattern::matches( const KMMessage * msg, bool ignoreBody ) const
{
if ( isEmpty() )
return true;
@@ -694,20 +713,22 @@ bool KMSearchPattern::matches( const KMM
switch ( mOperator ) {
case OpAnd: // all rules must match
for ( it.toFirst() ; it.current() ; ++it )
- if ( !(*it)->matches( msg ) )
- return false;
+ if ( !((*it)->requiresBody() && ignoreBody) )
+ if ( !(*it)->matches( msg ) )
+ return false;
return true;
case OpOr: // at least one rule must match
for ( it.toFirst() ; it.current() ; ++it )
- if ( (*it)->matches( msg ) )
- return true;
+ if ( !((*it)->requiresBody() && ignoreBody) )
+ if ( (*it)->matches( msg ) )
+ return true;
// fall through
default:
return false;
}
}
-bool KMSearchPattern::matches( const DwString & aStr ) const
+bool KMSearchPattern::matches( const DwString & aStr, bool ignoreBody ) const
{
if ( isEmpty() )
return true;
@@ -717,20 +738,22 @@ bool KMSearchPattern::matches( const DwS
switch ( mOperator ) {
case OpAnd: // all rules must match
for ( it.toFirst() ; it.current() ; ++it )
- if ( !(*it)->matches( aStr, msg ) )
- return false;
+ if ( !((*it)->requiresBody() && ignoreBody) )
+ if ( !(*it)->matches( aStr, msg ) )
+ return false;
return true;
case OpOr: // at least one rule must match
for ( it.toFirst() ; it.current() ; ++it )
- if ( (*it)->matches( aStr, msg ) )
- return true;
+ if ( !((*it)->requiresBody() && ignoreBody) )
+ if ( (*it)->matches( aStr, msg ) )
+ return true;
// fall through
default:
return false;
}
}
-bool KMSearchPattern::matches( Q_UINT32 serNum ) const
+bool KMSearchPattern::matches( Q_UINT32 serNum, bool ignoreBody ) const
{
if ( isEmpty() )
return true;
@@ -747,14 +770,14 @@ bool KMSearchPattern::matches( Q_UINT32
if ( !opened )
folder->open();
KMMsgBase *msgBase = folder->getMsgBase(idx);
- if (requiresBody()) {
+ if (requiresBody() && !ignoreBody) {
bool unGet = !msgBase->isMessage();
KMMessage *msg = folder->getMsg(idx);
- res = matches( msg );
+ res = matches( msg, ignoreBody );
if (unGet)
folder->unGetMsg(idx);
} else {
- res = matches( folder->getDwString(idx) );
+ res = matches( folder->getDwString(idx), ignoreBody );
}
if ( !opened )
folder->close();
@@ -882,6 +905,22 @@ QString KMSearchPattern::asString() cons
return result;
}
+QString KMSearchPattern::asImapString() const {
+ QStringList parts;
+ QString result;
+
+ for ( QPtrListIterator<KMSearchRule> it( *this ) ; it.current() ; ++it )
+ if ( !(*it)->asImapString().isEmpty() )
+ parts += (*it)->asImapString();
+
+ if ( mOperator == OpOr )
+ result = "(OR " + parts.join(" ") + ")";
+ else
+ result = parts.join(" ");
+
+ return result;
+}
+
const KMSearchPattern & KMSearchPattern::operator=( const KMSearchPattern & other ) {
if ( this == &other )
return *this;
Index: kmsearchpattern.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmsearchpattern.h,v
retrieving revision 1.27
diff -u -3 -p -r1.27 kmsearchpattern.h
--- kmsearchpattern.h 31 Jul 2004 20:55:49 -0000 1.27
+++ kmsearchpattern.h 3 Sep 2004 19:30:40 -0000
@@ -138,6 +138,9 @@ public:
/** Returns the rule as string. For debugging.*/
const QString asString() const;
+ /** Returns an imap search command */
+ QString asImapString() const;
+
private:
static Function configValueToFunc( const char * str );
static QString functionToString( Function function );
@@ -308,9 +311,9 @@ public:
@return TRUE if the match was successful, FALSE otherwise.
*/
- bool matches( const KMMessage * msg ) const;
- bool matches( const DwString & str ) const;
- bool matches( Q_UINT32 sernum ) const;
+ bool matches( const KMMessage * msg, bool ignoreBody = false ) const;
+ bool matches( const DwString & str, bool ignoreBody = false ) const;
+ bool matches( Q_UINT32 sernum, bool ignoreBody = false ) const;
/** Returns true if the pattern only depends the DwString that backs
a message */
@@ -359,6 +362,9 @@ public:
/** Returns the pattern as string. For debugging.*/
QString asString() const;
+ /** Returns an imap search command */
+ QString asImapString() const;
+
/** Overloaded assignment operator. Makes a deep copy. */
const KMSearchPattern & operator=( const KMSearchPattern & aPattern );
[Attachment #8 (application/pgp-signature)]
_______________________________________________
KMail developers mailing list
KMail-devel@kde.org
https://mail.kde.org/mailman/listinfo/kmail-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic