kmail

kmfilteraction.cpp
1 // kmfilteraction.cpp
2 // The process methods really should use an enum instead of an int
3 // -1 -> status unchanged, 0 -> success, 1 -> failure, 2-> critical failure
4 // (GoOn), (Ok), (ErrorButGoOn), (CriticalError)
5 
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 
10 #include "kmfilteraction.h"
11 
12 #include "customtemplates.h"
13 #include "customtemplates_kfg.h"
14 #include "kmcommands.h"
15 #include "kmmsgpart.h"
16 #include "kmfiltermgr.h"
17 #include "kmfolderindex.h"
18 #include "kmfoldermgr.h"
19 #include "messagesender.h"
20 #include "kmmainwidget.h"
21 #include <libkpimidentities/identity.h>
22 #include <libkpimidentities/identitymanager.h>
23 #include <libkpimidentities/identitycombo.h>
24 #include <libtdepim/tdefileio.h>
25 #include <libtdepim/collectingprocess.h>
26 using KPIM::CollectingProcess;
27 #include <mimelib/message.h>
28 #include "kmfawidgets.h"
29 #include "folderrequester.h"
31 #include "kmmsgbase.h"
32 #include "messageproperty.h"
33 #include "actionscheduler.h"
34 using KMail::MessageProperty;
35 using KMail::ActionScheduler;
36 #include "regexplineedit.h"
37 using KMail::RegExpLineEdit;
38 #include <kregexp3.h>
39 #include <tdetempfile.h>
40 #include <kdebug.h>
41 #include <tdelocale.h>
42 #include <tdeprocess.h>
43 #include <kaudioplayer.h>
44 #include <kurlrequester.h>
45 
46 #include <tqlabel.h>
47 #include <tqlayout.h>
48 #include <tqtextcodec.h>
49 #include <tqtimer.h>
50 #include <tqobject.h>
51 #include <tqstylesheet.h>
52 #include <tqtooltip.h>
53 #include <tqwhatsthis.h>
54 #include <assert.h>
55 
56 
57 //=============================================================================
58 //
59 // KMFilterAction
60 //
61 //=============================================================================
62 
63 KMFilterAction::KMFilterAction( const char* aName, const TQString aLabel )
64 {
65  mName = aName;
66  mLabel = aLabel;
67 }
68 
69 KMFilterAction::~KMFilterAction()
70 {
71 }
72 
74 {
75  ActionScheduler *handler = MessageProperty::filterHandler( msg );
76  ReturnCode result = process( msg );
77  if (handler)
78  handler->actionMessage( result );
79 }
80 
81 bool KMFilterAction::requiresBody(KMMsgBase*) const
82 {
83  return true;
84 }
85 
87 {
88  return 0;
89 }
90 
91 TQWidget* KMFilterAction::createParamWidget(TQWidget* parent) const
92 {
93  return new TQWidget(parent);
94 }
95 
97 {
98 }
99 
100 void KMFilterAction::setParamWidgetValue( TQWidget * ) const
101 {
102 }
103 
104 void KMFilterAction::clearParamWidget( TQWidget * ) const
105 {
106 }
107 
109 {
110  return false;
111 }
112 
114 {
115  return kmkernel->filterMgr()->tempOpenFolder(aFolder);
116 }
117 
118 void KMFilterAction::sendMDN( KMMessage * msg, KMime::MDN::DispositionType d,
119  const TQValueList<KMime::MDN::DispositionModifier> & m ) {
120  if ( !msg ) return;
121 
122  /* createMDN requires Return-Path and Disposition-Notification-To
123  * if it is not set in the message we assume that the notification should go to the
124  * sender
125  */
126  const TQString returnPath = msg->headerField( "Return-Path" );
127  const TQString dispNoteTo = msg->headerField( "Disposition-Notification-To" );
128  if ( returnPath.isEmpty() )
129  msg->setHeaderField( "Return-Path", msg->from() );
130  if ( dispNoteTo.isEmpty() )
131  msg->setHeaderField( "Disposition-Notification-To", msg->from() );
132 
133  KMMessage * mdn = msg->createMDN( KMime::MDN::AutomaticAction, d, false, m );
134  if ( mdn && !kmkernel->msgSender()->send( mdn, KMail::MessageSender::SendLater ) ) {
135  kdDebug(5006) << "KMFilterAction::sendMDN(): sending failed." << endl;
136  //delete mdn;
137  }
138 
139  //restore orignial header
140  if ( returnPath.isEmpty() )
141  msg->removeHeaderField( "Return-Path" );
142  if ( dispNoteTo.isEmpty() )
143  msg->removeHeaderField( "Disposition-Notification-To" );
144 }
145 
146 
147 //=============================================================================
148 //
149 // KMFilterActionWithNone
150 //
151 //=============================================================================
152 
153 KMFilterActionWithNone::KMFilterActionWithNone( const char* aName, const TQString aLabel )
154  : KMFilterAction( aName, aLabel )
155 {
156 }
157 
159 {
160  return label();
161 }
162 
163 
164 //=============================================================================
165 //
166 // KMFilterActionWithUOID
167 //
168 //=============================================================================
169 
170 KMFilterActionWithUOID::KMFilterActionWithUOID( const char* aName, const TQString aLabel )
171  : KMFilterAction( aName, aLabel ), mParameter( 0 )
172 {
173 }
174 
175 void KMFilterActionWithUOID::argsFromString( const TQString argsStr )
176 {
177  mParameter = argsStr.stripWhiteSpace().toUInt();
178 }
179 
181 {
182  return TQString::number( mParameter );
183 }
184 
186 {
187  // FIXME after string freeze:
188  // return i18n("").arg( );
189  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
190 }
191 
192 
193 //=============================================================================
194 //
195 // KMFilterActionWithString
196 //
197 //=============================================================================
198 
199 KMFilterActionWithString::KMFilterActionWithString( const char* aName, const TQString aLabel )
200  : KMFilterAction( aName, aLabel )
201 {
202 }
203 
204 TQWidget* KMFilterActionWithString::createParamWidget( TQWidget* parent ) const
205 {
206  TQLineEdit *le = new KLineEdit(parent);
207  le->setText( mParameter );
208  return le;
209 }
210 
212 {
213  mParameter = ((TQLineEdit*)paramWidget)->text();
214 }
215 
216 void KMFilterActionWithString::setParamWidgetValue( TQWidget* paramWidget ) const
217 {
218  ((TQLineEdit*)paramWidget)->setText( mParameter );
219 }
220 
221 void KMFilterActionWithString::clearParamWidget( TQWidget* paramWidget ) const
222 {
223  ((TQLineEdit*)paramWidget)->clear();
224 }
225 
226 void KMFilterActionWithString::argsFromString( const TQString argsStr )
227 {
228  mParameter = argsStr;
229 }
230 
232 {
233  return mParameter;
234 }
235 
237 {
238  // FIXME after string freeze:
239  // return i18n("").arg( );
240  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
241 }
242 
243 //=============================================================================
244 //
245 // class KMFilterActionWithStringList
246 //
247 //=============================================================================
248 
249 KMFilterActionWithStringList::KMFilterActionWithStringList( const char* aName, const TQString aLabel )
250  : KMFilterActionWithString( aName, aLabel )
251 {
252 }
253 
254 TQWidget* KMFilterActionWithStringList::createParamWidget( TQWidget* parent ) const
255 {
256  TQComboBox *cb = new TQComboBox( false, parent );
257  cb->insertStringList( mParameterList );
258  setParamWidgetValue( cb );
259  return cb;
260 }
261 
263 {
264  mParameter = ((TQComboBox*)paramWidget)->currentText();
265 }
266 
267 void KMFilterActionWithStringList::setParamWidgetValue( TQWidget* paramWidget ) const
268 {
269  int idx = mParameterList.findIndex( mParameter );
270  ((TQComboBox*)paramWidget)->setCurrentItem( idx >= 0 ? idx : 0 );
271 }
272 
273 void KMFilterActionWithStringList::clearParamWidget( TQWidget* paramWidget ) const
274 {
275  ((TQComboBox*)paramWidget)->setCurrentItem(0);
276 }
277 
278 void KMFilterActionWithStringList::argsFromString( const TQString argsStr )
279 {
280  int idx = mParameterList.findIndex( argsStr );
281  if ( idx < 0 ) {
282  mParameterList.append( argsStr );
283  idx = mParameterList.count() - 1;
284  }
285  mParameter = *mParameterList.at( idx );
286 }
287 
288 
289 //=============================================================================
290 //
291 // class KMFilterActionWithFolder
292 //
293 //=============================================================================
294 
295 KMFilterActionWithFolder::KMFilterActionWithFolder( const char* aName, const TQString aLabel )
296  : KMFilterAction( aName, aLabel )
297 {
298  mFolder = 0;
299 }
300 
301 TQWidget* KMFilterActionWithFolder::createParamWidget( TQWidget* parent ) const
302 {
303  FolderRequester *req = new FolderRequester( parent,
304  kmkernel->getKMMainWidget()->folderTree() );
305  setParamWidgetValue( req );
306  return req;
307 }
308 
310 {
311  mFolder = ((FolderRequester *)paramWidget)->folder();
312  mFolderName = ((FolderRequester *)paramWidget)->folderId();
313 }
314 
315 void KMFilterActionWithFolder::setParamWidgetValue( TQWidget* paramWidget ) const
316 {
317  if ( mFolder )
318  ((FolderRequester *)paramWidget)->setFolder( mFolder );
319  else
320  ((FolderRequester *)paramWidget)->setFolder( mFolderName );
321 }
322 
323 void KMFilterActionWithFolder::clearParamWidget( TQWidget* paramWidget ) const
324 {
325  ((FolderRequester *)paramWidget)->setFolder( kmkernel->draftsFolder() );
326 }
327 
328 void KMFilterActionWithFolder::argsFromString( const TQString argsStr )
329 {
330  mFolder = kmkernel->folderMgr()->findIdString( argsStr );
331  if (!mFolder)
332  mFolder = kmkernel->dimapFolderMgr()->findIdString( argsStr );
333  if (!mFolder)
334  mFolder = kmkernel->imapFolderMgr()->findIdString( argsStr );
335  if (mFolder)
336  mFolderName = mFolder->idString();
337  else
338  mFolderName = argsStr;
339 }
340 
342 {
343  TQString result;
344  if ( mFolder )
345  result = mFolder->idString();
346  else
347  result = mFolderName;
348  return result;
349 }
350 
352 {
353  TQString result;
354  if ( mFolder )
355  result = mFolder->prettyURL();
356  else
357  result = mFolderName;
358  return label() + " \"" + TQStyleSheet::escape( result ) + "\"";
359 }
360 
362 {
363  if ( aFolder == mFolder ) {
364  mFolder = aNewFolder;
365  if ( aNewFolder )
366  mFolderName = mFolder->idString();
367  return true;
368  } else
369  return false;
370 }
371 
372 //=============================================================================
373 //
374 // class KMFilterActionWithAddress
375 //
376 //=============================================================================
377 
378 KMFilterActionWithAddress::KMFilterActionWithAddress( const char* aName, const TQString aLabel )
379  : KMFilterActionWithString( aName, aLabel )
380 {
381 }
382 
383 TQWidget* KMFilterActionWithAddress::createParamWidget( TQWidget* parent ) const
384 {
385  KMFilterActionWithAddressWidget *w = new KMFilterActionWithAddressWidget(parent);
386  w->setText( mParameter );
387  return w;
388 }
389 
391 {
392  mParameter = ((KMFilterActionWithAddressWidget*)paramWidget)->text();
393 }
394 
395 void KMFilterActionWithAddress::setParamWidgetValue( TQWidget* paramWidget ) const
396 {
397  ((KMFilterActionWithAddressWidget*)paramWidget)->setText( mParameter );
398 }
399 
400 void KMFilterActionWithAddress::clearParamWidget( TQWidget* paramWidget ) const
401 {
402  ((KMFilterActionWithAddressWidget*)paramWidget)->clear();
403 }
404 
405 //=============================================================================
406 //
407 // class KMFilterActionWithCommand
408 //
409 //=============================================================================
410 
411 KMFilterActionWithCommand::KMFilterActionWithCommand( const char* aName, const TQString aLabel )
412  : KMFilterActionWithUrl( aName, aLabel )
413 {
414 }
415 
416 TQWidget* KMFilterActionWithCommand::createParamWidget( TQWidget* parent ) const
417 {
419 }
420 
421 void KMFilterActionWithCommand::applyParamWidgetValue( TQWidget* paramWidget )
422 {
424 }
425 
426 void KMFilterActionWithCommand::setParamWidgetValue( TQWidget* paramWidget ) const
427 {
429 }
430 
431 void KMFilterActionWithCommand::clearParamWidget( TQWidget* paramWidget ) const
432 {
434 }
435 
436 TQString KMFilterActionWithCommand::substituteCommandLineArgsFor( KMMessage *aMsg, TQPtrList<KTempFile> & aTempFileList ) const
437 {
438  TQString result = mParameter;
439  TQValueList<int> argList;
440  TQRegExp r( "%[0-9-]+" );
441 
442  // search for '%n'
443  int start = -1;
444  while ( ( start = r.search( result, start + 1 ) ) > 0 ) {
445  int len = r.matchedLength();
446  // and save the encountered 'n' in a list.
447  bool OK = false;
448  int n = result.mid( start + 1, len - 1 ).toInt( &OK );
449  if ( OK )
450  argList.append( n );
451  }
452 
453  // sort the list of n's
454  qHeapSort( argList );
455 
456  // and use TQString::arg to substitute filenames for the %n's.
457  int lastSeen = -2;
458  TQString tempFileName;
459  for ( TQValueList<int>::Iterator it = argList.begin() ; it != argList.end() ; ++it ) {
460  // setup temp files with check for duplicate %n's
461  if ( (*it) != lastSeen ) {
462  KTempFile *tf = new KTempFile();
463  if ( tf->status() != 0 ) {
464  tf->close();
465  delete tf;
466  kdDebug(5006) << "KMFilterActionWithCommand: Could not create temp file!" << endl;
467  return TQString();
468  }
469  tf->setAutoDelete(true);
470  aTempFileList.append( tf );
471  tempFileName = tf->name();
472  if ((*it) == -1)
473  KPIM::kCStringToFile( aMsg->asString(), tempFileName, //###
474  false, false, false );
475  else if (aMsg->numBodyParts() == 0)
476  KPIM::kByteArrayToFile( aMsg->bodyDecodedBinary(), tempFileName,
477  false, false, false );
478  else {
479  KMMessagePart msgPart;
480  aMsg->bodyPart( (*it), &msgPart );
481  KPIM::kByteArrayToFile( msgPart.bodyDecodedBinary(), tempFileName,
482  false, false, false );
483  }
484  tf->close();
485  }
486  // TQString( "%0 and %1 and %1" ).arg( 0 ).arg( 1 )
487  // returns "0 and 1 and %1", so we must call .arg as
488  // many times as there are %n's, regardless of their multiplicity.
489  if ((*it) == -1) result.replace( "%-1", tempFileName );
490  else result = result.arg( tempFileName );
491  }
492 
493  // And finally, replace the %{foo} with the content of the foo
494  // header field:
495  TQRegExp header_rx( "%\\{([a-z0-9-]+)\\}", false );
496  int idx = 0;
497  while ( ( idx = header_rx.search( result, idx ) ) != -1 ) {
498  TQString replacement = TDEProcess::quote( aMsg->headerField( TQString(header_rx.cap(1)).latin1() ) );
499  result.replace( idx, header_rx.matchedLength(), replacement );
500  idx += replacement.length();
501  }
502 
503  return result;
504 }
505 
506 
507 KMFilterAction::ReturnCode KMFilterActionWithCommand::genericProcess(KMMessage* aMsg, bool withOutput) const
508 {
509  Q_ASSERT( aMsg );
510 
511  if ( mParameter.isEmpty() )
512  return ErrorButGoOn;
513 
514  // TDEProcess doesn't support a TQProcess::launch() equivalent, so
515  // we must use a temp file :-(
516  KTempFile * inFile = new KTempFile;
517  inFile->setAutoDelete(true);
518 
519  TQPtrList<KTempFile> atmList;
520  atmList.setAutoDelete(true);
521  atmList.append( inFile );
522 
523  TQString commandLine = substituteCommandLineArgsFor( aMsg , atmList );
524  if ( commandLine.isEmpty() )
525  return ErrorButGoOn;
526 
527  // The parentheses force the creation of a subshell
528  // in which the user-specified command is executed.
529  // This is to really catch all output of the command as well
530  // as to avoid clashes of our redirection with the ones
531  // the user may have specified. In the long run, we
532  // shouldn't be using tempfiles at all for this class, due
533  // to security aspects. (mmutz)
534  commandLine = "(" + commandLine + ") <" + inFile->name();
535 
536  // write message to file
537  TQString tempFileName = inFile->name();
538  KPIM::kCStringToFile( aMsg->asString(), tempFileName, //###
539  false, false, false );
540  inFile->close();
541 
542  CollectingProcess shProc;
543  shProc.setUseShell(true);
544  shProc << commandLine;
545 
546  // run process:
547  if ( !shProc.start( TDEProcess::Block,
548  withOutput ? TDEProcess::Stdout
549  : TDEProcess::NoCommunication ) )
550  return ErrorButGoOn;
551 
552  if ( !shProc.normalExit() || shProc.exitStatus() != 0 ) {
553  return ErrorButGoOn;
554  }
555 
556  if ( withOutput ) {
557  // read altered message:
558  TQByteArray msgText = shProc.collectedStdout();
559 
560  if ( !msgText.isEmpty() ) {
561  /* If the pipe through alters the message, it could very well
562  happen that it no longer has a X-UID header afterwards. That is
563  unfortunate, as we need to removed the original from the folder
564  using that, and look it up in the message. When the (new) message
565  is uploaded, the header is stripped anyhow. */
566  TQString uid = aMsg->headerField("X-UID");
567  aMsg->fromByteArray( msgText );
568  aMsg->setHeaderField("X-UID",uid);
569  }
570  else
571  return ErrorButGoOn;
572  }
573  return GoOn;
574 }
575 
576 
577 //=============================================================================
578 //
579 // Specific Filter Actions
580 //
581 //=============================================================================
582 
583 //=============================================================================
584 // KMFilterActionSendReceipt - send receipt
585 // Return delivery receipt.
586 //=============================================================================
587 class KMFilterActionSendReceipt : public KMFilterActionWithNone
588 {
589 public:
590  KMFilterActionSendReceipt();
591  virtual ReturnCode process(KMMessage* msg) const;
592  static KMFilterAction* newAction(void);
593 };
594 
595 KMFilterAction* KMFilterActionSendReceipt::newAction(void)
596 {
597  return (new KMFilterActionSendReceipt);
598 }
599 
600 KMFilterActionSendReceipt::KMFilterActionSendReceipt()
601  : KMFilterActionWithNone( "confirm delivery", i18n("Confirm Delivery") )
602 {
603 }
604 
605 KMFilterAction::ReturnCode KMFilterActionSendReceipt::process(KMMessage* msg) const
606 {
607  KMMessage *receipt = msg->createDeliveryReceipt();
608  if ( !receipt ) return ErrorButGoOn;
609 
610  // Queue message. This is a) so that the user can check
611  // the receipt before sending and b) for speed reasons.
612  kmkernel->msgSender()->send( receipt, KMail::MessageSender::SendLater );
613 
614  return GoOn;
615 }
616 
617 
618 
619 //=============================================================================
620 // KMFilterActionSetTransport - set transport to...
621 // Specify mail transport (smtp server) to be used when replying to a message
622 //=============================================================================
623 class KMFilterActionTransport: public KMFilterActionWithString
624 {
625 public:
626  KMFilterActionTransport();
627  virtual ReturnCode process(KMMessage* msg) const;
628  static KMFilterAction* newAction(void);
629 };
630 
631 KMFilterAction* KMFilterActionTransport::newAction(void)
632 {
633  return (new KMFilterActionTransport);
634 }
635 
636 KMFilterActionTransport::KMFilterActionTransport()
637  : KMFilterActionWithString( "set transport", i18n("Set Transport To") )
638 {
639 }
640 
641 KMFilterAction::ReturnCode KMFilterActionTransport::process(KMMessage* msg) const
642 {
643  if ( mParameter.isEmpty() )
644  return ErrorButGoOn;
645  msg->setHeaderField( "X-KMail-Transport", mParameter );
646  return GoOn;
647 }
648 
649 
650 //=============================================================================
651 // KMFilterActionReplyTo - set Reply-To to
652 // Set the Reply-to header in a message
653 //=============================================================================
654 class KMFilterActionReplyTo: public KMFilterActionWithString
655 {
656 public:
657  KMFilterActionReplyTo();
658  virtual ReturnCode process(KMMessage* msg) const;
659  static KMFilterAction* newAction(void);
660 };
661 
662 KMFilterAction* KMFilterActionReplyTo::newAction(void)
663 {
664  return (new KMFilterActionReplyTo);
665 }
666 
667 KMFilterActionReplyTo::KMFilterActionReplyTo()
668  : KMFilterActionWithString( "set Reply-To", i18n("Set Reply-To To") )
669 {
670  mParameter = "";
671 }
672 
673 KMFilterAction::ReturnCode KMFilterActionReplyTo::process(KMMessage* msg) const
674 {
675  msg->setHeaderField( "Reply-To", mParameter );
676  return GoOn;
677 }
678 
679 
680 
681 //=============================================================================
682 // KMFilterActionIdentity - set identity to
683 // Specify Identity to be used when replying to a message
684 //=============================================================================
685 class KMFilterActionIdentity: public KMFilterActionWithUOID
686 {
687 public:
688  KMFilterActionIdentity();
689  virtual ReturnCode process(KMMessage* msg) const;
690  static KMFilterAction* newAction();
691 
692  TQWidget * createParamWidget( TQWidget * parent ) const;
693  void applyParamWidgetValue( TQWidget * parent );
694  void setParamWidgetValue( TQWidget * parent ) const;
695  void clearParamWidget( TQWidget * param ) const;
696 };
697 
698 KMFilterAction* KMFilterActionIdentity::newAction()
699 {
700  return (new KMFilterActionIdentity);
701 }
702 
703 KMFilterActionIdentity::KMFilterActionIdentity()
704  : KMFilterActionWithUOID( "set identity", i18n("Set Identity To") )
705 {
706  mParameter = kmkernel->identityManager()->defaultIdentity().uoid();
707 }
708 
709 KMFilterAction::ReturnCode KMFilterActionIdentity::process(KMMessage* msg) const
710 {
711  msg->setHeaderField( "X-KMail-Identity", TQString::number( mParameter ) );
712  return GoOn;
713 }
714 
715 TQWidget * KMFilterActionIdentity::createParamWidget( TQWidget * parent ) const
716 {
717  KPIM::IdentityCombo * ic = new KPIM::IdentityCombo( kmkernel->identityManager(), parent );
718  ic->setCurrentIdentity( mParameter );
719  return ic;
720 }
721 
722 void KMFilterActionIdentity::applyParamWidgetValue( TQWidget * paramWidget )
723 {
724  KPIM::IdentityCombo * ic = dynamic_cast<KPIM::IdentityCombo*>( paramWidget );
725  assert( ic );
726  mParameter = ic->currentIdentity();
727 }
728 
729 void KMFilterActionIdentity::clearParamWidget( TQWidget * paramWidget ) const
730 {
731  KPIM::IdentityCombo * ic = dynamic_cast<KPIM::IdentityCombo*>( paramWidget );
732  assert( ic );
733  ic->setCurrentItem( 0 );
734  //ic->setCurrentIdentity( kmkernel->identityManager()->defaultIdentity() );
735 }
736 
737 void KMFilterActionIdentity::setParamWidgetValue( TQWidget * paramWidget ) const
738 {
739  KPIM::IdentityCombo * ic = dynamic_cast<KPIM::IdentityCombo*>( paramWidget );
740  assert( ic );
741  ic->setCurrentIdentity( mParameter );
742 }
743 
744 //=============================================================================
745 // KMFilterActionSeStatus - set status to
746 // Set the status of messages
747 //=============================================================================
748 class KMFilterActionSeStatus: public KMFilterActionWithStringList
749 {
750 public:
751  KMFilterActionSeStatus();
752  virtual ReturnCode process(KMMessage* msg) const;
753  virtual bool requiresBody(KMMsgBase*) const;
754 
755  static KMFilterAction* newAction();
756 
757  virtual bool isEmpty() const { return false; }
758 
759  virtual void argsFromString( const TQString argsStr );
760  virtual const TQString argsAsString() const;
761  virtual const TQString displayString() const;
762 };
763 
764 
765 static const KMMsgStatus stati[] =
766 {
767  KMMsgStatusFlag,
768  KMMsgStatusRead,
769  KMMsgStatusUnread,
770  KMMsgStatusReplied,
771  KMMsgStatusForwarded,
772  KMMsgStatusOld,
773  KMMsgStatusNew,
774  KMMsgStatusWatched,
775  KMMsgStatusIgnored,
776  KMMsgStatusSpam,
777  KMMsgStatusHam
778 };
779 static const int StatiCount = sizeof( stati ) / sizeof( KMMsgStatus );
780 
781 KMFilterAction* KMFilterActionSeStatus::newAction()
782 {
783  return (new KMFilterActionSeStatus);
784 }
785 
786 KMFilterActionSeStatus::KMFilterActionSeStatus()
787  : KMFilterActionWithStringList( "set status", i18n("Mark As") )
788 {
789  // if you change this list, also update
790  // KMFilterActionSeStatus::stati above
791  mParameterList.append( "" );
792  mParameterList.append( i18n("msg status","Important") );
793  mParameterList.append( i18n("msg status","Read") );
794  mParameterList.append( i18n("msg status","Unread") );
795  mParameterList.append( i18n("msg status","Replied") );
796  mParameterList.append( i18n("msg status","Forwarded") );
797  mParameterList.append( i18n("msg status","Old") );
798  mParameterList.append( i18n("msg status","New") );
799  mParameterList.append( i18n("msg status","Watched") );
800  mParameterList.append( i18n("msg status","Ignored") );
801  mParameterList.append( i18n("msg status","Spam") );
802  mParameterList.append( i18n("msg status","Ham") );
803 
804  mParameter = *mParameterList.at(0);
805 }
806 
807 KMFilterAction::ReturnCode KMFilterActionSeStatus::process(KMMessage* msg) const
808 {
809  int idx = mParameterList.findIndex( mParameter );
810  if ( idx < 1 ) return ErrorButGoOn;
811 
812  KMMsgStatus status = stati[idx-1] ;
813  msg->setStatus( status );
814  return GoOn;
815 }
816 
817 bool KMFilterActionSeStatus::requiresBody(KMMsgBase*) const
818 {
819  return false;
820 }
821 
822 void KMFilterActionSeStatus::argsFromString( const TQString argsStr )
823 {
824  if ( argsStr.length() == 1 ) {
825  for ( int i = 0 ; i < StatiCount ; i++ )
826  if ( KMMsgBase::statusToStr(stati[i])[0] == argsStr[0] ) {
827  mParameter = *mParameterList.at(i+1);
828  return;
829  }
830  }
831  mParameter = *mParameterList.at(0);
832 }
833 
834 const TQString KMFilterActionSeStatus::argsAsString() const
835 {
836  int idx = mParameterList.findIndex( mParameter );
837  if ( idx < 1 ) return TQString();
838 
839  KMMsgStatus status = stati[idx-1];
840  return KMMsgBase::statusToStr(status);
841 }
842 
843 const TQString KMFilterActionSeStatus::displayString() const
844 {
845  // FIXME after string freeze:
846  // return i18n("").arg( );
847  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
848 }
849 
850 //=============================================================================
851 // KMFilterActionFakeDisposition - send fake MDN
852 // Sends a fake MDN or forces an ignore.
853 //=============================================================================
854 class KMFilterActionFakeDisposition: public KMFilterActionWithStringList
855 {
856 public:
857  KMFilterActionFakeDisposition();
858  virtual ReturnCode process(KMMessage* msg) const;
859  static KMFilterAction* newAction() {
860  return (new KMFilterActionFakeDisposition);
861  }
862 
863  virtual bool isEmpty() const { return false; }
864 
865  virtual void argsFromString( const TQString argsStr );
866  virtual const TQString argsAsString() const;
867  virtual const TQString displayString() const;
868 };
869 
870 
871 // if you change this list, also update
872 // the count in argsFromString
873 static const KMime::MDN::DispositionType mdns[] =
874 {
875  KMime::MDN::Displayed,
876  KMime::MDN::Deleted,
877  KMime::MDN::Dispatched,
878  KMime::MDN::Processed,
879  KMime::MDN::Denied,
880  KMime::MDN::Failed,
881 };
882 static const int numMDNs = sizeof mdns / sizeof *mdns;
883 
884 
885 KMFilterActionFakeDisposition::KMFilterActionFakeDisposition()
886  : KMFilterActionWithStringList( "fake mdn", i18n("Send Fake MDN") )
887 {
888  // if you change this list, also update
889  // mdns above
890  mParameterList.append( "" );
891  mParameterList.append( i18n("MDN type","Ignore") );
892  mParameterList.append( i18n("MDN type","Displayed") );
893  mParameterList.append( i18n("MDN type","Deleted") );
894  mParameterList.append( i18n("MDN type","Dispatched") );
895  mParameterList.append( i18n("MDN type","Processed") );
896  mParameterList.append( i18n("MDN type","Denied") );
897  mParameterList.append( i18n("MDN type","Failed") );
898 
899  mParameter = *mParameterList.at(0);
900 }
901 
902 KMFilterAction::ReturnCode KMFilterActionFakeDisposition::process(KMMessage* msg) const
903 {
904  int idx = mParameterList.findIndex( mParameter );
905  if ( idx < 1 ) return ErrorButGoOn;
906 
907  if ( idx == 1 ) // ignore
908  msg->setMDNSentState( KMMsgMDNIgnore );
909  else // send
910  sendMDN( msg, mdns[idx-2] ); // skip first two entries: "" and "ignore"
911  return GoOn;
912 }
913 
914 void KMFilterActionFakeDisposition::argsFromString( const TQString argsStr )
915 {
916  if ( argsStr.length() == 1 ) {
917  if ( argsStr[0] == 'I' ) { // ignore
918  mParameter = *mParameterList.at(1);
919  return;
920  }
921  for ( int i = 0 ; i < numMDNs ; i++ )
922  if ( char(mdns[i]) == argsStr[0] ) { // send
923  mParameter = *mParameterList.at(i+2);
924  return;
925  }
926  }
927  mParameter = *mParameterList.at(0);
928 }
929 
930 const TQString KMFilterActionFakeDisposition::argsAsString() const
931 {
932  int idx = mParameterList.findIndex( mParameter );
933  if ( idx < 1 ) return TQString();
934 
935  return TQString( TQChar( idx < 2 ? 'I' : char(mdns[idx-2]) ) );
936 }
937 
938 const TQString KMFilterActionFakeDisposition::displayString() const
939 {
940  // FIXME after string freeze:
941  // return i18n("").arg( );
942  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
943 }
944 
945 //=============================================================================
946 // KMFilterActionRemoveHeader - remove header
947 // Remove all instances of the given header field.
948 //=============================================================================
949 class KMFilterActionRemoveHeader: public KMFilterActionWithStringList
950 {
951 public:
952  KMFilterActionRemoveHeader();
953  virtual ReturnCode process(KMMessage* msg) const;
954  virtual TQWidget* createParamWidget( TQWidget* parent ) const;
955  virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
956 
957  static KMFilterAction* newAction();
958 };
959 
960 KMFilterAction* KMFilterActionRemoveHeader::newAction()
961 {
962  return (new KMFilterActionRemoveHeader);
963 }
964 
965 KMFilterActionRemoveHeader::KMFilterActionRemoveHeader()
966  : KMFilterActionWithStringList( "remove header", i18n("Remove Header") )
967 {
968  mParameterList << ""
969  << "Reply-To"
970  << "Delivered-To"
971  << "X-TDE-PR-Message"
972  << "X-TDE-PR-Package"
973  << "X-TDE-PR-Keywords";
974  mParameter = *mParameterList.at(0);
975 }
976 
977 TQWidget* KMFilterActionRemoveHeader::createParamWidget( TQWidget* parent ) const
978 {
979  TQComboBox *cb = new TQComboBox( true/*editable*/, parent );
980  cb->setInsertionPolicy( TQComboBox::AtBottom );
981  setParamWidgetValue( cb );
982  return cb;
983 }
984 
985 KMFilterAction::ReturnCode KMFilterActionRemoveHeader::process(KMMessage* msg) const
986 {
987  if ( mParameter.isEmpty() ) return ErrorButGoOn;
988 
989  while ( !msg->headerField( mParameter.latin1() ).isEmpty() )
990  msg->removeHeaderField( mParameter.latin1() );
991  return GoOn;
992 }
993 
994 void KMFilterActionRemoveHeader::setParamWidgetValue( TQWidget* paramWidget ) const
995 {
996  TQComboBox * cb = dynamic_cast<TQComboBox*>(paramWidget);
997  Q_ASSERT( cb );
998 
999  int idx = mParameterList.findIndex( mParameter );
1000  cb->clear();
1001  cb->insertStringList( mParameterList );
1002  if ( idx < 0 ) {
1003  cb->insertItem( mParameter );
1004  cb->setCurrentItem( cb->count() - 1 );
1005  } else {
1006  cb->setCurrentItem( idx );
1007  }
1008 }
1009 
1010 
1011 //=============================================================================
1012 // KMFilterActionAddHeader - add header
1013 // Add a header with the given value.
1014 //=============================================================================
1015 class KMFilterActionAddHeader: public KMFilterActionWithStringList
1016 {
1017 public:
1018  KMFilterActionAddHeader();
1019  virtual ReturnCode process(KMMessage* msg) const;
1020  virtual TQWidget* createParamWidget( TQWidget* parent ) const;
1021  virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
1022  virtual void applyParamWidgetValue( TQWidget* paramWidget );
1023  virtual void clearParamWidget( TQWidget* paramWidget ) const;
1024 
1025  virtual const TQString argsAsString() const;
1026  virtual void argsFromString( const TQString argsStr );
1027 
1028  virtual const TQString displayString() const;
1029 
1030  static KMFilterAction* newAction()
1031  {
1032  return (new KMFilterActionAddHeader);
1033  }
1034 private:
1035  TQString mValue;
1036 };
1037 
1038 KMFilterActionAddHeader::KMFilterActionAddHeader()
1039  : KMFilterActionWithStringList( "add header", i18n("Add Header") )
1040 {
1041  mParameterList << ""
1042  << "Reply-To"
1043  << "Delivered-To"
1044  << "X-TDE-PR-Message"
1045  << "X-TDE-PR-Package"
1046  << "X-TDE-PR-Keywords";
1047  mParameter = *mParameterList.at(0);
1048 }
1049 
1050 KMFilterAction::ReturnCode KMFilterActionAddHeader::process(KMMessage* msg) const
1051 {
1052  if ( mParameter.isEmpty() ) return ErrorButGoOn;
1053 
1054  msg->setHeaderField( mParameter.latin1(), mValue );
1055  return GoOn;
1056 }
1057 
1058 TQWidget* KMFilterActionAddHeader::createParamWidget( TQWidget* parent ) const
1059 {
1060  TQWidget *w = new TQWidget( parent );
1061  TQHBoxLayout *hbl = new TQHBoxLayout( w );
1062  hbl->setSpacing( 4 );
1063  TQComboBox *cb = new TQComboBox( true, w, "combo" );
1064  cb->setInsertionPolicy( TQComboBox::AtBottom );
1065  hbl->addWidget( cb, 0 /* stretch */ );
1066  TQLabel *l = new TQLabel( i18n("With value:"), w );
1067  l->setFixedWidth( l->sizeHint().width() );
1068  hbl->addWidget( l, 0 );
1069  TQLineEdit *le = new KLineEdit( w, "ledit" );
1070  hbl->addWidget( le, 1 );
1071  setParamWidgetValue( w );
1072  return w;
1073 }
1074 
1075 void KMFilterActionAddHeader::setParamWidgetValue( TQWidget* paramWidget ) const
1076 {
1077  int idx = mParameterList.findIndex( mParameter );
1078  TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
1079  Q_ASSERT( cb );
1080  cb->clear();
1081  cb->insertStringList( mParameterList );
1082  if ( idx < 0 ) {
1083  cb->insertItem( mParameter );
1084  cb->setCurrentItem( cb->count() - 1 );
1085  } else {
1086  cb->setCurrentItem( idx );
1087  }
1088  TQLineEdit *le = (TQLineEdit*)paramWidget->child("ledit");
1089  Q_ASSERT( le );
1090  le->setText( mValue );
1091 }
1092 
1093 void KMFilterActionAddHeader::applyParamWidgetValue( TQWidget* paramWidget )
1094 {
1095  TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
1096  Q_ASSERT( cb );
1097  mParameter = cb->currentText();
1098 
1099  TQLineEdit *le = (TQLineEdit*)paramWidget->child("ledit");
1100  Q_ASSERT( le );
1101  mValue = le->text();
1102 }
1103 
1104 void KMFilterActionAddHeader::clearParamWidget( TQWidget* paramWidget ) const
1105 {
1106  TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
1107  Q_ASSERT( cb );
1108  cb->setCurrentItem(0);
1109  TQLineEdit *le = (TQLineEdit*)paramWidget->child("ledit");
1110  Q_ASSERT( le );
1111  le->clear();
1112 }
1113 
1114 const TQString KMFilterActionAddHeader::argsAsString() const
1115 {
1116  TQString result = mParameter;
1117  result += '\t';
1118  result += mValue;
1119 
1120  return result;
1121 }
1122 
1123 const TQString KMFilterActionAddHeader::displayString() const
1124 {
1125  // FIXME after string freeze:
1126  // return i18n("").arg( );
1127  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
1128 }
1129 
1130 void KMFilterActionAddHeader::argsFromString( const TQString argsStr )
1131 {
1132  TQStringList l = TQStringList::split( '\t', argsStr, true /*allow empty entries*/ );
1133  TQString s;
1134  if ( l.count() < 2 ) {
1135  s = l[0];
1136  mValue = "";
1137  } else {
1138  s = l[0];
1139  mValue = l[1];
1140  }
1141 
1142  int idx = mParameterList.findIndex( s );
1143  if ( idx < 0 ) {
1144  mParameterList.append( s );
1145  idx = mParameterList.count() - 1;
1146  }
1147  mParameter = *mParameterList.at( idx );
1148 }
1149 
1150 
1151 //=============================================================================
1152 // KMFilterActionRewriteHeader - rewrite header
1153 // Rewrite a header using a regexp.
1154 //=============================================================================
1155 class KMFilterActionRewriteHeader: public KMFilterActionWithStringList
1156 {
1157 public:
1158  KMFilterActionRewriteHeader();
1159  virtual ReturnCode process(KMMessage* msg) const;
1160  virtual TQWidget* createParamWidget( TQWidget* parent ) const;
1161  virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
1162  virtual void applyParamWidgetValue( TQWidget* paramWidget );
1163  virtual void clearParamWidget( TQWidget* paramWidget ) const;
1164 
1165  virtual const TQString argsAsString() const;
1166  virtual void argsFromString( const TQString argsStr );
1167 
1168  virtual const TQString displayString() const;
1169 
1170  static KMFilterAction* newAction()
1171  {
1172  return (new KMFilterActionRewriteHeader);
1173  }
1174 private:
1175  KRegExp3 mRegExp;
1176  TQString mReplacementString;
1177 };
1178 
1179 KMFilterActionRewriteHeader::KMFilterActionRewriteHeader()
1180  : KMFilterActionWithStringList( "rewrite header", i18n("Rewrite Header") )
1181 {
1182  mParameterList << ""
1183  << "Subject"
1184  << "Reply-To"
1185  << "Delivered-To"
1186  << "X-TDE-PR-Message"
1187  << "X-TDE-PR-Package"
1188  << "X-TDE-PR-Keywords";
1189  mParameter = *mParameterList.at(0);
1190 }
1191 
1192 KMFilterAction::ReturnCode KMFilterActionRewriteHeader::process(KMMessage* msg) const
1193 {
1194  if ( mParameter.isEmpty() || !mRegExp.isValid() )
1195  return ErrorButGoOn;
1196 
1197  KRegExp3 rx = mRegExp; // KRegExp3::replace is not const.
1198 
1199  TQString newValue = rx.replace( msg->headerField( mParameter.latin1() ),
1200  mReplacementString );
1201 
1202  msg->setHeaderField( mParameter.latin1(), newValue );
1203  return GoOn;
1204 }
1205 
1206 TQWidget* KMFilterActionRewriteHeader::createParamWidget( TQWidget* parent ) const
1207 {
1208  TQWidget *w = new TQWidget( parent );
1209  TQHBoxLayout *hbl = new TQHBoxLayout( w );
1210  hbl->setSpacing( 4 );
1211 
1212  TQComboBox *cb = new TQComboBox( true, w, "combo" );
1213  cb->setInsertionPolicy( TQComboBox::AtBottom );
1214  hbl->addWidget( cb, 0 /* stretch */ );
1215 
1216  TQLabel *l = new TQLabel( i18n("Replace:"), w );
1217  l->setFixedWidth( l->sizeHint().width() );
1218  hbl->addWidget( l, 0 );
1219 
1220  RegExpLineEdit *rele = new RegExpLineEdit( w, "search" );
1221  hbl->addWidget( rele, 1 );
1222 
1223  l = new TQLabel( i18n("With:"), w );
1224  l->setFixedWidth( l->sizeHint().width() );
1225  hbl->addWidget( l, 0 );
1226 
1227  TQLineEdit *le = new KLineEdit( w, "replace" );
1228  hbl->addWidget( le, 1 );
1229 
1230  setParamWidgetValue( w );
1231  return w;
1232 }
1233 
1234 void KMFilterActionRewriteHeader::setParamWidgetValue( TQWidget* paramWidget ) const
1235 {
1236  int idx = mParameterList.findIndex( mParameter );
1237  TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
1238  Q_ASSERT( cb );
1239 
1240  cb->clear();
1241  cb->insertStringList( mParameterList );
1242  if ( idx < 0 ) {
1243  cb->insertItem( mParameter );
1244  cb->setCurrentItem( cb->count() - 1 );
1245  } else {
1246  cb->setCurrentItem( idx );
1247  }
1248 
1249  RegExpLineEdit *rele = (RegExpLineEdit*)paramWidget->child("search");
1250  Q_ASSERT( rele );
1251  rele->setText( mRegExp.pattern() );
1252 
1253  TQLineEdit *le = (TQLineEdit*)paramWidget->child("replace");
1254  Q_ASSERT( le );
1255  le->setText( mReplacementString );
1256 }
1257 
1258 void KMFilterActionRewriteHeader::applyParamWidgetValue( TQWidget* paramWidget )
1259 {
1260  TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
1261  Q_ASSERT( cb );
1262  mParameter = cb->currentText();
1263 
1264  RegExpLineEdit *rele = (RegExpLineEdit*)paramWidget->child("search");
1265  Q_ASSERT( rele );
1266  mRegExp.setPattern( rele->text() );
1267 
1268  TQLineEdit *le = (TQLineEdit*)paramWidget->child("replace");
1269  Q_ASSERT( le );
1270  mReplacementString = le->text();
1271 }
1272 
1273 void KMFilterActionRewriteHeader::clearParamWidget( TQWidget* paramWidget ) const
1274 {
1275  TQComboBox *cb = (TQComboBox*)paramWidget->child("combo");
1276  Q_ASSERT( cb );
1277  cb->setCurrentItem(0);
1278 
1279  RegExpLineEdit *rele = (RegExpLineEdit*)paramWidget->child("search");
1280  Q_ASSERT( rele );
1281  rele->clear();
1282 
1283  TQLineEdit *le = (TQLineEdit*)paramWidget->child("replace");
1284  Q_ASSERT( le );
1285  le->clear();
1286 }
1287 
1288 const TQString KMFilterActionRewriteHeader::argsAsString() const
1289 {
1290  TQString result = mParameter;
1291  result += '\t';
1292  result += mRegExp.pattern();
1293  result += '\t';
1294  result += mReplacementString;
1295 
1296  return result;
1297 }
1298 
1299 const TQString KMFilterActionRewriteHeader::displayString() const
1300 {
1301  // FIXME after string freeze:
1302  // return i18n("").arg( );
1303  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
1304 }
1305 
1306 void KMFilterActionRewriteHeader::argsFromString( const TQString argsStr )
1307 {
1308  TQStringList l = TQStringList::split( '\t', argsStr, true /*allow empty entries*/ );
1309  TQString s;
1310 
1311  s = l[0];
1312  mRegExp.setPattern( l[1] );
1313  mReplacementString = l[2];
1314 
1315  int idx = mParameterList.findIndex( s );
1316  if ( idx < 0 ) {
1317  mParameterList.append( s );
1318  idx = mParameterList.count() - 1;
1319  }
1320  mParameter = *mParameterList.at( idx );
1321 }
1322 
1323 
1324 //=============================================================================
1325 // KMFilterActionMove - move into folder
1326 // File message into another mail folder
1327 //=============================================================================
1328 class KMFilterActionMove: public KMFilterActionWithFolder
1329 {
1330 public:
1331  KMFilterActionMove();
1332  virtual ReturnCode process(KMMessage* msg) const;
1333  virtual bool requiresBody(KMMsgBase*) const;
1334  static KMFilterAction* newAction(void);
1335 };
1336 
1337 KMFilterAction* KMFilterActionMove::newAction(void)
1338 {
1339  return (new KMFilterActionMove);
1340 }
1341 
1342 KMFilterActionMove::KMFilterActionMove()
1343  : KMFilterActionWithFolder( "transfer", i18n("Move Into Folder") )
1344 {
1345 }
1346 
1347 KMFilterAction::ReturnCode KMFilterActionMove::process(KMMessage* msg) const
1348 {
1349  if ( !mFolder )
1350  return ErrorButGoOn;
1351 
1352  ActionScheduler *handler = MessageProperty::filterHandler( msg );
1353  if (handler) {
1354  MessageProperty::setFilterFolder( msg, mFolder );
1355  } else {
1356  // The old filtering system does not support online imap targets.
1357  // Skip online imap targets when using the old system.
1358  KMFolder *check;
1359  check = kmkernel->imapFolderMgr()->findIdString( argsAsString() );
1360  if (mFolder && (check != mFolder)) {
1361  MessageProperty::setFilterFolder( msg, mFolder );
1362  }
1363  }
1364  return GoOn;
1365 }
1366 
1367 bool KMFilterActionMove::requiresBody(KMMsgBase*) const
1368 {
1369  return false; //iff mFolder->folderMgr == msgBase->parent()->folderMgr;
1370 }
1371 
1372 
1373 //=============================================================================
1374 // KMFilterActionCopy - copy into folder
1375 // Copy message into another mail folder
1376 //=============================================================================
1377 class KMFilterActionCopy: public KMFilterActionWithFolder
1378 {
1379 public:
1380  KMFilterActionCopy();
1381  virtual ReturnCode process(KMMessage* msg) const;
1382  virtual void processAsync(KMMessage* msg) const;
1383  virtual bool requiresBody(KMMsgBase*) const;
1384  static KMFilterAction* newAction(void);
1385 };
1386 
1387 KMFilterAction* KMFilterActionCopy::newAction(void)
1388 {
1389  return (new KMFilterActionCopy);
1390 }
1391 
1392 KMFilterActionCopy::KMFilterActionCopy()
1393  : KMFilterActionWithFolder( "copy", i18n("Copy Into Folder") )
1394 {
1395 }
1396 
1397 KMFilterAction::ReturnCode KMFilterActionCopy::process(KMMessage* msg) const
1398 {
1399  // TODO opening and closing the folder is a trade off.
1400  // Perhaps Copy is a seldomly used action for now,
1401  // but I gonna look at improvements ASAP.
1402  if ( !mFolder )
1403  return ErrorButGoOn;
1404  if ( mFolder && mFolder->open( "filtercopy" ) != 0 )
1405  return ErrorButGoOn;
1406 
1407  // copy the message 1:1
1408  KMMessage* msgCopy = new KMMessage( new DwMessage( *msg->asDwMessage() ) );
1409 
1410  int index;
1411  int rc = mFolder->addMsg(msgCopy, &index);
1412  if (rc == 0 && index != -1)
1413  mFolder->unGetMsg( index );
1414  mFolder->close("filtercopy");
1415 
1416  return GoOn;
1417 }
1418 
1419 void KMFilterActionCopy::processAsync(KMMessage* msg) const
1420 {
1421  // FIXME remove the debug output
1422  kdDebug(5006) << "##### KMFilterActionCopy::processAsync(KMMessage* msg)" << endl;
1423  ActionScheduler *handler = MessageProperty::filterHandler( msg );
1424 
1425  KMCommand *cmd = new KMCopyCommand( mFolder, msg );
1426  TQObject::connect( cmd, TQ_SIGNAL( completed( KMCommand * ) ),
1427  handler, TQ_SLOT( copyMessageFinished( KMCommand * ) ) );
1428  cmd->start();
1429 }
1430 
1431 bool KMFilterActionCopy::requiresBody(KMMsgBase*) const
1432 {
1433  return true;
1434 }
1435 
1436 
1437 //=============================================================================
1438 // KMFilterActionForward - forward to
1439 // Forward message to another user, with a defined template
1440 //=============================================================================
1441 class KMFilterActionForward: public KMFilterActionWithAddress
1442 {
1443 public:
1444  KMFilterActionForward();
1445  virtual ReturnCode process( KMMessage* msg ) const;
1446  virtual TQWidget* createParamWidget( TQWidget* parent ) const;
1447  virtual void applyParamWidgetValue( TQWidget* paramWidget );
1448  virtual void setParamWidgetValue( TQWidget* paramWidget ) const;
1449  virtual void clearParamWidget( TQWidget* paramWidget ) const;
1450  virtual void argsFromString( const TQString argsStr );
1451  virtual const TQString argsAsString() const;
1452  virtual const TQString displayString() const;
1453 
1454  static KMFilterAction* newAction(void);
1455 
1456 private:
1457 
1458  mutable TQString mTemplate;
1459 };
1460 
1461 KMFilterAction* KMFilterActionForward::newAction(void)
1462 {
1463  return (new KMFilterActionForward);
1464 }
1465 
1466 KMFilterActionForward::KMFilterActionForward()
1467  : KMFilterActionWithAddress( "forward", i18n("Forward To") )
1468 {
1469 }
1470 
1471 KMFilterAction::ReturnCode KMFilterActionForward::process(KMMessage* aMsg) const
1472 {
1473  if ( mParameter.isEmpty() )
1474  return ErrorButGoOn;
1475 
1476  // avoid endless loops when this action is used in a filter
1477  // which applies to sent messages
1478  if ( KMMessage::addressIsInAddressList( mParameter, aMsg->to() ) ) {
1479  kdWarning(5006) << "Attempt to forward to receipient of original message, ignoring." << endl;
1480  return ErrorButGoOn;
1481  }
1482 
1483  KMMessage *fwdMsg = aMsg->createForward( mTemplate );
1484  fwdMsg->setTo( fwdMsg->to() + ',' + mParameter );
1485 
1486  if ( !kmkernel->msgSender()->send( fwdMsg, KMail::MessageSender::SendDefault ) ) {
1487  kdWarning(5006) << "KMFilterAction: could not forward message (sending failed)" << endl;
1488  return ErrorButGoOn; // error: couldn't send
1489  }
1490  else
1491  sendMDN( aMsg, KMime::MDN::Dispatched );
1492 
1493  // (the msgSender takes ownership of the message, so don't delete it here)
1494 
1495  return GoOn;
1496 }
1497 
1498 TQWidget* KMFilterActionForward::createParamWidget( TQWidget* parent ) const
1499 {
1500  TQWidget *addressAndTemplate = new TQWidget( parent );
1501  TQHBoxLayout *hBox = new TQHBoxLayout( addressAndTemplate );
1502  TQWidget *addressEdit = KMFilterActionWithAddress::createParamWidget( addressAndTemplate );
1503  addressEdit->setName( "addressEdit" );
1504  hBox->addWidget( addressEdit );
1505 
1506  KLineEdit *lineEdit = dynamic_cast<KLineEdit*>( addressEdit->child( "addressEdit" ) );
1507  Q_ASSERT( lineEdit );
1508  TQToolTip::add( lineEdit, i18n( "The addressee the message will be forwarded to" ) );
1509  TQWhatsThis::add( lineEdit, i18n( "The filter will forward the message to the addressee entered here." ) );
1510 
1511  TQComboBox *templateCombo = new TQComboBox( addressAndTemplate );
1512  templateCombo->setName( "templateCombo" );
1513  hBox->addWidget( templateCombo );
1514 
1515  templateCombo->insertItem( i18n( "Default Template" ) );
1516  TQStringList templateNames = GlobalSettingsBase::self()->customTemplates();
1517  for ( TQStringList::const_iterator it = templateNames.begin(); it != templateNames.end();
1518  it++ ) {
1519  CTemplates templat( *it );
1520  if ( templat.type() == CustomTemplates::TForward ||
1521  templat.type() == CustomTemplates::TUniversal )
1522  templateCombo->insertItem( *it );
1523  }
1524  templateCombo->setEnabled( templateCombo->count() > 1 );
1525  TQToolTip::add( templateCombo, i18n( "The template used when forwarding" ) );
1526  TQWhatsThis::add( templateCombo, i18n( "Set the forwarding template that will be used with this filter." ) );
1527 
1528  return addressAndTemplate;
1529 }
1530 
1531 void KMFilterActionForward::applyParamWidgetValue( TQWidget* paramWidget )
1532 {
1533  // Use findChildren<T> when porting to KDE 4
1534  TQWidget *addressEdit = dynamic_cast<TQWidget*>( paramWidget->child( "addressEdit" ) );
1535  Q_ASSERT( addressEdit );
1537 
1538  TQComboBox *templateCombo = dynamic_cast<TQComboBox*>( paramWidget->child( "templateCombo" ) );
1539  Q_ASSERT( templateCombo );
1540 
1541  if ( templateCombo->currentItem() == 0 ) {
1542  // Default template, so don't use a custom one
1543  mTemplate = TQString();
1544  }
1545  else {
1546  mTemplate = templateCombo->currentText();
1547  }
1548 }
1549 
1550 void KMFilterActionForward::setParamWidgetValue( TQWidget* paramWidget ) const
1551 {
1552  TQWidget *addressEdit = dynamic_cast<TQWidget*>( paramWidget->child( "addressEdit" ) );
1553  Q_ASSERT( addressEdit );
1555 
1556  TQComboBox *templateCombo = dynamic_cast<TQComboBox*>( paramWidget->child( "templateCombo" ) );
1557  Q_ASSERT( templateCombo );
1558 
1559  if ( mTemplate.isEmpty() ) {
1560  templateCombo->setCurrentItem( 0 );
1561  }
1562  else {
1563  // WTF: TQt3's combobox has no indexOf? Search it manually, then.
1564  int templateIndex = -1;
1565  for ( int i = 1; i < templateCombo->count(); i++ ) {
1566  if ( templateCombo->text( i ) == mTemplate ) {
1567  templateIndex = i;
1568  break;
1569  }
1570  }
1571 
1572  if ( templateIndex != -1 ) {
1573  templateCombo->setCurrentItem( templateIndex );
1574  }
1575  else {
1576  mTemplate = TQString();
1577  }
1578  }
1579 }
1580 
1581 void KMFilterActionForward::clearParamWidget( TQWidget* paramWidget ) const
1582 {
1583  TQWidget *addressEdit = dynamic_cast<TQWidget*>( paramWidget->child( "addressEdit" ) );
1584  Q_ASSERT( addressEdit );
1586 
1587  TQComboBox *templateCombo = dynamic_cast<TQComboBox*>( paramWidget->child( "templateCombo" ) );
1588  Q_ASSERT( templateCombo );
1589 
1590  templateCombo->setCurrentItem( 0 );
1591 }
1592 
1593 // We simply place a "@$$@" between the two parameters. The template is the last
1594 // parameter in the string, for compatibility reasons.
1595 static const TQString forwardFilterArgsSeperator = "@$$@";
1596 
1597 void KMFilterActionForward::argsFromString( const TQString argsStr )
1598 {
1599  int seperatorPos = argsStr.find( forwardFilterArgsSeperator );
1600 
1601  if ( seperatorPos == - 1 ) {
1602  // Old config, assume that the whole string is the addressee
1604  }
1605  else {
1606  TQString addressee = argsStr.left( seperatorPos );
1607  mTemplate = argsStr.mid( seperatorPos + forwardFilterArgsSeperator.length() );
1609  }
1610 }
1611 
1612 const TQString KMFilterActionForward::argsAsString() const
1613 {
1614  return KMFilterActionWithAddress::argsAsString() + forwardFilterArgsSeperator + mTemplate;
1615 }
1616 
1617 const TQString KMFilterActionForward::displayString() const
1618 {
1619  if ( mTemplate.isEmpty() )
1620  return i18n( "Forward to %1 with default template " ).arg( mParameter );
1621  else
1622  return i18n( "Forward to %1 with template %2" ).arg( mParameter, mTemplate );
1623 }
1624 
1625 //=============================================================================
1626 // KMFilterActionRedirect - redirect to
1627 // Redirect message to another user
1628 //=============================================================================
1629 class KMFilterActionRedirect: public KMFilterActionWithAddress
1630 {
1631 public:
1632  KMFilterActionRedirect();
1633  virtual ReturnCode process(KMMessage* msg) const;
1634  static KMFilterAction* newAction(void);
1635 };
1636 
1637 KMFilterAction* KMFilterActionRedirect::newAction(void)
1638 {
1639  return (new KMFilterActionRedirect);
1640 }
1641 
1642 KMFilterActionRedirect::KMFilterActionRedirect()
1643  : KMFilterActionWithAddress( "redirect", i18n("Redirect To") )
1644 {
1645 }
1646 
1647 KMFilterAction::ReturnCode KMFilterActionRedirect::process(KMMessage* aMsg) const
1648 {
1649  KMMessage* msg;
1650  if ( mParameter.isEmpty() )
1651  return ErrorButGoOn;
1652 
1653  msg = aMsg->createRedirect( mParameter );
1654 
1655  sendMDN( aMsg, KMime::MDN::Dispatched );
1656 
1657  if ( !kmkernel->msgSender()->send( msg, KMail::MessageSender::SendLater ) ) {
1658  kdDebug(5006) << "KMFilterAction: could not redirect message (sending failed)" << endl;
1659  return ErrorButGoOn; // error: couldn't send
1660  }
1661  return GoOn;
1662 }
1663 
1664 
1665 //=============================================================================
1666 // KMFilterActionExec - execute command
1667 // Execute a shell command
1668 //=============================================================================
1669 class KMFilterActionExec : public KMFilterActionWithCommand
1670 {
1671 public:
1672  KMFilterActionExec();
1673  virtual ReturnCode process(KMMessage* msg) const;
1674  static KMFilterAction* newAction(void);
1675 };
1676 
1677 KMFilterAction* KMFilterActionExec::newAction(void)
1678 {
1679  return (new KMFilterActionExec());
1680 }
1681 
1682 KMFilterActionExec::KMFilterActionExec()
1683  : KMFilterActionWithCommand( "execute", i18n("Execute Command") )
1684 {
1685 }
1686 
1687 KMFilterAction::ReturnCode KMFilterActionExec::process(KMMessage *aMsg) const
1688 {
1689  return KMFilterActionWithCommand::genericProcess( aMsg, false ); // ignore output
1690 }
1691 
1692 //=============================================================================
1693 // KMFilterActionExtFilter - use external filter app
1694 // External message filter: executes a shell command with message
1695 // on stdin; altered message is expected on stdout.
1696 //=============================================================================
1697 
1698 #include <weaver.h>
1699 class PipeJob : public KPIM::ThreadWeaver::Job
1700 {
1701  public:
1702  PipeJob(TQObject* parent = 0 , const char* name = 0, KMMessage* aMsg = 0, TQString cmd = 0, TQString tempFileName = 0 )
1703  : Job (parent, name),
1704  mTempFileName(tempFileName),
1705  mCmd(cmd),
1706  mMsg( aMsg )
1707  {
1708  }
1709 
1710  ~PipeJob() {}
1711  virtual void processEvent( KPIM::ThreadWeaver::Event *ev )
1712  {
1713  KPIM::ThreadWeaver::Job::processEvent( ev );
1714  if ( ev->action() == KPIM::ThreadWeaver::Event::JobFinished )
1715  deleteLater( );
1716  }
1717  protected:
1718  void run()
1719  {
1720  KPIM::ThreadWeaver::debug (1, "PipeJob::run: doing it .\n");
1721  FILE *p;
1722  TQByteArray ba;
1723 
1724  // backup the serial number in case the header gets lost
1725  TQString origSerNum = mMsg->headerField( "X-KMail-Filtered" );
1726 
1727  p = popen(TQFile::encodeName(mCmd), "r");
1728  int len =100;
1729  char buffer[100];
1730  // append data to ba:
1731  while (true) {
1732  if (! fgets( buffer, len, p ) ) break;
1733  int oldsize = ba.size();
1734  ba.resize( oldsize + strlen(buffer) );
1735  tqmemmove( ba.begin() + oldsize, buffer, strlen(buffer) );
1736  }
1737  pclose(p);
1738  if ( !ba.isEmpty() ) {
1739  KPIM::ThreadWeaver::debug (1, "PipeJob::run: %s", TQString(ba).latin1() );
1740  KMFolder *filterFolder = mMsg->parent();
1741  ActionScheduler *handler = MessageProperty::filterHandler( mMsg->getMsgSerNum() );
1742 
1743  mMsg->fromByteArray( ba );
1744  if ( !origSerNum.isEmpty() )
1745  mMsg->setHeaderField( "X-KMail-Filtered", origSerNum );
1746  if ( filterFolder && handler ) {
1747  bool oldStatus = handler->ignoreChanges( true );
1748  filterFolder->take( filterFolder->find( mMsg ) );
1749  filterFolder->addMsg( mMsg );
1750  handler->ignoreChanges( oldStatus );
1751  } else {
1752  kdDebug(5006) << "Warning: Cannot refresh the message from the external filter." << endl;
1753  }
1754  }
1755 
1756  KPIM::ThreadWeaver::debug (1, "PipeJob::run: done.\n" );
1757  // unlink the tempFile
1758  TQFile::remove(mTempFileName);
1759  }
1760  TQString mTempFileName;
1761  TQString mCmd;
1762  KMMessage *mMsg;
1763 };
1764 
1765 class KMFilterActionExtFilter: public KMFilterActionWithCommand
1766 {
1767 public:
1768  KMFilterActionExtFilter();
1769  virtual ReturnCode process(KMMessage* msg) const;
1770  virtual void processAsync(KMMessage* msg) const;
1771  static KMFilterAction* newAction(void);
1772 };
1773 
1774 KMFilterAction* KMFilterActionExtFilter::newAction(void)
1775 {
1776  return (new KMFilterActionExtFilter);
1777 }
1778 
1779 KMFilterActionExtFilter::KMFilterActionExtFilter()
1780  : KMFilterActionWithCommand( "filter app", i18n("Pipe Through") )
1781 {
1782 }
1783 KMFilterAction::ReturnCode KMFilterActionExtFilter::process(KMMessage* aMsg) const
1784 {
1785  return KMFilterActionWithCommand::genericProcess( aMsg, true ); // use output
1786 }
1787 
1788 void KMFilterActionExtFilter::processAsync(KMMessage* aMsg) const
1789 {
1790 
1791  ActionScheduler *handler = MessageProperty::filterHandler( aMsg->getMsgSerNum() );
1792  KTempFile * inFile = new KTempFile;
1793  inFile->setAutoDelete(false);
1794 
1795  TQPtrList<KTempFile> atmList;
1796  atmList.setAutoDelete(true);
1797  atmList.append( inFile );
1798 
1799  TQString commandLine = substituteCommandLineArgsFor( aMsg , atmList );
1800  if ( commandLine.isEmpty() )
1801  handler->actionMessage( ErrorButGoOn );
1802 
1803  // The parentheses force the creation of a subshell
1804  // in which the user-specified command is executed.
1805  // This is to really catch all output of the command as well
1806  // as to avoid clashes of our redirection with the ones
1807  // the user may have specified. In the long run, we
1808  // shouldn't be using tempfiles at all for this class, due
1809  // to security aspects. (mmutz)
1810  commandLine = "(" + commandLine + ") <" + inFile->name();
1811 
1812  // write message to file
1813  TQString tempFileName = inFile->name();
1814  KPIM::kCStringToFile( aMsg->asString(), tempFileName, //###
1815  false, false, false );
1816  inFile->close();
1817 
1818  PipeJob *job = new PipeJob(0, 0, aMsg, commandLine, tempFileName);
1819  TQObject::connect ( job, TQ_SIGNAL( done() ), handler, TQ_SLOT( actionMessage() ) );
1820  kmkernel->weaver()->enqueue(job);
1821 }
1822 
1823 //=============================================================================
1824 // KMFilterActionExecSound - execute command
1825 // Execute a sound
1826 //=============================================================================
1827 class KMFilterActionExecSound : public KMFilterActionWithTest
1828 {
1829 public:
1830  KMFilterActionExecSound();
1831  virtual ReturnCode process(KMMessage* msg) const;
1832  virtual bool requiresBody(KMMsgBase*) const;
1833  static KMFilterAction* newAction(void);
1834 };
1835 
1836 KMFilterActionWithTest::KMFilterActionWithTest( const char* aName, const TQString aLabel )
1837  : KMFilterAction( aName, aLabel )
1838 {
1839 }
1840 
1841 KMFilterActionWithTest::~KMFilterActionWithTest()
1842 {
1843 }
1844 
1845 TQWidget* KMFilterActionWithTest::createParamWidget( TQWidget* parent ) const
1846 {
1847  KMSoundTestWidget *le = new KMSoundTestWidget(parent);
1848  le->setUrl( mParameter );
1849  return le;
1850 }
1851 
1852 
1853 void KMFilterActionWithTest::applyParamWidgetValue( TQWidget* paramWidget )
1854 {
1855  mParameter = ((KMSoundTestWidget*)paramWidget)->url();
1856 }
1857 
1858 void KMFilterActionWithTest::setParamWidgetValue( TQWidget* paramWidget ) const
1859 {
1860  ((KMSoundTestWidget*)paramWidget)->setUrl( mParameter );
1861 }
1862 
1863 void KMFilterActionWithTest::clearParamWidget( TQWidget* paramWidget ) const
1864 {
1865  ((KMSoundTestWidget*)paramWidget)->clear();
1866 }
1867 
1868 void KMFilterActionWithTest::argsFromString( const TQString argsStr )
1869 {
1870  mParameter = argsStr;
1871 }
1872 
1873 const TQString KMFilterActionWithTest::argsAsString() const
1874 {
1875  return mParameter;
1876 }
1877 
1878 const TQString KMFilterActionWithTest::displayString() const
1879 {
1880  // FIXME after string freeze:
1881  // return i18n("").arg( );
1882  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
1883 }
1884 
1885 
1886 KMFilterActionExecSound::KMFilterActionExecSound()
1887  : KMFilterActionWithTest( "play sound", i18n("Play Sound") )
1888 {
1889 }
1890 
1891 KMFilterAction* KMFilterActionExecSound::newAction(void)
1892 {
1893  return (new KMFilterActionExecSound());
1894 }
1895 
1896 KMFilterAction::ReturnCode KMFilterActionExecSound::process(KMMessage*) const
1897 {
1898  if ( mParameter.isEmpty() )
1899  return ErrorButGoOn;
1900  TQString play = mParameter;
1901  TQString file = TQString::fromLatin1("file:");
1902  if (mParameter.startsWith(file))
1903  play = mParameter.mid(file.length());
1904  KAudioPlayer::play(TQFile::encodeName(play));
1905  return GoOn;
1906 }
1907 
1908 bool KMFilterActionExecSound::requiresBody(KMMsgBase*) const
1909 {
1910  return false;
1911 }
1912 
1913 KMFilterActionWithUrl::KMFilterActionWithUrl( const char* aName, const TQString aLabel )
1914  : KMFilterAction( aName, aLabel )
1915 {
1916 }
1917 
1918 KMFilterActionWithUrl::~KMFilterActionWithUrl()
1919 {
1920 }
1921 
1922 TQWidget* KMFilterActionWithUrl::createParamWidget( TQWidget* parent ) const
1923 {
1924  KURLRequester *le = new KURLRequester(parent);
1925  le->setURL( mParameter );
1926  return le;
1927 }
1928 
1929 
1931 {
1932  mParameter = ((KURLRequester*)paramWidget)->url();
1933 }
1934 
1935 void KMFilterActionWithUrl::setParamWidgetValue( TQWidget* paramWidget ) const
1936 {
1937  ((KURLRequester*)paramWidget)->setURL( mParameter );
1938 }
1939 
1940 void KMFilterActionWithUrl::clearParamWidget( TQWidget* paramWidget ) const
1941 {
1942  ((KURLRequester*)paramWidget)->clear();
1943 }
1944 
1945 void KMFilterActionWithUrl::argsFromString( const TQString argsStr )
1946 {
1947  mParameter = argsStr;
1948 }
1949 
1951 {
1952  return mParameter;
1953 }
1954 
1956 {
1957  // FIXME after string freeze:
1958  // return i18n("").arg( );
1959  return label() + " \"" + TQStyleSheet::escape( argsAsString() ) + "\"";
1960 }
1961 
1962 
1963 //=============================================================================
1964 //
1965 // Filter Action Dictionary
1966 //
1967 //=============================================================================
1969 {
1970  insert( KMFilterActionMove::newAction );
1971  insert( KMFilterActionCopy::newAction );
1972  insert( KMFilterActionIdentity::newAction );
1973  insert( KMFilterActionSeStatus::newAction );
1974  insert( KMFilterActionFakeDisposition::newAction );
1975  insert( KMFilterActionTransport::newAction );
1976  insert( KMFilterActionReplyTo::newAction );
1977  insert( KMFilterActionForward::newAction );
1978  insert( KMFilterActionRedirect::newAction );
1979  insert( KMFilterActionSendReceipt::newAction );
1980  insert( KMFilterActionExec::newAction );
1981  insert( KMFilterActionExtFilter::newAction );
1982  insert( KMFilterActionRemoveHeader::newAction );
1983  insert( KMFilterActionAddHeader::newAction );
1984  insert( KMFilterActionRewriteHeader::newAction );
1985  insert( KMFilterActionExecSound::newAction );
1986  // Register custom filter actions below this line.
1987 }
1988 // The int in the TQDict constructor (41) must be a prime
1989 // and should be greater than the double number of KMFilterAction types
1990 KMFilterActionDict::KMFilterActionDict()
1991  : TQDict<KMFilterActionDesc>(41)
1992 {
1993  mList.setAutoDelete(true);
1994  init();
1995 }
1996 
1997 void KMFilterActionDict::insert( KMFilterActionNewFunc aNewFunc )
1998 {
1999  KMFilterAction *action = aNewFunc();
2001  desc->name = action->name();
2002  desc->label = action->label();
2003  desc->create = aNewFunc;
2004  TQDict<KMFilterActionDesc>::insert( desc->name, desc );
2005  TQDict<KMFilterActionDesc>::insert( desc->label, desc );
2006  mList.append( desc );
2007  delete action;
2008 }
void insert(KMFilterActionNewFunc aNewFunc)
Overloaded member function, provided for convenience.
virtual void init(void)
Populate the dictionary with all known KMFilterAction types.
Abstract base class for KMail's filter actions that need a mail address as parameter,...
virtual void clearParamWidget(TQWidget *paramWidget) const
The filter action shall clear it's parameter widget's contents.
virtual void applyParamWidgetValue(TQWidget *paramWidget)
The filter action shall set it's parameter from the widget's contents.
virtual TQWidget * createParamWidget(TQWidget *parent) const
Creates a widget for setting the filter action parameter.
KMFilterActionWithAddress(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName.
virtual void setParamWidgetValue(TQWidget *paramWidget) const
The filter action shall set it's widget's contents from it's parameter.
Abstract base class for KMail's filter actions that need a mail folder as parameter,...
virtual TQWidget * createParamWidget(TQWidget *parent) const
Creates a widget for setting the filter action parameter.
virtual void argsFromString(const TQString argsStr)
Read extra arguments from given string.
KMFilterActionWithFolder(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName.
virtual const TQString displayString() const
Returns a translated string describing this filter for visualization purposes, e.g.
virtual void setParamWidgetValue(TQWidget *paramWidget) const
The filter action shall set it's widget's contents from it's parameter.
virtual const TQString argsAsString() const
Return extra arguments as string.
virtual bool folderRemoved(KMFolder *aFolder, KMFolder *aNewFolder)
Called from the filter when a folder is removed.
virtual void clearParamWidget(TQWidget *paramWidget) const
The filter action shall clear it's parameter widget's contents.
virtual void applyParamWidgetValue(TQWidget *paramWidget)
The filter action shall set it's parameter from the widget's contents.
Abstract base class for KMail's filter actions that need no parameter, e.g.
virtual const TQString displayString() const
Returns a translated string describing this filter for visualization purposes, e.g.
KMFilterActionWithNone(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName.
Abstract base class for KMail's filter actions that need a parameter which can be chosen from a fixed...
virtual void applyParamWidgetValue(TQWidget *paramWidget)
The filter action shall set it's parameter from the widget's contents.
virtual void setParamWidgetValue(TQWidget *paramWidget) const
The filter action shall set it's widget's contents from it's parameter.
virtual void argsFromString(const TQString argsStr)
Read extra arguments from given string.
virtual TQWidget * createParamWidget(TQWidget *parent) const
Creates a widget for setting the filter action parameter.
KMFilterActionWithStringList(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName.
virtual void clearParamWidget(TQWidget *paramWidget) const
The filter action shall clear it's parameter widget's contents.
Abstract base class for KMail's filter actions that need a free-form parameter, e....
virtual void setParamWidgetValue(TQWidget *paramWidget) const
The filter action shall set it's widget's contents from it's parameter.
virtual TQWidget * createParamWidget(TQWidget *parent) const
Creates a widget for setting the filter action parameter.
virtual void clearParamWidget(TQWidget *paramWidget) const
The filter action shall clear it's parameter widget's contents.
virtual bool isEmpty() const
Determines whether this action is valid.
virtual const TQString displayString() const
Returns a translated string describing this filter for visualization purposes, e.g.
virtual const TQString argsAsString() const
Return extra arguments as string.
KMFilterActionWithString(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName.
virtual void applyParamWidgetValue(TQWidget *paramWidget)
The filter action shall set it's parameter from the widget's contents.
virtual void argsFromString(const TQString argsStr)
Read extra arguments from given string.
Abstract base class for KMail's filter actions that need a parameter that has a UOID,...
virtual const TQString argsAsString() const
Return extra arguments as string.
virtual const TQString displayString() const
Returns a translated string describing this filter for visualization purposes, e.g.
KMFilterActionWithUOID(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName.
virtual void argsFromString(const TQString argsStr)
Read extra arguments from given string.
Abstract base class for KMail's filter actions that need a command line as parameter,...
virtual void setParamWidgetValue(TQWidget *paramWidget) const
The filter action shall set it's widget's contents from it's parameter.
virtual const TQString displayString() const
Returns a translated string describing this filter for visualization purposes, e.g.
virtual TQWidget * createParamWidget(TQWidget *parent) const
Creates a widget for setting the filter action parameter.
virtual const TQString argsAsString() const
Return extra arguments as string.
virtual void applyParamWidgetValue(TQWidget *paramWidget)
The filter action shall set it's parameter from the widget's contents.
virtual void argsFromString(const TQString argsStr)
Read extra arguments from given string.
KMFilterActionWithUrl(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName.
virtual void clearParamWidget(TQWidget *paramWidget) const
The filter action shall clear it's parameter widget's contents.
Abstract base class for KMail's filter actions.
virtual TQWidget * createParamWidget(TQWidget *parent) const
Creates a widget for setting the filter action parameter.
virtual void setParamWidgetValue(TQWidget *paramWidget) const
The filter action shall set it's widget's contents from it's parameter.
ReturnCode
Possible return codes of process:
static KMFilterAction * newAction()
Static function that creates a filter action of this type.
virtual void clearParamWidget(TQWidget *paramWidget) const
The filter action shall clear it's parameter widget's contents.
virtual ReturnCode process(KMMessage *msg) const =0
Execute action on given message.
const TQString name() const
Returns english name, ie.
virtual void applyParamWidgetValue(TQWidget *paramWidget)
The filter action shall set it's parameter from the widget's contents.
virtual bool folderRemoved(KMFolder *aFolder, KMFolder *aNewFolder)
Called from the filter when a folder is removed.
KMFilterAction(const char *aName, const TQString aLabel)
Initialize filter action with (english) name aName and (internationalized) label aLabel.
static void sendMDN(KMMessage *msg, KMime::MDN::DispositionType d, const TQValueList< KMime::MDN::DispositionModifier > &m=TQValueList< KMime::MDN::DispositionModifier >())
Automates the sending of MDNs from filter actions.
virtual bool requiresBody(KMMsgBase *msgBase) const
Determines if the action depends on the body of the message.
virtual void processAsync(KMMessage *msg) const
Execute an action on given message asynchronously.
const TQString label() const
Returns nationalized label, ie.
static int tempOpenFolder(KMFolder *aFolder)
Temporarily open folder.
Mail folder.
Definition: kmfolder.h:69
int addMsg(KMMessage *msg, int *index_return=0)
Add the given message to the folder.
Definition: kmfolder.cpp:390
KMMessage * take(int idx)
Detach message from this folder.
Definition: kmfolder.cpp:380
int find(const KMMsgBase *msg) const
Returns the index of the given message or -1 if not found.
Definition: kmfolder.cpp:435
This is a Mime Message.
Definition: kmmessage.h:68
static void bodyPart(DwBodyPart *aDwBodyPart, KMMessagePart *aPart, bool withBody=true)
Fill the KMMessagePart structure for a given DwBodyPart.
Definition: kmmessage.cpp:3108
TQString from() const
Get or set the 'From' header field.
Definition: kmmessage.cpp:2015
void setStatus(const KMMsgStatus status, int idx=-1)
Set status and mark dirty.
Definition: kmmessage.cpp:4153
static bool addressIsInAddressList(const TQString &address, const TQStringList &addresses)
Returns true if the given address is contained in the given address list.
Definition: kmmessage.cpp:3937
TQString to() const
Get or set the 'To' header field.
Definition: kmmessage.cpp:1894
KMMessage * createForward(const TQString &tmpl=TQString())
Create a new message that is a forward of this message, filling all required header fields with the p...
Definition: kmmessage.cpp:1229
void removeHeaderField(const TQCString &name)
Remove header field with given name.
Definition: kmmessage.cpp:2317
TQCString asString() const
Return the entire message contents as a string.
Definition: kmmessage.cpp:314
KMMessage * createRedirect(const TQString &toStr)
Create a new message that is a redirect to this message, filling all required header fields with the ...
Definition: kmmessage.cpp:1131
KMMessage * createMDN(KMime::MDN::ActionMode a, KMime::MDN::DispositionType d, bool allowGUI=false, TQValueList< KMime::MDN::DispositionModifier > m=TQValueList< KMime::MDN::DispositionModifier >())
Create a new message that is a MDN for this message, filling all required fields with proper values.
Definition: kmmessage.cpp:1395
TQString headerField(const TQCString &name) const
Returns the value of a header field with the given name.
Definition: kmmessage.cpp:2289
int numBodyParts() const
Number of body parts the message has.
Definition: kmmessage.cpp:2806
KMMessage * createDeliveryReceipt() const
Create a new message that is a delivery receipt of this message, filling required header fileds with ...
Definition: kmmessage.cpp:1635
void setHeaderField(const TQCString &name, const TQString &value, HeaderFieldType type=Unstructured, bool prepend=false)
Set the header field with the given name to the given value.
Definition: kmmessage.cpp:2339
A widget that contains a KLineEdit which shows the current folder and a button that fires a KMFolderS...
Auxiliary struct to KMFilterActionDict.