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