2 #include "filteractionwidget.h"
3 #include "filteraction.h"
5 #include "filtermanager.h"
6 #include "folderrequester.h"
8 #include "mailkernel.h"
9 #include "mdnadvicedialog.h"
10 #include "messageproperty.h"
11 #include "minimumcombobox.h"
12 #include "regexplineedit.h"
15 #include "soundtestwidget.h"
18 #include <akonadi/collectioncombobox.h>
19 #include <akonadi/itemcopyjob.h>
20 #include <akonadi/itemmodifyjob.h>
21 #include <akonadi/kmime/messagestatus.h>
22 #include <kabc/addressee.h>
25 #include <kmime/kmime_message.h>
26 #include <kpimidentities/identity.h>
27 #include <kpimidentities/identitycombo.h>
28 #include <kpimidentities/identitymanager.h>
29 #include <kpimutils/kfileio.h>
30 #include <kpimutils/email.h>
33 #include <ktemporaryfile.h>
34 #include <kurlrequester.h>
35 #include <libkdepim/addcontactjob.h>
36 #include <messagecore/emailaddressrequester.h>
37 #include <messagecore/mdnstateattribute.h>
38 #include <messagecore/messagehelpers.h>
39 #include <messagecore/stringutil.h>
40 #include <messagecomposer/messagefactory.h>
41 #include <messagecomposer/messagesender.h>
42 #include <messageviewer/globalsettings.h>
44 #ifndef KDEPIM_NO_NEPOMUK
45 #include <nepomuk/tag.h>
47 #include <phonon/mediaobject.h>
48 #include <templateparser/customtemplates_kfg.h>
49 #include <templateparser/customtemplates.h>
51 #include <QtGui/QHBoxLayout>
52 #include <QtGui/QLabel>
53 #include <QtGui/QTextDocument>
58 using MailCommon::MessageProperty
;
59 using MailCommon::RegExpLineEdit
;
60 using MessageComposer::MessageFactory
;
62 using namespace MailCommon
;
64 FilterAction::FilterAction( const char *name
, const QString
&label
, QObject
*parent
)
65 : QObject( parent
), mName( name
), mLabel( label
)
69 FilterAction::~FilterAction()
73 QString
FilterAction::label() const
78 QString
FilterAction::name() const
83 bool FilterAction::requiresBody() const
88 bool FilterAction::isEmpty() const
93 FilterAction
* FilterAction::newAction()
98 QWidget
* FilterAction::createParamWidget( QWidget
*parent
) const
100 return new QWidget( parent
);
103 void FilterAction::applyParamWidgetValue( QWidget
* )
107 void FilterAction::setParamWidgetValue( QWidget
* ) const
111 void FilterAction::clearParamWidget( QWidget
* ) const
115 bool FilterAction::folderRemoved( const Akonadi::Collection
&, const Akonadi::Collection
& )
120 void FilterAction::sendMDN( const Akonadi::Item
&item
, KMime::MDN::DispositionType type
,
121 const QList
<KMime::MDN::DispositionModifier
> &modifiers
)
123 const KMime::Message::Ptr msg
= MessageCore::Util::message( item
);
127 const QPair
<bool, KMime::MDN::SendingMode
> mdnSend
= MDNAdviceHelper::instance()->checkAndSetMDNInfo( item
, type
, true );
128 if ( mdnSend
.first
) {
129 const int quote
= MessageViewer::GlobalSettings::self()->quoteMessage();
130 MessageFactory
factory( msg
, Akonadi::Item().id() );
131 factory
.setIdentityManager( KernelIf
->identityManager() );
133 const KMime::Message::Ptr mdn
= factory
.createMDN( KMime::MDN::AutomaticAction
, type
, mdnSend
.second
, quote
, modifiers
);
135 if ( !KernelIf
->msgSender()->send( mdn
, MessageSender::SendLater
) ) {
136 kDebug() << "Sending failed.";
142 //=============================================================================
144 // FilterActionWithNone
146 //=============================================================================
148 FilterActionWithNone::FilterActionWithNone( const char *name
, const QString
&label
, QObject
*parent
)
149 : FilterAction( name
, label
, parent
)
153 QString
FilterActionWithNone::displayString() const
158 void FilterActionWithNone::argsFromString( const QString
& )
162 QString
FilterActionWithNone::argsAsString() const
167 //=============================================================================
169 // FilterActionWithUOID
171 //=============================================================================
173 FilterActionWithUOID::FilterActionWithUOID( const char *name
, const QString
&label
, QObject
*parent
)
174 : FilterAction( name
, label
, parent
), mParameter( 0 )
178 bool FilterActionWithUOID::isEmpty() const
180 return (mParameter
== 0);
183 void FilterActionWithUOID::argsFromString( const QString
&argsStr
)
185 mParameter
= argsStr
.trimmed().toUInt();
188 QString
FilterActionWithUOID::argsAsString() const
190 return QString::number( mParameter
);
193 QString
FilterActionWithUOID::displayString() const
195 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
199 //=============================================================================
201 // FilterActionWithString
203 //=============================================================================
205 FilterActionWithString::FilterActionWithString( const char *name
, const QString
&label
, QObject
*parent
)
206 : FilterAction( name
, label
, parent
)
210 bool FilterActionWithString::isEmpty() const
212 return mParameter
.trimmed().isEmpty();
215 QWidget
* FilterActionWithString::createParamWidget( QWidget
*parent
) const
217 KLineEdit
*lineEdit
= new KLineEdit( parent
);
218 lineEdit
->setClearButtonShown( true );
219 lineEdit
->setText( mParameter
);
221 connect( lineEdit
, SIGNAL(textChanged(QString
)), this, SIGNAL(filterActionModified()) );
226 void FilterActionWithString::applyParamWidgetValue( QWidget
*paramWidget
)
228 mParameter
= static_cast<KLineEdit
*>( paramWidget
)->text();
231 void FilterActionWithString::setParamWidgetValue( QWidget
*paramWidget
) const
233 static_cast<KLineEdit
*>( paramWidget
)->setText( mParameter
);
236 void FilterActionWithString::clearParamWidget( QWidget
*paramWidget
) const
238 static_cast<KLineEdit
*>( paramWidget
)->clear();
241 void FilterActionWithString::argsFromString( const QString
&argsStr
)
243 mParameter
= argsStr
;
246 QString
FilterActionWithString::argsAsString() const
251 QString
FilterActionWithString::displayString() const
253 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
256 //=============================================================================
258 // class FilterActionWithStringList
260 //=============================================================================
262 FilterActionWithStringList::FilterActionWithStringList( const char *name
, const QString
&label
, QObject
*parent
)
263 : FilterActionWithString( name
, label
, parent
)
267 QWidget
* FilterActionWithStringList::createParamWidget( QWidget
*parent
) const
269 MinimumComboBox
*comboBox
= new MinimumComboBox( parent
);
270 comboBox
->setEditable( false );
271 comboBox
->addItems( mParameterList
);
272 setParamWidgetValue( comboBox
);
274 connect( comboBox
, SIGNAL(currentIndexChanged(int)),
275 this, SIGNAL(filterActionModified()) );
280 void FilterActionWithStringList::applyParamWidgetValue( QWidget
*paramWidget
)
282 mParameter
= static_cast<MinimumComboBox
*>( paramWidget
)->currentText();
285 void FilterActionWithStringList::setParamWidgetValue( QWidget
*paramWidget
) const
287 const int index
= mParameterList
.indexOf( mParameter
);
288 static_cast<MinimumComboBox
*>( paramWidget
)->setCurrentIndex( index
>= 0 ? index
: 0 );
291 void FilterActionWithStringList::clearParamWidget( QWidget
*paramWidget
) const
293 static_cast<MinimumComboBox
*>( paramWidget
)->setCurrentIndex( 0 );
296 void FilterActionWithStringList::argsFromString( const QString
&argsStr
)
298 int index
= mParameterList
.indexOf( argsStr
);
300 mParameterList
.append( argsStr
);
301 index
= mParameterList
.count() - 1;
304 mParameter
= mParameterList
.at( index
);
308 //=============================================================================
310 // class FilterActionWithFolder
312 //=============================================================================
314 FilterActionWithFolder::FilterActionWithFolder( const char *name
, const QString
&label
, QObject
*parent
)
315 : FilterAction( name
, label
, parent
)
319 bool FilterActionWithFolder::isEmpty() const
321 return (!mFolder
.isValid() && mFolderName
.isEmpty());
324 QWidget
* FilterActionWithFolder::createParamWidget( QWidget
*parent
) const
326 FolderRequester
*requester
= new FolderRequester( parent
);
327 requester
->setShowOutbox( false );
328 setParamWidgetValue( requester
);
330 connect( requester
, SIGNAL(folderChanged(Akonadi::Collection
)),
331 this, SIGNAL(filterActionModified()) );
336 void FilterActionWithFolder::applyParamWidgetValue( QWidget
*paramWidget
)
338 mFolder
= static_cast<FolderRequester
*>( paramWidget
)->folderCollection();
339 mFolderName
= static_cast<FolderRequester
*>( paramWidget
)->folderId();
342 void FilterActionWithFolder::setParamWidgetValue( QWidget
*paramWidget
) const
344 if ( mFolder
.isValid() )
345 static_cast<FolderRequester
*>( paramWidget
)->setFolder( mFolder
);
347 static_cast<FolderRequester
*>( paramWidget
)->setFolder( mFolderName
);
350 void FilterActionWithFolder::clearParamWidget( QWidget
*paramWidget
) const
352 static_cast<FolderRequester
*>( paramWidget
)->setFolder( CommonKernel
->draftsCollectionFolder() );
355 void FilterActionWithFolder::argsFromString( const QString
&argsStr
)
358 const Akonadi::Collection::Id id
= argsStr
.toLongLong( &ok
);
360 mFolder
= Akonadi::Collection( id
);
361 mFolderName
= QString::number( mFolder
.id() );
363 mFolderName
= argsStr
;
367 QString
FilterActionWithFolder::argsAsString() const
370 if ( mFolder
.isValid() )
371 result
= QString::number( mFolder
.id() );
373 result
= mFolderName
;
378 QString
FilterActionWithFolder::displayString() const
381 if ( mFolder
.isValid() )
382 result
= mFolder
.url().path();
384 result
= mFolderName
;
386 return label() + QLatin1String( " \"" ) + Qt::escape( result
) + QLatin1String( "\"" );
389 bool FilterActionWithFolder::folderRemoved( const Akonadi::Collection
&oldFolder
, const Akonadi::Collection
&newFolder
)
391 if ( oldFolder
== mFolder
) {
393 if ( newFolder
.isValid() )
394 mFolderName
= mFolder
.id();
400 //=============================================================================
402 // class FilterActionWithAddress
404 //=============================================================================
406 FilterActionWithAddress::FilterActionWithAddress( const char *name
, const QString
&label
, QObject
*parent
)
407 : FilterActionWithString( name
, label
, parent
)
411 QWidget
* FilterActionWithAddress::createParamWidget( QWidget
*parent
) const
413 MessageCore::EmailAddressRequester
*requester
= new MessageCore::EmailAddressRequester( parent
);
414 requester
->setText( mParameter
);
416 connect( requester
, SIGNAL(textChanged()), this, SIGNAL(filterActionModified()) );
421 void FilterActionWithAddress::applyParamWidgetValue( QWidget
*paramWidget
)
423 mParameter
= qobject_cast
<MessageCore::EmailAddressRequester
*>( paramWidget
)->text();
426 void FilterActionWithAddress::setParamWidgetValue( QWidget
*paramWidget
) const
428 qobject_cast
<MessageCore::EmailAddressRequester
*>( paramWidget
)->setText( mParameter
);
431 void FilterActionWithAddress::clearParamWidget( QWidget
*paramWidget
) const
433 qobject_cast
<MessageCore::EmailAddressRequester
*>( paramWidget
)->clear();
436 //=============================================================================
438 // class FilterActionWithCommand
440 //=============================================================================
442 FilterActionWithCommand::FilterActionWithCommand( const char *name
, const QString
&label
, QObject
*parent
)
443 : FilterActionWithUrl( name
, label
, parent
)
447 QWidget
* FilterActionWithCommand::createParamWidget( QWidget
*parent
) const
449 return FilterActionWithUrl::createParamWidget( parent
);
452 void FilterActionWithCommand::applyParamWidgetValue( QWidget
*paramWidget
)
454 FilterActionWithUrl::applyParamWidgetValue( paramWidget
);
457 void FilterActionWithCommand::setParamWidgetValue( QWidget
*paramWidget
) const
459 FilterActionWithUrl::setParamWidgetValue( paramWidget
);
462 void FilterActionWithCommand::clearParamWidget( QWidget
*paramWidget
) const
464 FilterActionWithUrl::clearParamWidget( paramWidget
);
467 static KMime::Content
* findMimeNodeForIndex( KMime::Content
* node
, int &index
)
472 foreach ( KMime::Content
* child
, node
->contents() ) {
473 KMime::Content
*result
= findMimeNodeForIndex( child
, --index
);
481 QString
FilterActionWithCommand::substituteCommandLineArgsFor( const KMime::Message::Ptr
&aMsg
, QList
<KTemporaryFile
*> &aTempFileList
) const
483 QString result
= mParameter
;
485 QRegExp
r( "%[0-9-]+" );
489 while ( ( start
= r
.indexIn( result
, start
+ 1 ) ) > 0 ) {
490 const int len
= r
.matchedLength();
492 // and save the encountered 'n' in a list.
494 const int n
= result
.mid( start
+ 1, len
- 1 ).toInt( &ok
);
499 // sort the list of n's
502 // and use QString::arg to substitute filenames for the %n's.
504 QString tempFileName
;
505 for ( QList
<int>::Iterator it
= argList
.begin() ; it
!= argList
.end() ; ++it
) {
506 // setup temp files with check for duplicate %n's
507 if ( (*it
) != lastSeen
) {
508 KTemporaryFile
*tempFile
= new KTemporaryFile();
509 if ( !tempFile
->open() ) {
511 kDebug() << "FilterActionWithCommand: Could not create temp file!";
515 aTempFileList
.append( tempFile
);
516 tempFileName
= tempFile
->fileName();
519 KPIMUtils::kByteArrayToFile( aMsg
->encodedContent(), tempFileName
, //###
520 false, false, false );
521 else if (aMsg
->contents().size() == 0)
522 KPIMUtils::kByteArrayToFile( aMsg
->decodedContent(), tempFileName
,
523 false, false, false );
525 int index
= *it
; // we pass by reference below, so this is not const
526 KMime::Content
*content
= findMimeNodeForIndex( aMsg
.get(), index
);
528 KPIMUtils::kByteArrayToFile( content
->decodedContent(), tempFileName
,
529 false, false, false );
535 // QString( "%0 and %1 and %1" ).arg( 0 ).arg( 1 )
536 // returns "0 and 1 and %1", so we must call .arg as
537 // many times as there are %n's, regardless of their multiplicity.
539 result
.replace( "%-1", tempFileName
);
541 result
= result
.arg( tempFileName
);
550 * Substitutes placeholders in the command line with the
551 * content of the correspoding header in the message.
552 * %{From} -> Joe Author <joe@acme.com>
554 void substituteMessageHeaders( const KMime::Message::Ptr
&aMsg
, QString
&result
)
556 // Replace the %{foo} with the content of the foo header field.
557 // If the header doesn't exist, remove the placeholder.
558 QRegExp
header_rx( "%\\{([a-z0-9-]+)\\}", Qt::CaseInsensitive
);
560 while ( ( idx
= header_rx
.indexIn( result
, idx
) ) != -1 ) {
561 const KMime::Headers::Base
* header
= aMsg
->headerByType( header_rx
.cap(1).toLatin1() );
564 replacement
= KShell::quoteArg( header
->as7BitString() );
565 result
.replace( idx
, header_rx
.matchedLength(), replacement
);
566 idx
+= replacement
.length();
571 * Substitutes placeholders in the command line with the
572 * corresponding information from the item. Currently supported
573 * are %{itemid} and %{itemurl}.
575 void substituteCommandLineArgsForItem( const Akonadi::Item
&item
, QString
&commandLine
)
577 commandLine
.replace( QLatin1String( "%{itemurl}" ), item
.url( Akonadi::Item::UrlWithMimeType
).url() );
578 commandLine
.replace( QLatin1String( "%{itemid}" ), QString::number( item
.id() ) );
583 FilterAction::ReturnCode
FilterActionWithCommand::genericProcess( const Akonadi::Item
&item
, bool withOutput
) const
585 const KMime::Message::Ptr aMsg
= item
.payload
<KMime::Message::Ptr
>();
588 if ( mParameter
.isEmpty() )
591 // KProcess doesn't support a QProcess::launch() equivalent, so
592 // we must use a temp file :-(
593 KTemporaryFile
* inFile
= new KTemporaryFile
;
594 if ( !inFile
->open() )
597 QList
<KTemporaryFile
*> atmList
;
598 atmList
.append( inFile
);
600 QString commandLine
= substituteCommandLineArgsFor( aMsg
, atmList
);
601 substituteCommandLineArgsForItem( item
, commandLine
);
602 substituteMessageHeaders( aMsg
, commandLine
);
604 if ( commandLine
.isEmpty() ) {
605 qDeleteAll( atmList
);
609 // The parentheses force the creation of a subshell
610 // in which the user-specified command is executed.
611 // This is to really catch all output of the command as well
612 // as to avoid clashes of our redirection with the ones
613 // the user may have specified. In the long run, we
614 // shouldn't be using tempfiles at all for this class, due
615 // to security aspects. (mmutz)
616 commandLine
= QLatin1Char( '(' ) + commandLine
+ QLatin1String( ") <" ) + inFile
->fileName();
618 // write message to file
619 QString tempFileName
= inFile
->fileName();
620 if ( !KPIMUtils::kByteArrayToFile( aMsg
->encodedContent(), tempFileName
, //###
621 false, false, false ) ) {
622 qDeleteAll( atmList
);
624 return CriticalError
;
630 shProc
.setOutputChannelMode( KProcess::SeparateChannels
);
631 shProc
.setShellCommand( commandLine
);
632 int result
= shProc
.execute();
635 qDeleteAll( atmList
);
641 // read altered message:
642 const QByteArray msgText
= shProc
.readAllStandardOutput();
644 if ( !msgText
.isEmpty() ) {
645 /* If the pipe through alters the message, it could very well
646 happen that it no longer has a X-UID header afterwards. That is
647 unfortunate, as we need to removed the original from the folder
648 using that, and look it up in the message. When the (new) message
649 is uploaded, the header is stripped anyhow. */
650 const QString uid
= aMsg
->headerByType( "X-UID" ) ? aMsg
->headerByType( "X-UID" )->asUnicodeString() : "";
651 aMsg
->setContent( msgText
);
653 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "X-UID", aMsg
.get(), uid
, "utf-8" );
654 aMsg
->setHeader( header
);
656 new Akonadi::ItemModifyJob( item
, FilterIf
->filterManager() ); //TODO: check for errors
658 qDeleteAll( atmList
);
664 qDeleteAll( atmList
);
671 //=============================================================================
673 // Specific Filter Actions
675 //=============================================================================
677 //=============================================================================
678 // FilterActionSendReceipt - send receipt
679 // Return delivery receipt.
680 //=============================================================================
681 class FilterActionSendReceipt
: public FilterActionWithNone
684 FilterActionSendReceipt( QObject
*parent
= 0 );
685 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
686 static FilterAction
* newAction();
689 FilterAction
* FilterActionSendReceipt::newAction()
691 return new FilterActionSendReceipt
;
694 FilterActionSendReceipt::FilterActionSendReceipt( QObject
*parent
)
695 : FilterActionWithNone( "confirm delivery", i18n( "Confirm Delivery" ), parent
)
699 FilterAction::ReturnCode
FilterActionSendReceipt::process( const Akonadi::Item
&item
) const
701 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
703 MessageFactory
factory( msg
, item
.id() );
704 factory
.setFolderIdentity( Util::folderIdentity( item
) );
705 factory
.setIdentityManager( KernelIf
->identityManager() );
707 const KMime::Message::Ptr receipt
= factory
.createDeliveryReceipt();
711 // Queue message. This is a) so that the user can check
712 // the receipt before sending and b) for speed reasons.
713 KernelIf
->msgSender()->send( receipt
, MessageSender::SendLater
);
719 //=============================================================================
720 // FilterActionSetTransport - set transport to...
721 // Specify mail transport (smtp server) to be used when replying to a message
722 // TODO: use TransportComboBox so the user does not enter an invalid transport
723 //=============================================================================
724 class FilterActionTransport
: public FilterActionWithString
727 FilterActionTransport( QObject
*parent
= 0 );
728 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
729 static FilterAction
* newAction();
732 FilterAction
* FilterActionTransport::newAction()
734 return new FilterActionTransport
;
737 FilterActionTransport::FilterActionTransport( QObject
*parent
)
738 : FilterActionWithString( "set transport", i18n( "Set Transport To" ), parent
)
742 FilterAction::ReturnCode
FilterActionTransport::process( const Akonadi::Item
&item
) const
744 if ( mParameter
.isEmpty() )
747 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
748 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "X-KMail-Transport", msg
.get(), mParameter
, "utf-8" );
749 msg
->setHeader( header
);
752 new Akonadi::ItemModifyJob( item
, FilterIf
->filterManager() );
758 //=============================================================================
759 // FilterActionReplyTo - set Reply-To to
760 // Set the Reply-to header in a message
761 //=============================================================================
762 class FilterActionReplyTo
: public FilterActionWithString
765 FilterActionReplyTo( QObject
*parent
= 0 );
766 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
767 static FilterAction
* newAction();
770 FilterAction
* FilterActionReplyTo::newAction()
772 return new FilterActionReplyTo
;
775 FilterActionReplyTo::FilterActionReplyTo( QObject
*parent
)
776 : FilterActionWithString( "set Reply-To", i18n( "Set Reply-To To" ), parent
)
781 FilterAction::ReturnCode
FilterActionReplyTo::process( const Akonadi::Item
&item
) const
783 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
784 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "Reply-To", msg
.get(), mParameter
, "utf-8" );
785 msg
->setHeader( header
);
788 new Akonadi::ItemModifyJob( item
, FilterIf
->filterManager() );
794 //=============================================================================
795 // FilterActionIdentity - set identity to
796 // Specify Identity to be used when replying to a message
797 //=============================================================================
798 class FilterActionIdentity
: public FilterActionWithUOID
801 FilterActionIdentity( QObject
*parent
= 0 );
802 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
803 static FilterAction
* newAction();
805 QWidget
* createParamWidget( QWidget
*parent
) const;
806 void applyParamWidgetValue( QWidget
*parent
);
807 void setParamWidgetValue( QWidget
*parent
) const;
808 void clearParamWidget( QWidget
*param
) const;
811 FilterAction
* FilterActionIdentity::newAction()
813 return new FilterActionIdentity
;
816 FilterActionIdentity::FilterActionIdentity( QObject
*parent
)
817 : FilterActionWithUOID( "set identity", i18n( "Set Identity To" ), parent
)
819 mParameter
= KernelIf
->identityManager()->defaultIdentity().uoid();
822 FilterAction::ReturnCode
FilterActionIdentity::process( const Akonadi::Item
&item
) const
824 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
825 KMime::Headers::Generic
*header
= new KMime::Headers::Generic( "X-KMail-Identity", msg
.get(), QString::number( mParameter
), "utf-8" );
826 msg
->setHeader( header
);
829 new Akonadi::ItemModifyJob( item
, FilterIf
->filterManager() );
834 QWidget
* FilterActionIdentity::createParamWidget( QWidget
*parent
) const
836 KPIMIdentities::IdentityCombo
*comboBox
= new KPIMIdentities::IdentityCombo( KernelIf
->identityManager(), parent
);
837 comboBox
->setCurrentIdentity( mParameter
);
839 connect( comboBox
, SIGNAL(currentIndexChanged(int)), this, SIGNAL(filterActionModified()) );
844 void FilterActionIdentity::applyParamWidgetValue( QWidget
*paramWidget
)
846 const KPIMIdentities::IdentityCombo
*comboBox
= dynamic_cast<KPIMIdentities::IdentityCombo
*>( paramWidget
);
847 Q_ASSERT( comboBox
);
849 mParameter
= comboBox
->currentIdentity();
852 void FilterActionIdentity::clearParamWidget( QWidget
*paramWidget
) const
854 KPIMIdentities::IdentityCombo
*comboBox
= dynamic_cast<KPIMIdentities::IdentityCombo
*>( paramWidget
);
855 Q_ASSERT( comboBox
);
857 comboBox
->setCurrentIndex( 0 );
860 void FilterActionIdentity::setParamWidgetValue( QWidget
*paramWidget
) const
862 KPIMIdentities::IdentityCombo
*comboBox
= dynamic_cast<KPIMIdentities::IdentityCombo
*>( paramWidget
);
863 Q_ASSERT( comboBox
);
865 comboBox
->setCurrentIdentity( mParameter
);
869 //=============================================================================
870 // FilterActionSetStatus - set status to
871 // Set the status of messages
872 //=============================================================================
873 class FilterActionSetStatus
: public FilterActionWithStringList
876 FilterActionSetStatus( QObject
*parent
= 0 );
877 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
878 virtual bool requiresBody() const;
880 static FilterAction
* newAction();
882 virtual bool isEmpty() const { return false; }
884 virtual void argsFromString( const QString
&argsStr
);
885 virtual QString
argsAsString() const;
886 virtual QString
displayString() const;
889 static const Akonadi::MessageStatus stati
[] =
891 Akonadi::MessageStatus::statusImportant(),
892 Akonadi::MessageStatus::statusRead(),
893 Akonadi::MessageStatus::statusUnread(),
894 Akonadi::MessageStatus::statusReplied(),
895 Akonadi::MessageStatus::statusForwarded(),
896 Akonadi::MessageStatus::statusWatched(),
897 Akonadi::MessageStatus::statusIgnored(),
898 Akonadi::MessageStatus::statusSpam(),
899 Akonadi::MessageStatus::statusHam(),
900 Akonadi::MessageStatus::statusToAct()
903 static const int StatiCount
= sizeof( stati
) / sizeof( Akonadi::MessageStatus
);
905 FilterAction
* FilterActionSetStatus::newAction()
907 return new FilterActionSetStatus
;
910 FilterActionSetStatus::FilterActionSetStatus( QObject
*parent
)
911 : FilterActionWithStringList( "set status", i18n( "Mark As" ), parent
)
913 // if you change this list, also update
914 // FilterActionSetStatus::stati above
915 mParameterList
.append( "" );
916 mParameterList
.append( i18nc( "msg status", "Important" ) );
917 mParameterList
.append( i18nc( "msg status", "Read" ) );
918 mParameterList
.append( i18nc( "msg status", "Unread" ) );
919 mParameterList
.append( i18nc( "msg status", "Replied" ) );
920 mParameterList
.append( i18nc( "msg status", "Forwarded" ) );
921 mParameterList
.append( i18nc( "msg status", "Watched" ) );
922 mParameterList
.append( i18nc( "msg status", "Ignored" ) );
923 mParameterList
.append( i18nc( "msg status", "Spam" ) );
924 mParameterList
.append( i18nc( "msg status", "Ham" ) );
925 mParameterList
.append( i18nc( "msg status", "Action Item" ) );
927 mParameter
= mParameterList
.at( 0 );
930 FilterAction::ReturnCode
FilterActionSetStatus::process( const Akonadi::Item
&item
) const
932 const int index
= mParameterList
.indexOf( mParameter
);
936 Akonadi::MessageStatus status
;
937 status
.setStatusFromFlags( item
.flags() );
939 const Akonadi::MessageStatus newStatus
= stati
[ index
- 1 ];
940 if ( newStatus
== Akonadi::MessageStatus::statusUnread() )
941 status
.setRead( false );
943 status
.set( newStatus
);
945 Akonadi::Item
newItem( item
.id() );
946 newItem
.setRevision( item
.revision() );
947 newItem
.setFlags( status
.statusFlags() );
948 new Akonadi::ItemModifyJob( newItem
, FilterIf
->filterManager() ); // TODO handle error
953 bool FilterActionSetStatus::requiresBody() const
958 static QString
realStatusString( const QString
&statusStr
)
960 QString
result( statusStr
);
962 if ( result
.size() == 2 )
963 result
.remove( QLatin1Char( 'U' ) );
968 void FilterActionSetStatus::argsFromString( const QString
&argsStr
)
970 if ( argsStr
.length() == 1 ) {
971 Akonadi::MessageStatus status
;
973 for ( int i
= 0 ; i
< StatiCount
; ++i
) {
975 if ( realStatusString( status
.statusStr() ) == argsStr
.toLatin1() ) {
976 mParameter
= mParameterList
.at( i
+ 1 );
982 mParameter
= mParameterList
.at( 0 );
985 QString
FilterActionSetStatus::argsAsString() const
987 const int index
= mParameterList
.indexOf( mParameter
);
991 return realStatusString( stati
[index
- 1].statusStr() );
994 QString
FilterActionSetStatus::displayString() const
996 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
1000 //=============================================================================
1001 // FilterActionAddTag - append tag to message
1002 // Appends a tag to messages
1003 //=============================================================================
1004 class FilterActionAddTag
: public FilterActionWithStringList
1007 FilterActionAddTag( QObject
*parent
= 0 );
1008 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1009 virtual bool requiresBody() const;
1011 static FilterAction
* newAction();
1013 virtual bool isEmpty() const { return false; }
1015 virtual void argsFromString( const QString
&argsStr
);
1016 virtual QString
argsAsString() const;
1017 virtual QString
displayString() const;
1020 QStringList mLabelList
;
1023 FilterAction
* FilterActionAddTag::newAction()
1025 return new FilterActionAddTag
;
1028 FilterActionAddTag::FilterActionAddTag( QObject
*parent
)
1029 : FilterActionWithStringList( "add tag", i18n( "Add Tag" ), parent
)
1031 #ifndef KDEPIM_NO_NEPOMUK
1032 foreach( const Nepomuk::Tag
&tag
, Nepomuk::Tag::allTags() ) {
1033 mParameterList
.append( tag
.label() );
1034 mLabelList
.append( tag
.resourceUri().toString() );
1039 FilterAction::ReturnCode
FilterActionAddTag::process( const Akonadi::Item
&item
) const
1041 #ifndef KDEPIM_NO_NEPOMUK
1042 const int index
= mParameterList
.indexOf( mParameter
);
1044 return ErrorButGoOn
;
1046 Nepomuk::Resource
resource( item
.url() );
1047 resource
.addTag( mParameter
);
1053 bool FilterActionAddTag::requiresBody() const
1058 void FilterActionAddTag::argsFromString( const QString
&argsStr
)
1060 foreach ( const QString
& tag
, mParameterList
) {
1061 if ( tag
== argsStr
) {
1067 if ( mParameterList
.size() > 0 )
1068 mParameter
= mParameterList
.at( 0 );
1071 QString
FilterActionAddTag::argsAsString() const
1073 const int index
= mParameterList
.indexOf( mParameter
);
1077 return mParameterList
.at( index
);
1080 QString
FilterActionAddTag::displayString() const
1082 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
1086 //=============================================================================
1087 // FilterActionFakeDisposition - send fake MDN
1088 // Sends a fake MDN or forces an ignore.
1089 //=============================================================================
1090 class FilterActionFakeDisposition
: public FilterActionWithStringList
1093 FilterActionFakeDisposition( QObject
*parent
= 0 );
1094 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1095 static FilterAction
* newAction()
1097 return new FilterActionFakeDisposition
;
1100 virtual bool isEmpty() const { return false; }
1102 virtual void argsFromString( const QString
&argsStr
);
1103 virtual QString
argsAsString() const;
1104 virtual QString
displayString() const;
1108 // if you change this list, also update
1109 // the count in argsFromString
1110 static const KMime::MDN::DispositionType mdns
[] =
1112 KMime::MDN::Displayed
,
1113 KMime::MDN::Deleted
,
1114 KMime::MDN::Dispatched
,
1115 KMime::MDN::Processed
,
1119 static const int numMDNs
= sizeof( mdns
) / sizeof( *mdns
);
1122 FilterActionFakeDisposition::FilterActionFakeDisposition( QObject
*parent
)
1123 : FilterActionWithStringList( "fake mdn", i18n( "Send Fake MDN" ), parent
)
1125 // if you change this list, also update
1127 mParameterList
.append( "" );
1128 mParameterList
.append( i18nc( "MDN type", "Ignore" ) );
1129 mParameterList
.append( i18nc( "MDN type", "Displayed" ) );
1130 mParameterList
.append( i18nc( "MDN type", "Deleted" ) );
1131 mParameterList
.append( i18nc( "MDN type", "Dispatched" ) );
1132 mParameterList
.append( i18nc( "MDN type", "Processed" ) );
1133 mParameterList
.append( i18nc( "MDN type", "Denied" ) );
1134 mParameterList
.append( i18nc( "MDN type", "Failed" ) );
1136 mParameter
= mParameterList
.at( 0 );
1139 FilterAction::ReturnCode
FilterActionFakeDisposition::process( const Akonadi::Item
&item
) const
1141 const int index
= mParameterList
.indexOf( mParameter
);
1143 return ErrorButGoOn
;
1145 if ( index
== 1 ) { // ignore
1146 if ( item
.hasAttribute
<MessageCore::MDNStateAttribute
>() ) {
1147 item
.attribute
<MessageCore::MDNStateAttribute
>()->setMDNState( MessageCore::MDNStateAttribute::MDNIgnore
);
1148 Akonadi::ItemModifyJob
* modifyJob
= new Akonadi::ItemModifyJob( item
);
1149 modifyJob
->setIgnorePayload( true );
1152 sendMDN( item
, mdns
[ index
- 2 ] ); // skip first two entries: "" and "ignore"
1157 void FilterActionFakeDisposition::argsFromString( const QString
&argsStr
)
1159 if ( argsStr
.length() == 1 ) {
1160 if ( argsStr
[ 0 ] == 'I' ) { // ignore
1161 mParameter
= mParameterList
.at( 1 );
1165 for ( int i
= 0 ; i
< numMDNs
; i
++ ) {
1166 if ( char( mdns
[ i
] ) == argsStr
[ 0 ] ) { // send
1167 mParameter
= mParameterList
.at( i
+ 2 );
1173 mParameter
= mParameterList
.at( 0 );
1176 QString
FilterActionFakeDisposition::argsAsString() const
1178 const int index
= mParameterList
.indexOf( mParameter
);
1182 return QString( QChar( index
< 2 ? 'I' : char( mdns
[ index
- 2 ] ) ) );
1185 QString
FilterActionFakeDisposition::displayString() const
1187 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
1191 //=============================================================================
1192 // FilterActionRemoveHeader - remove header
1193 // Remove all instances of the given header field.
1194 //=============================================================================
1195 class FilterActionRemoveHeader
: public FilterActionWithStringList
1198 FilterActionRemoveHeader( QObject
*parent
= 0 );
1199 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1200 virtual QWidget
* createParamWidget( QWidget
*parent
) const;
1201 virtual void setParamWidgetValue( QWidget
*paramWidget
) const;
1203 static FilterAction
* newAction();
1206 FilterAction
* FilterActionRemoveHeader::newAction()
1208 return new FilterActionRemoveHeader
;
1211 FilterActionRemoveHeader::FilterActionRemoveHeader( QObject
*parent
)
1212 : FilterActionWithStringList( "remove header", i18n( "Remove Header" ), parent
)
1214 mParameterList
<< ""
1217 << "X-KDE-PR-Message"
1218 << "X-KDE-PR-Package"
1219 << "X-KDE-PR-Keywords";
1221 mParameter
= mParameterList
.at( 0 );
1224 QWidget
* FilterActionRemoveHeader::createParamWidget( QWidget
*parent
) const
1226 MinimumComboBox
*comboBox
= new MinimumComboBox( parent
);
1227 comboBox
->setEditable( true );
1228 comboBox
->setInsertPolicy( QComboBox::InsertAtBottom
);
1229 setParamWidgetValue( comboBox
);
1231 connect( comboBox
, SIGNAL(currentIndexChanged(int)),
1232 this, SIGNAL(filterActionModified()) );
1237 FilterAction::ReturnCode
FilterActionRemoveHeader::process( const Akonadi::Item
&item
) const
1239 if ( mParameter
.isEmpty() )
1240 return ErrorButGoOn
;
1242 KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1243 while ( msg
->headerByType( mParameter
.toLatin1() ) )
1244 msg
->removeHeader( mParameter
.toLatin1() );
1248 new Akonadi::ItemModifyJob( item
, FilterIf
->filterManager() );
1253 void FilterActionRemoveHeader::setParamWidgetValue( QWidget
*paramWidget
) const
1255 MinimumComboBox
*comboBox
= dynamic_cast<MinimumComboBox
*>(paramWidget
);
1256 Q_ASSERT( comboBox
);
1258 const int index
= mParameterList
.indexOf( mParameter
);
1260 comboBox
->addItems( mParameterList
);
1262 comboBox
->addItem( mParameter
);
1263 comboBox
->setCurrentIndex( comboBox
->count() - 1 );
1265 comboBox
->setCurrentIndex( index
);
1270 //=============================================================================
1271 // FilterActionAddHeader - add header
1272 // Add a header with the given value.
1273 //=============================================================================
1274 class FilterActionAddHeader
: public FilterActionWithStringList
1277 FilterActionAddHeader( QObject
*parent
= 0 );
1278 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1279 virtual QWidget
* createParamWidget( QWidget
*parent
) const;
1280 virtual void setParamWidgetValue( QWidget
*paramWidget
) const;
1281 virtual void applyParamWidgetValue( QWidget
*paramWidget
);
1282 virtual void clearParamWidget( QWidget
*paramWidget
) const;
1284 virtual QString
argsAsString() const;
1285 virtual void argsFromString( const QString
&argsStr
);
1287 virtual QString
displayString() const;
1289 static FilterAction
* newAction()
1291 return new FilterActionAddHeader
;
1298 FilterActionAddHeader::FilterActionAddHeader( QObject
*parent
)
1299 : FilterActionWithStringList( "add header", i18n( "Add Header" ), parent
)
1301 mParameterList
<< ""
1304 << "X-KDE-PR-Message"
1305 << "X-KDE-PR-Package"
1306 << "X-KDE-PR-Keywords";
1308 mParameter
= mParameterList
.at( 0 );
1311 FilterAction::ReturnCode
FilterActionAddHeader::process( const Akonadi::Item
&item
) const
1313 if ( mParameter
.isEmpty() )
1314 return ErrorButGoOn
;
1316 KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1318 KMime::Headers::Base
*header
= KMime::Headers::createHeader( mParameter
.toLatin1() );
1320 header
= new KMime::Headers::Generic( mParameter
.toLatin1(), msg
.get(), mValue
, "utf-8" );
1322 header
->fromUnicodeString( mValue
, "utf-8" );
1325 msg
->setHeader( header
);
1328 new Akonadi::ItemModifyJob( item
, FilterIf
->filterManager() );
1333 QWidget
* FilterActionAddHeader::createParamWidget( QWidget
*parent
) const
1335 QWidget
*widget
= new QWidget( parent
);
1336 QHBoxLayout
*layout
= new QHBoxLayout( widget
);
1337 layout
->setSpacing( 4 );
1338 layout
->setMargin( 0 );
1340 MinimumComboBox
*comboBox
= new MinimumComboBox( widget
);
1341 comboBox
->setObjectName( "combo" );
1342 comboBox
->setEditable( true );
1343 comboBox
->setInsertPolicy( QComboBox::InsertAtBottom
);
1344 layout
->addWidget( comboBox
, 0 /* stretch */ );
1346 QLabel
*label
= new QLabel( i18n( "With value:" ), widget
);
1347 label
->setFixedWidth( label
->sizeHint().width() );
1348 layout
->addWidget( label
, 0 );
1350 KLineEdit
*lineEdit
= new KLineEdit( widget
);
1351 lineEdit
->setObjectName( "ledit" );
1352 lineEdit
->setClearButtonShown( true );
1353 layout
->addWidget( lineEdit
, 1 );
1355 setParamWidgetValue( widget
);
1357 connect( comboBox
, SIGNAL(currentIndexChanged(int)),
1358 this, SIGNAL(filterActionModified()) );
1359 connect( lineEdit
, SIGNAL(textChanged(QString
)),
1360 this, SIGNAL(filterActionModified()) );
1365 void FilterActionAddHeader::setParamWidgetValue( QWidget
*paramWidget
) const
1367 const int index
= mParameterList
.indexOf( mParameter
);
1369 MinimumComboBox
*comboBox
= paramWidget
->findChild
<MinimumComboBox
*>( "combo" );
1370 Q_ASSERT( comboBox
);
1372 comboBox
->addItems( mParameterList
);
1375 comboBox
->addItem( mParameter
);
1376 comboBox
->setCurrentIndex( comboBox
->count() - 1 );
1378 comboBox
->setCurrentIndex( index
);
1381 KLineEdit
*lineEdit
= paramWidget
->findChild
<KLineEdit
*>( "ledit" );
1382 Q_ASSERT( lineEdit
);
1384 lineEdit
->setText( mValue
);
1387 void FilterActionAddHeader::applyParamWidgetValue( QWidget
*paramWidget
)
1389 const MinimumComboBox
*comboBox
= paramWidget
->findChild
<MinimumComboBox
*>( "combo" );
1390 Q_ASSERT( comboBox
);
1391 mParameter
= comboBox
->currentText();
1393 const KLineEdit
*lineEdit
= paramWidget
->findChild
<KLineEdit
*>( "ledit" );
1394 Q_ASSERT( lineEdit
);
1395 mValue
= lineEdit
->text();
1398 void FilterActionAddHeader::clearParamWidget( QWidget
*paramWidget
) const
1400 MinimumComboBox
*comboBox
= paramWidget
->findChild
<MinimumComboBox
*>( "combo" );
1401 Q_ASSERT( comboBox
);
1402 comboBox
->setCurrentIndex( 0 );
1404 KLineEdit
*lineEdit
= paramWidget
->findChild
<KLineEdit
*>( "ledit" );
1405 Q_ASSERT( lineEdit
);
1409 QString
FilterActionAddHeader::argsAsString() const
1411 QString result
= mParameter
;
1412 result
+= QLatin1Char( '\t' );
1418 QString
FilterActionAddHeader::displayString() const
1420 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
1423 void FilterActionAddHeader::argsFromString( const QString
&argsStr
)
1425 const QStringList list
= argsStr
.split( QLatin1Char( '\t' ) );
1427 if ( list
.count() < 2 ) {
1435 int index
= mParameterList
.indexOf( result
);
1437 mParameterList
.append( result
);
1438 index
= mParameterList
.count() - 1;
1441 mParameter
= mParameterList
.at( index
);
1445 //=============================================================================
1446 // FilterActionRewriteHeader - rewrite header
1447 // Rewrite a header using a regexp.
1448 //=============================================================================
1449 class FilterActionRewriteHeader
: public FilterActionWithStringList
1452 FilterActionRewriteHeader( QObject
*parent
= 0 );
1453 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1454 virtual QWidget
* createParamWidget( QWidget
*parent
) const;
1455 virtual void setParamWidgetValue( QWidget
*paramWidget
) const;
1456 virtual void applyParamWidgetValue( QWidget
*paramWidget
);
1457 virtual void clearParamWidget( QWidget
*paramWidget
) const;
1459 virtual QString
argsAsString() const;
1460 virtual void argsFromString( const QString
&argsStr
);
1462 virtual QString
displayString() const;
1464 static FilterAction
* newAction()
1466 return new FilterActionRewriteHeader
;
1471 QString mReplacementString
;
1474 FilterActionRewriteHeader::FilterActionRewriteHeader( QObject
*parent
)
1475 : FilterActionWithStringList( "rewrite header", i18n( "Rewrite Header" ), parent
)
1477 mParameterList
<< ""
1481 << "X-KDE-PR-Message"
1482 << "X-KDE-PR-Package"
1483 << "X-KDE-PR-Keywords";
1485 mParameter
= mParameterList
.at( 0 );
1488 FilterAction::ReturnCode
FilterActionRewriteHeader::process( const Akonadi::Item
&item
) const
1490 if ( mParameter
.isEmpty() || !mRegExp
.isValid() )
1491 return ErrorButGoOn
;
1493 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1495 KMime::Headers::Base
*header
= msg
->headerByType( mParameter
.toLatin1() );
1496 QString value
= header
? header
->asUnicodeString(): "";
1498 const QString newValue
= value
.replace( mRegExp
, mReplacementString
);
1501 return GoOn
; //TODO: Maybe create a new header by type?
1504 header
->fromUnicodeString( newValue
, "utf-8" );
1507 new Akonadi::ItemModifyJob( item
, FilterIf
->filterManager() );
1512 QWidget
* FilterActionRewriteHeader::createParamWidget( QWidget
*parent
) const
1514 QWidget
*widget
= new QWidget( parent
);
1515 QHBoxLayout
*layout
= new QHBoxLayout( widget
);
1516 layout
->setSpacing( 4 );
1517 layout
->setMargin( 0 );
1519 MinimumComboBox
*comboBox
= new MinimumComboBox( widget
);
1520 comboBox
->setEditable( true );
1521 comboBox
->setObjectName( "combo" );
1522 comboBox
->setInsertPolicy( QComboBox::InsertAtBottom
);
1523 layout
->addWidget( comboBox
, 0 /* stretch */ );
1525 QLabel
*label
= new QLabel( i18n( "Replace:" ), widget
);
1526 label
->setFixedWidth( label
->sizeHint().width() );
1527 layout
->addWidget( label
, 0 );
1529 RegExpLineEdit
*regExpLineEdit
= new RegExpLineEdit( widget
);
1530 regExpLineEdit
->setObjectName( "search" );
1531 layout
->addWidget( regExpLineEdit
, 1 );
1533 label
= new QLabel( i18n( "With:" ), widget
);
1534 label
->setFixedWidth( label
->sizeHint().width() );
1535 layout
->addWidget( label
, 0 );
1537 KLineEdit
*lineEdit
= new KLineEdit( widget
);
1538 lineEdit
->setObjectName( "replace" );
1539 lineEdit
->setClearButtonShown( true );
1540 layout
->addWidget( lineEdit
, 1 );
1542 setParamWidgetValue( widget
);
1544 connect( comboBox
, SIGNAL(currentIndexChanged(int)),
1545 this, SIGNAL(filterActionModified()) );
1546 connect( regExpLineEdit
, SIGNAL(textChanged(QString
)),
1547 this, SIGNAL(filterActionModified()) );
1548 connect( lineEdit
, SIGNAL(textChanged(QString
)),
1549 this, SIGNAL(filterActionModified()) );
1554 void FilterActionRewriteHeader::setParamWidgetValue( QWidget
*paramWidget
) const
1556 const int index
= mParameterList
.indexOf( mParameter
);
1557 MinimumComboBox
*comboBox
= paramWidget
->findChild
<MinimumComboBox
*>( "combo" );
1558 Q_ASSERT( comboBox
);
1561 comboBox
->addItems( mParameterList
);
1563 comboBox
->addItem( mParameter
);
1564 comboBox
->setCurrentIndex( comboBox
->count() - 1 );
1566 comboBox
->setCurrentIndex( index
);
1569 RegExpLineEdit
*regExpLineEdit
= paramWidget
->findChild
<RegExpLineEdit
*>( "search" );
1570 Q_ASSERT( regExpLineEdit
);
1571 regExpLineEdit
->setText( mRegExp
.pattern() );
1573 KLineEdit
*lineEdit
= paramWidget
->findChild
<KLineEdit
*>( "replace" );
1574 Q_ASSERT( lineEdit
);
1575 lineEdit
->setText( mReplacementString
);
1578 void FilterActionRewriteHeader::applyParamWidgetValue( QWidget
*paramWidget
)
1580 const MinimumComboBox
*comboBox
= paramWidget
->findChild
<MinimumComboBox
*>( "combo" );
1581 Q_ASSERT( comboBox
);
1582 mParameter
= comboBox
->currentText();
1584 const RegExpLineEdit
*regExpLineEdit
= paramWidget
->findChild
<RegExpLineEdit
*>( "search" );
1585 Q_ASSERT( regExpLineEdit
);
1586 mRegExp
.setPattern( regExpLineEdit
->text() );
1588 const KLineEdit
*lineEdit
= paramWidget
->findChild
<KLineEdit
*>( "replace" );
1589 Q_ASSERT( lineEdit
);
1590 mReplacementString
= lineEdit
->text();
1593 void FilterActionRewriteHeader::clearParamWidget( QWidget
*paramWidget
) const
1595 MinimumComboBox
*comboBox
= paramWidget
->findChild
<MinimumComboBox
*>( "combo" );
1596 Q_ASSERT( comboBox
);
1597 comboBox
->setCurrentIndex( 0 );
1599 RegExpLineEdit
*regExpLineEdit
= paramWidget
->findChild
<RegExpLineEdit
*>( "search" );
1600 Q_ASSERT( regExpLineEdit
);
1601 regExpLineEdit
->clear();
1603 KLineEdit
*lineEdit
= paramWidget
->findChild
<KLineEdit
*>( "replace" );
1604 Q_ASSERT( lineEdit
);
1608 QString
FilterActionRewriteHeader::argsAsString() const
1610 QString result
= mParameter
;
1611 result
+= QLatin1Char( '\t' );
1612 result
+= mRegExp
.pattern();
1613 result
+= QLatin1Char( '\t' );
1614 result
+= mReplacementString
;
1619 QString
FilterActionRewriteHeader::displayString() const
1621 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
1624 void FilterActionRewriteHeader::argsFromString( const QString
&argsStr
)
1626 const QStringList list
= argsStr
.split( QLatin1Char( '\t' ) );
1630 mRegExp
.setPattern( list
[ 1 ] );
1631 mReplacementString
= list
[ 2 ];
1633 int index
= mParameterList
.indexOf( result
);
1635 mParameterList
.append( result
);
1636 index
= mParameterList
.count() - 1;
1639 mParameter
= mParameterList
.at( index
);
1643 //=============================================================================
1644 // FilterActionMove - move into folder
1645 // File message into another mail folder
1646 //=============================================================================
1647 class FilterActionMove
: public FilterActionWithFolder
1650 FilterActionMove( QObject
*parent
= 0 );
1651 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1652 virtual bool requiresBody() const;
1653 static FilterAction
* newAction();
1656 FilterAction
* FilterActionMove::newAction()
1658 return new FilterActionMove
;
1661 FilterActionMove::FilterActionMove( QObject
*parent
)
1662 : FilterActionWithFolder( "transfer", i18n( "Move Into Folder" ), parent
)
1666 FilterAction::ReturnCode
FilterActionMove::process( const Akonadi::Item
&item
) const
1668 if ( !mFolder
.isValid() ) {
1669 const Akonadi::Collection targetFolder
= CommonKernel
->collectionFromId( mFolderName
);
1670 if ( !targetFolder
.isValid() )
1671 return ErrorButGoOn
;
1673 MessageProperty::setFilterFolder( item
, targetFolder
);
1677 MessageProperty::setFilterFolder( item
, mFolder
);
1681 bool FilterActionMove::requiresBody() const
1687 //=============================================================================
1688 // FilterActionCopy - copy into folder
1689 // Copy message into another mail folder
1690 //=============================================================================
1691 class FilterActionCopy
: public FilterActionWithFolder
1694 FilterActionCopy( QObject
*parent
= 0 );
1695 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1696 virtual bool requiresBody() const;
1697 static FilterAction
* newAction();
1700 FilterAction
* FilterActionCopy::newAction()
1702 return new FilterActionCopy
;
1705 FilterActionCopy::FilterActionCopy( QObject
*parent
)
1706 : FilterActionWithFolder( "copy", i18n( "Copy Into Folder" ), parent
)
1710 FilterAction::ReturnCode
FilterActionCopy::process( const Akonadi::Item
&item
) const
1712 // copy the message 1:1
1713 new Akonadi::ItemCopyJob( item
, mFolder
, FilterIf
->filterManager() ); // TODO handle error
1718 bool FilterActionCopy::requiresBody() const
1724 //=============================================================================
1725 // FilterActionForward - forward to
1726 // Forward message to another user, with a defined template
1727 //=============================================================================
1728 class FilterActionForward
: public FilterActionWithAddress
1731 FilterActionForward( QObject
*parent
= 0 );
1732 static FilterAction
* newAction();
1733 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1734 virtual QWidget
* createParamWidget( QWidget
*parent
) const;
1735 virtual void applyParamWidgetValue( QWidget
*paramWidget
);
1736 virtual void setParamWidgetValue( QWidget
*paramWidget
) const;
1737 virtual void clearParamWidget( QWidget
*paramWidget
) const;
1738 virtual void argsFromString( const QString
&argsStr
);
1739 virtual QString
argsAsString() const;
1740 virtual QString
displayString() const;
1743 mutable QString mTemplate
;
1746 FilterAction
*FilterActionForward::newAction()
1748 return new FilterActionForward
;
1751 FilterActionForward::FilterActionForward( QObject
*parent
)
1752 : FilterActionWithAddress( "forward", i18n( "Forward To" ), parent
)
1756 FilterAction::ReturnCode
FilterActionForward::process( const Akonadi::Item
&item
) const
1758 if ( mParameter
.isEmpty() )
1759 return ErrorButGoOn
;
1761 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
1762 // avoid endless loops when this action is used in a filter
1763 // which applies to sent messages
1764 if ( MessageCore::StringUtil::addressIsInAddressList( mParameter
,
1765 QStringList( msg
->to()->asUnicodeString() ) ) ) {
1766 kWarning() << "Attempt to forward to receipient of original message, ignoring.";
1767 return ErrorButGoOn
;
1770 MessageFactory
factory( msg
, item
.id() );
1771 factory
.setIdentityManager( KernelIf
->identityManager() );
1772 factory
.setFolderIdentity( Util::folderIdentity( item
) );
1773 factory
.setTemplate( mTemplate
);
1775 KMime::Message::Ptr fwdMsg
= factory
.createForward();
1776 fwdMsg
->to()->fromUnicodeString( fwdMsg
->to()->asUnicodeString() + QLatin1Char( ',' ) + mParameter
, "utf-8" );
1777 if ( !KernelIf
->msgSender()->send( fwdMsg
, MessageSender::SendDefault
) ) {
1778 kWarning() << "FilterAction: could not forward message (sending failed)";
1779 return ErrorButGoOn
; // error: couldn't send
1781 sendMDN( item
, KMime::MDN::Dispatched
);
1783 // (the msgSender takes ownership of the message, so don't delete it here)
1787 QWidget
* FilterActionForward::createParamWidget( QWidget
*parent
) const
1789 QWidget
*addressAndTemplate
= new QWidget( parent
);
1790 QHBoxLayout
*layout
= new QHBoxLayout( addressAndTemplate
);
1791 layout
->setMargin( 0 );
1793 QWidget
*addressEdit
= FilterActionWithAddress::createParamWidget( addressAndTemplate
);
1794 addressEdit
->setObjectName( "addressEdit" );
1795 layout
->addWidget( addressEdit
);
1797 MessageCore::EmailAddressRequester
*addressRequester
= qobject_cast
<MessageCore::EmailAddressRequester
*>( addressEdit
);
1798 Q_ASSERT( addressRequester
);
1799 KLineEdit
*lineEdit
= addressRequester
->lineEdit();
1800 lineEdit
->setToolTip( i18n( "The addressee to whom the message will be forwarded." ) );
1801 lineEdit
->setWhatsThis( i18n( "The filter will forward the message to the addressee entered here." ) );
1803 MinimumComboBox
*templateCombo
= new MinimumComboBox( addressAndTemplate
);
1804 templateCombo
->setObjectName( "templateCombo" );
1805 layout
->addWidget( templateCombo
);
1807 templateCombo
->addItem( i18n( "Default Template" ) );
1809 const QStringList templateNames
= SettingsIf
->customTemplates();
1810 foreach( const QString
&templateName
, templateNames
) {
1811 CTemplates
templat( templateName
);
1812 if ( templat
.type() == CustomTemplates::TForward
||
1813 templat
.type() == CustomTemplates::TUniversal
)
1814 templateCombo
->addItem( templateName
);
1817 templateCombo
->setEnabled( templateCombo
->count() > 1 );
1818 templateCombo
->setToolTip( i18n( "The template used when forwarding" ) );
1819 templateCombo
->setWhatsThis( i18n( "Set the forwarding template that will be used with this filter." ) );
1821 connect( templateCombo
, SIGNAL(currentIndexChanged(int)),
1822 this, SIGNAL(filterActionModified()) );
1823 connect( addressRequester
, SIGNAL(textChanged()),
1824 this, SIGNAL(filterActionModified()) );
1826 return addressAndTemplate
;
1829 void FilterActionForward::applyParamWidgetValue( QWidget
*paramWidget
)
1831 QWidget
*addressEdit
= paramWidget
->findChild
<QWidget
*>( "addressEdit" );
1832 Q_ASSERT( addressEdit
);
1833 FilterActionWithAddress::applyParamWidgetValue( addressEdit
);
1835 const MinimumComboBox
*templateCombo
= paramWidget
->findChild
<MinimumComboBox
*>( "templateCombo" );
1836 Q_ASSERT( templateCombo
);
1838 if ( templateCombo
->currentIndex() == 0 ) {
1839 // Default template, so don't use a custom one
1842 mTemplate
= templateCombo
->currentText();
1846 void FilterActionForward::setParamWidgetValue( QWidget
*paramWidget
) const
1848 QWidget
*addressEdit
= paramWidget
->findChild
<QWidget
*>( "addressEdit" );
1849 Q_ASSERT( addressEdit
);
1850 FilterActionWithAddress::setParamWidgetValue( addressEdit
);
1852 MinimumComboBox
*templateCombo
= paramWidget
->findChild
<MinimumComboBox
*>( "templateCombo" );
1853 Q_ASSERT( templateCombo
);
1855 if ( mTemplate
.isEmpty() ) {
1856 templateCombo
->setCurrentIndex( 0 );
1858 int templateIndex
= templateCombo
->findText( mTemplate
);
1859 if ( templateIndex
!= -1 ) {
1860 templateCombo
->setCurrentIndex( templateIndex
);
1867 void FilterActionForward::clearParamWidget( QWidget
*paramWidget
) const
1869 QWidget
*addressEdit
= paramWidget
->findChild
<QWidget
*>( "addressEdit" );
1870 Q_ASSERT( addressEdit
);
1871 FilterActionWithAddress::clearParamWidget( addressEdit
);
1873 MinimumComboBox
*templateCombo
= paramWidget
->findChild
<MinimumComboBox
*>( "templateCombo" );
1874 Q_ASSERT( templateCombo
);
1876 templateCombo
->setCurrentIndex( 0 );
1879 // We simply place a "@$$@" between the two parameters. The template is the last
1880 // parameter in the string, for compatibility reasons.
1881 static const QString forwardFilterArgsSeperator
= "@$$@";
1883 void FilterActionForward::argsFromString( const QString
&argsStr
)
1885 const int seperatorPos
= argsStr
.indexOf( forwardFilterArgsSeperator
);
1887 if ( seperatorPos
== - 1 ) {
1888 // Old config, assume that the whole string is the addressee
1889 FilterActionWithAddress::argsFromString( argsStr
);
1891 const QString addressee
= argsStr
.left( seperatorPos
);
1892 mTemplate
= argsStr
.mid( seperatorPos
+ forwardFilterArgsSeperator
.length() );
1893 FilterActionWithAddress::argsFromString( addressee
);
1897 QString
FilterActionForward::argsAsString() const
1899 return FilterActionWithAddress::argsAsString() + forwardFilterArgsSeperator
+ mTemplate
;
1902 QString
FilterActionForward::displayString() const
1904 if ( mTemplate
.isEmpty() )
1905 return i18n( "Forward to %1 with default template", mParameter
);
1907 return i18n( "Forward to %1 with template %2", mParameter
, mTemplate
);
1911 //=============================================================================
1912 // FilterActionRedirect - redirect to
1913 // Redirect message to another user
1914 //=============================================================================
1915 class FilterActionRedirect
: public FilterActionWithAddress
1918 FilterActionRedirect( QObject
*parent
= 0 );
1919 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1920 static FilterAction
* newAction();
1923 FilterAction
* FilterActionRedirect::newAction()
1925 return new FilterActionRedirect
;
1928 FilterActionRedirect::FilterActionRedirect( QObject
*parent
)
1929 : FilterActionWithAddress( "redirect", i18n( "Redirect To" ), parent
)
1933 FilterAction::ReturnCode
FilterActionRedirect::process( const Akonadi::Item
&item
) const
1935 if ( mParameter
.isEmpty() )
1936 return ErrorButGoOn
;
1938 KMime::Message::Ptr msg
= MessageCore::Util::message( item
);
1940 MessageFactory
factory( msg
, item
.id() );
1941 factory
.setFolderIdentity( Util::folderIdentity( item
) );
1942 factory
.setIdentityManager( KernelIf
->identityManager() );
1944 KMime::Message::Ptr rmsg
= factory
.createRedirect( mParameter
);
1946 return ErrorButGoOn
;
1948 sendMDN( item
, KMime::MDN::Dispatched
);
1950 if ( !KernelIf
->msgSender()->send( rmsg
, MessageSender::SendLater
) ) {
1951 kDebug() << "FilterAction: could not redirect message (sending failed)";
1952 return ErrorButGoOn
; // error: couldn't send
1959 //=============================================================================
1960 // FilterActionExec - execute command
1961 // Execute a shell command
1962 //=============================================================================
1963 class FilterActionExec
: public FilterActionWithCommand
1966 FilterActionExec( QObject
*parent
= 0 );
1967 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1968 static FilterAction
* newAction();
1971 FilterAction
* FilterActionExec::newAction()
1973 return new FilterActionExec();
1976 FilterActionExec::FilterActionExec( QObject
*parent
)
1977 : FilterActionWithCommand( "execute", i18n( "Execute Command" ), parent
)
1981 FilterAction::ReturnCode
FilterActionExec::process( const Akonadi::Item
&item
) const
1983 return FilterActionWithCommand::genericProcess( item
, false ); // ignore output
1987 //=============================================================================
1988 // FilterActionExtFilter - use external filter app
1989 // External message filter: executes a shell command with message
1990 // on stdin; altered message is expected on stdout.
1991 //=============================================================================
1992 class FilterActionExtFilter
: public FilterActionWithCommand
1995 FilterActionExtFilter( QObject
*parent
= 0 );
1996 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
1997 static FilterAction
* newAction();
2000 FilterAction
* FilterActionExtFilter::newAction()
2002 return new FilterActionExtFilter
;
2005 FilterActionExtFilter::FilterActionExtFilter( QObject
*parent
)
2006 : FilterActionWithCommand( "filter app", i18n( "Pipe Through" ), parent
)
2010 FilterAction::ReturnCode
FilterActionExtFilter::process( const Akonadi::Item
&item
) const
2012 return FilterActionWithCommand::genericProcess( item
, true ); // use output
2017 //=============================================================================
2018 // FilterActionExecSound - execute command
2020 //=============================================================================
2021 class FilterActionExecSound
: public FilterActionWithTest
2024 FilterActionExecSound( QObject
*parent
= 0 );
2025 ~FilterActionExecSound();
2026 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
2027 virtual bool requiresBody() const;
2028 static FilterAction
* newAction();
2031 mutable Phonon::MediaObject
* mPlayer
;
2034 FilterActionWithTest::FilterActionWithTest( const char *name
, const QString
&label
, QObject
*parent
)
2035 : FilterAction( name
, label
, parent
)
2039 FilterActionWithTest::~FilterActionWithTest()
2043 bool FilterActionWithTest::isEmpty() const
2045 return mParameter
.trimmed().isEmpty();
2048 QWidget
* FilterActionWithTest::createParamWidget( QWidget
*parent
) const
2050 SoundTestWidget
*soundWidget
= new SoundTestWidget( parent
);
2051 soundWidget
->setUrl( mParameter
);
2053 connect( soundWidget
, SIGNAL(textChanged(QString
)),
2054 this, SIGNAL(filterActionModified()) );
2060 void FilterActionWithTest::applyParamWidgetValue( QWidget
*paramWidget
)
2062 mParameter
= static_cast<SoundTestWidget
*>( paramWidget
)->url();
2065 void FilterActionWithTest::setParamWidgetValue( QWidget
*paramWidget
) const
2067 static_cast<SoundTestWidget
*>( paramWidget
)->setUrl( mParameter
);
2070 void FilterActionWithTest::clearParamWidget( QWidget
*paramWidget
) const
2072 static_cast<SoundTestWidget
*>( paramWidget
)->clear();
2075 void FilterActionWithTest::argsFromString( const QString
&argsStr
)
2077 mParameter
= argsStr
;
2080 QString
FilterActionWithTest::argsAsString() const
2085 QString
FilterActionWithTest::displayString() const
2087 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
2090 FilterActionExecSound::FilterActionExecSound( QObject
*parent
)
2091 : FilterActionWithTest( "play sound", i18n( "Play Sound" ) ),
2096 FilterActionExecSound::~FilterActionExecSound()
2101 FilterAction
* FilterActionExecSound::newAction()
2103 return new FilterActionExecSound();
2106 FilterAction::ReturnCode
FilterActionExecSound::process( const Akonadi::Item
& ) const
2108 if ( mParameter
.isEmpty() )
2109 return ErrorButGoOn
;
2112 mPlayer
= Phonon::createPlayer( Phonon::NotificationCategory
);
2114 mPlayer
->setCurrentSource( mParameter
);
2120 bool FilterActionExecSound::requiresBody() const
2127 FilterActionWithUrl::FilterActionWithUrl( const char *name
, const QString
&label
, QObject
*parent
)
2128 : FilterAction( name
, label
, parent
)
2132 FilterActionWithUrl::~FilterActionWithUrl()
2136 bool FilterActionWithUrl::isEmpty() const
2138 return mParameter
.trimmed().isEmpty();
2141 QWidget
* FilterActionWithUrl::createParamWidget( QWidget
*parent
) const
2143 KUrlRequester
*requester
= new KUrlRequester( parent
);
2144 requester
->setUrl( KUrl( mParameter
) );
2146 connect( requester
, SIGNAL(textChanged(QString
)), this, SIGNAL(filterActionModified()) );
2152 void FilterActionWithUrl::applyParamWidgetValue( QWidget
*paramWidget
)
2154 const KUrl url
= static_cast<KUrlRequester
*>( paramWidget
)->url();
2156 mParameter
= (url
.isLocalFile() ? url
.toLocalFile() : url
.path());
2159 void FilterActionWithUrl::setParamWidgetValue( QWidget
*paramWidget
) const
2161 static_cast<KUrlRequester
*>( paramWidget
)->setUrl( KUrl( mParameter
) );
2164 void FilterActionWithUrl::clearParamWidget( QWidget
*paramWidget
) const
2166 static_cast<KUrlRequester
*>( paramWidget
)->clear();
2169 void FilterActionWithUrl::argsFromString( const QString
&argsStr
)
2171 mParameter
= argsStr
;
2174 QString
FilterActionWithUrl::argsAsString() const
2179 QString
FilterActionWithUrl::displayString() const
2181 return label() + QLatin1String( " \"" ) + Qt::escape( argsAsString() ) + QLatin1String( "\"" );
2185 //=============================================================================
2186 // FilterActionAddToAddressBook
2187 // - add email address from header to address book
2188 //=============================================================================
2189 class FilterActionAddToAddressBook
: public FilterActionWithStringList
2192 FilterActionAddToAddressBook( QObject
*parent
= 0 );
2193 virtual ReturnCode
process( const Akonadi::Item
&item
) const;
2194 static FilterAction
* newAction();
2196 virtual bool isEmpty() const { return false; }
2198 virtual QWidget
* createParamWidget( QWidget
*parent
) const;
2199 virtual void setParamWidgetValue( QWidget
*paramWidget
) const;
2200 virtual void applyParamWidgetValue( QWidget
*paramWidget
);
2201 virtual void clearParamWidget( QWidget
*paramWidget
) const;
2203 virtual QString
argsAsString() const;
2204 virtual void argsFromString( const QString
&argsStr
);
2215 const QString mFromStr
, mToStr
, mCCStr
, mBCCStr
;
2216 HeaderType mHeaderType
;
2217 Akonadi::Collection::Id mCollectionId
;
2221 FilterAction
* FilterActionAddToAddressBook::newAction()
2223 return new FilterActionAddToAddressBook
;
2226 FilterActionAddToAddressBook::FilterActionAddToAddressBook( QObject
*parent
)
2227 : FilterActionWithStringList( "add to address book", i18n( "Add to Address Book" ), parent
),
2228 mFromStr( i18nc( "Email sender", "From" ) ),
2229 mToStr( i18nc( "Email recipient", "To" ) ),
2230 mCCStr( i18n( "CC" ) ),
2231 mBCCStr( i18n( "BCC" ) ),
2232 mHeaderType( FromHeader
),
2233 mCollectionId( -1 ),
2234 mCategory( i18n( "KMail Filter" ) )
2238 FilterAction::ReturnCode
FilterActionAddToAddressBook::process( const Akonadi::Item
&item
) const
2240 const KMime::Message::Ptr msg
= item
.payload
<KMime::Message::Ptr
>();
2243 switch ( mHeaderType
) {
2244 case FromHeader
: headerLine
= msg
->from()->asUnicodeString(); break;
2245 case ToHeader
: headerLine
= msg
->to()->asUnicodeString(); break;
2246 case CcHeader
: headerLine
= msg
->cc()->asUnicodeString(); break;
2247 case BccHeader
: headerLine
= msg
->bcc()->asUnicodeString(); break;
2250 const QStringList emails
= KPIMUtils::splitAddressList( headerLine
);
2252 foreach ( const QString
& singleEmail
, emails
) {
2253 QString name
, email
;
2254 KABC::Addressee::parseEmailAddress( singleEmail
, name
, email
);
2256 KABC::Addressee contact
;
2257 contact
.setNameFromString( name
);
2258 contact
.insertEmail( email
, true );
2259 if ( !mCategory
.isEmpty() )
2260 contact
.insertCategory( mCategory
);
2262 KPIM::AddContactJob
*job
= new KPIM::AddContactJob( contact
, Akonadi::Collection( mCollectionId
) );
2269 QWidget
* FilterActionAddToAddressBook::createParamWidget( QWidget
*parent
) const
2271 QWidget
*widget
= new QWidget( parent
);
2272 QGridLayout
*layout
= new QGridLayout( widget
);
2274 MinimumComboBox
*headerCombo
= new MinimumComboBox( widget
);
2275 headerCombo
->setObjectName( "HeaderComboBox" );
2276 layout
->addWidget( headerCombo
, 0, 0, 2, 1, Qt::AlignVCenter
);
2278 QLabel
*label
= new QLabel( i18n( "with category" ), widget
);
2279 layout
->addWidget( label
, 0, 1 );
2281 KLineEdit
*categoryEdit
= new KLineEdit( widget
);
2282 categoryEdit
->setObjectName( "CategoryEdit" );
2283 layout
->addWidget( categoryEdit
, 0, 2 );
2285 label
= new QLabel( i18n( "in address book" ), widget
);
2286 layout
->addWidget( label
, 1, 1 );
2288 Akonadi::CollectionComboBox
*collectionComboBox
= new Akonadi::CollectionComboBox( widget
);
2289 collectionComboBox
->setMimeTypeFilter( QStringList() << KABC::Addressee::mimeType() );
2290 collectionComboBox
->setAccessRightsFilter( Akonadi::Collection::CanCreateItem
);
2292 collectionComboBox
->setObjectName( "AddressBookComboBox" );
2293 collectionComboBox
->setToolTip( i18n( "<p>This defines the preferred address book.<br />"
2294 "If it is not accessible, the filter will fallback to the default address book.</p>" ) );
2295 layout
->addWidget( collectionComboBox
, 1, 2 );
2297 connect( categoryEdit
, SIGNAL(textChanged(QString
)),
2298 this, SIGNAL(filterActionModified()) );
2299 connect( headerCombo
, SIGNAL(currentIndexChanged(int)),
2300 this, SIGNAL(filterActionModified()) );
2302 setParamWidgetValue( widget
);
2307 void FilterActionAddToAddressBook::setParamWidgetValue( QWidget
*paramWidget
) const
2309 MinimumComboBox
*headerCombo
= paramWidget
->findChild
<MinimumComboBox
*>( "HeaderComboBox" );
2310 Q_ASSERT( headerCombo
);
2311 headerCombo
->clear();
2312 headerCombo
->addItem( mFromStr
, FromHeader
);
2313 headerCombo
->addItem( mToStr
, ToHeader
);
2314 headerCombo
->addItem( mCCStr
, CcHeader
);
2315 headerCombo
->addItem( mBCCStr
, BccHeader
);
2317 headerCombo
->setCurrentIndex( headerCombo
->findData( mHeaderType
) );
2319 KLineEdit
*categoryEdit
= paramWidget
->findChild
<KLineEdit
*>( "CategoryEdit" );
2320 Q_ASSERT( categoryEdit
);
2321 categoryEdit
->setText( mCategory
);
2323 Akonadi::CollectionComboBox
*collectionComboBox
= paramWidget
->findChild
<Akonadi::CollectionComboBox
*>( "AddressBookComboBox" );
2324 Q_ASSERT( collectionComboBox
);
2325 collectionComboBox
->setDefaultCollection( Akonadi::Collection( mCollectionId
) );
2326 collectionComboBox
->setProperty( "collectionId", mCollectionId
);
2329 void FilterActionAddToAddressBook::applyParamWidgetValue( QWidget
*paramWidget
)
2331 const MinimumComboBox
*headerCombo
= paramWidget
->findChild
<MinimumComboBox
*>( "HeaderComboBox" );
2332 Q_ASSERT( headerCombo
);
2333 mHeaderType
= static_cast<HeaderType
>( headerCombo
->itemData( headerCombo
->currentIndex() ).toInt() );
2335 const KLineEdit
*categoryEdit
= paramWidget
->findChild
<KLineEdit
*>( "CategoryEdit" );
2336 Q_ASSERT( categoryEdit
);
2337 mCategory
= categoryEdit
->text();
2339 const Akonadi::CollectionComboBox
*collectionComboBox
= paramWidget
->findChild
<Akonadi::CollectionComboBox
*>( "AddressBookComboBox" );
2340 Q_ASSERT( collectionComboBox
);
2341 const Akonadi::Collection collection
= collectionComboBox
->currentCollection();
2343 // it might be that the model of collectionComboBox has not finished loading yet, so
2344 // we use the previously 'stored' value from the 'collectionId' property
2345 if ( collection
.isValid() ) {
2346 mCollectionId
= collection
.id();
2347 connect( collectionComboBox
, SIGNAL(currentIndexChanged(int)),
2348 this, SIGNAL(filterActionModified()) );
2350 const QVariant value
= collectionComboBox
->property( "collectionId" );
2351 if ( value
.isValid() )
2352 mCollectionId
= value
.toLongLong();
2356 void FilterActionAddToAddressBook::clearParamWidget( QWidget
*paramWidget
) const
2358 MinimumComboBox
*headerCombo
= paramWidget
->findChild
<MinimumComboBox
*>( "HeaderComboBox" );
2359 Q_ASSERT( headerCombo
);
2360 headerCombo
->setCurrentItem( 0 );
2362 KLineEdit
*categoryEdit
= paramWidget
->findChild
<KLineEdit
*>( "CategoryEdit" );
2363 Q_ASSERT( categoryEdit
);
2364 categoryEdit
->setText( mCategory
);
2367 QString
FilterActionAddToAddressBook::argsAsString() const
2371 switch ( mHeaderType
) {
2372 case FromHeader
: result
= QLatin1String( "From" ); break;
2373 case ToHeader
: result
= QLatin1String( "To" ); break;
2374 case CcHeader
: result
= QLatin1String( "CC" ); break;
2375 case BccHeader
: result
= QLatin1String( "BCC" ); break;
2378 result
+= QLatin1Char( '\t' );
2379 result
+= QString::number( mCollectionId
);
2380 result
+= QLatin1Char( '\t' );
2381 result
+= mCategory
;
2386 void FilterActionAddToAddressBook::argsFromString( const QString
&argsStr
)
2388 const QStringList parts
= argsStr
.split( QLatin1Char( '\t' ), QString::KeepEmptyParts
);
2389 if ( parts
[ 0 ] == QLatin1String( "From" ) )
2390 mHeaderType
= FromHeader
;
2391 else if ( parts
[ 0 ] == QLatin1String( "To" ) )
2392 mHeaderType
= ToHeader
;
2393 else if ( parts
[ 0 ] == QLatin1String( "CC" ) )
2394 mHeaderType
= CcHeader
;
2395 else if ( parts
[ 0 ] == QLatin1String( "BCC" ) )
2396 mHeaderType
= BccHeader
;
2398 if ( parts
.count() >= 2 )
2399 mCollectionId
= parts
[ 1 ].toLongLong();
2401 if ( parts
.count() < 3 )
2404 mCategory
= parts
[ 2 ];
2408 //=============================================================================
2410 // Filter Action Dictionary
2412 //=============================================================================
2413 FilterActionDict::~FilterActionDict()
2415 qDeleteAll( mList
);
2418 void FilterActionDict::init()
2420 insert( FilterActionMove::newAction
);
2421 insert( FilterActionCopy::newAction
);
2422 insert( FilterActionIdentity::newAction
);
2423 insert( FilterActionSetStatus::newAction
);
2424 insert( FilterActionAddTag::newAction
);
2425 insert( FilterActionFakeDisposition::newAction
);
2426 insert( FilterActionTransport::newAction
);
2427 insert( FilterActionReplyTo::newAction
);
2428 insert( FilterActionForward::newAction
);
2429 insert( FilterActionRedirect::newAction
);
2430 insert( FilterActionSendReceipt::newAction
);
2431 insert( FilterActionExec::newAction
);
2432 insert( FilterActionExtFilter::newAction
);
2433 insert( FilterActionRemoveHeader::newAction
);
2434 insert( FilterActionAddHeader::newAction
);
2435 insert( FilterActionRewriteHeader::newAction
);
2437 insert( FilterActionExecSound::newAction
);
2439 insert( FilterActionAddToAddressBook::newAction
);
2440 // Register custom filter actions below this line.
2443 // The int in the QDict constructor (41) must be a prime
2444 // and should be greater than the double number of FilterAction types
2445 FilterActionDict::FilterActionDict()
2446 : QMultiHash
<QString
, FilterActionDesc
*>()
2451 void FilterActionDict::insert( FilterActionNewFunc aNewFunc
)
2453 FilterAction
*action
= aNewFunc();
2454 FilterActionDesc
* desc
= new FilterActionDesc
;
2455 desc
->name
= action
->name();
2456 desc
->label
= action
->label();
2457 desc
->create
= aNewFunc
;
2459 QMultiHash
<QString
, FilterActionDesc
*>::insert( desc
->name
, desc
);
2460 QMultiHash
<QString
, FilterActionDesc
*>::insert( desc
->label
, desc
);
2461 mList
.append( desc
);
2466 const QList
<FilterActionDesc
*>& FilterActionDict::list() const
2472 #include "filteraction.moc"