[prev in list] [next in list] [prev in thread] [next in thread]
List: kmail-devel
Subject: branches/work/kdepim-3.5.5+/kmail
From: Allen Winter <winter () kde ! org>
Date: 2006-10-31 1:56:15
Message-ID: 1162259775.092752.6066.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 600586 by winterz:
FEATURE: Andreas' New Background Filtering code
Backported from the patch Andreas provided for trunk.
CCMAIL: kmail-devel@kde.org
M +22 -12 branches/work/kdepim-3.5.5+/kmail/kmcommands.cpp
M +1 -1 branches/work/kdepim-3.5.5+/kmail/kmcommands.h
M +90 -15 branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.cpp
M +14 -6 branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.h
M +13 -2 branches/work/kdepim-3.5.5+/kmail/kmheaders.cpp
--- branches/work/kdepim-3.5.5+/kmail/kmcommands.cpp #600585:600586
@@ -1632,37 +1632,46 @@
KMFilter *filter )
: KMCommand( parent, msgList ), mFilter( filter )
{
+ QPtrListIterator<KMMsgBase> it(msgList);
+ while ( it.current() ) {
+ serNumList.append( (*it)->getMsgSerNum() );
+ ++it;
+ }
}
KMCommand::Result KMFilterActionCommand::execute()
{
KCursorSaver busy( KBusyPtr::busy() );
- QPtrList<KMMessage> msgList = retrievedMsgs();
- for (KMMessage *msg = msgList.first(); msg; msg = msgList.next())
- if( msg->parent() )
- kmkernel->filterMgr()->tempOpenFolder(msg->parent());
-
int msgCount = 0;
- int msgCountToFilter = msgList.count();
- for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
+ int msgCountToFilter = serNumList.count();
+ ProgressItem* progressItem =
+ ProgressManager::createProgressItem ( "filter"+ProgressManager::getUniqueID(),
+ i18n( "Filtering messages" ) );
+ progressItem->setTotalItems( msgCountToFilter );
+ QValueList<Q_UINT32>::const_iterator it;
+ for ( it = serNumList.begin(); it != serNumList.end(); it++ ) {
+ Q_UINT32 serNum = *it;
int diff = msgCountToFilter - ++msgCount;
if ( diff < 10 || !( msgCount % 20 ) || msgCount <= 10 ) {
+ progressItem->updateProgress();
QString statusMsg = i18n("Filtering message %1 of %2");
statusMsg = statusMsg.arg( msgCount ).arg( msgCountToFilter );
KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg );
KApplication::kApplication()->eventLoop()->processEvents( QEventLoop::ExcludeUserInput, 50 );
}
- msg->setTransferInProgress(false);
- int filterResult = kmkernel->filterMgr()->process(msg, mFilter);
+
+ int filterResult = kmkernel->filterMgr()->process( serNum, mFilter );
if (filterResult == 2) {
// something went horribly wrong (out of space?)
perror("Critical error");
kmkernel->emergencyExit( i18n("Not enough free disk space?" ));
}
- msg->setTransferInProgress(true);
+ progressItem->incCompletedItems();
}
+ progressItem->setComplete();
+ progressItem = 0;
return OK;
}
@@ -1694,8 +1703,9 @@
for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next())
scheduler->execFilters( msg );
} else {
- KMCommand *filterCommand = new KMFilterActionCommand( mMainWidget,
- *mHeaders->selectedMsgs(), mFilter);
+ KMCommand *filterCommand =
+ new KMFilterActionCommand( mMainWidget,
+ *mHeaders->selectedMsgs(), mFilter );
filterCommand->start();
int contentX, contentY;
HeaderItem *item = mHeaders->prepareMove( &contentX, &contentY );
--- branches/work/kdepim-3.5.5+/kmail/kmcommands.h #600585:600586
@@ -648,7 +648,7 @@
private:
virtual Result execute();
-
+ QValueList<Q_UINT32> serNumList;
KMFilter *mFilter;
};
--- branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.cpp #600585:600586
@@ -13,9 +13,10 @@
using KMail::FilterLog;
#include "kmfilterdlg.h"
#include "kmfolderindex.h"
+#include "kmfoldermgr.h"
+#include "kmmsgdict.h"
#include "messageproperty.h"
using KMail::MessageProperty;
-#include "kmfoldermgr.h"
// other KDE headers
#include <kdebug.h>
@@ -57,7 +58,7 @@
void KMFilterMgr::clear()
{
mDirtyBufferedFolderTarget = true;
- for ( QValueListIterator<KMFilter*> it = mFilters.begin() ;
+ for ( QValueListIterator<KMFilter*> it = mFilters.begin() ;
it != mFilters.end() ; ++it ) {
delete *it;
}
@@ -113,7 +114,7 @@
// Now, write out the new stuff:
int i = 0;
QString grpName;
- for ( QValueListConstIterator<KMFilter*> it = mFilters.constBegin() ;
+ for ( QValueListConstIterator<KMFilter*> it = mFilters.constBegin() ;
it != mFilters.constEnd() ; ++it ) {
if ( !(*it)->isEmpty() ) {
if ( bPopFilter )
@@ -200,7 +201,7 @@
if (filter->pattern()->matches( msg )) {
if ( FilterLog::instance()->isLogging() ) {
- FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
+ FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
FilterLog::patternResult );
}
if (filter->execActions( msg, stopIt ) == KMFilter::CriticalError)
@@ -220,6 +221,63 @@
return result;
}
+int KMFilterMgr::process( Q_UINT32 serNum, const KMFilter *filter )
+{
+ bool stopIt = false;
+ int result = 1;
+
+ if ( !filter )
+ return 1;
+
+ if ( isMatching( serNum, filter ) ) {
+ KMFolder *folder = 0;
+ int idx = -1;
+ // get the message with the serNum
+ KMMsgDict::instance()->getLocation( serNum, &folder, &idx );
+ if ( !folder || ( idx == -1 ) || ( idx >= folder->count() ) ) {
+ return 1;
+ }
+ bool opened = folder->isOpened();
+ if ( !opened )
+ folder->open();
+ KMMsgBase *msgBase = folder->getMsgBase( idx );
+ bool unGet = !msgBase->isMessage();
+ KMMessage *msg = folder->getMsg( idx );
+ // do the actual filtering stuff
+ if ( !msg || !beginFiltering( msg ) ) {
+ if ( unGet )
+ folder->unGetMsg( idx );
+ if ( !opened )
+ folder->close();
+ return 1;
+ }
+ if ( filter->execActions( msg, stopIt ) == KMFilter::CriticalError ) {
+ if ( unGet )
+ folder->unGetMsg( idx );
+ if ( !opened )
+ folder->close();
+ return 2;
+ }
+
+ KMFolder *targetFolder = MessageProperty::filterFolder( msg );
+
+ endFiltering( msg );
+ if ( targetFolder ) {
+ tempOpenFolder( targetFolder );
+ msg->setTransferInProgress( false );
+ result = targetFolder->moveMsg( msg );
+ msg->setTransferInProgress( true );
+ }
+ if ( unGet )
+ folder->unGetMsg( idx );
+ if ( !opened )
+ folder->close();
+ } else {
+ result = 1;
+ }
+ return result;
+}
+
int KMFilterMgr::process( KMMessage * msg, FilterSet set,
bool account, uint accountId ) {
if ( bPopFilter )
@@ -240,7 +298,7 @@
!stopIt && it != mFilters.constEnd() ; ++it ) {
if ( ( ( (set&Inbound) && (*it)->applyOnInbound() ) &&
- ( !account ||
+ ( !account ||
( account && (*it)->applyOnAccount( accountId ) ) ) ) ||
( (set&Outbound) && (*it)->applyOnOutbound() ) ||
( (set&Explicit) && (*it)->applyOnExplicit() ) ) {
@@ -254,7 +312,7 @@
if ( (*it)->pattern()->matches( msg ) ) {
// filter matches
if ( FilterLog::instance()->isLogging() ) {
- FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
+ FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
FilterLog::patternResult );
}
atLeastOneRuleMatched = true;
@@ -266,8 +324,8 @@
}
KMFolder *folder = MessageProperty::filterFolder( msg );
- /* endFilter does a take() and addButKeepUID() to ensure the changed
- * message is on disk. This is unnessecary if nothing matched, so just
+ /* endFilter does a take() and addButKeepUID() to ensure the changed
+ * message is on disk. This is unnessecary if nothing matched, so just
* reset state and don't update the listview at all. */
if ( atLeastOneRuleMatched )
endFiltering( msg );
@@ -281,6 +339,23 @@
return 1;
}
+bool KMFilterMgr::isMatching( Q_UINT32 serNum, const KMFilter *filter )
+{
+ bool result = false;
+ if ( FilterLog::instance()->isLogging() ) {
+ QString logText( i18n( "<b>Evaluating filter rules:</b> " ) );
+ logText.append( filter->pattern()->asString() );
+ FilterLog::instance()->add( logText, FilterLog::patternDesc );
+ }
+ if ( filter->pattern()->matches( serNum ) ) {
+ if ( FilterLog::instance()->isLogging() ) {
+ FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
+ FilterLog::patternResult );
+ }
+ result = true;
+ }
+ return result;
+}
bool KMFilterMgr::atLeastOneFilterAppliesTo( unsigned int accountID ) const
{
@@ -308,9 +383,9 @@
{
if (!mDirtyBufferedFolderTarget)
return mBufferedFolderTarget;
-
+
mDirtyBufferedFolderTarget = false;
-
+
QValueListConstIterator<KMFilter*> it = mFilters.constBegin();
for ( ; it != mFilters.constEnd() ; ++it ) {
KMFilter *filter = *it;
@@ -375,7 +450,7 @@
// We can't use the parent as long as the dialog is modeless
// and there is one shared dialog for all top level windows.
//
- mEditDialog = new KMFilterDlg( 0, "filterdialog", bPopFilter,
+ mEditDialog = new KMFilterDlg( 0, "filterdialog", bPopFilter,
checkForEmptyFilterList );
}
mEditDialog->show();
@@ -396,7 +471,7 @@
QString uniqueName = name;
int counter = 0;
bool found = true;
-
+
while ( found ) {
found = false;
for ( QValueListConstIterator<KMFilter*> it = mFilters.constBegin();
@@ -405,7 +480,7 @@
found = true;
++counter;
uniqueName = name;
- uniqueName += QString( " (" ) + QString::number( counter )
+ uniqueName += QString( " (" ) + QString::number( counter )
+ QString( ")" );
break;
}
@@ -456,7 +531,7 @@
bool rem = false;
QValueListConstIterator<KMFilter*> it = mFilters.constBegin();
for ( ; it != mFilters.constEnd() ; ++it )
- if ( (*it)->folderRemoved(aFolder, aNewFolder) )
+ if ( (*it)->folderRemoved(aFolder, aNewFolder) )
rem = true;
return rem;
@@ -467,7 +542,7 @@
#ifndef NDEBUG
void KMFilterMgr::dump(void) const
{
-
+
QValueListConstIterator<KMFilter*> it = mFilters.constBegin();
for ( ; it != mFilters.constEnd() ; ++it ) {
kdDebug(5006) << (*it)->asString() << endl;
--- branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.h #600585:600586
@@ -66,13 +66,13 @@
/**
* Returns whether at least one filter applies to this account,
- * which means that mail must be downloaded in order to be filtered,
+ * which means that mail must be downloaded in order to be filtered,
* for example;
* */
bool atLeastOneFilterAppliesTo( unsigned int accountID ) const;
/**
* Returns whether at least one incoming filter applies to this account,
- * which means that mail must be downloaded in order to be filtered,
+ * which means that mail must be downloaded in order to be filtered,
* for example;
* */
bool atLeastOneIncomingFilterAppliesTo( unsigned int accountID ) const;
@@ -105,20 +105,26 @@
@param msg The message to process.
@param aSet Select the filter set to use.
@param account true if an account id is specified else false
- @param accountId The id of the KMAccount that the message was
+ @param accountId The id of the KMAccount that the message was
retrieved from
@return 2 if a critical error occurred (eg out of disk space)
1 if the caller is still owner of the message and
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( KMMessage * msg, FilterSet aSet = Inbound,
+ int process( KMMessage * msg, FilterSet aSet = Inbound,
bool account = false, uint accountId = 0 );
/** For ad-hoc filters. Applies @p filter to @p msg. Return codes
- are as with the above method. */
+ are as with the above method.
+ @deprecated Use int process( quint32, const KMFilter * )
+ */
int process( KMMessage * msg, const KMFilter * filter );
+ /** For ad-hoc filters. Applies @p filter to message with @p serNum .
+ Return codes are as with the above method. */
+ int process( Q_UINT32 serNum, const KMFilter * filter );
+
void cleanup();
/** Increment the reference count for the filter manager.
Call this method before processing messages with process() */
@@ -174,7 +180,9 @@
void filterListUpdated();
private:
- int processPop( KMMessage * msg ) const;
+ int processPop( KMMessage *msg ) const;
+ /** Find out if a message matches the filter criteria */
+ bool isMatching( Q_UINT32 serNum, const KMFilter *filter );
QGuardedPtr<KMFilterDlg> mEditDialog;
QValueVector<KMFolder *> mOpenFolders;
--- branches/work/kdepim-3.5.5+/kmail/kmheaders.cpp #600585:600586
@@ -18,10 +18,13 @@
#include "kmfoldertree.h"
#include "folderjob.h"
using KMail::FolderJob;
+#include "actionscheduler.h"
+using KMail::ActionScheduler;
#include "broadcaststatus.h"
using KPIM::BroadcastStatus;
-#include "actionscheduler.h"
-using KMail::ActionScheduler;
+#include "progressmanager.h"
+using KPIM::ProgressManager;
+using KPIM::ProgressItem;
#include <maillistdrag.h>
#include "globalsettings.h"
using namespace KPIM;
@@ -1383,9 +1386,14 @@
KCursorSaver busy( KBusyPtr::busy() );
int msgCount = 0;
int msgCountToFilter = msgList->count();
+ ProgressItem* progressItem =
+ ProgressManager::createProgressItem( "filter"+ProgressManager::getUniqueID(),
+ i18n( "Filtering messages" ) );
+ progressItem->setTotalItems( msgCountToFilter );
for (KMMsgBase* msgBase=msgList->first(); msgBase; msgBase=msgList->next()) {
int diff = msgCountToFilter - ++msgCount;
if ( diff < 10 || !( msgCount % 20 ) || msgCount <= 10 ) {
+ progressItem->updateProgress();
QString statusMsg = i18n("Filtering message %1 of %2");
statusMsg = statusMsg.arg( msgCount ).arg( msgCountToFilter );
KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg );
@@ -1405,7 +1413,10 @@
} else {
if (slotFilterMsg(msg) == 2) break;
}
+ progressItem->incCompletedItems();
}
+ progressItem->setComplete();
+ progressItem = 0;
END_TIMER(filter);
SHOW_TIMER(filter);
}
_______________________________________________
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