3 #include "kmfilteraction.h"
5 // other KMail headers:
6 #include "kmcommands.h"
7 #include "kmfiltermgr.h"
8 #include "kmmainwidget.h"
9 #include "folderrequester.h"
10 #include "kmsoundtestwidget.h"
13 using KMail::FolderRequester
;
14 #include "messageproperty.h"
15 using KMail::MessageProperty
;
16 #include "regexplineedit.h"
17 using KMail::RegExpLineEdit
;
18 #include "stringutil.h"
21 #include "messagecore/stringutil.h"
22 #include "messagecore/messagehelpers.h"
24 #include "messagecore/kmfawidgets.h"
26 #include "messagecomposer/messagesender.h"
27 #include "messagecomposer/messagefactory.h"
28 using MessageComposer::MessageFactory
;
30 #include "templateparser/customtemplates.h"
31 #include "templateparser/customtemplates_kfg.h"
33 #include "libkdepim/addcontactjob.h"
35 // KDE PIM libs headers
36 #include <kpimidentities/identity.h>
37 #include <kpimidentities/identitymanager.h>
38 #include <kpimidentities/identitycombo.h>
39 #include <kpimutils/kfileio.h>
40 #include <kpimutils/email.h>
41 #include <akonadi/itemcopyjob.h>
42 #include <akonadi/itemmodifyjob.h>
43 #include <kmime/kmime_message.h>
46 #include <akonadi/collectioncombobox.h>
47 #include <kabc/addressee.h>
48 #include <kcombobox.h>
49 #include <ktemporaryfile.h>
52 #include <kurlrequester.h>
53 #include <phonon/mediaobject.h>
56 #include <nepomuk/tag.h>
63 #include "mdnadvicedialog.h"
64 #include "mdnadvicedialog.h"
65 #include <mdnstateattribute.h>
67 //=============================================================================
71 //=============================================================================
73 KMFilterAction::KMFilterAction( const char* aName
, const QString
&aLabel
)
79 KMFilterAction::~KMFilterAction()
83 bool KMFilterAction::requiresBody() const
88 KMFilterAction
* KMFilterAction::newAction()
93 QWidget
* KMFilterAction::createParamWidget(QWidget
* parent
) const
95 return new QWidget(parent
);
98 void KMFilterAction::applyParamWidgetValue(QWidget
*)
102 void KMFilterAction::setParamWidgetValue( QWidget
* ) const
106 void KMFilterAction::clearParamWidget( QWidget
* ) const
110 bool KMFilterAction::folderRemoved(const Akonadi::Collection
&, const Akonadi::Collection
&)
115 void KMFilterAction::sendMDN( Akonadi::Item item
, KMime::MDN::DispositionType d
,
116 const QList
<KMime::MDN::DispositionModifier
> & m
) {
117 KMime::Message::Ptr msg
= MessageCore::Util::message( item
);
120 QPair
< bool, KMime::MDN::SendingMode
> mdnSend
= MDNAdviceHelper::instance()->checkAndSetMDNInfo( item
, d
);
121 if( mdnSend
.first
) {
122 KConfigGroup
mdnConfig( KMKernel::config(), "MDN" );
123 int quote
= mdnConfig
.readEntry
<int>( "quote-message", 0 );
124 MessageFactory
factory( msg
, Akonadi::Item().id() );
125 factory
.setIdentityManager( KMKernel::self()->identityManager() );
126 KMime::Message::Ptr mdn
= factory
.createMDN( KMime::MDN::AutomaticAction
, d
, mdnSend
.second
, quote
, m
);
128 if( !kmkernel
->msgSender()->send( mdn
, MessageSender::SendLater
) ) {
129 kDebug() << "Sending failed.";
136 //=============================================================================
138 // KMFilterActionWithNone
140 //=============================================================================
142 KMFilterActionWithNone::KMFilterActionWithNone( const char* aName
, const QString
&aLabel
)
143 : KMFilterAction( aName
, aLabel
)
147 const QString
KMFilterActionWithNone::displayString() const
153 //=============================================================================
155 // KMFilterActionWithUOID
157 //=============================================================================
159 KMFilterActionWithUOID::KMFilterActionWithUOID( const char* aName
, const QString
&aLabel
)
160 : KMFilterAction( aName
, aLabel
), mParameter( 0 )
164 void KMFilterActionWithUOID::argsFromString( const QString
&argsStr
)
166 mParameter
= argsStr
.trimmed().toUInt();
169 const QString
KMFilterActionWithUOID::argsAsString() const
171 return QString::number( mParameter
);
174 const QString
KMFilterActionWithUOID::displayString() const
176 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
180 //=============================================================================
182 // KMFilterActionWithString
184 //=============================================================================
186 KMFilterActionWithString::KMFilterActionWithString( const char* aName
, const QString
&aLabel
)
187 : KMFilterAction( aName
, aLabel
)
191 QWidget
* KMFilterActionWithString::createParamWidget( QWidget
* parent
) const
193 KLineEdit
*le
= new KLineEdit(parent
);
194 le
->setClearButtonShown( true );
195 le
->setText( mParameter
);
199 void KMFilterActionWithString::applyParamWidgetValue( QWidget
* paramWidget
)
201 mParameter
= ((KLineEdit
*)paramWidget
)->text();
204 void KMFilterActionWithString::setParamWidgetValue( QWidget
* paramWidget
) const
206 ((KLineEdit
*)paramWidget
)->setText( mParameter
);
209 void KMFilterActionWithString::clearParamWidget( QWidget
* paramWidget
) const
211 ((KLineEdit
*)paramWidget
)->clear();
214 void KMFilterActionWithString::argsFromString( const QString
&argsStr
)
216 mParameter
= argsStr
;
219 const QString
KMFilterActionWithString::argsAsString() const
224 const QString
KMFilterActionWithString::displayString() const
226 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
229 //=============================================================================
231 // class KMFilterActionWithStringList
233 //=============================================================================
235 KMFilterActionWithStringList::KMFilterActionWithStringList( const char* aName
, const QString
&aLabel
)
236 : KMFilterActionWithString( aName
, aLabel
)
240 QWidget
* KMFilterActionWithStringList::createParamWidget( QWidget
* parent
) const
242 KComboBox
*cb
= new KComboBox( parent
);
243 cb
->setEditable( false );
244 cb
->addItems( mParameterList
);
245 setParamWidgetValue( cb
);
249 void KMFilterActionWithStringList::applyParamWidgetValue( QWidget
* paramWidget
)
251 mParameter
= ((KComboBox
*)paramWidget
)->currentText();
254 void KMFilterActionWithStringList::setParamWidgetValue( QWidget
* paramWidget
) const
256 const int idx
= mParameterList
.indexOf( mParameter
);
257 ((KComboBox
*)paramWidget
)->setCurrentIndex( idx
>= 0 ? idx
: 0 );
260 void KMFilterActionWithStringList::clearParamWidget( QWidget
* paramWidget
) const
262 ((KComboBox
*)paramWidget
)->setCurrentIndex(0);
265 void KMFilterActionWithStringList::argsFromString( const QString
&argsStr
)
267 int idx
= mParameterList
.indexOf( argsStr
);
269 mParameterList
.append( argsStr
);
270 idx
= mParameterList
.count() - 1;
272 mParameter
= mParameterList
.at( idx
);
276 //=============================================================================
278 // class KMFilterActionWithFolder
280 //=============================================================================
282 KMFilterActionWithFolder::KMFilterActionWithFolder( const char* aName
, const QString
&aLabel
)
283 : KMFilterAction( aName
, aLabel
)
287 QWidget
* KMFilterActionWithFolder::createParamWidget( QWidget
* parent
) const
289 FolderRequester
*req
= new FolderRequester( parent
);
290 req
->setShowOutbox( false );
291 setParamWidgetValue( req
);
295 void KMFilterActionWithFolder::applyParamWidgetValue( QWidget
* paramWidget
)
297 mFolder
= ((FolderRequester
*)paramWidget
)->folderCollection();
298 mFolderName
= ((FolderRequester
*)paramWidget
)->folderId();
301 void KMFilterActionWithFolder::setParamWidgetValue( QWidget
* paramWidget
) const
303 if ( mFolder
.isValid() )
304 ((FolderRequester
*)paramWidget
)->setFolder( mFolder
);
306 ((FolderRequester
*)paramWidget
)->setFolder( mFolderName
);
309 void KMFilterActionWithFolder::clearParamWidget( QWidget
* paramWidget
) const
311 ((FolderRequester
*)paramWidget
)->setFolder( kmkernel
->draftsCollectionFolder() );
314 void KMFilterActionWithFolder::argsFromString( const QString
&argsStr
)
316 mFolder
= kmkernel
->collectionFromId( argsStr
);
317 if ( mFolder
.isValid() )
318 mFolderName
= QString::number(mFolder
.id());
320 mFolderName
= argsStr
;
323 const QString
KMFilterActionWithFolder::argsAsString() const
326 if ( mFolder
.isValid() )
327 result
= QString::number(mFolder
.id());
329 result
= mFolderName
;
333 const QString
KMFilterActionWithFolder::displayString() const
336 if ( mFolder
.isValid() )
337 result
= mFolder
.url().path();
339 result
= mFolderName
;
340 return label() + " \"" + Qt::escape( result
) + "\"";
343 bool KMFilterActionWithFolder::folderRemoved( const Akonadi::Collection
& aFolder
, const Akonadi::Collection
& aNewFolder
)
345 if ( aFolder
== mFolder
) {
346 mFolder
= aNewFolder
;
347 if ( aNewFolder
.isValid() )
348 mFolderName
= mFolder
.id();
354 //=============================================================================
356 // class KMFilterActionWithAddress
358 //=============================================================================
360 KMFilterActionWithAddress::KMFilterActionWithAddress( const char* aName
, const QString
&aLabel
)
361 : KMFilterActionWithString( aName
, aLabel
)
365 QWidget
* KMFilterActionWithAddress::createParamWidget( QWidget
* parent
) const
367 KMFilterActionWithAddressWidget
*w
= new KMFilterActionWithAddressWidget(parent
);
368 w
->setText( mParameter
);
372 void KMFilterActionWithAddress::applyParamWidgetValue( QWidget
* paramWidget
)
374 mParameter
= ((KMFilterActionWithAddressWidget
*)paramWidget
)->text();
377 void KMFilterActionWithAddress::setParamWidgetValue( QWidget
* paramWidget
) const
379 ((KMFilterActionWithAddressWidget
*)paramWidget
)->setText( mParameter
);
382 void KMFilterActionWithAddress::clearParamWidget( QWidget
* paramWidget
) const
384 ((KMFilterActionWithAddressWidget
*)paramWidget
)->clear();
387 //=============================================================================
389 // class KMFilterActionWithCommand
391 //=============================================================================
393 KMFilterActionWithCommand::KMFilterActionWithCommand( const char* aName
, const QString
&aLabel
)
394 : KMFilterActionWithUrl( aName
, aLabel
)
398 QWidget
* KMFilterActionWithCommand::createParamWidget( QWidget
* parent
) const
400 return KMFilterActionWithUrl::createParamWidget( parent
);
403 void KMFilterActionWithCommand::applyParamWidgetValue( QWidget
* paramWidget
)
405 KMFilterActionWithUrl::applyParamWidgetValue( paramWidget
);
408 void KMFilterActionWithCommand::setParamWidgetValue( QWidget
* paramWidget
) const
410 KMFilterActionWithUrl::setParamWidgetValue( paramWidget
);
413 void KMFilterActionWithCommand::clearParamWidget( QWidget
* paramWidget
) const
415 KMFilterActionWithUrl::clearParamWidget( paramWidget
);
418 static KMime::Content
* findMimeNodeForIndex( KMime::Content
* node
, int &index
)
422 foreach ( KMime::Content
* child
, node
->contents() ) {
423 KMime::Content
*result
= findMimeNodeForIndex( child
, --index
);
430 QString
KMFilterActionWithCommand::substituteCommandLineArgsFor( const KMime::Message::Ptr
&aMsg
, QList
<KTemporaryFile
*> & aTempFileList
) const
432 QString result
= mParameter
;
434 QRegExp
r( "%[0-9-]+" );
438 while ( ( start
= r
.indexIn( result
, start
+ 1 ) ) > 0 ) {
439 int len
= r
.matchedLength();
440 // and save the encountered 'n' in a list.
442 int n
= result
.mid( start
+ 1, len
- 1 ).toInt( &OK
);
447 // sort the list of n's
450 // and use QString::arg to substitute filenames for the %n's.
452 QString tempFileName
;
453 for ( QList
<int>::Iterator it
= argList
.begin() ; it
!= argList
.end() ; ++it
) {
454 // setup temp files with check for duplicate %n's
455 if ( (*it
) != lastSeen
) {
456 KTemporaryFile
*tf
= new KTemporaryFile();
459 kDebug() << "KMFilterActionWithCommand: Could not create temp file!";
462 aTempFileList
.append( tf
);
463 tempFileName
= tf
->fileName();
465 KPIMUtils::kByteArrayToFile( aMsg
->encodedContent(), tempFileName
, //###
466 false, false, false );
467 else if (aMsg
->contents().size() == 0)
468 KPIMUtils::kByteArrayToFile( aMsg
->decodedContent(), tempFileName
,
469 false, false, false );
471 int index
= *it
; // we pass by reference below, so this is not const
472 KMime::Content
*content
= findMimeNodeForIndex( aMsg
.get(), index
);
474 KPIMUtils::kByteArrayToFile( content
->decodedContent(), tempFileName
,
475 false, false, false );
480 // QString( "%0 and %1 and %1" ).arg( 0 ).arg( 1 )
481 // returns "0 and 1 and %1", so we must call .arg as
482 // many times as there are %n's, regardless of their multiplicity.
483 if ((*it
) == -1) result
.replace( "%-1", tempFileName
);
484 else result
= result
.arg( tempFileName
);
487 // And finally, replace the %{foo} with the content of the foo
489 QRegExp
header_rx( "%\\{([a-z0-9-]+)\\}", Qt::CaseInsensitive
);
491 while ( ( idx
= header_rx
.indexIn( result
, idx
) ) != -1 ) {
492 QString replacement
= KShell::quoteArg( aMsg
->headerByType( header_rx
.cap(1).toLatin1() ) ? aMsg
->headerByType( header_rx
.cap(1).toLatin1() )->as7BitString(): "");
493 result
.replace( idx
, header_rx
.matchedLength(), replacement
);
494 idx
+= replacement
.length();
501 KMFilterAction::ReturnCode
KMFilterActionWithCommand::genericProcess( const Akonadi::Item
&item
, bool withOutput
) const
503 const KMime::Message::Ptr aMsg
= item
.payload
<KMime::Message::Ptr
>();
506 if ( mParameter
.isEmpty() )
509 // KProcess doesn't support a QProcess::launch() equivalent, so
510 // we must use a temp file :-(
511 KTemporaryFile
* inFile
= new KTemporaryFile
;
512 if ( !inFile
->open() )
515 QList
<KTemporaryFile
*> atmList
;
516 atmList
.append( inFile
);
518 QString commandLine
= substituteCommandLineArgsFor( aMsg
, atmList
);
519 if ( commandLine
.isEmpty() )
521 qDeleteAll( atmList
);
525 // The parentheses force the creation of a subshell
526 // in which the user-specified command is executed.
527 // This is to really catch all output of the command as well
528 // as to avoid clashes of our redirection with the ones
529 // the user may have specified. In the long run, we
530 // shouldn't be using tempfiles at all for this class, due
531 // to security aspects. (mmutz)
532 commandLine
= '(' + commandLine
+ ") <" + inFile
->fileName();
534 // write message to file
535 QString tempFileName
= inFile
->fileName();
536 if ( !KPIMUtils::kByteArrayToFile( aMsg
->encodedContent(), tempFileName
, //###
537 false, false, false ) ) {
538 qDeleteAll( atmList
);
540 return CriticalError
;
545 shProc
.setOutputChannelMode( KProcess::SeparateChannels
);
546 shProc
.setShellCommand( commandLine
);
547 int result
= shProc
.execute();
550 qDeleteAll( atmList
);
556 // read altered message:
557 QByteArray msgText
= shProc
.readAllStandardOutput();
559 if ( !msgText
.isEmpty() ) {
560 /* If the pipe through alters the message, it could very well
561 happen that it no longer has a X-UID header afterwards. That is
562 unfortunate, as we need to removed the original from the folder
563 using that, and look it up in the message. When the (new) message
564 is uploaded, the header is stripped anyhow. */
565 QString uid
= aMsg
->headerByType( "X-UID" ) ?aMsg
->headerByType( "X-UID")->asUnicodeString() : "" ;
566 aMsg
->setContent( msgText
);
568 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "X-UID", aMsg
.get(), uid
, "utf-8" );
569 aMsg
->setHeader( header
);
572 qDeleteAll( atmList
);
577 qDeleteAll( atmList
);
583 //=============================================================================
585 // Specific Filter Actions
587 //=============================================================================
589 //=============================================================================
590 // KMFilterActionSendReceipt - send receipt
591 // Return delivery receipt.
592 //=============================================================================
593 class KMFilterActionSendReceipt
: public KMFilterActionWithNone
596 KMFilterActionSendReceipt();
597 virtual ReturnCode
process( Akonadi::Item item
) const;
598 static KMFilterAction
* newAction(void);
601 KMFilterAction
* KMFilterActionSendReceipt::newAction(void)
603 return (new KMFilterActionSendReceipt
);
606 KMFilterActionSendReceipt::KMFilterActionSendReceipt()
607 : KMFilterActionWithNone( "confirm delivery", i18n("Confirm Delivery") )
611 KMFilterAction::ReturnCode
KMFilterActionSendReceipt::process( Akonadi::Item item
) const
613 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
614 MessageFactory
factory( msg
, item
.id() );
615 factory
.setFolderIdentity( KMail::Util::folderIdentity( item
) );
616 factory
.setIdentityManager( KMKernel::self()->identityManager() );
617 const KMime::Message::Ptr receipt
= factory
.createDeliveryReceipt();
618 if ( !receipt
) return ErrorButGoOn
;
620 // Queue message. This is a) so that the user can check
621 // the receipt before sending and b) for speed reasons.
622 kmkernel
->msgSender()->send( receipt
, MessageSender::SendLater
);
629 //=============================================================================
630 // KMFilterActionSetTransport - set transport to...
631 // Specify mail transport (smtp server) to be used when replying to a message
632 // TODO: use TransportComboBox so the user does not enter an invalid transport
633 //=============================================================================
634 class KMFilterActionTransport
: public KMFilterActionWithString
637 KMFilterActionTransport();
638 virtual ReturnCode
process( Akonadi::Item item
) const;
639 static KMFilterAction
* newAction(void);
642 KMFilterAction
* KMFilterActionTransport::newAction(void)
644 return (new KMFilterActionTransport
);
647 KMFilterActionTransport::KMFilterActionTransport()
648 : KMFilterActionWithString( "set transport", i18n("Set Transport To") )
652 KMFilterAction::ReturnCode
KMFilterActionTransport::process( Akonadi::Item item
) const
654 if ( mParameter
.isEmpty() )
656 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
657 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "X-KMail-Transport", msg
.get(), mParameter
, "utf-8");
658 msg
->setHeader( header
);
661 new Akonadi::ItemModifyJob( item
, kmkernel
->filterMgr() );
666 //=============================================================================
667 // KMFilterActionReplyTo - set Reply-To to
668 // Set the Reply-to header in a message
669 //=============================================================================
670 class KMFilterActionReplyTo
: public KMFilterActionWithString
673 KMFilterActionReplyTo();
674 virtual ReturnCode
process( Akonadi::Item item
) const;
675 static KMFilterAction
* newAction(void);
678 KMFilterAction
* KMFilterActionReplyTo::newAction(void)
680 return (new KMFilterActionReplyTo
);
683 KMFilterActionReplyTo::KMFilterActionReplyTo()
684 : KMFilterActionWithString( "set Reply-To", i18n("Set Reply-To To") )
689 KMFilterAction::ReturnCode
KMFilterActionReplyTo::process( Akonadi::Item item
) const
691 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
692 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "Reply-To", msg
.get(), mParameter
, "utf-8");
693 msg
->setHeader( header
);
696 new Akonadi::ItemModifyJob( item
, kmkernel
->filterMgr() );
702 //=============================================================================
703 // KMFilterActionIdentity - set identity to
704 // Specify Identity to be used when replying to a message
705 //=============================================================================
706 class KMFilterActionIdentity
: public KMFilterActionWithUOID
709 KMFilterActionIdentity();
710 virtual ReturnCode
process( Akonadi::Item item
) const;
711 static KMFilterAction
* newAction();
713 QWidget
* createParamWidget( QWidget
* parent
) const;
714 void applyParamWidgetValue( QWidget
* parent
);
715 void setParamWidgetValue( QWidget
* parent
) const;
716 void clearParamWidget( QWidget
* param
) const;
719 KMFilterAction
* KMFilterActionIdentity::newAction()
721 return (new KMFilterActionIdentity
);
724 KMFilterActionIdentity::KMFilterActionIdentity()
725 : KMFilterActionWithUOID( "set identity", i18n("Set Identity To") )
727 mParameter
= kmkernel
->identityManager()->defaultIdentity().uoid();
730 KMFilterAction::ReturnCode
KMFilterActionIdentity::process( Akonadi::Item item
) const
732 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
733 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "X-KMail-Identity", msg
.get(), QString::number(mParameter
), "utf-8");
734 msg
->setHeader( header
);
737 new Akonadi::ItemModifyJob( item
, kmkernel
->filterMgr() );
741 QWidget
* KMFilterActionIdentity::createParamWidget( QWidget
* parent
) const
743 KPIMIdentities::IdentityCombo
* ic
= new KPIMIdentities::IdentityCombo( kmkernel
->identityManager(), parent
);
744 ic
->setCurrentIdentity( mParameter
);
748 void KMFilterActionIdentity::applyParamWidgetValue( QWidget
* paramWidget
)
750 KPIMIdentities::IdentityCombo
* ic
= dynamic_cast<KPIMIdentities::IdentityCombo
*>( paramWidget
);
752 mParameter
= ic
->currentIdentity();
755 void KMFilterActionIdentity::clearParamWidget( QWidget
* paramWidget
) const
757 KPIMIdentities::IdentityCombo
* ic
= dynamic_cast<KPIMIdentities::IdentityCombo
*>( paramWidget
);
759 ic
->setCurrentIndex( 0 );
760 //ic->setCurrentIdentity( kmkernel->identityManager()->defaultIdentity() );
763 void KMFilterActionIdentity::setParamWidgetValue( QWidget
* paramWidget
) const
765 KPIMIdentities::IdentityCombo
* ic
= dynamic_cast<KPIMIdentities::IdentityCombo
*>( paramWidget
);
767 ic
->setCurrentIdentity( mParameter
);
770 //=============================================================================
771 // KMFilterActionSetStatus - set status to
772 // Set the status of messages
773 //=============================================================================
774 class KMFilterActionSetStatus
: public KMFilterActionWithStringList
777 KMFilterActionSetStatus();
778 virtual ReturnCode
process( Akonadi::Item item
) const;
779 virtual bool requiresBody() const;
781 static KMFilterAction
* newAction();
783 virtual bool isEmpty() const { return false; }
785 virtual void argsFromString( const QString
&argsStr
);
786 virtual const QString
argsAsString() const;
787 virtual const QString
displayString() const;
791 static const MessageStatus stati
[] =
793 MessageStatus::statusImportant(),
794 MessageStatus::statusRead(),
795 MessageStatus::statusUnread(),
796 MessageStatus::statusReplied(),
797 MessageStatus::statusForwarded(),
798 MessageStatus::statusWatched(),
799 MessageStatus::statusIgnored(),
800 MessageStatus::statusSpam(),
801 MessageStatus::statusHam(),
802 MessageStatus::statusToAct()
804 static const int StatiCount
= sizeof( stati
) / sizeof( MessageStatus
);
806 KMFilterAction
* KMFilterActionSetStatus::newAction()
808 return (new KMFilterActionSetStatus
);
811 KMFilterActionSetStatus::KMFilterActionSetStatus()
812 : KMFilterActionWithStringList( "set status", i18n("Mark As") )
814 // if you change this list, also update
815 // KMFilterActionSetStatus::stati above
816 mParameterList
.append( "" );
817 mParameterList
.append( i18nc("msg status","Important") );
818 mParameterList
.append( i18nc("msg status","Read") );
819 mParameterList
.append( i18nc("msg status","Unread") );
820 mParameterList
.append( i18nc("msg status","Replied") );
821 mParameterList
.append( i18nc("msg status","Forwarded") );
822 mParameterList
.append( i18nc("msg status","Watched") );
823 mParameterList
.append( i18nc("msg status","Ignored") );
824 mParameterList
.append( i18nc("msg status","Spam") );
825 mParameterList
.append( i18nc("msg status","Ham") );
826 mParameterList
.append( i18nc("msg status","Action Item") );
828 mParameter
= mParameterList
.at(0);
831 KMFilterAction::ReturnCode
KMFilterActionSetStatus::process( Akonadi::Item item
) const
833 const int idx
= mParameterList
.indexOf( mParameter
);
834 if ( idx
< 1 ) return ErrorButGoOn
;
836 Akonadi::MessageStatus status
;
837 status
.setStatusFromFlags( item
.flags() );
838 status
.set( stati
[ idx
- 1 ] );
839 Akonadi::Item
i( item
);
840 i
.setFlags( status
.statusFlags() );
841 new Akonadi::ItemModifyJob( i
, kmkernel
->filterMgr() ); // TODO handle error
845 bool KMFilterActionSetStatus::requiresBody() const
850 void KMFilterActionSetStatus::argsFromString( const QString
&argsStr
)
852 if ( argsStr
.length() == 1 ) {
853 MessageStatus status
;
855 for ( i
= 0 ; i
< StatiCount
; ++i
)
858 if ( status
.statusStr()[0] == argsStr
[0].toLatin1() ) {
859 mParameter
= mParameterList
.at(i
+1);
864 mParameter
= mParameterList
.at(0);
867 const QString
KMFilterActionSetStatus::argsAsString() const
869 const int idx
= mParameterList
.indexOf( mParameter
);
870 if ( idx
< 1 ) return QString();
872 return stati
[idx
-1].statusStr();
875 const QString
KMFilterActionSetStatus::displayString() const
877 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
880 //=============================================================================
881 // KMFilterActionAddTag - append tag to message
882 // Appends a tag to messages
883 //=============================================================================
884 class KMFilterActionAddTag
: public KMFilterActionWithStringList
887 KMFilterActionAddTag();
888 virtual ReturnCode
process( Akonadi::Item item
) const;
889 virtual bool requiresBody() const;
891 static KMFilterAction
* newAction();
893 virtual bool isEmpty() const { return false; }
895 virtual void argsFromString( const QString
&argsStr
);
896 virtual const QString
argsAsString() const;
897 virtual const QString
displayString() const;
900 QStringList mLabelList
;
903 KMFilterAction
* KMFilterActionAddTag::newAction()
905 return (new KMFilterActionAddTag
);
908 KMFilterActionAddTag::KMFilterActionAddTag()
909 : KMFilterActionWithStringList( "add tag", i18n("Add Tag") )
911 foreach( const Nepomuk::Tag
&tag
, Nepomuk::Tag::allTags() ) {
912 mParameterList
.append( tag
.label() );
913 mLabelList
.append( tag
.resourceUri().toString() );
917 KMFilterAction::ReturnCode
KMFilterActionAddTag::process( Akonadi::Item item
) const
919 const int idx
= mParameterList
.indexOf( mParameter
);
920 if ( idx
== -1 ) return ErrorButGoOn
;
922 Nepomuk::Resource
n_resource( item
.url() );
923 n_resource
.addTag( mParameter
);
927 bool KMFilterActionAddTag::requiresBody() const
932 void KMFilterActionAddTag::argsFromString( const QString
&argsStr
)
934 foreach ( const QString
& tag
, mParameterList
) {
935 if ( tag
== argsStr
) {
940 if ( mParameterList
.size() > 0 )
941 mParameter
= mParameterList
.at( 0 );
944 const QString
KMFilterActionAddTag::argsAsString() const
946 const int idx
= mParameterList
.indexOf( mParameter
);
947 if ( idx
== -1 ) return QString();
949 return mParameterList
.at( idx
);
952 const QString
KMFilterActionAddTag::displayString() const
954 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
957 //=============================================================================
958 // KMFilterActionFakeDisposition - send fake MDN
959 // Sends a fake MDN or forces an ignore.
960 //=============================================================================
961 class KMFilterActionFakeDisposition
: public KMFilterActionWithStringList
964 KMFilterActionFakeDisposition();
965 virtual ReturnCode
process( Akonadi::Item item
) const;
966 static KMFilterAction
* newAction() {
967 return (new KMFilterActionFakeDisposition
);
970 virtual bool isEmpty() const { return false; }
972 virtual void argsFromString( const QString
&argsStr
);
973 virtual const QString
argsAsString() const;
974 virtual const QString
displayString() const;
978 // if you change this list, also update
979 // the count in argsFromString
980 static const KMime::MDN::DispositionType mdns
[] =
982 KMime::MDN::Displayed
,
984 KMime::MDN::Dispatched
,
985 KMime::MDN::Processed
,
989 static const int numMDNs
= sizeof mdns
/ sizeof *mdns
;
992 KMFilterActionFakeDisposition::KMFilterActionFakeDisposition()
993 : KMFilterActionWithStringList( "fake mdn", i18n("Send Fake MDN") )
995 // if you change this list, also update
997 mParameterList
.append( "" );
998 mParameterList
.append( i18nc("MDN type","Ignore") );
999 mParameterList
.append( i18nc("MDN type","Displayed") );
1000 mParameterList
.append( i18nc("MDN type","Deleted") );
1001 mParameterList
.append( i18nc("MDN type","Dispatched") );
1002 mParameterList
.append( i18nc("MDN type","Processed") );
1003 mParameterList
.append( i18nc("MDN type","Denied") );
1004 mParameterList
.append( i18nc("MDN type","Failed") );
1006 mParameter
= mParameterList
.at(0);
1009 KMFilterAction::ReturnCode
KMFilterActionFakeDisposition::process( Akonadi::Item item
) const
1011 const int idx
= mParameterList
.indexOf( mParameter
);
1012 if ( idx
< 1 ) return ErrorButGoOn
;
1014 if ( idx
== 1 ) { // ignore
1015 if( item
.hasAttribute
< Akonadi::MDNStateAttribute
>() ) {
1016 item
.attribute
< Akonadi::MDNStateAttribute
>()->setMDNState( Akonadi::MDNStateAttribute::MDNIgnore
);
1017 Akonadi::ItemModifyJob
* modifyJob
= new Akonadi::ItemModifyJob( item
);
1018 modifyJob
->setIgnorePayload( true );
1021 sendMDN( item
, mdns
[idx
-2] ); // skip first two entries: "" and "ignore"
1025 void KMFilterActionFakeDisposition::argsFromString( const QString
&argsStr
)
1027 if ( argsStr
.length() == 1 ) {
1028 if ( argsStr
[0] == 'I' ) { // ignore
1029 mParameter
= mParameterList
.at(1);
1032 for ( int i
= 0 ; i
< numMDNs
; i
++ )
1033 if ( char(mdns
[i
]) == argsStr
[0] ) { // send
1034 mParameter
= mParameterList
.at(i
+2);
1038 mParameter
= mParameterList
.at(0);
1041 const QString
KMFilterActionFakeDisposition::argsAsString() const
1043 const int idx
= mParameterList
.indexOf( mParameter
);
1044 if ( idx
< 1 ) return QString();
1046 return QString( QChar( idx
< 2 ? 'I' : char(mdns
[idx
-2]) ) );
1049 const QString
KMFilterActionFakeDisposition::displayString() const
1051 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
1054 //=============================================================================
1055 // KMFilterActionRemoveHeader - remove header
1056 // Remove all instances of the given header field.
1057 //=============================================================================
1058 class KMFilterActionRemoveHeader
: public KMFilterActionWithStringList
1061 KMFilterActionRemoveHeader();
1062 virtual ReturnCode
process( Akonadi::Item item
) const;
1063 virtual QWidget
* createParamWidget( QWidget
* parent
) const;
1064 virtual void setParamWidgetValue( QWidget
* paramWidget
) const;
1066 static KMFilterAction
* newAction();
1069 KMFilterAction
* KMFilterActionRemoveHeader::newAction()
1071 return (new KMFilterActionRemoveHeader
);
1074 KMFilterActionRemoveHeader::KMFilterActionRemoveHeader()
1075 : KMFilterActionWithStringList( "remove header", i18n("Remove Header") )
1077 mParameterList
<< ""
1080 << "X-KDE-PR-Message"
1081 << "X-KDE-PR-Package"
1082 << "X-KDE-PR-Keywords";
1083 mParameter
= mParameterList
.at(0);
1086 QWidget
* KMFilterActionRemoveHeader::createParamWidget( QWidget
* parent
) const
1088 KComboBox
*cb
= new KComboBox( parent
);
1089 cb
->setEditable( true );
1090 cb
->setInsertPolicy( QComboBox::InsertAtBottom
);
1091 setParamWidgetValue( cb
);
1095 KMFilterAction::ReturnCode
KMFilterActionRemoveHeader::process( Akonadi::Item item
) const
1097 if ( mParameter
.isEmpty() ) return ErrorButGoOn
;
1099 KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1100 while ( msg
->headerByType( mParameter
.toLatin1() ) )
1101 msg
->removeHeader( mParameter
.toLatin1() );
1103 new Akonadi::ItemModifyJob( item
, kmkernel
->filterMgr() );
1107 void KMFilterActionRemoveHeader::setParamWidgetValue( QWidget
* paramWidget
) const
1109 KComboBox
* cb
= dynamic_cast<KComboBox
*>(paramWidget
);
1112 const int idx
= mParameterList
.indexOf( mParameter
);
1114 cb
->addItems( mParameterList
);
1116 cb
->addItem( mParameter
);
1117 cb
->setCurrentIndex( cb
->count() - 1 );
1119 cb
->setCurrentIndex( idx
);
1124 //=============================================================================
1125 // KMFilterActionAddHeader - add header
1126 // Add a header with the given value.
1127 //=============================================================================
1128 class KMFilterActionAddHeader
: public KMFilterActionWithStringList
1131 KMFilterActionAddHeader();
1132 virtual ReturnCode
process( Akonadi::Item item
) const;
1133 virtual QWidget
* createParamWidget( QWidget
* parent
) const;
1134 virtual void setParamWidgetValue( QWidget
* paramWidget
) const;
1135 virtual void applyParamWidgetValue( QWidget
* paramWidget
);
1136 virtual void clearParamWidget( QWidget
* paramWidget
) const;
1138 virtual const QString
argsAsString() const;
1139 virtual void argsFromString( const QString
&argsStr
);
1141 virtual const QString
displayString() const;
1143 static KMFilterAction
* newAction()
1145 return (new KMFilterActionAddHeader
);
1151 KMFilterActionAddHeader::KMFilterActionAddHeader()
1152 : KMFilterActionWithStringList( "add header", i18n("Add Header") )
1154 mParameterList
<< ""
1157 << "X-KDE-PR-Message"
1158 << "X-KDE-PR-Package"
1159 << "X-KDE-PR-Keywords";
1160 mParameter
= mParameterList
.at(0);
1163 KMFilterAction::ReturnCode
KMFilterActionAddHeader::process( Akonadi::Item item
) const
1165 if ( mParameter
.isEmpty() ) return ErrorButGoOn
;
1167 KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1168 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( mParameter
.toLatin1(), msg
.get(), mValue
, "utf-8" );
1169 msg
->setHeader( header
);
1171 new Akonadi::ItemModifyJob( item
, kmkernel
->filterMgr() );
1175 QWidget
* KMFilterActionAddHeader::createParamWidget( QWidget
* parent
) const
1177 QWidget
*w
= new QWidget( parent
);
1178 QHBoxLayout
*hbl
= new QHBoxLayout( w
);
1179 hbl
->setSpacing( 4 );
1180 hbl
->setMargin( 0 );
1181 KComboBox
*cb
= new KComboBox( w
);
1182 cb
->setObjectName( "combo" );
1183 cb
->setEditable( true );
1184 cb
->setInsertPolicy( QComboBox::InsertAtBottom
);
1185 hbl
->addWidget( cb
, 0 /* stretch */ );
1186 QLabel
*l
= new QLabel( i18n("With value:"), w
);
1187 l
->setFixedWidth( l
->sizeHint().width() );
1188 hbl
->addWidget( l
, 0 );
1189 KLineEdit
*le
= new KLineEdit( w
);
1190 le
->setObjectName( "ledit" );
1191 le
->setClearButtonShown( true );
1192 hbl
->addWidget( le
, 1 );
1193 setParamWidgetValue( w
);
1197 void KMFilterActionAddHeader::setParamWidgetValue( QWidget
* paramWidget
) const
1199 const int idx
= mParameterList
.indexOf( mParameter
);
1200 KComboBox
*cb
= paramWidget
->findChild
<KComboBox
*>("combo");
1203 cb
->addItems( mParameterList
);
1205 cb
->addItem( mParameter
);
1206 cb
->setCurrentIndex( cb
->count() - 1 );
1208 cb
->setCurrentIndex( idx
);
1210 KLineEdit
*le
= paramWidget
->findChild
<KLineEdit
*>("ledit");
1212 le
->setText( mValue
);
1215 void KMFilterActionAddHeader::applyParamWidgetValue( QWidget
* paramWidget
)
1217 KComboBox
*cb
= paramWidget
->findChild
<KComboBox
*>("combo");
1219 mParameter
= cb
->currentText();
1221 KLineEdit
*le
= paramWidget
->findChild
<KLineEdit
*>("ledit");
1223 mValue
= le
->text();
1226 void KMFilterActionAddHeader::clearParamWidget( QWidget
* paramWidget
) const
1228 KComboBox
*cb
= paramWidget
->findChild
<KComboBox
*>("combo");
1230 cb
->setCurrentIndex(0);
1231 KLineEdit
*le
= paramWidget
->findChild
<KLineEdit
*>("ledit");
1236 const QString
KMFilterActionAddHeader::argsAsString() const
1238 QString result
= mParameter
;
1245 const QString
KMFilterActionAddHeader::displayString() const
1247 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
1250 void KMFilterActionAddHeader::argsFromString( const QString
&argsStr
)
1252 const QStringList l
= argsStr
.split( '\t' );
1254 if ( l
.count() < 2 ) {
1262 int idx
= mParameterList
.indexOf( s
);
1264 mParameterList
.append( s
);
1265 idx
= mParameterList
.count() - 1;
1267 mParameter
= mParameterList
.at( idx
);
1271 //=============================================================================
1272 // KMFilterActionRewriteHeader - rewrite header
1273 // Rewrite a header using a regexp.
1274 //=============================================================================
1275 class KMFilterActionRewriteHeader
: public KMFilterActionWithStringList
1278 KMFilterActionRewriteHeader();
1279 virtual ReturnCode
process( Akonadi::Item item
) const;
1280 virtual QWidget
* createParamWidget( QWidget
* parent
) const;
1281 virtual void setParamWidgetValue( QWidget
* paramWidget
) const;
1282 virtual void applyParamWidgetValue( QWidget
* paramWidget
);
1283 virtual void clearParamWidget( QWidget
* paramWidget
) const;
1285 virtual const QString
argsAsString() const;
1286 virtual void argsFromString( const QString
&argsStr
);
1288 virtual const QString
displayString() const;
1290 static KMFilterAction
* newAction()
1292 return (new KMFilterActionRewriteHeader
);
1296 QString mReplacementString
;
1299 KMFilterActionRewriteHeader::KMFilterActionRewriteHeader()
1300 : KMFilterActionWithStringList( "rewrite header", i18n("Rewrite Header") )
1302 mParameterList
<< ""
1306 << "X-KDE-PR-Message"
1307 << "X-KDE-PR-Package"
1308 << "X-KDE-PR-Keywords";
1309 mParameter
= mParameterList
.at(0);
1312 KMFilterAction::ReturnCode
KMFilterActionRewriteHeader::process( Akonadi::Item item
) const
1314 if ( mParameter
.isEmpty() || !mRegExp
.isValid() )
1315 return ErrorButGoOn
;
1317 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1318 // QString::replace is not const.
1319 QString value
= msg
->headerByType( mParameter
.toLatin1() ) ? msg
->headerByType( mParameter
.toLatin1() )->asUnicodeString(): "";
1321 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( mParameter
.toLatin1(), msg
.get(), value
.replace( mRegExp
, mReplacementString
), "utf-8" );
1322 msg
->setHeader( header
);
1325 new Akonadi::ItemModifyJob( item
, kmkernel
->filterMgr() );
1329 QWidget
* KMFilterActionRewriteHeader::createParamWidget( QWidget
* parent
) const
1331 QWidget
*w
= new QWidget( parent
);
1332 QHBoxLayout
*hbl
= new QHBoxLayout( w
);
1333 hbl
->setSpacing( 4 );
1334 hbl
->setMargin( 0 );
1336 KComboBox
*cb
= new KComboBox( w
);
1337 cb
->setEditable( true );
1338 cb
->setObjectName( "combo" );
1339 cb
->setInsertPolicy( QComboBox::InsertAtBottom
);
1340 hbl
->addWidget( cb
, 0 /* stretch */ );
1342 QLabel
*l
= new QLabel( i18n("Replace:"), w
);
1343 l
->setFixedWidth( l
->sizeHint().width() );
1344 hbl
->addWidget( l
, 0 );
1346 RegExpLineEdit
*rele
= new RegExpLineEdit( w
);
1347 rele
->setObjectName( "search" );
1348 hbl
->addWidget( rele
, 1 );
1350 l
= new QLabel( i18n("With:"), w
);
1351 l
->setFixedWidth( l
->sizeHint().width() );
1352 hbl
->addWidget( l
, 0 );
1354 KLineEdit
*le
= new KLineEdit( w
);
1355 le
->setObjectName( "replace" );
1356 le
->setClearButtonShown( true );
1357 hbl
->addWidget( le
, 1 );
1359 setParamWidgetValue( w
);
1363 void KMFilterActionRewriteHeader::setParamWidgetValue( QWidget
* paramWidget
) const
1365 const int idx
= mParameterList
.indexOf( mParameter
);
1366 KComboBox
*cb
= paramWidget
->findChild
<KComboBox
*>("combo");
1370 cb
->addItems( mParameterList
);
1372 cb
->addItem( mParameter
);
1373 cb
->setCurrentIndex( cb
->count() - 1 );
1375 cb
->setCurrentIndex( idx
);
1378 RegExpLineEdit
*rele
= paramWidget
->findChild
<RegExpLineEdit
*>("search");
1380 rele
->setText( mRegExp
.pattern() );
1382 KLineEdit
*le
= paramWidget
->findChild
<KLineEdit
*>("replace");
1384 le
->setText( mReplacementString
);
1387 void KMFilterActionRewriteHeader::applyParamWidgetValue( QWidget
* paramWidget
)
1389 KComboBox
*cb
= paramWidget
->findChild
<KComboBox
*>("combo");
1391 mParameter
= cb
->currentText();
1393 RegExpLineEdit
*rele
= paramWidget
->findChild
<RegExpLineEdit
*>("search");
1395 mRegExp
.setPattern( rele
->text() );
1397 KLineEdit
*le
= paramWidget
->findChild
<KLineEdit
*>("replace");
1399 mReplacementString
= le
->text();
1402 void KMFilterActionRewriteHeader::clearParamWidget( QWidget
* paramWidget
) const
1404 KComboBox
*cb
= paramWidget
->findChild
<KComboBox
*>("combo");
1406 cb
->setCurrentIndex(0);
1408 RegExpLineEdit
*rele
= paramWidget
->findChild
<RegExpLineEdit
*>("search");
1412 KLineEdit
*le
= paramWidget
->findChild
<KLineEdit
*>("replace");
1417 const QString
KMFilterActionRewriteHeader::argsAsString() const
1419 QString result
= mParameter
;
1421 result
+= mRegExp
.pattern();
1423 result
+= mReplacementString
;
1428 const QString
KMFilterActionRewriteHeader::displayString() const
1430 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
1433 void KMFilterActionRewriteHeader::argsFromString( const QString
&argsStr
)
1435 const QStringList l
= argsStr
.split( '\t' );
1439 mRegExp
.setPattern( l
[1] );
1440 mReplacementString
= l
[2];
1442 int idx
= mParameterList
.indexOf( s
);
1444 mParameterList
.append( s
);
1445 idx
= mParameterList
.count() - 1;
1447 mParameter
= mParameterList
.at( idx
);
1451 //=============================================================================
1452 // KMFilterActionMove - move into folder
1453 // File message into another mail folder
1454 //=============================================================================
1455 class KMFilterActionMove
: public KMFilterActionWithFolder
1458 KMFilterActionMove();
1459 virtual ReturnCode
process( Akonadi::Item item
) const;
1460 virtual bool requiresBody() const;
1461 static KMFilterAction
* newAction(void);
1464 KMFilterAction
* KMFilterActionMove::newAction(void)
1466 return (new KMFilterActionMove
);
1469 KMFilterActionMove::KMFilterActionMove()
1470 : KMFilterActionWithFolder( "transfer", i18n("Move Into Folder") )
1474 KMFilterAction::ReturnCode
KMFilterActionMove::process( Akonadi::Item item
) const
1476 if ( !mFolder
.isValid() ) {
1477 const Akonadi::Collection targetFolder
= kmkernel
->collectionFromId( mFolderName
);
1478 if( !targetFolder
.isValid() )
1479 return ErrorButGoOn
;
1480 MessageProperty::setFilterFolder( item
, targetFolder
);
1483 MessageProperty::setFilterFolder( item
, mFolder
);
1487 bool KMFilterActionMove::requiresBody() const
1493 //=============================================================================
1494 // KMFilterActionCopy - copy into folder
1495 // Copy message into another mail folder
1496 //=============================================================================
1497 class KMFilterActionCopy
: public KMFilterActionWithFolder
1500 KMFilterActionCopy();
1501 virtual ReturnCode
process( Akonadi::Item item
) const;
1502 virtual bool requiresBody() const;
1503 static KMFilterAction
* newAction(void);
1506 KMFilterAction
* KMFilterActionCopy::newAction( void )
1508 return ( new KMFilterActionCopy
);
1511 KMFilterActionCopy::KMFilterActionCopy()
1512 : KMFilterActionWithFolder( "copy", i18n("Copy Into Folder") )
1516 KMFilterAction::ReturnCode
KMFilterActionCopy::process( Akonadi::Item item
) const
1518 // copy the message 1:1
1519 new Akonadi::ItemCopyJob( item
, mFolder
, kmkernel
->filterMgr() ); // TODO handle error
1523 bool KMFilterActionCopy::requiresBody() const
1528 //=============================================================================
1529 // KMFilterActionForward - forward to
1530 // Forward message to another user, with a defined template
1531 //=============================================================================
1532 class KMFilterActionForward
: public KMFilterActionWithAddress
1535 KMFilterActionForward();
1536 static KMFilterAction
* newAction( void );
1537 virtual ReturnCode
process( Akonadi::Item item
) const;
1538 virtual QWidget
* createParamWidget( QWidget
* parent
) const;
1539 virtual void applyParamWidgetValue( QWidget
* paramWidget
);
1540 virtual void setParamWidgetValue( QWidget
* paramWidget
) const;
1541 virtual void clearParamWidget( QWidget
* paramWidget
) const;
1542 virtual void argsFromString( const QString
&argsStr
);
1543 virtual const QString
argsAsString() const;
1544 virtual const QString
displayString() const;
1548 mutable QString mTemplate
;
1551 KMFilterAction
*KMFilterActionForward::newAction( void )
1553 return ( new KMFilterActionForward
);
1556 KMFilterActionForward::KMFilterActionForward()
1557 : KMFilterActionWithAddress( "forward", i18n("Forward To") )
1561 KMFilterAction::ReturnCode
KMFilterActionForward::process( Akonadi::Item item
) const
1563 if ( mParameter
.isEmpty() )
1564 return ErrorButGoOn
;
1566 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1567 // avoid endless loops when this action is used in a filter
1568 // which applies to sent messages
1569 if ( MessageCore::StringUtil::addressIsInAddressList( mParameter
,
1570 QStringList( msg
->to()->asUnicodeString() ) ) ) {
1571 kWarning() << "Attempt to forward to receipient of original message, ignoring.";
1572 return ErrorButGoOn
;
1574 MessageFactory
factory( msg
, item
.id() );
1575 factory
.setIdentityManager( KMKernel::self()->identityManager() );
1576 factory
.setFolderIdentity( KMail::Util::folderIdentity( item
) );
1577 factory
.setTemplate( mTemplate
);
1578 KMime::Message::Ptr fwdMsg
= factory
.createForward();
1579 fwdMsg
->to()->fromUnicodeString( fwdMsg
->to()->asUnicodeString() + ',' + mParameter
, "utf-8" );
1580 if ( !kmkernel
->msgSender()->send( fwdMsg
, MessageSender::SendDefault
) ) {
1581 kWarning() << "KMFilterAction: could not forward message (sending failed)";
1582 return ErrorButGoOn
; // error: couldn't send
1585 sendMDN( item
, KMime::MDN::Dispatched
);
1587 // (the msgSender takes ownership of the message, so don't delete it here)
1591 QWidget
* KMFilterActionForward::createParamWidget( QWidget
* parent
) const
1593 QWidget
*addressAndTemplate
= new QWidget( parent
);
1594 QHBoxLayout
*hBox
= new QHBoxLayout( addressAndTemplate
);
1595 hBox
->setMargin( 0 );
1596 QWidget
*addressEdit
= KMFilterActionWithAddress::createParamWidget( addressAndTemplate
);
1597 addressEdit
->setObjectName( "addressEdit" );
1598 hBox
->addWidget( addressEdit
);
1600 KLineEdit
*lineEdit
= addressEdit
->findChild
<KLineEdit
*>( "addressEdit" );
1601 Q_ASSERT( lineEdit
);
1602 lineEdit
->setToolTip( i18n( "The addressee to whom the message will be forwarded." ) );
1603 lineEdit
->setWhatsThis( i18n( "The filter will forward the message to the addressee entered here." ) );
1605 KComboBox
*templateCombo
= new KComboBox( addressAndTemplate
);
1606 templateCombo
->setObjectName( "templateCombo" );
1607 hBox
->addWidget( templateCombo
);
1609 templateCombo
->addItem( i18n( "Default Template" ) );
1610 QStringList templateNames
= GlobalSettingsBase::self()->customTemplates();
1611 foreach( const QString
&templateName
, templateNames
) {
1612 CTemplates
templat( templateName
);
1613 if ( templat
.type() == CustomTemplates::TForward
||
1614 templat
.type() == CustomTemplates::TUniversal
)
1615 templateCombo
->addItem( templateName
);
1617 templateCombo
->setEnabled( templateCombo
->count() > 1 );
1618 templateCombo
->setToolTip( i18n( "The template used when forwarding" ) );
1619 templateCombo
->setWhatsThis( i18n( "Set the forwarding template that will be used with this filter." ) );
1621 return addressAndTemplate
;
1624 void KMFilterActionForward::applyParamWidgetValue( QWidget
* paramWidget
)
1626 QWidget
*addressEdit
= paramWidget
->findChild
<QWidget
*>( "addressEdit" );
1627 Q_ASSERT( addressEdit
);
1628 KMFilterActionWithAddress::applyParamWidgetValue( addressEdit
);
1630 KComboBox
*templateCombo
= paramWidget
->findChild
<KComboBox
*>( "templateCombo" );
1631 Q_ASSERT( templateCombo
);
1633 if ( templateCombo
->currentIndex() == 0 ) {
1634 // Default template, so don't use a custom one
1638 mTemplate
= templateCombo
->currentText();
1642 void KMFilterActionForward::setParamWidgetValue( QWidget
* paramWidget
) const
1644 QWidget
*addressEdit
= paramWidget
->findChild
<QWidget
*>( "addressEdit" );
1645 Q_ASSERT( addressEdit
);
1646 KMFilterActionWithAddress::setParamWidgetValue( addressEdit
);
1648 KComboBox
*templateCombo
= paramWidget
->findChild
<KComboBox
*>( "templateCombo" );
1649 Q_ASSERT( templateCombo
);
1651 if ( mTemplate
.isEmpty() ) {
1652 templateCombo
->setCurrentIndex( 0 );
1655 int templateIndex
= templateCombo
->findText( mTemplate
);
1656 if ( templateIndex
!= -1 ) {
1657 templateCombo
->setCurrentIndex( templateIndex
);
1665 void KMFilterActionForward::clearParamWidget( QWidget
* paramWidget
) const
1667 QWidget
*addressEdit
= paramWidget
->findChild
<QWidget
*>( "addressEdit" );
1668 Q_ASSERT( addressEdit
);
1669 KMFilterActionWithAddress::clearParamWidget( addressEdit
);
1671 KComboBox
*templateCombo
= paramWidget
->findChild
<KComboBox
*>( "templateCombo" );
1672 Q_ASSERT( templateCombo
);
1674 templateCombo
->setCurrentIndex( 0 );
1677 // We simply place a "@$$@" between the two parameters. The template is the last
1678 // parameter in the string, for compatibility reasons.
1679 static const QString forwardFilterArgsSeperator
= "@$$@";
1681 void KMFilterActionForward::argsFromString( const QString
&argsStr
)
1683 int seperatorPos
= argsStr
.indexOf( forwardFilterArgsSeperator
);
1685 if ( seperatorPos
== - 1 ) {
1686 // Old config, assume that the whole string is the addressee
1687 KMFilterActionWithAddress::argsFromString( argsStr
);
1690 const QString addressee
= argsStr
.left( seperatorPos
);
1691 mTemplate
= argsStr
.mid( seperatorPos
+ forwardFilterArgsSeperator
.length() );
1692 KMFilterActionWithAddress::argsFromString( addressee
);
1696 const QString
KMFilterActionForward::argsAsString() const
1698 return KMFilterActionWithAddress::argsAsString() + forwardFilterArgsSeperator
+ mTemplate
;
1701 const QString
KMFilterActionForward::displayString() const
1703 if ( mTemplate
.isEmpty() )
1704 return i18n( "Forward to %1 with default template", mParameter
);
1706 return i18n( "Forward to %1 with template %2", mParameter
, mTemplate
);
1709 //=============================================================================
1710 // KMFilterActionRedirect - redirect to
1711 // Redirect message to another user
1712 //=============================================================================
1713 class KMFilterActionRedirect
: public KMFilterActionWithAddress
1716 KMFilterActionRedirect();
1717 virtual ReturnCode
process( Akonadi::Item item
) const;
1718 static KMFilterAction
* newAction(void);
1721 KMFilterAction
* KMFilterActionRedirect::newAction(void)
1723 return (new KMFilterActionRedirect
);
1726 KMFilterActionRedirect::KMFilterActionRedirect()
1727 : KMFilterActionWithAddress( "redirect", i18n("Redirect To") )
1731 KMFilterAction::ReturnCode
KMFilterActionRedirect::process( Akonadi::Item item
) const
1733 if ( mParameter
.isEmpty() )
1734 return ErrorButGoOn
;
1736 KMime::Message::Ptr msg
= MessageCore::Util::message( item
);
1737 MessageFactory
factory( msg
, item
.id() );
1738 factory
.setFolderIdentity( KMail::Util::folderIdentity( item
) );
1739 factory
.setIdentityManager( KMKernel::self()->identityManager() );
1740 KMime::Message::Ptr rmsg
= factory
.createRedirect( mParameter
);
1742 return ErrorButGoOn
;
1744 sendMDN( item
, KMime::MDN::Dispatched
);
1746 if ( !kmkernel
->msgSender()->send( rmsg
, MessageSender::SendLater
) ) {
1747 kDebug() << "KMFilterAction: could not redirect message (sending failed)";
1748 return ErrorButGoOn
; // error: couldn't send
1754 //=============================================================================
1755 // KMFilterActionExec - execute command
1756 // Execute a shell command
1757 //=============================================================================
1758 class KMFilterActionExec
: public KMFilterActionWithCommand
1761 KMFilterActionExec();
1762 virtual ReturnCode
process( Akonadi::Item item
) const;
1763 static KMFilterAction
* newAction(void);
1766 KMFilterAction
* KMFilterActionExec::newAction(void)
1768 return (new KMFilterActionExec());
1771 KMFilterActionExec::KMFilterActionExec()
1772 : KMFilterActionWithCommand( "execute", i18n("Execute Command") )
1776 KMFilterAction::ReturnCode
KMFilterActionExec::process( Akonadi::Item item
) const
1778 return KMFilterActionWithCommand::genericProcess( item
, false ); // ignore output
1781 //=============================================================================
1782 // KMFilterActionExtFilter - use external filter app
1783 // External message filter: executes a shell command with message
1784 // on stdin; altered message is expected on stdout.
1785 //=============================================================================
1787 class KMFilterActionExtFilter
: public KMFilterActionWithCommand
1790 KMFilterActionExtFilter();
1791 virtual ReturnCode
process( Akonadi::Item item2
) const;
1792 static KMFilterAction
* newAction(void);
1795 KMFilterAction
* KMFilterActionExtFilter::newAction(void)
1797 return (new KMFilterActionExtFilter
);
1800 KMFilterActionExtFilter::KMFilterActionExtFilter()
1801 : KMFilterActionWithCommand( "filter app", i18n("Pipe Through") )
1804 KMFilterAction::ReturnCode
KMFilterActionExtFilter::process( Akonadi::Item item
) const
1806 return KMFilterActionWithCommand::genericProcess( item
, true ); // use output
1809 //=============================================================================
1810 // KMFilterActionExecSound - execute command
1812 //=============================================================================
1813 class KMFilterActionExecSound
: public KMFilterActionWithTest
1816 KMFilterActionExecSound();
1817 ~KMFilterActionExecSound();
1818 virtual ReturnCode
process( Akonadi::Item item
) const;
1819 virtual bool requiresBody() const;
1820 static KMFilterAction
* newAction(void);
1822 mutable Phonon::MediaObject
* mPlayer
;
1825 KMFilterActionWithTest::KMFilterActionWithTest( const char* aName
, const QString
&aLabel
)
1826 : KMFilterAction( aName
, aLabel
)
1830 KMFilterActionWithTest::~KMFilterActionWithTest()
1834 QWidget
* KMFilterActionWithTest::createParamWidget( QWidget
* parent
) const
1836 KMSoundTestWidget
*le
= new KMSoundTestWidget(parent
);
1837 le
->setUrl( mParameter
);
1842 void KMFilterActionWithTest::applyParamWidgetValue( QWidget
* paramWidget
)
1844 mParameter
= ((KMSoundTestWidget
*)paramWidget
)->url();
1847 void KMFilterActionWithTest::setParamWidgetValue( QWidget
* paramWidget
) const
1849 ((KMSoundTestWidget
*)paramWidget
)->setUrl( mParameter
);
1852 void KMFilterActionWithTest::clearParamWidget( QWidget
* paramWidget
) const
1854 ((KMSoundTestWidget
*)paramWidget
)->clear();
1857 void KMFilterActionWithTest::argsFromString( const QString
&argsStr
)
1859 mParameter
= argsStr
;
1862 const QString
KMFilterActionWithTest::argsAsString() const
1867 const QString
KMFilterActionWithTest::displayString() const
1869 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
1873 KMFilterActionExecSound::KMFilterActionExecSound()
1874 : KMFilterActionWithTest( "play sound", i18n("Play Sound") ),
1879 KMFilterActionExecSound::~KMFilterActionExecSound()
1884 KMFilterAction
* KMFilterActionExecSound::newAction(void)
1886 return (new KMFilterActionExecSound());
1889 KMFilterAction::ReturnCode
KMFilterActionExecSound::process( Akonadi::Item
) const
1891 if ( mParameter
.isEmpty() )
1892 return ErrorButGoOn
;
1895 mPlayer
= Phonon::createPlayer(Phonon::NotificationCategory
);
1897 mPlayer
->setCurrentSource( mParameter
);
1902 bool KMFilterActionExecSound::requiresBody() const
1907 KMFilterActionWithUrl::KMFilterActionWithUrl( const char* aName
, const QString
&aLabel
)
1908 : KMFilterAction( aName
, aLabel
)
1912 KMFilterActionWithUrl::~KMFilterActionWithUrl()
1916 QWidget
* KMFilterActionWithUrl::createParamWidget( QWidget
* parent
) const
1918 KUrlRequester
*le
= new KUrlRequester(parent
);
1919 le
->setUrl( KUrl( mParameter
) );
1924 void KMFilterActionWithUrl::applyParamWidgetValue( QWidget
* paramWidget
)
1926 const KUrl url
= ((KUrlRequester
*)paramWidget
)->url();
1927 mParameter
= url
.isLocalFile() ? url
.toLocalFile() : url
.path();
1930 void KMFilterActionWithUrl::setParamWidgetValue( QWidget
* paramWidget
) const
1932 ((KUrlRequester
*)paramWidget
)->setUrl( KUrl( mParameter
) );
1935 void KMFilterActionWithUrl::clearParamWidget( QWidget
* paramWidget
) const
1937 ((KUrlRequester
*)paramWidget
)->clear();
1940 void KMFilterActionWithUrl::argsFromString( const QString
&argsStr
)
1942 mParameter
= argsStr
;
1945 const QString
KMFilterActionWithUrl::argsAsString() const
1950 const QString
KMFilterActionWithUrl::displayString() const
1952 return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
1955 //=============================================================================
1956 // KMFilterActionAddToAddressBook
1957 // - add email address from header to address book
1958 //=============================================================================
1959 class KMFilterActionAddToAddressBook
: public KMFilterActionWithStringList
1962 KMFilterActionAddToAddressBook();
1963 virtual ReturnCode
process( Akonadi::Item item
) const;
1964 static KMFilterAction
* newAction();
1966 virtual bool isEmpty() const { return false; }
1968 virtual QWidget
* createParamWidget( QWidget
* parent
) const;
1969 virtual void setParamWidgetValue( QWidget
* paramWidget
) const;
1970 virtual void applyParamWidgetValue( QWidget
* paramWidget
);
1971 virtual void clearParamWidget( QWidget
* paramWidget
) const;
1973 virtual const QString
argsAsString() const;
1974 virtual void argsFromString( const QString
&argsStr
);
1985 const QString mFromStr
, mToStr
, mCCStr
, mBCCStr
;
1986 HeaderType mHeaderType
;
1987 Akonadi::Collection::Id mCollectionId
;
1991 KMFilterAction
* KMFilterActionAddToAddressBook::newAction()
1993 return ( new KMFilterActionAddToAddressBook
);
1996 KMFilterActionAddToAddressBook::KMFilterActionAddToAddressBook()
1997 : KMFilterActionWithStringList( "add to address book", i18n( "Add to Address Book" ) ),
1998 mFromStr( i18nc( "Email sender", "From" ) ),
1999 mToStr( i18nc( "Email recipient", "To" ) ),
2000 mCCStr( i18n( "CC" ) ),
2001 mBCCStr( i18n( "BCC" ) ),
2002 mHeaderType( FromHeader
),
2003 mCollectionId( -1 ),
2004 mCategory( i18n( "KMail Filter" ) )
2008 KMFilterAction::ReturnCode
KMFilterActionAddToAddressBook::process( Akonadi::Item item
) const
2010 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
2013 switch ( mHeaderType
) {
2014 case FromHeader
: headerLine
= msg
->from()->asUnicodeString(); break;
2015 case ToHeader
: headerLine
= msg
->to()->asUnicodeString(); break;
2016 case CcHeader
: headerLine
= msg
->cc()->asUnicodeString(); break;
2017 case BccHeader
: headerLine
= msg
->bcc()->asUnicodeString(); break;
2020 const QStringList emails
= KPIMUtils::splitAddressList( headerLine
);
2022 foreach ( const QString singleEmail
, emails
) {
2023 QString name
, email
;
2024 KABC::Addressee::parseEmailAddress( singleEmail
, name
, email
);
2026 KABC::Addressee contact
;
2027 contact
.setNameFromString( name
);
2028 contact
.insertEmail( email
, true );
2029 if ( !mCategory
.isEmpty() )
2030 contact
.insertCategory( mCategory
);
2032 KPIM::AddContactJob
*job
= new KPIM::AddContactJob( contact
, Akonadi::Collection( mCollectionId
) );
2039 QWidget
* KMFilterActionAddToAddressBook::createParamWidget( QWidget
* parent
) const
2041 QWidget
*widget
= new QWidget( parent
);
2042 QGridLayout
*layout
= new QGridLayout ( widget
);
2044 KComboBox
*headerCombo
= new KComboBox( widget
);
2045 headerCombo
->setObjectName( "HeaderComboBox" );
2046 layout
->addWidget( headerCombo
, 0, 0, 2, 1, Qt::AlignVCenter
);
2048 QLabel
*label
= new QLabel( i18n( "with category" ), widget
);
2049 layout
->addWidget( label
, 0, 1 );
2051 KLineEdit
*categoryEdit
= new KLineEdit( widget
);
2052 categoryEdit
->setObjectName( "CategoryEdit" );
2053 layout
->addWidget( categoryEdit
, 0, 2 );
2055 label
= new QLabel( i18n( "in address book" ), widget
);
2056 layout
->addWidget( label
, 1, 1 );
2058 Akonadi::CollectionComboBox
*collectionComboBox
= new Akonadi::CollectionComboBox( widget
);
2059 collectionComboBox
->setMimeTypeFilter( QStringList() << KABC::Addressee::mimeType() );
2060 collectionComboBox
->setAccessRightsFilter( Akonadi::Collection::CanCreateItem
);
2062 collectionComboBox
->setObjectName( "AddressBookComboBox" );
2063 collectionComboBox
->setToolTip( i18n( "<p>This defines the preferred address book.<br />"
2064 "If it is not accessible, the filter will fallback to the default address book.</p>" ) );
2065 layout
->addWidget( collectionComboBox
, 1, 2 );
2067 setParamWidgetValue( widget
);
2072 void KMFilterActionAddToAddressBook::setParamWidgetValue( QWidget
* paramWidget
) const
2074 KComboBox
*headerCombo
= paramWidget
->findChild
<KComboBox
*>( "HeaderComboBox" );
2075 Q_ASSERT( headerCombo
);
2076 headerCombo
->clear();
2077 headerCombo
->addItem( mFromStr
, FromHeader
);
2078 headerCombo
->addItem( mToStr
, ToHeader
);
2079 headerCombo
->addItem( mCCStr
, CcHeader
);
2080 headerCombo
->addItem( mBCCStr
, BccHeader
);
2082 headerCombo
->setCurrentIndex( headerCombo
->findData( mHeaderType
) );
2084 KLineEdit
*categoryEdit
= paramWidget
->findChild
<KLineEdit
*>( "CategoryEdit" );
2085 Q_ASSERT( categoryEdit
);
2086 categoryEdit
->setText( mCategory
);
2088 Akonadi::CollectionComboBox
*collectionComboBox
= paramWidget
->findChild
<Akonadi::CollectionComboBox
*>( "AddressBookComboBox" );
2089 Q_ASSERT( collectionComboBox
);
2090 collectionComboBox
->setDefaultCollection( Akonadi::Collection( mCollectionId
) );
2091 collectionComboBox
->setProperty( "collectionId", mCollectionId
);
2094 void KMFilterActionAddToAddressBook::applyParamWidgetValue( QWidget
* paramWidget
)
2096 KComboBox
*headerCombo
= paramWidget
->findChild
<KComboBox
*>( "HeaderComboBox" );
2097 Q_ASSERT( headerCombo
);
2098 mHeaderType
= static_cast<HeaderType
>( headerCombo
->itemData( headerCombo
->currentIndex() ).toInt() );
2100 KLineEdit
*categoryEdit
= paramWidget
->findChild
<KLineEdit
*>( "CategoryEdit" );
2101 Q_ASSERT( categoryEdit
);
2102 mCategory
= categoryEdit
->text();
2104 Akonadi::CollectionComboBox
*collectionComboBox
= paramWidget
->findChild
<Akonadi::CollectionComboBox
*>( "AddressBookComboBox" );
2105 Q_ASSERT( collectionComboBox
);
2106 const Akonadi::Collection collection
= collectionComboBox
->currentCollection();
2108 // it might be that the model of collectionComboBox has not finished loading yet, so
2109 // we use the previously 'stored' value from the 'collectionId' property
2110 if ( collection
.isValid() )
2111 mCollectionId
= collection
.id();
2113 const QVariant value
= collectionComboBox
->property( "collectionId" );
2114 if ( value
.isValid() )
2115 mCollectionId
= value
.toLongLong();
2119 void KMFilterActionAddToAddressBook::clearParamWidget( QWidget
* paramWidget
) const
2121 KComboBox
*headerCombo
= paramWidget
->findChild
<KComboBox
*>( "HeaderComboBox" );
2122 Q_ASSERT( headerCombo
);
2123 headerCombo
->setCurrentItem( 0 );
2125 KLineEdit
*categoryEdit
= paramWidget
->findChild
<KLineEdit
*>( "CategoryEdit" );
2126 Q_ASSERT( categoryEdit
);
2127 categoryEdit
->setText( mCategory
);
2130 const QString
KMFilterActionAddToAddressBook::argsAsString() const
2134 switch ( mHeaderType
) {
2135 case FromHeader
: result
= QLatin1String( "From" ); break;
2136 case ToHeader
: result
= QLatin1String( "To" ); break;
2137 case CcHeader
: result
= QLatin1String( "CC" ); break;
2138 case BccHeader
: result
= QLatin1String( "BCC" ); break;
2141 result
+= QLatin1Char( '\t' );
2142 result
+= QString::number( mCollectionId
);
2143 result
+= QLatin1Char( '\t' );
2144 result
+= mCategory
;
2149 void KMFilterActionAddToAddressBook::argsFromString( const QString
&argsStr
)
2151 const QStringList parts
= argsStr
.split( QLatin1Char( '\t' ), QString::KeepEmptyParts
);
2152 if ( parts
[ 0 ] == QLatin1String( "From" ) )
2153 mHeaderType
= FromHeader
;
2154 else if ( parts
[ 0 ] == QLatin1String( "To" ) )
2155 mHeaderType
= ToHeader
;
2156 else if ( parts
[ 0 ] == QLatin1String( "CC" ) )
2157 mHeaderType
= CcHeader
;
2158 else if ( parts
[ 0 ] == QLatin1String( "BCC" ) )
2159 mHeaderType
= BccHeader
;
2161 if ( parts
.count() >= 2 )
2162 mCollectionId
= parts
[ 1 ].toLongLong();
2164 if ( parts
.count() < 3 )
2167 mCategory
= parts
[ 2 ];
2170 //=============================================================================
2172 // Filter Action Dictionary
2174 //=============================================================================
2175 KMFilterActionDict::~KMFilterActionDict()
2177 qDeleteAll( mList
);
2180 void KMFilterActionDict::init(void)
2182 insert( KMFilterActionMove::newAction
);
2183 insert( KMFilterActionCopy::newAction
);
2184 insert( KMFilterActionIdentity::newAction
);
2185 insert( KMFilterActionSetStatus::newAction
);
2186 insert( KMFilterActionAddTag::newAction
);
2187 insert( KMFilterActionFakeDisposition::newAction
);
2188 insert( KMFilterActionTransport::newAction
);
2189 insert( KMFilterActionReplyTo::newAction
);
2190 insert( KMFilterActionForward::newAction
);
2191 insert( KMFilterActionRedirect::newAction
);
2192 insert( KMFilterActionSendReceipt::newAction
);
2193 insert( KMFilterActionExec::newAction
);
2194 insert( KMFilterActionExtFilter::newAction
);
2195 insert( KMFilterActionRemoveHeader::newAction
);
2196 insert( KMFilterActionAddHeader::newAction
);
2197 insert( KMFilterActionRewriteHeader::newAction
);
2198 insert( KMFilterActionExecSound::newAction
);
2199 insert( KMFilterActionAddToAddressBook::newAction
);
2200 // Register custom filter actions below this line.
2202 // The int in the QDict constructor (41) must be a prime
2203 // and should be greater than the double number of KMFilterAction types
2204 KMFilterActionDict::KMFilterActionDict()
2205 : QMultiHash
<QString
, KMFilterActionDesc
*>()
2210 void KMFilterActionDict::insert( KMFilterActionNewFunc aNewFunc
)
2212 KMFilterAction
*action
= aNewFunc();
2213 KMFilterActionDesc
* desc
= new KMFilterActionDesc
;
2214 desc
->name
= action
->name();
2215 desc
->label
= action
->label();
2216 desc
->create
= aNewFunc
;
2217 QMultiHash
<QString
, KMFilterActionDesc
*>::insert( desc
->name
, desc
);
2218 QMultiHash
<QString
, KMFilterActionDesc
*>::insert( desc
->label
, desc
);
2219 mList
.append( desc
);