3 Author: Marc Mutz <Marc@Mutz.com>
4 based upon work by Stefan Taferner <taferner@kde.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "kmfilterdlg.h"
23 // other KMail headers:
24 #include "kmsearchpatternedit.h"
25 #include "kmfiltermgr.h"
26 #include "kmmainwidget.h"
27 #include "accountmanager.h"
28 using KMail::AccountManager
;
29 #include "filterimporterexporter.h"
30 using KMail::FilterImporterExporter
;
33 #include <kcombobox.h>
34 #include <kmessagebox.h>
37 #include <kinputdialog.h>
38 #include <kiconloader.h>
39 #include <kwindowsystem.h>
41 #include <kicondialog.h>
42 #include <kkeysequencewidget.h>
43 #include <kpushbutton.h>
44 #include <kconfiggroup.h>
45 #include <ktabwidget.h>
50 #include <QGridLayout>
52 #include <QListWidget>
53 #include <QStackedWidget>
54 #include <QVBoxLayout>
55 #include <QTreeWidget>
61 // What's this help texts
62 const char * _wt_filterlist
=
63 I18N_NOOP( "<qt><p>This is the list of defined filters. "
64 "They are processed top-to-bottom.</p>"
65 "<p>Click on any filter to edit it "
66 "using the controls in the right-hand half "
67 "of the dialog.</p></qt>" );
68 const char * _wt_filterlist_new
=
69 I18N_NOOP( "<qt><p>Click this button to create a new filter.</p>"
70 "<p>The filter will be inserted just before the currently-"
71 "selected one, but you can always change that "
73 "<p>If you have clicked this button accidentally, you can undo this "
74 "by clicking on the <em>Delete</em> button.</p></qt>" );
75 const char * _wt_filterlist_copy
=
76 I18N_NOOP( "<qt><p>Click this button to copy a filter.</p>"
77 "<p>If you have clicked this button accidentally, you can undo this "
78 "by clicking on the <em>Delete</em> button.</p></qt>" );
79 const char * _wt_filterlist_delete
=
80 I18N_NOOP( "<qt><p>Click this button to <em>delete</em> the currently-"
81 "selected filter from the list above.</p>"
82 "<p>There is no way to get the filter back once "
83 "it is deleted, but you can always leave the "
84 "dialog by clicking <em>Cancel</em> to discard the "
85 "changes made.</p></qt>" );
86 const char * _wt_filterlist_up
=
87 I18N_NOOP( "<qt><p>Click this button to move the currently-"
88 "selected filter <em>up</em> one in the list above.</p>"
89 "<p>This is useful since the order of the filters in the list "
90 "determines the order in which they are tried on messages: "
91 "The topmost filter gets tried first.</p>"
92 "<p>If you have clicked this button accidentally, you can undo this "
93 "by clicking on the <em>Down</em> button.</p></qt>" );
94 const char * _wt_filterlist_down
=
95 I18N_NOOP( "<qt><p>Click this button to move the currently-"
96 "selected filter <em>down</em> one in the list above.</p>"
97 "<p>This is useful since the order of the filters in the list "
98 "determines the order in which they are tried on messages: "
99 "The topmost filter gets tried first.</p>"
100 "<p>If you have clicked this button accidentally, you can undo this "
101 "by clicking on the <em>Up</em> button.</p></qt>" );
102 const char * _wt_filterlist_rename
=
103 I18N_NOOP( "<qt><p>Click this button to rename the currently-selected filter.</p>"
104 "<p>Filters are named automatically, as long as they start with "
106 "<p>If you have renamed a filter accidentally and want automatic "
107 "naming back, click this button and select <em>Clear</em> followed "
108 "by <em>OK</em> in the appearing dialog.</p></qt>" );
109 const char * _wt_filterdlg_showLater
=
110 I18N_NOOP( "<qt><p>Check this button to force the confirmation dialog to be "
111 "displayed.</p><p>This is useful if you have defined a ruleset that tags "
112 "messages to be downloaded later. Without the possibility to force "
113 "the dialog popup, these messages could never be downloaded if no "
114 "other large messages were waiting on the server, or if you wanted to "
115 "change the ruleset to tag the messages differently.</p></qt>" );
117 // The anchor of the filter dialog's help.
118 const char * KMFilterDlgHelpAnchor
= "filters-id" ;
119 const char * KMPopFilterDlgHelpAnchor
= "popfilters-id" ;
121 //=============================================================================
123 // class KMFilterDlg (the filter dialog)
125 //=============================================================================
127 KMFilterDlg::KMFilterDlg(QWidget
* parent
, bool popFilter
, bool createDummyFilter
)
129 bPopFilter(popFilter
)
132 setCaption( i18n("POP3 Filter Rules") );
134 setCaption( i18n("Filter Rules") );
135 setButtons( Help
|Ok
|Apply
|Cancel
|User1
|User2
);
137 KWindowSystem::setIcons( winId(), qApp
->windowIcon().pixmap(IconSize(KIconLoader::Desktop
),IconSize(KIconLoader::Desktop
)), qApp
->windowIcon().pixmap(IconSize(KIconLoader::Small
),IconSize(KIconLoader::Small
)) );
138 setHelp( (bPopFilter
)? KMPopFilterDlgHelpAnchor
: KMFilterDlgHelpAnchor
);
139 setButtonText( User1
, i18n("Import...") );
140 setButtonText( User2
, i18n("Export...") );
141 connect( this, SIGNAL(user1Clicked()),
142 this, SLOT( slotImportFilters()) );
143 connect( this, SIGNAL(user2Clicked()),
144 this, SLOT( slotExportFilters()) );
146 QWidget
*w
= new QWidget( this );
148 QHBoxLayout
*topLayout
= new QHBoxLayout( w
);
149 topLayout
->setObjectName( "topLayout" );
150 topLayout
->setSpacing( spacingHint() );
151 topLayout
->setMargin( 0 );
152 QHBoxLayout
*hbl
= topLayout
;
153 QVBoxLayout
*vbl2
= 0;
157 mFilterList
= new KMFilterListBox( i18n("Available Filters"), w
, 0, bPopFilter
);
158 topLayout
->addWidget( mFilterList
, 1 /*stretch*/ );
161 KTabWidget
*tabWidget
= new KTabWidget( w
);
162 tabWidget
->setObjectName( "kmfd_tab" );
163 topLayout
->addWidget( tabWidget
);
165 page1
= new QWidget( tabWidget
);
166 tabWidget
->addTab( page1
, i18nc("General mail filter settings.", "General") );
167 hbl
= new QHBoxLayout( page1
);
168 hbl
->setObjectName( "kmfd_hbl" );
169 hbl
->setSpacing( spacingHint() );
172 page2
= new QWidget( tabWidget
);
173 tabWidget
->addTab( page2
, i18nc("Advanced mail filter settings.","Advanced") );
174 vbl2
= new QVBoxLayout( page2
);
175 vbl2
->setObjectName( "kmfd_vbl2" );
176 vbl2
->setSpacing( spacingHint() );
177 vbl2
->setMargin( 0 );
180 QVBoxLayout
*vbl
= new QVBoxLayout();
181 hbl
->addLayout( vbl
);
182 vbl
->setObjectName( "kmfd_vbl" );
183 vbl
->setSpacing( spacingHint() );
184 hbl
->setStretchFactor( vbl
, 2 );
186 mPatternEdit
= new KMSearchPatternEdit( i18n("Filter Criteria"),
187 bPopFilter
? w
: page1
, bPopFilter
);
188 vbl
->addWidget( mPatternEdit
, 0, Qt::AlignTop
);
191 mActionGroup
= new KMPopFilterActionWidget( i18n("Filter Action"), w
);
192 vbl
->addWidget( mActionGroup
, 0, Qt::AlignTop
);
194 mGlobalsBox
= new QGroupBox( i18n("Global Options"), w
);
195 QHBoxLayout
*layout
= new QHBoxLayout
;
196 mShowLaterBtn
= new QCheckBox( i18n("Always &show matched 'Download Later' messages in confirmation dialog"), mGlobalsBox
);
197 mShowLaterBtn
->setWhatsThis( i18n(_wt_filterdlg_showLater
) );
198 layout
->addWidget( mShowLaterBtn
);
199 mGlobalsBox
->setLayout( layout
);
200 vbl
->addWidget( mGlobalsBox
, 0, Qt::AlignTop
);
203 QGroupBox
*agb
= new QGroupBox( i18n("Filter Actions"), page1
);
204 QHBoxLayout
*layout
= new QHBoxLayout
;
205 mActionLister
= new KMFilterActionWidgetLister( agb
);
206 layout
->addWidget( mActionLister
);
207 agb
->setLayout( layout
);
208 vbl
->addWidget( agb
, 0, Qt::AlignTop
);
210 mAdvOptsGroup
= new QGroupBox (i18n("Advanced Options"), page2
);
212 QGridLayout
*gl
= new QGridLayout();
213 QVBoxLayout
*vbl3
= new QVBoxLayout();
214 gl
->addLayout( vbl3
, 0, 0 );
215 vbl3
->setObjectName( "vbl3" );
216 vbl3
->setSpacing( spacingHint() );
217 vbl3
->addStretch( 1 );
218 mApplyOnIn
= new QCheckBox( i18n("Apply this filter to incoming messages:"), mAdvOptsGroup
);
219 vbl3
->addWidget( mApplyOnIn
);
220 QButtonGroup
*bg
= new QButtonGroup( mAdvOptsGroup
);
221 bg
->setObjectName( "bg" );
222 mApplyOnForAll
= new QRadioButton( i18n("from all accounts"), mAdvOptsGroup
);
223 bg
->addButton( mApplyOnForAll
);
224 vbl3
->addWidget( mApplyOnForAll
);
225 mApplyOnForTraditional
= new QRadioButton( i18n("from all but online IMAP accounts"), mAdvOptsGroup
);
226 bg
->addButton( mApplyOnForTraditional
);
227 vbl3
->addWidget( mApplyOnForTraditional
);
228 mApplyOnForChecked
= new QRadioButton( i18n("from checked accounts only"), mAdvOptsGroup
);
229 bg
->addButton( mApplyOnForChecked
);
230 vbl3
->addWidget( mApplyOnForChecked
);
231 vbl3
->addStretch( 2 );
233 mAccountList
= new QTreeWidget( mAdvOptsGroup
);
234 mAccountList
->setObjectName( "accountList" );
235 mAccountList
->setColumnCount( 2 );
236 QStringList headerNames
;
237 headerNames
<< i18n("Account Name") << i18n("Type");
238 mAccountList
->setHeaderItem( new QTreeWidgetItem( headerNames
) );
239 mAccountList
->setAllColumnsShowFocus( true );
240 mAccountList
->setFrameStyle( QFrame::WinPanel
+ QFrame::Sunken
);
241 mAccountList
->setSortingEnabled( false );
242 mAccountList
->setRootIsDecorated( false );
243 gl
->addWidget( mAccountList
, 0, 1, 4, 3 );
245 mApplyOnOut
= new QCheckBox( i18n("Apply this filter to &sent messages"), mAdvOptsGroup
);
246 gl
->addWidget( mApplyOnOut
, 4, 0, 1, 4 );
248 mApplyOnCtrlJ
= new QCheckBox( i18n("Apply this filter on manual &filtering"), mAdvOptsGroup
);
249 gl
->addWidget( mApplyOnCtrlJ
, 5, 0, 1, 4 );
251 mStopProcessingHere
= new QCheckBox( i18n("If this filter &matches, stop processing here"), mAdvOptsGroup
);
252 gl
->addWidget( mStopProcessingHere
, 6, 0, 1, 4 );
253 mConfigureShortcut
= new QCheckBox( i18n("Add this filter to the Apply Filter menu"), mAdvOptsGroup
);
254 gl
->addWidget( mConfigureShortcut
, 7, 0, 1, 2 );
255 QLabel
*keyButtonLabel
= new QLabel( i18n( "Shortcut:" ), mAdvOptsGroup
);
256 keyButtonLabel
->setAlignment( Qt::AlignVCenter
| Qt::AlignRight
);
257 gl
->addWidget( keyButtonLabel
, 7, 2, 1, 1);
258 mKeySeqWidget
= new KKeySequenceWidget( mAdvOptsGroup
);
259 mKeySeqWidget
->setObjectName( "FilterShortcutSelector" );
260 gl
->addWidget( mKeySeqWidget
, 7, 3, 1, 1);
261 mKeySeqWidget
->setEnabled( false );
262 mKeySeqWidget
->setCheckActionCollections(
263 kmkernel
->getKMMainWidget()->actionCollections() );
264 mConfigureToolbar
= new QCheckBox( i18n("Additionally add this filter to the toolbar"), mAdvOptsGroup
);
265 gl
->addWidget( mConfigureToolbar
, 8, 0, 1, 4 );
266 mConfigureToolbar
->setEnabled( false );
268 KHBox
*hbox
= new KHBox( mAdvOptsGroup
);
269 mFilterActionLabel
= new QLabel( i18n( "Icon for this filter:" ),
271 mFilterActionLabel
->setEnabled( false );
273 mFilterActionIconButton
= new KIconButton( hbox
);
274 mFilterActionLabel
->setBuddy( mFilterActionIconButton
);
275 mFilterActionIconButton
->setIconType( KIconLoader::NoGroup
, KIconLoader::Action
, false );
276 mFilterActionIconButton
->setIconSize( 16 );
277 mFilterActionIconButton
->setIcon( "system-run" );
278 mFilterActionIconButton
->setEnabled( false );
280 gl
->addWidget( hbox
, 9, 0, 1, 4 );
282 mAdvOptsGroup
->setLayout( gl
);
284 vbl2
->addWidget( mAdvOptsGroup
, 0, Qt::AlignTop
);
287 vbl
->addStretch( 1 );
289 // load the filter parts into the edit widgets
290 connect( mFilterList
, SIGNAL(filterSelected(KMFilter
*)),
291 this, SLOT(slotFilterSelected(KMFilter
*)) );
294 // set the state of the global setting 'show later msgs'
295 connect( mShowLaterBtn
, SIGNAL(toggled(bool)),
296 mFilterList
, SLOT(slotShowLaterToggled(bool)));
298 // set the action in the filter when changed
299 connect( mActionGroup
, SIGNAL(actionChanged(const KMPopFilterAction
)),
300 this, SLOT(slotActionChanged(const KMPopFilterAction
)) );
302 // transfer changes from the 'Apply this filter on...'
303 // combo box to the filter
304 connect( mApplyOnIn
, SIGNAL(clicked()),
305 this, SLOT(slotApplicabilityChanged()) );
306 connect( mApplyOnForAll
, SIGNAL(clicked()),
307 this, SLOT(slotApplicabilityChanged()) );
308 connect( mApplyOnForTraditional
, SIGNAL(clicked()),
309 this, SLOT(slotApplicabilityChanged()) );
310 connect( mApplyOnForChecked
, SIGNAL(clicked()),
311 this, SLOT(slotApplicabilityChanged()) );
312 connect( mApplyOnOut
, SIGNAL(clicked()),
313 this, SLOT(slotApplicabilityChanged()) );
314 connect( mApplyOnCtrlJ
, SIGNAL(clicked()),
315 this, SLOT(slotApplicabilityChanged()) );
316 connect( mAccountList
, SIGNAL( itemChanged(QTreeWidgetItem
*,int) ),
317 this, SLOT( slotApplicableAccountsChanged() ) );
319 // transfer changes from the 'stop processing here'
320 // check box to the filter
321 connect( mStopProcessingHere
, SIGNAL(toggled(bool)),
322 this, SLOT(slotStopProcessingButtonToggled(bool)) );
324 connect( mConfigureShortcut
, SIGNAL(toggled(bool)),
325 this, SLOT(slotConfigureShortcutButtonToggled(bool)) );
327 connect( mKeySeqWidget
, SIGNAL( keySequenceChanged( const QKeySequence
& ) ),
328 this, SLOT( slotShortcutChanged( const QKeySequence
& ) ) );
330 connect( mConfigureToolbar
, SIGNAL(toggled(bool)),
331 this, SLOT(slotConfigureToolbarButtonToggled(bool)) );
333 connect( mFilterActionIconButton
, SIGNAL( iconChanged( const QString
& ) ),
334 this, SLOT( slotFilterActionIconChanged( const QString
& ) ) );
337 // reset all widgets here
338 connect( mFilterList
, SIGNAL(resetWidgets()),
339 this, SLOT(slotReset()) );
341 connect( mFilterList
, SIGNAL( applyWidgets() ),
342 this, SLOT( slotUpdateFilter() ) );
344 // support auto-naming the filter
345 connect( mPatternEdit
, SIGNAL(maybeNameChanged()),
346 mFilterList
, SLOT(slotUpdateFilterName()) );
348 // apply changes on 'Apply'
349 connect( this, SIGNAL(applyClicked()),
350 mFilterList
, SLOT(slotApplyFilterChanges()) );
352 // apply changes on 'OK'
353 connect( this, SIGNAL(okClicked()),
354 mFilterList
, SLOT(slotApplyFilterChanges()) );
356 // save dialog size on 'OK'
357 connect( this, SIGNAL(okClicked()),
358 this, SLOT(slotSaveSize()) );
360 // destruct the dialog on OK, close and Cancel
361 connect( this, SIGNAL(finished()),
362 this, SLOT(slotFinished()) );
364 KConfigGroup
geometry( KMKernel::config(), "Geometry");
365 const char * configKey
366 = bPopFilter
? "popFilterDialogSize" : "filterDialogSize";
367 if ( geometry
.hasKey( configKey
) )
368 resize( geometry
.readEntry( configKey
, QSize() ));
372 // load the filter list (emits filterSelected())
373 mFilterList
->loadFilterList( createDummyFilter
);
376 void KMFilterDlg::slotFinished() {
380 void KMFilterDlg::slotSaveSize() {
381 KConfigGroup
geometry( KMKernel::config(), "Geometry" );
382 geometry
.writeEntry( bPopFilter
? "popFilterDialogSize" : "filterDialogSize", size() );
385 /** Set action of popFilter */
386 void KMFilterDlg::slotActionChanged(const KMPopFilterAction aAction
)
388 mFilter
->setAction(aAction
);
391 void KMFilterDlg::slotFilterSelected( KMFilter
* aFilter
)
396 mActionGroup
->setAction( aFilter
->action() );
397 mGlobalsBox
->setEnabled(true);
398 mShowLaterBtn
->setChecked(mFilterList
->showLaterMsgs());
400 mActionLister
->setActionList( aFilter
->actions() );
402 mAdvOptsGroup
->setEnabled( true );
405 mPatternEdit
->setSearchPattern( aFilter
->pattern() );
409 kDebug(5006) << "apply on inbound ==" << aFilter
->applyOnInbound();
410 kDebug(5006) << "apply on outbound ==" << aFilter
->applyOnOutbound();
411 kDebug(5006) << "apply on explicit ==" << aFilter
->applyOnExplicit();
413 // NOTE: setting these values activates the slot that sets them in
414 // the filter! So make sure we have the correct values _before_ we
415 // set the first one:
416 const bool applyOnIn
= aFilter
->applyOnInbound();
417 const bool applyOnForAll
= aFilter
->applicability() == KMFilter::All
;
418 const bool applyOnTraditional
= aFilter
->applicability() == KMFilter::ButImap
;
419 const bool applyOnOut
= aFilter
->applyOnOutbound();
420 const bool applyOnExplicit
= aFilter
->applyOnExplicit();
421 const bool stopHere
= aFilter
->stopProcessingHere();
422 const bool configureShortcut
= aFilter
->configureShortcut();
423 const bool configureToolbar
= aFilter
->configureToolbar();
424 const QString icon
= aFilter
->icon();
425 const KShortcut
shortcut( aFilter
->shortcut() );
427 mApplyOnIn
->setChecked( applyOnIn
);
428 mApplyOnForAll
->setEnabled( applyOnIn
);
429 mApplyOnForTraditional
->setEnabled( applyOnIn
);
430 mApplyOnForChecked
->setEnabled( applyOnIn
);
431 mApplyOnForAll
->setChecked( applyOnForAll
);
432 mApplyOnForTraditional
->setChecked( applyOnTraditional
);
433 mApplyOnForChecked
->setChecked( !applyOnForAll
&& !applyOnTraditional
);
434 mAccountList
->setEnabled( mApplyOnForChecked
->isEnabled() && mApplyOnForChecked
->isChecked() );
435 slotUpdateAccountList();
436 mApplyOnOut
->setChecked( applyOnOut
);
437 mApplyOnCtrlJ
->setChecked( applyOnExplicit
);
438 mStopProcessingHere
->setChecked( stopHere
);
439 mConfigureShortcut
->setChecked( configureShortcut
);
440 mKeySeqWidget
->setKeySequence( shortcut
.primary(),
441 KKeySequenceWidget::NoValidate
);
442 mConfigureToolbar
->setChecked( configureToolbar
);
443 mFilterActionIconButton
->setIcon( icon
);
447 void KMFilterDlg::slotReset()
450 mPatternEdit
->reset();
453 mActionGroup
->reset();
454 mGlobalsBox
->setEnabled( false );
456 mActionLister
->reset();
457 mAdvOptsGroup
->setEnabled( false );
458 slotUpdateAccountList();
462 void KMFilterDlg::slotUpdateFilter()
464 mPatternEdit
->updateSearchPattern();
466 mActionLister
->updateActionList();
470 void KMFilterDlg::slotApplicabilityChanged()
473 mFilter
->setApplyOnInbound( mApplyOnIn
->isChecked() );
474 mFilter
->setApplyOnOutbound( mApplyOnOut
->isChecked() );
475 mFilter
->setApplyOnExplicit( mApplyOnCtrlJ
->isChecked() );
476 if ( mApplyOnForAll
->isChecked() )
477 mFilter
->setApplicability( KMFilter::All
);
478 else if ( mApplyOnForTraditional
->isChecked() )
479 mFilter
->setApplicability( KMFilter::ButImap
);
480 else if ( mApplyOnForChecked
->isChecked() )
481 mFilter
->setApplicability( KMFilter::Checked
);
483 mApplyOnForAll
->setEnabled( mApplyOnIn
->isChecked() );
484 mApplyOnForTraditional
->setEnabled( mApplyOnIn
->isChecked() );
485 mApplyOnForChecked
->setEnabled( mApplyOnIn
->isChecked() );
486 mAccountList
->setEnabled( mApplyOnForChecked
->isEnabled() && mApplyOnForChecked
->isChecked() );
488 // Advanced tab functionality - Update list of accounts this filter applies to
489 QTreeWidgetItemIterator
it( mAccountList
);
490 while( QTreeWidgetItem
* item
= *it
) {
491 int id
= item
->text( 2 ).toInt();
492 item
->setCheckState( 0, mFilter
->applyOnAccount( id
) ? Qt::Checked
:
497 kDebug(5006) << "Setting filter to be applied at"
498 << ( mFilter
->applyOnInbound() ? "incoming " : "" )
499 << ( mFilter
->applyOnOutbound() ? "outgoing " : "" )
500 << ( mFilter
->applyOnExplicit() ? "explicit CTRL-J" : "" );
504 void KMFilterDlg::slotApplicableAccountsChanged()
506 // Advanced tab functionality - Update list of accounts this filter applies to
507 if ( mFilter
&& mApplyOnForChecked
->isEnabled() && mApplyOnForChecked
->isChecked() ) {
509 QTreeWidgetItemIterator
it( mAccountList
);
511 while( QTreeWidgetItem
*item
= *it
) {
512 int id
= item
->text( 2 ).toInt();
513 mFilter
->setApplyOnAccount( id
, item
->checkState( 0 ) == Qt::Checked
);
519 void KMFilterDlg::slotStopProcessingButtonToggled( bool aChecked
)
522 mFilter
->setStopProcessingHere( aChecked
);
525 void KMFilterDlg::slotConfigureShortcutButtonToggled( bool aChecked
)
528 mFilter
->setConfigureShortcut( aChecked
);
529 mKeySeqWidget
->setEnabled( aChecked
);
530 mConfigureToolbar
->setEnabled( aChecked
);
531 mFilterActionIconButton
->setEnabled( aChecked
);
532 mFilterActionLabel
->setEnabled( aChecked
);
536 void KMFilterDlg::slotShortcutChanged( const QKeySequence
&newSeq
)
539 mKeySeqWidget
->applyStealShortcut();
540 mFilter
->setShortcut( KShortcut( newSeq
) );
544 void KMFilterDlg::slotConfigureToolbarButtonToggled( bool aChecked
)
547 mFilter
->setConfigureToolbar( aChecked
);
550 void KMFilterDlg::slotFilterActionIconChanged( const QString
&icon
)
553 mFilter
->setIcon( icon
);
556 void KMFilterDlg::slotUpdateAccountList()
558 mAccountList
->clear();
560 QTreeWidgetItem
*top
= 0;
562 // Block the signals here, otherwise we end up calling
563 // slotApplicableAccountsChanged(), which will read the incomplete item
564 // state and write that back to the filter
565 mAccountList
->blockSignals( true );
566 QList
<KMAccount
*>::iterator accountIt
= kmkernel
->acctMgr()->begin();
567 while ( accountIt
!= kmkernel
->acctMgr()->end() ) {
568 KMAccount
*account
= *accountIt
;
570 QTreeWidgetItem
*listItem
= new QTreeWidgetItem( mAccountList
, top
);
571 listItem
->setText( 0, account
->name() );
572 listItem
->setText( 1, KAccount::displayNameForType( account
->type() ) );
573 listItem
->setText( 2, QString( "%1" ).arg( account
->id() ) );
575 listItem
->setCheckState( 0, mFilter
->applyOnAccount( account
->id() ) ?
576 Qt::Checked
: Qt::Unchecked
);
579 mAccountList
->blockSignals( false );
581 // make sure our hidden column is really hidden (Qt tends to re-show it)
582 mAccountList
->hideColumn( 2 );
583 mAccountList
->resizeColumnToContents( 0 );
584 mAccountList
->resizeColumnToContents( 1 );
586 top
= mAccountList
->topLevelItem( 0 );
588 mAccountList
->setCurrentItem( top
);
592 //=============================================================================
594 // class KMFilterListBox (the filter list manipulator)
596 //=============================================================================
598 KMFilterListBox::KMFilterListBox( const QString
& title
, QWidget
*parent
,
599 const char* name
, bool popFilter
)
600 : QGroupBox( title
, parent
),
601 bPopFilter(popFilter
)
603 setObjectName( name
);
604 QVBoxLayout
*layout
= new QVBoxLayout();
608 //----------- the list box
609 mListWidget
= new QListWidget(this);
610 mListWidget
->setMinimumWidth(150);
611 mListWidget
->setWhatsThis( i18n(_wt_filterlist
) );
613 layout
->addWidget( mListWidget
);
615 //----------- the first row of buttons
616 KHBox
*hb
= new KHBox(this);
618 mBtnUp
= new KPushButton( QString(), hb
);
619 mBtnUp
->setAutoRepeat( true );
620 mBtnUp
->setIcon( KIcon( "go-up" ) );
621 mBtnUp
->setIconSize( QSize( KIconLoader::SizeSmall
, KIconLoader::SizeSmall
) );
622 mBtnUp
->setMinimumSize( mBtnUp
->sizeHint() * 1.2 );
623 mBtnDown
= new KPushButton( QString(), hb
);
624 mBtnDown
->setAutoRepeat( true );
625 mBtnDown
->setIcon( KIcon( "go-down" ) );
626 mBtnDown
->setIconSize( QSize( KIconLoader::SizeSmall
, KIconLoader::SizeSmall
) );
627 mBtnDown
->setMinimumSize( mBtnDown
->sizeHint() * 1.2 );
628 mBtnUp
->setToolTip( i18nc("Move selected filter up.", "Up") );
629 mBtnDown
->setToolTip( i18nc("Move selected filter down.", "Down") );
630 mBtnUp
->setWhatsThis( i18n(_wt_filterlist_up
) );
631 mBtnDown
->setWhatsThis( i18n(_wt_filterlist_down
) );
633 layout
->addWidget( hb
);
635 //----------- the second row of buttons
636 hb
= new KHBox(this);
638 mBtnNew
= new QPushButton( QString(), hb
);
639 mBtnNew
->setIcon( KIcon( "document-new" ) );
640 mBtnNew
->setIconSize( QSize( KIconLoader::SizeSmall
, KIconLoader::SizeSmall
) );
641 mBtnNew
->setMinimumSize( mBtnNew
->sizeHint() * 1.2 );
642 mBtnCopy
= new QPushButton( QString(), hb
);
643 mBtnCopy
->setIcon( KIcon( "edit-copy" ) );
644 mBtnCopy
->setIconSize( QSize( KIconLoader::SizeSmall
, KIconLoader::SizeSmall
) );
645 mBtnCopy
->setMinimumSize( mBtnCopy
->sizeHint() * 1.2 );
646 mBtnDelete
= new QPushButton( QString(), hb
);
647 mBtnDelete
->setIcon( KIcon( "edit-delete" ) );
648 mBtnDelete
->setIconSize( QSize( KIconLoader::SizeSmall
, KIconLoader::SizeSmall
) );
649 mBtnDelete
->setMinimumSize( mBtnDelete
->sizeHint() * 1.2 );
650 mBtnRename
= new QPushButton( i18n("Rename..."), hb
);
651 mBtnNew
->setToolTip( i18nc("@action:button in filter list manipulator", "New") );
652 mBtnCopy
->setToolTip( i18n("Copy") );
653 mBtnDelete
->setToolTip( i18n("Delete"));
654 mBtnNew
->setWhatsThis( i18n(_wt_filterlist_new
) );
655 mBtnCopy
->setWhatsThis( i18n(_wt_filterlist_copy
) );
656 mBtnDelete
->setWhatsThis( i18n(_wt_filterlist_delete
) );
657 mBtnRename
->setWhatsThis( i18n(_wt_filterlist_rename
) );
659 layout
->addWidget( hb
);
662 //----------- now connect everything
663 connect( mListWidget
, SIGNAL(currentRowChanged(int)),
664 this, SLOT(slotSelected(int)) );
665 connect( mListWidget
, SIGNAL(itemDoubleClicked(QListWidgetItem
*)),
666 this, SLOT( slotRename()) );
667 connect( mBtnUp
, SIGNAL(clicked()),
668 this, SLOT(slotUp()) );
669 connect( mBtnDown
, SIGNAL(clicked()),
670 this, SLOT(slotDown()) );
671 connect( mBtnNew
, SIGNAL(clicked()),
672 this, SLOT(slotNew()) );
673 connect( mBtnCopy
, SIGNAL(clicked()),
674 this, SLOT(slotCopy()) );
675 connect( mBtnDelete
, SIGNAL(clicked()),
676 this, SLOT(slotDelete()) );
677 connect( mBtnRename
, SIGNAL(clicked()),
678 this, SLOT(slotRename()) );
680 // the dialog should call loadFilterList()
681 // when all signals are connected.
686 KMFilterListBox::~KMFilterListBox()
688 qDeleteAll( mFilterList
);
692 void KMFilterListBox::createFilter( const QByteArray
& field
,
693 const QString
& value
)
695 KMSearchRule
*newRule
= KMSearchRule::createInstance( field
, KMSearchRule::FuncContains
, value
);
697 KMFilter
*newFilter
= new KMFilter( bPopFilter
);
698 newFilter
->pattern()->append( newRule
);
699 newFilter
->pattern()->setName( QString("<%1>:%2").arg( QString::fromLatin1( field
) ).arg( value
) );
701 KMFilterActionDesc
*desc
= kmkernel
->filterActionDict()->value( "transfer" );
703 newFilter
->actions()->append( desc
->create() );
705 insertFilter( newFilter
);
709 bool KMFilterListBox::showLaterMsgs()
714 void KMFilterListBox::slotUpdateFilterName()
716 if ( mIdxSelItem
< 0 ) {
717 kDebug(5006) << "Called while no filter is selected, ignoring. idx=" << mIdxSelItem
;
721 KMSearchPattern
*p
= mFilterList
.at(mIdxSelItem
)->pattern();
724 QString shouldBeName
= p
->name();
725 QString displayedName
= mListWidget
->item( mIdxSelItem
)->text();
727 if ( shouldBeName
.trimmed().isEmpty() ) {
728 mFilterList
.at(mIdxSelItem
)->setAutoNaming( true );
731 if ( mFilterList
.at(mIdxSelItem
)->isAutoNaming() ) {
732 // auto-naming of patterns
733 if ( p
->first() && !p
->first()->field().trimmed().isEmpty() )
734 shouldBeName
= QString( "<%1>: %2" ).arg( QString::fromLatin1( p
->first()->field() ) ).arg( p
->first()->contents() );
736 shouldBeName
= '<' + i18n("unnamed") + '>';
737 p
->setName( shouldBeName
);
740 if ( displayedName
== shouldBeName
) return;
742 mListWidget
->blockSignals(true);
743 mListWidget
->item( mIdxSelItem
)->setText( shouldBeName
);
744 mListWidget
->blockSignals(false);
747 void KMFilterListBox::slotShowLaterToggled(bool aOn
)
752 void KMFilterListBox::slotApplyFilterChanges()
754 if ( mIdxSelItem
>= 0 ) {
756 slotSelected( mListWidget
->currentRow() );
759 // by now all edit widgets should have written back
760 // their widget's data into our filter list.
764 fm
= kmkernel
->popFilterMgr();
766 fm
= kmkernel
->filterMgr();
768 QList
<KMFilter
*> newFilters
= filtersForSaving();
771 fm
->setShowLaterMsgs( mShowLater
);
773 fm
->setFilters( newFilters
);
774 if ( fm
->atLeastOneOnlineImapFolderTarget() ) {
775 QString str
= i18n("At least one filter targets a folder on an online "
776 "IMAP account. Such filters will only be applied "
777 "when manually filtering and when filtering "
778 "incoming online IMAP mail.");
779 KMessageBox::information( this, str
, QString(), "filterDlgOnlineImapCheck" );
783 QList
<KMFilter
*> KMFilterListBox::filtersForSaving() const
785 const_cast<KMFilterListBox
*>( this )->applyWidgets(); // signals aren't const
786 QList
<KMFilter
*> filters
;
787 QStringList emptyFilters
;
788 foreach ( KMFilter
*const it
, mFilterList
) {
789 KMFilter
*f
= new KMFilter( *it
); // deep copy
792 // the filter is valid:
795 // the filter is invalid:
796 emptyFilters
<< f
->name();
801 // report on invalid filters:
802 if ( !emptyFilters
.empty() ) {
803 QString msg
= i18n("The following filters have not been saved because they "
804 "were invalid (e.g. containing no actions or no search "
806 KMessageBox::informationList( 0, msg
, emptyFilters
, QString(),
807 "ShowInvalidFilterWarning" );
812 void KMFilterListBox::slotSelected( int aIdx
)
814 kDebug(5006) << "idx=" << aIdx
;
817 if ( mIdxSelItem
>= 0 && mIdxSelItem
< mFilterList
.count() ) {
818 KMFilter
*f
= mFilterList
.at(aIdx
);
820 emit
filterSelected( f
);
829 void KMFilterListBox::slotNew()
831 // just insert a new filter.
832 insertFilter( new KMFilter( bPopFilter
) );
836 void KMFilterListBox::slotCopy()
838 if ( mIdxSelItem
< 0 ) {
839 kDebug(5006) << "Called while no filter is selected, ignoring.";
843 // make sure that all changes are written to the filter before we copy it
846 KMFilter
*filter
= mFilterList
.at( mIdxSelItem
);
848 // enableControls should make sure this method is
849 // never called when no filter is selected.
852 // inserts a copy of the current filter.
853 insertFilter( new KMFilter( *filter
) );
857 void KMFilterListBox::slotDelete()
859 if ( mIdxSelItem
< 0 ) {
860 kDebug(5006) << "Called while no filter is selected, ignoring.";
864 int oIdxSelItem
= mIdxSelItem
;
867 // TODO remove this line: mListWidget->clearSelection();
868 // broadcast that all widgets let go
872 // remove the filter from both the filter list...
873 mFilterList
.takeAt( oIdxSelItem
);
875 mListWidget
->takeItem( oIdxSelItem
);
877 int count
= mListWidget
->count();
878 // and set the new current item.
879 if ( count
> oIdxSelItem
)
880 // oIdxItem is still a valid index
881 mListWidget
->setCurrentRow( oIdxSelItem
);
883 // oIdxSelIdx is no longer valid, but the
884 // list box isn't empty
885 mListWidget
->setCurrentRow( count
- 1 );
887 // work around a problem when deleting the first item in a QListWidget:
888 // after takeItem, slotSelectionChanged is emitted with 1, but the row 0
889 // remains selected and another selectCurrentRow(0) does not trigger the
890 // selectionChanged signal
891 // (qt-copy as of 2006-12-22 / gungl)
892 if ( oIdxSelItem
== 0 )
895 mIdxSelItem
= mListWidget
->currentRow();
899 void KMFilterListBox::slotUp()
901 if ( mIdxSelItem
< 0 ) {
902 kDebug(5006) << "Called while no filter is selected, ignoring.";
905 if ( mIdxSelItem
== 0 ) {
906 kDebug(5006) << "Called while the _topmost_ filter is selected, ignoring.";
910 swapNeighbouringFilters( mIdxSelItem
, mIdxSelItem
- 1 );
914 void KMFilterListBox::slotDown()
916 if ( mIdxSelItem
< 0 ) {
917 kDebug(5006) << "Called while no filter is selected, ignoring.";
920 if ( mIdxSelItem
== (int)mListWidget
->count() - 1 ) {
921 kDebug(5006) << "Called while the _last_ filter is selected, ignoring.";
925 swapNeighbouringFilters( mIdxSelItem
, mIdxSelItem
+ 1);
929 void KMFilterListBox::slotRename()
931 if ( mIdxSelItem
< 0 ) {
932 kDebug(5006) << "Called while no filter is selected, ignoring.";
936 bool okPressed
= false;
937 KMFilter
*filter
= mFilterList
.at( mIdxSelItem
);
939 // enableControls should make sure this method is
940 // never called when no filter is selected.
943 // allow empty names - those will turn auto-naming on again
944 QValidator
*validator
= new QRegExpValidator( QRegExp( ".*" ), 0 );
945 QString newName
= KInputDialog::getText
947 i18n("Rename Filter"),
948 i18n("Rename filter \"%1\" to:\n(leave the field empty for automatic naming)",
949 filter
->pattern()->name() ) /*label*/,
950 filter
->pattern()->name() /* initial value */,
951 &okPressed
, topLevelWidget(), validator
955 if ( !okPressed
) return;
957 if ( newName
.isEmpty() ) {
958 // bait for slotUpdateFilterName to
959 // use automatic naming again.
960 filter
->pattern()->setName( "<>" );
961 filter
->setAutoNaming( true );
963 filter
->pattern()->setName( newName
);
964 filter
->setAutoNaming( false );
967 slotUpdateFilterName();
970 void KMFilterListBox::enableControls()
972 bool theFirst
= ( mIdxSelItem
== 0 );
973 bool theLast
= ( mIdxSelItem
>= (int)mFilterList
.count() - 1 );
974 bool aFilterIsSelected
= ( mIdxSelItem
>= 0 );
976 mBtnUp
->setEnabled( aFilterIsSelected
&& !theFirst
);
977 mBtnDown
->setEnabled( aFilterIsSelected
&& !theLast
);
978 mBtnCopy
->setEnabled( aFilterIsSelected
);
979 mBtnDelete
->setEnabled( aFilterIsSelected
);
980 mBtnRename
->setEnabled( aFilterIsSelected
);
982 if ( aFilterIsSelected
)
983 mListWidget
->scrollToItem( mListWidget
->currentItem() );
986 void KMFilterListBox::loadFilterList( bool createDummyFilter
)
991 // we don't want the insertion to
992 // cause flicker in the edit widgets.
997 mListWidget
->clear();
999 const KMFilterMgr
*manager
= 0;
1002 mShowLater
= kmkernel
->popFilterMgr()->showLaterMsgs();
1003 manager
= kmkernel
->popFilterMgr();
1007 manager
= kmkernel
->filterMgr();
1009 Q_ASSERT( manager
);
1011 QList
<KMFilter
*>::const_iterator it
;
1012 for ( it
= manager
->filters().constBegin() ;
1013 it
!= manager
->filters().constEnd();
1015 mFilterList
.append( new KMFilter( **it
) ); // deep copy
1016 mListWidget
->addItem( (*it
)->pattern()->name() );
1019 blockSignals(false);
1022 // create an empty filter when there's none, to avoid a completely
1023 // disabled dialog (usability tests indicated that the new-filter
1024 // button is too hard to find that way):
1025 if ( !mListWidget
->count() && createDummyFilter
)
1028 if ( mListWidget
->count() > 0 )
1029 mListWidget
->setCurrentRow( 0 );
1034 void KMFilterListBox::insertFilter( KMFilter
* aFilter
)
1036 // must be really a filter...
1039 // if mIdxSelItem < 0, QListBox::insertItem will append.
1040 mListWidget
->insertItem( mIdxSelItem
, aFilter
->pattern()->name() );
1041 if ( mIdxSelItem
< 0 ) {
1042 // none selected -> append
1043 mFilterList
.append( aFilter
);
1044 mListWidget
->setCurrentRow( mListWidget
->count() - 1 );
1046 // insert just before selected
1047 mFilterList
.insert( mIdxSelItem
, aFilter
);
1048 mListWidget
->setCurrentRow( mIdxSelItem
);
1053 void KMFilterListBox::appendFilter( KMFilter
* aFilter
)
1055 mFilterList
.append( aFilter
);
1056 mListWidget
->addItems( QStringList( aFilter
->pattern()->name() ) );
1059 void KMFilterListBox::swapNeighbouringFilters( int untouchedOne
, int movedOne
)
1061 // must be neighbours...
1062 assert( untouchedOne
- movedOne
== 1 || movedOne
- untouchedOne
== 1 );
1064 // untouchedOne is at idx. to move it down(up),
1065 // remove item at idx+(-)1 w/o deleting it.
1066 QListWidgetItem
*item
= mListWidget
->item( movedOne
);
1067 mListWidget
->takeItem( movedOne
);
1068 // now selected item is at idx(idx-1), so
1069 // insert the other item at idx, ie. above(below).
1070 mListWidget
->insertItem( untouchedOne
, item
);
1072 KMFilter
* filter
= mFilterList
.takeAt( movedOne
);
1073 mFilterList
.insert( untouchedOne
, filter
);
1075 mIdxSelItem
+= movedOne
- untouchedOne
;
1079 //=============================================================================
1081 // class KMFilterActionWidget
1083 //=============================================================================
1085 KMFilterActionWidget::KMFilterActionWidget( QWidget
*parent
, const char* name
)
1088 setObjectName( name
);
1092 mComboBox
= new KComboBox( this );
1093 mComboBox
->setEditable( false );
1094 assert( mComboBox
);
1095 mWidgetStack
= new QStackedWidget(this);
1096 assert( mWidgetStack
);
1100 QList
<KMFilterActionDesc
*> list
= kmkernel
->filterActionDict()->list();
1101 QList
<KMFilterActionDesc
*>::const_iterator it
;
1102 for ( i
=0, it
= list
.constBegin() ; it
!= list
.constEnd() ; ++it
, ++i
) {
1103 //create an instance:
1104 KMFilterAction
*a
= (*it
)->create();
1105 // append to the list of actions:
1106 mActionList
.append( a
);
1107 // add parameter widget to widget stack:
1108 mWidgetStack
->insertWidget( i
, a
->createParamWidget( mWidgetStack
) );
1109 // add (i18n-ized) name to combo box
1110 mComboBox
->addItem( (*it
)->label
);
1112 // widget for the case where no action is selected.
1113 mWidgetStack
->insertWidget( i
,new QLabel( i18n("Please select an action."), mWidgetStack
) );
1114 mWidgetStack
->setCurrentIndex(i
);
1115 mComboBox
->addItem( " " );
1116 mComboBox
->setCurrentIndex(i
);
1118 // don't show scroll bars.
1119 mComboBox
->setMaxCount( mComboBox
->count() );
1120 // layout management:
1121 // o the combo box is not to be made larger than it's sizeHint(),
1122 // the parameter widget should grow instead.
1123 // o the whole widget takes all space horizontally, but is fixed vertically.
1124 mComboBox
->adjustSize();
1125 mComboBox
->setSizePolicy( QSizePolicy( QSizePolicy::Fixed
, QSizePolicy::Fixed
) );
1126 setSizePolicy( QSizePolicy( QSizePolicy::Preferred
, QSizePolicy::Fixed
) );
1129 // redirect focus to the filter action combo box
1130 setFocusProxy( mComboBox
);
1132 // now connect the combo box and the widget stack
1133 connect( mComboBox
, SIGNAL(activated(int)),
1134 mWidgetStack
, SLOT(setCurrentIndex (int)) );
1137 KMFilterActionWidget::~KMFilterActionWidget()
1139 qDeleteAll( mActionList
);
1142 void KMFilterActionWidget::setAction( const KMFilterAction
* aAction
)
1145 int count
= mComboBox
->count() - 1 ; // last entry is the empty one
1146 QString label
= ( aAction
) ? aAction
->label() : QString() ;
1148 // find the index of typeOf(aAction) in mComboBox
1149 // and clear the other widgets on the way.
1150 for ( int i
= 0; i
< count
; i
++ )
1151 if ( aAction
&& mComboBox
->itemText(i
) == label
) {
1152 //...set the parameter widget to the settings
1154 aAction
->setParamWidgetValue( mWidgetStack
->widget(i
) );
1155 //...and show the correct entry of
1157 mComboBox
->setCurrentIndex(i
); // (mm) also raise the widget, but doesn't
1158 mWidgetStack
->setCurrentIndex(i
);
1160 } else // clear the parameter widget
1161 mActionList
.at(i
)->clearParamWidget( mWidgetStack
->widget(i
) );
1162 if ( found
) return;
1164 // not found, so set the empty widget
1165 mComboBox
->setCurrentIndex( count
); // last item
1166 mWidgetStack
->setCurrentIndex( count
) ;
1169 KMFilterAction
* KMFilterActionWidget::action() const
1171 // look up the action description via the label
1172 // returned by KComboBox::currentText()...
1173 KMFilterActionDesc
*desc
= kmkernel
->filterActionDict()->value( mComboBox
->currentText() );
1175 // ...create an instance...
1176 KMFilterAction
*fa
= desc
->create();
1178 // ...and apply the setting of the parameter widget.
1179 fa
->applyParamWidgetValue( mWidgetStack
->currentWidget() );
1187 //=============================================================================
1189 // class KMFilterActionWidgetLister (the filter action editor)
1191 //=============================================================================
1193 KMFilterActionWidgetLister::KMFilterActionWidgetLister( QWidget
*parent
, const char* name
)
1194 : KWidgetLister( 1, FILTER_MAX_ACTIONS
, parent
, name
)
1199 KMFilterActionWidgetLister::~KMFilterActionWidgetLister()
1203 void KMFilterActionWidgetLister::setActionList( QList
<KMFilterAction
*> *aList
)
1208 regenerateActionListFromWidgets();
1210 mActionList
= aList
;
1212 ((QWidget
*)parent())->setEnabled( true );
1214 if ( aList
->count() == 0 ) {
1219 int superfluousItems
= (int)mActionList
->count() - mMaxWidgets
;
1220 if ( superfluousItems
> 0 ) {
1221 kDebug(5006) <<"KMFilterActionWidgetLister: Clipping action list to"
1222 << mMaxWidgets
<< "items!";
1224 for ( ; superfluousItems
; superfluousItems
-- )
1225 mActionList
->removeLast();
1228 // set the right number of widgets
1229 setNumberOfShownWidgetsTo( mActionList
->count() );
1231 // load the actions into the widgets
1232 QList
<KMFilterAction
*>::const_iterator aIt
;
1233 QList
<QWidget
*>::ConstIterator wIt
= mWidgetList
.constBegin();
1234 for ( aIt
= mActionList
->constBegin();
1235 ( aIt
!= mActionList
->constEnd() && wIt
!= mWidgetList
.constEnd() );
1237 static_cast<KMFilterActionWidget
*>( *wIt
)->setAction( ( *aIt
) );
1240 void KMFilterActionWidgetLister::reset()
1243 regenerateActionListFromWidgets();
1247 ((QWidget
*)parent())->setEnabled( false );
1250 QWidget
* KMFilterActionWidgetLister::createWidget( QWidget
*parent
)
1252 return new KMFilterActionWidget(parent
);
1255 void KMFilterActionWidgetLister::clearWidget( QWidget
*aWidget
)
1258 ((KMFilterActionWidget
*)aWidget
)->setAction(0);
1261 void KMFilterActionWidgetLister::regenerateActionListFromWidgets()
1263 if ( !mActionList
) return;
1265 mActionList
->clear();
1267 foreach ( const QWidget
* w
, mWidgetList
) {
1268 KMFilterAction
*a
= static_cast<const KMFilterActionWidget
*>( w
)->action();
1270 mActionList
->append( a
);
1275 //=============================================================================
1277 // class KMPopFilterActionWidget
1279 //=============================================================================
1281 KMPopFilterActionWidget::KMPopFilterActionWidget( const QString
& title
, QWidget
*parent
, const char* name
)
1282 : QGroupBox( title
, parent
)
1284 setObjectName( name
);
1285 QVBoxLayout
*layout
= new QVBoxLayout( this );
1286 QButtonGroup
*bg
= new QButtonGroup( this );
1288 QRadioButton
*downBtn
= new QRadioButton( i18n("&Download mail"), this );
1289 QRadioButton
*laterBtn
= new QRadioButton( i18n("Download mail la&ter"), this );
1290 QRadioButton
*deleteBtn
= new QRadioButton( i18n("D&elete mail from server"), this );
1292 layout
->addWidget( downBtn
);
1293 layout
->addWidget( laterBtn
);
1294 layout
->addWidget( deleteBtn
);
1295 bg
->addButton( downBtn
);
1296 bg
->addButton( laterBtn
);
1297 bg
->addButton( deleteBtn
);
1299 mActionMap
.insert( Down
, downBtn
);
1300 mActionMap
.insert( Later
, laterBtn
);
1301 mActionMap
.insert( Delete
, deleteBtn
);
1303 mButtonMap
.insert( downBtn
, Down
);
1304 mButtonMap
.insert( laterBtn
, Later
);
1305 mButtonMap
.insert( deleteBtn
, Delete
);
1307 connect( bg
, SIGNAL(buttonClicked(QAbstractButton
*)),
1308 this, SLOT(slotActionClicked(QAbstractButton
*)) );
1311 void KMPopFilterActionWidget::setAction( KMPopFilterAction aAction
)
1313 if( aAction
== NoAction
)
1320 blockSignals( true );
1321 if(!mActionMap
[aAction
]->isChecked())
1323 mActionMap
[aAction
]->setChecked(true);
1325 blockSignals( false );
1330 KMPopFilterAction
KMPopFilterActionWidget::action()
1335 void KMPopFilterActionWidget::slotActionClicked( QAbstractButton
*btn
)
1337 emit
actionChanged( mButtonMap
[btn
] );
1338 setAction( mButtonMap
[btn
] );
1341 void KMPopFilterActionWidget::reset()
1344 mActionMap
[Down
]->setChecked( true );
1345 blockSignals(false);
1347 setEnabled( false );
1350 void KMFilterDlg::slotImportFilters()
1352 FilterImporterExporter
importer( this, bPopFilter
);
1353 QList
<KMFilter
*> filters
= importer
.importFilters();
1355 // FIXME message box how many were imported?
1356 if ( filters
.isEmpty() ) return;
1358 QList
<KMFilter
*>::ConstIterator it
;
1360 for ( it
= filters
.constBegin() ; it
!= filters
.constEnd() ; ++it
) {
1361 mFilterList
->appendFilter( *it
); // no need to deep copy, ownership passes to the list
1365 void KMFilterDlg::slotExportFilters()
1367 FilterImporterExporter
exporter( this, bPopFilter
);
1368 QList
<KMFilter
*> filters
= mFilterList
->filtersForSaving();
1369 exporter
.exportFilters( filters
);
1370 QList
<KMFilter
*>::ConstIterator it
;
1371 for ( it
= filters
.constBegin(); it
!= filters
.constEnd(); ++it
)
1375 #include "kmfilterdlg.moc"