kmail Library API Documentation

rulewidgethandlermanager.cpp

00001 /*  -*- mode: C++; c-file-style: "gnu" -*-
00002     rulewidgethandlermanager.cpp
00003 
00004     This file is part of KMail, the KDE mail client.
00005     Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
00006 
00007     KMail is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     KMail is distributed in the hope that it will be useful, but
00013     WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     In addition, as a special exception, the copyright holders give
00022     permission to link the code of this program with any edition of
00023     the Qt library by Trolltech AS, Norway (or with modified versions
00024     of Qt that use the same license as Qt), and distribute linked
00025     combinations including the two.  You must obey the GNU General
00026     Public License in all respects for all of the code used other than
00027     Qt.  If you modify this file, you may extend this exception to
00028     your version of the file, but you are not obligated to do so.  If
00029     you do not wish to do so, delete this exception statement from
00030     your version.
00031 */
00032 
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036 
00037 #include "rulewidgethandlermanager.h"
00038 
00039 #include "interfaces/rulewidgethandler.h"
00040 #include "stl_util.h"
00041 
00042 #include <kdebug.h>
00043 
00044 #include <qwidgetstack.h>
00045 #include <qstring.h>
00046 #include <qcstring.h>
00047 #include <qobject.h>
00048 #include <qobjectlist.h>
00049 
00050 #include <assert.h>
00051 
00052 #include <algorithm>
00053 using std::for_each;
00054 using std::remove;
00055 
00056 KMail::RuleWidgetHandlerManager * KMail::RuleWidgetHandlerManager::self = 0;
00057 
00058 namespace {
00059   class TextRuleWidgetHandler : public KMail::RuleWidgetHandler {
00060   public:
00061     TextRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
00062     ~TextRuleWidgetHandler() {}
00063 
00064     QWidget * createFunctionWidget( int number,
00065                                     QWidgetStack *functionStack,
00066                                     const QObject *receiver ) const;
00067     QWidget * createValueWidget( int number,
00068                                  QWidgetStack *valueStack,
00069                                  const QObject *receiver ) const;
00070     KMSearchRule::Function function( const QCString & field,
00071                                      const QWidgetStack *functionStack ) const;
00072     QString value( const QCString & field,
00073                    const QWidgetStack *functionStack,
00074                    const QWidgetStack *valueStack ) const;
00075     QString prettyValue( const QCString & field,
00076                          const QWidgetStack *functionStack,
00077                          const QWidgetStack *valueStack ) const;
00078     bool handlesField( const QCString & field ) const;
00079     void reset( QWidgetStack *functionStack,
00080                 QWidgetStack *valueStack ) const;
00081     bool setRule( QWidgetStack *functionStack,
00082                   QWidgetStack *valueStack,
00083                   const KMSearchRule *rule ) const;
00084     bool update( const QCString & field,
00085                  QWidgetStack *functionStack,
00086                  QWidgetStack *valueStack ) const;
00087 
00088  private:
00089     KMSearchRule::Function currentFunction( const QWidgetStack *functionStack ) const;
00090     QString currentValue( const QWidgetStack *valueStack,
00091                           KMSearchRule::Function func ) const;
00092   };
00093 
00094   class MessageRuleWidgetHandler : public KMail::RuleWidgetHandler {
00095   public:
00096     MessageRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
00097     ~MessageRuleWidgetHandler() {}
00098 
00099     QWidget * createFunctionWidget( int number,
00100                                     QWidgetStack *functionStack,
00101                                     const QObject *receiver ) const;
00102     QWidget * createValueWidget( int number,
00103                                  QWidgetStack *valueStack,
00104                                  const QObject *receiver ) const;
00105     KMSearchRule::Function function( const QCString & field,
00106                                      const QWidgetStack *functionStack ) const;
00107     QString value( const QCString & field,
00108                    const QWidgetStack *functionStack,
00109                    const QWidgetStack *valueStack ) const;
00110     QString prettyValue( const QCString & field,
00111                          const QWidgetStack *functionStack,
00112                          const QWidgetStack *valueStack ) const;
00113     bool handlesField( const QCString & field ) const;
00114     void reset( QWidgetStack *functionStack,
00115                 QWidgetStack *valueStack ) const;
00116     bool setRule( QWidgetStack *functionStack,
00117                   QWidgetStack *valueStack,
00118                   const KMSearchRule *rule ) const;
00119     bool update( const QCString & field,
00120                  QWidgetStack *functionStack,
00121                  QWidgetStack *valueStack ) const;
00122 
00123  private:
00124     KMSearchRule::Function currentFunction( const QWidgetStack *functionStack ) const;
00125     QString currentValue( const QWidgetStack *valueStack,
00126                           KMSearchRule::Function func ) const;
00127   };
00128 
00129 
00130   class StatusRuleWidgetHandler : public KMail::RuleWidgetHandler {
00131   public:
00132     StatusRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
00133     ~StatusRuleWidgetHandler() {}
00134 
00135     QWidget * createFunctionWidget( int number,
00136                                     QWidgetStack *functionStack,
00137                                     const QObject *receiver ) const;
00138     QWidget * createValueWidget( int number,
00139                                  QWidgetStack *valueStack,
00140                                  const QObject *receiver ) const;
00141     KMSearchRule::Function function( const QCString & field,
00142                                      const QWidgetStack *functionStack ) const;
00143     QString value( const QCString & field,
00144                    const QWidgetStack *functionStack,
00145                    const QWidgetStack *valueStack ) const;
00146     QString prettyValue( const QCString & field,
00147                          const QWidgetStack *functionStack,
00148                          const QWidgetStack *valueStack ) const;
00149     bool handlesField( const QCString & field ) const;
00150     void reset( QWidgetStack *functionStack,
00151                 QWidgetStack *valueStack ) const;
00152     bool setRule( QWidgetStack *functionStack,
00153                   QWidgetStack *valueStack,
00154                   const KMSearchRule *rule ) const;
00155     bool update( const QCString & field,
00156                  QWidgetStack *functionStack,
00157                  QWidgetStack *valueStack ) const;
00158 
00159   private:
00160     KMSearchRule::Function currentFunction( const QWidgetStack *functionStack ) const;
00161     int currentStatusValue( const QWidgetStack *valueStack ) const;
00162   };
00163 
00164   class NumericRuleWidgetHandler : public KMail::RuleWidgetHandler {
00165   public:
00166     NumericRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
00167     ~NumericRuleWidgetHandler() {}
00168 
00169     QWidget * createFunctionWidget( int number,
00170                                     QWidgetStack *functionStack,
00171                                     const QObject *receiver ) const;
00172     QWidget * createValueWidget( int number,
00173                                  QWidgetStack *valueStack,
00174                                  const QObject *receiver ) const;
00175     KMSearchRule::Function function( const QCString & field,
00176                                      const QWidgetStack *functionStack ) const;
00177     QString value( const QCString & field,
00178                    const QWidgetStack *functionStack,
00179                    const QWidgetStack *valueStack ) const;
00180     QString prettyValue( const QCString & field,
00181                          const QWidgetStack *functionStack,
00182                          const QWidgetStack *valueStack ) const;
00183     bool handlesField( const QCString & field ) const;
00184     void reset( QWidgetStack *functionStack,
00185                 QWidgetStack *valueStack ) const;
00186     bool setRule( QWidgetStack *functionStack,
00187                   QWidgetStack *valueStack,
00188                   const KMSearchRule *rule ) const;
00189     bool update( const QCString & field,
00190                  QWidgetStack *functionStack,
00191                  QWidgetStack *valueStack ) const;
00192 
00193   private:
00194     KMSearchRule::Function currentFunction( const QWidgetStack *functionStack ) const;
00195     QString currentValue( const QWidgetStack *valueStack ) const;
00196   };
00197 }
00198 
00199 KMail::RuleWidgetHandlerManager::RuleWidgetHandlerManager()
00200 {
00201   registerHandler( new NumericRuleWidgetHandler() );
00202   registerHandler( new StatusRuleWidgetHandler() );
00203   registerHandler( new MessageRuleWidgetHandler() );
00204    // the TextRuleWidgetHandler is the fallback handler, so it has to be added
00205   // as last handler
00206   registerHandler( new TextRuleWidgetHandler() );
00207 }
00208 
00209 KMail::RuleWidgetHandlerManager::~RuleWidgetHandlerManager()
00210 {
00211   for_each( mHandlers.begin(), mHandlers.end(),
00212         DeleteAndSetToZero<RuleWidgetHandler>() );
00213 }
00214 
00215 void KMail::RuleWidgetHandlerManager::registerHandler( const RuleWidgetHandler * handler )
00216 {
00217   if ( !handler )
00218     return;
00219   unregisterHandler( handler ); // don't produce duplicates
00220   mHandlers.push_back( handler );
00221 }
00222 
00223 void KMail::RuleWidgetHandlerManager::unregisterHandler( const RuleWidgetHandler * handler )
00224 {
00225   // don't delete them, only remove them from the list!
00226   mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
00227 }
00228 
00229 namespace {
00233   int childCount( const QObject *parent, const char *objName )
00234   {
00235     QObjectList *list = parent->queryList( 0, objName, false, false );
00236     if ( !list )
00237       return 0;
00238     const int count = list->count();
00239     delete list; list = 0;
00240     return count;
00241   }
00242 }
00243 
00244 void KMail::RuleWidgetHandlerManager::createWidgets( QWidgetStack *functionStack,
00245                                                      QWidgetStack *valueStack,
00246                                                      const QObject *receiver ) const
00247 {
00248   for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
00249     QWidget *w = 0;
00250     for ( int i = 0;
00251           ( w = (*it)->createFunctionWidget( i, functionStack, receiver ) );
00252           ++i ) {
00253       if ( childCount( functionStack, w->name() ) < 2 ) {
00254         // there wasn't already a widget with this name, so add this widget
00255         functionStack->addWidget( w );
00256       }
00257       else {
00258         // there was already a widget with this name, so discard this widget
00259         kdDebug(5006) << "RuleWidgetHandlerManager::createWidgets: "
00260                       << w->name() << " already exists in functionStack"
00261                       << endl;
00262         delete w; w = 0;
00263       }
00264     }
00265     for ( int i = 0;
00266           ( w = (*it)->createValueWidget( i, valueStack, receiver ) );
00267           ++i ) {
00268       if ( childCount( valueStack, w->name() ) < 2 ) {
00269         // there wasn't already a widget with this name, so add this widget
00270         valueStack->addWidget( w );
00271       }
00272       else {
00273         // there was already a widget with this name, so discard this widget
00274         kdDebug(5006) << "RuleWidgetHandlerManager::createWidgets: "
00275                       << w->name() << " already exists in valueStack"
00276                       << endl;
00277         delete w; w = 0;
00278       }
00279     }
00280   }
00281 }
00282 
00283 KMSearchRule::Function KMail::RuleWidgetHandlerManager::function( const QCString& field,
00284                                                                   const QWidgetStack *functionStack ) const
00285 {
00286   for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
00287     const KMSearchRule::Function func = (*it)->function( field,
00288                                                          functionStack );
00289     if ( func != KMSearchRule::FuncNone )
00290       return func;
00291   }
00292   return KMSearchRule::FuncNone;
00293 }
00294 
00295 QString KMail::RuleWidgetHandlerManager::value( const QCString& field,
00296                                                 const QWidgetStack *functionStack,
00297                                                 const QWidgetStack *valueStack ) const
00298 {
00299   for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
00300     const QString val = (*it)->value( field, functionStack, valueStack );
00301     if ( !val.isEmpty() )
00302       return val;
00303   }
00304   return QString::null;
00305 }
00306 
00307 QString KMail::RuleWidgetHandlerManager::prettyValue( const QCString& field,
00308                                                       const QWidgetStack *functionStack,
00309                                                       const QWidgetStack *valueStack ) const
00310 {
00311   for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
00312     const QString val = (*it)->prettyValue( field, functionStack, valueStack );
00313     if ( !val.isEmpty() )
00314       return val;
00315   }
00316   return QString::null;
00317 }
00318 
00319 void KMail::RuleWidgetHandlerManager::reset( QWidgetStack *functionStack,
00320                                              QWidgetStack *valueStack ) const
00321 {
00322   for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
00323     (*it)->reset( functionStack, valueStack );
00324   }
00325   update( "", functionStack, valueStack );
00326 }
00327 
00328 void KMail::RuleWidgetHandlerManager::setRule( QWidgetStack *functionStack,
00329                                                QWidgetStack *valueStack,
00330                                                const KMSearchRule *rule ) const
00331 {
00332   assert( rule );
00333   reset( functionStack, valueStack );
00334   for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
00335     if ( (*it)->setRule( functionStack, valueStack, rule ) )
00336       return;
00337   }
00338 }
00339 
00340 void KMail::RuleWidgetHandlerManager::update( const QCString &field,
00341                                               QWidgetStack *functionStack,
00342                                               QWidgetStack *valueStack ) const
00343 {
00344   //kdDebug(5006) << "RuleWidgetHandlerManager::update( \"" << field
00345   //              << "\", ... )" << endl;
00346   for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
00347     if ( (*it)->update( field, functionStack, valueStack ) )
00348       return;
00349   }
00350 }
00351 
00352 //-----------------------------------------------------------------------------
00353 
00354 namespace {
00355   // FIXME (Qt >= 4.0):
00356   // This is a simplified and constified copy of QObject::child(). According
00357   // to a comment in qobject.h QObject::child() will be made const in Qt 4.0.
00358   // So once we require Qt 4.0 this can be removed.
00359   QObject* QObject_child_const( const QObject *parent,
00360                                 const char *objName )
00361   {
00362     const QObjectList *list = parent->children();
00363     if ( !list )
00364       return 0;
00365 
00366     QObjectListIterator it( *list );
00367     QObject *obj;
00368     while ( ( obj = it.current() ) ) {
00369       ++it;
00370       if ( !objName || qstrcmp( objName, obj->name() ) == 0 )
00371         break;
00372     }
00373     return obj;
00374   }
00375 }
00376 
00377 //-----------------------------------------------------------------------------
00378 
00379 // these includes are temporary and should not be needed for the code
00380 // above this line, so they appear only here:
00381 #include "kmaddrbook.h"
00382 #include "kmsearchpattern.h"
00383 #include "regexplineedit.h"
00384 using KMail::RegExpLineEdit;
00385 
00386 #include <klocale.h>
00387 #include <knuminput.h>
00388 
00389 #include <qcombobox.h>
00390 #include <qlabel.h>
00391 
00392 //=============================================================================
00393 //
00394 // class TextRuleWidgetHandler
00395 //
00396 //=============================================================================
00397 
00398 namespace {
00399   // also see KMSearchRule::matches() and KMSearchRule::Function
00400   // if you change the following strings!
00401   static const struct {
00402     const KMSearchRule::Function id;
00403     const char *displayName;
00404   } TextFunctions[] = {
00405     { KMSearchRule::FuncContains,           I18N_NOOP( "contains" )          },
00406     { KMSearchRule::FuncContainsNot,        I18N_NOOP( "does not contain" )   },
00407     { KMSearchRule::FuncEquals,             I18N_NOOP( "equals" )            },
00408     { KMSearchRule::FuncNotEqual,           I18N_NOOP( "does not equal" )     },
00409     { KMSearchRule::FuncRegExp,             I18N_NOOP( "matches regular expr." ) },
00410     { KMSearchRule::FuncNotRegExp,          I18N_NOOP( "does not match reg. expr." ) },
00411     { KMSearchRule::FuncIsInAddressbook,    I18N_NOOP( "is in address book" ) },
00412     { KMSearchRule::FuncIsNotInAddressbook, I18N_NOOP( "is not in address book" ) },
00413     { KMSearchRule::FuncIsInCategory,       I18N_NOOP( "is in category" ) },
00414     { KMSearchRule::FuncIsNotInCategory,    I18N_NOOP( "is not in category" ) }
00415   };
00416   static const int TextFunctionCount =
00417     sizeof( TextFunctions ) / sizeof( *TextFunctions );
00418 
00419   //---------------------------------------------------------------------------
00420 
00421   QWidget * TextRuleWidgetHandler::createFunctionWidget( int number,
00422                                                          QWidgetStack *functionStack,
00423                                                          const QObject *receiver ) const
00424   {
00425     if ( number != 0 )
00426       return 0;
00427 
00428     QComboBox *funcCombo = new QComboBox( functionStack, "textRuleFuncCombo" );
00429     for ( int i = 0; i < TextFunctionCount; ++i ) {
00430       funcCombo->insertItem( i18n( TextFunctions[i].displayName ) );
00431     }
00432     funcCombo->adjustSize();
00433     QObject::connect( funcCombo, SIGNAL( activated( int ) ),
00434                       receiver, SLOT( slotFunctionChanged() ) );
00435     return funcCombo;
00436   }
00437 
00438   //---------------------------------------------------------------------------
00439 
00440   QWidget * TextRuleWidgetHandler::createValueWidget( int number,
00441                                                       QWidgetStack *valueStack,
00442                                                       const QObject *receiver ) const
00443   {
00444     if ( number == 0 ) {
00445       RegExpLineEdit *lineEdit =
00446         new RegExpLineEdit( valueStack, "regExpLineEdit" );
00447       QObject::connect( lineEdit, SIGNAL( textChanged( const QString & ) ),
00448                         receiver, SLOT( slotValueChanged() ) );
00449       return lineEdit;
00450     }
00451 
00452     // blank QLabel to hide value widget for in-address-book rule
00453     if ( number == 1 ) {
00454       return new QLabel( valueStack, "textRuleValueHider" );
00455     }
00456 
00457     if ( number == 2 ) {
00458       QComboBox *combo =  new QComboBox( valueStack, "categoryCombo" );
00459       QStringList categories = KabcBridge::categories();
00460       combo->insertStringList( categories );
00461       QObject::connect( combo, SIGNAL( activated( int ) ),
00462                         receiver, SLOT( slotValueChanged() ) );
00463       return combo;
00464     }
00465 
00466     return 0;
00467   }
00468 
00469   //---------------------------------------------------------------------------
00470 
00471   KMSearchRule::Function TextRuleWidgetHandler::currentFunction( const QWidgetStack *functionStack ) const
00472   {
00473     const QComboBox *funcCombo =
00474       dynamic_cast<QComboBox*>( QObject_child_const( functionStack,
00475                                                      "textRuleFuncCombo" ) );
00476     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
00477     //  dynamic_cast<QComboBox*>( functionStack->child( "textRuleFuncCombo",
00478     //                                                  0, false ) );
00479     if ( funcCombo ) {
00480       return TextFunctions[funcCombo->currentItem()].id;
00481     }
00482     else
00483       kdDebug(5006) << "TextRuleWidgetHandler::currentFunction: "
00484                        "textRuleFuncCombo not found." << endl;
00485     return KMSearchRule::FuncNone;
00486   }
00487 
00488   //---------------------------------------------------------------------------
00489 
00490   KMSearchRule::Function TextRuleWidgetHandler::function( const QCString &,
00491                                                           const QWidgetStack *functionStack ) const
00492   {
00493     return currentFunction( functionStack );
00494   }
00495 
00496   //---------------------------------------------------------------------------
00497 
00498   QString TextRuleWidgetHandler::currentValue( const QWidgetStack *valueStack,
00499                                                KMSearchRule::Function func ) const
00500   {
00501     // here we gotta check the combobox which contains the categories
00502     if ( func  == KMSearchRule::FuncIsInCategory ||
00503          func  == KMSearchRule::FuncIsNotInCategory ) {
00504       const QComboBox *combo=
00505         dynamic_cast<QComboBox*>( QObject_child_const( valueStack,
00506                                                        "categoryCombo" ) );
00507     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
00508     //  dynamic_cast<QComboBox*>( valueStack->child( "categoryCombo",
00509     //                                               0, false ) );
00510       if ( combo ) {
00511         return combo->currentText();
00512       }
00513       else {
00514         kdDebug(5006) << "TextRuleWidgetHandler::currentValue: "
00515                          "categoryCombo not found." << endl;
00516         return QString::null;
00517       }
00518     }
00519 
00520     //in other cases of func it is a lineedit
00521     const RegExpLineEdit *lineEdit =
00522       dynamic_cast<RegExpLineEdit*>( QObject_child_const( valueStack,
00523                                                           "regExpLineEdit" ) );
00524     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
00525     //  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00526     //                                                    0, false ) );
00527     if ( lineEdit ) {
00528       return lineEdit->text();
00529       }
00530     else
00531       kdDebug(5006) << "TextRuleWidgetHandler::currentValue: "
00532                        "regExpLineEdit not found." << endl;
00533 
00534     // or anything else, like addressbook
00535     return QString::null;
00536   }
00537 
00538   //---------------------------------------------------------------------------
00539 
00540   QString TextRuleWidgetHandler::value( const QCString &,
00541                                         const QWidgetStack *functionStack,
00542                                         const QWidgetStack *valueStack ) const
00543   {
00544     KMSearchRule::Function func = currentFunction( functionStack );
00545     if ( func == KMSearchRule::FuncIsInAddressbook )
00546       return "is in address book"; // just a non-empty dummy value
00547     else if ( func == KMSearchRule::FuncIsNotInAddressbook )
00548       return "is not in address book"; // just a non-empty dummy value
00549     else
00550       return currentValue( valueStack, func );
00551   }
00552 
00553   //---------------------------------------------------------------------------
00554 
00555   QString TextRuleWidgetHandler::prettyValue( const QCString &,
00556                                               const QWidgetStack *functionStack,
00557                                               const QWidgetStack *valueStack ) const
00558   {
00559     KMSearchRule::Function func = currentFunction( functionStack );
00560     if ( func == KMSearchRule::FuncIsInAddressbook )
00561       return i18n( "is in address book" );
00562     else if ( func == KMSearchRule::FuncIsNotInAddressbook )
00563       return i18n( "is not in address book" );
00564     else
00565       return currentValue( valueStack, func );
00566   }
00567 
00568   //---------------------------------------------------------------------------
00569 
00570   bool TextRuleWidgetHandler::handlesField( const QCString & ) const
00571   {
00572     return true; // we handle all fields (as fallback)
00573   }
00574 
00575   //---------------------------------------------------------------------------
00576 
00577   void TextRuleWidgetHandler::reset( QWidgetStack *functionStack,
00578                                      QWidgetStack *valueStack ) const
00579   {
00580     // reset the function combo box
00581     QComboBox *funcCombo =
00582       dynamic_cast<QComboBox*>( functionStack->child( "textRuleFuncCombo",
00583                                                       0, false ) );
00584     if ( funcCombo ) {
00585       funcCombo->blockSignals( true );
00586       funcCombo->setCurrentItem( 0 );
00587       funcCombo->blockSignals( false );
00588     }
00589 
00590     // reset the value widget
00591     RegExpLineEdit *lineEdit =
00592       dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00593                                                         0, false ) );
00594     if ( lineEdit ) {
00595       lineEdit->blockSignals( true );
00596       lineEdit->clear();
00597       lineEdit->blockSignals( false );
00598       lineEdit->showEditButton( false );
00599       valueStack->raiseWidget( lineEdit );
00600     }
00601 
00602     QComboBox *combo =
00603       dynamic_cast<QComboBox*>( valueStack->child( "categoryCombo",
00604                                                    0, false ) );
00605     if (combo) {
00606       combo->blockSignals( true );
00607       combo->setCurrentItem( 0 );
00608       combo->blockSignals( false );
00609     }
00610   }
00611 
00612   //---------------------------------------------------------------------------
00613 
00614   bool TextRuleWidgetHandler::setRule( QWidgetStack *functionStack,
00615                                        QWidgetStack *valueStack,
00616                                        const KMSearchRule *rule ) const
00617   {
00618     if ( !rule ) {
00619       reset( functionStack, valueStack );
00620       return false;
00621     }
00622 
00623     const KMSearchRule::Function func = rule->function();
00624     int i = 0;
00625     for ( ; i < TextFunctionCount; ++i )
00626       if ( func == TextFunctions[i].id )
00627         break;
00628     QComboBox *funcCombo =
00629       dynamic_cast<QComboBox*>( functionStack->child( "textRuleFuncCombo",
00630                                                       0, false ) );
00631     if ( funcCombo ) {
00632       funcCombo->blockSignals( true );
00633       if ( i < TextFunctionCount )
00634         funcCombo->setCurrentItem( i );
00635       else {
00636         kdDebug(5006) << "TextRuleWidgetHandler::setRule( "
00637                       << rule->asString()
00638                       << " ): unhandled function" << endl;
00639         funcCombo->setCurrentItem( 0 );
00640       }
00641       funcCombo->blockSignals( false );
00642       functionStack->raiseWidget( funcCombo );
00643     }
00644 
00645     if ( func == KMSearchRule::FuncIsInAddressbook ||
00646          func == KMSearchRule::FuncIsNotInAddressbook ) {
00647       QWidget *w =
00648         static_cast<QWidget*>( valueStack->child( "textRuleValueHider",
00649                                                   0, false ) );
00650       valueStack->raiseWidget( w );
00651     }
00652     else if ( func == KMSearchRule::FuncIsInCategory ||
00653               func == KMSearchRule::FuncIsNotInCategory) {
00654       QComboBox *combo =
00655         static_cast<QComboBox*>( valueStack->child( "categoryCombo",
00656                                                     0, false ) );
00657       combo->blockSignals( true );
00658       for ( i = 0; i < combo->count(); ++i )
00659         if ( rule->contents() == combo->text( i ) ) {
00660           combo->setCurrentItem( i );
00661           break;
00662         }
00663       if ( i == combo->count() )
00664         combo->setCurrentItem( 0 );
00665 
00666       combo->blockSignals( false );
00667       valueStack->raiseWidget( combo );
00668     }
00669     else {
00670       RegExpLineEdit *lineEdit =
00671         dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00672                                                           0, false ) );
00673       if ( lineEdit ) {
00674         lineEdit->blockSignals( true );
00675         lineEdit->setText( rule->contents() );
00676         lineEdit->blockSignals( false );
00677         lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
00678                                   func == KMSearchRule::FuncNotRegExp );
00679         valueStack->raiseWidget( lineEdit );
00680       }
00681     }
00682     return true;
00683   }
00684 
00685 
00686   //---------------------------------------------------------------------------
00687 
00688   bool TextRuleWidgetHandler::update( const QCString &,
00689                                       QWidgetStack *functionStack,
00690                                       QWidgetStack *valueStack ) const
00691   {
00692     // raise the correct function widget
00693     functionStack->raiseWidget(
00694       static_cast<QWidget*>( functionStack->child( "textRuleFuncCombo",
00695                                                    0, false ) ) );
00696 
00697     // raise the correct value widget
00698     KMSearchRule::Function func = currentFunction( functionStack );
00699     if ( func == KMSearchRule::FuncIsInAddressbook ||
00700          func == KMSearchRule::FuncIsNotInAddressbook ) {
00701       valueStack->raiseWidget(
00702         static_cast<QWidget*>( valueStack->child( "textRuleValueHider",
00703                                                   0, false ) ) );
00704     }
00705     else if ( func == KMSearchRule::FuncIsInCategory ||
00706               func == KMSearchRule::FuncIsNotInCategory) {
00707       valueStack->raiseWidget(
00708         static_cast<QWidget*>( valueStack->child( "categoryCombo",
00709                                                   0, false ) ) );
00710     }
00711     else {
00712       RegExpLineEdit *lineEdit =
00713         dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00714                                                           0, false ) );
00715       if ( lineEdit ) {
00716         lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
00717                                   func == KMSearchRule::FuncNotRegExp );
00718         valueStack->raiseWidget( lineEdit );
00719       }
00720     }
00721     return true;
00722   }
00723 
00724 } // anonymous namespace for TextRuleWidgetHandler
00725 
00726 
00727 //=============================================================================
00728 //
00729 // class MessageRuleWidgetHandler
00730 //
00731 //=============================================================================
00732 
00733 namespace {
00734   // also see KMSearchRule::matches() and KMSearchRule::Function
00735   // if you change the following strings!
00736   static const struct {
00737     const KMSearchRule::Function id;
00738     const char *displayName;
00739   } MessageFunctions[] = {
00740     { KMSearchRule::FuncContains,        I18N_NOOP( "contains" )          },
00741     { KMSearchRule::FuncContainsNot,     I18N_NOOP( "does not contain" )  },
00742     { KMSearchRule::FuncRegExp,          I18N_NOOP( "matches regular expr." ) },
00743     { KMSearchRule::FuncNotRegExp,       I18N_NOOP( "does not match reg. expr." ) },
00744     { KMSearchRule::FuncHasAttachment,   I18N_NOOP( "has an attachment" ) },
00745     { KMSearchRule::FuncHasNoAttachment, I18N_NOOP( "has no attachment" ) },
00746   };
00747   static const int MessageFunctionCount =
00748     sizeof( MessageFunctions ) / sizeof( *MessageFunctions );
00749 
00750   //---------------------------------------------------------------------------
00751 
00752   QWidget * MessageRuleWidgetHandler::createFunctionWidget( int number,
00753                                                             QWidgetStack *functionStack,
00754                                                             const QObject *receiver ) const
00755   {
00756     if ( number != 0 )
00757       return 0;
00758 
00759     QComboBox *funcCombo = new QComboBox( functionStack, "messageRuleFuncCombo" );
00760     for ( int i = 0; i < MessageFunctionCount; ++i ) {
00761       funcCombo->insertItem( i18n( MessageFunctions[i].displayName ) );
00762     }
00763     funcCombo->adjustSize();
00764     QObject::connect( funcCombo, SIGNAL( activated( int ) ),
00765                       receiver, SLOT( slotFunctionChanged() ) );
00766     return funcCombo;
00767   }
00768 
00769   //---------------------------------------------------------------------------
00770 
00771   QWidget * MessageRuleWidgetHandler::createValueWidget( int number,
00772                                                          QWidgetStack *valueStack,
00773                                                          const QObject *receiver ) const
00774   {
00775     if ( number == 0 ) {
00776       RegExpLineEdit *lineEdit =
00777         new RegExpLineEdit( valueStack, "regExpLineEdit" );
00778       QObject::connect( lineEdit, SIGNAL( textChanged( const QString & ) ),
00779                         receiver, SLOT( slotValueChanged() ) );
00780       return lineEdit;
00781     }
00782 
00783     // blank QLabel to hide value widget for has-attachment rule
00784     if ( number == 1 ) {
00785       return new QLabel( valueStack, "textRuleValueHider" );
00786     }
00787 
00788     return 0;
00789   }
00790 
00791   //---------------------------------------------------------------------------
00792 
00793   KMSearchRule::Function MessageRuleWidgetHandler::currentFunction( const QWidgetStack *functionStack ) const
00794   {
00795     const QComboBox *funcCombo =
00796       dynamic_cast<QComboBox*>( QObject_child_const( functionStack,
00797                                                      "messageRuleFuncCombo" ) );
00798     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
00799     //  dynamic_cast<QComboBox*>( functionStack->child( "messageRuleFuncCombo",
00800     //                                                  0, false ) );
00801     if ( funcCombo ) {
00802       return MessageFunctions[funcCombo->currentItem()].id;
00803     }
00804     else
00805       kdDebug(5006) << "MessageRuleWidgetHandler::currentFunction: "
00806                        "messageRuleFuncCombo not found." << endl;
00807     return KMSearchRule::FuncNone;
00808   }
00809 
00810   //---------------------------------------------------------------------------
00811 
00812   KMSearchRule::Function MessageRuleWidgetHandler::function( const QCString & field,
00813                                                              const QWidgetStack *functionStack ) const
00814   {
00815     if ( !handlesField( field ) )
00816       return KMSearchRule::FuncNone;
00817 
00818     return currentFunction( functionStack );
00819   }
00820 
00821   //---------------------------------------------------------------------------
00822 
00823   QString MessageRuleWidgetHandler::currentValue( const QWidgetStack *valueStack,
00824                                                   KMSearchRule::Function ) const
00825   {
00826     const RegExpLineEdit *lineEdit =
00827       dynamic_cast<RegExpLineEdit*>( QObject_child_const( valueStack,
00828                                                           "regExpLineEdit" ) );
00829     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
00830     //  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00831     //                                                    0, false ) );
00832     if ( lineEdit ) {
00833       return lineEdit->text();
00834     }
00835     else
00836       kdDebug(5006) << "MessageRuleWidgetHandler::currentValue: "
00837                        "regExpLineEdit not found." << endl;
00838 
00839     return QString::null;
00840   }
00841 
00842   //---------------------------------------------------------------------------
00843 
00844   QString MessageRuleWidgetHandler::value( const QCString & field,
00845                                            const QWidgetStack *functionStack,
00846                                            const QWidgetStack *valueStack ) const
00847   {
00848     if ( !handlesField( field ) )
00849       return QString::null;
00850 
00851     KMSearchRule::Function func = currentFunction( functionStack );
00852     if ( func == KMSearchRule::FuncHasAttachment )
00853       return "has an attachment"; // just a non-empty dummy value
00854     else if ( func == KMSearchRule::FuncHasNoAttachment )
00855       return "has no attachment"; // just a non-empty dummy value
00856     else
00857       return currentValue( valueStack, func );
00858   }
00859 
00860   //---------------------------------------------------------------------------
00861 
00862   QString MessageRuleWidgetHandler::prettyValue( const QCString & field,
00863                                                  const QWidgetStack *functionStack,
00864                                                  const QWidgetStack *valueStack ) const
00865   {
00866     if ( !handlesField( field ) )
00867       return QString::null;
00868 
00869     KMSearchRule::Function func = currentFunction( functionStack );
00870     if ( func == KMSearchRule::FuncHasAttachment )
00871       return i18n( "has an attachment" );
00872     else if ( func == KMSearchRule::FuncHasNoAttachment )
00873       return i18n( "has no attachment" );
00874     else
00875       return currentValue( valueStack, func );
00876   }
00877 
00878   //---------------------------------------------------------------------------
00879 
00880   bool MessageRuleWidgetHandler::handlesField( const QCString & field ) const
00881   {
00882     return ( field == "<message>" );
00883   }
00884 
00885   //---------------------------------------------------------------------------
00886 
00887   void MessageRuleWidgetHandler::reset( QWidgetStack *functionStack,
00888                                         QWidgetStack *valueStack ) const
00889   {
00890     // reset the function combo box
00891     QComboBox *funcCombo =
00892       dynamic_cast<QComboBox*>( functionStack->child( "messageRuleFuncCombo",
00893                                                       0, false ) );
00894     if ( funcCombo ) {
00895       funcCombo->blockSignals( true );
00896       funcCombo->setCurrentItem( 0 );
00897       funcCombo->blockSignals( false );
00898     }
00899 
00900     // reset the value widget
00901     RegExpLineEdit *lineEdit =
00902       dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00903                                                         0, false ) );
00904     if ( lineEdit ) {
00905       lineEdit->blockSignals( true );
00906       lineEdit->clear();
00907       lineEdit->blockSignals( false );
00908       lineEdit->showEditButton( false );
00909       valueStack->raiseWidget( lineEdit );
00910     }
00911   }
00912 
00913   //---------------------------------------------------------------------------
00914 
00915   bool MessageRuleWidgetHandler::setRule( QWidgetStack *functionStack,
00916                                           QWidgetStack *valueStack,
00917                                           const KMSearchRule *rule ) const
00918   {
00919     if ( !rule || !handlesField( rule->field() ) ) {
00920       reset( functionStack, valueStack );
00921       return false;
00922     }
00923 
00924     const KMSearchRule::Function func = rule->function();
00925     int i = 0;
00926     for ( ; i < MessageFunctionCount; ++i )
00927       if ( func == MessageFunctions[i].id )
00928         break;
00929     QComboBox *funcCombo =
00930       dynamic_cast<QComboBox*>( functionStack->child( "messageRuleFuncCombo",
00931                                                       0, false ) );
00932     if ( funcCombo ) {
00933       funcCombo->blockSignals( true );
00934       if ( i < MessageFunctionCount )
00935         funcCombo->setCurrentItem( i );
00936       else {
00937         kdDebug(5006) << "MessageRuleWidgetHandler::setRule( "
00938                       << rule->asString()
00939                       << " ): unhandled function" << endl;
00940         funcCombo->setCurrentItem( 0 );
00941       }
00942       funcCombo->blockSignals( false );
00943       functionStack->raiseWidget( funcCombo );
00944     }
00945 
00946     if ( func == KMSearchRule::FuncHasAttachment  ||
00947          func == KMSearchRule::FuncHasNoAttachment ) {
00948       QWidget *w =
00949         static_cast<QWidget*>( valueStack->child( "textRuleValueHider",
00950                                                   0, false ) );
00951       valueStack->raiseWidget( w );
00952     }
00953     else {
00954       RegExpLineEdit *lineEdit =
00955         dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00956                                                           0, false ) );
00957       if ( lineEdit ) {
00958         lineEdit->blockSignals( true );
00959         lineEdit->setText( rule->contents() );
00960         lineEdit->blockSignals( false );
00961         lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
00962                                   func == KMSearchRule::FuncNotRegExp );
00963         valueStack->raiseWidget( lineEdit );
00964       }
00965     }
00966     return true;
00967   }
00968 
00969 
00970   //---------------------------------------------------------------------------
00971 
00972   bool MessageRuleWidgetHandler::update( const QCString & field,
00973                                       QWidgetStack *functionStack,
00974                                       QWidgetStack *valueStack ) const
00975   {
00976     if ( !handlesField( field ) )
00977       return false;
00978     // raise the correct function widget
00979     functionStack->raiseWidget(
00980       static_cast<QWidget*>( functionStack->child( "messageRuleFuncCombo",
00981                                                    0, false ) ) );
00982 
00983     // raise the correct value widget
00984     KMSearchRule::Function func = currentFunction( functionStack );
00985     if ( func == KMSearchRule::FuncHasAttachment  ||
00986          func == KMSearchRule::FuncHasNoAttachment ) {
00987       QWidget *w =
00988         static_cast<QWidget*>( valueStack->child( "textRuleValueHider",
00989                                                   0, false ) );
00990       valueStack->raiseWidget( w );
00991     }
00992     else {
00993       RegExpLineEdit *lineEdit =
00994         dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
00995                                                           0, false ) );
00996       if ( lineEdit ) {
00997         lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
00998                                   func == KMSearchRule::FuncNotRegExp );
00999         valueStack->raiseWidget( lineEdit );
01000       }
01001     }
01002     return true;
01003   }
01004 
01005 } // anonymous namespace for MessageRuleWidgetHandler
01006 
01007 
01008 //=============================================================================
01009 //
01010 // class StatusRuleWidgetHandler
01011 //
01012 //=============================================================================
01013 
01014 namespace {
01015   static const struct {
01016     const KMSearchRule::Function id;
01017     const char *displayName;
01018   } StatusFunctions[] = {
01019     { KMSearchRule::FuncContains,    I18N_NOOP( "is" )    },
01020     { KMSearchRule::FuncContainsNot, I18N_NOOP( "is not" ) }
01021   };
01022   static const int StatusFunctionCount =
01023     sizeof( StatusFunctions ) / sizeof( *StatusFunctions );
01024 
01025   //---------------------------------------------------------------------------
01026 
01027   QWidget * StatusRuleWidgetHandler::createFunctionWidget( int number,
01028                                                            QWidgetStack *functionStack,
01029                                                            const QObject *receiver ) const
01030   {
01031     if ( number != 0 )
01032       return 0;
01033 
01034     QComboBox *funcCombo = new QComboBox( functionStack,
01035                                           "statusRuleFuncCombo" );
01036     for ( int i = 0; i < StatusFunctionCount; ++i ) {
01037       funcCombo->insertItem( i18n( StatusFunctions[i].displayName ) );
01038     }
01039     funcCombo->adjustSize();
01040     QObject::connect( funcCombo, SIGNAL( activated( int ) ),
01041                       receiver, SLOT( slotFunctionChanged() ) );
01042     return funcCombo;
01043   }
01044 
01045   //---------------------------------------------------------------------------
01046 
01047   QWidget * StatusRuleWidgetHandler::createValueWidget( int number,
01048                                                         QWidgetStack *valueStack,
01049                                                         const QObject *receiver ) const
01050   {
01051     if ( number != 0 )
01052       return 0;
01053 
01054     QComboBox *statusCombo = new QComboBox( valueStack,
01055                                             "statusRuleValueCombo" );
01056     for ( int i = 0; i < KMail::StatusValueCountWithoutHidden; ++i ) {
01057       statusCombo->insertItem( i18n( KMail::StatusValues[i] ) );
01058     }
01059     statusCombo->adjustSize();
01060     QObject::connect( statusCombo, SIGNAL( activated( int ) ),
01061                       receiver, SLOT( slotValueChanged() ) );
01062     return statusCombo;
01063   }
01064 
01065   //---------------------------------------------------------------------------
01066 
01067   KMSearchRule::Function StatusRuleWidgetHandler::currentFunction( const QWidgetStack *functionStack ) const
01068   {
01069     const QComboBox *funcCombo =
01070       dynamic_cast<QComboBox*>( QObject_child_const( functionStack,
01071                                                      "statusRuleFuncCombo" ) );
01072     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
01073     //  dynamic_cast<QComboBox*>( functionStack->child( "statusRuleFuncCombo",
01074     //                                                  0, false ) );
01075     if ( funcCombo ) {
01076       return StatusFunctions[funcCombo->currentItem()].id;
01077     }
01078     else
01079       kdDebug(5006) << "StatusRuleWidgetHandler::currentFunction: "
01080                        "statusRuleFuncCombo not found." << endl;
01081     return KMSearchRule::FuncNone;
01082   }
01083 
01084   //---------------------------------------------------------------------------
01085 
01086   KMSearchRule::Function StatusRuleWidgetHandler::function( const QCString & field,
01087                                                             const QWidgetStack *functionStack ) const
01088   {
01089     if ( !handlesField( field ) )
01090       return KMSearchRule::FuncNone;
01091 
01092     return currentFunction( functionStack );
01093   }
01094 
01095   //---------------------------------------------------------------------------
01096 
01097   int StatusRuleWidgetHandler::currentStatusValue( const QWidgetStack *valueStack ) const
01098   {
01099     const QComboBox *statusCombo =
01100       dynamic_cast<QComboBox*>( QObject_child_const( valueStack,
01101                                                      "statusRuleValueCombo" ) );
01102     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
01103     //  dynamic_cast<QComboBox*>( valueStack->child( "statusRuleValueCombo",
01104     //                                               0, false ) );
01105     if ( statusCombo ) {
01106       return statusCombo->currentItem();
01107     }
01108     else
01109       kdDebug(5006) << "StatusRuleWidgetHandler::currentStatusValue: "
01110                        "statusRuleValueCombo not found." << endl;
01111     return -1;
01112   }
01113 
01114   //---------------------------------------------------------------------------
01115 
01116   QString StatusRuleWidgetHandler::value( const QCString & field,
01117                                           const QWidgetStack *,
01118                                           const QWidgetStack *valueStack ) const
01119   {
01120     if ( !handlesField( field ) )
01121       return QString::null;
01122 
01123     const int status = currentStatusValue( valueStack );
01124     if ( status != -1 )
01125       return QString::fromLatin1( KMail::StatusValues[status] );
01126     else
01127       return QString::null;
01128   }
01129 
01130   //---------------------------------------------------------------------------
01131 
01132   QString StatusRuleWidgetHandler::prettyValue( const QCString & field,
01133                                                 const QWidgetStack *,
01134                                                 const QWidgetStack *valueStack ) const
01135   {
01136     if ( !handlesField( field ) )
01137       return QString::null;
01138 
01139     const int status = currentStatusValue( valueStack );
01140     if ( status != -1 )
01141       return i18n( KMail::StatusValues[status] );
01142     else
01143       return QString::null;
01144   }
01145 
01146   //---------------------------------------------------------------------------
01147 
01148   bool StatusRuleWidgetHandler::handlesField( const QCString & field ) const
01149   {
01150     return ( field == "<status>" );
01151   }
01152 
01153   //---------------------------------------------------------------------------
01154 
01155   void StatusRuleWidgetHandler::reset( QWidgetStack *functionStack,
01156                                        QWidgetStack *valueStack ) const
01157   {
01158     // reset the function combo box
01159     QComboBox *funcCombo =
01160       dynamic_cast<QComboBox*>( functionStack->child( "statusRuleFuncCombo",
01161                                                       0, false ) );
01162     if ( funcCombo ) {
01163       funcCombo->blockSignals( true );
01164       funcCombo->setCurrentItem( 0 );
01165       funcCombo->blockSignals( false );
01166     }
01167 
01168     // reset the status value combo box
01169     QComboBox *statusCombo =
01170       dynamic_cast<QComboBox*>( valueStack->child( "statusRuleValueCombo",
01171                                                    0, false ) );
01172     if ( statusCombo ) {
01173       statusCombo->blockSignals( true );
01174       statusCombo->setCurrentItem( 0 );
01175       statusCombo->blockSignals( false );
01176     }
01177   }
01178 
01179   //---------------------------------------------------------------------------
01180 
01181   bool StatusRuleWidgetHandler::setRule( QWidgetStack *functionStack,
01182                                          QWidgetStack *valueStack,
01183                                          const KMSearchRule *rule ) const
01184   {
01185     if ( !rule || !handlesField( rule->field() ) ) {
01186       reset( functionStack, valueStack );
01187       return false;
01188     }
01189 
01190     // set the function
01191     const KMSearchRule::Function func = rule->function();
01192     int funcIndex = 0;
01193     for ( ; funcIndex < StatusFunctionCount; ++funcIndex )
01194       if ( func == StatusFunctions[funcIndex].id )
01195         break;
01196     QComboBox *funcCombo =
01197       dynamic_cast<QComboBox*>( functionStack->child( "statusRuleFuncCombo",
01198                                                       0, false ) );
01199     if ( funcCombo ) {
01200       funcCombo->blockSignals( true );
01201       if ( funcIndex < StatusFunctionCount )
01202         funcCombo->setCurrentItem( funcIndex );
01203       else {
01204         kdDebug(5006) << "StatusRuleWidgetHandler::setRule( "
01205                       << rule->asString()
01206                       << " ): unhandled function" << endl;
01207         funcCombo->setCurrentItem( 0 );
01208       }
01209       funcCombo->blockSignals( false );
01210       functionStack->raiseWidget( funcCombo );
01211     }
01212 
01213     // set the value
01214     const QString value = rule->contents();
01215     int valueIndex = 0;
01216     for ( ; valueIndex < KMail::StatusValueCountWithoutHidden; ++valueIndex )
01217       if ( value == QString::fromLatin1(
01218                KMail::StatusValues[valueIndex] ) )
01219         break;
01220     QComboBox *statusCombo =
01221       dynamic_cast<QComboBox*>( valueStack->child( "statusRuleValueCombo",
01222                                                    0, false ) );
01223     if ( statusCombo ) {
01224       statusCombo->blockSignals( true );
01225       if ( valueIndex < KMail::StatusValueCountWithoutHidden )
01226         statusCombo->setCurrentItem( valueIndex );
01227       else {
01228         kdDebug(5006) << "StatusRuleWidgetHandler::setRule( "
01229                       << rule->asString()
01230                       << " ): unhandled value" << endl;
01231         statusCombo->setCurrentItem( 0 );
01232       }
01233       statusCombo->blockSignals( false );
01234       valueStack->raiseWidget( statusCombo );
01235     }
01236     return true;
01237   }
01238 
01239 
01240   //---------------------------------------------------------------------------
01241 
01242   bool StatusRuleWidgetHandler::update( const QCString &field,
01243                                         QWidgetStack *functionStack,
01244                                         QWidgetStack *valueStack ) const
01245   {
01246     if ( !handlesField( field ) )
01247       return false;
01248 
01249     // raise the correct function widget
01250     functionStack->raiseWidget(
01251       static_cast<QWidget*>( functionStack->child( "statusRuleFuncCombo",
01252                                                    0, false ) ) );
01253 
01254     // raise the correct value widget
01255     valueStack->raiseWidget(
01256       static_cast<QWidget*>( valueStack->child( "statusRuleValueCombo",
01257                                                 0, false ) ) );
01258     return true;
01259   }
01260 
01261 } // anonymous namespace for StatusRuleWidgetHandler
01262 
01263 
01264 //=============================================================================
01265 //
01266 // class NumericRuleWidgetHandler
01267 //
01268 //=============================================================================
01269 
01270 namespace {
01271   static const struct {
01272     const KMSearchRule::Function id;
01273     const char *displayName;
01274   } NumericFunctions[] = {
01275     { KMSearchRule::FuncEquals,           I18N_NOOP( "is equal to" )         },
01276     { KMSearchRule::FuncNotEqual,         I18N_NOOP( "is not equal to" )      },
01277     { KMSearchRule::FuncIsGreater,        I18N_NOOP( "is greater than" )     },
01278     { KMSearchRule::FuncIsLessOrEqual,    I18N_NOOP( "is less than or equal to" ) },
01279     { KMSearchRule::FuncIsLess,           I18N_NOOP( "is less than" )        },
01280     { KMSearchRule::FuncIsGreaterOrEqual, I18N_NOOP( "is greater than or equal to" ) }
01281   };
01282   static const int NumericFunctionCount =
01283     sizeof( NumericFunctions ) / sizeof( *NumericFunctions );
01284 
01285   //---------------------------------------------------------------------------
01286 
01287   QWidget * NumericRuleWidgetHandler::createFunctionWidget( int number,
01288                                                             QWidgetStack *functionStack,
01289                                                             const QObject *receiver ) const
01290   {
01291     if ( number != 0 )
01292       return 0;
01293 
01294     QComboBox *funcCombo = new QComboBox( functionStack,
01295                                           "numericRuleFuncCombo" );
01296     for ( int i = 0; i < NumericFunctionCount; ++i ) {
01297       funcCombo->insertItem( i18n( NumericFunctions[i].displayName ) );
01298     }
01299     funcCombo->adjustSize();
01300     QObject::connect( funcCombo, SIGNAL( activated( int ) ),
01301                       receiver, SLOT( slotFunctionChanged() ) );
01302     return funcCombo;
01303   }
01304 
01305   //---------------------------------------------------------------------------
01306 
01307   QWidget * NumericRuleWidgetHandler::createValueWidget( int number,
01308                                                          QWidgetStack *valueStack,
01309                                                          const QObject *receiver ) const
01310   {
01311     if ( number != 0 )
01312       return 0;
01313 
01314     KIntNumInput *numInput = new KIntNumInput( valueStack, "KIntNumInput" );
01315     QObject::connect( numInput, SIGNAL( valueChanged( int ) ),
01316                       receiver, SLOT( slotValueChanged() ) );
01317     return numInput;
01318   }
01319 
01320   //---------------------------------------------------------------------------
01321 
01322   KMSearchRule::Function NumericRuleWidgetHandler::currentFunction( const QWidgetStack *functionStack ) const
01323   {
01324     const QComboBox *funcCombo =
01325       dynamic_cast<QComboBox*>( QObject_child_const( functionStack,
01326                                                      "numericRuleFuncCombo" ) );
01327     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
01328     //  dynamic_cast<QComboBox*>( functionStack->child( "numericRuleFuncCombo",
01329     //                                                  0, false ) );
01330     if ( funcCombo ) {
01331       return NumericFunctions[funcCombo->currentItem()].id;
01332     }
01333     else
01334       kdDebug(5006) << "NumericRuleWidgetHandler::currentFunction: "
01335                        "numericRuleFuncCombo not found." << endl;
01336     return KMSearchRule::FuncNone;
01337   }
01338 
01339   //---------------------------------------------------------------------------
01340 
01341   KMSearchRule::Function NumericRuleWidgetHandler::function( const QCString & field,
01342                                                              const QWidgetStack *functionStack ) const
01343   {
01344     if ( !handlesField( field ) )
01345       return KMSearchRule::FuncNone;
01346 
01347     return currentFunction( functionStack );
01348   }
01349 
01350   //---------------------------------------------------------------------------
01351 
01352   QString NumericRuleWidgetHandler::currentValue( const QWidgetStack *valueStack ) const
01353   {
01354     const KIntNumInput *numInput =
01355       dynamic_cast<KIntNumInput*>( QObject_child_const( valueStack,
01356                                                         "KIntNumInput" ) );
01357     // FIXME (Qt >= 4.0): Use the following when QObject::child() is const.
01358     //  dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
01359     //                                                  0, false ) );
01360     if ( numInput ) {
01361       return QString::number( numInput->value() );
01362     }
01363     else
01364       kdDebug(5006) << "NumericRuleWidgetHandler::currentValue: "
01365                        "KIntNumInput not found." << endl;
01366     return QString::null;
01367   }
01368 
01369   //---------------------------------------------------------------------------
01370 
01371   QString NumericRuleWidgetHandler::value( const QCString & field,
01372                                            const QWidgetStack *,
01373                                            const QWidgetStack *valueStack ) const
01374   {
01375     if ( !handlesField( field ) )
01376       return QString::null;
01377 
01378     return currentValue( valueStack );
01379   }
01380 
01381   //---------------------------------------------------------------------------
01382 
01383   QString NumericRuleWidgetHandler::prettyValue( const QCString & field,
01384                                                  const QWidgetStack *,
01385                                                  const QWidgetStack *valueStack ) const
01386   {
01387     if ( !handlesField( field ) )
01388       return QString::null;
01389 
01390     return currentValue( valueStack );
01391   }
01392 
01393   //---------------------------------------------------------------------------
01394 
01395   bool NumericRuleWidgetHandler::handlesField( const QCString & field ) const
01396   {
01397     return ( field == "<size>" || field == "<age in days>" );
01398   }
01399 
01400   //---------------------------------------------------------------------------
01401 
01402   void NumericRuleWidgetHandler::reset( QWidgetStack *functionStack,
01403                                         QWidgetStack *valueStack ) const
01404   {
01405     // reset the function combo box
01406     QComboBox *funcCombo =
01407       dynamic_cast<QComboBox*>( functionStack->child( "numericRuleFuncCombo",
01408                                                       0, false ) );
01409     if ( funcCombo ) {
01410       funcCombo->blockSignals( true );
01411       funcCombo->setCurrentItem( 0 );
01412       funcCombo->blockSignals( false );
01413     }
01414 
01415     // reset the value widget
01416     KIntNumInput *numInput =
01417       dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
01418                                                       0, false ) );
01419     if ( numInput ) {
01420       numInput->blockSignals( true );
01421       numInput->setValue( 0 );
01422       numInput->blockSignals( false );
01423     }
01424   }
01425 
01426   //---------------------------------------------------------------------------
01427 
01428   void initNumInput( KIntNumInput *numInput, const QCString &field )
01429   {
01430     if ( field == "<size>" ) {
01431       numInput->setMinValue( 0 );
01432       numInput->setSuffix( i18n( " bytes" ) );
01433     }
01434     else {
01435       numInput->setMinValue( -10000 );
01436       numInput->setSuffix( i18n( " days" ) );
01437     }
01438   }
01439 
01440   //---------------------------------------------------------------------------
01441 
01442   bool NumericRuleWidgetHandler::setRule( QWidgetStack *functionStack,
01443                                           QWidgetStack *valueStack,
01444                                           const KMSearchRule *rule ) const
01445   {
01446     if ( !rule || !handlesField( rule->field() ) ) {
01447       reset( functionStack, valueStack );
01448       return false;
01449     }
01450 
01451     // set the function
01452     const KMSearchRule::Function func = rule->function();
01453     int funcIndex = 0;
01454     for ( ; funcIndex < NumericFunctionCount; ++funcIndex )
01455       if ( func == NumericFunctions[funcIndex].id )
01456         break;
01457     QComboBox *funcCombo =
01458       dynamic_cast<QComboBox*>( functionStack->child( "numericRuleFuncCombo",
01459                                                       0, false ) );
01460     if ( funcCombo ) {
01461       funcCombo->blockSignals( true );
01462       if ( funcIndex < NumericFunctionCount )
01463         funcCombo->setCurrentItem( funcIndex );
01464       else {
01465         kdDebug(5006) << "NumericRuleWidgetHandler::setRule( "
01466                       << rule->asString()
01467                       << " ): unhandled function" << endl;
01468         funcCombo->setCurrentItem( 0 );
01469       }
01470       funcCombo->blockSignals( false );
01471       functionStack->raiseWidget( funcCombo );
01472     }
01473 
01474     // set the value
01475     bool ok;
01476     int value = rule->contents().toInt( &ok );
01477     if ( !ok )
01478       value = 0;
01479     KIntNumInput *numInput =
01480       dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
01481                                                       0, false ) );
01482     if ( numInput ) {
01483       initNumInput( numInput, rule->field() );
01484       numInput->blockSignals( true );
01485       numInput->setValue( value );
01486       numInput->blockSignals( false );
01487       valueStack->raiseWidget( numInput );
01488     }
01489     return true;
01490   }
01491 
01492 
01493   //---------------------------------------------------------------------------
01494 
01495   bool NumericRuleWidgetHandler::update( const QCString &field,
01496                                          QWidgetStack *functionStack,
01497                                          QWidgetStack *valueStack ) const
01498   {
01499     if ( !handlesField( field ) )
01500       return false;
01501 
01502     // raise the correct function widget
01503     functionStack->raiseWidget(
01504       static_cast<QWidget*>( functionStack->child( "numericRuleFuncCombo",
01505                                                    0, false ) ) );
01506 
01507     // raise the correct value widget
01508     KIntNumInput *numInput =
01509       dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
01510                                                       0, false ) );
01511     if ( numInput ) {
01512       initNumInput( numInput, field );
01513       valueStack->raiseWidget( numInput );
01514     }
01515     return true;
01516   }
01517 
01518 } // anonymous namespace for NumericRuleWidgetHandler
01519 
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Apr 4 06:44:26 2005 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003