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