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