Version: 1.4.7 (using KDE 3.0.8 (KDE 3.1 beta2)) Installed from: compiled sources Compiler: gcc version 3.1 OS: Linux (i686) release 2.4.18 When I am creating a "sent mail" filter, I would like to have that message mangled BEFORE it is sent, not after. e.g. many mailing lists won't accept mail from nonsubscribers. I don't like signing up with my "real" email address, so I use sign up using a dash-alias: -something. (e.g. akohlsmith-kde@mixdown.ca, akohlsmith-slashdot@mixdown.ca, akohlsmith-spammylist@mixdown.ca). Currently in kmail I need separate identities for each of these, or I need to manually edit the From: when composing/replying to a message. I'd like to be able to set up a "sent mail" filter that changes the From: to whatever I want and have the outgoing message altered. Currently when I set up a filter it sends the message BEFORE applying the filter. The end result is that the message to the list bounces but my sent mail folder shows that the From is correct. example: I am signed up for the acpi-devel mailing list as akohlsmtih-acpi@mixdown.ca. I don't want to create another identity just to facilitate sending email to this list, so I set up a filter: Match any of the following: <recipients> contains acpi-devel@lists.sourceforge.net Filter actions: rewrite header From replace akohlsmith with akohlsmith-acpi Advanced Options: apply this filter [x] to sent messages Now when I send a message to acpi-devel@lists.sourceforge.net the mail that gets sent is from akohlsmith@mixdown.ca, but my sent mail shows it is from akohlsmith-acpi@mixdown.ca. This is what I mean by the "to sent mail" checkbox is too literal; it only applies the filter to mail in the "sent mail" folder. It should (in my opinion) be applied to any outgoing mail. Now I also use sent mail filters to send all mail going to my company to a special sent mail folder, so the action is "move to mixdown-sent" -- this should still be possible.
This is no bug but a wish. Furthermore I'm pretty sure that it's a duplicate.
Subject: Re: filter for sent mail is too literal > This is no bug but a wish. Furthermore I'm pretty sure that it's a > duplicate. My apologies, I mis-clicked. I didn't notice anything like it in the similar bugs/wishlist screen that the bug tracker brings up though. Regards, Andrew
*** Bug 67298 has been marked as a duplicate of this bug. ***
Still would like to keep this as a feature request for 3.2.2+
*** Bug 78816 has been marked as a duplicate of this bug. ***
*** Bug 92225 has been marked as a duplicate of this bug. ***
*** Bug 61592 has been marked as a duplicate of this bug. ***
This is also useful for outgoing mail virus scanning.
*** Bug 97243 has been marked as a duplicate of this bug. ***
Since the functionality is now in the code but not working should this not be considered a bug now? i.e. what use is setting the sending identity or rewriting headers if they only apply *after* the message leaves?
*** Bug 99194 has been marked as a duplicate of this bug. ***
Created attachment 19051 [details] kmail.diff I have added a checkbox to the Advanced-Tab "Apply this filter before sending messages" Filters are processed before sending, at this point in time the mail is already signed/encrypted. In other words the body can only be seen/manipulated in filters if the message is not encrypted. before I continue I'd like to get some feedback if this is required. some options a) as is, body in preSend filter is not available b) pass unencrypted message to filter. Manipulation is still not possible, but usage in filter criteria should work (to be verified) c) process filter before encryption. If mail is deleted from outbox it goes through the filter but is never sent. Moving to different folder will prevent mail from sending, only mails in outbox are sent. (check: is FilterMgr accessible at this stage?) comments?
At this point in time I can't see a real *use* for mangling the body of messages before sending, but I do see the possibility of using a filter to run the entire message through a script or something external (virus scan?) before sending. Personally I like (c) best, but (b) is also pretty nifty... with (b) you can always pass back a "bzzzt, try again" type of error and this bypasses the need to manipulate encrypted messages. I need to check out kdesvn again, as I've upgraded my system and am running 3.5.5 on Slackware.
I'm not sure what is the difference between "mangling the body of messages before sending" and "run the entire message through a script". However I'd like to see a hook to change the body of messages before sending simply to allow adding functionality (formatting/changing/replacing/whatever) that KMail does not (yet) provide through the use of scripts. That said I think (c) does exactly that AFAICT. Best, Michael
SVN commit 622728 by schaarsc: Add "Apply this filter before sending messages" Note: Quick win. Works for headers and clear text mails. CCBUG: 48938 M +8 -0 branches/work/kdepim-3.5.5+/kmail/kmfilter.cpp M +13 -0 branches/work/kdepim-3.5.5+/kmail/kmfilter.h M +20 -9 branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.cpp M +1 -1 branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.h M +1 -0 branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.cpp M +1 -1 branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.h M +16 -0 branches/work/kdepim-3.5.5+/kmail/kmsender.cpp --- branches/work/kdepim-3.5.5+/kmail/kmfilter.cpp #622727:622728 @@ -51,6 +51,7 @@ mAction = Down; else { bApplyOnInbound = true; + bApplyBeforeOutbound = false; bApplyOnOutbound = false; bApplyOnExplicit = true; bStopProcessingHere = true; @@ -75,6 +76,7 @@ mAction = aFilter.mAction; } else { bApplyOnInbound = aFilter.applyOnInbound(); + bApplyBeforeOutbound = aFilter.applyBeforeOutbound(); bApplyOnOutbound = aFilter.applyOnOutbound(); bApplyOnExplicit = aFilter.applyOnExplicit(); bStopProcessingHere = aFilter.stopProcessingHere(); @@ -231,12 +233,14 @@ else { QStringList sets = config->readListEntry("apply-on"); if ( sets.isEmpty() && !config->hasKey("apply-on") ) { + bApplyBeforeOutbound = false; bApplyOnOutbound = false; bApplyOnInbound = true; bApplyOnExplicit = true; mApplicability = ButImap; } else { bApplyOnInbound = bool(sets.contains("check-mail")); + bApplyBeforeOutbound = bool(sets.contains("before-send-mail")); bApplyOnOutbound = bool(sets.contains("send-mail")); bApplyOnExplicit = bool(sets.contains("manual-filtering")); mApplicability = (AccountType)config->readNumEntry( "Applicability", ButImap ); @@ -317,6 +321,8 @@ QStringList sets; if ( bApplyOnInbound ) sets.append( "check-mail" ); + if ( bApplyBeforeOutbound ) + sets.append( "before-send-mail" ); if ( bApplyOnOutbound ) sets.append( "send-mail" ); if ( bApplyOnExplicit ) @@ -403,6 +409,8 @@ result += "This filter belongs to the following sets:"; if ( bApplyOnInbound ) result += " Inbound"; + if ( bApplyBeforeOutbound ) + result += " before-Outbound"; if ( bApplyOnOutbound ) result += " Outbound"; if ( bApplyOnExplicit ) --- branches/work/kdepim-3.5.5+/kmail/kmfilter.h #622727:622728 @@ -145,12 +145,24 @@ */ void setApplyOnOutbound( bool aApply=TRUE ) { bApplyOnOutbound = aApply; } + /** Set whether this filter should be applied on + outbound messages before sending (@p aApply == TRUE) or not. + See applyOnOutbound applyOnInbound setApplyOnInbound + */ + void setApplyBeforeOutbound( bool aApply=TRUE ) { bApplyBeforeOutbound = aApply; } + /** @return TRUE if this filter should be applied on outbound messages, FALSE otherwise. @see setApplyOnOutbound applyOnInbound setApplyOnInbound */ bool applyOnOutbound() const { return bApplyOnOutbound; } + /** @return TRUE if this filter should be applied on + outbound messages before they are sent, FALSE otherwise. + @see setApplyOnOutbound applyOnInbound setApplyOnInbound + */ + bool applyBeforeOutbound() const { return bApplyBeforeOutbound; } + /** Set whether this filter should be applied on inbound messages (@p aApply == TRUE) or not. @see setApplyOnOutbound applyOnInbound applyOnOutbound @@ -300,6 +312,7 @@ KShortcut mShortcut; bool bPopFilter : 1; bool bApplyOnInbound : 1; + bool bApplyBeforeOutbound : 1; bool bApplyOnOutbound : 1; bool bApplyOnExplicit : 1; bool bStopProcessingHere : 1; --- branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.cpp #622727:622728 @@ -181,7 +181,7 @@ i18n("Advanced Options"), page2); { QWidget *adv_w = new QWidget( mAdvOptsGroup ); - QGridLayout *gl = new QGridLayout( adv_w, 8 /*rows*/, 3 /*cols*/, + QGridLayout *gl = new QGridLayout( adv_w, 10 /*rows*/, 3 /*cols*/, 0 /*border*/, spacingHint() ); QVBoxLayout *vbl3 = new QVBoxLayout( gl, spacingHint(), "vbl3" ); @@ -209,26 +209,29 @@ mAccountList->setSorting( -1 ); gl->addMultiCellWidget( mAccountList, 0, 3, 1, 3 ); + mApplyBeforeOut = new QCheckBox( i18n("Apply this filter before sending messages"), adv_w ); + gl->addMultiCellWidget( mApplyBeforeOut, 4, 4, 0, 3 ); + mApplyOnOut = new QCheckBox( i18n("Apply this filter to &sent messages"), adv_w ); - gl->addMultiCellWidget( mApplyOnOut, 4, 4, 0, 3 ); + gl->addMultiCellWidget( mApplyOnOut, 5, 5, 0, 3 ); mApplyOnCtrlJ = new QCheckBox( i18n("Apply this filter on manual &filtering"), adv_w ); - gl->addMultiCellWidget( mApplyOnCtrlJ, 5, 5, 0, 3 ); + gl->addMultiCellWidget( mApplyOnCtrlJ, 6, 6, 0, 3 ); mStopProcessingHere = new QCheckBox( i18n("If this filter &matches, stop processing here"), adv_w ); gl->addMultiCellWidget( mStopProcessingHere, - 6, 6, /*from to row*/ + 7, 7, /*from to row*/ 0, 3 /*from to col*/ ); mConfigureShortcut = new QCheckBox( i18n("Add this filter to the Apply Filter menu"), adv_w ); - gl->addMultiCellWidget( mConfigureShortcut, 7, 7, 0, 1 ); + gl->addMultiCellWidget( mConfigureShortcut, 8, 8, 0, 1 ); QLabel *keyButtonLabel = new QLabel( i18n( "Shortcut:" ), adv_w ); keyButtonLabel->setAlignment( AlignVCenter | AlignRight ); - gl->addMultiCellWidget( keyButtonLabel, 7, 7, 2, 2 ); + gl->addMultiCellWidget( keyButtonLabel, 8, 8, 2, 2 ); mKeyButton = new KKeyButton( adv_w, "FilterShortcutSelector" ); - gl->addMultiCellWidget( mKeyButton, 7, 7, 3, 3 ); + gl->addMultiCellWidget( mKeyButton, 8, 8, 3, 3 ); mKeyButton->setEnabled( false ); mConfigureToolbar = new QCheckBox( i18n("Additionally add this filter to the toolbar"), adv_w ); - gl->addMultiCellWidget( mConfigureToolbar, 8, 8, 0, 3 ); + gl->addMultiCellWidget( mConfigureToolbar, 9, 9, 0, 3 ); mConfigureToolbar->setEnabled( false ); QHBox *hbox = new QHBox( adv_w ); @@ -243,7 +246,7 @@ mFilterActionIconButton->setIcon( "gear" ); mFilterActionIconButton->setEnabled( false ); - gl->addMultiCellWidget( hbox, 9, 9, 0, 3 ); + gl->addMultiCellWidget( hbox, 10, 10, 0, 3 ); } vbl2->addWidget( mAdvOptsGroup, 0, Qt::AlignTop ); } @@ -273,6 +276,8 @@ this, SLOT(slotApplicabilityChanged()) ); connect( mApplyOnForChecked, SIGNAL(clicked()), this, SLOT(slotApplicabilityChanged()) ); + connect( mApplyBeforeOut, SIGNAL(clicked()), + this, SLOT(slotApplicabilityChanged()) ); connect( mApplyOnOut, SIGNAL(clicked()), this, SLOT(slotApplicabilityChanged()) ); connect( mApplyOnCtrlJ, SIGNAL(clicked()), @@ -376,6 +381,8 @@ << aFilter->applyOnInbound() << endl; kdDebug(5006) << "apply on outbound == " << aFilter->applyOnOutbound() << endl; + kdDebug(5006) << "apply before outbound == " + << aFilter->applyBeforeOutbound() << endl; kdDebug(5006) << "apply on explicit == " << aFilter->applyOnExplicit() << endl; @@ -385,6 +392,7 @@ const bool applyOnIn = aFilter->applyOnInbound(); const bool applyOnForAll = aFilter->applicability() == KMFilter::All; const bool applyOnTraditional = aFilter->applicability() == KMFilter::ButImap; + const bool applyBeforeOut = aFilter->applyBeforeOutbound(); const bool applyOnOut = aFilter->applyOnOutbound(); const bool applyOnExplicit = aFilter->applyOnExplicit(); const bool stopHere = aFilter->stopProcessingHere(); @@ -402,6 +410,7 @@ mApplyOnForChecked->setChecked( !applyOnForAll && !applyOnTraditional ); mAccountList->setEnabled( mApplyOnForChecked->isEnabled() && mApplyOnForChecked->isChecked() ); slotUpdateAccountList(); + mApplyBeforeOut->setChecked( applyBeforeOut ); mApplyOnOut->setChecked( applyOnOut ); mApplyOnCtrlJ->setChecked( applyOnExplicit ); mStopProcessingHere->setChecked( stopHere ); @@ -439,6 +448,7 @@ { if ( mFilter ) { mFilter->setApplyOnInbound( mApplyOnIn->isChecked() ); + mFilter->setApplyBeforeOutbound( mApplyBeforeOut->isChecked() ); mFilter->setApplyOnOutbound( mApplyOnOut->isChecked() ); mFilter->setApplyOnExplicit( mApplyOnCtrlJ->isChecked() ); if ( mApplyOnForAll->isChecked() ) @@ -467,6 +477,7 @@ kdDebug(5006) << "KMFilterDlg: setting filter to be applied at " << ( mFilter->applyOnInbound() ? "incoming " : "" ) << ( mFilter->applyOnOutbound() ? "outgoing " : "" ) + << ( mFilter->applyBeforeOutbound() ? "before_outgoing " : "" ) << ( mFilter->applyOnExplicit() ? "explicit CTRL-J" : "" ) << endl; } --- branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.h #622727:622728 @@ -376,7 +376,7 @@ KMPopFilterActionWidget *mActionGroup; /** Lets the user select whether to apply this filter on inbound/outbound messages, both, or only on explicit CTRL-J. */ - QCheckBox *mApplyOnIn, *mApplyOnOut, *mApplyOnCtrlJ; + QCheckBox *mApplyOnIn, *mApplyOnOut, *mApplyBeforeOut, *mApplyOnCtrlJ; /** For a filter applied to inbound messages selects whether to apply this filter to all accounts or to selected accounts only. */ QRadioButton *mApplyOnForAll, *mApplyOnForTraditional, *mApplyOnForChecked; --- branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.cpp #622727:622728 @@ -301,6 +301,7 @@ ( !account || ( account && (*it)->applyOnAccount( accountId ) ) ) ) || ( (set&Outbound) && (*it)->applyOnOutbound() ) || + ( (set&BeforeOutbound) && (*it)->applyBeforeOutbound() ) || ( (set&Explicit) && (*it)->applyOnExplicit() ) ) { // filter is applicable --- branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.h #622727:622728 @@ -43,7 +43,7 @@ void clear(); enum FilterSet { NoSet = 0x0, Inbound = 0x1, Outbound = 0x2, Explicit = 0x4, - All = Inbound|Outbound|Explicit }; + BeforeOutbound = 0x8, All = Inbound|BeforeOutbound|Outbound|Explicit }; /** Reload filter rules from config file. */ void readConfig(void); --- branches/work/kdepim-3.5.5+/kmail/kmsender.cpp #622727:622728 @@ -462,6 +462,22 @@ } mCurrentMsg->setTransferInProgress( TRUE ); + // apply filters before sending message + // TODO: to support encrypted/signed messages this sould be moved to messagecomposer.cpp + // Disable the emitting of msgAdded signal, because the message is taken out of the + // current folder (outbox) and re-added, to make filter actions changing the message + // work. We don't want that to screw up message counts. + if ( kmkernel->filterMgr() ) { + if ( mCurrentMsg->parent() ) mCurrentMsg->parent()->quiet( true ); + const int processResult = kmkernel->filterMgr()->process( mCurrentMsg, KMFilterMgr::BeforeOutbound ); + if ( mCurrentMsg->parent() ) mCurrentMsg->parent()->quiet( false ); + if ( processResult == 2 /* critical error */ ) { + perror("Critical error: Unable to execute filters before sending message(out of space?)"); + KMessageBox::information(0, i18n("Critical error: " + "during filtering before sending message (out of space?)")); + } + } + // start the sender process or initialize communication if (!mSendInProgress) {
*** Bug 147723 has been marked as a duplicate of this bug. ***
Added my vote for this, as it's potentially very useful for me and it had me fooled when trying to use it. I usually use sendmail as my mail transport but AOL rejects emails from hosts it doesn't recognise so it would be great if a filter could automatically use my ISP's SMTP server if the email's going to an AOL user without me having to notice who their ISP is.
This is very important for users' privacy, e.g. for adding a x-no-archive: yes header.
This bug is still present in KMail 1.11.2
SVN commit 1002356 by bbigras: Add support to filter outgoing message before they are sent based on a commit from Christian Schaarschmidt on the kdepim-3.5.5+ branch BUG: 48938 CCMAIL: exit3219@gmail.com M +8 -0 kmfilter.cpp M +13 -0 kmfilter.h M +21 -7 kmfilterdlg.cpp M +1 -1 kmfilterdlg.h M +1 -0 kmfiltermgr.cpp M +1 -1 kmfiltermgr.h M +16 -0 kmsender.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=1002356