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