• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

kmail

kmfiltermgr.cpp

Go to the documentation of this file.
00001 // -*- mode: C++; c-file-style: "gnu" -*-
00002 // kmfiltermgr.cpp
00003 
00004 // my header
00005 #include "kmfiltermgr.h"
00006 
00007 // other kmail headers
00008 #include "filterlog.h"
00009 using KMail::FilterLog;
00010 #include "kmfilterdlg.h"
00011 #include "kmfolderindex.h"
00012 #include "filterimporterexporter.h"
00013 using KMail::FilterImporterExporter;
00014 #include "kmfoldermgr.h"
00015 #include "kmmsgdict.h"
00016 #include "messageproperty.h"
00017 using KMail::MessageProperty;
00018 
00019 // other KDE headers
00020 #include <kdebug.h>
00021 #include <klocale.h>
00022 #include <kconfig.h>
00023 #include <kconfiggroup.h>
00024 
00025 // other Qt headers
00026 #include <QRegExp>
00027 
00028 // other headers
00029 #include <assert.h>
00030 
00031 
00032 //-----------------------------------------------------------------------------
00033 KMFilterMgr::KMFilterMgr( bool popFilter )
00034   : mEditDialog( 0 ),
00035     bPopFilter( popFilter ),
00036     mShowLater( false ),
00037     mDirtyBufferedFolderTarget( true ),
00038     mBufferedFolderTarget( true ),
00039     mRefCount( 0 )
00040 {
00041   if (bPopFilter)
00042     kDebug(5006) <<"pPopFilter set";
00043   connect( kmkernel, SIGNAL( folderRemoved( KMFolder* ) ),
00044            this, SLOT( slotFolderRemoved( KMFolder* ) ) );
00045 }
00046 
00047 
00048 //-----------------------------------------------------------------------------
00049 KMFilterMgr::~KMFilterMgr()
00050 {
00051   deref( true );
00052   writeConfig( false );
00053   clear();
00054 }
00055 
00056 void KMFilterMgr::clear()
00057 {
00058   mDirtyBufferedFolderTarget = true;
00059   qDeleteAll( mFilters );
00060   mFilters.clear();
00061 }
00062 
00063 //-----------------------------------------------------------------------------
00064 void KMFilterMgr::readConfig(void)
00065 {
00066   KConfig* config = KMKernel::config();
00067   clear();
00068 
00069   if ( bPopFilter ) {
00070     KConfigGroup group = config->group( "General" );
00071     mShowLater = group.readEntry( "popshowDLmsgs", 0 );
00072   } 
00073   mFilters = FilterImporterExporter::readFiltersFromConfig( config, bPopFilter );
00074 }
00075 
00076 //-----------------------------------------------------------------------------
00077 void KMFilterMgr::writeConfig(bool withSync)
00078 {
00079   KConfig* config = KMKernel::config();
00080 
00081   // Now, write out the new stuff:  
00082   FilterImporterExporter::writeFiltersToConfig( mFilters, config, bPopFilter );
00083   KConfigGroup group = config->group( "General" );
00084   if ( bPopFilter )
00085       group.writeEntry("popshowDLmsgs", mShowLater);
00086 
00087   if ( withSync ) group.sync();
00088 }
00089 
00090 int KMFilterMgr::processPop( KMMessage * msg ) const {
00091   for ( QList<KMFilter*>::const_iterator it = mFilters.begin();
00092         it != mFilters.end() ; ++it )
00093     if ( (*it)->pattern()->matches( msg ) )
00094       return (*it)->action();
00095   return NoAction;
00096 }
00097 
00098 bool KMFilterMgr::beginFiltering(KMMsgBase *msgBase) const
00099 {
00100   if (MessageProperty::filtering( msgBase ))
00101     return false;
00102   MessageProperty::setFiltering( msgBase, true );
00103   MessageProperty::setFilterFolder( msgBase, 0 );
00104   if ( FilterLog::instance()->isLogging() ) {
00105     FilterLog::instance()->addSeparator();
00106   }
00107   return true;
00108 }
00109 
00110 int KMFilterMgr::moveMessage(KMMessage *msg) const
00111 {
00112   if (MessageProperty::filterFolder(msg)->moveMsg( msg ) == 0) {
00113     if ( kmkernel->folderIsTrash( MessageProperty::filterFolder( msg )))
00114       KMFilterAction::sendMDN( msg, KMime::MDN::Deleted );
00115   } else {
00116     kDebug(5006) <<"KMfilterAction - couldn't move msg";
00117     return 2;
00118   }
00119   return 0;
00120 }
00121 
00122 void KMFilterMgr::endFiltering(KMMsgBase *msgBase) const
00123 {
00124   KMFolder *parent = msgBase->parent();
00125   if ( parent ) {
00126     if ( parent == MessageProperty::filterFolder( msgBase ) ) {
00127       parent->take( parent->find( msgBase ) );
00128     }
00129     else if ( ! MessageProperty::filterFolder( msgBase ) ) {
00130       int index = parent->find( msgBase );
00131       KMMessage *msg = parent->getMsg( index );
00132       parent->take( index );
00133       parent->addMsgKeepUID( msg );
00134     }
00135   }
00136   MessageProperty::setFiltering( msgBase, false );
00137 }
00138 
00139 int KMFilterMgr::process( KMMessage * msg, const KMFilter * filter ) {
00140   bool stopIt = false;
00141   int result = 1;
00142 
00143   if ( !msg || !filter || !beginFiltering( msg ))
00144     return 1;
00145 
00146   if ( isMatching( msg, filter ) ) {
00147     if (filter->execActions( msg, stopIt ) == KMFilter::CriticalError)
00148       return 2;
00149 
00150     KMFolder *folder = MessageProperty::filterFolder( msg );
00151 
00152     endFiltering( msg );
00153     if (folder) {
00154       tempOpenFolder( folder );
00155       result = folder->moveMsg( msg );
00156     }
00157   } else {
00158     endFiltering( msg );
00159     result = 1;
00160   }
00161   return result;
00162 }
00163 
00164 int KMFilterMgr::process( quint32 serNum, const KMFilter * filter ) {
00165   bool stopIt = false;
00166   int result = 1;
00167 
00168   if ( !filter)
00169     return 1;
00170 
00171   if ( isMatching( serNum, filter ) ) {
00172     KMFolder *folder = 0;
00173     int idx = -1;
00174     // get the message with the serNum
00175     KMMsgDict::instance()->getLocation(serNum, &folder, &idx);
00176     if ( !folder || ( idx == -1 ) || ( idx >= folder->count() ) ) {
00177       return 1;
00178     }
00179     KMFolderOpener openFolder( folder, "filtermgr" );
00180     KMMsgBase *msgBase = folder->getMsgBase( idx );
00181     bool unGet = !msgBase->isMessage();
00182     KMMessage *msg = folder->getMsg( idx );
00183     // do the actual filtering stuff
00184     if ( !msg || !beginFiltering( msg ) ) {
00185       if ( unGet) {
00186         folder->unGetMsg( idx );
00187         folder->close( "filtermgr" );
00188       }
00189       return 1;
00190     }
00191     if ( filter->execActions( msg, stopIt ) == KMFilter::CriticalError ) {
00192       if ( unGet ) {
00193         folder->unGetMsg( idx );
00194         folder->close( "filtermgr" );
00195       }
00196       return 2;
00197     }
00198 
00199     KMFolder *targetFolder = MessageProperty::filterFolder( msg );
00200 
00201     endFiltering( msg );
00202     if ( targetFolder ) {
00203       tempOpenFolder( targetFolder );
00204       msg->setTransferInProgress( false );
00205       result = targetFolder->moveMsg( msg );
00206       msg->setTransferInProgress( true );
00207     }
00208     if ( unGet) {
00209       folder->unGetMsg( idx );
00210       folder->close( "filtermgr" );
00211     }
00212   } else {
00213     result = 1;
00214   }
00215   return result;
00216 }
00217 
00218 int KMFilterMgr::process( KMMessage * msg, FilterSet set,
00219                           bool account, uint accountId ) {
00220   if ( bPopFilter )
00221     return processPop( msg );
00222 
00223   if ( set == NoSet ) {
00224     kDebug(5006) <<"KMFilterMgr: process() called with not filter set selected";
00225     return 1;
00226   }
00227 
00228   bool stopIt = false;
00229   bool atLeastOneRuleMatched = false;
00230 
00231   if (!beginFiltering( msg ))
00232     return 1;
00233   for ( QList<KMFilter*>::const_iterator it = mFilters.begin();
00234         !stopIt && it != mFilters.end() ; ++it ) {
00235 
00236     if ( ( ( (set&Inbound) && (*it)->applyOnInbound() ) &&
00237          ( !account ||
00238              ( account && (*it)->applyOnAccount( accountId ) ) ) ) ||
00239          ( (set&Outbound)  && (*it)->applyOnOutbound() ) ||
00240          ( (set&Explicit) && (*it)->applyOnExplicit() ) ) {
00241         // filter is applicable
00242 
00243       if ( isMatching( msg, (*it) ) ) {
00244         // filter matches
00245         atLeastOneRuleMatched = true;
00246         // execute actions:
00247         if ( (*it)->execActions(msg, stopIt) == KMFilter::CriticalError )
00248           return 2;
00249       }
00250     }
00251   }
00252 
00253   KMFolder *folder = MessageProperty::filterFolder( msg );
00254   /* endFilter does a take() and addButKeepUID() to ensure the changed
00255    * message is on disk. This is unnessecary if nothing matched, so just
00256    * reset state and don't update the listview at all. */
00257   if ( atLeastOneRuleMatched )
00258     endFiltering( msg );
00259   else
00260     MessageProperty::setFiltering( msg, false );
00261   if (folder) {
00262     tempOpenFolder( folder );
00263     folder->moveMsg(msg);
00264     return 0;
00265   }
00266   return 1;
00267 }
00268 
00269 bool KMFilterMgr::isMatching( KMMessage * msg, const KMFilter * filter )
00270 {
00271   bool result = false;
00272   if ( FilterLog::instance()->isLogging() ) {
00273     QString logText( i18n( "<b>Evaluating filter rules:</b> " ) );
00274     logText.append( filter->pattern()->asString() );
00275     FilterLog::instance()->add( logText, FilterLog::patternDesc );
00276   }
00277   if ( filter->pattern()->matches( msg ) ) {
00278     if ( FilterLog::instance()->isLogging() ) {
00279       FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
00280                                   FilterLog::patternResult );
00281     }
00282     result = true;
00283   }
00284   return result;
00285 }
00286 
00287 bool KMFilterMgr::isMatching( quint32 serNum, const KMFilter * filter )
00288 {
00289   bool result = false;
00290   if ( FilterLog::instance()->isLogging() ) {
00291     QString logText( i18n( "<b>Evaluating filter rules:</b> " ) );
00292     logText.append( filter->pattern()->asString() );
00293     FilterLog::instance()->add( logText, FilterLog::patternDesc );
00294   }
00295   if ( filter->pattern()->matches( serNum ) ) {
00296     if ( FilterLog::instance()->isLogging() ) {
00297       FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
00298                                   FilterLog::patternResult );
00299     }
00300     result = true;
00301   }
00302   return result;
00303 }
00304 
00305 bool KMFilterMgr::atLeastOneFilterAppliesTo( unsigned int accountID ) const
00306 {
00307   QList<KMFilter*>::const_iterator it = mFilters.begin();
00308   for ( ; it != mFilters.end() ; ++it ) {
00309     if ( (*it)->applyOnAccount( accountID ) ) {
00310       return true;
00311     }
00312   }
00313   return false;
00314 }
00315 
00316 bool KMFilterMgr::atLeastOneIncomingFilterAppliesTo( unsigned int accountID ) const
00317 {
00318   QList<KMFilter*>::const_iterator it = mFilters.begin();
00319   for ( ; it != mFilters.end() ; ++it ) {
00320     if ( (*it)->applyOnInbound() && (*it)->applyOnAccount( accountID ) ) {
00321       return true;
00322     }
00323   }
00324   return false;
00325 }
00326 
00327 bool KMFilterMgr::atLeastOneOnlineImapFolderTarget()
00328 {
00329   if (!mDirtyBufferedFolderTarget)
00330     return mBufferedFolderTarget;
00331 
00332   mDirtyBufferedFolderTarget = false;
00333 
00334   QList<KMFilter*>::const_iterator it = mFilters.begin();
00335   for ( ; it != mFilters.end() ; ++it ) {
00336     KMFilter *filter = *it;
00337     QList<KMFilterAction*>::const_iterator jt = filter->actions()->begin();
00338     const QList<KMFilterAction*>::const_iterator jtend = filter->actions()->end();
00339     for ( ; jt != jtend ; ++jt ) {
00340       KMFilterActionWithFolder *f = dynamic_cast<KMFilterActionWithFolder*>(*jt);
00341       if (!f)
00342         continue;
00343       QString name = f->argsAsString();
00344       KMFolder *folder = kmkernel->imapFolderMgr()->findIdString( name );
00345       if (folder) {
00346         mBufferedFolderTarget = true;
00347         return true;
00348       }
00349     }
00350   }
00351   mBufferedFolderTarget = false;
00352   return false;
00353 }
00354 
00355 //-----------------------------------------------------------------------------
00356 void KMFilterMgr::ref( void )
00357 {
00358   mRefCount++;
00359 }
00360 
00361 //-----------------------------------------------------------------------------
00362 void KMFilterMgr::deref( bool force )
00363 {
00364   if ( !force ) {
00365     mRefCount--;
00366   }
00367   if ( mRefCount < 0 ) {
00368     mRefCount = 0;
00369   }
00370   if ( mRefCount && !force ) {
00371     return;
00372   }
00373   QVector< KMFolder *>::const_iterator it;
00374   for ( it = mOpenFolders.begin(); it != mOpenFolders.end(); ++it ) {
00375     (*it)->close( "filtermgr" );
00376   }
00377   mOpenFolders.clear();
00378 }
00379 
00380 
00381 //-----------------------------------------------------------------------------
00382 int KMFilterMgr::tempOpenFolder( KMFolder *aFolder )
00383 {
00384   assert( aFolder );
00385 
00386   int rc = aFolder->open( "filtermgr" );
00387   if ( rc ) {
00388     return rc;
00389   }
00390 
00391   mOpenFolders.append( aFolder );
00392   return 0;
00393 }
00394 
00395 
00396 //-----------------------------------------------------------------------------
00397 void KMFilterMgr::openDialog( QWidget *, bool checkForEmptyFilterList )
00398 {
00399   if( !mEditDialog )
00400   {
00401     //
00402     // We can't use the parent as long as the dialog is modeless
00403     // and there is one shared dialog for all top level windows.
00404     //
00405     mEditDialog = new KMFilterDlg( 0, bPopFilter, checkForEmptyFilterList );
00406     mEditDialog->setObjectName( "filterdialog" );
00407   }
00408   mEditDialog->show();
00409 }
00410 
00411 
00412 //-----------------------------------------------------------------------------
00413 void KMFilterMgr::createFilter( const QByteArray & field, const QString & value )
00414 {
00415   openDialog( 0, false );
00416   mEditDialog->createFilter( field, value );
00417 }
00418 
00419 
00420 //-----------------------------------------------------------------------------
00421 const QString KMFilterMgr::createUniqueName( const QString & name )
00422 {
00423   QString uniqueName = name;
00424   int counter = 0;
00425   bool found = true;
00426 
00427   while ( found ) {
00428     found = false;
00429     for ( QList<KMFilter*>::const_iterator it = mFilters.begin();
00430           it != mFilters.end(); ++it ) {
00431       if ( !( (*it)->name().compare( uniqueName ) ) ) {
00432         found = true;
00433         ++counter;
00434         uniqueName = name;
00435         uniqueName += QString( " (" ) + QString::number( counter )
00436                     + QString( ")" );
00437         break;
00438       }
00439     }
00440   }
00441   return uniqueName;
00442 }
00443 
00444 
00445 //-----------------------------------------------------------------------------
00446 void KMFilterMgr::appendFilters( const QList<KMFilter*> &filters,
00447                                  bool replaceIfNameExists )
00448 {
00449   mDirtyBufferedFolderTarget = true;
00450   beginUpdate();
00451   if ( replaceIfNameExists ) {
00452     QList<KMFilter*>::const_iterator it1 = filters.begin();
00453     for ( ; it1 != filters.end() ; ++it1 ) {
00454       for ( int i = 0; i < mFilters.count(); i++ ) {
00455         KMFilter *filter = mFilters[i];
00456         if ( (*it1)->name() == filter->name() ) {
00457           mFilters.removeAll( filter );
00458           i = 0;
00459         }
00460       }
00461     }
00462   }
00463   mFilters += filters;
00464   writeConfig( true );
00465   endUpdate();
00466 }
00467 
00468 void KMFilterMgr::setFilters( const QList<KMFilter*> &filters )
00469 {
00470   beginUpdate();
00471   clear();
00472   mFilters = filters;
00473   writeConfig( true );
00474   endUpdate();
00475 }
00476 
00477 void KMFilterMgr::slotFolderRemoved( KMFolder * aFolder )
00478 {
00479   folderRemoved( aFolder, 0 );
00480 }
00481 
00482 //-----------------------------------------------------------------------------
00483 bool KMFilterMgr::folderRemoved(KMFolder* aFolder, KMFolder* aNewFolder)
00484 {
00485   mDirtyBufferedFolderTarget = true;
00486   bool rem = false;
00487   QList<KMFilter*>::const_iterator it = mFilters.begin();
00488   for ( ; it != mFilters.end() ; ++it )
00489     if ( (*it)->folderRemoved(aFolder, aNewFolder) )
00490       rem = true;
00491 
00492   return rem;
00493 }
00494 
00495 
00496 //-----------------------------------------------------------------------------
00497 #ifndef NDEBUG
00498 void KMFilterMgr::dump(void) const
00499 {
00500   QList<KMFilter*>::const_iterator it = mFilters.begin();
00501   for ( ; it != mFilters.end() ; ++it ) {
00502     kDebug(5006) << (*it)->asString();
00503   }
00504 }
00505 #endif
00506 
00507 //-----------------------------------------------------------------------------
00508 void KMFilterMgr::endUpdate(void)
00509 {
00510   emit filterListUpdated();
00511 }
00512 
00513 #include "kmfiltermgr.moc"

kmail

Skip menu "kmail"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  •   doc
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal