00001
00002
00003
00004
00005
00006
00007
#include <config.h>
00008
#include "kmfilterdlg.h"
00009
00010
00011
#include "kmsearchpatternedit.h"
00012
#include "kmfiltermgr.h"
00013
00014
00015
#include <kmessagebox.h>
00016
#include <kdebug.h>
00017
#include <klocale.h>
00018
#include <kinputdialog.h>
00019
#include <kiconloader.h>
00020
#include <kapplication.h>
00021
#include <kwin.h>
00022
#include <kconfig.h>
00023
#include <kicondialog.h>
00024
00025
00026
#include <qlayout.h>
00027
#include <qlabel.h>
00028
#include <qcombobox.h>
00029
#include <qwidgetstack.h>
00030
#include <qtooltip.h>
00031
#include <qwhatsthis.h>
00032
#include <qcheckbox.h>
00033
#include <qpushbutton.h>
00034
#include <qhbox.h>
00035
00036
00037
#include <assert.h>
00038
00039
00040
00041
const char * _wt_filterlist =
00042 I18N_NOOP(
"<qt><p>This is the list of defined filters. "
00043
"They are processed top-to-bottom.</p>"
00044
"<p>Click on any filter to edit it "
00045
"using the controls in the right-hand half "
00046
"of the dialog.</p></qt>" );
00047
const char * _wt_filterlist_new =
00048 I18N_NOOP(
"<qt><p>Click this button to create a new filter.</p>"
00049
"<p>The filter will be inserted just before the currently-"
00050
"selected one, but you can always change that "
00051
"later on.</p>"
00052
"<p>If you have clicked this button accidentally, you can undo this "
00053
"by clicking on the <em>Delete</em> button.</p></qt>" );
00054
const char * _wt_filterlist_copy =
00055 I18N_NOOP(
"<qt><p>Click this button to copy a filter.</p>"
00056
"<p>If you have clicked this button accidentally, you can undo this "
00057
"by clicking on the <em>Delete</em> button.</p></qt>" );
00058
const char * _wt_filterlist_delete =
00059 I18N_NOOP(
"<qt><p>Click this button to <em>delete</em> the currently-"
00060
"selected filter from the list above.</p>"
00061
"<p>There is no way to get the filter back once "
00062
"it is deleted, but you can always leave the "
00063
"dialog by clicking <em>Cancel</em> to discard the "
00064
"changes made.</p></qt>" );
00065
const char * _wt_filterlist_up =
00066 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
00067
"selected filter <em>up</em> one in the list above.</p>"
00068
"<p>This is useful since the order of the filters in the list "
00069
"determines the order in which they are tried on messages: "
00070
"The topmost filter gets tried first.</p>"
00071
"<p>If you have clicked this button accidentally, you can undo this "
00072
"by clicking on the <em>Down</em> button.</p></qt>" );
00073
const char * _wt_filterlist_down =
00074 I18N_NOOP(
"<qt><p>Click this button to move the currently-"
00075
"selected filter <em>down</em> one in the list above.</p>"
00076
"<p>This is useful since the order of the filters in the list "
00077
"determines the order in which they are tried on messages: "
00078
"The topmost filter gets tried first.</p>"
00079
"<p>If you have clicked this button accidentally, you can undo this "
00080
"by clicking on the <em>Up</em> button.</p></qt>" );
00081
const char * _wt_filterlist_rename =
00082 I18N_NOOP(
"<qt><p>Click this button to rename the currently-selected filter.</p>"
00083
"<p>Filters are named automatically, as long as they start with "
00084
"\"<<\".</p>"
00085
"<p>If you have renamed a filter accidentally and want automatic "
00086
"naming back, click this button and select <em>Clear</em> followed "
00087
"by <em>OK</em> in the appearing dialog.</p></qt>" );
00088
const char * _wt_filterdlg_showLater =
00089 I18N_NOOP(
"<qt><p>Check this button to force the confirmation dialog to be "
00090
"displayed.</p><p>This is useful if you have defined a ruleset that tags "
00091
"messages to be downloaded later. Without the possibility to force "
00092
"the dialog popup, these messages could never be downloaded if no "
00093
"other large messages were waiting on the server, or if you wanted to "
00094
"change the ruleset to tag the messages differently.</p></qt>" );
00095
00096
00097
const char * KMFilterDlgHelpAnchor =
"filters-id" ;
00098
const char * KMPopFilterDlgHelpAnchor =
"popfilters-id" ;
00099
00100
00101
00102
00103
00104
00105
00106 KMFilterDlg::KMFilterDlg(
QWidget* parent,
const char* name,
bool popFilter)
00107 : KDialogBase( parent, name, FALSE ,
00108 (popFilter)? i18n("POP3 Filter Rules"): i18n("Filter Rules") ,
00109 Help|Ok|Apply|Cancel ,
00110 Ok , FALSE ),
00111 bPopFilter(popFilter)
00112 {
00113 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
00114 setHelp( (bPopFilter)? KMPopFilterDlgHelpAnchor: KMFilterDlgHelpAnchor );
00115
00116
QWidget *w =
new QWidget(
this);
00117 setMainWidget(w);
00118
QHBoxLayout *hbl =
new QHBoxLayout( w, 0, spacingHint(),
"kmfd_hbl" );
00119
00120
mFilterList =
new KMFilterListBox( i18n(
"Available Filters"), w, 0, bPopFilter);
00121 hbl->addWidget(
mFilterList, 1 );
00122
00123
QVBoxLayout *vbl =
new QVBoxLayout( hbl, spacingHint(),
"kmfd_vbl" );
00124 hbl->setStretchFactor( vbl, 2 );
00125
00126
mPatternEdit =
new KMSearchPatternEdit( i18n(
"Filter Criteria"), w ,
"spe", bPopFilter);
00127 vbl->addWidget(
mPatternEdit, 0, Qt::AlignTop );
00128
00129
if(bPopFilter){
00130
mActionGroup =
new KMPopFilterActionWidget( i18n(
"Filter Action"), w );
00131 vbl->addWidget(
mActionGroup, 0, Qt::AlignTop );
00132
00133 mGlobalsBox =
new QVGroupBox(i18n(
"Global Options"), w);
00134 mShowLaterBtn =
new QCheckBox(i18n(
"Always &show matched 'Download Later' messages in confirmation dialog"), mGlobalsBox);
00135 QWhatsThis::add( mShowLaterBtn, i18n(_wt_filterdlg_showLater) );
00136 vbl->addWidget( mGlobalsBox, 0, Qt::AlignTop );
00137 }
00138
else {
00139
QGroupBox *agb =
new QGroupBox( 1 , Vertical, i18n(
"Filter Actions"), w );
00140
mActionLister =
new KMFilterActionWidgetLister( agb );
00141 vbl->addWidget( agb, 0, Qt::AlignTop );
00142
00143 mAdvOptsGroup =
new QGroupBox ( 1 , Vertical,
00144 i18n(
"Advanced Options"), w);
00145 {
00146 QWidget *adv_w =
new QWidget( mAdvOptsGroup );
00147
QGridLayout *gl =
new QGridLayout( adv_w, 4 , 4 ,
00148 0 , spacingHint() );
00149 gl->setColStretch( 0, 1 );
00150
QLabel *l =
new QLabel( i18n(
"Apply this filter"), adv_w );
00151 gl->addWidget( l, 0, 0, AlignLeft );
00152
mApplyOnIn =
new QCheckBox( i18n(
"to &incoming messages"), adv_w );
00153 gl->addWidget(
mApplyOnIn, 0, 1 );
00154
mApplyOnOut =
new QCheckBox( i18n(
"to &sent messages"), adv_w );
00155 gl->addWidget(
mApplyOnOut, 0, 2 );
00156
mApplyOnCtrlJ =
new QCheckBox( i18n(
"on manual &filtering"), adv_w );
00157 gl->addWidget(
mApplyOnCtrlJ, 0, 3 );
00158 mStopProcessingHere =
new QCheckBox( i18n(
"If this filter &matches, stop processing here"), adv_w );
00159 gl->addMultiCellWidget( mStopProcessingHere,
00160 1, 1,
00161 0, 3 );
00162 mConfigureShortcut =
new QCheckBox( i18n(
"Add this filter to the Apply Filter menu"), adv_w );
00163 gl->addMultiCellWidget( mConfigureShortcut, 2, 2, 0, 3 );
00164
00165
QHBox *hbox =
new QHBox( adv_w );
00166 mFilterActionLabel =
new QLabel( i18n(
"Icon for this filter:" ),
00167 hbox );
00168 mFilterActionLabel->setEnabled(
false );
00169
00170 mFilterActionIconButton =
new KIconButton( hbox );
00171 mFilterActionLabel->setBuddy( mFilterActionIconButton );
00172 mFilterActionIconButton->setIconType( KIcon::NoGroup, KIcon::Any,
true );
00173 mFilterActionIconButton->setIconSize( 16 );
00174 mFilterActionIconButton->setIcon(
"gear" );
00175 mFilterActionIconButton->setEnabled(
false );
00176
00177 gl->addMultiCellWidget( hbox, 3, 3, 0, 3 );
00178 }
00179 vbl->addWidget( mAdvOptsGroup, 0, Qt::AlignTop );
00180 }
00181
00182 vbl->addStretch( 1 );
00183
00184
00185 connect(
mFilterList, SIGNAL(filterSelected(KMFilter*)),
00186
this, SLOT(
slotFilterSelected(KMFilter*)) );
00187
00188
if (bPopFilter){
00189
00190 connect( mShowLaterBtn, SIGNAL(toggled(
bool)),
00191
mFilterList, SLOT(slotShowLaterToggled(
bool)));
00192
00193
00194 connect(
mActionGroup, SIGNAL(actionChanged(
const KMPopFilterAction)),
00195
this, SLOT(
slotActionChanged(
const KMPopFilterAction)) );
00196 }
else {
00197
00198
00199 connect(
mApplyOnIn, SIGNAL(clicked()),
00200
this, SLOT(slotApplicabilityChanged()) );
00201 connect(
mApplyOnOut, SIGNAL(clicked()),
00202
this, SLOT(slotApplicabilityChanged()) );
00203 connect(
mApplyOnCtrlJ, SIGNAL(clicked()),
00204
this, SLOT(slotApplicabilityChanged()) );
00205
00206
00207
00208 connect( mStopProcessingHere, SIGNAL(toggled(
bool)),
00209
this, SLOT(slotStopProcessingButtonToggled(
bool)) );
00210
00211 connect( mConfigureShortcut, SIGNAL(toggled(
bool)),
00212
this, SLOT(slotConfigureShortcutButtonToggled(
bool)) );
00213
00214 connect( mFilterActionIconButton, SIGNAL( iconChanged(
QString ) ),
00215
this, SLOT( slotFilterActionIconChanged(
QString ) ) );
00216 }
00217
00218
00219 connect(
mFilterList, SIGNAL(resetWidgets()),
00220
this, SLOT(slotReset()) );
00221
00222 connect(
mFilterList, SIGNAL( applyWidgets() ),
00223
this, SLOT( slotUpdateFilter() ) );
00224
00225
00226 connect(
mPatternEdit, SIGNAL(maybeNameChanged()),
00227
mFilterList, SLOT(slotUpdateFilterName()) );
00228
00229
00230 connect(
this, SIGNAL(applyClicked()),
00231
mFilterList, SLOT(slotApplyFilterChanges()) );
00232
00233
00234 connect(
this, SIGNAL(okClicked()),
00235
mFilterList, SLOT(slotApplyFilterChanges()) );
00236
00237
00238 connect(
this, SIGNAL(okClicked()),
00239
this, SLOT(slotSaveSize()) );
00240
00241
00242 connect(
this, SIGNAL(finished()),
00243
this, SLOT(
slotFinished()) );
00244
00245 KConfigGroup geometry( KMKernel::config(),
"Geometry");
00246
const char * configKey
00247 = bPopFilter ?
"popFilterDialogSize" :
"filterDialogSize";
00248
if ( geometry.hasKey( configKey ) )
00249 resize( geometry.readSizeEntry( configKey ) );
00250
else
00251 adjustSize();
00252
00253
00254
mFilterList->
loadFilterList();
00255 }
00256
00257 void KMFilterDlg::slotFinished() {
00258 delayedDestruct();
00259 }
00260
00261
void KMFilterDlg::slotSaveSize() {
00262 KConfigGroup geometry( KMKernel::config(),
"Geometry" );
00263 geometry.writeEntry( bPopFilter ?
"popFilterDialogSize" :
"filterDialogSize", size() );
00264 }
00265
00267 void KMFilterDlg::slotActionChanged(
const KMPopFilterAction aAction)
00268 {
00269 mFilter->setAction(aAction);
00270 }
00271
00272 void KMFilterDlg::slotFilterSelected( KMFilter* aFilter )
00273 {
00274 assert( aFilter );
00275
00276
if (bPopFilter){
00277
mActionGroup->setAction( aFilter->action() );
00278 mGlobalsBox->setEnabled(
true);
00279 mShowLaterBtn->setChecked(
mFilterList->
showLaterMsgs());
00280 }
else {
00281
mActionLister->setActionList( aFilter->actions() );
00282
00283 mAdvOptsGroup->setEnabled(
true );
00284 }
00285
00286
mPatternEdit->
setSearchPattern( aFilter->pattern() );
00287 mFilter = aFilter;
00288
00289
if (!bPopFilter) {
00290 kdDebug(5006) <<
"apply on inbound == "
00291 << aFilter->applyOnInbound() << endl;
00292 kdDebug(5006) <<
"apply on outbound == "
00293 << aFilter->applyOnOutbound() << endl;
00294 kdDebug(5006) <<
"apply on explicit == "
00295 << aFilter->applyOnExplicit() << endl;
00296
00297
00298
00299
00300
const bool applyOnIn = aFilter->applyOnInbound();
00301
const bool applyOnOut = aFilter->applyOnOutbound();
00302
const bool applyOnExplicit = aFilter->applyOnExplicit();
00303
const bool stopHere = aFilter->stopProcessingHere();
00304
const bool configureShortcut = aFilter->configureShortcut();
00305
const QString icon = aFilter->icon();
00306
00307
mApplyOnIn->setChecked( applyOnIn );
00308
mApplyOnOut->setChecked( applyOnOut );
00309
mApplyOnCtrlJ->setChecked( applyOnExplicit );
00310 mStopProcessingHere->setChecked( stopHere );
00311 mConfigureShortcut->setChecked( configureShortcut );
00312 mFilterActionIconButton->setIcon( icon );
00313 }
00314 }
00315
00316
void KMFilterDlg::slotReset()
00317 {
00318 mFilter = 0;
00319 mPatternEdit->
reset();
00320
00321
if(bPopFilter) {
00322 mActionGroup->reset();
00323 mGlobalsBox->setEnabled(
false );
00324 }
else {
00325
mActionLister->reset();
00326 mAdvOptsGroup->setEnabled(
false );
00327 }
00328 }
00329
00330
void KMFilterDlg::slotUpdateFilter()
00331 {
00332
mPatternEdit->
updateSearchPattern();
00333
if ( !bPopFilter ) {
00334
mActionLister->updateActionList();
00335 }
00336 }
00337
00338
void KMFilterDlg::slotApplicabilityChanged()
00339 {
00340
if ( !mFilter )
00341
return;
00342
00343 mFilter->setApplyOnInbound(
mApplyOnIn->isChecked() );
00344 mFilter->setApplyOnOutbound(
mApplyOnOut->isChecked() );
00345 mFilter->setApplyOnExplicit(
mApplyOnCtrlJ->isChecked() );
00346 kdDebug(5006) <<
"KMFilterDlg: setting filter to be applied at "
00347 << ( mFilter->applyOnInbound() ?
"incoming " :
"" )
00348 << ( mFilter->applyOnOutbound() ?
"outgoing " :
"" )
00349 << ( mFilter->applyOnExplicit() ?
"explicit CTRL-J" :
"" )
00350 << endl;
00351 }
00352
00353
void KMFilterDlg::slotStopProcessingButtonToggled(
bool aChecked )
00354 {
00355
if ( !mFilter )
00356
return;
00357
00358 mFilter->setStopProcessingHere( aChecked );
00359 }
00360
00361
void KMFilterDlg::slotConfigureShortcutButtonToggled(
bool aChecked )
00362 {
00363
if ( !mFilter )
00364
return;
00365
00366 mFilter->setConfigureShortcut( aChecked );
00367 mFilterActionIconButton->setEnabled( aChecked );
00368 mFilterActionLabel->setEnabled( aChecked );
00369 }
00370
00371
void KMFilterDlg::slotFilterActionIconChanged(
QString icon )
00372 {
00373
if ( !mFilter )
00374
return;
00375
00376 mFilter->setIcon( icon );
00377 }
00378
00379
00380
00381
00382
00383
00384
00385 KMFilterListBox::KMFilterListBox(
const QString & title,
QWidget *parent,
const char* name,
bool popFilter )
00386 :
QGroupBox( 1, Horizontal, title, parent, name ),
00387 bPopFilter(popFilter)
00388 {
00389
mFilterList.setAutoDelete(TRUE);
00390
mIdxSelItem = -1;
00391
00392
00393
mListBox =
new QListBox(
this);
00394
mListBox->setMinimumWidth(150);
00395 QWhatsThis::add(
mListBox, i18n(_wt_filterlist) );
00396
00397
00398
QHBox *hb =
new QHBox(
this);
00399 hb->setSpacing(4);
00400
mBtnUp =
new QPushButton( QString::null, hb );
00401
mBtnUp->setAutoRepeat(
true );
00402
mBtnUp->setPixmap( BarIcon(
"up", KIcon::SizeSmall ) );
00403
mBtnUp->setMinimumSize(
mBtnUp->sizeHint() * 1.2 );
00404
mBtnDown =
new QPushButton( QString::null, hb );
00405
mBtnDown->setAutoRepeat(
true );
00406
mBtnDown->setPixmap( BarIcon(
"down", KIcon::SizeSmall ) );
00407
mBtnDown->setMinimumSize(
mBtnDown->sizeHint() * 1.2 );
00408 QToolTip::add(
mBtnUp, i18n(
"Up") );
00409 QToolTip::add(
mBtnDown, i18n(
"Down") );
00410 QWhatsThis::add(
mBtnUp, i18n(_wt_filterlist_up) );
00411 QWhatsThis::add(
mBtnDown, i18n(_wt_filterlist_down) );
00412
00413
00414 hb =
new QHBox(
this);
00415 hb->setSpacing(4);
00416
mBtnNew =
new QPushButton( QString::null, hb );
00417
mBtnNew->setPixmap( BarIcon(
"filenew", KIcon::SizeSmall ) );
00418
mBtnNew->setMinimumSize(
mBtnNew->sizeHint() * 1.2 );
00419
mBtnCopy =
new QPushButton( QString::null, hb );
00420
mBtnCopy->setPixmap( BarIcon(
"editcopy", KIcon::SizeSmall ) );
00421
mBtnCopy->setMinimumSize(
mBtnCopy->sizeHint() * 1.2 );
00422
mBtnDelete =
new QPushButton( QString::null, hb );
00423
mBtnDelete->setPixmap( BarIcon(
"editdelete", KIcon::SizeSmall ) );
00424
mBtnDelete->setMinimumSize(
mBtnDelete->sizeHint() * 1.2 );
00425
mBtnRename =
new QPushButton( i18n(
"Rename..."), hb );
00426 QToolTip::add(
mBtnNew, i18n(
"New") );
00427 QToolTip::add(
mBtnCopy, i18n(
"Copy") );
00428 QToolTip::add(
mBtnDelete, i18n(
"Delete"));
00429 QWhatsThis::add(
mBtnNew, i18n(_wt_filterlist_new) );
00430 QWhatsThis::add(
mBtnCopy, i18n(_wt_filterlist_copy) );
00431 QWhatsThis::add(
mBtnDelete, i18n(_wt_filterlist_delete) );
00432 QWhatsThis::add(
mBtnRename, i18n(_wt_filterlist_rename) );
00433
00434
00435
00436 connect(
mListBox, SIGNAL(highlighted(
int)),
00437
this, SLOT(
slotSelected(
int)) );
00438 connect(
mListBox, SIGNAL( doubleClicked (
QListBoxItem * )),
00439
this, SLOT(
slotRename()) );
00440 connect(
mBtnUp, SIGNAL(clicked()),
00441
this, SLOT(
slotUp()) );
00442 connect(
mBtnDown, SIGNAL(clicked()),
00443
this, SLOT(
slotDown()) );
00444 connect(
mBtnNew, SIGNAL(clicked()),
00445
this, SLOT(
slotNew()) );
00446 connect(
mBtnCopy, SIGNAL(clicked()),
00447
this, SLOT(
slotCopy()) );
00448 connect(
mBtnDelete, SIGNAL(clicked()),
00449
this, SLOT(
slotDelete()) );
00450 connect(
mBtnRename, SIGNAL(clicked()),
00451
this, SLOT(
slotRename()) );
00452
00453
00454
00455 enableControls();
00456 }
00457
00458
00459 void KMFilterListBox::createFilter(
const QCString & field,
00460
const QString & value )
00461 {
00462
KMSearchRule *newRule = KMSearchRule::createInstance( field, KMSearchRule::FuncContains, value );
00463
00464 KMFilter *newFilter =
new KMFilter(0, bPopFilter);
00465 newFilter->pattern()->append( newRule );
00466 newFilter->pattern()->setName(
QString(
"<%1>:%2").arg( field ).arg( value) );
00467
00468
KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[
"transfer"];
00469
if ( desc )
00470 newFilter->actions()->append( desc->
create() );
00471
00472 insertFilter( newFilter );
00473 enableControls();
00474 }
00475
00476 bool KMFilterListBox::showLaterMsgs()
00477 {
00478
return mShowLater;
00479 }
00480
00481 void KMFilterListBox::slotUpdateFilterName()
00482 {
00483
KMSearchPattern *p =
mFilterList.at(
mIdxSelItem)->pattern();
00484
if ( !p )
return;
00485
00486
QString shouldBeName = p->
name();
00487
QString displayedName =
mListBox->text(
mIdxSelItem );
00488
00489
if ( shouldBeName.stripWhiteSpace().isEmpty() || shouldBeName[0] ==
'<' ) {
00490
00491
if ( p->first() && !p->first()->field().stripWhiteSpace().isEmpty() )
00492 shouldBeName =
QString(
"<%1>: %2" ).arg( p->first()->field() ).arg( p->first()->contents() );
00493
else
00494 shouldBeName =
"<" + i18n(
"unnamed") +
">";
00495 p->
setName( shouldBeName );
00496 }
00497
00498
if ( displayedName == shouldBeName )
return;
00499
00500
mListBox->blockSignals(TRUE);
00501
mListBox->changeItem( shouldBeName,
mIdxSelItem );
00502
mListBox->blockSignals(FALSE);
00503 }
00504
00505 void KMFilterListBox::slotShowLaterToggled(
bool aOn)
00506 {
00507 mShowLater = aOn;
00508 }
00509
00510 void KMFilterListBox::slotApplyFilterChanges()
00511 {
00512
int oIdxSelItem =
mIdxSelItem;
00513
00514
mListBox->selectAll( FALSE );
00515
00516
00517 emit
resetWidgets();
00518 mIdxSelItem = -1;
00519 enableControls();
00520
00521
00522
00523
00524 KMFilterMgr *fm;
00525
if (bPopFilter)
00526 fm = kmkernel->popFilterMgr();
00527
else
00528 fm = kmkernel->filterMgr();
00529
00530
00531 fm->beginUpdate();
00532 fm->clear();
00533
00534
QStringList emptyFilters;
00535
QPtrListIterator<KMFilter> it(
mFilterList );
00536
for ( it.toFirst() ; it.current() ; ++it ) {
00537 KMFilter *f =
new KMFilter( **it );
00538 f->purify();
00539
if ( !f->isEmpty() )
00540
00541 fm->append( f );
00542
else {
00543
00544 emptyFilters << f->name();
00545
delete f;
00546 }
00547 }
00548
if (bPopFilter)
00549 fm->setShowLaterMsgs(mShowLater);
00550
00551
00552 fm->endUpdate();
00553 fm->writeConfig();
00554
00555
00556
if ( !emptyFilters.empty() ) {
00557
QString msg = i18n(
"The following filters have not been saved because they "
00558
"were invalid (e.g. containing no actions or no search "
00559
"rules).");
00560 KMessageBox::informationList( 0, msg, emptyFilters, QString::null,
00561
"ShowInvalidFilterWarning" );
00562 }
00563
00564
if ( oIdxSelItem >= 0 ) {
00565 mIdxSelItem = oIdxSelItem;
00566
mListBox->setSelected( oIdxSelItem, TRUE);
00567
slotSelected(
mListBox->currentItem() );
00568 }
00569 }
00570
00571 void KMFilterListBox::slotSelected(
int aIdx )
00572 {
00573
mIdxSelItem = aIdx;
00574
00575 KMFilter *f =
mFilterList.at(aIdx);
00576
if ( f )
00577 emit
filterSelected( f );
00578
else
00579 emit
resetWidgets();
00580 enableControls();
00581 }
00582
00583 void KMFilterListBox::slotNew()
00584 {
00585
00586 insertFilter(
new KMFilter(0, bPopFilter) );
00587 enableControls();
00588 }
00589
00590 void KMFilterListBox::slotCopy()
00591 {
00592
if (
mIdxSelItem < 0 ) {
00593 kdDebug(5006) <<
"KMFilterListBox::slotCopy called while no filter is selected, ignoring." << endl;
00594
return;
00595 }
00596
00597
00598 emit
applyWidgets();
00599
00600 KMFilter *filter =
mFilterList.at(
mIdxSelItem );
00601
00602
00603
00604 assert( filter );
00605
00606
00607 insertFilter(
new KMFilter( *filter ) );
00608 enableControls();
00609 }
00610
00611 void KMFilterListBox::slotDelete()
00612 {
00613
if (
mIdxSelItem < 0 ) {
00614 kdDebug(5006) <<
"KMFilterListBox::slotDelete called while no filter is selected, ignoring." << endl;
00615
return;
00616 }
00617
00618
int oIdxSelItem =
mIdxSelItem;
00619 mIdxSelItem = -1;
00620
00621
mListBox->selectAll(FALSE);
00622
00623
00624 emit
resetWidgets();
00625
00626
00627
mFilterList.remove( oIdxSelItem );
00628
00629
mListBox->removeItem( oIdxSelItem );
00630
00631
int count = (
int)
mListBox->count();
00632
00633
if ( count > oIdxSelItem )
00634
00635
mListBox->setSelected( oIdxSelItem, TRUE );
00636
else if ( (
int)
mListBox->count() )
00637
00638
00639
mListBox->setSelected( count - 1, TRUE );
00640
00641
00642 enableControls();
00643 }
00644
00645 void KMFilterListBox::slotUp()
00646 {
00647
if (
mIdxSelItem < 0 ) {
00648 kdDebug(5006) <<
"KMFilterListBox::slotUp called while no filter is selected, ignoring." << endl;
00649
return;
00650 }
00651
if (
mIdxSelItem == 0 ) {
00652 kdDebug(5006) <<
"KMFilterListBox::slotUp called while the _topmost_ filter is selected, ignoring." << endl;
00653
return;
00654 }
00655
00656 swapNeighbouringFilters(
mIdxSelItem,
mIdxSelItem - 1 );
00657 enableControls();
00658 }
00659
00660 void KMFilterListBox::slotDown()
00661 {
00662
if (
mIdxSelItem < 0 ) {
00663 kdDebug(5006) <<
"KMFilterListBox::slotDown called while no filter is selected, ignoring." << endl;
00664
return;
00665 }
00666
if (
mIdxSelItem == (
int)
mListBox->count() - 1 ) {
00667 kdDebug(5006) <<
"KMFilterListBox::slotDown called while the _last_ filter is selected, ignoring." << endl;
00668
return;
00669 }
00670
00671 swapNeighbouringFilters(
mIdxSelItem,
mIdxSelItem + 1);
00672 enableControls();
00673 }
00674
00675 void KMFilterListBox::slotRename()
00676 {
00677
if (
mIdxSelItem < 0 ) {
00678 kdDebug(5006) <<
"KMFilterListBox::slotRename called while no filter is selected, ignoring." << endl;
00679
return;
00680 }
00681
00682
bool okPressed = FALSE;
00683 KMFilter *filter =
mFilterList.at(
mIdxSelItem );
00684
00685
00686
00687 assert( filter );
00688
00689
QString newName = KInputDialog::getText
00690 (
00691 i18n(
"Rename Filter"),
00692 i18n(
"Rename filter \"%1\" to:").arg( filter->pattern()->name() ) ,
00693 filter->pattern()->name() ,
00694 &okPressed, topLevelWidget()
00695 );
00696
00697
if ( !okPressed )
return;
00698
00699
if ( newName.isEmpty() )
00700
00701
00702 filter->pattern()->setName(
"<>" );
00703
else
00704 filter->pattern()->setName( newName );
00705
00706
slotUpdateFilterName();
00707 }
00708
00709
void KMFilterListBox::enableControls()
00710 {
00711
bool theFirst = ( mIdxSelItem == 0 );
00712
bool theLast = ( mIdxSelItem >= (
int)mFilterList.count() - 1 );
00713
bool aFilterIsSelected = ( mIdxSelItem >= 0 );
00714
00715 mBtnUp->setEnabled( aFilterIsSelected && !theFirst );
00716 mBtnDown->setEnabled( aFilterIsSelected && !theLast );
00717 mBtnCopy->setEnabled( aFilterIsSelected );
00718 mBtnDelete->setEnabled( aFilterIsSelected );
00719 mBtnRename->setEnabled( aFilterIsSelected );
00720
00721
if ( aFilterIsSelected )
00722 mListBox->ensureCurrentVisible();
00723 }
00724
00725 void KMFilterListBox::loadFilterList()
00726 {
00727 assert(
mListBox);
00728 setEnabled(FALSE);
00729
00730
00731 blockSignals(TRUE);
00732
00733
00734
mFilterList.clear();
00735
mListBox->clear();
00736
00737
QPtrList<KMFilter> *manager;
00738
if(bPopFilter)
00739 {
00740 mShowLater = kmkernel->popFilterMgr()->showLaterMsgs();
00741 manager = kmkernel->popFilterMgr();
00742 }
00743
else
00744 {
00745 manager = kmkernel->filterMgr();
00746 }
00747
00748
QPtrListIterator<KMFilter> it( *manager );
00749
for ( it.toFirst() ; it.current() ; ++it ) {
00750
mFilterList.append(
new KMFilter( **it ) );
00751
mListBox->insertItem( (*it)->pattern()->name() );
00752 }
00753
00754 blockSignals(FALSE);
00755 setEnabled(TRUE);
00756
00757
00758
00759
00760
if ( !
mListBox->count() )
00761
slotNew();
00762
00763 assert(
mListBox->count() > 0 );
00764
mListBox->setSelected( 0,
true );
00765
00766 enableControls();
00767 }
00768
00769
void KMFilterListBox::insertFilter( KMFilter* aFilter )
00770 {
00771
00772 assert( aFilter );
00773
00774
00775 mListBox->insertItem( aFilter->pattern()->name(), mIdxSelItem );
00776
if ( mIdxSelItem < 0 ) {
00777
00778 mFilterList.append( aFilter );
00779 mListBox->setSelected( mListBox->count() - 1, TRUE );
00780
00781 }
else {
00782
00783
mFilterList.insert( mIdxSelItem, aFilter );
00784
mListBox->setSelected( mIdxSelItem, TRUE );
00785
00786 }
00787
00788 }
00789
00790
void KMFilterListBox::swapNeighbouringFilters(
int untouchedOne,
int movedOne )
00791 {
00792
00793 assert( untouchedOne - movedOne == 1 || movedOne - untouchedOne == 1 );
00794
00795
00796
00797
QListBoxItem *item =
mListBox->item( movedOne );
00798
mListBox->takeItem( item );
00799
00800
00801
mListBox->insertItem( item, untouchedOne );
00802
00803 KMFilter* filter =
mFilterList.take( movedOne );
00804
mFilterList.insert( untouchedOne, filter );
00805
00806
mIdxSelItem += movedOne - untouchedOne;
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816 KMFilterActionWidget::KMFilterActionWidget(
QWidget *parent,
const char* name )
00817 :
QHBox( parent, name )
00818 {
00819
int i;
00820 mActionList.setAutoDelete(TRUE);
00821
00822 mComboBox =
new QComboBox( FALSE,
this );
00823 assert( mComboBox );
00824 mWidgetStack =
new QWidgetStack(
this);
00825 assert( mWidgetStack );
00826
00827 setSpacing( 4 );
00828
00829
QPtrListIterator<KMFilterActionDesc> it ( kmkernel->filterActionDict()->list() );
00830
for ( i=0, it.toFirst() ; it.current() ; ++it, ++i ) {
00831
00832
KMFilterAction *a = (*it)->create();
00833
00834 mActionList.append( a );
00835
00836 mWidgetStack->addWidget( a->
createParamWidget( mWidgetStack ), i );
00837
00838 mComboBox->insertItem( (*it)->label );
00839 }
00840
00841 mWidgetStack->addWidget(
new QLabel( i18n(
"Please select an action."), mWidgetStack ), i );
00842 mWidgetStack->raiseWidget(i);
00843 mComboBox->insertItem(
" " );
00844 mComboBox->setCurrentItem(i);
00845
00846
00847 mComboBox->setSizeLimit( mComboBox->count() );
00848
00849
00850
00851
00852 mComboBox->adjustSize();
00853 mComboBox->setSizePolicy(
QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
00854 setSizePolicy(
QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
00855 updateGeometry();
00856
00857
00858 setFocusProxy( mComboBox );
00859
00860
00861 connect( mComboBox, SIGNAL(activated(
int)),
00862 mWidgetStack, SLOT(raiseWidget(
int)) );
00863 }
00864
00865 void KMFilterActionWidget::setAction(
const KMFilterAction* aAction )
00866 {
00867
int i=0;
00868
bool found = FALSE;
00869
int count = mComboBox->count() - 1 ;
00870
QString label = ( aAction ) ? aAction->
label() : QString::null ;
00871
00872
00873
00874
for ( ; i < count ; i++ )
00875
if ( aAction && mComboBox->text(i) == label ) {
00876
00877
00878 aAction->
setParamWidgetValue( mWidgetStack->widget(i) );
00879
00880
00881 mComboBox->setCurrentItem(i);
00882 mWidgetStack->raiseWidget(i);
00883 found = TRUE;
00884 }
else
00885 mActionList.at(i)->clearParamWidget( mWidgetStack->widget(i) );
00886
if ( found )
return;
00887
00888
00889 mComboBox->setCurrentItem( count );
00890 mWidgetStack->raiseWidget( count) ;
00891 }
00892
00893 KMFilterAction *
KMFilterActionWidget::action()
00894 {
00895
00896
00897
KMFilterActionDesc *desc = (*kmkernel->filterActionDict())[ mComboBox->currentText() ];
00898
if ( desc ) {
00899
00900
KMFilterAction *fa = desc->
create();
00901
if ( fa ) {
00902
00903 fa->
applyParamWidgetValue( mWidgetStack->visibleWidget() );
00904
return fa;
00905 }
00906 }
00907
00908
return 0;
00909 }
00910
00911
00912
00913
00914
00915
00916
00917 KMFilterActionWidgetLister::KMFilterActionWidgetLister(
QWidget *parent,
const char* name )
00918 : KWidgetLister( 1, FILTER_MAX_ACTIONS, parent, name )
00919 {
00920 mActionList = 0;
00921 }
00922
00923 KMFilterActionWidgetLister::~KMFilterActionWidgetLister()
00924 {
00925 }
00926
00927
void KMFilterActionWidgetLister::setActionList(
QPtrList<KMFilterAction> *aList )
00928 {
00929 assert ( aList );
00930
00931
if ( mActionList )
00932 regenerateActionListFromWidgets();
00933
00934 mActionList = aList;
00935
00936 ((
QWidget*)parent())->setEnabled( TRUE );
00937
00938
if ( aList->count() == 0 ) {
00939 slotClear();
00940
return;
00941 }
00942
00943
int superfluousItems = (
int)mActionList->count() - mMaxWidgets ;
00944
if ( superfluousItems > 0 ) {
00945 kdDebug(5006) <<
"KMFilterActionWidgetLister: Clipping action list to "
00946 << mMaxWidgets <<
" items!" << endl;
00947
00948
for ( ; superfluousItems ; superfluousItems-- )
00949 mActionList->removeLast();
00950 }
00951
00952
00953 setNumberOfShownWidgetsTo( mActionList->count() );
00954
00955
00956
QPtrListIterator<KMFilterAction> aIt( *mActionList );
00957
QPtrListIterator<QWidget> wIt( mWidgetList );
00958
for ( aIt.toFirst(), wIt.toFirst() ;
00959 aIt.current() && wIt.current() ; ++aIt, ++wIt )
00960 ((
KMFilterActionWidget*)(*wIt))->setAction( (*aIt) );
00961 }
00962
00963
void KMFilterActionWidgetLister::reset()
00964 {
00965
if ( mActionList )
00966 regenerateActionListFromWidgets();
00967
00968 mActionList = 0;
00969 slotClear();
00970 ((
QWidget*)parent())->setEnabled( FALSE );
00971 }
00972
00973
QWidget* KMFilterActionWidgetLister::createWidget(
QWidget *parent )
00974 {
00975
return new KMFilterActionWidget(parent);
00976 }
00977
00978
void KMFilterActionWidgetLister::clearWidget(
QWidget *aWidget )
00979 {
00980
if ( aWidget )
00981 ((
KMFilterActionWidget*)aWidget)->setAction(0);
00982 }
00983
00984
void KMFilterActionWidgetLister::regenerateActionListFromWidgets()
00985 {
00986
if ( !mActionList )
return;
00987
00988 mActionList->clear();
00989
00990
QPtrListIterator<QWidget> it( mWidgetList );
00991
for ( it.toFirst() ; it.current() ; ++it ) {
00992
KMFilterAction *a = ((
KMFilterActionWidget*)(*it))->action();
00993
if ( a )
00994 mActionList->append( a );
00995 }
00996
00997 }
00998
00999
01000
01001
01002
01003
01004
01005 KMPopFilterActionWidget::KMPopFilterActionWidget(
const QString& title,
QWidget *parent,
const char* name )
01006 :
QVButtonGroup( title, parent, name )
01007 {
01008 mActionMap[Down] =
new QRadioButton( i18n(
"&Download mail"),
this );
01009 mActionMap[Later] =
new QRadioButton( i18n(
"Download mail la&ter"),
this );
01010 mActionMap[Delete] =
new QRadioButton( i18n(
"D&elete mail from server"),
this );
01011 mIdMap[id(mActionMap[Later])] = Later;
01012 mIdMap[id(mActionMap[Down])] = Down;
01013 mIdMap[id(mActionMap[Delete])] = Delete;
01014
01015 connect(
this, SIGNAL(clicked(
int)),
01016
this, SLOT( slotActionClicked(
int)) );
01017 }
01018
01019
void KMPopFilterActionWidget::setAction( KMPopFilterAction aAction )
01020 {
01021
if( aAction == NoAction)
01022 {
01023 aAction = Later;
01024 }
01025
01026 mAction = aAction;
01027
01028 blockSignals(
true );
01029
if(!mActionMap[aAction]->isChecked())
01030 {
01031 mActionMap[aAction]->setChecked(
true);
01032 }
01033 blockSignals(
false );
01034
01035 setEnabled(
true);
01036 }
01037
01038 KMPopFilterAction KMPopFilterActionWidget::action()
01039 {
01040
return mAction;
01041 }
01042
01043
void KMPopFilterActionWidget::slotActionClicked(
int aId)
01044 {
01045 emit actionChanged(mIdMap[aId]);
01046
setAction(mIdMap[aId]);
01047 }
01048
01049
void KMPopFilterActionWidget::reset()
01050 {
01051 blockSignals(TRUE);
01052 mActionMap[Down]->setChecked( TRUE );
01053 blockSignals(FALSE);
01054
01055 setEnabled( FALSE );
01056 }
01057
01058
#include "kmfilterdlg.moc"