summaryrefslogtreecommitdiffstats
path: root/kmail/kmfilter.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /kmail/kmfilter.cpp
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kmail/kmfilter.cpp')
-rw-r--r--kmail/kmfilter.cpp430
1 files changed, 430 insertions, 0 deletions
diff --git a/kmail/kmfilter.cpp b/kmail/kmfilter.cpp
new file mode 100644
index 00000000..d4456234
--- /dev/null
+++ b/kmail/kmfilter.cpp
@@ -0,0 +1,430 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ * kmail: KDE mail client
+ * Copyright (c) 1996-1998 Stefan Taferner <taferner@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kmfilter.h"
+#include "kmkernel.h"
+#include "accountmanager.h"
+using KMail::AccountManager;
+#include "kmacctimap.h"
+#include "kmfilteraction.h"
+#include "kmglobal.h"
+#include "filterlog.h"
+using KMail::FilterLog;
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kconfig.h>
+
+#include <assert.h>
+
+
+KMFilter::KMFilter( KConfig* aConfig, bool popFilter )
+ : bPopFilter(popFilter)
+{
+ if (!bPopFilter)
+ mActions.setAutoDelete( true );
+
+ if ( aConfig )
+ readConfig( aConfig );
+ else if ( bPopFilter )
+ mAction = Down;
+ else {
+ bApplyOnInbound = true;
+ bApplyOnOutbound = false;
+ bApplyOnExplicit = true;
+ bStopProcessingHere = true;
+ bConfigureShortcut = false;
+ bConfigureToolbar = false;
+ bAutoNaming = true;
+ mApplicability = All;
+ }
+}
+
+
+KMFilter::KMFilter( const KMFilter & aFilter )
+{
+ bPopFilter = aFilter.isPopFilter();
+
+ if ( !bPopFilter )
+ mActions.setAutoDelete( true );
+
+ mPattern = aFilter.mPattern;
+
+ if ( bPopFilter ){
+ mAction = aFilter.mAction;
+ } else {
+ bApplyOnInbound = aFilter.applyOnInbound();
+ bApplyOnOutbound = aFilter.applyOnOutbound();
+ bApplyOnExplicit = aFilter.applyOnExplicit();
+ bStopProcessingHere = aFilter.stopProcessingHere();
+ bConfigureShortcut = aFilter.configureShortcut();
+ bConfigureToolbar = aFilter.configureToolbar();
+ mApplicability = aFilter.applicability();
+ mIcon = aFilter.icon();
+ mShortcut = aFilter.shortcut();
+
+ QPtrListIterator<KMFilterAction> it( aFilter.mActions );
+ for ( it.toFirst() ; it.current() ; ++it ) {
+ KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ (*it)->name() ];
+ if ( desc ) {
+ KMFilterAction *f = desc->create();
+ if ( f ) {
+ f->argsFromString( (*it)->argsAsString() );
+ mActions.append( f );
+ }
+ }
+ }
+
+ mAccounts.clear();
+ QValueListConstIterator<int> it2;
+ for ( it2 = aFilter.mAccounts.begin() ; it2 != aFilter.mAccounts.end() ; ++it2 )
+ mAccounts.append( *it2 );
+ }
+}
+
+// only for !bPopFilter
+KMFilter::ReturnCode KMFilter::execActions( KMMessage* msg, bool& stopIt ) const
+{
+ ReturnCode status = NoResult;
+
+ QPtrListIterator<KMFilterAction> it( mActions );
+ for ( it.toFirst() ; it.current() ; ++it ) {
+
+ if ( FilterLog::instance()->isLogging() ) {
+ QString logText( i18n( "<b>Applying filter action:</b> %1" )
+ .arg( (*it)->displayString() ) );
+ FilterLog::instance()->add( logText, FilterLog::appliedAction );
+ }
+
+ KMFilterAction::ReturnCode result = (*it)->process( msg );
+
+ switch ( result ) {
+ case KMFilterAction::CriticalError:
+ if ( FilterLog::instance()->isLogging() ) {
+ QString logText = QString( "<font color=#FF0000>%1</font>" )
+ .arg( i18n( "A critical error occurred. Processing stops here." ) );
+ FilterLog::instance()->add( logText, FilterLog::appliedAction );
+ }
+ // in case it's a critical error: return immediately!
+ return CriticalError;
+ case KMFilterAction::ErrorButGoOn:
+ if ( FilterLog::instance()->isLogging() ) {
+ QString logText = QString( "<font color=#FF0000>%1</font>" )
+ .arg( i18n( "A problem was found while applying this action." ) );
+ FilterLog::instance()->add( logText, FilterLog::appliedAction );
+ }
+ default:
+ break;
+ }
+ }
+
+ if ( status == NoResult ) // No filters matched, keep copy of message
+ status = GoOn;
+
+ stopIt = stopProcessingHere();
+
+ return status;
+}
+
+bool KMFilter::requiresBody( KMMsgBase* msg )
+{
+ if (pattern() && pattern()->requiresBody())
+ return true; // no pattern means always matches?
+ QPtrListIterator<KMFilterAction> it( *actions() );
+ for ( it.toFirst() ; it.current() ; ++it )
+ if ((*it)->requiresBody( msg ))
+ return true;
+ return false;
+}
+
+/** No descriptions */
+// only for bPopFilter
+void KMFilter::setAction(const KMPopFilterAction aAction)
+{
+ mAction = aAction;
+}
+
+// only for bPopFilter
+KMPopFilterAction KMFilter::action()
+{
+ return mAction;
+}
+
+// only for !bPopFilter
+bool KMFilter::folderRemoved( KMFolder* aFolder, KMFolder* aNewFolder )
+{
+ bool rem = false;
+
+ QPtrListIterator<KMFilterAction> it( mActions );
+ for ( it.toFirst() ; it.current() ; ++it )
+ if ( (*it)->folderRemoved( aFolder, aNewFolder ) )
+ rem = true;
+
+ return rem;
+}
+
+void KMFilter::setApplyOnAccount( uint id, bool aApply )
+{
+ if (aApply && !mAccounts.contains( id )) {
+ mAccounts.append( id );
+ } else if (!aApply && mAccounts.contains( id )) {
+ mAccounts.remove( id );
+ }
+}
+
+bool KMFilter::applyOnAccount( uint id ) const
+{
+ if ( applicability() == All )
+ return true;
+ if ( applicability() == ButImap ) {
+ KMAccount *account = kmkernel->acctMgr()->find( id );
+ bool result = account && !dynamic_cast<KMAcctImap*>(account);
+ return result;
+ }
+ if ( applicability() == Checked )
+ return mAccounts.contains( id );
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+void KMFilter::readConfig(KConfig* config)
+{
+ // MKSearchPattern::readConfig ensures
+ // that the pattern is purified.
+ mPattern.readConfig(config);
+
+ if (bPopFilter) {
+ // get the action description...
+ QString action = config->readEntry( "action" );
+ if ( action == "down" )
+ mAction = Down;
+ else if ( action == "later" )
+ mAction = Later;
+ else if ( action == "delete" )
+ mAction = Delete;
+ else
+ mAction = NoAction;
+ }
+ else {
+ QStringList sets = config->readListEntry("apply-on");
+ if ( sets.isEmpty() && !config->hasKey("apply-on") ) {
+ bApplyOnOutbound = false;
+ bApplyOnInbound = true;
+ bApplyOnExplicit = true;
+ mApplicability = ButImap;
+ } else {
+ bApplyOnInbound = bool(sets.contains("check-mail"));
+ bApplyOnOutbound = bool(sets.contains("send-mail"));
+ bApplyOnExplicit = bool(sets.contains("manual-filtering"));
+ mApplicability = (AccountType)config->readNumEntry( "Applicability", ButImap );
+ }
+
+ bStopProcessingHere = config->readBoolEntry("StopProcessingHere", true);
+ bConfigureShortcut = config->readBoolEntry("ConfigureShortcut", false);
+ QString shortcut( config->readEntry( "Shortcut" ) );
+ if ( !shortcut.isEmpty() ) {
+ KShortcut sc( shortcut );
+ setShortcut( sc );
+ }
+ bConfigureToolbar = config->readBoolEntry("ConfigureToolbar", false);
+ bConfigureToolbar = bConfigureToolbar && bConfigureShortcut;
+ mIcon = config->readEntry( "Icon", "gear" );
+ bAutoNaming = config->readBoolEntry("AutomaticName", false);
+
+ int i, numActions;
+ QString actName, argsName;
+
+ mActions.clear();
+
+ numActions = config->readNumEntry("actions",0);
+ if (numActions > FILTER_MAX_ACTIONS) {
+ numActions = FILTER_MAX_ACTIONS ;
+ KMessageBox::information( 0, i18n("<qt>Too many filter actions in filter rule <b>%1</b>.</qt>").arg( mPattern.name() ) );
+ }
+
+ for ( i=0 ; i < numActions ; i++ ) {
+ actName.sprintf("action-name-%d", i);
+ argsName.sprintf("action-args-%d", i);
+ // get the action description...
+ KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ config->readEntry( actName ) ];
+ if ( desc ) {
+ //...create an instance...
+ KMFilterAction *fa = desc->create();
+ if ( fa ) {
+ //...load it with it's parameter...
+ fa->argsFromString( config->readEntry( argsName ) );
+ //...check if it's emoty and...
+ if ( !fa->isEmpty() )
+ //...append it if it's not and...
+ mActions.append( fa );
+ else
+ //...delete is else.
+ delete fa;
+ }
+ } else
+ KMessageBox::information( 0 /* app-global modal dialog box */,
+ i18n("<qt>Unknown filter action <b>%1</b><br>in filter rule <b>%2</b>.<br>Ignoring it.</qt>")
+ .arg( config->readEntry( actName ) ).arg( mPattern.name() ) );
+ }
+
+ mAccounts = config->readIntListEntry( "accounts-set" );
+ }
+}
+
+
+void KMFilter::writeConfig(KConfig* config) const
+{
+ mPattern.writeConfig(config);
+
+ if (bPopFilter) {
+ switch ( mAction ) {
+ case Down:
+ config->writeEntry( "action", "down" );
+ break;
+ case Later:
+ config->writeEntry( "action", "later" );
+ break;
+ case Delete:
+ config->writeEntry( "action", "delete" );
+ break;
+ default:
+ config->writeEntry( "action", "" );
+ }
+ } else {
+ QStringList sets;
+ if ( bApplyOnInbound )
+ sets.append( "check-mail" );
+ if ( bApplyOnOutbound )
+ sets.append( "send-mail" );
+ if ( bApplyOnExplicit )
+ sets.append( "manual-filtering" );
+ config->writeEntry( "apply-on", sets );
+
+ config->writeEntry( "StopProcessingHere", bStopProcessingHere );
+ config->writeEntry( "ConfigureShortcut", bConfigureShortcut );
+ if ( !mShortcut.isNull() )
+ config->writeEntry( "Shortcut", mShortcut.toString() );
+ config->writeEntry( "ConfigureToolbar", bConfigureToolbar );
+ config->writeEntry( "Icon", mIcon );
+ config->writeEntry( "AutomaticName", bAutoNaming );
+ config->writeEntry( "Applicability", mApplicability );
+
+ QString key;
+ int i;
+
+ QPtrListIterator<KMFilterAction> it( mActions );
+ for ( i=0, it.toFirst() ; it.current() ; ++it, ++i ) {
+ config->writeEntry( key.sprintf("action-name-%d", i),
+ (*it)->name() );
+ config->writeEntry( key.sprintf("action-args-%d", i),
+ (*it)->argsAsString() );
+ }
+ config->writeEntry( "actions", i );
+ config->writeEntry( "accounts-set", mAccounts );
+ }
+}
+
+void KMFilter::purify()
+{
+ mPattern.purify();
+
+ if (!bPopFilter) {
+ QPtrListIterator<KMFilterAction> it( mActions );
+ it.toLast();
+ while ( it.current() )
+ if ( (*it)->isEmpty() )
+ mActions.remove ( (*it) );
+ else
+ --it;
+
+ // Remove invalid accounts from mAccounts - just to be tidy
+ QValueListIterator<int> it2 = mAccounts.begin();
+ while ( it2 != mAccounts.end() ) {
+ if ( !kmkernel->acctMgr()->find( *it2 ) )
+ it2 = mAccounts.remove( it2 );
+ else
+ ++it2;
+ }
+ }
+}
+
+bool KMFilter::isEmpty() const
+{
+ if (bPopFilter)
+ return mPattern.isEmpty();
+ else
+ return mPattern.isEmpty() && mActions.isEmpty() && mAccounts.isEmpty();
+}
+
+#ifndef NDEBUG
+const QString KMFilter::asString() const
+{
+ QString result;
+
+ result += mPattern.asString();
+
+ if (bPopFilter){
+ result += " action: ";
+ result += mAction;
+ result += "\n";
+ }
+ else {
+ QPtrListIterator<KMFilterAction> it( mActions );
+ for ( it.toFirst() ; it.current() ; ++it ) {
+ result += " action: ";
+ result += (*it)->label();
+ result += " ";
+ result += (*it)->argsAsString();
+ result += "\n";
+ }
+ result += "This filter belongs to the following sets:";
+ if ( bApplyOnInbound )
+ result += " Inbound";
+ if ( bApplyOnOutbound )
+ result += " Outbound";
+ if ( bApplyOnExplicit )
+ result += " Explicit";
+ result += "\n";
+ if ( bApplyOnInbound && mApplicability == All ) {
+ result += "This filter applies to all accounts.\n";
+ } else if ( bApplyOnInbound && mApplicability == ButImap ) {
+ result += "This filter applies to all but online IMAP accounts.\n";
+ } else if ( bApplyOnInbound ) {
+ QValueListConstIterator<int> it2;
+ result += "This filter applies to the following accounts:";
+ if ( mAccounts.isEmpty() )
+ result += " None";
+ else for ( it2 = mAccounts.begin() ; it2 != mAccounts.end() ; ++it2 )
+ if ( kmkernel->acctMgr()->find( *it2 ) )
+ result += " " + kmkernel->acctMgr()->find( *it2 )->name();
+ result += "\n";
+ }
+ if ( bStopProcessingHere )
+ result += "If it matches, processing stops at this filter.\n";
+ }
+ return result;
+}
+#endif