7 #include "kmfilterdlg.h"
10 #include "kmsearchpatternedit.h"
11 #include "kmfiltermgr.h"
12 #include "kmmainwidget.h"
13 #include "accountmanager.h"
15 #include "filterimporterexporter.h"
17 #include "foldersetselector.h"
18 #include "globalsettings.h"
21 #include <tdemessagebox.h>
23 #include <tdelocale.h>
24 #include <kinputdialog.h>
25 #include <kiconloader.h>
26 #include <tdeapplication.h>
28 #include <tdeconfig.h>
29 #include <kicondialog.h>
30 #include <kkeybutton.h>
31 #include <tdelistview.h>
32 #include <kpushbutton.h>
37 #include <tqcombobox.h>
38 #include <tqwidgetstack.h>
39 #include <tqtooltip.h>
40 #include <tqwhatsthis.h>
41 #include <tqcheckbox.h>
43 #include <tqvalidator.h>
44 #include <tqtabwidget.h>
49 using namespace KMail;
53 const char * _wt_filterlist =
54 I18N_NOOP(
"<qt><p>This is the list of defined filters. "
55 "They are processed top-to-bottom.</p>"
56 "<p>Click on any filter to edit it "
57 "using the controls in the right-hand half "
58 "of the dialog.</p></qt>" );
59 const char * _wt_filterlist_new =
60 I18N_NOOP(
"<qt><p>Click this button to create a new filter.</p>"
61 "<p>The filter will be inserted just before the currently-"
62 "selected one, but you can always change that "
64 "<p>If you have clicked this button accidentally, you can undo this "
65 "by clicking on the <em>Delete</em> button.</p></qt>" );
66 const char * _wt_filterlist_copy =
67 I18N_NOOP(
"<qt><p>Click this button to copy a filter.</p>"
68 "<p>If you have clicked this button accidentally, you can undo this "
69 "by clicking on the <em>Delete</em> button.</p></qt>" );
70 const char * _wt_filterlist_delete =
71 I18N_NOOP(
"<qt><p>Click this button to <em>delete</em> the currently-"
72 "selected filter from the list above.</p>"
73 "<p>There is no way to get the filter back once "
74 "it is deleted, but you can always leave the "
75 "dialog by clicking <em>Cancel</em> to discard the "
76 "changes made.</p></qt>" );
77 const char * _wt_filterlist_top =
78 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
79 "selected filter to the <em>top</em> of the list above.</p>"
80 "<p>This is useful since the order of the filters in the list "
81 "determines the order in which they are tried on messages: "
82 "The topmost filter gets tried first.</p></qt>" );
83 const char * _wt_filterlist_up =
84 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
85 "selected filter <em>up</em> one in the list above.</p>"
86 "<p>This is useful since the order of the filters in the list "
87 "determines the order in which they are tried on messages: "
88 "The topmost filter gets tried first.</p>"
89 "<p>If you have clicked this button accidentally, you can undo this "
90 "by clicking on the <em>Down</em> button.</p></qt>" );
91 const char * _wt_filterlist_down =
92 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
93 "selected filter <em>down</em> one in the list above.</p>"
94 "<p>This is useful since the order of the filters in the list "
95 "determines the order in which they are tried on messages: "
96 "The topmost filter gets tried first.</p>"
97 "<p>If you have clicked this button accidentally, you can undo this "
98 "by clicking on the <em>Up</em> button.</p></qt>" );
99 const char * _wt_filterlist_bot =
100 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
101 "selected filter to the <em>bottom</em> of the list above.</p>"
102 "<p>This is useful since the order of the filters in the list "
103 "determines the order in which they are tried on messages: "
104 "The topmost filter gets tried first.</p></qt>" );
105 const char * _wt_filterlist_rename =
106 I18N_NOOP(
"<qt><p>Click this button to rename the currently-selected filter.</p>"
107 "<p>Filters are named automatically, as long as they start with "
109 "<p>If you have renamed a filter accidentally and want automatic "
110 "naming back, click this button and select <em>Clear</em> followed "
111 "by <em>OK</em> in the appearing dialog.</p></qt>" );
112 const char * _wt_filterdlg_showLater =
113 I18N_NOOP(
"<qt><p>Check this button to force the confirmation dialog to be "
114 "displayed.</p><p>This is useful if you have defined a ruleset that tags "
115 "messages to be downloaded later. Without the possibility to force "
116 "the dialog popup, these messages could never be downloaded if no "
117 "other large messages were waiting on the server, or if you wanted to "
118 "change the ruleset to tag the messages differently.</p></qt>" );
121 const char * KMFilterDlgHelpAnchor =
"filters-id" ;
122 const char * KMPopFilterDlgHelpAnchor =
"popfilters-id" ;
131 : KDialogBase( parent, name, false ,
132 (popFilter)? i18n(
"POP3 Filter Rules"): i18n(
"Filter Rules") ,
133 Help|Ok|Apply|Cancel|User1|User2 ,
135 bPopFilter(popFilter)
137 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
138 setHelp( (bPopFilter)? KMPopFilterDlgHelpAnchor: KMFilterDlgHelpAnchor );
139 setButtonText( User1, i18n(
"Import") );
140 setButtonText( User2, i18n(
"Export") );
141 connect(
this, TQ_SIGNAL(user1Clicked()),
143 connect(
this, TQ_SIGNAL(user2Clicked()),
146 TQWidget *w =
new TQWidget(
this );
148 TQHBoxLayout *topLayout =
new TQHBoxLayout( w, 0, spacingHint(),
"topLayout" );
149 TQHBoxLayout *hbl = topLayout;
150 TQVBoxLayout *vbl2 = 0;
158 TQTabWidget *tabWidget =
new TQTabWidget( w,
"kmfd_tab" );
159 tabWidget->setMargin( KDialog::marginHint() );
160 topLayout->addWidget( tabWidget );
162 page1 =
new TQWidget( tabWidget );
163 tabWidget->addTab( page1, i18n(
"&General") );
164 hbl =
new TQHBoxLayout( page1, 0, spacingHint(),
"kmfd_hbl" );
166 page2 =
new TQWidget( tabWidget );
167 tabWidget->addTab( page2, i18n(
"A&dvanced") );
168 vbl2 =
new TQVBoxLayout( page2, 0, spacingHint(),
"kmfd_vbl2" );
171 TQVBoxLayout *vbl =
new TQVBoxLayout( hbl, spacingHint(),
"kmfd_vbl" );
172 hbl->setStretchFactor( vbl, 2 );
178 mActionGroup =
new KMPopFilterActionWidget( i18n(
"Filter Action"), w );
181 mGlobalsBox =
new TQVGroupBox(i18n(
"Global Options"), w);
182 mShowLaterBtn =
new TQCheckBox(i18n(
"Always &show matched 'Download Later' messages in confirmation dialog"), mGlobalsBox);
183 TQWhatsThis::add( mShowLaterBtn, i18n(_wt_filterdlg_showLater) );
184 vbl->addWidget( mGlobalsBox, 0, TQt::AlignTop );
187 TQGroupBox *agb =
new TQGroupBox( 1 , TQt::Vertical, i18n(
"Filter Actions"), page1 );
189 vbl->addWidget( agb, 0, TQt::AlignTop );
191 mAdvOptsGroup =
new TQGroupBox ( 1 , TQt::Vertical,
192 i18n(
"Advanced Options"), page2);
194 TQWidget *adv_w =
new TQWidget( mAdvOptsGroup );
195 TQGridLayout *gl =
new TQGridLayout( adv_w, 8 , 3 ,
198 TQVBoxLayout *vbl3 =
new TQVBoxLayout( gl, spacingHint(),
"vbl3" );
199 vbl3->addStretch( 1 );
200 mApplyOnIn =
new TQCheckBox( i18n(
"Apply this filter to incoming messages:"), adv_w );
202 TQButtonGroup *bg =
new TQButtonGroup( 0,
"bg" );
203 bg->setExclusive(
true );
204 mApplyOnForAll =
new TQRadioButton( i18n(
"from all accounts"), adv_w );
207 mApplyOnForTraditional =
new TQRadioButton( i18n(
"from all but online IMAP accounts"), adv_w );
208 bg->insert( mApplyOnForTraditional );
209 vbl3->addWidget( mApplyOnForTraditional );
210 mApplyOnForChecked =
new TQRadioButton( i18n(
"from checked accounts only"), adv_w );
211 bg->insert( mApplyOnForChecked );
212 vbl3->addWidget( mApplyOnForChecked );
213 vbl3->addStretch( 2 );
219 mAccountList->setFrameStyle( TQFrame::WinPanel + TQFrame::Sunken );
223 mApplyOnOut =
new TQCheckBox( i18n(
"Apply this filter to &sent messages"), adv_w );
224 gl->addMultiCellWidget( mApplyOnOut, 4, 4, 0, 3 );
226 mApplyOnCtrlJ =
new TQCheckBox( i18n(
"Apply this filter on manual &filtering"), adv_w );
227 gl->addMultiCellWidget( mApplyOnCtrlJ, 5, 5, 0, 3 );
229 mStopProcessingHere =
new TQCheckBox( i18n(
"If this filter &matches, stop processing here"), adv_w );
230 gl->addMultiCellWidget( mStopProcessingHere,
233 mConfigureShortcut =
new TQCheckBox( i18n(
"Add this filter to the Apply Filter menu"), adv_w );
234 gl->addMultiCellWidget( mConfigureShortcut, 7, 7, 0, 1 );
235 TQLabel *keyButtonLabel =
new TQLabel( i18n(
"Shortcut:" ), adv_w );
236 keyButtonLabel->setAlignment( AlignVCenter | AlignRight );
237 gl->addMultiCellWidget( keyButtonLabel, 7, 7, 2, 2 );
238 mKeyButton =
new KKeyButton( adv_w,
"FilterShortcutSelector" );
239 gl->addMultiCellWidget( mKeyButton, 7, 7, 3, 3 );
240 mKeyButton->setEnabled(
false );
241 mConfigureToolbar =
new TQCheckBox( i18n(
"Additionally add this filter to the toolbar"), adv_w );
242 gl->addMultiCellWidget( mConfigureToolbar, 8, 8, 0, 3 );
243 mConfigureToolbar->setEnabled(
false );
245 TQHBox *hbox =
new TQHBox( adv_w );
246 mFilterActionLabel =
new TQLabel( i18n(
"Icon for this filter:" ),
248 mFilterActionLabel->setEnabled(
false );
250 mFilterActionIconButton =
new TDEIconButton( hbox );
251 mFilterActionLabel->setBuddy( mFilterActionIconButton );
252 mFilterActionIconButton->setIconType( TDEIcon::NoGroup, TDEIcon::Any,
true );
253 mFilterActionIconButton->setIconSize( 16 );
254 mFilterActionIconButton->setIcon(
"gear" );
255 mFilterActionIconButton->setEnabled(
false );
257 gl->addMultiCellWidget( hbox, 9, 9, 0, 3 );
259 vbl2->addWidget( mAdvOptsGroup, 0, TQt::AlignTop );
262 vbl->addStretch( 1 );
265 connect(
mFilterList, TQ_SIGNAL(filterSelected(KMFilter*)),
270 connect( mShowLaterBtn, TQ_SIGNAL(toggled(
bool)),
274 connect(
mActionGroup, TQ_SIGNAL(actionChanged(
const KMPopFilterAction)),
280 this, TQ_SLOT(slotApplicabilityChanged()) );
282 this, TQ_SLOT(slotApplicabilityChanged()) );
283 connect( mApplyOnForTraditional, TQ_SIGNAL(clicked()),
284 this, TQ_SLOT(slotApplicabilityChanged()) );
285 connect( mApplyOnForChecked, TQ_SIGNAL(clicked()),
286 this, TQ_SLOT(slotApplicabilityChanged()) );
287 connect( mApplyOnOut, TQ_SIGNAL(clicked()),
288 this, TQ_SLOT(slotApplicabilityChanged()) );
289 connect( mApplyOnCtrlJ, TQ_SIGNAL(clicked()),
290 this, TQ_SLOT(slotApplicabilityChanged()) );
291 connect(
mAccountList, TQ_SIGNAL(clicked(TQListViewItem*)),
292 this, TQ_SLOT(slotApplicableAccountsChanged()) );
293 connect(
mAccountList, TQ_SIGNAL(spacePressed(TQListViewItem*)),
294 this, TQ_SLOT(slotApplicableAccountsChanged()) );
298 connect( mStopProcessingHere, TQ_SIGNAL(toggled(
bool)),
299 this, TQ_SLOT(slotStopProcessingButtonToggled(
bool)) );
301 connect( mConfigureShortcut, TQ_SIGNAL(toggled(
bool)),
302 this, TQ_SLOT(slotConfigureShortcutButtonToggled(
bool)) );
304 connect( mKeyButton, TQ_SIGNAL( capturedShortcut(
const TDEShortcut& ) ),
305 this, TQ_SLOT( slotCapturedShortcutChanged(
const TDEShortcut& ) ) );
307 connect( mConfigureToolbar, TQ_SIGNAL(toggled(
bool)),
308 this, TQ_SLOT(slotConfigureToolbarButtonToggled(
bool)) );
310 connect( mFilterActionIconButton, TQ_SIGNAL( iconChanged( TQString ) ),
311 this, TQ_SLOT( slotFilterActionIconChanged( TQString ) ) );
316 this, TQ_SLOT(slotReset()) );
319 this, TQ_SLOT( slotUpdateFilter() ) );
326 connect(
this, TQ_SIGNAL(applyClicked()),
330 connect(
this, TQ_SIGNAL(okClicked()),
334 connect(
this, TQ_SIGNAL(okClicked()),
335 this, TQ_SLOT(slotSaveSize()) );
338 connect(
this, TQ_SIGNAL(finished()),
339 this, TQ_SLOT(slotFinished()) );
341 TDEConfigGroup geometry( KMKernel::config(),
"Geometry");
342 const char * configKey
343 = bPopFilter ?
"popFilterDialogSize" :
"filterDialogSize";
344 if ( geometry.hasKey( configKey ) )
345 resize( geometry.readSizeEntry( configKey ) );
353 void KMFilterDlg::slotFinished() {
357 void KMFilterDlg::slotSaveSize() {
358 TDEConfigGroup geometry( KMKernel::config(),
"Geometry" );
359 geometry.writeEntry( bPopFilter ?
"popFilterDialogSize" :
"filterDialogSize", size() );
365 mFilter->setAction(aAction);
374 mGlobalsBox->setEnabled(
true );
379 mAdvOptsGroup->setEnabled(
true );
386 kdDebug(5006) <<
"apply on inbound == "
387 << aFilter->applyOnInbound() << endl;
388 kdDebug(5006) <<
"apply on outbound == "
389 << aFilter->applyOnOutbound() << endl;
390 kdDebug(5006) <<
"apply on explicit == "
391 << aFilter->applyOnExplicit() << endl;
396 const bool applyOnIn = aFilter->applyOnInbound();
397 const bool applyOnForAll = aFilter->applicability() == KMFilter::All;
398 const bool applyOnTraditional = aFilter->applicability() == KMFilter::ButImap;
399 const bool applyOnOut = aFilter->applyOnOutbound();
400 const bool applyOnExplicit = aFilter->applyOnExplicit();
401 const bool stopHere = aFilter->stopProcessingHere();
402 const bool configureShortcut = aFilter->configureShortcut();
403 const bool configureToolbar = aFilter->configureToolbar();
404 const TQString icon = aFilter->icon();
405 const TDEShortcut shortcut( aFilter->shortcut() );
409 mApplyOnForTraditional->setEnabled( applyOnIn );
410 mApplyOnForChecked->setEnabled( applyOnIn );
412 mApplyOnForTraditional->setChecked( applyOnTraditional );
413 mApplyOnForChecked->setChecked( !applyOnForAll && !applyOnTraditional );
414 mAccountList->setEnabled( mApplyOnForChecked->isEnabled() && mApplyOnForChecked->isChecked() );
415 slotUpdateAccountList();
416 mApplyOnOut->setChecked( applyOnOut );
417 mApplyOnCtrlJ->setChecked( applyOnExplicit );
418 mStopProcessingHere->setChecked( stopHere );
419 mConfigureShortcut->setChecked( configureShortcut );
420 mKeyButton->setShortcut( shortcut,
false );
421 mConfigureToolbar->setChecked( configureToolbar );
422 mFilterActionIconButton->setIcon( icon );
426 void KMFilterDlg::slotReset()
433 mGlobalsBox->setEnabled(
false );
436 mAdvOptsGroup->setEnabled(
false );
437 slotUpdateAccountList();
441 void KMFilterDlg::slotUpdateFilter()
449 void KMFilterDlg::slotApplicabilityChanged()
452 mFilter->setApplyOnInbound(
mApplyOnIn->isChecked() );
453 mFilter->setApplyOnOutbound( mApplyOnOut->isChecked() );
454 mFilter->setApplyOnExplicit( mApplyOnCtrlJ->isChecked() );
456 mFilter->setApplicability( KMFilter::All );
457 else if ( mApplyOnForTraditional->isChecked() )
458 mFilter->setApplicability( KMFilter::ButImap );
459 else if ( mApplyOnForChecked->isChecked() )
460 mFilter->setApplicability( KMFilter::Checked );
463 mApplyOnForTraditional->setEnabled(
mApplyOnIn->isChecked() );
464 mApplyOnForChecked->setEnabled(
mApplyOnIn->isChecked() );
465 mAccountList->setEnabled( mApplyOnForChecked->isEnabled() && mApplyOnForChecked->isChecked() );
469 while ( it.current() ) {
470 TQCheckListItem *item =
dynamic_cast<TQCheckListItem*
>( it.current() );
472 int id = item->text( 2 ).toInt();
473 item->setOn( mFilter->applyOnAccount(
id ) );
478 kdDebug(5006) <<
"KMFilterDlg: setting filter to be applied at "
479 << ( mFilter->applyOnInbound() ?
"incoming " :
"" )
480 << ( mFilter->applyOnOutbound() ?
"outgoing " :
"" )
481 << ( mFilter->applyOnExplicit() ?
"explicit CTRL-J" :
"" )
486 void KMFilterDlg::slotApplicableAccountsChanged()
488 if ( mFilter && mApplyOnForChecked->isEnabled() && mApplyOnForChecked->isChecked() ) {
491 while ( it.current() ) {
492 TQCheckListItem *item =
dynamic_cast<TQCheckListItem*
>( it.current() );
494 int id = item->text( 2 ).toInt();
495 mFilter->setApplyOnAccount(
id, item->isOn() );
502 void KMFilterDlg::slotStopProcessingButtonToggled(
bool aChecked )
505 mFilter->setStopProcessingHere( aChecked );
508 void KMFilterDlg::slotConfigureShortcutButtonToggled(
bool aChecked )
511 mFilter->setConfigureShortcut( aChecked );
512 mKeyButton->setEnabled( aChecked );
513 mConfigureToolbar->setEnabled( aChecked );
514 mFilterActionIconButton->setEnabled( aChecked );
515 mFilterActionLabel->setEnabled( aChecked );
519 void KMFilterDlg::slotCapturedShortcutChanged(
const TDEShortcut& sc )
521 TDEShortcut mySc(sc);
522 if ( mySc == mKeyButton->shortcut() )
return;
526 if ( mySc.isNull() || mySc.toString().isEmpty() )
528 if ( !mySc.isNull() && !( kmkernel->getKMMainWidget()->shortcutIsValid( mySc ) ) ) {
529 TQString msg( i18n(
"The selected shortcut is already used, "
530 "please select a different one." ) );
531 KMessageBox::sorry(
this, msg );
533 mKeyButton->setShortcut( mySc,
false );
535 mFilter->setShortcut( mKeyButton->shortcut() );
539 void KMFilterDlg::slotConfigureToolbarButtonToggled(
bool aChecked )
542 mFilter->setConfigureToolbar( aChecked );
545 void KMFilterDlg::slotFilterActionIconChanged( TQString icon )
548 mFilter->setIcon( icon );
551 void KMFilterDlg::slotUpdateAccountList()
554 TQListViewItem *top = 0;
555 for( KMAccount *a = kmkernel->acctMgr()->first(); a!=0;
556 a = kmkernel->acctMgr()->next() ) {
557 TQCheckListItem *listItem =
558 new TQCheckListItem(
mAccountList, top, a->name(), TQCheckListItem::CheckBox );
559 listItem->setText( 1, a->type() );
560 listItem->setText( 2, TQString(
"%1" ).arg( a->id() ) );
562 listItem->setOn( mFilter->applyOnAccount( a->id() ) );
580 : TQGroupBox( 1, TQt::Horizontal, title, parent, name ),
581 bPopFilter(popFilter)
589 TQWhatsThis::add(
mListBox, i18n(_wt_filterlist) );
592 TQHBox *hb =
new TQHBox(
this);
594 mBtnTop =
new KPushButton( TQString(), hb );
595 mBtnTop->setAutoRepeat(
true );
596 mBtnTop->setIconSet( BarIconSet(
"go-top", TDEIcon::SizeSmall ) );
597 mBtnTop->setMinimumSize( mBtnTop->sizeHint() * 1.2 );
598 mBtnUp =
new KPushButton( TQString(), hb );
599 mBtnUp->setAutoRepeat(
true );
600 mBtnUp->setIconSet( BarIconSet(
"go-up", TDEIcon::SizeSmall ) );
601 mBtnUp->setMinimumSize( mBtnUp->sizeHint() * 1.2 );
602 mBtnDown =
new KPushButton( TQString(), hb );
603 mBtnDown->setAutoRepeat(
true );
604 mBtnDown->setIconSet( BarIconSet(
"go-down", TDEIcon::SizeSmall ) );
605 mBtnDown->setMinimumSize( mBtnDown->sizeHint() * 1.2 );
606 mBtnBot =
new KPushButton( TQString(), hb );
607 mBtnBot->setAutoRepeat(
true );
608 mBtnBot->setIconSet( BarIconSet(
"go-bottom", TDEIcon::SizeSmall ) );
609 mBtnBot->setMinimumSize( mBtnBot->sizeHint() * 1.2 );
610 TQToolTip::add( mBtnTop, i18n(
"Top") );
611 TQToolTip::add( mBtnUp, i18n(
"Up") );
612 TQToolTip::add( mBtnDown, i18n(
"Down") );
613 TQToolTip::add( mBtnBot, i18n(
"Bottom") );
614 TQWhatsThis::add( mBtnTop, i18n(_wt_filterlist_top) );
615 TQWhatsThis::add( mBtnUp, i18n(_wt_filterlist_up) );
616 TQWhatsThis::add( mBtnDown, i18n(_wt_filterlist_down) );
617 TQWhatsThis::add( mBtnBot, i18n(_wt_filterlist_bot) );
620 hb =
new TQHBox(
this);
622 mBtnNew =
new TQPushButton( TQString(), hb );
623 mBtnNew->setPixmap( BarIcon(
"document-new", TDEIcon::SizeSmall ) );
625 mBtnCopy =
new TQPushButton( TQString(), hb );
626 mBtnCopy->setIconSet( BarIconSet(
"edit-copy", TDEIcon::SizeSmall ) );
627 mBtnCopy->setMinimumSize( mBtnCopy->sizeHint() * 1.2 );
628 mBtnDelete =
new TQPushButton( TQString(), hb );
629 mBtnDelete->setIconSet( BarIconSet(
"edit-delete", TDEIcon::SizeSmall ) );
630 mBtnDelete->setMinimumSize( mBtnDelete->sizeHint() * 1.2 );
631 mBtnRename =
new TQPushButton( i18n(
"Rename..."), hb );
632 TQToolTip::add(
mBtnNew, i18n(
"New") );
633 TQToolTip::add( mBtnCopy, i18n(
"Copy") );
634 TQToolTip::add( mBtnDelete, i18n(
"Delete"));
635 TQWhatsThis::add(
mBtnNew, i18n(_wt_filterlist_new) );
636 TQWhatsThis::add( mBtnCopy, i18n(_wt_filterlist_copy) );
637 TQWhatsThis::add( mBtnDelete, i18n(_wt_filterlist_delete) );
638 TQWhatsThis::add( mBtnRename, i18n(_wt_filterlist_rename) );
642 hb =
new TQHBox(
this );
644 TQPushButton *btn =
new TQPushButton( i18n(
"Select Source Folders"), hb );
645 connect( btn, TQ_SIGNAL(clicked()), TQ_SLOT(slotSelectSourceFolders()) );
650 connect(
mListBox, TQ_SIGNAL(highlighted(
int)),
652 connect(
mListBox, TQ_SIGNAL( doubleClicked ( TQListBoxItem * )),
654 connect( mBtnTop, TQ_SIGNAL(clicked()),
656 connect( mBtnUp, TQ_SIGNAL(clicked()),
657 this, TQ_SLOT(
slotUp()) );
658 connect( mBtnDown, TQ_SIGNAL(clicked()),
660 connect( mBtnBot, TQ_SIGNAL(clicked()),
662 connect(
mBtnNew, TQ_SIGNAL(clicked()),
664 connect( mBtnCopy, TQ_SIGNAL(clicked()),
666 connect( mBtnDelete, TQ_SIGNAL(clicked()),
668 connect( mBtnRename, TQ_SIGNAL(clicked()),
678 const TQString & value )
682 KMFilter *newFilter =
new KMFilter(0, bPopFilter);
683 newFilter->pattern()->append( newRule );
684 newFilter->pattern()->setName( TQString(
"<%1>:%2").arg( TQString(field) ).arg( TQString(value) ) );
688 newFilter->actions()->append( desc->create() );
690 insertFilter( newFilter );
704 TQString shouldBeName = p->
name();
707 if ( shouldBeName.stripWhiteSpace().isEmpty() ) {
713 if ( !p->isEmpty() && p->first() && !p->first()->field().stripWhiteSpace().isEmpty() )
714 shouldBeName = TQString(
"<%1>: %2" ).arg( TQString(p->first()->field()) ).arg( TQString(p->first()->contents()) );
716 shouldBeName =
"<" + i18n(
"unnamed") +
">";
720 if ( displayedName == shouldBeName )
return;
744 fm = kmkernel->popFilterMgr();
746 fm = kmkernel->filterMgr();
751 fm->setShowLaterMsgs(mShowLater);
753 fm->setFilters( newFilters );
754 if (fm->atLeastOneOnlineImapFolderTarget()) {
755 TQString str = i18n(
"At least one filter targets a folder on an online "
756 "IMAP account. Such filters will only be applied "
757 "when manually filtering and when filtering "
758 "incoming online IMAP mail.");
759 KMessageBox::information(
this, str, TQString(),
760 "filterDlgOnlineImapCheck" );
767 TQValueList<KMFilter*> filters;
768 TQStringList emptyFilters;
770 for ( it.toFirst() ; it.current() ; ++it ) {
771 KMFilter *f =
new KMFilter( **it );
778 emptyFilters << f->name();
784 if ( !emptyFilters.empty() ) {
785 TQString msg = i18n(
"The following filters have not been saved because they "
786 "were invalid (e.g. containing no actions or no search "
788 KMessageBox::informationList( 0, msg, emptyFilters, TQString(),
789 "ShowInvalidFilterWarning" );
809 insertFilter(
new KMFilter(0, bPopFilter) );
816 kdDebug(5006) <<
"KMFilterListBox::slotCopy called while no filter is selected, ignoring." << endl;
830 insertFilter(
new KMFilter( *filter ) );
837 kdDebug(5006) <<
"KMFilterListBox::slotDelete called while no filter is selected, ignoring." << endl;
852 mListBox->removeItem( oIdxSelItem );
856 if ( count > oIdxSelItem )
858 mListBox->setSelected( oIdxSelItem,
true );
862 mListBox->setSelected( count - 1,
true );
871 kdDebug(5006) <<
"KMFilterListBox::slotTop called while no filter is selected, ignoring." << endl;
875 kdDebug(5006) <<
"KMFilterListBox::slotTop called while the _topmost_ filter is selected, ignoring." << endl;
886 kdDebug(5006) <<
"KMFilterListBox::slotUp called while no filter is selected, ignoring." << endl;
890 kdDebug(5006) <<
"KMFilterListBox::slotUp called while the _topmost_ filter is selected, ignoring." << endl;
901 kdDebug(5006) <<
"KMFilterListBox::slotDown called while no filter is selected, ignoring." << endl;
905 kdDebug(5006) <<
"KMFilterListBox::slotDown called while the _last_ filter is selected, ignoring." << endl;
916 kdDebug(5006) <<
"KMFilterListBox::slotBottom called while no filter is selected, ignoring." << endl;
920 kdDebug(5006) <<
"KMFilterListBox::slotBottom called while the _last_ filter is selected, ignoring." << endl;
931 kdDebug(5006) <<
"KMFilterListBox::slotRename called while no filter is selected, ignoring." << endl;
935 bool okPressed = false ;
943 TQValidator *validator =
new TQRegExpValidator( TQRegExp(
".*" ), 0 );
944 TQString newName = KInputDialog::getText
946 i18n(
"Rename Filter"),
947 i18n(
"Rename filter \"%1\" to:\n(leave the field empty for automatic naming)")
948 .arg( filter->pattern()->name() ) ,
949 filter->pattern()->name() ,
950 &okPressed, topLevelWidget(), 0, validator
954 if ( !okPressed )
return;
956 if ( newName.isEmpty() ) {
959 filter->pattern()->setName(
"<>" );
960 filter->setAutoNaming(
true );
962 filter->pattern()->setName( newName );
963 filter->setAutoNaming(
false );
969 void KMFilterListBox::slotSelectSourceFolders()
971 FolderSetSelector dlg( kmkernel->getKMMainWidget()->folderTree(),
this );
972 dlg.setCaption( i18n(
"Select Folders to Filter" ) );
973 if ( !GlobalSettings::filterSourceFolders().isEmpty() )
974 dlg.setSelectedFolders( GlobalSettings::filterSourceFolders() );
975 if ( dlg.exec() == TQDialog::Accepted ) {
976 GlobalSettings::setFilterSourceFolders( dlg.selectedFolders() );
980 void KMFilterListBox::enableControls()
986 mBtnTop->setEnabled( aFilterIsSelected && !theFirst );
987 mBtnUp->setEnabled( aFilterIsSelected && !theFirst );
988 mBtnDown->setEnabled( aFilterIsSelected && !theLast );
989 mBtnBot->setEnabled( aFilterIsSelected && !theLast );
990 mBtnCopy->setEnabled( aFilterIsSelected );
991 mBtnDelete->setEnabled( aFilterIsSelected );
992 mBtnRename->setEnabled( aFilterIsSelected );
994 if ( aFilterIsSelected )
1001 setEnabled(
false );
1005 blockSignals(
true );
1011 const KMFilterMgr *manager = 0;
1014 mShowLater = kmkernel->popFilterMgr()->showLaterMsgs();
1015 manager = kmkernel->popFilterMgr();
1019 manager = kmkernel->filterMgr();
1021 Q_ASSERT( manager );
1023 TQValueListConstIterator<KMFilter*> it;
1024 for ( it = manager->filters().constBegin() ; it != manager->filters().constEnd() ; ++it ) {
1026 mListBox->insertItem( (*it)->pattern()->name() );
1029 blockSignals(
false );
1035 if ( !
mListBox->count() && createDummyFilter )
1044 void KMFilterListBox::insertFilter( KMFilter* aFilter )
1065 void KMFilterListBox::appendFilter( KMFilter* aFilter )
1068 mListBox->insertItem( aFilter->pattern()->name(), -1 );
1071 void KMFilterListBox::swapNeighbouringFilters(
int untouchedOne,
int movedOne )
1074 assert( untouchedOne - movedOne == 1 || movedOne - untouchedOne == 1 );
1078 TQListBoxItem *item =
mListBox->item( movedOne );
1082 mListBox->insertItem( item, untouchedOne );
1090 void KMFilterListBox::swapFilters(
int from,
int to )
1092 TQListBoxItem *item =
mListBox->item( from );
1111 : TQHBox( parent, name )
1114 mActionList.setAutoDelete(
true );
1116 mComboBox =
new TQComboBox(
false ,
this );
1117 assert( mComboBox );
1118 mWidgetStack =
new TQWidgetStack(
this);
1119 assert( mWidgetStack );
1123 TQPtrListIterator<KMFilterActionDesc> it ( kmkernel->filterActionDict()->list() );
1124 for ( i=0, it.toFirst() ; it.current() ; ++it, ++i ) {
1128 mActionList.append( a );
1132 mComboBox->insertItem( (*it)->label );
1135 mWidgetStack->addWidget(
new TQLabel( i18n(
"Please select an action."), mWidgetStack ), i );
1136 mWidgetStack->raiseWidget(i);
1137 mComboBox->insertItem(
" " );
1138 mComboBox->setCurrentItem(i);
1141 mComboBox->setSizeLimit( mComboBox->count() );
1146 mComboBox->adjustSize();
1147 mComboBox->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) );
1148 setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
1152 setFocusProxy( mComboBox );
1155 connect( mComboBox, TQ_SIGNAL(activated(
int)),
1156 mWidgetStack, TQ_SLOT(raiseWidget(
int)) );
1162 bool found = false ;
1163 int count = mComboBox->count() - 1 ;
1164 TQString label = ( aAction ) ? aAction->
label() : TQString() ;
1168 for ( ; i < count ; i++ )
1169 if ( aAction && mComboBox->text(i) == label ) {
1175 mComboBox->setCurrentItem(i);
1176 mWidgetStack->raiseWidget(i);
1179 mActionList.at(i)->clearParamWidget( mWidgetStack->widget(i) );
1180 if ( found )
return;
1183 mComboBox->setCurrentItem( count );
1184 mWidgetStack->raiseWidget( count) ;
1191 KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ mComboBox->currentText() ];
1211 KMFilterActionWidgetLister::KMFilterActionWidgetLister( TQWidget *parent,
const char* name )
1212 : KWidgetLister( 1, FILTER_MAX_ACTIONS, parent, name )
1217 KMFilterActionWidgetLister::~KMFilterActionWidgetLister()
1221 void KMFilterActionWidgetLister::setActionList( TQPtrList<KMFilterAction> *aList )
1226 regenerateActionListFromWidgets();
1228 mActionList = aList;
1230 ((TQWidget*)parent())->setEnabled(
true );
1232 if ( aList->count() == 0 ) {
1237 int superfluousItems = (int)mActionList->count() - mMaxWidgets ;
1238 if ( superfluousItems > 0 ) {
1239 kdDebug(5006) <<
"KMFilterActionWidgetLister: Clipping action list to "
1240 << mMaxWidgets <<
" items!" << endl;
1242 for ( ; superfluousItems ; superfluousItems-- )
1243 mActionList->removeLast();
1247 setNumberOfShownWidgetsTo( mActionList->count() );
1250 TQPtrListIterator<KMFilterAction> aIt( *mActionList );
1251 TQPtrListIterator<TQWidget> wIt( mWidgetList );
1252 for ( aIt.toFirst(), wIt.toFirst() ;
1253 aIt.current() && wIt.current() ; ++aIt, ++wIt )
1257 void KMFilterActionWidgetLister::reset()
1260 regenerateActionListFromWidgets();
1264 ((TQWidget*)parent())->setEnabled(
false );
1267 TQWidget* KMFilterActionWidgetLister::createWidget( TQWidget *parent )
1272 void KMFilterActionWidgetLister::clearWidget( TQWidget *aWidget )
1278 void KMFilterActionWidgetLister::regenerateActionListFromWidgets()
1280 if ( !mActionList )
return;
1282 mActionList->clear();
1284 TQPtrListIterator<TQWidget> it( mWidgetList );
1285 for ( it.toFirst() ; it.current() ; ++it ) {
1288 mActionList->append( a );
1299 KMPopFilterActionWidget::KMPopFilterActionWidget(
const TQString& title, TQWidget *parent,
const char* name )
1300 : TQVButtonGroup( title, parent, name )
1302 mActionMap[Down] =
new TQRadioButton( i18n(
"&Download mail"),
this );
1303 mActionMap[Later] =
new TQRadioButton( i18n(
"Download mail la&ter"),
this );
1304 mActionMap[Delete] =
new TQRadioButton( i18n(
"D&elete mail from server"),
this );
1305 mIdMap[id(mActionMap[Later])] = Later;
1306 mIdMap[id(mActionMap[Down])] = Down;
1307 mIdMap[id(mActionMap[Delete])] = Delete;
1309 connect(
this, TQ_SIGNAL(clicked(
int)),
1310 this, TQ_SLOT( slotActionClicked(
int)) );
1313 void KMPopFilterActionWidget::setAction( KMPopFilterAction aAction )
1315 if( aAction == NoAction)
1322 blockSignals(
true );
1323 if(!mActionMap[aAction]->isChecked())
1325 mActionMap[aAction]->setChecked(
true );
1327 blockSignals(
false );
1332 KMPopFilterAction KMPopFilterActionWidget::action()
1337 void KMPopFilterActionWidget::slotActionClicked(
int aId)
1339 emit actionChanged(mIdMap[aId]);
1340 setAction(mIdMap[aId]);
1343 void KMPopFilterActionWidget::reset()
1345 blockSignals(
true );
1346 mActionMap[Down]->setChecked(
true );
1347 blockSignals(
false );
1349 setEnabled(
false );
1357 if (filters.isEmpty())
return;
1359 TQValueListConstIterator<KMFilter*> it;
1361 for ( it = filters.constBegin() ; it != filters.constEnd() ; ++it ) {
1371 TQValueList<KMFilter*>::iterator it;
1372 for ( it = filters.begin(); it != filters.end(); ++it )
1376 #include "kmfilterdlg.moc"
Abstract base class for KMail's filter actions.
virtual TQWidget * createParamWidget(TQWidget *parent) const
Creates a widget for setting the filter action parameter.
virtual void setParamWidgetValue(TQWidget *paramWidget) const
The filter action shall set it's widget's contents from it's parameter.
virtual void applyParamWidgetValue(TQWidget *paramWidget)
The filter action shall set it's parameter from the widget's contents.
const TQString label() const
Returns nationalized label, ie.
KMFilterDlg(TQWidget *parent=0, const char *name=0, bool popFilter=false, bool createDummyFilter=true)
Create the filter dialog.
KMPopFilterActionWidget * mActionGroup
The widget that allows editing the popFilter actions.
TDEListView * mAccountList
ListView that shows the accounts in the advanced tab.
void slotExportFilters()
Called when a user clicks the export filters button.
void slotFilterSelected(KMFilter *aFilter)
Internally connected to KMFilterListBox::filterSelected.
TQRadioButton * mApplyOnForAll
For a filter applied to inbound messages selects whether to apply this filter to all accounts or to s...
KMFilterActionWidgetLister * mActionLister
The widget that allows editing of the filter actions.
void slotImportFilters()
Called when a user clicks the import filters button.
KMFilterListBox * mFilterList
The widget that contains the ListBox showing the filters, and the controls to remove filters,...
KMSearchPatternEdit * mPatternEdit
The widget that allows editing of the filter pattern.
void slotActionChanged(const KMPopFilterAction aAction)
Action for popFilter.
TQCheckBox * mApplyOnIn
Lets the user select whether to apply this filter on inbound/outbound messages, both,...
This is a complex widget that is used to manipulate KMail's filter list.
TQListBox * mListBox
The listbox displaying the filter list.
void slotTop()
Called when the user clicks the 'Top' button.
KMFilterListBox(const TQString &title, TQWidget *parent=0, const char *name=0, bool popFilter=false)
Constuctor.
TQPushButton * mBtnNew
The various action buttons.
void slotBottom()
Called when the user clicks the 'Bottom' button.
void applyWidgets()
Emitted when this widget wants the edit widgets to apply the changes to the current filter.
void loadFilterList(bool createDummyFilter)
Loads the filter list and selects the first filter.
void slotSelected(int aIdx)
Called when the user clicks on a filter in the filter list.
bool showLaterMsgs()
Returns wheather the global option 'Show Later Msgs' is set or not.
void slotRename()
Called when the user clicks the 'Rename' button.
TQPtrList< KMFilter > mFilterList
The deep copy of the filter list.
void slotApplyFilterChanges()
Called when the user clicks either 'Apply' or 'OK' in KMFilterDlg.
void slotUp()
Called when the user clicks the 'Up' button.
TQValueList< KMFilter * > filtersForSaving() const
Returns a list of copies of the current list of filters.
void resetWidgets()
Emitted when this widget wants the edit widgets to let go of their filter reference.
void slotDown()
Called when the user clicks the 'Down' button.
void slotUpdateFilterName()
Called when the name of a filter might have changed (e.g.
void slotCopy()
Called when the user clicks the 'Copy' button.
void filterSelected(KMFilter *filter)
Emitted when a new filter has been selected by the user or if the current filter has changed after a ...
void slotNew()
Called when the user clicks the 'New' button.
int mIdxSelItem
The index of the currently selected item.
void createFilter(const TQCString &field, const TQString &value)
Called from KMFilterDlg.
void slotDelete()
Called when the user clicks the 'Delete' button.
void slotShowLaterToggled(bool aOn)
Called when the user toggles the 'Show Download Later Msgs' Checkbox in the Global Options section.
This widget is intended to be used in the filter configuration as well as in the message search dialo...
void updateSearchPattern()
Updates the search pattern according to the current widget values.
void reset()
Called when the widget should let go of the currently referenced filter and disable itself.
void setSearchPattern(KMSearchPattern *aPattern)
Set the search pattern.
This class is an abstraction of a search over messages.
void setName(const TQString &newName)
Set the name of the search pattern.
TQString name() const
Get the name of the search pattern.
Incoming mail is sent through the list of mail filter rules before it is placed in the associated mai...
static KMSearchRule * createInstance(const TQCString &field=0, Function function=FuncContains, const TQString &contents=TQString())
Create a search rule of a certain type by instantiating the appro- priate subclass depending on the f...
The account manager is responsible for creating accounts of various types via the factory method crea...
Utility class that provides persisting of filters to/from TDEConfig.
TQValueList< KMFilter * > importFilters()
Import filters.
void exportFilters(const TQValueList< KMFilter * > &)
Export the given filter rules to a file which is asked from the user.
Auxiliary struct to KMFilterActionDict.