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

svn path=/trunk/KDE/kdepim/; revision=1002356
wilder-work
Bruno Bigras 17 years ago
parent 68cd3416ae
commit d7ee26817d
  1. 8
      kmfilter.cpp
  2. 13
      kmfilter.h
  3. 28
      kmfilterdlg.cpp
  4. 2
      kmfilterdlg.h
  5. 1
      kmfiltermgr.cpp
  6. 2
      kmfiltermgr.h
  7. 16
      kmsender.cpp

@ -49,6 +49,7 @@ KMFilter::KMFilter( bool popFilter )
mAction = Down;
else {
bApplyOnInbound = true;
bApplyBeforeOutbound = false;
bApplyOnOutbound = false;
bApplyOnExplicit = true;
bStopProcessingHere = true;
@ -77,6 +78,7 @@ KMFilter::KMFilter( const KMFilter & aFilter )
mAction = aFilter.mAction;
} else {
bApplyOnInbound = aFilter.applyOnInbound();
bApplyBeforeOutbound = aFilter.applyBeforeOutbound();
bApplyOnOutbound = aFilter.applyOnOutbound();
bApplyOnExplicit = aFilter.applyOnExplicit();
bStopProcessingHere = aFilter.stopProcessingHere();
@ -242,11 +244,13 @@ void KMFilter::readConfig(KConfigGroup & config)
else {
QStringList sets = config.readEntry("apply-on", QStringList() );
if ( sets.isEmpty() && !config.hasKey("apply-on") ) {
bApplyBeforeOutbound = false;
bApplyOnOutbound = false;
bApplyOnInbound = true;
bApplyOnExplicit = true;
mApplicability = ButImap;
} else {
bApplyBeforeOutbound = bool(sets.contains("before-send-mail"));
bApplyOnInbound = bool(sets.contains("check-mail"));
bApplyOnOutbound = bool(sets.contains("send-mail"));
bApplyOnExplicit = bool(sets.contains("manual-filtering"));
@ -331,6 +335,8 @@ void KMFilter::writeConfig(KConfigGroup & config) const
QStringList sets;
if ( bApplyOnInbound )
sets.append( "check-mail" );
if ( bApplyBeforeOutbound )
sets.append( "before-send-mail" );
if ( bApplyOnOutbound )
sets.append( "send-mail" );
if ( bApplyOnExplicit )
@ -428,6 +434,8 @@ const QString KMFilter::asString() const
result += "This filter belongs to the following sets:";
if ( bApplyOnInbound )
result += " Inbound";
if ( bApplyBeforeOutbound )
result += " before-Outbound";
if ( bApplyOnOutbound )
result += " Outbound";
if ( bApplyOnExplicit )

@ -140,12 +140,24 @@ public:
*/
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
@ -312,6 +324,7 @@ private:
KShortcut mShortcut;
bool bPopFilter : 1;
bool bApplyOnInbound : 1;
bool bApplyBeforeOutbound : 1;
bool bApplyOnOutbound : 1;
bool bApplyOnExplicit : 1;
bool bStopProcessingHere : 1;

@ -244,27 +244,34 @@ KMFilterDlg::KMFilterDlg(QWidget* parent, bool popFilter, bool createDummyFilter
mAccountList->setRootIsDecorated( false );
gl->addWidget( mAccountList, 0, 1, 4, 3 );
mApplyBeforeOut = new QCheckBox( i18n("Apply this filter &before sending messages"), mAdvOptsGroup );
mApplyBeforeOut->setToolTip( i18n( "<p>The filter will be triggered <b>before</b> the message is sent and it will affect both the local copy and the sent copy of the message.</p>"
"<p>This is required if the recipient's copy also needs to be modified.</p>" ) );
gl->addWidget( mApplyBeforeOut, 5, 0, 1, 4 );
mApplyOnOut = new QCheckBox( i18n("Apply this filter to &sent messages"), mAdvOptsGroup );
mApplyOnOut->setToolTip( i18n( "<p>The filter will be triggered <b>after</b> the message is sent and it will only affect the local copy of the message.</p>"
"<p>If the recipient's copy also needs to be modified, please use \"Apply this filter <b>before</b> sending messages\".</p>" ) );
gl->addWidget( mApplyOnOut, 4, 0, 1, 4 );
mApplyOnCtrlJ = new QCheckBox( i18n("Apply this filter on manual &filtering"), mAdvOptsGroup );
gl->addWidget( mApplyOnCtrlJ, 5, 0, 1, 4 );
gl->addWidget( mApplyOnCtrlJ, 6, 0, 1, 4 );
mStopProcessingHere = new QCheckBox( i18n("If this filter &matches, stop processing here"), mAdvOptsGroup );
gl->addWidget( mStopProcessingHere, 6, 0, 1, 4 );
gl->addWidget( mStopProcessingHere, 7, 0, 1, 4 );
mConfigureShortcut = new QCheckBox( i18n("Add this filter to the Apply Filter menu"), mAdvOptsGroup );
gl->addWidget( mConfigureShortcut, 7, 0, 1, 2 );
gl->addWidget( mConfigureShortcut, 8, 0, 1, 2 );
QLabel *keyButtonLabel = new QLabel( i18n( "Shortcut:" ), mAdvOptsGroup );
keyButtonLabel->setAlignment( Qt::AlignVCenter | Qt::AlignRight );
gl->addWidget( keyButtonLabel, 7, 2, 1, 1);
gl->addWidget( keyButtonLabel, 8, 2, 1, 1);
mKeySeqWidget = new KKeySequenceWidget( mAdvOptsGroup );
mKeySeqWidget->setObjectName( "FilterShortcutSelector" );
gl->addWidget( mKeySeqWidget, 7, 3, 1, 1);
gl->addWidget( mKeySeqWidget, 8, 3, 1, 1);
mKeySeqWidget->setEnabled( false );
mKeySeqWidget->setCheckActionCollections(
kmkernel->getKMMainWidget()->actionCollections() );
mConfigureToolbar = new QCheckBox( i18n("Additionally add this filter to the toolbar"), mAdvOptsGroup );
gl->addWidget( mConfigureToolbar, 8, 0, 1, 4 );
gl->addWidget( mConfigureToolbar, 9, 0, 1, 4 );
mConfigureToolbar->setEnabled( false );
KHBox *hbox = new KHBox( mAdvOptsGroup );
@ -279,7 +286,7 @@ KMFilterDlg::KMFilterDlg(QWidget* parent, bool popFilter, bool createDummyFilter
mFilterActionIconButton->setIcon( "system-run" );
mFilterActionIconButton->setEnabled( false );
gl->addWidget( hbox, 9, 0, 1, 4 );
gl->addWidget( hbox, 10, 0, 1, 4 );
mAdvOptsGroup->setLayout( gl );
}
@ -311,6 +318,8 @@ KMFilterDlg::KMFilterDlg(QWidget* parent, bool popFilter, bool createDummyFilter
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()),
@ -422,6 +431,7 @@ void KMFilterDlg::slotFilterSelected( KMFilter* aFilter )
if (!bPopFilter) {
kDebug() << "apply on inbound ==" << aFilter->applyOnInbound();
kDebug() << "apply on outbound ==" << aFilter->applyOnOutbound();
kDebug() << "apply before outbound == " << aFilter->applyBeforeOutbound();
kDebug() << "apply on explicit ==" << aFilter->applyOnExplicit();
// NOTE: setting these values activates the slot that sets them in
@ -430,6 +440,7 @@ void KMFilterDlg::slotFilterSelected( KMFilter* aFilter )
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();
@ -447,6 +458,7 @@ void KMFilterDlg::slotFilterSelected( KMFilter* aFilter )
mApplyOnForChecked->setChecked( !applyOnForAll && !applyOnTraditional );
mAccountList->setEnabled( mApplyOnForChecked->isEnabled() && mApplyOnForChecked->isChecked() );
slotUpdateAccountList();
mApplyBeforeOut->setChecked( applyBeforeOut );
mApplyOnOut->setChecked( applyOnOut );
mApplyOnCtrlJ->setChecked( applyOnExplicit );
mStopProcessingHere->setChecked( stopHere );
@ -485,6 +497,7 @@ void KMFilterDlg::slotApplicabilityChanged()
{
if ( mFilter ) {
mFilter->setApplyOnInbound( mApplyOnIn->isChecked() );
mFilter->setApplyBeforeOutbound( mApplyBeforeOut->isChecked() );
mFilter->setApplyOnOutbound( mApplyOnOut->isChecked() );
mFilter->setApplyOnExplicit( mApplyOnCtrlJ->isChecked() );
if ( mApplyOnForAll->isChecked() )
@ -511,6 +524,7 @@ void KMFilterDlg::slotApplicabilityChanged()
kDebug() << "Setting filter to be applied at"
<< ( mFilter->applyOnInbound() ? "incoming " : "" )
<< ( mFilter->applyOnOutbound() ? "outgoing " : "" )
<< ( mFilter->applyBeforeOutbound() ? "before_outgoing " : "" )
<< ( mFilter->applyOnExplicit() ? "explicit CTRL-J" : "" );
}
}

@ -421,7 +421,7 @@ protected:
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;

@ -238,6 +238,7 @@ int KMFilterMgr::process( KMMessage * msg, FilterSet set,
( !account ||
( account && (*it)->applyOnAccount( accountId ) ) ) ) ||
( (set&Outbound) && (*it)->applyOnOutbound() ) ||
( (set&BeforeOutbound) && (*it)->applyBeforeOutbound() ) ||
( (set&Explicit) && (*it)->applyOnExplicit() ) ) {
// filter is applicable

@ -38,7 +38,7 @@ public:
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);

@ -500,6 +500,22 @@ void KMSender::doSendMsg()
}
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 */ ) {
kError() << "Critical error: Unable to execute filters before sending message (out of space?)";
KMessageBox::information( 0, i18n( "Critical error: "
"Unable to execute filters before sending message (out of space?)" ) );
}
}
/// start the sender process or initialize communication
if ( !mSendInProgress ) {
Q_ASSERT( !mProgressItem );

Loading…
Cancel
Save