kmail

rulewidgethandlermanager.cpp
1 /*
2  rulewidgethandlermanager.cpp
3 
4  This file is part of KMail, the KDE mail client.
5  Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
6 
7  KMail is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  KMail is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the TQt library by Trolltech AS, Norway (or with modified versions
24  of TQt that use the same license as TQt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  TQt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36 
37 #include "rulewidgethandlermanager.h"
38 
39 #include "interfaces/rulewidgethandler.h"
40 #include "stl_util.h"
41 
42 #include <kdebug.h>
43 #include <kiconloader.h>
44 
45 #include <tqwidgetstack.h>
46 #include <tqstring.h>
47 #include <tqcstring.h>
48 #include <tqobject.h>
49 #include <tqobjectlist.h>
50 
51 #include <assert.h>
52 
53 #include <algorithm>
54 using std::for_each;
55 using std::remove;
56 
57 KMail::RuleWidgetHandlerManager * KMail::RuleWidgetHandlerManager::self = 0;
58 
59 namespace {
60  class TextRuleWidgetHandler : public KMail::RuleWidgetHandler {
61  public:
62  TextRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
63  ~TextRuleWidgetHandler() {}
64 
65  TQWidget * createFunctionWidget( int number,
66  TQWidgetStack *functionStack,
67  const TQObject *receiver ) const;
68  TQWidget * createValueWidget( int number,
69  TQWidgetStack *valueStack,
70  const TQObject *receiver ) const;
71  KMSearchRule::Function function( const TQCString & field,
72  const TQWidgetStack *functionStack ) const;
73  TQString value( const TQCString & field,
74  const TQWidgetStack *functionStack,
75  const TQWidgetStack *valueStack ) const;
76  TQString prettyValue( const TQCString & field,
77  const TQWidgetStack *functionStack,
78  const TQWidgetStack *valueStack ) const;
79  bool handlesField( const TQCString & field ) const;
80  void reset( TQWidgetStack *functionStack,
81  TQWidgetStack *valueStack ) const;
82  bool setRule( TQWidgetStack *functionStack,
83  TQWidgetStack *valueStack,
84  const KMSearchRule *rule ) const;
85  bool update( const TQCString & field,
86  TQWidgetStack *functionStack,
87  TQWidgetStack *valueStack ) const;
88 
89  private:
90  KMSearchRule::Function currentFunction( const TQWidgetStack *functionStack ) const;
91  TQString currentValue( const TQWidgetStack *valueStack,
92  KMSearchRule::Function func ) const;
93  };
94 
95  class MessageRuleWidgetHandler : public KMail::RuleWidgetHandler {
96  public:
97  MessageRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
98  ~MessageRuleWidgetHandler() {}
99 
100  TQWidget * createFunctionWidget( int number,
101  TQWidgetStack *functionStack,
102  const TQObject *receiver ) const;
103  TQWidget * createValueWidget( int number,
104  TQWidgetStack *valueStack,
105  const TQObject *receiver ) const;
106  KMSearchRule::Function function( const TQCString & field,
107  const TQWidgetStack *functionStack ) const;
108  TQString value( const TQCString & field,
109  const TQWidgetStack *functionStack,
110  const TQWidgetStack *valueStack ) const;
111  TQString prettyValue( const TQCString & field,
112  const TQWidgetStack *functionStack,
113  const TQWidgetStack *valueStack ) const;
114  bool handlesField( const TQCString & field ) const;
115  void reset( TQWidgetStack *functionStack,
116  TQWidgetStack *valueStack ) const;
117  bool setRule( TQWidgetStack *functionStack,
118  TQWidgetStack *valueStack,
119  const KMSearchRule *rule ) const;
120  bool update( const TQCString & field,
121  TQWidgetStack *functionStack,
122  TQWidgetStack *valueStack ) const;
123 
124  private:
125  KMSearchRule::Function currentFunction( const TQWidgetStack *functionStack ) const;
126  TQString currentValue( const TQWidgetStack *valueStack,
127  KMSearchRule::Function func ) const;
128  };
129 
130 
131  class StatusRuleWidgetHandler : public KMail::RuleWidgetHandler {
132  public:
133  StatusRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
134  ~StatusRuleWidgetHandler() {}
135 
136  TQWidget * createFunctionWidget( int number,
137  TQWidgetStack *functionStack,
138  const TQObject *receiver ) const;
139  TQWidget * createValueWidget( int number,
140  TQWidgetStack *valueStack,
141  const TQObject *receiver ) const;
142  KMSearchRule::Function function( const TQCString & field,
143  const TQWidgetStack *functionStack ) const;
144  TQString value( const TQCString & field,
145  const TQWidgetStack *functionStack,
146  const TQWidgetStack *valueStack ) const;
147  TQString prettyValue( const TQCString & field,
148  const TQWidgetStack *functionStack,
149  const TQWidgetStack *valueStack ) const;
150  bool handlesField( const TQCString & field ) const;
151  void reset( TQWidgetStack *functionStack,
152  TQWidgetStack *valueStack ) const;
153  bool setRule( TQWidgetStack *functionStack,
154  TQWidgetStack *valueStack,
155  const KMSearchRule *rule ) const;
156  bool update( const TQCString & field,
157  TQWidgetStack *functionStack,
158  TQWidgetStack *valueStack ) const;
159 
160  private:
161  KMSearchRule::Function currentFunction( const TQWidgetStack *functionStack ) const;
162  int currenStatusValue( const TQWidgetStack *valueStack ) const;
163  };
164 
165  class NumericRuleWidgetHandler : public KMail::RuleWidgetHandler {
166  public:
167  NumericRuleWidgetHandler() : KMail::RuleWidgetHandler() {}
168  ~NumericRuleWidgetHandler() {}
169 
170  TQWidget * createFunctionWidget( int number,
171  TQWidgetStack *functionStack,
172  const TQObject *receiver ) const;
173  TQWidget * createValueWidget( int number,
174  TQWidgetStack *valueStack,
175  const TQObject *receiver ) const;
176  KMSearchRule::Function function( const TQCString & field,
177  const TQWidgetStack *functionStack ) const;
178  TQString value( const TQCString & field,
179  const TQWidgetStack *functionStack,
180  const TQWidgetStack *valueStack ) const;
181  TQString prettyValue( const TQCString & field,
182  const TQWidgetStack *functionStack,
183  const TQWidgetStack *valueStack ) const;
184  bool handlesField( const TQCString & field ) const;
185  void reset( TQWidgetStack *functionStack,
186  TQWidgetStack *valueStack ) const;
187  bool setRule( TQWidgetStack *functionStack,
188  TQWidgetStack *valueStack,
189  const KMSearchRule *rule ) const;
190  bool update( const TQCString & field,
191  TQWidgetStack *functionStack,
192  TQWidgetStack *valueStack ) const;
193 
194  private:
195  KMSearchRule::Function currentFunction( const TQWidgetStack *functionStack ) const;
196  TQString currentValue( const TQWidgetStack *valueStack ) const;
197  };
198 }
199 
200 KMail::RuleWidgetHandlerManager::RuleWidgetHandlerManager()
201 {
202  registerHandler( new NumericRuleWidgetHandler() );
203  registerHandler( new StatusRuleWidgetHandler() );
204  registerHandler( new MessageRuleWidgetHandler() );
205  // the TextRuleWidgetHandler is the fallback handler, so it has to be added
206  // as last handler
207  registerHandler( new TextRuleWidgetHandler() );
208 }
209 
210 KMail::RuleWidgetHandlerManager::~RuleWidgetHandlerManager()
211 {
212  for_each( mHandlers.begin(), mHandlers.end(),
213  DeleteAndSetToZero<RuleWidgetHandler>() );
214 }
215 
216 void KMail::RuleWidgetHandlerManager::registerHandler( const RuleWidgetHandler * handler )
217 {
218  if ( !handler )
219  return;
220  unregisterHandler( handler ); // don't produce duplicates
221  mHandlers.push_back( handler );
222 }
223 
224 void KMail::RuleWidgetHandlerManager::unregisterHandler( const RuleWidgetHandler * handler )
225 {
226  // don't delete them, only remove them from the list!
227  mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
228 }
229 
230 namespace {
234  int childCount( const TQObject *parent, const char *objName )
235  {
236  TQObjectList *list = parent->queryList( 0, objName, false, false );
237  if ( !list )
238  return 0;
239  const int count = list->count();
240  delete list; list = 0;
241  return count;
242  }
243 }
244 
245 void KMail::RuleWidgetHandlerManager::createWidgets( TQWidgetStack *functionStack,
246  TQWidgetStack *valueStack,
247  const TQObject *receiver ) const
248 {
249  for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
250  TQWidget *w = 0;
251  for ( int i = 0;
252  ( w = (*it)->createFunctionWidget( i, functionStack, receiver ) );
253  ++i ) {
254  if ( childCount( functionStack, w->name() ) < 2 ) {
255  // there wasn't already a widget with this name, so add this widget
256  functionStack->addWidget( w );
257  }
258  else {
259  // there was already a widget with this name, so discard this widget
260  kdDebug(5006) << "RuleWidgetHandlerManager::createWidgets: "
261  << w->name() << " already exists in functionStack"
262  << endl;
263  delete w; w = 0;
264  }
265  }
266  for ( int i = 0;
267  ( w = (*it)->createValueWidget( i, valueStack, receiver ) );
268  ++i ) {
269  if ( childCount( valueStack, w->name() ) < 2 ) {
270  // there wasn't already a widget with this name, so add this widget
271  valueStack->addWidget( w );
272  }
273  else {
274  // there was already a widget with this name, so discard this widget
275  kdDebug(5006) << "RuleWidgetHandlerManager::createWidgets: "
276  << w->name() << " already exists in valueStack"
277  << endl;
278  delete w; w = 0;
279  }
280  }
281  }
282 }
283 
284 KMSearchRule::Function KMail::RuleWidgetHandlerManager::function( const TQCString& field,
285  const TQWidgetStack *functionStack ) const
286 {
287  for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
288  const KMSearchRule::Function func = (*it)->function( field,
289  functionStack );
290  if ( func != KMSearchRule::FuncNone )
291  return func;
292  }
293  return KMSearchRule::FuncNone;
294 }
295 
296 TQString KMail::RuleWidgetHandlerManager::value( const TQCString& field,
297  const TQWidgetStack *functionStack,
298  const TQWidgetStack *valueStack ) const
299 {
300  for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
301  const TQString val = (*it)->value( field, functionStack, valueStack );
302  if ( !val.isEmpty() )
303  return val;
304  }
305  return TQString();
306 }
307 
308 TQString KMail::RuleWidgetHandlerManager::prettyValue( const TQCString& field,
309  const TQWidgetStack *functionStack,
310  const TQWidgetStack *valueStack ) const
311 {
312  for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
313  const TQString val = (*it)->prettyValue( field, functionStack, valueStack );
314  if ( !val.isEmpty() )
315  return val;
316  }
317  return TQString();
318 }
319 
320 void KMail::RuleWidgetHandlerManager::reset( TQWidgetStack *functionStack,
321  TQWidgetStack *valueStack ) const
322 {
323  for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
324  (*it)->reset( functionStack, valueStack );
325  }
326  update( "", functionStack, valueStack );
327 }
328 
329 void KMail::RuleWidgetHandlerManager::setRule( TQWidgetStack *functionStack,
330  TQWidgetStack *valueStack,
331  const KMSearchRule *rule ) const
332 {
333  assert( rule );
334  reset( functionStack, valueStack );
335  for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
336  if ( (*it)->setRule( functionStack, valueStack, rule ) )
337  return;
338  }
339 }
340 
341 void KMail::RuleWidgetHandlerManager::update( const TQCString &field,
342  TQWidgetStack *functionStack,
343  TQWidgetStack *valueStack ) const
344 {
345  //kdDebug(5006) << "RuleWidgetHandlerManager::update( \"" << field
346  // << "\", ... )" << endl;
347  for ( const_iterator it = mHandlers.begin(); it != mHandlers.end(); ++it ) {
348  if ( (*it)->update( field, functionStack, valueStack ) )
349  return;
350  }
351 }
352 
353 //-----------------------------------------------------------------------------
354 
355 namespace {
356  // FIXME (TQt >= 4.0):
357  // This is a simplified and constified copy of TQObject::child(). According
358  // to a comment in tqobject.h TQObject::child() will be made const in TQt 4.0.
359  // So once we require TQt 4.0 this can be removed.
360  TQObject* TQObject_child_const( const TQObject *parent,
361  const char *objName )
362  {
363  const TQObjectList list = parent->childrenListObject();
364  if ( list.isEmpty() )
365  return 0;
366 
367  TQObjectListIterator it( list );
368  TQObject *obj;
369  while ( ( obj = it.current() ) ) {
370  ++it;
371  if ( !objName || qstrcmp( objName, obj->name() ) == 0 )
372  break;
373  }
374  return obj;
375  }
376 }
377 
378 //-----------------------------------------------------------------------------
379 
380 // these includes are temporary and should not be needed for the code
381 // above this line, so they appear only here:
382 #include "kmaddrbook.h"
383 #include "kmsearchpattern.h"
384 #include "regexplineedit.h"
385 using KMail::RegExpLineEdit;
386 
387 #include <tdelocale.h>
388 #include <knuminput.h>
389 
390 #include <tqcombobox.h>
391 #include <tqlabel.h>
392 
393 //=============================================================================
394 //
395 // class TextRuleWidgetHandler
396 //
397 //=============================================================================
398 
399 namespace {
400  // also see KMSearchRule::matches() and KMSearchRule::Function
401  // if you change the following strings!
402  static const struct {
403  const KMSearchRule::Function id;
404  const char *displayName;
405  } TextFunctions[] = {
406  { KMSearchRule::FuncContains, I18N_NOOP( "contains" ) },
407  { KMSearchRule::FuncContainsNot, I18N_NOOP( "does not contain" ) },
408  { KMSearchRule::FuncEquals, I18N_NOOP( "equals" ) },
409  { KMSearchRule::FuncNotEqual, I18N_NOOP( "does not equal" ) },
410  { KMSearchRule::FuncRegExp, I18N_NOOP( "matches regular expr." ) },
411  { KMSearchRule::FuncNotRegExp, I18N_NOOP( "does not match reg. expr." ) },
412  { KMSearchRule::FuncIsInAddressbook, I18N_NOOP( "is in address book" ) },
413  { KMSearchRule::FuncIsNotInAddressbook, I18N_NOOP( "is not in address book" ) },
414  { KMSearchRule::FuncIsInCategory, I18N_NOOP( "is in category" ) },
415  { KMSearchRule::FuncIsNotInCategory, I18N_NOOP( "is not in category" ) }
416  };
417  static const int TextFunctionCount =
418  sizeof( TextFunctions ) / sizeof( *TextFunctions );
419 
420  //---------------------------------------------------------------------------
421 
422  TQWidget * TextRuleWidgetHandler::createFunctionWidget( int number,
423  TQWidgetStack *functionStack,
424  const TQObject *receiver ) const
425  {
426  if ( number != 0 )
427  return 0;
428 
429  TQComboBox *funcCombo = new TQComboBox( functionStack, "textRuleFuncCombo" );
430  for ( int i = 0; i < TextFunctionCount; ++i ) {
431  funcCombo->insertItem( i18n( TextFunctions[i].displayName ) );
432  }
433  funcCombo->adjustSize();
434  TQObject::connect( funcCombo, TQ_SIGNAL( activated( int ) ),
435  receiver, TQ_SLOT( slotFunctionChanged() ) );
436  return funcCombo;
437  }
438 
439  //---------------------------------------------------------------------------
440 
441  TQWidget * TextRuleWidgetHandler::createValueWidget( int number,
442  TQWidgetStack *valueStack,
443  const TQObject *receiver ) const
444  {
445  if ( number == 0 ) {
446  RegExpLineEdit *lineEdit =
447  new RegExpLineEdit( valueStack, "regExpLineEdit" );
448  TQObject::connect( lineEdit, TQ_SIGNAL( textChanged( const TQString & ) ),
449  receiver, TQ_SLOT( slotValueChanged() ) );
450  return lineEdit;
451  }
452 
453  // blank TQLabel to hide value widget for in-address-book rule
454  if ( number == 1 ) {
455  return new TQLabel( valueStack, "textRuleValueHider" );
456  }
457 
458  if ( number == 2 ) {
459  TQComboBox *combo = new TQComboBox( valueStack, "categoryCombo" );
460  TQStringList categories = KabcBridge::categories();
461  combo->insertStringList( categories );
462  TQObject::connect( combo, TQ_SIGNAL( activated( int ) ),
463  receiver, TQ_SLOT( slotValueChanged() ) );
464  return combo;
465  }
466 
467  return 0;
468  }
469 
470  //---------------------------------------------------------------------------
471 
472  KMSearchRule::Function TextRuleWidgetHandler::currentFunction( const TQWidgetStack *functionStack ) const
473  {
474  const TQComboBox *funcCombo =
475  dynamic_cast<TQComboBox*>( TQObject_child_const( functionStack,
476  "textRuleFuncCombo" ) );
477  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
478  // dynamic_cast<TQComboBox*>( functionStack->child( "textRuleFuncCombo",
479  // 0, false ) );
480  if ( funcCombo ) {
481  return TextFunctions[funcCombo->currentItem()].id;
482  }
483  else
484  kdDebug(5006) << "TextRuleWidgetHandler::currentFunction: "
485  "textRuleFuncCombo not found." << endl;
486  return KMSearchRule::FuncNone;
487  }
488 
489  //---------------------------------------------------------------------------
490 
491  KMSearchRule::Function TextRuleWidgetHandler::function( const TQCString &,
492  const TQWidgetStack *functionStack ) const
493  {
494  return currentFunction( functionStack );
495  }
496 
497  //---------------------------------------------------------------------------
498 
499  TQString TextRuleWidgetHandler::currentValue( const TQWidgetStack *valueStack,
500  KMSearchRule::Function func ) const
501  {
502  // here we gotta check the combobox which contains the categories
503  if ( func == KMSearchRule::FuncIsInCategory ||
504  func == KMSearchRule::FuncIsNotInCategory ) {
505  const TQComboBox *combo=
506  dynamic_cast<TQComboBox*>( TQObject_child_const( valueStack,
507  "categoryCombo" ) );
508  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
509  // dynamic_cast<TQComboBox*>( valueStack->child( "categoryCombo",
510  // 0, false ) );
511  if ( combo ) {
512  return combo->currentText();
513  }
514  else {
515  kdDebug(5006) << "TextRuleWidgetHandler::currentValue: "
516  "categoryCombo not found." << endl;
517  return TQString();
518  }
519  }
520 
521  //in other cases of func it is a lineedit
522  const RegExpLineEdit *lineEdit =
523  dynamic_cast<RegExpLineEdit*>( TQObject_child_const( valueStack,
524  "regExpLineEdit" ) );
525  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
526  // dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
527  // 0, false ) );
528  if ( lineEdit ) {
529  return lineEdit->text();
530  }
531  else
532  kdDebug(5006) << "TextRuleWidgetHandler::currentValue: "
533  "regExpLineEdit not found." << endl;
534 
535  // or anything else, like addressbook
536  return TQString();
537  }
538 
539  //---------------------------------------------------------------------------
540 
541  TQString TextRuleWidgetHandler::value( const TQCString &,
542  const TQWidgetStack *functionStack,
543  const TQWidgetStack *valueStack ) const
544  {
545  KMSearchRule::Function func = currentFunction( functionStack );
546  if ( func == KMSearchRule::FuncIsInAddressbook )
547  return "is in address book"; // just a non-empty dummy value
548  else if ( func == KMSearchRule::FuncIsNotInAddressbook )
549  return "is not in address book"; // just a non-empty dummy value
550  else
551  return currentValue( valueStack, func );
552  }
553 
554  //---------------------------------------------------------------------------
555 
556  TQString TextRuleWidgetHandler::prettyValue( const TQCString &,
557  const TQWidgetStack *functionStack,
558  const TQWidgetStack *valueStack ) const
559  {
560  KMSearchRule::Function func = currentFunction( functionStack );
561  if ( func == KMSearchRule::FuncIsInAddressbook )
562  return i18n( "is in address book" );
563  else if ( func == KMSearchRule::FuncIsNotInAddressbook )
564  return i18n( "is not in address book" );
565  else
566  return currentValue( valueStack, func );
567  }
568 
569  //---------------------------------------------------------------------------
570 
571  bool TextRuleWidgetHandler::handlesField( const TQCString & ) const
572  {
573  return true; // we handle all fields (as fallback)
574  }
575 
576  //---------------------------------------------------------------------------
577 
578  void TextRuleWidgetHandler::reset( TQWidgetStack *functionStack,
579  TQWidgetStack *valueStack ) const
580  {
581  // reset the function combo box
582  TQComboBox *funcCombo =
583  dynamic_cast<TQComboBox*>( functionStack->child( "textRuleFuncCombo",
584  0, false ) );
585  if ( funcCombo ) {
586  funcCombo->blockSignals( true );
587  funcCombo->setCurrentItem( 0 );
588  funcCombo->blockSignals( false );
589  }
590 
591  // reset the value widget
592  RegExpLineEdit *lineEdit =
593  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
594  0, false ) );
595  if ( lineEdit ) {
596  lineEdit->blockSignals( true );
597  lineEdit->clear();
598  lineEdit->blockSignals( false );
599  lineEdit->showEditButton( false );
600  valueStack->raiseWidget( lineEdit );
601  }
602 
603  TQComboBox *combo =
604  dynamic_cast<TQComboBox*>( valueStack->child( "categoryCombo",
605  0, false ) );
606  if (combo) {
607  combo->blockSignals( true );
608  combo->setCurrentItem( 0 );
609  combo->blockSignals( false );
610  }
611  }
612 
613  //---------------------------------------------------------------------------
614 
615  bool TextRuleWidgetHandler::setRule( TQWidgetStack *functionStack,
616  TQWidgetStack *valueStack,
617  const KMSearchRule *rule ) const
618  {
619  if ( !rule ) {
620  reset( functionStack, valueStack );
621  return false;
622  }
623 
624  const KMSearchRule::Function func = rule->function();
625  int i = 0;
626  for ( ; i < TextFunctionCount; ++i )
627  if ( func == TextFunctions[i].id )
628  break;
629  TQComboBox *funcCombo =
630  dynamic_cast<TQComboBox*>( functionStack->child( "textRuleFuncCombo",
631  0, false ) );
632  if ( funcCombo ) {
633  funcCombo->blockSignals( true );
634  if ( i < TextFunctionCount )
635  funcCombo->setCurrentItem( i );
636  else {
637  kdDebug(5006) << "TextRuleWidgetHandler::setRule( "
638  << rule->asString()
639  << " ): unhandled function" << endl;
640  funcCombo->setCurrentItem( 0 );
641  }
642  funcCombo->blockSignals( false );
643  functionStack->raiseWidget( funcCombo );
644  }
645 
646  if ( func == KMSearchRule::FuncIsInAddressbook ||
647  func == KMSearchRule::FuncIsNotInAddressbook ) {
648  TQWidget *w =
649  static_cast<TQWidget*>( valueStack->child( "textRuleValueHider",
650  0, false ) );
651  valueStack->raiseWidget( w );
652  }
653  else if ( func == KMSearchRule::FuncIsInCategory ||
654  func == KMSearchRule::FuncIsNotInCategory) {
655  TQComboBox *combo =
656  static_cast<TQComboBox*>( static_cast<TQWidget*>(valueStack->child( "categoryCombo",
657  0, false )) );
658  combo->blockSignals( true );
659  for ( i = 0; i < combo->count(); ++i )
660  if ( rule->contents() == combo->text( i ) ) {
661  combo->setCurrentItem( i );
662  break;
663  }
664  if ( i == combo->count() )
665  combo->setCurrentItem( 0 );
666 
667  combo->blockSignals( false );
668  valueStack->raiseWidget( combo );
669  }
670  else {
671  RegExpLineEdit *lineEdit =
672  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
673  0, false ) );
674  if ( lineEdit ) {
675  lineEdit->blockSignals( true );
676  lineEdit->setText( rule->contents() );
677  lineEdit->blockSignals( false );
678  lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
679  func == KMSearchRule::FuncNotRegExp );
680  valueStack->raiseWidget( lineEdit );
681  }
682  }
683  return true;
684  }
685 
686 
687  //---------------------------------------------------------------------------
688 
689  bool TextRuleWidgetHandler::update( const TQCString &,
690  TQWidgetStack *functionStack,
691  TQWidgetStack *valueStack ) const
692  {
693  // raise the correct function widget
694  functionStack->raiseWidget(
695  static_cast<TQWidget*>( functionStack->child( "textRuleFuncCombo",
696  0, false ) ) );
697 
698  // raise the correct value widget
699  KMSearchRule::Function func = currentFunction( functionStack );
700  if ( func == KMSearchRule::FuncIsInAddressbook ||
701  func == KMSearchRule::FuncIsNotInAddressbook ) {
702  valueStack->raiseWidget(
703  static_cast<TQWidget*>( valueStack->child( "textRuleValueHider",
704  0, false ) ) );
705  }
706  else if ( func == KMSearchRule::FuncIsInCategory ||
707  func == KMSearchRule::FuncIsNotInCategory) {
708  valueStack->raiseWidget(
709  static_cast<TQWidget*>( valueStack->child( "categoryCombo",
710  0, false ) ) );
711  }
712  else {
713  RegExpLineEdit *lineEdit =
714  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
715  0, false ) );
716  if ( lineEdit ) {
717  lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
718  func == KMSearchRule::FuncNotRegExp );
719  valueStack->raiseWidget( lineEdit );
720  }
721  }
722  return true;
723  }
724 
725 } // anonymous namespace for TextRuleWidgetHandler
726 
727 
728 //=============================================================================
729 //
730 // class MessageRuleWidgetHandler
731 //
732 //=============================================================================
733 
734 namespace {
735  // also see KMSearchRule::matches() and KMSearchRule::Function
736  // if you change the following strings!
737  static const struct {
738  const KMSearchRule::Function id;
739  const char *displayName;
740  } MessageFunctions[] = {
741  { KMSearchRule::FuncContains, I18N_NOOP( "contains" ) },
742  { KMSearchRule::FuncContainsNot, I18N_NOOP( "does not contain" ) },
743  { KMSearchRule::FuncRegExp, I18N_NOOP( "matches regular expr." ) },
744  { KMSearchRule::FuncNotRegExp, I18N_NOOP( "does not match reg. expr." ) },
745  { KMSearchRule::FuncHasAttachment, I18N_NOOP( "has an attachment" ) },
746  { KMSearchRule::FuncHasNoAttachment, I18N_NOOP( "has no attachment" ) },
747  };
748  static const int MessageFunctionCount =
749  sizeof( MessageFunctions ) / sizeof( *MessageFunctions );
750 
751  //---------------------------------------------------------------------------
752 
753  TQWidget * MessageRuleWidgetHandler::createFunctionWidget( int number,
754  TQWidgetStack *functionStack,
755  const TQObject *receiver ) const
756  {
757  if ( number != 0 )
758  return 0;
759 
760  TQComboBox *funcCombo = new TQComboBox( functionStack, "messageRuleFuncCombo" );
761  for ( int i = 0; i < MessageFunctionCount; ++i ) {
762  funcCombo->insertItem( i18n( MessageFunctions[i].displayName ) );
763  }
764  funcCombo->adjustSize();
765  TQObject::connect( funcCombo, TQ_SIGNAL( activated( int ) ),
766  receiver, TQ_SLOT( slotFunctionChanged() ) );
767  return funcCombo;
768  }
769 
770  //---------------------------------------------------------------------------
771 
772  TQWidget * MessageRuleWidgetHandler::createValueWidget( int number,
773  TQWidgetStack *valueStack,
774  const TQObject *receiver ) const
775  {
776  if ( number == 0 ) {
777  RegExpLineEdit *lineEdit =
778  new RegExpLineEdit( valueStack, "regExpLineEdit" );
779  TQObject::connect( lineEdit, TQ_SIGNAL( textChanged( const TQString & ) ),
780  receiver, TQ_SLOT( slotValueChanged() ) );
781  return lineEdit;
782  }
783 
784  // blank TQLabel to hide value widget for has-attachment rule
785  if ( number == 1 ) {
786  return new TQLabel( valueStack, "textRuleValueHider" );
787  }
788 
789  return 0;
790  }
791 
792  //---------------------------------------------------------------------------
793 
794  KMSearchRule::Function MessageRuleWidgetHandler::currentFunction( const TQWidgetStack *functionStack ) const
795  {
796  const TQComboBox *funcCombo =
797  dynamic_cast<TQComboBox*>( TQObject_child_const( functionStack,
798  "messageRuleFuncCombo" ) );
799  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
800  // dynamic_cast<TQComboBox*>( functionStack->child( "messageRuleFuncCombo",
801  // 0, false ) );
802  if ( funcCombo ) {
803  return MessageFunctions[funcCombo->currentItem()].id;
804  }
805  else
806  kdDebug(5006) << "MessageRuleWidgetHandler::currentFunction: "
807  "messageRuleFuncCombo not found." << endl;
808  return KMSearchRule::FuncNone;
809  }
810 
811  //---------------------------------------------------------------------------
812 
813  KMSearchRule::Function MessageRuleWidgetHandler::function( const TQCString & field,
814  const TQWidgetStack *functionStack ) const
815  {
816  if ( !handlesField( field ) )
817  return KMSearchRule::FuncNone;
818 
819  return currentFunction( functionStack );
820  }
821 
822  //---------------------------------------------------------------------------
823 
824  TQString MessageRuleWidgetHandler::currentValue( const TQWidgetStack *valueStack,
825  KMSearchRule::Function ) const
826  {
827  const RegExpLineEdit *lineEdit =
828  dynamic_cast<RegExpLineEdit*>( TQObject_child_const( valueStack,
829  "regExpLineEdit" ) );
830  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
831  // dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
832  // 0, false ) );
833  if ( lineEdit ) {
834  return lineEdit->text();
835  }
836  else
837  kdDebug(5006) << "MessageRuleWidgetHandler::currentValue: "
838  "regExpLineEdit not found." << endl;
839 
840  return TQString();
841  }
842 
843  //---------------------------------------------------------------------------
844 
845  TQString MessageRuleWidgetHandler::value( const TQCString & field,
846  const TQWidgetStack *functionStack,
847  const TQWidgetStack *valueStack ) const
848  {
849  if ( !handlesField( field ) )
850  return TQString();
851 
852  KMSearchRule::Function func = currentFunction( functionStack );
853  if ( func == KMSearchRule::FuncHasAttachment )
854  return "has an attachment"; // just a non-empty dummy value
855  else if ( func == KMSearchRule::FuncHasNoAttachment )
856  return "has no attachment"; // just a non-empty dummy value
857  else
858  return currentValue( valueStack, func );
859  }
860 
861  //---------------------------------------------------------------------------
862 
863  TQString MessageRuleWidgetHandler::prettyValue( const TQCString & field,
864  const TQWidgetStack *functionStack,
865  const TQWidgetStack *valueStack ) const
866  {
867  if ( !handlesField( field ) )
868  return TQString();
869 
870  KMSearchRule::Function func = currentFunction( functionStack );
871  if ( func == KMSearchRule::FuncHasAttachment )
872  return i18n( "has an attachment" );
873  else if ( func == KMSearchRule::FuncHasNoAttachment )
874  return i18n( "has no attachment" );
875  else
876  return currentValue( valueStack, func );
877  }
878 
879  //---------------------------------------------------------------------------
880 
881  bool MessageRuleWidgetHandler::handlesField( const TQCString & field ) const
882  {
883  return ( field == "<message>" );
884  }
885 
886  //---------------------------------------------------------------------------
887 
888  void MessageRuleWidgetHandler::reset( TQWidgetStack *functionStack,
889  TQWidgetStack *valueStack ) const
890  {
891  // reset the function combo box
892  TQComboBox *funcCombo =
893  dynamic_cast<TQComboBox*>( functionStack->child( "messageRuleFuncCombo",
894  0, false ) );
895  if ( funcCombo ) {
896  funcCombo->blockSignals( true );
897  funcCombo->setCurrentItem( 0 );
898  funcCombo->blockSignals( false );
899  }
900 
901  // reset the value widget
902  RegExpLineEdit *lineEdit =
903  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
904  0, false ) );
905  if ( lineEdit ) {
906  lineEdit->blockSignals( true );
907  lineEdit->clear();
908  lineEdit->blockSignals( false );
909  lineEdit->showEditButton( false );
910  valueStack->raiseWidget( lineEdit );
911  }
912  }
913 
914  //---------------------------------------------------------------------------
915 
916  bool MessageRuleWidgetHandler::setRule( TQWidgetStack *functionStack,
917  TQWidgetStack *valueStack,
918  const KMSearchRule *rule ) const
919  {
920  if ( !rule || !handlesField( rule->field() ) ) {
921  reset( functionStack, valueStack );
922  return false;
923  }
924 
925  const KMSearchRule::Function func = rule->function();
926  int i = 0;
927  for ( ; i < MessageFunctionCount; ++i )
928  if ( func == MessageFunctions[i].id )
929  break;
930  TQComboBox *funcCombo =
931  dynamic_cast<TQComboBox*>( functionStack->child( "messageRuleFuncCombo",
932  0, false ) );
933  if ( funcCombo ) {
934  funcCombo->blockSignals( true );
935  if ( i < MessageFunctionCount )
936  funcCombo->setCurrentItem( i );
937  else {
938  kdDebug(5006) << "MessageRuleWidgetHandler::setRule( "
939  << rule->asString()
940  << " ): unhandled function" << endl;
941  funcCombo->setCurrentItem( 0 );
942  }
943  funcCombo->blockSignals( false );
944  functionStack->raiseWidget( funcCombo );
945  }
946 
947  if ( func == KMSearchRule::FuncHasAttachment ||
948  func == KMSearchRule::FuncHasNoAttachment ) {
949  TQWidget *w =
950  static_cast<TQWidget*>( valueStack->child( "textRuleValueHider",
951  0, false ) );
952  valueStack->raiseWidget( w );
953  }
954  else {
955  RegExpLineEdit *lineEdit =
956  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
957  0, false ) );
958  if ( lineEdit ) {
959  lineEdit->blockSignals( true );
960  lineEdit->setText( rule->contents() );
961  lineEdit->blockSignals( false );
962  lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
963  func == KMSearchRule::FuncNotRegExp );
964  valueStack->raiseWidget( lineEdit );
965  }
966  }
967  return true;
968  }
969 
970 
971  //---------------------------------------------------------------------------
972 
973  bool MessageRuleWidgetHandler::update( const TQCString & field,
974  TQWidgetStack *functionStack,
975  TQWidgetStack *valueStack ) const
976  {
977  if ( !handlesField( field ) )
978  return false;
979  // raise the correct function widget
980  functionStack->raiseWidget(
981  static_cast<TQWidget*>( functionStack->child( "messageRuleFuncCombo",
982  0, false ) ) );
983 
984  // raise the correct value widget
985  KMSearchRule::Function func = currentFunction( functionStack );
986  if ( func == KMSearchRule::FuncHasAttachment ||
987  func == KMSearchRule::FuncHasNoAttachment ) {
988  TQWidget *w =
989  static_cast<TQWidget*>( valueStack->child( "textRuleValueHider",
990  0, false ) );
991  valueStack->raiseWidget( w );
992  }
993  else {
994  RegExpLineEdit *lineEdit =
995  dynamic_cast<RegExpLineEdit*>( valueStack->child( "regExpLineEdit",
996  0, false ) );
997  if ( lineEdit ) {
998  lineEdit->showEditButton( func == KMSearchRule::FuncRegExp ||
999  func == KMSearchRule::FuncNotRegExp );
1000  valueStack->raiseWidget( lineEdit );
1001  }
1002  }
1003  return true;
1004  }
1005 
1006 } // anonymous namespace for MessageRuleWidgetHandler
1007 
1008 
1009 //=============================================================================
1010 //
1011 // class StatusRuleWidgetHandler
1012 //
1013 //=============================================================================
1014 
1015 namespace {
1016  static const struct {
1017  const KMSearchRule::Function id;
1018  const char *displayName;
1019  } StatusFunctions[] = {
1020  { KMSearchRule::FuncContains, I18N_NOOP( "is" ) },
1021  { KMSearchRule::FuncContainsNot, I18N_NOOP( "is not" ) }
1022  };
1023  static const int StatusFunctionCount =
1024  sizeof( StatusFunctions ) / sizeof( *StatusFunctions );
1025 
1026  //---------------------------------------------------------------------------
1027 
1028  TQWidget * StatusRuleWidgetHandler::createFunctionWidget( int number,
1029  TQWidgetStack *functionStack,
1030  const TQObject *receiver ) const
1031  {
1032  if ( number != 0 )
1033  return 0;
1034 
1035  TQComboBox *funcCombo = new TQComboBox( functionStack,
1036  "statusRuleFuncCombo" );
1037  for ( int i = 0; i < StatusFunctionCount; ++i ) {
1038  funcCombo->insertItem( i18n( StatusFunctions[i].displayName ) );
1039  }
1040  funcCombo->adjustSize();
1041  TQObject::connect( funcCombo, TQ_SIGNAL( activated( int ) ),
1042  receiver, TQ_SLOT( slotFunctionChanged() ) );
1043  return funcCombo;
1044  }
1045 
1046  //---------------------------------------------------------------------------
1047 
1048  TQWidget * StatusRuleWidgetHandler::createValueWidget( int number,
1049  TQWidgetStack *valueStack,
1050  const TQObject *receiver ) const
1051  {
1052  if ( number != 0 )
1053  return 0;
1054 
1055  TQComboBox *statusCombo = new TQComboBox( valueStack,
1056  "statusRuleValueCombo" );
1057  for ( int i = 0; i < KMail::StatusValueCountWithoutHidden; ++i ) {
1058  statusCombo->insertItem( UserIcon( KMail::StatusValues[ i ].icon ), i18n( KMail::StatusValues[ i ].text ) );
1059  }
1060  statusCombo->adjustSize();
1061  TQObject::connect( statusCombo, TQ_SIGNAL( activated( int ) ),
1062  receiver, TQ_SLOT( slotValueChanged() ) );
1063  return statusCombo;
1064  }
1065 
1066  //---------------------------------------------------------------------------
1067 
1068  KMSearchRule::Function StatusRuleWidgetHandler::currentFunction( const TQWidgetStack *functionStack ) const
1069  {
1070  const TQComboBox *funcCombo =
1071  dynamic_cast<TQComboBox*>( TQObject_child_const( functionStack,
1072  "statusRuleFuncCombo" ) );
1073  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
1074  // dynamic_cast<TQComboBox*>( functionStack->child( "statusRuleFuncCombo",
1075  // 0, false ) );
1076  if ( funcCombo ) {
1077  return StatusFunctions[funcCombo->currentItem()].id;
1078  }
1079  else
1080  kdDebug(5006) << "StatusRuleWidgetHandler::currentFunction: "
1081  "statusRuleFuncCombo not found." << endl;
1082  return KMSearchRule::FuncNone;
1083  }
1084 
1085  //---------------------------------------------------------------------------
1086 
1087  KMSearchRule::Function StatusRuleWidgetHandler::function( const TQCString & field,
1088  const TQWidgetStack *functionStack ) const
1089  {
1090  if ( !handlesField( field ) )
1091  return KMSearchRule::FuncNone;
1092 
1093  return currentFunction( functionStack );
1094  }
1095 
1096  //---------------------------------------------------------------------------
1097 
1098  int StatusRuleWidgetHandler::currenStatusValue( const TQWidgetStack *valueStack ) const
1099  {
1100  const TQComboBox *statusCombo =
1101  dynamic_cast<TQComboBox*>( TQObject_child_const( valueStack,
1102  "statusRuleValueCombo" ) );
1103  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
1104  // dynamic_cast<TQComboBox*>( valueStack->child( "statusRuleValueCombo",
1105  // 0, false ) );
1106  if ( statusCombo ) {
1107  return statusCombo->currentItem();
1108  }
1109  else
1110  kdDebug(5006) << "StatusRuleWidgetHandler::currenStatusValue: "
1111  "statusRuleValueCombo not found." << endl;
1112  return -1;
1113  }
1114 
1115  //---------------------------------------------------------------------------
1116 
1117  TQString StatusRuleWidgetHandler::value( const TQCString & field,
1118  const TQWidgetStack *,
1119  const TQWidgetStack *valueStack ) const
1120  {
1121  if ( !handlesField( field ) )
1122  return TQString();
1123 
1124  const int status = currenStatusValue( valueStack );
1125  if ( status != -1 )
1126  return TQString::fromLatin1( KMail::StatusValues[ status ].text );
1127  else
1128  return TQString();
1129  }
1130 
1131  //---------------------------------------------------------------------------
1132 
1133  TQString StatusRuleWidgetHandler::prettyValue( const TQCString & field,
1134  const TQWidgetStack *,
1135  const TQWidgetStack *valueStack ) const
1136  {
1137  if ( !handlesField( field ) )
1138  return TQString();
1139 
1140  const int status = currenStatusValue( valueStack );
1141  if ( status != -1 )
1142  return i18n( KMail::StatusValues[ status ].text );
1143  else
1144  return TQString();
1145  }
1146 
1147  //---------------------------------------------------------------------------
1148 
1149  bool StatusRuleWidgetHandler::handlesField( const TQCString & field ) const
1150  {
1151  return ( field == "<status>" );
1152  }
1153 
1154  //---------------------------------------------------------------------------
1155 
1156  void StatusRuleWidgetHandler::reset( TQWidgetStack *functionStack,
1157  TQWidgetStack *valueStack ) const
1158  {
1159  // reset the function combo box
1160  TQComboBox *funcCombo =
1161  dynamic_cast<TQComboBox*>( functionStack->child( "statusRuleFuncCombo",
1162  0, false ) );
1163  if ( funcCombo ) {
1164  funcCombo->blockSignals( true );
1165  funcCombo->setCurrentItem( 0 );
1166  funcCombo->blockSignals( false );
1167  }
1168 
1169  // reset the status value combo box
1170  TQComboBox *statusCombo =
1171  dynamic_cast<TQComboBox*>( valueStack->child( "statusRuleValueCombo",
1172  0, false ) );
1173  if ( statusCombo ) {
1174  statusCombo->blockSignals( true );
1175  statusCombo->setCurrentItem( 0 );
1176  statusCombo->blockSignals( false );
1177  }
1178  }
1179 
1180  //---------------------------------------------------------------------------
1181 
1182  bool StatusRuleWidgetHandler::setRule( TQWidgetStack *functionStack,
1183  TQWidgetStack *valueStack,
1184  const KMSearchRule *rule ) const
1185  {
1186  if ( !rule || !handlesField( rule->field() ) ) {
1187  reset( functionStack, valueStack );
1188  return false;
1189  }
1190 
1191  // set the function
1192  const KMSearchRule::Function func = rule->function();
1193  int funcIndex = 0;
1194  for ( ; funcIndex < StatusFunctionCount; ++funcIndex )
1195  if ( func == StatusFunctions[funcIndex].id )
1196  break;
1197  TQComboBox *funcCombo =
1198  dynamic_cast<TQComboBox*>( functionStack->child( "statusRuleFuncCombo",
1199  0, false ) );
1200  if ( funcCombo ) {
1201  funcCombo->blockSignals( true );
1202  if ( funcIndex < StatusFunctionCount )
1203  funcCombo->setCurrentItem( funcIndex );
1204  else {
1205  kdDebug(5006) << "StatusRuleWidgetHandler::setRule( "
1206  << rule->asString()
1207  << " ): unhandled function" << endl;
1208  funcCombo->setCurrentItem( 0 );
1209  }
1210  funcCombo->blockSignals( false );
1211  functionStack->raiseWidget( funcCombo );
1212  }
1213 
1214  // set the value
1215  const TQString value = rule->contents();
1216  int valueIndex = 0;
1217  for ( ; valueIndex < KMail::StatusValueCountWithoutHidden; ++valueIndex )
1218  if ( value == TQString::fromLatin1(
1219  KMail::StatusValues[ valueIndex ].text ) )
1220  break;
1221  TQComboBox *statusCombo =
1222  dynamic_cast<TQComboBox*>( valueStack->child( "statusRuleValueCombo",
1223  0, false ) );
1224  if ( statusCombo ) {
1225  statusCombo->blockSignals( true );
1226  if ( valueIndex < KMail::StatusValueCountWithoutHidden )
1227  statusCombo->setCurrentItem( valueIndex );
1228  else {
1229  kdDebug(5006) << "StatusRuleWidgetHandler::setRule( "
1230  << rule->asString()
1231  << " ): unhandled value" << endl;
1232  statusCombo->setCurrentItem( 0 );
1233  }
1234  statusCombo->blockSignals( false );
1235  valueStack->raiseWidget( statusCombo );
1236  }
1237  return true;
1238  }
1239 
1240 
1241  //---------------------------------------------------------------------------
1242 
1243  bool StatusRuleWidgetHandler::update( const TQCString &field,
1244  TQWidgetStack *functionStack,
1245  TQWidgetStack *valueStack ) const
1246  {
1247  if ( !handlesField( field ) )
1248  return false;
1249 
1250  // raise the correct function widget
1251  functionStack->raiseWidget(
1252  static_cast<TQWidget*>( functionStack->child( "statusRuleFuncCombo",
1253  0, false ) ) );
1254 
1255  // raise the correct value widget
1256  valueStack->raiseWidget(
1257  static_cast<TQWidget*>( valueStack->child( "statusRuleValueCombo",
1258  0, false ) ) );
1259  return true;
1260  }
1261 
1262 } // anonymous namespace for StatusRuleWidgetHandler
1263 
1264 
1265 //=============================================================================
1266 //
1267 // class NumericRuleWidgetHandler
1268 //
1269 //=============================================================================
1270 
1271 namespace {
1272  static const struct {
1273  const KMSearchRule::Function id;
1274  const char *displayName;
1275  } NumericFunctions[] = {
1276  { KMSearchRule::FuncEquals, I18N_NOOP( "is equal to" ) },
1277  { KMSearchRule::FuncNotEqual, I18N_NOOP( "is not equal to" ) },
1278  { KMSearchRule::FuncIsGreater, I18N_NOOP( "is greater than" ) },
1279  { KMSearchRule::FuncIsLessOrEqual, I18N_NOOP( "is less than or equal to" ) },
1280  { KMSearchRule::FuncIsLess, I18N_NOOP( "is less than" ) },
1281  { KMSearchRule::FuncIsGreaterOrEqual, I18N_NOOP( "is greater than or equal to" ) }
1282  };
1283  static const int NumericFunctionCount =
1284  sizeof( NumericFunctions ) / sizeof( *NumericFunctions );
1285 
1286  //---------------------------------------------------------------------------
1287 
1288  TQWidget * NumericRuleWidgetHandler::createFunctionWidget( int number,
1289  TQWidgetStack *functionStack,
1290  const TQObject *receiver ) const
1291  {
1292  if ( number != 0 )
1293  return 0;
1294 
1295  TQComboBox *funcCombo = new TQComboBox( functionStack,
1296  "numericRuleFuncCombo" );
1297  for ( int i = 0; i < NumericFunctionCount; ++i ) {
1298  funcCombo->insertItem( i18n( NumericFunctions[i].displayName ) );
1299  }
1300  funcCombo->adjustSize();
1301  TQObject::connect( funcCombo, TQ_SIGNAL( activated( int ) ),
1302  receiver, TQ_SLOT( slotFunctionChanged() ) );
1303  return funcCombo;
1304  }
1305 
1306  //---------------------------------------------------------------------------
1307 
1308  TQWidget * NumericRuleWidgetHandler::createValueWidget( int number,
1309  TQWidgetStack *valueStack,
1310  const TQObject *receiver ) const
1311  {
1312  if ( number != 0 )
1313  return 0;
1314 
1315  KIntNumInput *numInput = new KIntNumInput( valueStack, "KIntNumInput" );
1316  TQObject::connect( numInput, TQ_SIGNAL( valueChanged( int ) ),
1317  receiver, TQ_SLOT( slotValueChanged() ) );
1318  return numInput;
1319  }
1320 
1321  //---------------------------------------------------------------------------
1322 
1323  KMSearchRule::Function NumericRuleWidgetHandler::currentFunction( const TQWidgetStack *functionStack ) const
1324  {
1325  const TQComboBox *funcCombo =
1326  dynamic_cast<TQComboBox*>( TQObject_child_const( functionStack,
1327  "numericRuleFuncCombo" ) );
1328  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
1329  // dynamic_cast<TQComboBox*>( functionStack->child( "numericRuleFuncCombo",
1330  // 0, false ) );
1331  if ( funcCombo ) {
1332  return NumericFunctions[funcCombo->currentItem()].id;
1333  }
1334  else
1335  kdDebug(5006) << "NumericRuleWidgetHandler::currentFunction: "
1336  "numericRuleFuncCombo not found." << endl;
1337  return KMSearchRule::FuncNone;
1338  }
1339 
1340  //---------------------------------------------------------------------------
1341 
1342  KMSearchRule::Function NumericRuleWidgetHandler::function( const TQCString & field,
1343  const TQWidgetStack *functionStack ) const
1344  {
1345  if ( !handlesField( field ) )
1346  return KMSearchRule::FuncNone;
1347 
1348  return currentFunction( functionStack );
1349  }
1350 
1351  //---------------------------------------------------------------------------
1352 
1353  TQString NumericRuleWidgetHandler::currentValue( const TQWidgetStack *valueStack ) const
1354  {
1355  const KIntNumInput *numInput =
1356  dynamic_cast<KIntNumInput*>( TQObject_child_const( valueStack,
1357  "KIntNumInput" ) );
1358  // FIXME (TQt >= 4.0): Use the following when TQObject::child() is const.
1359  // dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
1360  // 0, false ) );
1361  if ( numInput ) {
1362  return TQString::number( numInput->value() );
1363  }
1364  else
1365  kdDebug(5006) << "NumericRuleWidgetHandler::currentValue: "
1366  "KIntNumInput not found." << endl;
1367  return TQString();
1368  }
1369 
1370  //---------------------------------------------------------------------------
1371 
1372  TQString NumericRuleWidgetHandler::value( const TQCString & field,
1373  const TQWidgetStack *,
1374  const TQWidgetStack *valueStack ) const
1375  {
1376  if ( !handlesField( field ) )
1377  return TQString();
1378 
1379  return currentValue( valueStack );
1380  }
1381 
1382  //---------------------------------------------------------------------------
1383 
1384  TQString NumericRuleWidgetHandler::prettyValue( const TQCString & field,
1385  const TQWidgetStack *,
1386  const TQWidgetStack *valueStack ) const
1387  {
1388  if ( !handlesField( field ) )
1389  return TQString();
1390 
1391  return currentValue( valueStack );
1392  }
1393 
1394  //---------------------------------------------------------------------------
1395 
1396  bool NumericRuleWidgetHandler::handlesField( const TQCString & field ) const
1397  {
1398  return ( field == "<size>" || field == "<age in days>" );
1399  }
1400 
1401  //---------------------------------------------------------------------------
1402 
1403  void NumericRuleWidgetHandler::reset( TQWidgetStack *functionStack,
1404  TQWidgetStack *valueStack ) const
1405  {
1406  // reset the function combo box
1407  TQComboBox *funcCombo =
1408  dynamic_cast<TQComboBox*>( functionStack->child( "numericRuleFuncCombo",
1409  0, false ) );
1410  if ( funcCombo ) {
1411  funcCombo->blockSignals( true );
1412  funcCombo->setCurrentItem( 0 );
1413  funcCombo->blockSignals( false );
1414  }
1415 
1416  // reset the value widget
1417  KIntNumInput *numInput =
1418  dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
1419  0, false ) );
1420  if ( numInput ) {
1421  numInput->blockSignals( true );
1422  numInput->setValue( 0 );
1423  numInput->blockSignals( false );
1424  }
1425  }
1426 
1427  //---------------------------------------------------------------------------
1428 
1429  void initNumInput( KIntNumInput *numInput, const TQCString &field )
1430  {
1431  if ( field == "<size>" ) {
1432  numInput->setMinValue( 0 );
1433  numInput->setSuffix( i18n( " bytes" ) );
1434  }
1435  else {
1436  numInput->setMinValue( -10000 );
1437  numInput->setSuffix( i18n( " days" ) );
1438  }
1439  }
1440 
1441  //---------------------------------------------------------------------------
1442 
1443  bool NumericRuleWidgetHandler::setRule( TQWidgetStack *functionStack,
1444  TQWidgetStack *valueStack,
1445  const KMSearchRule *rule ) const
1446  {
1447  if ( !rule || !handlesField( rule->field() ) ) {
1448  reset( functionStack, valueStack );
1449  return false;
1450  }
1451 
1452  // set the function
1453  const KMSearchRule::Function func = rule->function();
1454  int funcIndex = 0;
1455  for ( ; funcIndex < NumericFunctionCount; ++funcIndex )
1456  if ( func == NumericFunctions[funcIndex].id )
1457  break;
1458  TQComboBox *funcCombo =
1459  dynamic_cast<TQComboBox*>( functionStack->child( "numericRuleFuncCombo",
1460  0, false ) );
1461  if ( funcCombo ) {
1462  funcCombo->blockSignals( true );
1463  if ( funcIndex < NumericFunctionCount )
1464  funcCombo->setCurrentItem( funcIndex );
1465  else {
1466  kdDebug(5006) << "NumericRuleWidgetHandler::setRule( "
1467  << rule->asString()
1468  << " ): unhandled function" << endl;
1469  funcCombo->setCurrentItem( 0 );
1470  }
1471  funcCombo->blockSignals( false );
1472  functionStack->raiseWidget( funcCombo );
1473  }
1474 
1475  // set the value
1476  bool ok;
1477  int value = rule->contents().toInt( &ok );
1478  if ( !ok )
1479  value = 0;
1480  KIntNumInput *numInput =
1481  dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
1482  0, false ) );
1483  if ( numInput ) {
1484  initNumInput( numInput, rule->field() );
1485  numInput->blockSignals( true );
1486  numInput->setValue( value );
1487  numInput->blockSignals( false );
1488  valueStack->raiseWidget( numInput );
1489  }
1490  return true;
1491  }
1492 
1493 
1494  //---------------------------------------------------------------------------
1495 
1496  bool NumericRuleWidgetHandler::update( const TQCString &field,
1497  TQWidgetStack *functionStack,
1498  TQWidgetStack *valueStack ) const
1499  {
1500  if ( !handlesField( field ) )
1501  return false;
1502 
1503  // raise the correct function widget
1504  functionStack->raiseWidget(
1505  static_cast<TQWidget*>( functionStack->child( "numericRuleFuncCombo",
1506  0, false ) ) );
1507 
1508  // raise the correct value widget
1509  KIntNumInput *numInput =
1510  dynamic_cast<KIntNumInput*>( valueStack->child( "KIntNumInput",
1511  0, false ) );
1512  if ( numInput ) {
1513  initNumInput( numInput, field );
1514  valueStack->raiseWidget( numInput );
1515  }
1516  return true;
1517  }
1518 
1519 } // anonymous namespace for NumericRuleWidgetHandler
1520 
Incoming mail is sent through the list of mail filter rules before it is placed in the associated mai...
TQCString field() const
Return message header field name (without the trailing ':').
Function function() const
Return filter function.
const TQString asString() const
Returns the rule as string.
TQString contents() const
Return the value.
Function
Operators for comparison of field and contents.
Singleton to manage the list of RuleWidgetHandlers.
An interface to filter/search rule widget handlers.
folderdiaquotatab.h
Definition: aboutdata.cpp:40