kmail Library API Documentation

kmsearchpatternedit.cpp

00001 // kmsearchpatternedit.cpp
00002 // Author: Marc Mutz <Marc@Mutz.com>
00003 // This code is under GPL
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 // class KMSearchRuleWidget
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 ); // sFilter{Func,Field}List are local to KMSearchRuleWidget
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   // don't show sliders when popping up this menu
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   //--------------set the field
00109   int i = indexOfRuleField( aRule->field() );
00110 
00111   if ( i<0 ) { // not found -> user defined field
00112     mRuleField->changeItem( QString(aRule->field()), 0 );
00113     i=0;
00114   } else // found in the list of predefined fields
00115     mRuleField->changeItem( "", 0 );
00116 
00117   mRuleField->setCurrentItem( i );
00118 
00119   //--------------set function and contents
00120   mRuleFunc->setCurrentItem( (int)aRule->function() );
00121   //--------------special case status search
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   //if (i18nVal == i18n("todo")) return "todo";
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   //---------- initialize list of filter operators
00224   if ( mFilterFuncList.isEmpty() )
00225   {
00226     // also see KMSearchRule::matches() and KMSearchRule::Function
00227     // if you change the following strings!
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   //---------- initialize list of filter operators
00241   if ( mFilterFieldList.isEmpty() )
00242   {
00243     mFilterFieldList.append("");
00244     // also see KMSearchRule::matches() and ruleFieldToEnglish() if
00245     // you change the following i18n-ized strings!
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     // these others only represent message headers and you can add to
00254     // them as you like
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   //---------- initialize list of stati
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     //mStatiList.append( i18n( "todo" ) );
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 // class KMFilterActionWidgetLister (the filter action editor)
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() ) // move this below next 'if'?
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   // HACK to workaround regression in Qt 3.1.3 and Qt 3.2.0 (fixes bug #63537)
00348   setNumberOfShownWidgetsTo( QMAX((int)mRuleList->count(),mMinWidgets)+1 );
00349   // set the right number of widgets
00350   setNumberOfShownWidgetsTo( QMAX((int)mRuleList->count(),mMinWidgets) );
00351 
00352   // load the actions into the widgets
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 // class KMSearchPatternEdit
00406 //
00407 //=============================================================================
00408 
00409 KMSearchPatternEdit::KMSearchPatternEdit(QWidget *parent, const char *name, bool headersOnly, bool absoluteDates )
00410   : QGroupBox( 1/*columns*/, 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/*column*/, 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   //------------the radio buttons
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   //------------the list of KMSearchRuleWidget's
00441   mRuleLister = new KMSearchRuleWidgetLister( this, "swl", headersOnly, absoluteDates );
00442   mRuleLister->slotClear();
00443 
00444   //------------connect a few signals
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"
KDE Logo
This file is part of the documentation for kmail Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:37:34 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003