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

kmail

kmfilteraction.cpp

Go to the documentation of this file.
00001 // kmfilteraction.cpp
00002 
00003 #include "kmfilteraction.h"
00004 
00005 // other KMail headers:
00006 #include "kmcommands.h"
00007 #include "kmmsgpart.h"
00008 #include "kmfiltermgr.h"
00009 #include "kmfolderindex.h"
00010 #include "kmfoldermgr.h"
00011 #include "messagesender.h"
00012 #include "kmmainwidget.h"
00013 #include <kpimidentities/identity.h>
00014 #include <kpimidentities/identitymanager.h>
00015 #include <kpimidentities/identitycombo.h>
00016 #include <kpimutils/kfileio.h>
00017 #include <mimelib/message.h>
00018 #include "kmfawidgets.h"
00019 #include "folderrequester.h"
00020 using KMail::FolderRequester;
00021 #include "kmmsgbase.h"
00022 #include "templateparser.h"
00023 using KMail::TemplateParser;
00024 #include "messageproperty.h"
00025 #include "actionscheduler.h"
00026 using KMail::MessageProperty;
00027 using KMail::ActionScheduler;
00028 #include "regexplineedit.h"
00029 using KMail::RegExpLineEdit;
00030 
00031 #include <kcombobox.h>
00032 #include <ktemporaryfile.h>
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035 #include <kurlrequester.h>
00036 #include <Phonon/MediaObject>
00037 #include <kshell.h>
00038 #include <kprocess.h>
00039 
00040 // Qt headers:
00041 #include <QTextCodec>
00042 #include <QTextDocument>
00043 
00044 // other headers:
00045 #include <assert.h>
00046 #include <string.h>
00047 
00048 //=============================================================================
00049 //
00050 // KMFilterAction
00051 //
00052 //=============================================================================
00053 
00054 KMFilterAction::KMFilterAction( const char* aName, const QString &aLabel )
00055 {
00056   mName = aName;
00057   mLabel = aLabel;
00058 }
00059 
00060 KMFilterAction::~KMFilterAction()
00061 {
00062 }
00063 
00064 void KMFilterAction::processAsync(KMMessage* msg) const
00065 {
00066   ActionScheduler *handler = MessageProperty::filterHandler( msg );
00067   ReturnCode result = process( msg );
00068   if (handler)
00069     handler->actionMessage( result );
00070 }
00071 
00072 bool KMFilterAction::requiresBody(KMMsgBase*) const
00073 {
00074   return true;
00075 }
00076 
00077 KMFilterAction* KMFilterAction::newAction()
00078 {
00079   return 0;
00080 }
00081 
00082 QWidget* KMFilterAction::createParamWidget(QWidget* parent) const
00083 {
00084   return new QWidget(parent);
00085 }
00086 
00087 void KMFilterAction::applyParamWidgetValue(QWidget*)
00088 {
00089 }
00090 
00091 void KMFilterAction::setParamWidgetValue( QWidget * ) const
00092 {
00093 }
00094 
00095 void KMFilterAction::clearParamWidget( QWidget * ) const
00096 {
00097 }
00098 
00099 bool KMFilterAction::folderRemoved(KMFolder*, KMFolder*)
00100 {
00101   return false;
00102 }
00103 
00104 int KMFilterAction::tempOpenFolder(KMFolder* aFolder)
00105 {
00106   return kmkernel->filterMgr()->tempOpenFolder(aFolder);
00107 }
00108 
00109 void KMFilterAction::sendMDN( KMMessage * msg, KMime::MDN::DispositionType d,
00110                               const QList<KMime::MDN::DispositionModifier> & m ) {
00111   if ( !msg ) return;
00112 
00113   /* createMDN requires Return-Path and Disposition-Notification-To
00114    * if it is not set in the message we assume that the notification should go to the
00115    * sender
00116    */
00117   const QString returnPath = msg->headerField( "Return-Path" );
00118   const QString dispNoteTo = msg->headerField( "Disposition-Notification-To" );
00119   if ( returnPath.isEmpty() )
00120     msg->setHeaderField( "Return-Path", msg->from() );
00121   if ( dispNoteTo.isEmpty() )
00122     msg->setHeaderField( "Disposition-Notification-To", msg->from() );
00123 
00124   KMMessage * mdn = msg->createMDN( KMime::MDN::AutomaticAction, d, false, m );
00125   if ( mdn && !kmkernel->msgSender()->send( mdn, KMail::MessageSender::SendLater ) ) {
00126     kDebug(5006) << "Sending failed.";
00127     //delete mdn;
00128   }
00129 
00130   //restore orignial header
00131   if ( returnPath.isEmpty() )
00132     msg->removeHeaderField( "Return-Path" );
00133   if ( dispNoteTo.isEmpty() )
00134     msg->removeHeaderField( "Disposition-Notification-To" );
00135 }
00136 
00137 
00138 //=============================================================================
00139 //
00140 // KMFilterActionWithNone
00141 //
00142 //=============================================================================
00143 
00144 KMFilterActionWithNone::KMFilterActionWithNone( const char* aName, const QString &aLabel )
00145   : KMFilterAction( aName, aLabel )
00146 {
00147 }
00148 
00149 const QString KMFilterActionWithNone::displayString() const
00150 {
00151   return label();
00152 }
00153 
00154 
00155 //=============================================================================
00156 //
00157 // KMFilterActionWithUOID
00158 //
00159 //=============================================================================
00160 
00161 KMFilterActionWithUOID::KMFilterActionWithUOID( const char* aName, const QString &aLabel )
00162   : KMFilterAction( aName, aLabel ), mParameter( 0 )
00163 {
00164 }
00165 
00166 void KMFilterActionWithUOID::argsFromString( const QString &argsStr )
00167 {
00168   mParameter = argsStr.trimmed().toUInt();
00169 }
00170 
00171 const QString KMFilterActionWithUOID::argsAsString() const
00172 {
00173   return QString::number( mParameter );
00174 }
00175 
00176 const QString KMFilterActionWithUOID::displayString() const
00177 {
00178   // FIXME after string freeze:
00179   // return i18n("").arg( );
00180   return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
00181 }
00182 
00183 
00184 //=============================================================================
00185 //
00186 // KMFilterActionWithString
00187 //
00188 //=============================================================================
00189 
00190 KMFilterActionWithString::KMFilterActionWithString( const char* aName, const QString &aLabel )
00191   : KMFilterAction( aName, aLabel )
00192 {
00193 }
00194 
00195 QWidget* KMFilterActionWithString::createParamWidget( QWidget* parent ) const
00196 {
00197   KLineEdit *le = new KLineEdit(parent);
00198   le->setClearButtonShown( true );
00199   le->setText( mParameter );
00200   return le;
00201 }
00202 
00203 void KMFilterActionWithString::applyParamWidgetValue( QWidget* paramWidget )
00204 {
00205   mParameter = ((KLineEdit*)paramWidget)->text();
00206 }
00207 
00208 void KMFilterActionWithString::setParamWidgetValue( QWidget* paramWidget ) const
00209 {
00210   ((KLineEdit*)paramWidget)->setText( mParameter );
00211 }
00212 
00213 void KMFilterActionWithString::clearParamWidget( QWidget* paramWidget ) const
00214 {
00215   ((KLineEdit*)paramWidget)->clear();
00216 }
00217 
00218 void KMFilterActionWithString::argsFromString( const QString &argsStr )
00219 {
00220   mParameter = argsStr;
00221 }
00222 
00223 const QString KMFilterActionWithString::argsAsString() const
00224 {
00225   return mParameter;
00226 }
00227 
00228 const QString KMFilterActionWithString::displayString() const
00229 {
00230   // FIXME after string freeze:
00231   // return i18n("").arg( );
00232   return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
00233 }
00234 
00235 //=============================================================================
00236 //
00237 // class KMFilterActionWithStringList
00238 //
00239 //=============================================================================
00240 
00241 KMFilterActionWithStringList::KMFilterActionWithStringList( const char* aName, const QString &aLabel )
00242   : KMFilterActionWithString( aName, aLabel )
00243 {
00244 }
00245 
00246 QWidget* KMFilterActionWithStringList::createParamWidget( QWidget* parent ) const
00247 {
00248   KComboBox *cb = new KComboBox( parent );
00249   cb->setEditable( false );
00250   cb->addItems( mParameterList );
00251   setParamWidgetValue( cb );
00252   return cb;
00253 }
00254 
00255 void KMFilterActionWithStringList::applyParamWidgetValue( QWidget* paramWidget )
00256 {
00257   mParameter = ((KComboBox*)paramWidget)->currentText();
00258 }
00259 
00260 void KMFilterActionWithStringList::setParamWidgetValue( QWidget* paramWidget ) const
00261 {
00262   int idx = mParameterList.indexOf( mParameter );
00263   ((KComboBox*)paramWidget)->setCurrentIndex( idx >= 0 ? idx : 0 );
00264 }
00265 
00266 void KMFilterActionWithStringList::clearParamWidget( QWidget* paramWidget ) const
00267 {
00268   ((KComboBox*)paramWidget)->setCurrentIndex(0);
00269 }
00270 
00271 void KMFilterActionWithStringList::argsFromString( const QString &argsStr )
00272 {
00273   int idx = mParameterList.indexOf( argsStr );
00274   if ( idx < 0 ) {
00275     mParameterList.append( argsStr );
00276     idx = mParameterList.count() - 1;
00277   }
00278   mParameter = mParameterList.at( idx );
00279 }
00280 
00281 
00282 //=============================================================================
00283 //
00284 // class KMFilterActionWithFolder
00285 //
00286 //=============================================================================
00287 
00288 KMFilterActionWithFolder::KMFilterActionWithFolder( const char* aName, const QString &aLabel )
00289   : KMFilterAction( aName, aLabel )
00290 {
00291   mFolder = 0;
00292 }
00293 
00294 QWidget* KMFilterActionWithFolder::createParamWidget( QWidget* parent ) const
00295 {
00296   FolderRequester *req = new FolderRequester( parent,
00297       kmkernel->getKMMainWidget()->folderTree() );
00298   setParamWidgetValue( req );
00299   return req;
00300 }
00301 
00302 void KMFilterActionWithFolder::applyParamWidgetValue( QWidget* paramWidget )
00303 {
00304   mFolder = ((FolderRequester *)paramWidget)->folder();
00305   mFolderName = ((FolderRequester *)paramWidget)->folderId();
00306 }
00307 
00308 void KMFilterActionWithFolder::setParamWidgetValue( QWidget* paramWidget ) const
00309 {
00310   if ( mFolder )
00311     ((FolderRequester *)paramWidget)->setFolder( mFolder );
00312   else
00313     ((FolderRequester *)paramWidget)->setFolder( mFolderName );
00314 }
00315 
00316 void KMFilterActionWithFolder::clearParamWidget( QWidget* paramWidget ) const
00317 {
00318   ((FolderRequester *)paramWidget)->setFolder( kmkernel->draftsFolder() );
00319 }
00320 
00321 void KMFilterActionWithFolder::argsFromString( const QString &argsStr )
00322 {
00323   mFolder = kmkernel->folderMgr()->findIdString( argsStr );
00324   if (!mFolder)
00325      mFolder = kmkernel->dimapFolderMgr()->findIdString( argsStr );
00326   if (!mFolder)
00327      mFolder = kmkernel->imapFolderMgr()->findIdString( argsStr );
00328   if (mFolder)
00329      mFolderName = mFolder->idString();
00330   else
00331      mFolderName = argsStr;
00332 }
00333 
00334 const QString KMFilterActionWithFolder::argsAsString() const
00335 {
00336   QString result;
00337   if ( mFolder )
00338     result = mFolder->idString();
00339   else
00340     result = mFolderName;
00341   return result;
00342 }
00343 
00344 const QString KMFilterActionWithFolder::displayString() const
00345 {
00346   QString result;
00347   if ( mFolder )
00348     result = mFolder->prettyUrl();
00349   else
00350     result = mFolderName;
00351   return label() + " \"" + Qt::escape( result ) + "\"";
00352 }
00353 
00354 bool KMFilterActionWithFolder::folderRemoved( KMFolder* aFolder, KMFolder* aNewFolder )
00355 {
00356   if ( aFolder == mFolder ) {
00357     mFolder = aNewFolder;
00358     if ( aNewFolder )
00359       mFolderName = mFolder->idString();
00360     return true;
00361   } else
00362     return false;
00363 }
00364 
00365 //=============================================================================
00366 //
00367 // class KMFilterActionWithAddress
00368 //
00369 //=============================================================================
00370 
00371 KMFilterActionWithAddress::KMFilterActionWithAddress( const char* aName, const QString &aLabel )
00372   : KMFilterActionWithString( aName, aLabel )
00373 {
00374 }
00375 
00376 QWidget* KMFilterActionWithAddress::createParamWidget( QWidget* parent ) const
00377 {
00378   KMFilterActionWithAddressWidget *w = new KMFilterActionWithAddressWidget(parent);
00379   w->setText( mParameter );
00380   return w;
00381 }
00382 
00383 void KMFilterActionWithAddress::applyParamWidgetValue( QWidget* paramWidget )
00384 {
00385   mParameter = ((KMFilterActionWithAddressWidget*)paramWidget)->text();
00386 }
00387 
00388 void KMFilterActionWithAddress::setParamWidgetValue( QWidget* paramWidget ) const
00389 {
00390   ((KMFilterActionWithAddressWidget*)paramWidget)->setText( mParameter );
00391 }
00392 
00393 void KMFilterActionWithAddress::clearParamWidget( QWidget* paramWidget ) const
00394 {
00395   ((KMFilterActionWithAddressWidget*)paramWidget)->clear();
00396 }
00397 
00398 //=============================================================================
00399 //
00400 // class KMFilterActionWithCommand
00401 //
00402 //=============================================================================
00403 
00404 KMFilterActionWithCommand::KMFilterActionWithCommand( const char* aName, const QString &aLabel )
00405   : KMFilterActionWithUrl( aName, aLabel )
00406 {
00407 }
00408 
00409 QWidget* KMFilterActionWithCommand::createParamWidget( QWidget* parent ) const
00410 {
00411   return KMFilterActionWithUrl::createParamWidget( parent );
00412 }
00413 
00414 void KMFilterActionWithCommand::applyParamWidgetValue( QWidget* paramWidget )
00415 {
00416   KMFilterActionWithUrl::applyParamWidgetValue( paramWidget );
00417 }
00418 
00419 void KMFilterActionWithCommand::setParamWidgetValue( QWidget* paramWidget ) const
00420 {
00421   KMFilterActionWithUrl::setParamWidgetValue( paramWidget );
00422 }
00423 
00424 void KMFilterActionWithCommand::clearParamWidget( QWidget* paramWidget ) const
00425 {
00426   KMFilterActionWithUrl::clearParamWidget( paramWidget );
00427 }
00428 
00429 QString KMFilterActionWithCommand::substituteCommandLineArgsFor( KMMessage *aMsg, QList<KTemporaryFile*> & aTempFileList ) const
00430 {
00431   QString result = mParameter;
00432   QList<int> argList;
00433   QRegExp r( "%[0-9-]+" );
00434 
00435   // search for '%n'
00436   int start = -1;
00437   while ( ( start = r.indexIn( result, start + 1 ) ) > 0 ) {
00438     int len = r.matchedLength();
00439     // and save the encountered 'n' in a list.
00440     bool OK = false;
00441     int n = result.mid( start + 1, len - 1 ).toInt( &OK );
00442     if ( OK )
00443       argList.append( n );
00444   }
00445 
00446   // sort the list of n's
00447   qSort( argList );
00448 
00449   // and use QString::arg to substitute filenames for the %n's.
00450   int lastSeen = -2;
00451   QString tempFileName;
00452   for ( QList<int>::Iterator it = argList.begin() ; it != argList.end() ; ++it ) {
00453     // setup temp files with check for duplicate %n's
00454     if ( (*it) != lastSeen ) {
00455       KTemporaryFile *tf = new KTemporaryFile();
00456       if ( !tf->open() ) {
00457         delete tf;
00458         kDebug(5006) <<"KMFilterActionWithCommand: Could not create temp file!";
00459         return QString();
00460       }
00461       aTempFileList.append( tf );
00462       tempFileName = tf->fileName();
00463       if ((*it) == -1)
00464         KPIMUtils::kByteArrayToFile( aMsg->asString(), tempFileName, //###
00465                           false, false, false );
00466       else if (aMsg->numBodyParts() == 0)
00467         KPIMUtils::kByteArrayToFile( aMsg->bodyDecodedBinary(), tempFileName,
00468                           false, false, false );
00469       else {
00470         KMMessagePart msgPart;
00471         aMsg->bodyPart( (*it), &msgPart );
00472         KPIMUtils::kByteArrayToFile( msgPart.bodyDecodedBinary(), tempFileName,
00473                           false, false, false );
00474       }
00475       tf->close();
00476     }
00477     // QString( "%0 and %1 and %1" ).arg( 0 ).arg( 1 )
00478     // returns "0 and 1 and %1", so we must call .arg as
00479     // many times as there are %n's, regardless of their multiplicity.
00480     if ((*it) == -1) result.replace( "%-1", tempFileName );
00481     else result = result.arg( tempFileName );
00482   }
00483 
00484   // And finally, replace the %{foo} with the content of the foo
00485   // header field:
00486   QRegExp header_rx( "%\\{([a-z0-9-]+)\\}", Qt::CaseInsensitive );
00487   int idx = 0;
00488   while ( ( idx = header_rx.indexIn( result, idx ) ) != -1 ) {
00489     QString replacement = KShell::quoteArg( aMsg->headerField( header_rx.cap(1).toLatin1() ) );
00490     result.replace( idx, header_rx.matchedLength(), replacement );
00491     idx += replacement.length();
00492   }
00493 
00494   return result;
00495 }
00496 
00497 
00498 KMFilterAction::ReturnCode KMFilterActionWithCommand::genericProcess(KMMessage* aMsg, bool withOutput) const
00499 {
00500   Q_ASSERT( aMsg );
00501 
00502   if ( mParameter.isEmpty() )
00503     return ErrorButGoOn;
00504 
00505   // KProcess doesn't support a QProcess::launch() equivalent, so
00506   // we must use a temp file :-(
00507   KTemporaryFile * inFile = new KTemporaryFile;
00508   inFile->open();
00509 
00510   QList<KTemporaryFile*> atmList;
00511   atmList.append( inFile );
00512 
00513   QString commandLine = substituteCommandLineArgsFor( aMsg, atmList );
00514   if ( commandLine.isEmpty() )
00515   {
00516     qDeleteAll( atmList );
00517     atmList.clear();
00518     return ErrorButGoOn;
00519   }
00520   // The parentheses force the creation of a subshell
00521   // in which the user-specified command is executed.
00522   // This is to really catch all output of the command as well
00523   // as to avoid clashes of our redirection with the ones
00524   // the user may have specified. In the long run, we
00525   // shouldn't be using tempfiles at all for this class, due
00526   // to security aspects. (mmutz)
00527   commandLine =  '(' + commandLine + ") <" + inFile->fileName();
00528 
00529   // write message to file
00530   QString tempFileName = inFile->fileName();
00531   KPIMUtils::kByteArrayToFile( aMsg->asString(), tempFileName, //###
00532                   false, false, false );
00533   inFile->close();
00534 
00535   KProcess shProc;
00536   shProc.setOutputChannelMode( KProcess::SeparateChannels );
00537   shProc.setShellCommand( commandLine );
00538   int result = shProc.execute();
00539 
00540   if ( result != 0 ) {
00541     qDeleteAll( atmList );
00542     atmList.clear();
00543     return ErrorButGoOn;
00544   }
00545 
00546   if ( withOutput ) {
00547     // read altered message:
00548     QByteArray msgText = shProc.readAllStandardOutput();
00549 
00550     if ( !msgText.isEmpty() ) {
00551     /* If the pipe through alters the message, it could very well
00552        happen that it no longer has a X-UID header afterwards. That is
00553        unfortunate, as we need to removed the original from the folder
00554        using that, and look it up in the message. When the (new) message
00555        is uploaded, the header is stripped anyhow. */
00556       QString uid = aMsg->headerField("X-UID");
00557       aMsg->fromString( msgText );
00558       aMsg->setHeaderField("X-UID",uid);
00559     }
00560     else {
00561       qDeleteAll( atmList );
00562       atmList.clear();
00563       return ErrorButGoOn;
00564     }
00565   }
00566   qDeleteAll( atmList );
00567   atmList.clear();
00568   return GoOn;
00569 }
00570 
00571 
00572 //=============================================================================
00573 //
00574 //   Specific  Filter  Actions
00575 //
00576 //=============================================================================
00577 
00578 //=============================================================================
00579 // KMFilterActionSendReceipt - send receipt
00580 // Return delivery receipt.
00581 //=============================================================================
00582 class KMFilterActionSendReceipt : public KMFilterActionWithNone
00583 {
00584 public:
00585   KMFilterActionSendReceipt();
00586   virtual ReturnCode process(KMMessage* msg) const;
00587   static KMFilterAction* newAction(void);
00588 };
00589 
00590 KMFilterAction* KMFilterActionSendReceipt::newAction(void)
00591 {
00592   return (new KMFilterActionSendReceipt);
00593 }
00594 
00595 KMFilterActionSendReceipt::KMFilterActionSendReceipt()
00596   : KMFilterActionWithNone( "confirm delivery", i18n("Confirm Delivery") )
00597 {
00598 }
00599 
00600 KMFilterAction::ReturnCode KMFilterActionSendReceipt::process(KMMessage* msg) const
00601 {
00602   KMMessage *receipt = msg->createDeliveryReceipt();
00603   if ( !receipt ) return ErrorButGoOn;
00604 
00605   // Queue message. This is a) so that the user can check
00606   // the receipt before sending and b) for speed reasons.
00607   kmkernel->msgSender()->send( receipt, KMail::MessageSender::SendLater );
00608 
00609   return GoOn;
00610 }
00611 
00612 
00613 
00614 //=============================================================================
00615 // KMFilterActionSetTransport - set transport to...
00616 // Specify mail transport (smtp server) to be used when replying to a message
00617 // TODO: use TransportComboBox so the user does not enter an invalid transport
00618 //=============================================================================
00619 class KMFilterActionTransport: public KMFilterActionWithString
00620 {
00621 public:
00622   KMFilterActionTransport();
00623   virtual ReturnCode process(KMMessage* msg) const;
00624   static KMFilterAction* newAction(void);
00625 };
00626 
00627 KMFilterAction* KMFilterActionTransport::newAction(void)
00628 {
00629   return (new KMFilterActionTransport);
00630 }
00631 
00632 KMFilterActionTransport::KMFilterActionTransport()
00633   : KMFilterActionWithString( "set transport", i18n("Set Transport To") )
00634 {
00635 }
00636 
00637 KMFilterAction::ReturnCode KMFilterActionTransport::process(KMMessage* msg) const
00638 {
00639   if ( mParameter.isEmpty() )
00640     return ErrorButGoOn;
00641   msg->setHeaderField( "X-KMail-Transport", mParameter );
00642   return GoOn;
00643 }
00644 
00645 
00646 //=============================================================================
00647 // KMFilterActionReplyTo - set Reply-To to
00648 // Set the Reply-to header in a message
00649 //=============================================================================
00650 class KMFilterActionReplyTo: public KMFilterActionWithString
00651 {
00652 public:
00653   KMFilterActionReplyTo();
00654   virtual ReturnCode process(KMMessage* msg) const;
00655   static KMFilterAction* newAction(void);
00656 };
00657 
00658 KMFilterAction* KMFilterActionReplyTo::newAction(void)
00659 {
00660   return (new KMFilterActionReplyTo);
00661 }
00662 
00663 KMFilterActionReplyTo::KMFilterActionReplyTo()
00664   : KMFilterActionWithString( "set Reply-To", i18n("Set Reply-To To") )
00665 {
00666   mParameter = "";
00667 }
00668 
00669 KMFilterAction::ReturnCode KMFilterActionReplyTo::process(KMMessage* msg) const
00670 {
00671   msg->setHeaderField( "Reply-To", mParameter );
00672   return GoOn;
00673 }
00674 
00675 
00676 
00677 //=============================================================================
00678 // KMFilterActionIdentity - set identity to
00679 // Specify Identity to be used when replying to a message
00680 //=============================================================================
00681 class KMFilterActionIdentity: public KMFilterActionWithUOID
00682 {
00683 public:
00684   KMFilterActionIdentity();
00685   virtual ReturnCode process(KMMessage* msg) const;
00686   static KMFilterAction* newAction();
00687 
00688   QWidget * createParamWidget( QWidget * parent ) const;
00689   void applyParamWidgetValue( QWidget * parent );
00690   void setParamWidgetValue( QWidget * parent ) const;
00691   void clearParamWidget( QWidget * param ) const;
00692 };
00693 
00694 KMFilterAction* KMFilterActionIdentity::newAction()
00695 {
00696   return (new KMFilterActionIdentity);
00697 }
00698 
00699 KMFilterActionIdentity::KMFilterActionIdentity()
00700   : KMFilterActionWithUOID( "set identity", i18n("Set Identity To") )
00701 {
00702   mParameter = kmkernel->identityManager()->defaultIdentity().uoid();
00703 }
00704 
00705 KMFilterAction::ReturnCode KMFilterActionIdentity::process(KMMessage* msg) const
00706 {
00707   msg->setHeaderField( "X-KMail-Identity", QString::number( mParameter ) );
00708   return GoOn;
00709 }
00710 
00711 QWidget * KMFilterActionIdentity::createParamWidget( QWidget * parent ) const
00712 {
00713   KPIMIdentities::IdentityCombo * ic = new KPIMIdentities::IdentityCombo( kmkernel->identityManager(), parent );
00714   ic->setCurrentIdentity( mParameter );
00715   return ic;
00716 }
00717 
00718 void KMFilterActionIdentity::applyParamWidgetValue( QWidget * paramWidget )
00719 {
00720   KPIMIdentities::IdentityCombo * ic = dynamic_cast<KPIMIdentities::IdentityCombo*>( paramWidget );
00721   assert( ic );
00722   mParameter = ic->currentIdentity();
00723 }
00724 
00725 void KMFilterActionIdentity::clearParamWidget( QWidget * paramWidget ) const
00726 {
00727   KPIMIdentities::IdentityCombo * ic = dynamic_cast<KPIMIdentities::IdentityCombo*>( paramWidget );
00728   assert( ic );
00729   ic->setCurrentIndex( 0 );
00730   //ic->setCurrentIdentity( kmkernel->identityManager()->defaultIdentity() );
00731 }
00732 
00733 void KMFilterActionIdentity::setParamWidgetValue( QWidget * paramWidget ) const
00734 {
00735   KPIMIdentities::IdentityCombo * ic = dynamic_cast<KPIMIdentities::IdentityCombo*>( paramWidget );
00736   assert( ic );
00737   ic->setCurrentIdentity( mParameter );
00738 }
00739 
00740 //=============================================================================
00741 // KMFilterActionSetStatus - set status to
00742 // Set the status of messages
00743 //=============================================================================
00744 class KMFilterActionSetStatus: public KMFilterActionWithStringList
00745 {
00746 public:
00747   KMFilterActionSetStatus();
00748   virtual ReturnCode process(KMMessage* msg) const;
00749   virtual bool requiresBody(KMMsgBase*) const;
00750 
00751   static KMFilterAction* newAction();
00752 
00753   virtual bool isEmpty() const { return false; }
00754 
00755   virtual void argsFromString( const QString &argsStr );
00756   virtual const QString argsAsString() const;
00757   virtual const QString displayString() const;
00758 };
00759 
00760 
00761 static const MessageStatus stati[] =
00762 {
00763   MessageStatus::statusImportant(),
00764   MessageStatus::statusRead(),
00765   MessageStatus::statusUnread(),
00766   MessageStatus::statusReplied(),
00767   MessageStatus::statusForwarded(),
00768   MessageStatus::statusOld(),
00769   MessageStatus::statusNew(),
00770   MessageStatus::statusWatched(),
00771   MessageStatus::statusIgnored(),
00772   MessageStatus::statusSpam(),
00773   MessageStatus::statusHam()
00774 };
00775 static const int StatiCount = sizeof( stati ) / sizeof( MessageStatus );
00776 
00777 KMFilterAction* KMFilterActionSetStatus::newAction()
00778 {
00779   return (new KMFilterActionSetStatus);
00780 }
00781 
00782 KMFilterActionSetStatus::KMFilterActionSetStatus()
00783   : KMFilterActionWithStringList( "set status", i18n("Mark As") )
00784 {
00785   // if you change this list, also update
00786   // KMFilterActionSetStatus::stati above
00787   mParameterList.append( "" );
00788   mParameterList.append( i18nc("msg status","Important") );
00789   mParameterList.append( i18nc("msg status","Read") );
00790   mParameterList.append( i18nc("msg status","Unread") );
00791   mParameterList.append( i18nc("msg status","Replied") );
00792   mParameterList.append( i18nc("msg status","Forwarded") );
00793   mParameterList.append( i18nc("msg status","Old") );
00794   mParameterList.append( i18nc("msg status","New") );
00795   mParameterList.append( i18nc("msg status","Watched") );
00796   mParameterList.append( i18nc("msg status","Ignored") );
00797   mParameterList.append( i18nc("msg status","Spam") );
00798   mParameterList.append( i18nc("msg status","Ham") );
00799 
00800   mParameter = mParameterList.at(0);
00801 }
00802 
00803 KMFilterAction::ReturnCode KMFilterActionSetStatus::process(KMMessage* msg) const
00804 {
00805   int idx = mParameterList.indexOf( mParameter );
00806   if ( idx < 1 ) return ErrorButGoOn;
00807 
00808   msg->setStatus( stati[idx-1] );
00809   return GoOn;
00810 }
00811 
00812 bool KMFilterActionSetStatus::requiresBody(KMMsgBase*) const
00813 {
00814   return false;
00815 }
00816 
00817 void KMFilterActionSetStatus::argsFromString( const QString &argsStr )
00818 {
00819   if ( argsStr.length() == 1 ) {
00820     MessageStatus status;
00821     int i;
00822     for ( i = 0 ; i < StatiCount ; i++ )
00823     {
00824       status = stati[i];
00825       if ( status.getStatusStr()[0] == argsStr[0].toLatin1() ) {
00826         mParameter = mParameterList.at(i+1);
00827         return;
00828       }
00829     }
00830   }
00831   mParameter = mParameterList.at(0);
00832 }
00833 
00834 const QString KMFilterActionSetStatus::argsAsString() const
00835 {
00836   int idx = mParameterList.indexOf( mParameter );
00837   if ( idx < 1 ) return QString();
00838 
00839   return stati[idx-1].getStatusStr();
00840 }
00841 
00842 const QString KMFilterActionSetStatus::displayString() const
00843 {
00844   // FIXME after string freeze:
00845   // return i18n("").arg( );
00846   return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
00847 }
00848 
00849 //=============================================================================
00850 // KMFilterActionFakeDisposition - send fake MDN
00851 // Sends a fake MDN or forces an ignore.
00852 //=============================================================================
00853 class KMFilterActionFakeDisposition: public KMFilterActionWithStringList
00854 {
00855 public:
00856   KMFilterActionFakeDisposition();
00857   virtual ReturnCode process(KMMessage* msg) const;
00858   static KMFilterAction* newAction() {
00859     return (new KMFilterActionFakeDisposition);
00860   }
00861 
00862   virtual bool isEmpty() const { return false; }
00863 
00864   virtual void argsFromString( const QString &argsStr );
00865   virtual const QString argsAsString() const;
00866   virtual const QString