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