[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