kmail

kmfilteraction.cpp
00001 // kmfilteraction.cpp
00002 // The process methods really should use an enum instead of an int
00003 // -1 -> status unchanged, 0 -> success, 1 -> failure, 2-> critical failure
00004 // (GoOn),                 (Ok),         (ErrorButGoOn), (CriticalError)
00005 
00006 #ifdef HAVE_CONFIG_H
00007 #include <config.h>
00008 #endif
00009 
00010 #include "kmfilteraction.h"
00011 
00012 #include "customtemplates.h"
00013 #include "customtemplates_kfg.h"
00014 #include "kmcommands.h"
00015 #include "kmmsgpart.h"
00016 #include "kmfiltermgr.h"
00017 #include "kmfolderindex.h"
00018 #include "kmfoldermgr.h"
00019 #include "messagesender.h"
00020 #include "kmmainwidget.h"
00021 #include <libkpimidentities/identity.h>
00022 #include <libkpimidentities/identitymanager.h>
00023 #include <libkpimidentities/identitycombo.h>
00024 #include <libkdepim/kfileio.h>
00025 #include <libkdepim/collectingprocess.h>
00026 using KPIM::CollectingProcess;
00027 #include <mimelib/message.h>
00028 #include "kmfawidgets.h"
00029 #include "folderrequester.h"
00030 using KMail::FolderRequester;
00031 #include "kmmsgbase.h"
00032 #include "messageproperty.h"
00033 #include "actionscheduler.h"
00034 using KMail::MessageProperty;
00035 using KMail::ActionScheduler;
00036 #include "regexplineedit.h"
00037 using KMail::RegExpLineEdit;
00038 #include <kregexp3.h>
00039 #include <ktempfile.h>
00040 #include <kdebug.h>
00041 #include <klocale.h>
00042 #include <kprocess.h>
00043 #include <kaudioplayer.h>
00044 #include <kurlrequester.h>
00045 
00046 #include <tqlabel.h>
00047 #include <tqlayout.h>
00048 #include <tqtextcodec.h>
00049 #include <tqtimer.h>
00050 #include <tqobject.h>
00051 #include <tqstylesheet.h>
00052 #include <tqtooltip.h>
00053 #include <tqwhatsthis.h> 
00054 #include <assert.h>
00055 
00056 
00057 //=============================================================================
00058 //
00059 // KMFilterAction
00060 //
00061 //=============================================================================
00062 
00063 KMFilterAction::KMFilterAction( const char* aName, const TQString aLabel )
00064 {
00065   mName = aName;
00066   mLabel = aLabel;
00067 }
00068 
00069 KMFilterAction::~KMFilterAction()
00070 {
00071 }
00072 
00073 void KMFilterAction::processAsync(KMMessage* msg) const
00074 {
00075   ActionScheduler *handler = MessageProperty::filterHandler( msg );
00076   ReturnCode result = process( msg );
00077   if (handler)
00078     handler->actionMessage( result );
00079 }
00080 
00081 bool KMFilterAction::requiresBody(KMMsgBase*) const
00082 {
00083   return true;
00084 }
00085 
00086 KMFilterAction* KMFilterAction::newAction()
00087 {
00088   return 0;
00089 }
00090 
00091 TQWidget* KMFilterAction::createParamWidget(TQWidget* parent) const
00092 {
00093   return new TQWidget(parent);
00094 }
00095 
00096 void KMFilterAction::applyParamWidgetValue(TQWidget*)
00097 {
00098 }
00099 
00100 void KMFilterAction::setParamWidgetValue( TQWidget * ) const
00101 {
00102 }
00103 
00104 void KMFilterAction::clearParamWidget( TQWidget * ) const
00105 {
00106 }
00107 
00108 bool KMFilterAction::folderRemoved(KMFolder*, KMFolder*)
00109 {
00110   return false;
00111 }
00112 
00113 int KMFilterAction::tempOpenFolder(KMFolder* aFolder)
00114 {
00115   return kmkernel->filterMgr()->tempOpenFolder(aFolder);
00116 }
00117 
00118 void KMFilterAction::sendMDN( KMMessage * msg, KMime::MDN::DispositionType d,
00119                               const TQValueList<KMime::MDN::DispositionModifier> & m ) {
00120   if ( !msg ) return;
00121 
00122   /* createMDN requires Return-Path and Disposition-Notification-To
00123    * if it is not set in the message we assume that the notification should go to the
00124    * sender
00125    */
00126   const TQString returnPath = msg->headerField( "Return-Path" );
00127   const TQString dispNoteTo = msg->headerField( "Disposition-Notification-To" );
00128   if ( returnPath.isEmpty() )
00129     msg->setHeaderField( "Return-Path", msg->from() );
00130   if ( dispNoteTo.isEmpty() )
00131     msg->setHeaderField( "Disposition-Notification-To", msg->from() );
00132 
00133   KMMessage * mdn = msg->createMDN( KMime::MDN::AutomaticAction, d, false, m );
00134   if ( mdn && !kmkernel->msgSender()->send( mdn, KMail::MessageSender::SendLater ) ) {
00135     kdDebug(5006) << "KMFilterAction::sendMDN(): sending failed." << endl;
00136     //delete mdn;
00137   }
00138 
00139   //restore orignial header
00140   if ( returnPath.isEmpty() )
00141     msg->removeHeaderField( "Return-Path" );
00142   if ( dispNoteTo.isEmpty() )
00143     msg->removeHeaderField( "Disposition-Notification-To" );
00144 }
00145 
00146 
00147 //=============================================================================
00148 //
00149 // KMFilterActionWithNone
00150 //
00151 //=============================================================================
00152 
00153 KMFilterActionWithNone::KMFilterActionWithNone( const char* aName, const TQString aLabel )
00154   : KMFilterAction( aName, aLabel )
00155 {
00156 }
00157 
00158 const TQString KMFilterActionWithNone::displayString() const
00159 {
00160   return label();
00161 }
00162 
00163 
00164 //=============================================================================
00165 //
00166 // KMFilterActionWithUOID
00167 //
00168 //=============================================================================
00169 
00170 KMFilterActionWithUOID::KMFilterActionWithUOID( const char* aName, const TQString aLabel )
00171   : KMFilterAction( aName, aLabel ), mParameter( 0 )
00172 {
00173 }
00174 
00175 void KMFilterActionWithUOID::argsFromString( const TQString argsStr )
00176 {
00177   mParameter = argsStr.stripWhiteSpace().toUInt();
00178 }
00179 
00180 const TQString KMFilterActionWithUOID::argsAsString() const
00181 {
00182   return TQString::number( mParameter );
00183 }
00184 
00185 const TQString KMFilterActionWithUOID::displayString() const
00186 {
00187   // FIXME after string freeze:
00188   // return i18n("").arg( );
00189   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
00190 }
00191 
00192 
00193 //=============================================================================
00194 //
00195 // KMFilterActionWithString
00196 //
00197 //=============================================================================
00198 
00199 KMFilterActionWithString::KMFilterActionWithString( const char* aName, const TQString aLabel )
00200   : KMFilterAction( aName, aLabel )
00201 {
00202 }
00203 
00204 TQWidget* KMFilterActionWithString::createParamWidget( TQWidget* parent ) const
00205 {
00206   TQLineEdit *le = new KLineEdit(parent);
00207   le->setText( mParameter );
00208   return le;
00209 }
00210 
00211 void KMFilterActionWithString::applyParamWidgetValue( TQWidget* paramWidget )
00212 {
00213   mParameter = ((TQLineEdit*)paramWidget)->text();
00214 }
00215 
00216 void KMFilterActionWithString::setParamWidgetValue( TQWidget* paramWidget ) const
00217 {
00218   ((TQLineEdit*)paramWidget)->setText( mParameter );
00219 }
00220 
00221 void KMFilterActionWithString::clearParamWidget( TQWidget* paramWidget ) const
00222 {
00223   ((TQLineEdit*)paramWidget)->clear();
00224 }
00225 
00226 void KMFilterActionWithString::argsFromString( const TQString argsStr )
00227 {
00228   mParameter = argsStr;
00229 }
00230 
00231 const TQString KMFilterActionWithString::argsAsString() const
00232 {
00233   return mParameter;
00234 }
00235 
00236 const TQString KMFilterActionWithString::displayString() const
00237 {
00238   // FIXME after string freeze:
00239   // return i18n("").arg( );
00240   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
00241 }
00242 
00243 //=============================================================================
00244 //
00245 // class KMFilterActionWithStringList
00246 //
00247 //=============================================================================
00248 
00249 KMFilterActionWithStringList::KMFilterActionWithStringList( const char* aName, const TQString aLabel )
00250   : KMFilterActionWithString( aName, aLabel )
00251 {
00252 }
00253 
00254 TQWidget* KMFilterActionWithStringList::createParamWidget( TQWidget* parent ) const
00255 {
00256   TQComboBox *cb = new TQComboBox( false, parent );
00257   cb->insertStringList( mParameterList );
00258   setParamWidgetValue( cb );
00259   return cb;
00260 }
00261 
00262 void KMFilterActionWithStringList::applyParamWidgetValue( TQWidget* paramWidget )
00263 {
00264   mParameter = ((TQComboBox*)paramWidget)->currentText();
00265 }
00266 
00267 void KMFilterActionWithStringList::setParamWidgetValue( TQWidget* paramWidget ) const
00268 {
00269   int idx = mParameterList.findIndex( mParameter );
00270   ((TQComboBox*)paramWidget)->setCurrentItem( idx >= 0 ? idx : 0 );
00271 }
00272 
00273 void KMFilterActionWithStringList::clearParamWidget( TQWidget* paramWidget ) const
00274 {
00275   ((TQComboBox*)paramWidget)->setCurrentItem(0);
00276 }
00277 
00278 void KMFilterActionWithStringList::argsFromString( const TQString argsStr )
00279 {
00280   int idx = mParameterList.findIndex( argsStr );
00281   if ( idx < 0 ) {
00282     mParameterList.append( argsStr );
00283     idx = mParameterList.count() - 1;
00284   }
00285   mParameter = *mParameterList.at( idx );
00286 }
00287 
00288 
00289 //=============================================================================
00290 //
00291 // class KMFilterActionWithFolder
00292 //
00293 //=============================================================================
00294 
00295 KMFilterActionWithFolder::KMFilterActionWithFolder( const char* aName, const TQString aLabel )
00296   : KMFilterAction( aName, aLabel )
00297 {
00298   mFolder = 0;
00299 }
00300 
00301 TQWidget* KMFilterActionWithFolder::createParamWidget( TQWidget* parent ) const
00302 {
00303   FolderRequester *req = new FolderRequester( parent,
00304       kmkernel->getKMMainWidget()->folderTree() );
00305   setParamWidgetValue( req );
00306   return req;
00307 }
00308 
00309 void KMFilterActionWithFolder::applyParamWidgetValue( TQWidget* paramWidget )
00310 {
00311   mFolder = ((FolderRequester *)paramWidget)->folder();
00312   mFolderName = ((FolderRequester *)paramWidget)->folderId();
00313 }
00314 
00315 void KMFilterActionWithFolder::setParamWidgetValue( TQWidget* paramWidget ) const
00316 {
00317   if ( mFolder )
00318     ((FolderRequester *)paramWidget)->setFolder( mFolder );
00319   else
00320     ((FolderRequester *)paramWidget)->setFolder( mFolderName );
00321 }
00322 
00323 void KMFilterActionWithFolder::clearParamWidget( TQWidget* paramWidget ) const
00324 {
00325   ((FolderRequester *)paramWidget)->setFolder( kmkernel->draftsFolder() );
00326 }
00327 
00328 void KMFilterActionWithFolder::argsFromString( const TQString argsStr )
00329 {
00330   mFolder = kmkernel->folderMgr()->findIdString( argsStr );
00331   if (!mFolder)
00332      mFolder = kmkernel->dimapFolderMgr()->findIdString( argsStr );
00333   if (!mFolder)
00334      mFolder = kmkernel->imapFolderMgr()->findIdString( argsStr );
00335   if (mFolder)
00336      mFolderName = mFolder->idString();
00337   else
00338      mFolderName = argsStr;
00339 }
00340 
00341 const TQString KMFilterActionWithFolder::argsAsString() const
00342 {
00343   TQString result;
00344   if ( mFolder )
00345     result = mFolder->idString();
00346   else
00347     result = mFolderName;
00348   return result;
00349 }
00350 
00351 const TQString KMFilterActionWithFolder::displayString() const
00352 {
00353   TQString result;
00354   if ( mFolder )
00355     result = mFolder->prettyURL();
00356   else
00357     result = mFolderName;
00358   return label() + " \"" + TQStyleSheet::escape( result ) + "\"";
00359 }
00360 
00361 bool KMFilterActionWithFolder::folderRemoved( KMFolder* aFolder, KMFolder* aNewFolder )
00362 {
00363   if ( aFolder == mFolder ) {
00364     mFolder = aNewFolder;
00365     if ( aNewFolder )
00366       mFolderName = mFolder->idString();
00367     return true;
00368   } else
00369     return false;
00370 }
00371 
00372 //=============================================================================
00373 //
00374 // class KMFilterActionWithAddress
00375 //
00376 //=============================================================================
00377 
00378 KMFilterActionWithAddress::KMFilterActionWithAddress( const char* aName, const TQString aLabel )
00379   : KMFilterActionWithString( aName, aLabel )
00380 {
00381 }
00382 
00383 TQWidget* KMFilterActionWithAddress::createParamWidget( TQWidget* parent ) const
00384 {
00385   KMFilterActionWithAddressWidget *w = new KMFilterActionWithAddressWidget(parent);
00386   w->setText( mParameter );
00387   return w;
00388 }
00389 
00390 void KMFilterActionWithAddress::applyParamWidgetValue( TQWidget* paramWidget )
00391 {
00392   mParameter = ((KMFilterActionWithAddressWidget*)paramWidget)->text();
00393 }
00394 
00395 void KMFilterActionWithAddress::setParamWidgetValue( TQWidget* paramWidget ) const
00396 {
00397   ((KMFilterActionWithAddressWidget*)paramWidget)->setText( mParameter );
00398 }
00399 
00400 void KMFilterActionWithAddress::clearParamWidget( TQWidget* paramWidget ) const
00401 {
00402   ((KMFilterActionWithAddressWidget*)paramWidget)->clear();
00403 }
00404 
00405 //=============================================================================
00406 //
00407 // class KMFilterActionWithCommand
00408 //
00409 //=============================================================================
00410 
00411 KMFilterActionWithCommand::KMFilterActionWithCommand( const char* aName, const TQString aLabel )
00412   : KMFilterActionWithUrl( aName, aLabel )
00413 {
00414 }
00415 
00416 TQWidget* KMFilterActionWithCommand::createParamWidget( TQWidget* parent ) const
00417 {
00418   return KMFilterActionWithUrl::createParamWidget( parent );
00419 }
00420 
00421 void KMFilterActionWithCommand::applyParamWidgetValue( TQWidget* paramWidget )
00422 {
00423   KMFilterActionWithUrl::applyParamWidgetValue( paramWidget );
00424 }
00425 
00426 void KMFilterActionWithCommand::setParamWidgetValue( TQWidget* paramWidget ) const
00427 {
00428   KMFilterActionWithUrl::setParamWidgetValue( paramWidget );
00429 }
00430 
00431 void KMFilterActionWithCommand::clearParamWidget( TQWidget* paramWidget ) const
00432 {
00433   KMFilterActionWithUrl::clearParamWidget( paramWidget );
00434 }
00435 
00436 TQString KMFilterActionWithCommand::substituteCommandLineArgsFor( KMMessage *aMsg, TQPtrList<KTempFile> & aTempFileList ) const
00437 {
00438   TQString result = mParameter;
00439   TQValueList<int> argList;
00440   TQRegExp r( "%[0-9-]+" );
00441 
00442   // search for '%n'
00443   int start = -1;
00444   while ( ( start = r.search( result, start + 1 ) ) > 0 ) {
00445     int len = r.matchedLength();
00446     // and save the encountered 'n' in a list.
00447     bool OK = false;
00448     int n = result.mid( start + 1, len - 1 ).toInt( &OK );
00449     if ( OK )
00450       argList.append( n );
00451   }
00452 
00453   // sort the list of n's
00454   qHeapSort( argList );
00455 
00456   // and use TQString::arg to substitute filenames for the %n's.
00457   int lastSeen = -2;
00458   TQString tempFileName;
00459   for ( TQValueList<int>::Iterator it = argList.begin() ; it != argList.end() ; ++it ) {
00460     // setup temp files with check for duplicate %n's
00461     if ( (*it) != lastSeen ) {
00462       KTempFile *tf = new KTempFile();
00463       if ( tf->status() != 0 ) {
00464         tf->close();
00465         delete tf;
00466         kdDebug(5006) << "KMFilterActionWithCommand: Could not create temp file!" << endl;
00467         return TQString();
00468       }
00469       tf->setAutoDelete(true);
00470       aTempFileList.append( tf );
00471       tempFileName = tf->name();
00472       if ((*it) == -1)
00473         KPIM::kCStringToFile( aMsg->asString(), tempFileName, //###
00474                           false, false, false );
00475       else if (aMsg->numBodyParts() == 0)
00476         KPIM::kByteArrayToFile( aMsg->bodyDecodedBinary(), tempFileName,
00477                           false, false, false );
00478       else {
00479         KMMessagePart msgPart;
00480         aMsg->bodyPart( (*it), &msgPart );
00481         KPIM::kByteArrayToFile( msgPart.bodyDecodedBinary(), tempFileName,
00482                           false, false, false );
00483       }
00484       tf->close();
00485     }
00486     // TQString( "%0 and %1 and %1" ).arg( 0 ).arg( 1 )
00487     // returns "0 and 1 and %1", so we must call .arg as
00488     // many times as there are %n's, regardless of their multiplicity.
00489     if ((*it) == -1) result.replace( "%-1", tempFileName );
00490     else result = result.arg( tempFileName );
00491   }
00492 
00493   // And finally, replace the %{foo} with the content of the foo
00494   // header field:
00495   TQRegExp header_rx( "%\\{([a-z0-9-]+)\\}", false );
00496   int idx = 0;
00497   while ( ( idx = header_rx.search( result, idx ) ) != -1 ) {
00498     TQString replacement = KProcess::quote( aMsg->headerField( TQString(header_rx.cap(1)).latin1() ) );
00499     result.replace( idx, header_rx.matchedLength(), replacement );
00500     idx += replacement.length();
00501   }
00502 
00503   return result;
00504 }
00505 
00506 
00507 KMFilterAction::ReturnCode KMFilterActionWithCommand::genericProcess(KMMessage* aMsg, bool withOutput) const
00508 {
00509   Q_ASSERT( aMsg );
00510 
00511   if ( mParameter.isEmpty() )
00512     return ErrorButGoOn;
00513 
00514   // KProcess doesn't support a TQProcess::launch() equivalent, so
00515   // we must use a temp file :-(
00516   KTempFile * inFile = new KTempFile;
00517   inFile->setAutoDelete(true);
00518 
00519   TQPtrList<KTempFile> atmList;
00520   atmList.setAutoDelete(true);
00521   atmList.append( inFile );
00522 
00523   TQString commandLine = substituteCommandLineArgsFor( aMsg , atmList );
00524   if ( commandLine.isEmpty() )
00525     return ErrorButGoOn;
00526 
00527   // The parentheses force the creation of a subshell
00528   // in which the user-specified command is executed.
00529   // This is to really catch all output of the command as well
00530   // as to avoid clashes of our redirection with the ones
00531   // the user may have specified. In the long run, we
00532   // shouldn't be using tempfiles at all for this class, due
00533   // to security aspects. (mmutz)
00534   commandLine =  "(" + commandLine + ") <" + inFile->name();
00535 
00536   // write message to file
00537   TQString tempFileName = inFile->name();
00538   KPIM::kCStringToFile( aMsg->asString(), tempFileName, //###
00539                   false, false, false );
00540   inFile->close();
00541 
00542   CollectingProcess shProc;
00543   shProc.setUseShell(true);
00544   shProc << commandLine;
00545 
00546   // run process:
00547   if ( !shProc.start( KProcess::Block,
00548                       withOutput ? KProcess::Stdout
00549                                  : KProcess::NoCommunication ) )
00550     return ErrorButGoOn;
00551 
00552   if ( !shProc.normalExit() || shProc.exitStatus() != 0 ) {
00553     return ErrorButGoOn;
00554   }
00555 
00556   if ( withOutput ) {
00557     // read altered message:
00558     TQByteArray msgText = shProc.collectedStdout();
00559 
00560     if ( !msgText.isEmpty() ) {
00561     /* If the pipe through alters the message, it could very well
00562        happen that it no longer has a X-UID header afterwards. That is
00563        unfortunate, as we need to removed the original from the folder
00564        using that, and look it up in the message. When the (new) message
00565        is uploaded, the header is stripped anyhow. */
00566       TQString uid = aMsg->headerField("X-UID");
00567       aMsg->fromByteArray( msgText );
00568       aMsg->setHeaderField("X-UID",uid);
00569     }
00570     else
00571       return ErrorButGoOn;
00572   }
00573   return GoOn;
00574 }
00575 
00576 
00577 //=============================================================================
00578 //
00579 //   Specific  Filter  Actions
00580 //
00581 //=============================================================================
00582 
00583 //=============================================================================
00584 // KMFilterActionSendReceipt - send receipt
00585 // Return delivery receipt.
00586 //=============================================================================
00587 class KMFilterActionSendReceipt : public KMFilterActionWithNone
00588 {
00589 public:
00590   KMFilterActionSendReceipt();
00591   virtual ReturnCode process(KMMessage* msg) const;
00592   static KMFilterAction* newAction(void);
00593 };
00594 
00595 KMFilterAction* KMFilterActionSendReceipt::newAction(void)
00596 {
00597   return (new KMFilterActionSendReceipt);
00598 }
00599 
00600 KMFilterActionSendReceipt::KMFilterActionSendReceipt()
00601   : KMFilterActionWithNone( "confirm delivery", i18n("Confirm Delivery") )
00602 {
00603 }
00604 
00605 KMFilterAction::ReturnCode KMFilterActionSendReceipt::process(KMMessage* msg) const
00606 {
00607   KMMessage *receipt = msg->createDeliveryReceipt();
00608   if ( !receipt ) return ErrorButGoOn;
00609 
00610   // Queue message. This is a) so that the user can check
00611   // the receipt before sending and b) for speed reasons.
00612   kmkernel->msgSender()->send( receipt, KMail::MessageSender::SendLater );
00613 
00614   return GoOn;
00615 }
00616 
00617 
00618 
00619 //=============================================================================
00620 // KMFilterActionSetTransport - set transport to...
00621 // Specify mail transport (smtp server) to be used when replying to a message
00622 //=============================================================================
00623 class KMFilterActionTransport: public KMFilterActionWithString
00624 {
00625 public:
00626   KMFilterActionTransport();
00627   virtual ReturnCode process(KMMessage* msg) const;
00628   static KMFilterAction* newAction(void);
00629 };
00630 
00631 KMFilterAction* KMFilterActionTransport::newAction(void)
00632 {
00633   return (new KMFilterActionTransport);
00634 }
00635 
00636 KMFilterActionTransport::KMFilterActionTransport()
00637   : KMFilterActionWithString( "set transport", i18n("Set Transport To") )
00638 {
00639 }
00640 
00641 KMFilterAction::ReturnCode KMFilterActionTransport::process(KMMessage* msg) const
00642 {
00643   if ( mParameter.isEmpty() )
00644     return ErrorButGoOn;
00645   msg->setHeaderField( "X-KMail-Transport", mParameter );
00646   return GoOn;
00647 }
00648 
00649 
00650 //=============================================================================
00651 // KMFilterActionReplyTo - set Reply-To to
00652 // Set the Reply-to header in a message
00653 //=============================================================================
00654 class KMFilterActionReplyTo: public KMFilterActionWithString
00655 {
00656 public:
00657   KMFilterActionReplyTo();
00658   virtual ReturnCode process(KMMessage* msg) const;
00659   static KMFilterAction* newAction(void);
00660 };
00661 
00662 KMFilterAction* KMFilterActionReplyTo::newAction(void)
00663 {
00664   return (new KMFilterActionReplyTo);
00665 }
00666 
00667 KMFilterActionReplyTo::KMFilterActionReplyTo()
00668   : KMFilterActionWithString( "set Reply-To", i18n("Set Reply-To To") )
00669 {
00670   mParameter = "";
00671 }
00672 
00673 KMFilterAction::ReturnCode KMFilterActionReplyTo::process(KMMessage* msg) const
00674 {
00675   msg->setHeaderField( "Reply-To", mParameter );
00676   return GoOn;
00677 }
00678 
00679 
00680 
00681 //=============================================================================
00682 // KMFilterActionIdentity - set identity to
00683 // Specify Identity to be used when replying to a message
00684 //=============================================================================
00685 class KMFilterActionIdentity: public KMFilterActionWithUOID
00686 {
00687 public:
00688   KMFilterActionIdentity();
00689   virtual ReturnCode process(KMMessage* msg) const;
00690   static KMFilterAction* newAction();
00691 
00692   TQWidget * createParamWidget( TQWidget * parent ) const;
00693   void applyParamWidgetValue( TQWidget * parent );
00694   void setParamWidgetValue( TQWidget * parent ) const;
00695   void clearParamWidget( TQWidget * param ) const;
00696 };
00697 
00698 KMFilterAction* KMFilterActionIdentity::newAction()
00699 {
00700   return (new KMFilterActionIdentity);
00701 }
00702 
00703 KMFilterActionIdentity::KMFilterActionIdentity()
00704   : KMFilterActionWithUOID( "set identity", i18n("Set Identity To") )
00705 {
00706   mParameter = kmkernel->identityManager()->defaultIdentity().uoid();
00707 }
00708 
00709 KMFilterAction::ReturnCode KMFilterActionIdentity::process(KMMessage* msg) const
00710 {
00711   msg->setHeaderField( "X-KMail-Identity", TQString::number( mParameter ) );
00712   return GoOn;
00713 }
00714 
00715 TQWidget * KMFilterActionIdentity::createParamWidget( TQWidget * parent ) const
00716 {
00717   KPIM::IdentityCombo * ic = new KPIM::IdentityCombo( kmkernel->identityManager(), parent );
00718   ic->setCurrentIdentity( mParameter );
00719   return ic;
00720 }
00721 
00722 void KMFilterActionIdentity::applyParamWidgetValue( TQWidget * paramWidget )
00723 {
00724   KPIM::IdentityCombo * ic = dynamic_cast<KPIM::IdentityCombo*>( paramWidget );
00725   assert( ic );
00726   mParameter = ic->currentIdentity();
00727 }
00728 
00729 void KMFilterActionIdentity::clearParamWidget( TQWidget * paramWidget ) const
00730 {
00731   KPIM::IdentityCombo * ic = dynamic_cast<KPIM::IdentityCombo*>( paramWidget );
00732   assert( ic );
00733   ic->setCurrentItem( 0 );
00734   //ic->setCurrentIdentity( kmkernel->identityManager()->defaultIdentity() );
00735 }
00736 
00737 void KMFilterActionIdentity::setParamWidgetValue( TQWidget * paramWidget ) const
00738 {
00739   KPIM::IdentityCombo * ic = dynamic_cast<KPIM::IdentityCombo*>( paramWidget );
00740   assert( ic );
00741   ic->setCurrentIdentity( mParameter );
00742 }
00743 
00744 //=============================================================================
00745 // KMFilterActionSeStatus - set status to
00746 // Set the status of messages
00747 //=============================================================================
00748 class KMFilterActionSeStatus: public KMFilterActionWithStringList
00749 {
00750 public:
00751   KMFilterActionSeStatus();
00752   virtual ReturnCode process(KMMessage* msg) const;
00753   virtual bool requiresBody(KMMsgBase*) const;
00754 
00755   static KMFilterAction* newAction();
00756 
00757   virtual bool isEmpty() const { return false; }
00758 
00759   virtual void argsFromString( const TQString argsStr );
00760   virtual const TQString argsAsString() const;
00761   virtual const TQString displayString() const;
00762 };
00763 
00764 
00765 static const KMMsgStatus stati[] =
00766 {
00767   KMMsgStatusFlag,
00768   KMMsgStatusRead,
00769   KMMsgStatusUnread,
00770   KMMsgStatusReplied,
00771   KMMsgStatusForwarded,
00772   KMMsgStatusOld,
00773   KMMsgStatusNew,
00774   KMMsgStatusWatched,
00775   KMMsgStatusIgnored,
00776   KMMsgStatusSpam,
00777   KMMsgStatusHam
00778 };
00779 static const int StatiCount = sizeof( stati ) / sizeof( KMMsgStatus );
00780 
00781 KMFilterAction* KMFilterActionSeStatus::newAction()
00782 {
00783   return (new KMFilterActionSeStatus);
00784 }
00785 
00786 KMFilterActionSeStatus::KMFilterActionSeStatus()
00787   : KMFilterActionWithStringList( "set status", i18n("Mark As") )
00788 {
00789   // if you change this list, also update
00790   // KMFilterActionSeStatus::stati above
00791   mParameterList.append( "" );
00792   mParameterList.append( i18n("msg status","Important") );
00793   mParameterList.append( i18n("msg status","Read") );
00794   mParameterList.append( i18n("msg status","Unread") );
00795   mParameterList.append( i18n("msg status","Replied") );
00796   mParameterList.append( i18n("msg status","Forwarded") );
00797   mParameterList.append( i18n("msg status","Old") );
00798   mParameterList.append( i18n("msg status","New") );
00799   mParameterList.append( i18n("msg status","Watched") );
00800   mParameterList.append( i18n("msg status","Ignored") );
00801   mParameterList.append( i18n("msg status","Spam") );
00802   mParameterList.append( i18n("msg status","Ham") );
00803 
00804   mParameter = *mParameterList.at(0);
00805 }
00806 
00807 KMFilterAction::ReturnCode KMFilterActionSeStatus::process(KMMessage* msg) const
00808 {
00809   int idx = mParameterList.findIndex( mParameter );
00810   if ( idx < 1 ) return ErrorButGoOn;
00811 
00812   KMMsgStatus status = stati[idx-1] ;
00813   msg->setStatus( status );
00814   return GoOn;
00815 }
00816 
00817 bool KMFilterActionSeStatus::requiresBody(KMMsgBase*) const
00818 {
00819   return false;
00820 }
00821 
00822 void KMFilterActionSeStatus::argsFromString( const TQString argsStr )
00823 {
00824   if ( argsStr.length() == 1 ) {
00825     for ( int i = 0 ; i < StatiCount ; i++ )
00826       if ( KMMsgBase::statusToStr(stati[i])[0] == argsStr[0] ) {
00827         mParameter = *mParameterList.at(i+1);
00828         return;
00829       }
00830   }
00831   mParameter = *mParameterList.at(0);
00832 }
00833 
00834 const TQString KMFilterActionSeStatus::argsAsString() const
00835 {
00836   int idx = mParameterList.findIndex( mParameter );
00837   if ( idx < 1 ) return TQString();
00838 
00839   KMMsgStatus status = stati[idx-1];
00840   return KMMsgBase::statusToStr(status);
00841 }
00842 
00843 const TQString KMFilterActionSeStatus::displayString() const
00844 {
00845   // FIXME after string freeze:
00846   // return i18n("").arg( );
00847   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
00848 }
00849 
00850 //=============================================================================
00851 // KMFilterActionFakeDisposition - send fake MDN
00852 // Sends a fake MDN or forces an ignore.
00853 //=============================================================================
00854 class KMFilterActionFakeDisposition: public KMFilterActionWithStringList
00855 {
00856 public:
00857   KMFilterActionFakeDisposition();
00858   virtual ReturnCode process(KMMessage* msg) const;
00859   static KMFilterAction* newAction() {
00860     return (new KMFilterActionFakeDisposition);
00861   }
00862 
00863   virtual bool isEmpty() const { return false; }
00864 
00865   virtual void argsFromString( const TQString argsStr );
00866   virtual const TQString argsAsString() const;
00867   virtual const TQString displayString() const;
00868 };
00869 
00870 
00871 // if you change this list, also update
00872 // the count in argsFromString
00873 static const KMime::MDN::DispositionType mdns[] =
00874 {
00875   KMime::MDN::Displayed,
00876   KMime::MDN::Deleted,
00877   KMime::MDN::Dispatched,
00878   KMime::MDN::Processed,
00879   KMime::MDN::Denied,
00880   KMime::MDN::Failed,
00881 };
00882 static const int numMDNs = sizeof mdns / sizeof *mdns;
00883 
00884 
00885 KMFilterActionFakeDisposition::KMFilterActionFakeDisposition()
00886   : KMFilterActionWithStringList( "fake mdn", i18n("Send Fake MDN") )
00887 {
00888   // if you change this list, also update
00889   // mdns above
00890   mParameterList.append( "" );
00891   mParameterList.append( i18n("MDN type","Ignore") );
00892   mParameterList.append( i18n("MDN type","Displayed") );
00893   mParameterList.append( i18n("MDN type","Deleted") );
00894   mParameterList.append( i18n("MDN type","Dispatched") );
00895   mParameterList.append( i18n("MDN type","Processed") );
00896   mParameterList.append( i18n("MDN type","Denied") );
00897   mParameterList.append( i18n("MDN type","Failed") );
00898 
00899   mParameter = *mParameterList.at(0);
00900 }
00901 
00902 KMFilterAction::ReturnCode KMFilterActionFakeDisposition::process(KMMessage* msg) const
00903 {
00904   int idx = mParameterList.findIndex( mParameter );
00905   if ( idx < 1 ) return ErrorButGoOn;
00906 
00907   if ( idx == 1 ) // ignore
00908     msg->setMDNSentState( KMMsgMDNIgnore );
00909   else // send
00910     sendMDN( msg, mdns[idx-2] ); // skip first two entries: "" and "ignore"
00911   return GoOn;
00912 }
00913 
00914 void KMFilterActionFakeDisposition::argsFromString( const TQString argsStr )
00915 {
00916   if ( argsStr.length() == 1 ) {
00917     if ( argsStr[0] == 'I' ) { // ignore
00918       mParameter = *mParameterList.at(1);
00919       return;
00920     }
00921     for ( int i = 0 ; i < numMDNs ; i++ )
00922       if ( char(mdns[i]) == argsStr[0] ) { // send
00923         mParameter = *mParameterList.at(i+2);
00924         return;
00925       }
00926   }
00927   mParameter = *mParameterList.at(0);
00928 }
00929 
00930 const TQString KMFilterActionFakeDisposition::argsAsString() const
00931 {
00932   int idx = mParameterList.findIndex( mParameter );
00933   if ( idx < 1 ) return TQString();
00934 
00935   return TQString( TQChar( idx < 2 ? 'I' : char(mdns[idx-2]) ) );
00936 }
00937 
00938 const TQString KMFilterActionFakeDisposition::displayString() const
00939 {
00940   // FIXME after string freeze:
00941   // return i18n("").arg( );
00942   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
00943 }
00944 
00945 //=============================================================================
00946 // KMFilterActionRemoveHeader - remove header
00947 // Remove all instances of the given header field.
00948 //=============================================================================
00949 class KMFilterActionRemoveHeader: public KMFilterActionWithStringList
00950 {
00951 public:
00952   KMFilterActionRemoveHeader();
00953   virtual ReturnCode process(KMMessage* msg) const;
00954   virtual TQWidget* createParamWidget( TQWidget* parent ) const;
00955   virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
00956 
00957   static KMFilterAction* newAction();
00958 };
00959 
00960 KMFilterAction* KMFilterActionRemoveHeader::newAction()
00961 {
00962   return (new KMFilterActionRemoveHeader);
00963 }
00964 
00965 KMFilterActionRemoveHeader::KMFilterActionRemoveHeader()
00966   : KMFilterActionWithStringList( "remove header", i18n("Remove Header") )
00967 {
00968   mParameterList << ""
00969                  << "Reply-To"
00970                  << "Delivered-To"
00971                  << "X-KDE-PR-Message"
00972                  << "X-KDE-PR-Package"
00973                  << "X-KDE-PR-Keywords";
00974   mParameter = *mParameterList.at(0);
00975 }
00976 
00977 TQWidget* KMFilterActionRemoveHeader::createParamWidget( TQWidget* parent ) const
00978 {
00979   TQComboBox *cb = new TQComboBox( true/*editable*/, parent );
00980   cb->setInsertionPolicy( TQComboBox::AtBottom );
00981   setParamWidgetValue( cb );
00982   return cb;
00983 }
00984 
00985 KMFilterAction::ReturnCode KMFilterActionRemoveHeader::process(KMMessage* msg) const
00986 {
00987   if ( mParameter.isEmpty() ) return ErrorButGoOn;
00988 
00989   while ( !msg->headerField( mParameter.latin1() ).isEmpty() )
00990     msg->removeHeaderField( mParameter.latin1() );
00991   return GoOn;
00992 }
00993 
00994 void KMFilterActionRemoveHeader::setParamWidgetValue( TQWidget* paramWidget ) const
00995 {
00996   TQComboBox * cb = dynamic_cast<TQComboBox*>(paramWidget);
00997   Q_ASSERT( cb );
00998 
00999   int idx = mParameterList.findIndex( mParameter );
01000   cb->clear();
01001   cb->insertStringList( mParameterList );
01002   if ( idx < 0 ) {
01003     cb->insertItem( mParameter );
01004     cb->setCurrentItem( cb->count() - 1 );
01005   } else {
01006     cb->setCurrentItem( idx );
01007   }
01008 }
01009 
01010 
01011 //=============================================================================
01012 // KMFilterActionAddHeader - add header
01013 // Add a header with the given value.
01014 //=============================================================================
01015 class KMFilterActionAddHeader: public KMFilterActionWithStringList
01016 {
01017 public:
01018   KMFilterActionAddHeader();
01019   virtual ReturnCode process(KMMessage* msg) const;
01020   virtual TQWidget* createParamWidget( TQWidget* parent ) const;
01021   virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
01022   virtual void applyParamWidgetValue( TQWidget* paramWidget );
01023   virtual void clearParamWidget( TQWidget* paramWidget ) const;
01024 
01025   virtual const TQString argsAsString() const;
01026   virtual void argsFromString( const TQString argsStr );
01027 
01028   virtual const TQString displayString() const;
01029 
01030   static KMFilterAction* newAction()
01031   {
01032     return (new KMFilterActionAddHeader);
01033   }
01034 private:
01035   TQString mValue;
01036 };
01037 
01038 KMFilterActionAddHeader::KMFilterActionAddHeader()
01039   : KMFilterActionWithStringList( "add header", i18n("Add Header") )
01040 {
01041   mParameterList << ""
01042                  << "Reply-To"
01043                  << "Delivered-To"
01044                  << "X-KDE-PR-Message"
01045                  << "X-KDE-PR-Package"
01046                  << "X-KDE-PR-Keywords";
01047   mParameter = *mParameterList.at(0);
01048 }
01049 
01050 KMFilterAction::ReturnCode KMFilterActionAddHeader::process(KMMessage* msg) const
01051 {
01052   if ( mParameter.isEmpty() ) return ErrorButGoOn;
01053 
01054   msg->setHeaderField( mParameter.latin1(), mValue );
01055   return GoOn;
01056 }
01057 
01058 TQWidget* KMFilterActionAddHeader::createParamWidget( TQWidget* parent ) const
01059 {
01060   TQWidget *w = new TQWidget( parent );
01061   TQHBoxLayout *hbl = new TQHBoxLayout( w );
01062   hbl->setSpacing( 4 );
01063   TQComboBox *cb = new TQComboBox( true, w, "combo" );
01064   cb->setInsertionPolicy( TQComboBox::AtBottom );
01065   hbl->addWidget( cb, 0 /* stretch */ );
01066   TQLabel *l = new TQLabel( i18n("With value:"), w );
01067   l->setFixedWidth( l->sizeHint().width() );
01068   hbl->addWidget( l, 0 );
01069   TQLineEdit *le = new KLineEdit( w, "ledit" );
01070   hbl->addWidget( le, 1 );
01071   setParamWidgetValue( w );
01072   return w;
01073 }
01074 
01075 void KMFilterActionAddHeader::setParamWidgetValue( TQWidget* paramWidget ) const
01076 {
01077   int idx = mParameterList.findIndex( mParameter );
01078   TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
01079   Q_ASSERT( cb );
01080   cb->clear();
01081   cb->insertStringList( mParameterList );
01082   if ( idx < 0 ) {
01083     cb->insertItem( mParameter );
01084     cb->setCurrentItem( cb->count() - 1 );
01085   } else {
01086     cb->setCurrentItem( idx );
01087   }
01088   TQLineEdit *le = (TQLineEdit*)paramWidget->child("ledit");
01089   Q_ASSERT( le );
01090   le->setText( mValue );
01091 }
01092 
01093 void KMFilterActionAddHeader::applyParamWidgetValue( TQWidget* paramWidget )
01094 {
01095   TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
01096   Q_ASSERT( cb );
01097   mParameter = cb->currentText();
01098 
01099   TQLineEdit *le = (TQLineEdit*)paramWidget->child("ledit");
01100   Q_ASSERT( le );
01101   mValue = le->text();
01102 }
01103 
01104 void KMFilterActionAddHeader::clearParamWidget( TQWidget* paramWidget ) const
01105 {
01106   TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
01107   Q_ASSERT( cb );
01108   cb->setCurrentItem(0);
01109   TQLineEdit *le = (TQLineEdit*)paramWidget->child("ledit");
01110   Q_ASSERT( le );
01111   le->clear();
01112 }
01113 
01114 const TQString KMFilterActionAddHeader::argsAsString() const
01115 {
01116   TQString result = mParameter;
01117   result += '\t';
01118   result += mValue;
01119 
01120   return result;
01121 }
01122 
01123 const TQString KMFilterActionAddHeader::displayString() const
01124 {
01125   // FIXME after string freeze:
01126   // return i18n("").arg( );
01127   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
01128 }
01129 
01130 void KMFilterActionAddHeader::argsFromString( const TQString argsStr )
01131 {
01132   TQStringList l = TQStringList::split( '\t', argsStr, true /*allow empty entries*/ );
01133   TQString s;
01134   if ( l.count() < 2 ) {
01135     s = l[0];
01136     mValue = "";
01137   } else {
01138     s = l[0];
01139     mValue = l[1];
01140   }
01141 
01142   int idx = mParameterList.findIndex( s );
01143   if ( idx < 0 ) {
01144     mParameterList.append( s );
01145     idx = mParameterList.count() - 1;
01146   }
01147   mParameter = *mParameterList.at( idx );
01148 }
01149 
01150 
01151 //=============================================================================
01152 // KMFilterActionRewriteHeader - rewrite header
01153 // Rewrite a header using a regexp.
01154 //=============================================================================
01155 class KMFilterActionRewriteHeader: public KMFilterActionWithStringList
01156 {
01157 public:
01158   KMFilterActionRewriteHeader();
01159   virtual ReturnCode process(KMMessage* msg) const;
01160   virtual TQWidget* createParamWidget( TQWidget* parent ) const;
01161   virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
01162   virtual void applyParamWidgetValue( TQWidget* paramWidget );
01163   virtual void clearParamWidget( TQWidget* paramWidget ) const;
01164 
01165   virtual const TQString argsAsString() const;
01166   virtual void argsFromString( const TQString argsStr );
01167 
01168   virtual const TQString displayString() const;
01169 
01170   static KMFilterAction* newAction()
01171   {
01172     return (new KMFilterActionRewriteHeader);
01173   }
01174 private:
01175   KRegExp3 mRegExp;
01176   TQString mReplacementString;
01177 };
01178 
01179 KMFilterActionRewriteHeader::KMFilterActionRewriteHeader()
01180   : KMFilterActionWithStringList( "rewrite header", i18n("Rewrite Header") )
01181 {
01182   mParameterList << ""
01183                  << "Subject"
01184                  << "Reply-To"
01185                  << "Delivered-To"
01186                  << "X-KDE-PR-Message"
01187                  << "X-KDE-PR-Package"
01188                  << "X-KDE-PR-Keywords";
01189   mParameter = *mParameterList.at(0);
01190 }
01191 
01192 KMFilterAction::ReturnCode KMFilterActionRewriteHeader::process(KMMessage* msg) const
01193 {
01194   if ( mParameter.isEmpty() || !mRegExp.isValid() )
01195     return ErrorButGoOn;
01196 
01197   KRegExp3 rx = mRegExp; // KRegExp3::replace is not const.
01198 
01199   TQString newValue = rx.replace( msg->headerField( mParameter.latin1() ),
01200                                      mReplacementString );
01201 
01202   msg->setHeaderField( mParameter.latin1(), newValue );
01203   return GoOn;
01204 }
01205 
01206 TQWidget* KMFilterActionRewriteHeader::createParamWidget( TQWidget* parent ) const
01207 {
01208   TQWidget *w = new TQWidget( parent );
01209   TQHBoxLayout *hbl = new TQHBoxLayout( w );
01210   hbl->setSpacing( 4 );
01211 
01212   TQComboBox *cb = new TQComboBox( true, w, "combo" );
01213   cb->setInsertionPolicy( TQComboBox::AtBottom );
01214   hbl->addWidget( cb, 0 /* stretch */ );
01215 
01216   TQLabel *l = new TQLabel( i18n("Replace:"), w );
01217   l->setFixedWidth( l->sizeHint().width() );
01218   hbl->addWidget( l, 0 );
01219 
01220   RegExpLineEdit *rele = new RegExpLineEdit( w, "search" );
01221   hbl->addWidget( rele, 1 );
01222 
01223   l = new TQLabel( i18n("With:"), w );
01224   l->setFixedWidth( l->sizeHint().width() );
01225   hbl->addWidget( l, 0 );
01226 
01227   TQLineEdit *le = new KLineEdit( w, "replace" );
01228   hbl->addWidget( le, 1 );
01229 
01230   setParamWidgetValue( w );
01231   return w;
01232 }
01233 
01234 void KMFilterActionRewriteHeader::setParamWidgetValue( TQWidget* paramWidget ) const
01235 {
01236   int idx = mParameterList.findIndex( mParameter );
01237   TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
01238   Q_ASSERT( cb );
01239 
01240   cb->clear();
01241   cb->insertStringList( mParameterList );
01242   if ( idx < 0 ) {
01243     cb->insertItem( mParameter );
01244     cb->setCurrentItem( cb->count() - 1 );
01245   } else {
01246     cb->setCurrentItem( idx );
01247   }
01248 
01249   RegExpLineEdit *rele = (RegExpLineEdit*)paramWidget->child("search");
01250   Q_ASSERT( rele );
01251   rele->setText( mRegExp.pattern() );
01252 
01253   TQLineEdit *le = (TQLineEdit*)paramWidget->child("replace");
01254   Q_ASSERT( le );
01255   le->setText( mReplacementString );
01256 }
01257 
01258 void KMFilterActionRewriteHeader::applyParamWidgetValue( TQWidget* paramWidget )
01259 {
01260   TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
01261   Q_ASSERT( cb );
01262   mParameter = cb->currentText();
01263 
01264   RegExpLineEdit *rele = (RegExpLineEdit*)paramWidget->child("search");
01265   Q_ASSERT( rele );
01266   mRegExp.setPattern( rele->text() );
01267 
01268   TQLineEdit *le = (TQLineEdit*)paramWidget->child("replace");
01269   Q_ASSERT( le );
01270   mReplacementString = le->text();
01271 }
01272 
01273 void KMFilterActionRewriteHeader::clearParamWidget( TQWidget* paramWidget ) const
01274 {
01275   TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
01276   Q_ASSERT( cb );
01277   cb->setCurrentItem(0);
01278 
01279   RegExpLineEdit *rele = (RegExpLineEdit*)paramWidget->child("search");
01280   Q_ASSERT( rele );
01281   rele->clear();
01282 
01283   TQLineEdit *le = (TQLineEdit*)paramWidget->child("replace");
01284   Q_ASSERT( le );
01285   le->clear();
01286 }
01287 
01288 const TQString KMFilterActionRewriteHeader::argsAsString() const
01289 {
01290   TQString result = mParameter;
01291   result += '\t';
01292   result += mRegExp.pattern();
01293   result += '\t';
01294   result += mReplacementString;
01295 
01296   return result;
01297 }
01298 
01299 const TQString KMFilterActionRewriteHeader::displayString() const
01300 {
01301   // FIXME after string freeze:
01302   // return i18n("").arg( );
01303   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
01304 }
01305 
01306 void KMFilterActionRewriteHeader::argsFromString( const TQString argsStr )
01307 {
01308   TQStringList l = TQStringList::split( '\t', argsStr, true /*allow empty entries*/ );
01309   TQString s;
01310 
01311   s = l[0];
01312   mRegExp.setPattern( l[1] );
01313   mReplacementString = l[2];
01314 
01315   int idx = mParameterList.findIndex( s );
01316   if ( idx < 0 ) {
01317     mParameterList.append( s );
01318     idx = mParameterList.count() - 1;
01319   }
01320   mParameter = *mParameterList.at( idx );
01321 }
01322 
01323 
01324 //=============================================================================
01325 // KMFilterActionMove - move into folder
01326 // File message into another mail folder
01327 //=============================================================================
01328 class KMFilterActionMove: public KMFilterActionWithFolder
01329 {
01330 public:
01331   KMFilterActionMove();
01332   virtual ReturnCode process(KMMessage* msg) const;
01333   virtual bool requiresBody(KMMsgBase*) const;
01334   static KMFilterAction* newAction(void);
01335 };
01336 
01337 KMFilterAction* KMFilterActionMove::newAction(void)
01338 {
01339   return (new KMFilterActionMove);
01340 }
01341 
01342 KMFilterActionMove::KMFilterActionMove()
01343   : KMFilterActionWithFolder( "transfer", i18n("Move Into Folder") )
01344 {
01345 }
01346 
01347 KMFilterAction::ReturnCode KMFilterActionMove::process(KMMessage* msg) const
01348 {
01349   if ( !mFolder )
01350     return ErrorButGoOn;
01351 
01352   ActionScheduler *handler = MessageProperty::filterHandler( msg );
01353   if (handler) {
01354     MessageProperty::setFilterFolder( msg, mFolder );
01355   } else {
01356     // The old filtering system does not support online imap targets.
01357     // Skip online imap targets when using the old system.
01358     KMFolder *check;
01359     check = kmkernel->imapFolderMgr()->findIdString( argsAsString() );
01360     if (mFolder && (check != mFolder)) {
01361       MessageProperty::setFilterFolder( msg, mFolder );
01362     }
01363   }
01364   return GoOn;
01365 }
01366 
01367 bool KMFilterActionMove::requiresBody(KMMsgBase*) const
01368 {
01369     return false; //iff mFolder->folderMgr == msgBase->parent()->folderMgr;
01370 }
01371 
01372 
01373 //=============================================================================
01374 // KMFilterActionCopy - copy into folder
01375 // Copy message into another mail folder
01376 //=============================================================================
01377 class KMFilterActionCopy: public KMFilterActionWithFolder
01378 {
01379 public:
01380   KMFilterActionCopy();
01381   virtual ReturnCode process(KMMessage* msg) const;
01382   virtual void processAsync(KMMessage* msg) const;
01383   virtual bool requiresBody(KMMsgBase*) const;
01384   static KMFilterAction* newAction(void);
01385 };
01386 
01387 KMFilterAction* KMFilterActionCopy::newAction(void)
01388 {
01389   return (new KMFilterActionCopy);
01390 }
01391 
01392 KMFilterActionCopy::KMFilterActionCopy()
01393   : KMFilterActionWithFolder( "copy", i18n("Copy Into Folder") )
01394 {
01395 }
01396 
01397 KMFilterAction::ReturnCode KMFilterActionCopy::process(KMMessage* msg) const
01398 {
01399   // TODO opening and closing the folder is a trade off.
01400   // Perhaps Copy is a seldomly used action for now,
01401   // but I gonna look at improvements ASAP.
01402   if ( !mFolder )
01403     return ErrorButGoOn;
01404   if ( mFolder && mFolder->open( "filtercopy" ) != 0 )
01405     return ErrorButGoOn;
01406 
01407   // copy the message 1:1
01408   KMMessage* msgCopy = new KMMessage( new DwMessage( *msg->asDwMessage() ) );
01409 
01410   int index;
01411   int rc = mFolder->addMsg(msgCopy, &index);
01412   if (rc == 0 && index != -1)
01413     mFolder->unGetMsg( index );
01414   mFolder->close("filtercopy");
01415 
01416   return GoOn;
01417 }
01418 
01419 void KMFilterActionCopy::processAsync(KMMessage* msg) const
01420 {
01421   // FIXME remove the debug output
01422   kdDebug(5006) << "##### KMFilterActionCopy::processAsync(KMMessage* msg)" << endl;
01423   ActionScheduler *handler = MessageProperty::filterHandler( msg );
01424 
01425   KMCommand *cmd = new KMCopyCommand( mFolder, msg );
01426   TQObject::connect( cmd, TQT_SIGNAL( completed( KMCommand * ) ),
01427                     handler, TQT_SLOT( copyMessageFinished( KMCommand * ) ) );
01428   cmd->start();
01429 }
01430 
01431 bool KMFilterActionCopy::requiresBody(KMMsgBase*) const
01432 {
01433     return true;
01434 }
01435 
01436 
01437 //=============================================================================
01438 // KMFilterActionForward - forward to
01439 // Forward message to another user, with a defined template
01440 //=============================================================================
01441 class KMFilterActionForward: public KMFilterActionWithAddress
01442 {
01443 public:
01444   KMFilterActionForward();
01445   virtual ReturnCode process( KMMessage* msg ) const;
01446   virtual TQWidget* createParamWidget( TQWidget* parent ) const;
01447   virtual void applyParamWidgetValue( TQWidget* paramWidget );
01448   virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
01449   virtual void clearParamWidget( TQWidget* paramWidget ) const;
01450   virtual void argsFromString( const TQString argsStr );
01451   virtual const TQString argsAsString() const;
01452   virtual const TQString displayString() const;
01453 
01454   static KMFilterAction* newAction(void);
01455 
01456 private:
01457 
01458   mutable TQString mTemplate;
01459 };
01460 
01461 KMFilterAction* KMFilterActionForward::newAction(void)
01462 {
01463   return (new KMFilterActionForward);
01464 }
01465 
01466 KMFilterActionForward::KMFilterActionForward()
01467   : KMFilterActionWithAddress( "forward", i18n("Forward To") )
01468 {
01469 }
01470 
01471 KMFilterAction::ReturnCode KMFilterActionForward::process(KMMessage* aMsg) const
01472 {
01473   if ( mParameter.isEmpty() )
01474     return ErrorButGoOn;
01475 
01476   // avoid endless loops when this action is used in a filter
01477   // which applies to sent messages
01478   if ( KMMessage::addressIsInAddressList( mParameter, aMsg->to() ) ) {
01479     kdWarning(5006) << "Attempt to forward to receipient of original message, ignoring." << endl;
01480     return ErrorButGoOn;
01481   }
01482 
01483   KMMessage *fwdMsg = aMsg->createForward( mTemplate );
01484   fwdMsg->setTo( fwdMsg->to() + ',' + mParameter );
01485 
01486   if ( !kmkernel->msgSender()->send( fwdMsg, KMail::MessageSender::SendDefault ) ) {
01487     kdWarning(5006) << "KMFilterAction: could not forward message (sending failed)" << endl;
01488     return ErrorButGoOn; // error: couldn't send
01489   }
01490   else
01491     sendMDN( aMsg, KMime::MDN::Dispatched );
01492 
01493   // (the msgSender takes ownership of the message, so don't delete it here)
01494 
01495   return GoOn;
01496 }
01497 
01498 TQWidget* KMFilterActionForward::createParamWidget( TQWidget* parent ) const
01499 {
01500   TQWidget *addressAndTemplate = new TQWidget( parent );
01501   TQHBoxLayout *hBox = new TQHBoxLayout( addressAndTemplate );
01502   TQWidget *addressEdit = KMFilterActionWithAddress::createParamWidget( addressAndTemplate );
01503   addressEdit->setName( "addressEdit" );
01504   hBox->addWidget( addressEdit );
01505 
01506   KLineEdit *lineEdit = dynamic_cast<KLineEdit*>( addressEdit->child( "addressEdit" ) );
01507   Q_ASSERT( lineEdit );
01508   TQToolTip::add( lineEdit, i18n( "The addressee the message will be forwarded to" ) );
01509   TQWhatsThis::add( lineEdit, i18n( "The filter will forward the message to the addressee entered here." ) );
01510 
01511   TQComboBox *templateCombo = new TQComboBox( addressAndTemplate );
01512   templateCombo->setName( "templateCombo" );
01513   hBox->addWidget( templateCombo );
01514 
01515   templateCombo->insertItem( i18n( "Default Template" ) );
01516   TQStringList templateNames = GlobalSettingsBase::self()->customTemplates();
01517   for ( TQStringList::const_iterator it = templateNames.begin(); it != templateNames.end();
01518         it++ ) {
01519     CTemplates templat( *it );
01520     if ( templat.type() == CustomTemplates::TForward ||
01521          templat.type() == CustomTemplates::TUniversal )
01522       templateCombo->insertItem( *it );
01523   }
01524   templateCombo->setEnabled( templateCombo->count() > 1 );
01525   TQToolTip::add( templateCombo, i18n( "The template used when forwarding" ) );
01526   TQWhatsThis::add( templateCombo, i18n( "Set the forwarding template that will be used with this filter." ) );
01527 
01528   return addressAndTemplate;
01529 }
01530 
01531 void KMFilterActionForward::applyParamWidgetValue( TQWidget* paramWidget )
01532 {
01533   // Use findChildren<T> when porting to KDE 4
01534   TQWidget *addressEdit = dynamic_cast<TQWidget*>( paramWidget->child( "addressEdit" ) );
01535   Q_ASSERT( addressEdit );
01536   KMFilterActionWithAddress::applyParamWidgetValue( addressEdit );
01537 
01538   TQComboBox *templateCombo = dynamic_cast<TQComboBox*>( paramWidget->child( "templateCombo" ) );
01539   Q_ASSERT( templateCombo );
01540 
01541   if ( templateCombo->currentItem() == 0 ) {
01542     // Default template, so don't use a custom one
01543     mTemplate = TQString();
01544   }
01545   else {
01546     mTemplate = templateCombo->currentText();
01547   }
01548 }
01549 
01550 void KMFilterActionForward::setParamWidgetValue( TQWidget* paramWidget ) const
01551 {
01552   TQWidget *addressEdit = dynamic_cast<TQWidget*>( paramWidget->child( "addressEdit" ) );
01553   Q_ASSERT( addressEdit );
01554   KMFilterActionWithAddress::setParamWidgetValue( addressEdit );
01555 
01556   TQComboBox *templateCombo = dynamic_cast<TQComboBox*>( paramWidget->child( "templateCombo" ) );
01557   Q_ASSERT( templateCombo );
01558 
01559   if ( mTemplate.isEmpty() ) {
01560     templateCombo->setCurrentItem( 0 );
01561   }
01562   else {
01563     // WTF: TQt3's combobox has no indexOf? Search it manually, then.
01564     int templateIndex = -1;
01565     for ( int i = 1; i < templateCombo->count(); i++ ) {
01566       if ( templateCombo->text( i ) == mTemplate ) {
01567         templateIndex = i;
01568         break;
01569       }
01570     }
01571 
01572     if ( templateIndex != -1 ) {
01573       templateCombo->setCurrentItem( templateIndex );
01574     }
01575     else {
01576       mTemplate = TQString();
01577     }
01578   }
01579 }
01580 
01581 void KMFilterActionForward::clearParamWidget( TQWidget* paramWidget ) const
01582 {
01583   TQWidget *addressEdit = dynamic_cast<TQWidget*>( paramWidget->child( "addressEdit" ) );
01584   Q_ASSERT( addressEdit );
01585   KMFilterActionWithAddress::clearParamWidget( addressEdit );
01586 
01587   TQComboBox *templateCombo = dynamic_cast<TQComboBox*>( paramWidget->child( "templateCombo" ) );
01588   Q_ASSERT( templateCombo );
01589 
01590   templateCombo->setCurrentItem( 0 );
01591 }
01592 
01593 // We simply place a "@$$@" between the two parameters. The template is the last
01594 // parameter in the string, for compatibility reasons.
01595 static const TQString forwardFilterArgsSeperator = "@$$@";
01596 
01597 void KMFilterActionForward::argsFromString( const TQString argsStr )
01598 {
01599   int seperatorPos = argsStr.find( forwardFilterArgsSeperator );
01600 
01601   if ( seperatorPos == - 1 ) {
01602     // Old config, assume that the whole string is the addressee
01603     KMFilterActionWithAddress::argsFromString( argsStr );
01604   }
01605   else {
01606     TQString addressee = argsStr.left( seperatorPos );
01607     mTemplate = argsStr.mid( seperatorPos + forwardFilterArgsSeperator.length() );
01608     KMFilterActionWithAddress::argsFromString( addressee );
01609   }
01610 }
01611 
01612 const TQString KMFilterActionForward::argsAsString() const
01613 {
01614   return KMFilterActionWithAddress::argsAsString() + forwardFilterArgsSeperator + mTemplate;
01615 }
01616 
01617 const TQString KMFilterActionForward::displayString() const
01618 {
01619   if ( mTemplate.isEmpty() )
01620     return i18n( "Forward to %1 with default template " ).arg( mParameter );
01621   else
01622     return i18n( "Forward to %1 with template %2" ).arg( mParameter, mTemplate );
01623 }
01624 
01625 //=============================================================================
01626 // KMFilterActionRedirect - redirect to
01627 // Redirect message to another user
01628 //=============================================================================
01629 class KMFilterActionRedirect: public KMFilterActionWithAddress
01630 {
01631 public:
01632   KMFilterActionRedirect();
01633   virtual ReturnCode process(KMMessage* msg) const;
01634   static KMFilterAction* newAction(void);
01635 };
01636 
01637 KMFilterAction* KMFilterActionRedirect::newAction(void)
01638 {
01639   return (new KMFilterActionRedirect);
01640 }
01641 
01642 KMFilterActionRedirect::KMFilterActionRedirect()
01643   : KMFilterActionWithAddress( "redirect", i18n("Redirect To") )
01644 {
01645 }
01646 
01647 KMFilterAction::ReturnCode KMFilterActionRedirect::process(KMMessage* aMsg) const
01648 {
01649   KMMessage* msg;
01650   if ( mParameter.isEmpty() )
01651     return ErrorButGoOn;
01652 
01653   msg = aMsg->createRedirect( mParameter );
01654 
01655   sendMDN( aMsg, KMime::MDN::Dispatched );
01656 
01657   if ( !kmkernel->msgSender()->send( msg, KMail::MessageSender::SendLater ) ) {
01658     kdDebug(5006) << "KMFilterAction: could not redirect message (sending failed)" << endl;
01659     return ErrorButGoOn; // error: couldn't send
01660   }
01661   return GoOn;
01662 }
01663 
01664 
01665 //=============================================================================
01666 // KMFilterActionExec - execute command
01667 // Execute a shell command
01668 //=============================================================================
01669 class KMFilterActionExec : public KMFilterActionWithCommand
01670 {
01671 public:
01672   KMFilterActionExec();
01673   virtual ReturnCode process(KMMessage* msg) const;
01674   static KMFilterAction* newAction(void);
01675 };
01676 
01677 KMFilterAction* KMFilterActionExec::newAction(void)
01678 {
01679   return (new KMFilterActionExec());
01680 }
01681 
01682 KMFilterActionExec::KMFilterActionExec()
01683   : KMFilterActionWithCommand( "execute", i18n("Execute Command") )
01684 {
01685 }
01686 
01687 KMFilterAction::ReturnCode KMFilterActionExec::process(KMMessage *aMsg) const
01688 {
01689   return KMFilterActionWithCommand::genericProcess( aMsg, false ); // ignore output
01690 }
01691 
01692 //=============================================================================
01693 // KMFilterActionExtFilter - use external filter app
01694 // External message filter: executes a shell command with message
01695 // on stdin; altered message is expected on stdout.
01696 //=============================================================================
01697 
01698 #include <weaver.h>
01699 class PipeJob : public KPIM::ThreadWeaver::Job
01700 {
01701   public:
01702     PipeJob(TQObject* parent = 0 , const char* name = 0, KMMessage* aMsg = 0, TQString cmd = 0, TQString tempFileName = 0 )
01703       : Job (parent, name),
01704         mTempFileName(tempFileName),
01705         mCmd(cmd),
01706         mMsg( aMsg )
01707     {
01708     }
01709 
01710     ~PipeJob() {}
01711     virtual void processEvent( KPIM::ThreadWeaver::Event *ev )
01712     {
01713       KPIM::ThreadWeaver::Job::processEvent( ev );
01714       if ( ev->action() == KPIM::ThreadWeaver::Event::JobFinished )
01715         deleteLater( );
01716     }
01717   protected:
01718     void run()
01719     {
01720       KPIM::ThreadWeaver::debug (1, "PipeJob::run: doing it .\n");
01721       FILE *p;
01722       TQByteArray ba;
01723 
01724       // backup the serial number in case the header gets lost
01725       TQString origSerNum = mMsg->headerField( "X-KMail-Filtered" );
01726 
01727       p = popen(TQFile::encodeName(mCmd), "r");
01728       int len =100;
01729       char buffer[100];
01730       // append data to ba:
01731       while (true)  {
01732         if (! fgets( buffer, len, p ) ) break;
01733         int oldsize = ba.size();
01734         ba.resize( oldsize + strlen(buffer) );
01735         tqmemmove( ba.begin() + oldsize, buffer, strlen(buffer) );
01736       }
01737       pclose(p);
01738       if ( !ba.isEmpty() ) {
01739         KPIM::ThreadWeaver::debug (1, "PipeJob::run: %s", TQString(ba).latin1() );
01740         KMFolder *filterFolder =  mMsg->parent();
01741         ActionScheduler *handler = MessageProperty::filterHandler( mMsg->getMsgSerNum() );
01742 
01743         mMsg->fromByteArray( ba );
01744         if ( !origSerNum.isEmpty() )
01745           mMsg->setHeaderField( "X-KMail-Filtered", origSerNum );
01746         if ( filterFolder && handler ) {
01747           bool oldStatus = handler->ignoreChanges( true );
01748           filterFolder->take( filterFolder->find( mMsg ) );
01749           filterFolder->addMsg( mMsg );
01750           handler->ignoreChanges( oldStatus );
01751         } else {
01752           kdDebug(5006) << "Warning: Cannot refresh the message from the external filter." << endl;
01753         }
01754       }
01755 
01756       KPIM::ThreadWeaver::debug (1, "PipeJob::run: done.\n" );
01757       // unlink the tempFile
01758       TQFile::remove(mTempFileName);
01759     }
01760     TQString mTempFileName;
01761     TQString mCmd;
01762     KMMessage *mMsg;
01763 };
01764 
01765 class KMFilterActionExtFilter: public KMFilterActionWithCommand
01766 {
01767 public:
01768   KMFilterActionExtFilter();
01769   virtual ReturnCode process(KMMessage* msg) const;
01770   virtual void processAsync(KMMessage* msg) const;
01771   static KMFilterAction* newAction(void);
01772 };
01773 
01774 KMFilterAction* KMFilterActionExtFilter::newAction(void)
01775 {
01776   return (new KMFilterActionExtFilter);
01777 }
01778 
01779 KMFilterActionExtFilter::KMFilterActionExtFilter()
01780   : KMFilterActionWithCommand( "filter app", i18n("Pipe Through") )
01781 {
01782 }
01783 KMFilterAction::ReturnCode KMFilterActionExtFilter::process(KMMessage* aMsg) const
01784 {
01785   return KMFilterActionWithCommand::genericProcess( aMsg, true ); // use output
01786 }
01787 
01788 void KMFilterActionExtFilter::processAsync(KMMessage* aMsg) const
01789 {
01790 
01791   ActionScheduler *handler = MessageProperty::filterHandler( aMsg->getMsgSerNum() );
01792   KTempFile * inFile = new KTempFile;
01793   inFile->setAutoDelete(false);
01794 
01795   TQPtrList<KTempFile> atmList;
01796   atmList.setAutoDelete(true);
01797   atmList.append( inFile );
01798 
01799   TQString commandLine = substituteCommandLineArgsFor( aMsg , atmList );
01800   if ( commandLine.isEmpty() )
01801     handler->actionMessage( ErrorButGoOn );
01802 
01803   // The parentheses force the creation of a subshell
01804   // in which the user-specified command is executed.
01805   // This is to really catch all output of the command as well
01806   // as to avoid clashes of our redirection with the ones
01807   // the user may have specified. In the long run, we
01808   // shouldn't be using tempfiles at all for this class, due
01809   // to security aspects. (mmutz)
01810   commandLine =  "(" + commandLine + ") <" + inFile->name();
01811 
01812   // write message to file
01813   TQString tempFileName = inFile->name();
01814   KPIM::kCStringToFile( aMsg->asString(), tempFileName, //###
01815       false, false, false );
01816   inFile->close();
01817 
01818   PipeJob *job = new PipeJob(0, 0, aMsg, commandLine, tempFileName);
01819   TQObject::connect ( job, TQT_SIGNAL( done() ), handler, TQT_SLOT( actionMessage() ) );
01820   kmkernel->weaver()->enqueue(job);
01821 }
01822 
01823 //=============================================================================
01824 // KMFilterActionExecSound - execute command
01825 // Execute a sound
01826 //=============================================================================
01827 class KMFilterActionExecSound : public KMFilterActionWithTest
01828 {
01829 public:
01830   KMFilterActionExecSound();
01831   virtual ReturnCode process(KMMessage* msg) const;
01832   virtual bool requiresBody(KMMsgBase*) const;
01833   static KMFilterAction* newAction(void);
01834 };
01835 
01836 KMFilterActionWithTest::KMFilterActionWithTest( const char* aName, const TQString aLabel )
01837   : KMFilterAction( aName, aLabel )
01838 {
01839 }
01840 
01841 KMFilterActionWithTest::~KMFilterActionWithTest()
01842 {
01843 }
01844 
01845 TQWidget* KMFilterActionWithTest::createParamWidget( TQWidget* parent ) const
01846 {
01847   KMSoundTestWidget *le = new KMSoundTestWidget(parent);
01848   le->setUrl( mParameter );
01849   return le;
01850 }
01851 
01852 
01853 void KMFilterActionWithTest::applyParamWidgetValue( TQWidget* paramWidget )
01854 {
01855   mParameter = ((KMSoundTestWidget*)paramWidget)->url();
01856 }
01857 
01858 void KMFilterActionWithTest::setParamWidgetValue( TQWidget* paramWidget ) const
01859 {
01860   ((KMSoundTestWidget*)paramWidget)->setUrl( mParameter );
01861 }
01862 
01863 void KMFilterActionWithTest::clearParamWidget( TQWidget* paramWidget ) const
01864 {
01865   ((KMSoundTestWidget*)paramWidget)->clear();
01866 }
01867 
01868 void KMFilterActionWithTest::argsFromString( const TQString argsStr )
01869 {
01870   mParameter = argsStr;
01871 }
01872 
01873 const TQString KMFilterActionWithTest::argsAsString() const
01874 {
01875   return mParameter;
01876 }
01877 
01878 const TQString KMFilterActionWithTest::displayString() const
01879 {
01880   // FIXME after string freeze:
01881   // return i18n("").arg( );
01882   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
01883 }
01884 
01885 
01886 KMFilterActionExecSound::KMFilterActionExecSound()
01887   : KMFilterActionWithTest( "play sound", i18n("Play Sound") )
01888 {
01889 }
01890 
01891 KMFilterAction* KMFilterActionExecSound::newAction(void)
01892 {
01893   return (new KMFilterActionExecSound());
01894 }
01895 
01896 KMFilterAction::ReturnCode KMFilterActionExecSound::process(KMMessage*) const
01897 {
01898   if ( mParameter.isEmpty() )
01899     return ErrorButGoOn;
01900   TQString play = mParameter;
01901   TQString file = TQString::fromLatin1("file:");
01902   if (mParameter.startsWith(file))
01903     play = mParameter.mid(file.length());
01904   KAudioPlayer::play(TQFile::encodeName(play));
01905   return GoOn;
01906 }
01907 
01908 bool KMFilterActionExecSound::requiresBody(KMMsgBase*) const
01909 {
01910   return false;
01911 }
01912 
01913 KMFilterActionWithUrl::KMFilterActionWithUrl( const char* aName, const TQString aLabel )
01914   : KMFilterAction( aName, aLabel )
01915 {
01916 }
01917 
01918 KMFilterActionWithUrl::~KMFilterActionWithUrl()
01919 {
01920 }
01921 
01922 TQWidget* KMFilterActionWithUrl::createParamWidget( TQWidget* parent ) const
01923 {
01924   KURLRequester *le = new KURLRequester(parent);
01925   le->setURL( mParameter );
01926   return le;
01927 }
01928 
01929 
01930 void KMFilterActionWithUrl::applyParamWidgetValue( TQWidget* paramWidget )
01931 {
01932   mParameter = ((KURLRequester*)paramWidget)->url();
01933 }
01934 
01935 void KMFilterActionWithUrl::setParamWidgetValue( TQWidget* paramWidget ) const
01936 {
01937   ((KURLRequester*)paramWidget)->setURL( mParameter );
01938 }
01939 
01940 void KMFilterActionWithUrl::clearParamWidget( TQWidget* paramWidget ) const
01941 {
01942   ((KURLRequester*)paramWidget)->clear();
01943 }
01944 
01945 void KMFilterActionWithUrl::argsFromString( const TQString argsStr )
01946 {
01947   mParameter = argsStr;
01948 }
01949 
01950 const TQString KMFilterActionWithUrl::argsAsString() const
01951 {
01952   return mParameter;
01953 }
01954 
01955 const TQString KMFilterActionWithUrl::displayString() const
01956 {
01957   // FIXME after string freeze:
01958   // return i18n("").arg( );
01959   return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
01960 }
01961 
01962 
01963 //=============================================================================
01964 //
01965 //   Filter  Action  Dictionary
01966 //
01967 //=============================================================================
01968 void KMFilterActionDict::init(void)
01969 {
01970   insert( KMFilterActionMove::newAction );
01971   insert( KMFilterActionCopy::newAction );
01972   insert( KMFilterActionIdentity::newAction );
01973   insert( KMFilterActionSeStatus::newAction );
01974   insert( KMFilterActionFakeDisposition::newAction );
01975   insert( KMFilterActionTransport::newAction );
01976   insert( KMFilterActionReplyTo::newAction );
01977   insert( KMFilterActionForward::newAction );
01978   insert( KMFilterActionRedirect::newAction );
01979   insert( KMFilterActionSendReceipt::newAction );
01980   insert( KMFilterActionExec::newAction );
01981   insert( KMFilterActionExtFilter::newAction );
01982   insert( KMFilterActionRemoveHeader::newAction );
01983   insert( KMFilterActionAddHeader::newAction );
01984   insert( KMFilterActionRewriteHeader::newAction );
01985   insert( KMFilterActionExecSound::newAction );
01986   // Register custom filter actions below this line.
01987 }
01988 // The int in the TQDict constructor (41) must be a prime
01989 // and should be greater than the double number of KMFilterAction types
01990 KMFilterActionDict::KMFilterActionDict()
01991   : TQDict<KMFilterActionDesc>(41)
01992 {
01993   mList.setAutoDelete(true);
01994   init();
01995 }
01996 
01997 void KMFilterActionDict::insert( KMFilterActionNewFunc aNewFunc )
01998 {
01999   KMFilterAction *action = aNewFunc();
02000   KMFilterActionDesc* desc = new KMFilterActionDesc;
02001   desc->name = action->name();
02002   desc->label = action->label();
02003   desc->create = aNewFunc;
02004   TQDict<KMFilterActionDesc>::insert( desc->name, desc );
02005   TQDict<KMFilterActionDesc>::insert( desc->label, desc );
02006   mList.append( desc );
02007   delete action;
02008 }