kmail Library API Documentation

kmfilter.cpp

00001 // -*- mode: C++; c-file-style: "gnu" -*-
00002 // kmfilter.cpp
00003 // Author: Stefan Taferner <taferner@kde.org>
00004 
00005 #ifdef HAVE_CONFIG_H
00006 #include <config.h>
00007 #endif
00008 
00009 #include "kmfilter.h"
00010 #include "kmfilteraction.h"
00011 #include "kmglobal.h"
00012 #include "filterlog.h"
00013 using KMail::FilterLog;
00014 
00015 #include <klocale.h>
00016 #include <kmessagebox.h>
00017 #include <kdebug.h>
00018 #include <kconfig.h>
00019 
00020 #include <assert.h>
00021 
00022 
00023 KMFilter::KMFilter( KConfig* aConfig, bool popFilter )
00024   : bPopFilter(popFilter)
00025 {
00026   if (!bPopFilter)
00027     mActions.setAutoDelete( true );
00028 
00029   if ( aConfig )
00030     readConfig( aConfig );
00031   else if ( bPopFilter )
00032     mAction = Down;
00033   else {
00034     bApplyOnInbound = true;
00035     bApplyOnOutbound = false;
00036     bApplyOnExplicit = true;
00037     bStopProcessingHere = true;
00038     bConfigureShortcut = false;
00039     bConfigureToolbar = false;
00040   }
00041 }
00042 
00043 
00044 KMFilter::KMFilter( const KMFilter & aFilter )
00045 {
00046   bPopFilter = aFilter.isPopFilter();
00047 
00048   if ( !bPopFilter )
00049     mActions.setAutoDelete( true );
00050 
00051   mPattern = aFilter.mPattern;
00052 
00053   if ( bPopFilter ){
00054     mAction = aFilter.mAction;
00055   } else {
00056     bApplyOnInbound = aFilter.applyOnInbound();
00057     bApplyOnOutbound = aFilter.applyOnOutbound();
00058     bApplyOnExplicit = aFilter.applyOnExplicit();
00059     bStopProcessingHere = aFilter.stopProcessingHere();
00060     bConfigureShortcut = aFilter.configureShortcut();
00061     bConfigureToolbar = aFilter.configureToolbar();
00062     mIcon = aFilter.icon();
00063 
00064     QPtrListIterator<KMFilterAction> it( aFilter.mActions );
00065     for ( it.toFirst() ; it.current() ; ++it ) {
00066       KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ (*it)->name() ];
00067       if ( desc ) {
00068     KMFilterAction *f = desc->create();
00069     if ( f ) {
00070       f->argsFromString( (*it)->argsAsString() );
00071       mActions.append( f );
00072     }
00073       }
00074     }
00075   }
00076 }
00077 
00078 // only for !bPopFilter
00079 KMFilter::ReturnCode KMFilter::execActions( KMMessage* msg, bool& stopIt ) const
00080 {
00081   ReturnCode status = NoResult;
00082 
00083   QPtrListIterator<KMFilterAction> it( mActions );
00084   for ( it.toFirst() ; it.current() ; ++it ) {
00085 
00086     if ( FilterLog::instance()->isLogging() ) {
00087       QString logText( i18n( "<b>Applying filter action:</b> " ) );
00088       logText.append( (*it)->label() );
00089       logText.append( " \"" );
00090       logText.append( FilterLog::recode( (*it)->argsAsString() ) );
00091       logText.append( "\"" );
00092       FilterLog::instance()->add( logText, FilterLog::appliedAction );
00093     }
00094 
00095     KMFilterAction::ReturnCode result = (*it)->process( msg );
00096 
00097     switch ( result ) {
00098     case KMFilterAction::CriticalError:
00099       // in case it's a critical error: return immediately!
00100       return CriticalError;
00101     case KMFilterAction::ErrorButGoOn:
00102     default:
00103       break;
00104     }
00105   }
00106 
00107   if ( status == NoResult ) // No filters matched, keep copy of message
00108     status = GoOn;
00109 
00110   stopIt = stopProcessingHere();
00111 
00112   return status;
00113 }
00114 
00115 bool KMFilter::requiresBody( KMMsgBase* msg )
00116 {
00117   if (pattern() && pattern()->requiresBody())
00118     return true; // no pattern means always matches?
00119   QPtrListIterator<KMFilterAction> it( *actions() );
00120   for ( it.toFirst() ; it.current() ; ++it )
00121     if ((*it)->requiresBody( msg ))
00122       return true;
00123   return false;
00124 }
00125 
00127 // only for bPopFilter
00128 void KMFilter::setAction(const KMPopFilterAction aAction)
00129 {
00130   mAction = aAction;
00131 }
00132 
00133 // only for bPopFilter
00134 KMPopFilterAction KMFilter::action()
00135 {
00136   return mAction;
00137 }
00138 
00139 // only for !bPopFilter
00140 bool KMFilter::folderRemoved( KMFolder* aFolder, KMFolder* aNewFolder )
00141 {
00142   bool rem = false;
00143 
00144   QPtrListIterator<KMFilterAction> it( mActions );
00145   for ( it.toFirst() ; it.current() ; ++it )
00146     if ( (*it)->folderRemoved( aFolder, aNewFolder ) )
00147       rem = true;
00148 
00149   return rem;
00150 }
00151 
00152 //-----------------------------------------------------------------------------
00153 void KMFilter::readConfig(KConfig* config)
00154 {
00155   // MKSearchPattern::readConfig ensures
00156   // that the pattern is purified.
00157   mPattern.readConfig(config);
00158 
00159   if (bPopFilter) {
00160     // get the action description...
00161     QString action = config->readEntry( "action" );
00162     if ( action == "down" )
00163       mAction = Down;
00164     else if ( action == "later" )
00165       mAction = Later;
00166     else if ( action == "delete" )
00167       mAction = Delete;
00168     else
00169       mAction = NoAction;
00170   }
00171   else {
00172     QStringList sets = config->readListEntry("apply-on");
00173     if ( sets.isEmpty() && !config->hasKey("apply-on") ) {
00174       bApplyOnOutbound = false;
00175       bApplyOnInbound = true;
00176       bApplyOnExplicit = true;
00177     } else {
00178       bApplyOnInbound = bool(sets.contains("check-mail"));
00179       bApplyOnOutbound = bool(sets.contains("send-mail"));
00180       bApplyOnExplicit = bool(sets.contains("manual-filtering"));
00181     }
00182 
00183     bStopProcessingHere = config->readBoolEntry("StopProcessingHere", true);
00184     bConfigureShortcut = config->readBoolEntry("ConfigureShortcut", false);
00185     bConfigureToolbar = config->readBoolEntry("ConfigureToolbar", false);
00186     bConfigureToolbar = bConfigureToolbar && bConfigureShortcut;
00187     mIcon = config->readEntry( "Icon", "gear" );
00188 
00189     int i, numActions;
00190     QString actName, argsName;
00191 
00192     mActions.clear();
00193 
00194     numActions = config->readNumEntry("actions",0);
00195     if (numActions > FILTER_MAX_ACTIONS) {
00196       numActions = FILTER_MAX_ACTIONS ;
00197       KMessageBox::information( 0, i18n("<qt>Too many filter actions in filter rule <b>%1</b>.</qt>").arg( mPattern.name() ) );
00198     }
00199 
00200     for ( i=0 ; i < numActions ; i++ ) {
00201       actName.sprintf("action-name-%d", i);
00202       argsName.sprintf("action-args-%d", i);
00203       // get the action description...
00204       KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ config->readEntry( actName ) ];
00205       if ( desc ) {
00206         //...create an instance...
00207         KMFilterAction *fa = desc->create();
00208         if ( fa ) {
00209       //...load it with it's parameter...
00210           fa->argsFromString( config->readEntry( argsName ) );
00211       //...check if it's emoty and...
00212       if ( !fa->isEmpty() )
00213         //...append it if it's not and...
00214         mActions.append( fa );
00215       else
00216         //...delete is else.
00217         delete fa;
00218         }
00219       } else
00220         KMessageBox::information( 0 /* app-global modal dialog box */,
00221                   i18n("<qt>Unknown filter action <b>%1</b><br>in filter rule <b>%2</b>.<br>Ignoring it.</qt>")
00222                        .arg( config->readEntry( actName ) ).arg( mPattern.name() ) );
00223     }
00224   }
00225 }
00226 
00227 
00228 void KMFilter::writeConfig(KConfig* config) const
00229 {
00230   mPattern.writeConfig(config);
00231 
00232   if (bPopFilter) {
00233     switch ( mAction ) {
00234     case Down:
00235       config->writeEntry( "action", "down" );
00236       break;
00237     case Later:
00238       config->writeEntry( "action", "later" );
00239       break;
00240     case Delete:
00241       config->writeEntry( "action", "delete" );
00242       break;
00243     default:
00244       config->writeEntry( "action", "" );
00245     }
00246   } else {
00247     QStringList sets;
00248     if ( bApplyOnInbound )
00249       sets.append( "check-mail" );
00250     if ( bApplyOnOutbound )
00251       sets.append( "send-mail" );
00252     if ( bApplyOnExplicit )
00253       sets.append( "manual-filtering" );
00254     config->writeEntry( "apply-on", sets );
00255 
00256     config->writeEntry( "StopProcessingHere", bStopProcessingHere );
00257     config->writeEntry( "ConfigureShortcut", bConfigureShortcut );
00258     config->writeEntry( "ConfigureToolbar", bConfigureToolbar );
00259     config->writeEntry( "Icon", mIcon );
00260 
00261     QString key;
00262     int i;
00263 
00264     QPtrListIterator<KMFilterAction> it( mActions );
00265     for ( i=0, it.toFirst() ; it.current() ; ++it, ++i ) {
00266       config->writeEntry( key.sprintf("action-name-%d", i),
00267                   (*it)->name() );
00268       config->writeEntry( key.sprintf("action-args-%d", i),
00269               (*it)->argsAsString() );
00270     }
00271     config->writeEntry("actions", i );
00272   }
00273 }
00274 
00275 void KMFilter::purify()
00276 {
00277   mPattern.purify();
00278 
00279   if (!bPopFilter) {
00280     QPtrListIterator<KMFilterAction> it( mActions );
00281     it.toLast();
00282     while ( it.current() )
00283       if ( (*it)->isEmpty() )
00284         mActions.remove ( (*it) );
00285       else
00286         --it;
00287   }
00288 }
00289 
00290 bool KMFilter::isEmpty() const
00291 {
00292   if (bPopFilter)
00293     return mPattern.isEmpty();
00294   else
00295     return mPattern.isEmpty() && mActions.isEmpty();
00296 }
00297 
00298 #ifndef NDEBUG
00299 const QString KMFilter::asString() const
00300 {
00301   QString result;
00302 
00303   result += mPattern.asString();
00304 
00305   if (bPopFilter){
00306     result += "    action: ";
00307     result += mAction;
00308     result += "\n";
00309   }
00310   else {
00311     QPtrListIterator<KMFilterAction> it( mActions );
00312     for ( it.toFirst() ; it.current() ; ++it ) {
00313       result += "    action: ";
00314       result += (*it)->label();
00315       result += " ";
00316       result += (*it)->argsAsString();
00317       result += "\n";
00318     }
00319     result += "This filter belongs to the following sets:";
00320     if ( bApplyOnInbound )
00321       result += " Inbound";
00322     if ( bApplyOnOutbound )
00323       result += " Outbound";
00324     if ( bApplyOnExplicit )
00325       result += " Explicit";
00326     result += "\n";
00327     if ( bStopProcessingHere )
00328       result += "If it matches, processing stops at this filter.\n";
00329   }
00330   return result;
00331 }
00332 #endif
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 22:43:45 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003