00001
00002
00003
00004
00005
00006
#include <config.h>
00007
#include "kmsearchpatternedit.h"
00008
00009
#include "kmsearchpattern.h"
00010
#include "rulewidgethandlermanager.h"
00011
using KMail::RuleWidgetHandlerManager;
00012
00013
#include <klocale.h>
00014
#include <kdialog.h>
00015
#include <kdebug.h>
00016
00017
#include <qradiobutton.h>
00018
#include <qcombobox.h>
00019
#include <qbuttongroup.h>
00020
#include <qwidgetstack.h>
00021
#include <qlayout.h>
00022
00023
#include <assert.h>
00024
00025
00026
00027
00028
enum { Message, Body, AnyHeader, Recipients, Size, AgeInDays, Status };
00029
00030
00031
static const struct {
00032
const char *internalName;
00033
const char *displayName;
00034 } SpecialRuleFields[] = {
00035 {
"<message>", I18N_NOOP(
"<message>" ) },
00036 {
"<body>", I18N_NOOP(
"<body>" ) },
00037 {
"<any header>", I18N_NOOP(
"<any header>" ) },
00038 {
"<recipients>", I18N_NOOP(
"<recipients>" ) },
00039 {
"<size>", I18N_NOOP(
"<size in bytes>" ) },
00040 {
"<age in days>", I18N_NOOP(
"<age in days>" ) },
00041 {
"<status>", I18N_NOOP(
"<status>" ) }
00042 };
00043
static const int SpecialRuleFieldsCount =
00044
sizeof( SpecialRuleFields ) /
sizeof( *SpecialRuleFields );
00045
00046
00047
00048
00049
00050
00051
00052 KMSearchRuleWidget::KMSearchRuleWidget(
QWidget *parent,
KMSearchRule *aRule,
00053
const char *name,
bool headersOnly,
00054
bool absoluteDates )
00055 :
QWidget( parent, name ),
00056 mRuleField( 0 ),
00057 mFunctionStack( 0 ),
00058 mValueStack( 0 ),
00059 mAbsoluteDates( absoluteDates )
00060 {
00061 initFieldList( headersOnly, absoluteDates );
00062 initWidget();
00063
00064
if ( aRule )
00065
setRule( aRule );
00066
else
00067
reset();
00068 }
00069
00070 void KMSearchRuleWidget::setHeadersOnly(
bool headersOnly )
00071 {
00072
QCString currentText =
rule()->
field();
00073 initFieldList( headersOnly, mAbsoluteDates );
00074
00075 mRuleField->clear();
00076 mRuleField->insertStringList( mFilterFieldList );
00077 mRuleField->setSizeLimit( mRuleField->count() );
00078 mRuleField->adjustSize();
00079
00080
if ((currentText !=
"<message>") &&
00081 (currentText !=
"<body>"))
00082 mRuleField->changeItem( currentText, 0 );
00083
else
00084 mRuleField->changeItem( QString::null, 0 );
00085 }
00086
00087
void KMSearchRuleWidget::initWidget()
00088 {
00089
QHBoxLayout * hlay =
new QHBoxLayout(
this, 0, KDialog::spacingHint() );
00090
00091
00092 mRuleField =
new QComboBox(
true,
this,
"mRuleField" );
00093 mRuleField->insertStringList( mFilterFieldList );
00094
00095 mRuleField->setSizeLimit( mRuleField->count() );
00096 mRuleField->adjustSize();
00097 hlay->addWidget( mRuleField );
00098
00099
00100 mFunctionStack =
new QWidgetStack(
this,
"mFunctionStack" );
00101 hlay->addWidget( mFunctionStack );
00102
00103 mValueStack =
new QWidgetStack(
this,
"mValueStack" );
00104 hlay->addWidget( mValueStack );
00105 hlay->setStretchFactor( mValueStack, 10 );
00106
00107 RuleWidgetHandlerManager::instance()->createWidgets( mFunctionStack,
00108 mValueStack,
00109
this );
00110
00111
00112 setFocusProxy( mRuleField );
00113
00114 connect( mRuleField, SIGNAL( activated(
const QString & ) ),
00115
this, SLOT( slotRuleFieldChanged(
const QString & ) ) );
00116 connect( mRuleField, SIGNAL( textChanged(
const QString & ) ),
00117
this, SLOT( slotRuleFieldChanged(
const QString & ) ) );
00118 connect( mRuleField, SIGNAL( textChanged(
const QString & ) ),
00119
this, SIGNAL(
fieldChanged(
const QString & ) ) );
00120 }
00121
00122 void KMSearchRuleWidget::setRule(
KMSearchRule *aRule )
00123 {
00124 assert ( aRule );
00125
00126
00127
00128
00129
00130
int i =
indexOfRuleField( aRule->
field() );
00131
00132 mRuleField->blockSignals(
true );
00133
00134
if ( i < 0 ) {
00135 mRuleField->changeItem( QString::fromLatin1( aRule->
field() ), 0 );
00136 i = 0;
00137 }
else {
00138 mRuleField->changeItem( QString::null, 0 );
00139 }
00140
00141 mRuleField->setCurrentItem( i );
00142 mRuleField->blockSignals(
false );
00143
00144 RuleWidgetHandlerManager::instance()->setRule( mFunctionStack, mValueStack,
00145 aRule );
00146 }
00147
00148 KMSearchRule*
KMSearchRuleWidget::rule()
const {
00149
const QCString ruleField =
ruleFieldToEnglish( mRuleField->currentText() );
00150
const KMSearchRule::Function function =
00151 RuleWidgetHandlerManager::instance()->function( ruleField,
00152 mFunctionStack );
00153
const QString value =
00154 RuleWidgetHandlerManager::instance()->value( ruleField, mFunctionStack,
00155 mValueStack );
00156
00157
return KMSearchRule::createInstance( ruleField, function, value );
00158 }
00159
00160 void KMSearchRuleWidget::reset()
00161 {
00162 mRuleField->blockSignals(
true );
00163 mRuleField->changeItem(
"", 0 );
00164 mRuleField->setCurrentItem( 0 );
00165 mRuleField->blockSignals(
false );
00166
00167 RuleWidgetHandlerManager::instance()->reset( mFunctionStack, mValueStack );
00168 }
00169
00170
void KMSearchRuleWidget::slotFunctionChanged()
00171 {
00172
const QCString ruleField =
ruleFieldToEnglish( mRuleField->currentText() );
00173 RuleWidgetHandlerManager::instance()->update( ruleField,
00174 mFunctionStack,
00175 mValueStack );
00176 }
00177
00178
void KMSearchRuleWidget::slotValueChanged()
00179 {
00180
const QCString ruleField =
ruleFieldToEnglish( mRuleField->currentText() );
00181
const QString prettyValue =
00182 RuleWidgetHandlerManager::instance()->prettyValue( ruleField,
00183 mFunctionStack,
00184 mValueStack );
00185 emit
contentsChanged( prettyValue );
00186 }
00187
00188 QCString KMSearchRuleWidget::ruleFieldToEnglish(
const QString & i18nVal )
00189 {
00190
for (
int i = 0; i < SpecialRuleFieldsCount; ++i ) {
00191
if ( i18nVal == i18n( SpecialRuleFields[i].displayName ) )
00192
return SpecialRuleFields[i].internalName;
00193 }
00194
return i18nVal.latin1();
00195 }
00196
00197
int KMSearchRuleWidget::ruleFieldToId(
const QString & i18nVal )
00198 {
00199
for (
int i = 0; i < SpecialRuleFieldsCount; ++i ) {
00200
if ( i18nVal == i18n( SpecialRuleFields[i].displayName ) )
00201
return i;
00202 }
00203
return -1;
00204 }
00205
00206 int KMSearchRuleWidget::indexOfRuleField(
const QCString & aName )
const
00207
{
00208
if ( aName.isEmpty() )
00209
return -1;
00210
00211
QString i18n_aName = i18n( aName );
00212
00213
for (
int i = 1; i < mRuleField->count(); ++i ) {
00214
if ( mRuleField->text( i ) == i18n_aName )
00215
return i;
00216 }
00217
00218
return -1;
00219 }
00220
00221
void KMSearchRuleWidget::initFieldList(
bool headersOnly,
bool absoluteDates )
00222 {
00223 mFilterFieldList.clear();
00224 mFilterFieldList.append(
"");
00225
if( !headersOnly ) {
00226 mFilterFieldList.append( i18n( SpecialRuleFields[Message].displayName ) );
00227 mFilterFieldList.append( i18n( SpecialRuleFields[Body].displayName ) );
00228 }
00229 mFilterFieldList.append( i18n( SpecialRuleFields[AnyHeader].displayName ) );
00230 mFilterFieldList.append( i18n( SpecialRuleFields[Recipients].displayName ) );
00231 mFilterFieldList.append( i18n( SpecialRuleFields[Size].displayName ) );
00232
if ( !absoluteDates )
00233 mFilterFieldList.append( i18n( SpecialRuleFields[AgeInDays].displayName ) );
00234 mFilterFieldList.append( i18n( SpecialRuleFields[Status].displayName ) );
00235
00236
00237 mFilterFieldList.append(
"Subject");
00238 mFilterFieldList.append(
"From");
00239 mFilterFieldList.append(
"To");
00240 mFilterFieldList.append(
"CC");
00241 mFilterFieldList.append(
"Reply-To");
00242 mFilterFieldList.append(
"List-Id");
00243 mFilterFieldList.append(
"Organization");
00244 mFilterFieldList.append(
"Resent-From");
00245 mFilterFieldList.append(
"X-Loop");
00246 mFilterFieldList.append(
"X-Mailing-List");
00247 mFilterFieldList.append(
"X-Spam-Flag");
00248 }
00249
00250
void KMSearchRuleWidget::slotRuleFieldChanged(
const QString & field )
00251 {
00252 RuleWidgetHandlerManager::instance()->update(
ruleFieldToEnglish( field ),
00253 mFunctionStack,
00254 mValueStack );
00255 }
00256
00257
00258
00259
00260
00261
00262
00263 KMSearchRuleWidgetLister::KMSearchRuleWidgetLister(
QWidget *parent,
const char* name,
bool headersOnly,
bool absoluteDates )
00264 : KWidgetLister( 2, FILTER_MAX_RULES, parent, name )
00265 {
00266 mRuleList = 0;
00267 mHeadersOnly = headersOnly;
00268 mAbsoluteDates = absoluteDates;
00269 }
00270
00271 KMSearchRuleWidgetLister::~KMSearchRuleWidgetLister()
00272 {
00273 }
00274
00275
void KMSearchRuleWidgetLister::setRuleList(
QPtrList<KMSearchRule> *aList )
00276 {
00277 assert ( aList );
00278
00279
if ( mRuleList )
00280 regenerateRuleListFromWidgets();
00281
00282 mRuleList = aList;
00283
00284
if ( mWidgetList.first() )
00285 mWidgetList.first()->blockSignals(TRUE);
00286
00287
if ( aList->count() == 0 ) {
00288 slotClear();
00289 mWidgetList.first()->blockSignals(FALSE);
00290
return;
00291 }
00292
00293
int superfluousItems = (
int)mRuleList->count() - mMaxWidgets ;
00294
if ( superfluousItems > 0 ) {
00295 kdDebug(5006) <<
"KMSearchRuleWidgetLister: Clipping rule list to "
00296 << mMaxWidgets <<
" items!" << endl;
00297
00298
for ( ; superfluousItems ; superfluousItems-- )
00299 mRuleList->removeLast();
00300 }
00301
00302
00303 setNumberOfShownWidgetsTo( QMAX((
int)mRuleList->count(),mMinWidgets)+1 );
00304
00305 setNumberOfShownWidgetsTo( QMAX((
int)mRuleList->count(),mMinWidgets) );
00306
00307
00308
QPtrListIterator<KMSearchRule> rIt( *mRuleList );
00309
QPtrListIterator<QWidget> wIt( mWidgetList );
00310
for ( rIt.toFirst(), wIt.toFirst() ;
00311 rIt.current() && wIt.current() ; ++rIt, ++wIt ) {
00312 (static_cast<KMSearchRuleWidget*>(*wIt))->setRule( (*rIt) );
00313 }
00314
for ( ; wIt.current() ; ++wIt )
00315 ((
KMSearchRuleWidget*)(*wIt))->reset();
00316
00317 assert( mWidgetList.first() );
00318 mWidgetList.first()->blockSignals(FALSE);
00319 }
00320
00321
void KMSearchRuleWidgetLister::setHeadersOnly(
bool headersOnly )
00322 {
00323
QPtrListIterator<QWidget> wIt( mWidgetList );
00324
for ( wIt.toFirst() ; wIt.current() ; ++wIt ) {
00325 (static_cast<KMSearchRuleWidget*>(*wIt))->setHeadersOnly( headersOnly );
00326 }
00327 }
00328
00329
void KMSearchRuleWidgetLister::reset()
00330 {
00331
if ( mRuleList )
00332 regenerateRuleListFromWidgets();
00333
00334 mRuleList = 0;
00335 slotClear();
00336 }
00337
00338
QWidget* KMSearchRuleWidgetLister::createWidget(
QWidget *parent )
00339 {
00340
return new KMSearchRuleWidget(parent, 0, 0, mHeadersOnly, mAbsoluteDates);
00341 }
00342
00343
void KMSearchRuleWidgetLister::clearWidget(
QWidget *aWidget )
00344 {
00345
if ( aWidget )
00346 ((
KMSearchRuleWidget*)aWidget)->reset();
00347 }
00348
00349
void KMSearchRuleWidgetLister::regenerateRuleListFromWidgets()
00350 {
00351
if ( !mRuleList )
return;
00352
00353 mRuleList->clear();
00354
00355
QPtrListIterator<QWidget> it( mWidgetList );
00356
for ( it.toFirst() ; it.current() ; ++it ) {
00357
KMSearchRule *r = ((
KMSearchRuleWidget*)(*it))->rule();
00358
if ( r )
00359 mRuleList->append( r );
00360 }
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 KMSearchPatternEdit::KMSearchPatternEdit(
QWidget *parent,
const char *name,
bool headersOnly,
bool absoluteDates )
00373 :
QGroupBox( 1, Horizontal, parent, name )
00374 {
00375 setTitle( i18n(
"Search Criteria") );
00376 initLayout( headersOnly, absoluteDates );
00377 }
00378
00379 KMSearchPatternEdit::KMSearchPatternEdit(
const QString & title,
QWidget *parent,
const char *name,
bool headersOnly,
bool absoluteDates)
00380 :
QGroupBox( 1, Horizontal, title, parent, name )
00381 {
00382 initLayout( headersOnly, absoluteDates );
00383 }
00384
00385 KMSearchPatternEdit::~KMSearchPatternEdit()
00386 {
00387 }
00388
00389
void KMSearchPatternEdit::initLayout(
bool headersOnly,
bool absoluteDates)
00390 {
00391
00392 mAllRBtn =
new QRadioButton( i18n(
"Match a&ll of the following"),
this,
"mAllRBtn" );
00393 mAnyRBtn =
new QRadioButton( i18n(
"Match an&y of the following"),
this,
"mAnyRBtn" );
00394
00395 mAllRBtn->setChecked(TRUE);
00396 mAnyRBtn->setChecked(FALSE);
00397
00398
QButtonGroup *bg =
new QButtonGroup(
this );
00399 bg->hide();
00400 bg->insert( mAllRBtn, (
int)KMSearchPattern::OpAnd );
00401 bg->insert( mAnyRBtn, (
int)KMSearchPattern::OpOr );
00402
00403
00404 mRuleLister =
new KMSearchRuleWidgetLister(
this,
"swl", headersOnly, absoluteDates );
00405 mRuleLister->slotClear();
00406
00407
00408 connect( bg, SIGNAL(clicked(
int)),
00409
this, SLOT(slotRadioClicked(
int)) );
00410
00411
KMSearchRuleWidget *srw = (
KMSearchRuleWidget*)mRuleLister->mWidgetList.first();
00412
if ( srw ) {
00413 connect( srw, SIGNAL(fieldChanged(
const QString &)),
00414
this, SLOT(slotAutoNameHack()) );
00415 connect( srw, SIGNAL(contentsChanged(
const QString &)),
00416
this, SLOT(slotAutoNameHack()) );
00417 }
else
00418 kdDebug(5006) <<
"KMSearchPatternEdit: no first KMSearchRuleWidget, though slotClear() has been called!" << endl;
00419 }
00420
00421 void KMSearchPatternEdit::setSearchPattern(
KMSearchPattern *aPattern )
00422 {
00423 assert( aPattern );
00424
00425 mRuleLister->setRuleList( aPattern );
00426
00427 mPattern = aPattern;
00428
00429 blockSignals(TRUE);
00430
if ( mPattern->
op() == KMSearchPattern::OpOr )
00431 mAnyRBtn->setChecked(TRUE);
00432
else
00433 mAllRBtn->setChecked(TRUE);
00434 blockSignals(FALSE);
00435
00436 setEnabled( TRUE );
00437 }
00438
00439 void KMSearchPatternEdit::setHeadersOnly(
bool headersOnly )
00440 {
00441 mRuleLister->setHeadersOnly( headersOnly );
00442 }
00443
00444 void KMSearchPatternEdit::reset()
00445 {
00446 mRuleLister->reset();
00447
00448 blockSignals(TRUE);
00449 mAllRBtn->setChecked( TRUE );
00450 blockSignals(FALSE);
00451
00452 setEnabled( FALSE );
00453 }
00454
00455
void KMSearchPatternEdit::slotRadioClicked(
int aIdx)
00456 {
00457
if ( mPattern )
00458 mPattern->
setOp( (KMSearchPattern::Operator)aIdx );
00459 }
00460
00461
void KMSearchPatternEdit::slotAutoNameHack()
00462 {
00463 mRuleLister->regenerateRuleListFromWidgets();
00464 emit
maybeNameChanged();
00465 }
00466
00467
#include "kmsearchpatternedit.moc"