From 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: 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 --- kmail/kmfilter.cpp | 430 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100644 kmail/kmfilter.cpp (limited to 'kmail/kmfilter.cpp') 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 + * + * 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 +#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 +#include +#include +#include + +#include + + +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 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 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 it( mActions ); + for ( it.toFirst() ; it.current() ; ++it ) { + + if ( FilterLog::instance()->isLogging() ) { + QString logText( i18n( "Applying filter action: %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( "%1" ) + .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( "%1" ) + .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 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 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(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("Too many filter actions in filter rule %1.").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("Unknown filter action %1
in filter rule %2.
Ignoring it.
") + .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 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 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 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 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 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 -- cgit v1.2.3