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 )
01400 return ErrorButGoOn;
01401 if ( mFolder && mFolder->open( "filtercopy" ) != 0 )
01402 return ErrorButGoOn;
01403
01404
01405 KMMessage* msgCopy = new KMMessage( new DwMessage( *msg->asDwMessage() ) );
01406
01407 int index;
01408 int rc = mFolder->addMsg(msgCopy, &index);
01409 if (rc == 0 && index != -1)
01410 mFolder->unGetMsg( index );
01411 mFolder->close("filtercopy");
01412
01413 return GoOn;
01414 }
01415
01416 void KMFilterActionCopy::processAsync(KMMessage* msg) const
01417 {
01418
01419 kdDebug(5006) << "##### KMFilterActionCopy::processAsync(KMMessage* msg)" << endl;
01420 ActionScheduler *handler = MessageProperty::filterHandler( msg );
01421
01422 KMCommand *cmd = new KMCopyCommand( mFolder, msg );
01423 QObject::connect( cmd, SIGNAL( completed( KMCommand * ) ),
01424 handler, SLOT( copyMessageFinished( KMCommand * ) ) );
01425 cmd->start();
01426 }
01427
01428 bool KMFilterActionCopy::requiresBody(KMMsgBase*) const
01429 {
01430 return true;
01431 }
01432
01433
01434
01435
01436
01437
01438 class KMFilterActionForward: public KMFilterActionWithAddress
01439 {
01440 public:
01441 KMFilterActionForward();
01442 virtual ReturnCode process(KMMessage* msg) const;
01443 static KMFilterAction* newAction(void);
01444 };
01445
01446 KMFilterAction* KMFilterActionForward::newAction(void)
01447 {
01448 return (new KMFilterActionForward);
01449 }
01450
01451 KMFilterActionForward::KMFilterActionForward()
01452 : KMFilterActionWithAddress( "forward", i18n("Forward To") )
01453 {
01454 }
01455
01456 KMFilterAction::ReturnCode KMFilterActionForward::process(KMMessage* aMsg) const
01457 {
01458 if ( mParameter.isEmpty() )
01459 return ErrorButGoOn;
01460
01461
01462
01463 if ( KMMessage::addressIsInAddressList( mParameter, aMsg->to() ) )
01464 return ErrorButGoOn;
01465
01466
01467
01468
01469
01470
01471
01472 KMMessage* msg = new KMMessage;
01473
01474 msg->initFromMessage( aMsg );
01475
01476
01477
01478 TemplateParser parser( msg, TemplateParser::Forward,
01479 aMsg->body(), false, false, false, false);
01480 parser.process( aMsg );
01481
01482 QCString
01483 encoding = KMMsgBase::autoDetectCharset( aMsg->charset(),
01484 KMMessage::preferredCharsets(),
01485 msg->body() );
01486 if( encoding.isEmpty() )
01487 encoding = "utf-8";
01488 QCString str = KMMsgBase::codecForName( encoding )->fromUnicode( msg->body() );
01489
01490 msg->setCharset( encoding );
01491 msg->setTo( mParameter );
01492 msg->setSubject( "Fwd: " + aMsg->subject() );
01493
01494 bool isQP = kmkernel->msgSender()->sendQuotedPrintable();
01495
01496 if( aMsg->numBodyParts() == 0 )
01497 {
01498 msg->setAutomaticFields( true );
01499 msg->setHeaderField( "Content-Type", "text/plain" );
01500
01501 QValueList<int> dummy;
01502 msg->setBodyAndGuessCte(str, dummy, !isQP);
01503 msg->setCharset( encoding );
01504 if( isQP )
01505 msg->setBodyEncoded( str );
01506 else
01507 msg->setBody( str );
01508 }
01509 else
01510 {
01511 KMMessagePart bodyPart, msgPart;
01512
01513 msg->removeHeaderField( "Content-Type" );
01514 msg->removeHeaderField( "Content-Transfer-Encoding" );
01515 msg->setAutomaticFields( true );
01516 msg->setBody( "This message is in MIME format.\n\n" );
01517
01518 bodyPart.setTypeStr( "text" );
01519 bodyPart.setSubtypeStr( "plain" );
01520
01521 QValueList<int> dummy;
01522 bodyPart.setBodyAndGuessCte(str, dummy, !isQP);
01523 bodyPart.setCharset( encoding );
01524 bodyPart.setBodyEncoded( str );
01525 msg->addBodyPart( &bodyPart );
01526
01527 for( int i = 0; i < aMsg->numBodyParts(); i++ )
01528 {
01529 aMsg->bodyPart( i, &msgPart );
01530 if( i > 0 || qstricmp( msgPart.typeStr(), "text" ) != 0 )
01531 msg->addBodyPart( &msgPart );
01532 }
01533 }
01534 msg->cleanupHeader();
01535 msg->link( aMsg, KMMsgStatusForwarded );
01536
01537 sendMDN( aMsg, KMime::MDN::Dispatched );
01538
01539 if ( !kmkernel->msgSender()->send( msg, KMail::MessageSender::SendLater ) ) {
01540 kdDebug(5006) << "KMFilterAction: could not forward message (sending failed)" << endl;
01541 return ErrorButGoOn;
01542 }
01543 return GoOn;
01544 }
01545
01546
01547
01548
01549
01550
01551 class KMFilterActionRedirect: public KMFilterActionWithAddress
01552 {
01553 public:
01554 KMFilterActionRedirect();
01555 virtual ReturnCode process(KMMessage* msg) const;
01556 static KMFilterAction* newAction(void);
01557 };
01558
01559 KMFilterAction* KMFilterActionRedirect::newAction(void)
01560 {
01561 return (new KMFilterActionRedirect);
01562 }
01563
01564 KMFilterActionRedirect::KMFilterActionRedirect()
01565 : KMFilterActionWithAddress( "redirect", i18n("Redirect To") )
01566 {
01567 }
01568
01569 KMFilterAction::ReturnCode KMFilterActionRedirect::process(KMMessage* aMsg) const
01570 {
01571 KMMessage* msg;
01572 if ( mParameter.isEmpty() )
01573 return ErrorButGoOn;
01574
01575 msg = aMsg->createRedirect( mParameter );
01576
01577 sendMDN( aMsg, KMime::MDN::Dispatched );
01578
01579 if ( !kmkernel->msgSender()->send( msg, KMail::MessageSender::SendLater ) ) {
01580 kdDebug(5006) << "KMFilterAction: could not redirect message (sending failed)" << endl;
01581 return ErrorButGoOn;
01582 }
01583 return GoOn;
01584 }
01585
01586
01587
01588
01589
01590
01591 class KMFilterActionExec : public KMFilterActionWithCommand
01592 {
01593 public:
01594 KMFilterActionExec();
01595 virtual ReturnCode process(KMMessage* msg) const;
01596 static KMFilterAction* newAction(void);
01597 };
01598
01599 KMFilterAction* KMFilterActionExec::newAction(void)
01600 {
01601 return (new KMFilterActionExec());
01602 }
01603
01604 KMFilterActionExec::KMFilterActionExec()
01605 : KMFilterActionWithCommand( "execute", i18n("Execute Command") )
01606 {
01607 }
01608
01609 KMFilterAction::ReturnCode KMFilterActionExec::process(KMMessage *aMsg) const
01610 {
01611 return KMFilterActionWithCommand::genericProcess( aMsg, false );
01612 }
01613
01614
01615
01616
01617
01618
01619
01620 #include <weaver.h>
01621 class PipeJob : public KPIM::ThreadWeaver::Job
01622 {
01623 public:
01624 PipeJob(QObject* parent = 0 , const char* name = 0, KMMessage* aMsg = 0, QString cmd = 0, QString tempFileName = 0 )
01625 : Job (parent, name),
01626 mTempFileName(tempFileName),
01627 mCmd(cmd),
01628 mMsg( aMsg )
01629 {
01630 }
01631
01632 ~PipeJob() {}
01633 virtual void processEvent( KPIM::ThreadWeaver::Event *ev )
01634 {
01635 KPIM::ThreadWeaver::Job::processEvent( ev );
01636 if ( ev->action() == KPIM::ThreadWeaver::Event::JobFinished )
01637 deleteLater( );
01638 }
01639 protected:
01640 void run()
01641 {
01642 KPIM::ThreadWeaver::debug (1, "PipeJob::run: doing it .\n");
01643 FILE *p;
01644 QByteArray ba;
01645
01646
01647 QString origSerNum = mMsg->headerField( "X-KMail-Filtered" );
01648
01649 p = popen(QFile::encodeName(mCmd), "r");
01650 int len =100;
01651 char buffer[100];
01652
01653 while (true) {
01654 if (! fgets( buffer, len, p ) ) break;
01655 int oldsize = ba.size();
01656 ba.resize( oldsize + strlen(buffer) );
01657 qmemmove( ba.begin() + oldsize, buffer, strlen(buffer) );
01658 }
01659 pclose(p);
01660 if ( !ba.isEmpty() ) {
01661 KPIM::ThreadWeaver::debug (1, "PipeJob::run: %s", QString(ba).latin1() );
01662 KMFolder *filterFolder = mMsg->parent();
01663 ActionScheduler *handler = MessageProperty::filterHandler( mMsg->getMsgSerNum() );
01664
01665 mMsg->fromByteArray( ba );
01666 if ( !origSerNum.isEmpty() )
01667 mMsg->setHeaderField( "X-KMail-Filtered", origSerNum );
01668 if ( filterFolder && handler ) {
01669 bool oldStatus = handler->ignoreChanges( true );
01670 filterFolder->take( filterFolder->find( mMsg ) );
01671 filterFolder->addMsg( mMsg );
01672 handler->ignoreChanges( oldStatus );
01673 } else {
01674 kdDebug(5006) << "Warning: Cannot refresh the message from the external filter." << endl;
01675 }
01676 }
01677
01678 KPIM::ThreadWeaver::debug (1, "PipeJob::run: done.\n" );
01679
01680 QFile::remove(mTempFileName);
01681 }
01682 QString mTempFileName;
01683 QString mCmd;
01684 KMMessage *mMsg;
01685 };
01686
01687 class KMFilterActionExtFilter: public KMFilterActionWithCommand
01688 {
01689 public:
01690 KMFilterActionExtFilter();
01691 virtual ReturnCode process(KMMessage* msg) const;
01692 virtual void processAsync(KMMessage* msg) const;
01693 static KMFilterAction* newAction(void);
01694 };
01695
01696 KMFilterAction* KMFilterActionExtFilter::newAction(void)
01697 {
01698 return (new KMFilterActionExtFilter);
01699 }
01700
01701 KMFilterActionExtFilter::KMFilterActionExtFilter()
01702 : KMFilterActionWithCommand( "filter app", i18n("Pipe Through") )
01703 {
01704 }
01705 KMFilterAction::ReturnCode KMFilterActionExtFilter::process(KMMessage* aMsg) const
01706 {
01707 return KMFilterActionWithCommand::genericProcess( aMsg, true );
01708 }
01709
01710 void KMFilterActionExtFilter::processAsync(KMMessage* aMsg) const
01711 {
01712
01713 ActionScheduler *handler = MessageProperty::filterHandler( aMsg->getMsgSerNum() );
01714 KTempFile * inFile = new KTempFile;
01715 inFile->setAutoDelete(false);
01716
01717 QPtrList<KTempFile> atmList;
01718 atmList.setAutoDelete(true);
01719 atmList.append( inFile );
01720
01721 QString commandLine = substituteCommandLineArgsFor( aMsg , atmList );
01722 if ( commandLine.isEmpty() )
01723 handler->actionMessage( ErrorButGoOn );
01724
01725
01726
01727
01728
01729
01730
01731
01732 commandLine = "(" + commandLine + ") <" + inFile->name();
01733
01734
01735 QString tempFileName = inFile->name();
01736 KPIM::kCStringToFile( aMsg->asString(), tempFileName,
01737 false, false, false );
01738 inFile->close();
01739
01740 PipeJob *job = new PipeJob(0, 0, aMsg, commandLine, tempFileName);
01741 QObject::connect ( job, SIGNAL( done() ), handler, SLOT( actionMessage() ) );
01742 kmkernel->weaver()->enqueue(job);
01743 }
01744
01745
01746
01747
01748
01749 class KMFilterActionExecSound : public KMFilterActionWithTest
01750 {
01751 public:
01752 KMFilterActionExecSound();
01753 virtual ReturnCode process(KMMessage* msg) const;
01754 virtual bool requiresBody(KMMsgBase*) const;
01755 static KMFilterAction* newAction(void);
01756 };
01757
01758 KMFilterActionWithTest::KMFilterActionWithTest( const char* aName, const QString aLabel )
01759 : KMFilterAction( aName, aLabel )
01760 {
01761 }
01762
01763 KMFilterActionWithTest::~KMFilterActionWithTest()
01764 {
01765 }
01766
01767 QWidget* KMFilterActionWithTest::createParamWidget( QWidget* parent ) const
01768 {
01769 KMSoundTestWidget *le = new KMSoundTestWidget(parent);
01770 le->setUrl( mParameter );
01771 return le;
01772 }
01773
01774
01775 void KMFilterActionWithTest::applyParamWidgetValue( QWidget* paramWidget )
01776 {
01777 mParameter = ((KMSoundTestWidget*)paramWidget)->url();
01778 }
01779
01780 void KMFilterActionWithTest::setParamWidgetValue( QWidget* paramWidget ) const
01781 {
01782 ((KMSoundTestWidget*)paramWidget)->setUrl( mParameter );
01783 }
01784
01785 void KMFilterActionWithTest::clearParamWidget( QWidget* paramWidget ) const
01786 {
01787 ((KMSoundTestWidget*)paramWidget)->clear();
01788 }
01789
01790 void KMFilterActionWithTest::argsFromString( const QString argsStr )
01791 {
01792 mParameter = argsStr;
01793 }
01794
01795 const QString KMFilterActionWithTest::argsAsString() const
01796 {
01797 return mParameter;
01798 }
01799
01800 const QString KMFilterActionWithTest::displayString() const
01801 {
01802
01803
01804 return label() + " \"" + QStyleSheet::escape( argsAsString() ) + "\"";
01805 }
01806
01807
01808 KMFilterActionExecSound::KMFilterActionExecSound()
01809 : KMFilterActionWithTest( "play sound", i18n("Play Sound") )
01810 {
01811 }
01812
01813 KMFilterAction* KMFilterActionExecSound::newAction(void)
01814 {
01815 return (new KMFilterActionExecSound());
01816 }
01817
01818 KMFilterAction::ReturnCode KMFilterActionExecSound::process(KMMessage*) const
01819 {
01820 if ( mParameter.isEmpty() )
01821 return ErrorButGoOn;
01822 QString play = mParameter;
01823 QString file = QString::fromLatin1("file:");
01824 if (mParameter.startsWith(file))
01825 play = mParameter.mid(file.length());
01826 KAudioPlayer::play(QFile::encodeName(play));
01827 return GoOn;
01828 }
01829
01830 bool KMFilterActionExecSound::requiresBody(KMMsgBase*) const
01831 {
01832 return false;
01833 }
01834
01835 KMFilterActionWithUrl::KMFilterActionWithUrl( const char* aName, const QString aLabel )
01836 : KMFilterAction( aName, aLabel )
01837 {
01838 }
01839
01840 KMFilterActionWithUrl::~KMFilterActionWithUrl()
01841 {
01842 }
01843
01844 QWidget* KMFilterActionWithUrl::createParamWidget( QWidget* parent ) const
01845 {
01846 KURLRequester *le = new KURLRequester(parent);
01847 le->setURL( mParameter );
01848 return le;
01849 }
01850
01851
01852 void KMFilterActionWithUrl::applyParamWidgetValue( QWidget* paramWidget )
01853 {
01854 mParameter = ((KURLRequester*)paramWidget)->url();
01855 }
01856
01857 void KMFilterActionWithUrl::setParamWidgetValue( QWidget* paramWidget ) const
01858 {
01859 ((KURLRequester*)paramWidget)->setURL( mParameter );
01860 }
01861
01862 void KMFilterActionWithUrl::clearParamWidget( QWidget* paramWidget ) const
01863 {
01864 ((KURLRequester*)paramWidget)->clear();
01865 }
01866
01867 void KMFilterActionWithUrl::argsFromString( const QString argsStr )
01868 {
01869 mParameter = argsStr;
01870 }
01871
01872 const QString KMFilterActionWithUrl::argsAsString() const
01873 {
01874 return mParameter;
01875 }
01876
01877 const QString KMFilterActionWithUrl::displayString() const
01878 {
01879
01880
01881 return label() + " \"" + QStyleSheet::escape( argsAsString() ) + "\"";
01882 }
01883
01884
01885
01886
01887
01888
01889
01890 void KMFilterActionDict::init(void)
01891 {
01892 insert( KMFilterActionMove::newAction );
01893 insert( KMFilterActionCopy::newAction );
01894 insert( KMFilterActionIdentity::newAction );
01895 insert( KMFilterActionSetStatus::newAction );
01896 insert( KMFilterActionFakeDisposition::newAction );
01897 insert( KMFilterActionTransport::newAction );
01898 insert( KMFilterActionReplyTo::newAction );
01899 insert( KMFilterActionForward::newAction );
01900 insert( KMFilterActionRedirect::newAction );
01901 insert( KMFilterActionSendReceipt::newAction );
01902 insert( KMFilterActionExec::newAction );
01903 insert( KMFilterActionExtFilter::newAction );
01904 insert( KMFilterActionRemoveHeader::newAction );
01905 insert( KMFilterActionAddHeader::newAction );
01906 insert( KMFilterActionRewriteHeader::newAction );
01907 insert( KMFilterActionExecSound::newAction );
01908
01909 }
01910
01911
01912 KMFilterActionDict::KMFilterActionDict()
01913 : QDict<KMFilterActionDesc>(41)
01914 {
01915 mList.setAutoDelete(true);
01916 init();
01917 }
01918
01919 void KMFilterActionDict::insert( KMFilterActionNewFunc aNewFunc )
01920 {
01921 KMFilterAction *action = aNewFunc();
01922 KMFilterActionDesc* desc = new KMFilterActionDesc;
01923 desc->name = action->name();
01924 desc->label = action->label();
01925 desc->create = aNewFunc;
01926 QDict<KMFilterActionDesc>::insert( desc->name, desc );
01927 QDict<KMFilterActionDesc>::insert( desc->label, desc );
01928 mList.append( desc );
01929 delete action;
01930 }