libtdepim

kscoringeditor.cpp
1 /*
2  kscoringeditor.cpp
3 
4  Copyright (c) 2001 Mathias Waack
5  Copyright (C) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
6 
7  Author: Mathias Waack <mathias@atoll-net.de>
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software Foundation,
15  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
16 */
17 
18 #undef TQT_NO_COMPAT
19 
20 #include "kscoring.h"
21 #include "kscoringeditor.h"
22 
23 #include <kdebug.h>
24 #include <tdelocale.h>
25 #include <kcombobox.h>
26 #include <kcolorcombo.h>
27 #include <kiconloader.h>
28 #include <kregexpeditorinterface.h>
29 #include <ktrader.h>
30 #include <tdeparts/componentfactory.h>
31 
32 
33 #include <tqlabel.h>
34 #include <tqpushbutton.h>
35 #include <tqlayout.h>
36 #include <tqtooltip.h>
37 #include <tqcheckbox.h>
38 #include <tqbuttongroup.h>
39 #include <tqradiobutton.h>
40 #include <tqwidgetstack.h>
41 #include <tqapplication.h>
42 #include <tqtimer.h>
43 #include <tqhbox.h>
44 
45 // works for both ListBox and ComboBox
46 template <class T> static int setCurrentItem(T *box, const TQString& s)
47 {
48  int cnt = box->count();
49  for (int i=0;i<cnt;++i) {
50  if (box->text(i) == s) {
51  box->setCurrentItem(i);
52  return i;
53  }
54  }
55  return -1;
56 }
57 
58 
59 //============================================================================
60 //
61 // class SingleConditionWidget (editor for one condition, used in ConditionEditWidget)
62 //
63 //============================================================================
64 SingleConditionWidget::SingleConditionWidget(KScoringManager *m,TQWidget *p, const char *n)
65  : TQFrame(p,n), manager(m)
66 {
67  TQBoxLayout *topL = new TQVBoxLayout(this,5);
68  TQBoxLayout *firstRow = new TQHBoxLayout(topL);
69  neg = new TQCheckBox(i18n("Not"),this);
70  TQToolTip::add(neg,i18n("Negate this condition"));
71  firstRow->addWidget(neg);
72  headers = new KComboBox(this);
73  headers->insertStringList(manager->getDefaultHeaders());
74  headers->setEditable( true );
75  TQToolTip::add(headers,i18n("Select the header to match this condition against"));
76  firstRow->addWidget(headers,1);
77  matches = new KComboBox(this);
78  matches->insertStringList(KScoringExpression::conditionNames());
79  TQToolTip::add(matches,i18n("Select the type of match"));
80  firstRow->addWidget(matches,1);
81  connect( matches, TQT_SIGNAL( activated( int ) ), TQT_SLOT( toggleRegExpButton( int ) ) );
82  TQHBoxLayout *secondRow = new TQHBoxLayout( topL );
83  secondRow->setSpacing( 1 );
84  expr = new KLineEdit( this );
85  TQToolTip::add(expr,i18n("The condition for the match"));
86  // reserve space for at least 20 characters
87  expr->setMinimumWidth(fontMetrics().maxWidth()*20);
88  secondRow->addWidget( expr );
89  regExpButton = new TQPushButton( i18n("Edit..."), this );
90  secondRow->addWidget( regExpButton );
91  connect( regExpButton, TQT_SIGNAL( clicked() ), TQT_SLOT( showRegExpDialog() ) );
92 
93  // occupy at much width as possible
94  setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding,TQSizePolicy::Fixed));
95  setFrameStyle(Box | Sunken);
96  setLineWidth(1);
97 }
98 
99 SingleConditionWidget::~SingleConditionWidget()
100 {}
101 
102 void SingleConditionWidget::setCondition(KScoringExpression *e)
103 {
104  neg->setChecked(e->isNeg());
105  headers->setCurrentText( e->getHeader() );
106  setCurrentItem(matches,KScoringExpression::getNameForCondition(e->getCondition()));
107  toggleRegExpButton( matches->currentItem() );
108  expr->setText(e->getExpression());
109 }
110 
111 KScoringExpression* SingleConditionWidget::createCondition() const
112 {
113  TQString head = headers->currentText();
114  TQString match = matches->currentText();
115  int condType = KScoringExpression::getConditionForName(match);
116  match = KScoringExpression::getTypeString(condType);
117  TQString cond = expr->text();
118  TQString negs = (neg->isChecked())?"1":"0";
119  return new KScoringExpression(head,match,cond,negs);
120 }
121 
122 void SingleConditionWidget::clear()
123 {
124  neg->setChecked(false);
125  expr->clear();
126 }
127 
128 void SingleConditionWidget::toggleRegExpButton( int selected )
129 {
130  bool isRegExp = (KScoringExpression::MATCH == selected ||
131  KScoringExpression::MATCHCS == selected) &&
132  !TDETrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty();
133  regExpButton->setEnabled( isRegExp );
134 }
135 
136 void SingleConditionWidget::showRegExpDialog()
137 {
138  TQDialog *editorDialog = KParts::ComponentFactory::createInstanceFromQuery<TQDialog>( "KRegExpEditor/KRegExpEditor" );
139  if ( editorDialog ) {
140  KRegExpEditorInterface *editor = static_cast<KRegExpEditorInterface *>( editorDialog->tqt_cast( "KRegExpEditorInterface" ) );
141  Q_ASSERT( editor ); // This should not fail!
142  editor->setRegExp( expr->text() );
143  editorDialog->exec();
144  expr->setText( editor->regExp() );
145  }
146 }
147 
148 //============================================================================
149 //
150 // class ConditionEditWidget (the widget to edit the conditions of a rule)
151 //
152 //============================================================================
153 ConditionEditWidget::ConditionEditWidget(KScoringManager *m, TQWidget *p, const char *n)
154  : KWidgetLister(1,8,p,n), manager(m)
155 {
156  // create one initial widget
157  addWidgetAtEnd();
158 }
159 
160 ConditionEditWidget::~ConditionEditWidget()
161 {}
162 
163 TQWidget* ConditionEditWidget::createWidget(TQWidget *parent)
164 {
165  return new SingleConditionWidget(manager,parent);
166 }
167 
169 {
170  Q_ASSERT( w->isA("SingleConditionWidget") );
171  SingleConditionWidget *sw = dynamic_cast<SingleConditionWidget*>(w);
172  if (sw)
173  sw->clear();
174 }
175 
176 void ConditionEditWidget::slotEditRule(KScoringRule *rule)
177 {
178  KScoringRule::ScoreExprList l;
179  if (rule) l = rule->getExpressions();
180  if (!rule || l.count() == 0) {
181  slotClear();
182  } else {
183  setNumberOfShownWidgetsTo(l.count());
184  KScoringExpression *e = l.first();
185  SingleConditionWidget *scw = static_cast<SingleConditionWidget*>(mWidgetList.first());
186  while (e && scw) {
187  scw->setCondition(e);
188  e = l.next();
189  scw = static_cast<SingleConditionWidget*>(mWidgetList.next());
190  }
191  }
192 }
193 
194 void ConditionEditWidget::updateRule(KScoringRule *rule)
195 {
196  rule->cleanExpressions();
197  for(TQWidget *w = mWidgetList.first(); w; w = mWidgetList.next()) {
198  if (! w->isA("SingleConditionWidget")) {
199  kdWarning(5100) << "there is a widget in ConditionEditWidget "
200  << "which isn't a SingleConditionWidget" << endl;
201  } else {
202  SingleConditionWidget *saw = dynamic_cast<SingleConditionWidget*>(w);
203  if (saw)
204  rule->addExpression(saw->createCondition());
205  }
206  }
207 }
208 
209 //============================================================================
210 //
211 // class SingleActionWidget (editor for one action, used in ActionEditWidget)
212 //
213 //============================================================================
214 SingleActionWidget::SingleActionWidget(KScoringManager *m,TQWidget *p, const char *n)
215  : TQWidget(p,n), notifyEditor(0), scoreEditor(0), colorEditor(0),manager(m)
216 {
217  TQHBoxLayout *topL = new TQHBoxLayout(this,0,5);
218  types = new KComboBox(this);
219  types->setEditable(false);
220  topL->addWidget(types);
221  stack = new TQWidgetStack(this);
222  topL->addWidget(stack);
223 
224  dummyLabel = new TQLabel(i18n("Select an action."), stack);
225  stack->addWidget(dummyLabel, 0);
226 
227  // init widget stack and the types combo box
228  int index = 1;
229  types->insertItem(TQString());
230  TQStringList l = ActionBase::userNames();
231  for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
232  TQString name = *it;
233  int feature = ActionBase::getTypeForUserName(name);
234  if (manager->hasFeature(feature)) {
235  types->insertItem(name);
236  TQWidget *w=0;
237  switch (feature) {
238  case ActionBase::SETSCORE:
239  w = scoreEditor = new KIntSpinBox(-99999,99999,1,0,10, stack);
240  break;
241  case ActionBase::NOTIFY:
242  w = notifyEditor = new KLineEdit(stack);
243  break;
244  case ActionBase::COLOR:
245  w = colorEditor = new KColorCombo(stack);
246  break;
247  case ActionBase::MARKASREAD:
248  w = new TQLabel( stack ); // empty dummy
249  break;
250  }
251  if ( w )
252  stack->addWidget(w,index++);
253  }
254  }
255 
256  connect(types,TQT_SIGNAL(activated(int)),stack,TQT_SLOT(raiseWidget(int)));
257 
258  // raise the dummy label
259  types->setCurrentItem(0);
260  stack->raiseWidget(dummyLabel);
261 }
262 
263 SingleActionWidget::~SingleActionWidget()
264 {
265 }
266 
267 void SingleActionWidget::setAction(ActionBase *act)
268 {
269  kdDebug(5100) << "SingleActionWidget::setAction()" << endl;
270  setCurrentItem(types,ActionBase::userName(act->getType()));
271  int index = types->currentItem();
272  stack->raiseWidget(index);
273  switch (act->getType()) {
274  case ActionBase::SETSCORE:
275  scoreEditor->setValue(act->getValueString().toInt());
276  break;
277  case ActionBase::NOTIFY:
278  notifyEditor->setText(act->getValueString());
279  break;
280  case ActionBase::COLOR:
281  colorEditor->setColor(TQColor(act->getValueString()));
282  break;
283  case ActionBase::MARKASREAD:
284  // nothing
285  break;
286  default:
287  kdWarning(5100) << "unknown action type in SingleActionWidget::setAction()" << endl;
288  }
289 }
290 
291 ActionBase* SingleActionWidget::createAction() const
292 {
293  // no action selected...
294  if (types->currentText().isEmpty())
295  return 0;
296 
297  int type = ActionBase::getTypeForUserName(types->currentText());
298  switch (type) {
299  case ActionBase::SETSCORE:
300  return new ActionSetScore(scoreEditor->value());
301  case ActionBase::NOTIFY:
302  return new ActionNotify(notifyEditor->text());
303  case ActionBase::COLOR:
304  return new ActionColor(TQString(colorEditor->color().name()));
305  case ActionBase::MARKASREAD:
306  return new ActionMarkAsRead();
307  default:
308  kdWarning(5100) << "unknown action type in SingleActionWidget::getValue()" << endl;
309  return 0;
310  }
311 }
312 
313 void SingleActionWidget::clear()
314 {
315  if (scoreEditor) scoreEditor->setValue(0);
316  if (notifyEditor) notifyEditor->clear();
317  if (colorEditor) colorEditor->setCurrentItem(0);
318  types->setCurrentItem(0);
319  stack->raiseWidget(dummyLabel);
320 }
321 
322 //============================================================================
323 //
324 // class ActionEditWidget (the widget to edit the actions of a rule)
325 //
326 //============================================================================
327 ActionEditWidget::ActionEditWidget(KScoringManager *m,TQWidget *p, const char *n)
328  : KWidgetLister(1,8,p,n), manager(m)
329 {
330  // create one initial widget
331  addWidgetAtEnd();
332 }
333 
334 ActionEditWidget::~ActionEditWidget()
335 {}
336 
337 TQWidget* ActionEditWidget::createWidget( TQWidget *parent )
338 {
339  return new SingleActionWidget(manager,parent);
340 }
341 
342 void ActionEditWidget::slotEditRule(KScoringRule *rule)
343 {
344  KScoringRule::ActionList l;
345  if (rule) l = rule->getActions();
346  if (!rule || l.count() == 0) {
347  slotClear();
348  } else {
349  setNumberOfShownWidgetsTo(l.count());
350  ActionBase *act = l.first();
351  SingleActionWidget *saw = static_cast<SingleActionWidget*>(mWidgetList.first());
352  while (act && saw) {
353  saw->setAction(act);
354  act = l.next();
355  saw = static_cast<SingleActionWidget*>(mWidgetList.next());
356  }
357  }
358 }
359 
360 void ActionEditWidget::updateRule(KScoringRule *rule)
361 {
362  rule->cleanActions();
363  for(TQWidget *w = mWidgetList.first(); w; w = mWidgetList.next()) {
364  if (! w->isA("SingleActionWidget")) {
365  kdWarning(5100) << "there is a widget in ActionEditWidget "
366  << "which isn't a SingleActionWidget" << endl;
367  } else {
368  SingleActionWidget *saw = dynamic_cast<SingleActionWidget*>(w);
369  if (saw)
370  {
371  ActionBase *act = saw->createAction();
372  if (act)
373  rule->addAction(act);
374  }
375  }
376  }
377 }
378 
380 {
381  Q_ASSERT( w->isA("SingleActionWidget") );
382  SingleActionWidget *sw = dynamic_cast<SingleActionWidget*>(w);
383  if (sw)
384  sw->clear();
385 }
386 
387 //============================================================================
388 //
389 // class RuleEditWidget (the widget to edit one rule)
390 //
391 //============================================================================
392 RuleEditWidget::RuleEditWidget(KScoringManager *m,TQWidget *p, const char *n)
393  : TQWidget(p,n), dirty(false), manager(m), oldRuleName(TQString())
394 {
395  kdDebug(5100) << "RuleEditWidget::RuleEditWidget()" << endl;
396  if ( !n ) setName( "RuleEditWidget" );
397  TQVBoxLayout *topLayout = new TQVBoxLayout( this, 5, KDialog::spacingHint() );
398 
399  //------------- Name, Servers, Groups ---------------------
400  TQGroupBox *groupB = new TQGroupBox(i18n("Properties"),this);
401  topLayout->addWidget(groupB);
402  TQGridLayout* groupL = new TQGridLayout(groupB, 6,2, 8,5);
403  groupL->addRowSpacing(0, fontMetrics().lineSpacing()-4);
404 
405  // name
406  ruleNameEdit = new KLineEdit( groupB, "ruleNameEdit" );
407  groupL->addWidget( ruleNameEdit, 1, 1 );
408  TQLabel *ruleNameLabel = new TQLabel(ruleNameEdit, i18n("&Name:"), groupB, "ruleNameLabel");
409  groupL->addWidget( ruleNameLabel, 1, 0 );
410 
411  // groups
412  groupsEdit = new KLineEdit( groupB, "groupsEdit" );
413  groupL->addWidget( groupsEdit, 2, 1 );
414  TQLabel *groupsLabel = new TQLabel(groupsEdit, i18n("&Groups:"), groupB, "groupsLabel");
415  groupL->addWidget( groupsLabel, 2, 0 );
416 
417  TQPushButton *groupsBtn = new TQPushButton(i18n("A&dd Group"), groupB);
418  connect(groupsBtn,TQT_SIGNAL(clicked()),TQT_SLOT(slotAddGroup()));
419  groupL->addWidget( groupsBtn, 3, 0 );
420 
421  groupsBox = new KComboBox( false, groupB, "groupsBox" );
422  groupsBox->setDuplicatesEnabled(false);
423  groupsBox->insertStringList(manager->getGroups());
424  groupsBox->setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed));
425  groupL->addWidget( groupsBox, 3, 1 );
426 
427  // expires
428  expireCheck = new TQCheckBox(i18n("&Expire rule automatically"), groupB);
429  groupL->addMultiCellWidget( expireCheck, 4,4, 0,1 );
430  expireEdit = new KIntSpinBox(1,99999,1,30,10, groupB, "expireWidget");
431  //Init suffix
432  slotExpireEditChanged(30);
433  connect(expireEdit, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotExpireEditChanged(int)));
434  groupL->addWidget( expireEdit, 5, 1 );
435  expireLabel = new TQLabel(expireEdit, i18n("&Rule is valid for:"), groupB, "expireLabel");
436  groupL->addWidget( expireLabel, 5, 0 );
437  expireLabel->setEnabled(false);
438  expireEdit->setEnabled(false);
439 
440  connect(expireCheck, TQT_SIGNAL(toggled(bool)), expireLabel, TQT_SLOT(setEnabled(bool)));
441  connect(expireCheck, TQT_SIGNAL(toggled(bool)), expireEdit, TQT_SLOT(setEnabled(bool)));
442 
443  //------------- Conditions ---------------------
444  TQGroupBox *groupConds = new TQGroupBox(i18n("Conditions"), this);
445  topLayout->addWidget(groupConds);
446  TQGridLayout *condL = new TQGridLayout(groupConds, 3,2, 8,5);
447 
448  condL->addRowSpacing(0, fontMetrics().lineSpacing()-4);
449 
450  TQButtonGroup *buttonGroup = new TQButtonGroup(groupConds);
451  buttonGroup->hide();
452  linkModeAnd = new TQRadioButton(i18n("Match a&ll conditions"), groupConds);
453  buttonGroup->insert(linkModeAnd);
454  condL->addWidget(linkModeAnd, 1,0);
455  linkModeOr = new TQRadioButton(i18n("Matc&h any condition"), groupConds);
456  buttonGroup->insert(linkModeOr);
457  condL->addWidget(linkModeOr, 1,1);
458  linkModeAnd->setChecked(true);
459 
460  condEditor = new ConditionEditWidget(manager,groupConds);
461  condL->addMultiCellWidget(condEditor, 2,2, 0,1);
462  connect(condEditor,TQT_SIGNAL(widgetRemoved()),this,TQT_SLOT(slotShrink()));
463 
464  //------------- Actions ---------------------
465  TQGroupBox *groupActions = new TQGroupBox(i18n("Actions"), this);
466  topLayout->addWidget(groupActions);
467  TQBoxLayout *actionL = new TQVBoxLayout(groupActions,8,5);
468  actionL->addSpacing(fontMetrics().lineSpacing()-4);
469  actionEditor = new ActionEditWidget(manager,groupActions);
470  actionL->addWidget(actionEditor);
471  connect(actionEditor,TQT_SIGNAL(widgetRemoved()),this,TQT_SLOT(slotShrink()));
472 
473  topLayout->addStretch(1);
474 
475  kdDebug(5100) << "constructed RuleEditWidget" << endl;
476 }
477 
478 RuleEditWidget::~RuleEditWidget()
479 {
480 }
481 
482 void RuleEditWidget::slotEditRule(const TQString& ruleName)
483 {
484  kdDebug(5100) << "RuleEditWidget::slotEditRule(" << ruleName << ")" << endl;
485 // // first update the old rule if there is one
486 // kdDebug(5100) << "let see if we have a rule with name " << oldRuleName << endl;
487 // KScoringRule *rule;
488 // if (!oldRuleName.isNull() && oldRuleName != ruleName) {
489 // rule = manager->findRule(oldRuleName);
490 // if (rule) {
491 // kdDebug(5100) << "updating rule " << rule->getName() << endl;
492 // updateRule(rule);
493 // }
494 // }
495 
496  KScoringRule* rule = manager->findRule(ruleName);
497  if (!rule) {
498  kdDebug(5100) << "no rule for ruleName " << ruleName << endl;
499  clearContents();
500  return;
501  }
502  oldRuleName = rule->getName();
503  ruleNameEdit->setText(rule->getName());
504  groupsEdit->setText(rule->getGroups().join(";"));
505 
506  bool b = rule->getExpireDate().isValid();
507  expireCheck->setChecked(b);
508  expireEdit->setEnabled(b);
509  expireLabel->setEnabled(b);
510  if (b)
511  expireEdit->setValue(TQDate::currentDate().daysTo(rule->getExpireDate()));
512  else
513  expireEdit->setValue(30);
514  if (rule->getLinkMode() == KScoringRule::AND) {
515  linkModeAnd->setChecked(true);
516  }
517  else {
518  linkModeOr->setChecked(true);
519  }
520 
521  condEditor->slotEditRule(rule);
522  actionEditor->slotEditRule(rule);
523 
524  kdDebug(5100) << "RuleEditWidget::slotEditRule() ready" << endl;
525 }
526 
527 void RuleEditWidget::clearContents()
528 {
529  ruleNameEdit->setText("");
530  groupsEdit->setText("");
531  expireCheck->setChecked(false);
532  expireEdit->setValue(30);
533  expireEdit->setEnabled(false);
534  condEditor->slotEditRule(0);
535  actionEditor->slotEditRule(0);
536  oldRuleName = TQString();
537 }
538 
539 void RuleEditWidget::updateRule(KScoringRule *rule)
540 {
541  oldRuleName = TQString();
542  TQString groups = groupsEdit->text();
543  if (groups.isEmpty())
544  rule->setGroups(TQStringList(".*"));
545  else
546  rule->setGroups(TQStringList::split(";",groups));
547  bool b = expireCheck->isChecked();
548  if (b)
549  rule->setExpireDate(TQDate::currentDate().addDays(expireEdit->value()));
550  else
551  rule->setExpireDate(TQDate());
552  actionEditor->updateRule(rule);
553  rule->setLinkMode(linkModeAnd->isChecked()?KScoringRule::AND:KScoringRule::OR);
554  condEditor->updateRule(rule);
555  if (rule->getName() != ruleNameEdit->text())
556  manager->setRuleName(rule,ruleNameEdit->text());
557 }
558 
559 void RuleEditWidget::updateRule()
560 {
561  KScoringRule *rule = manager->findRule(oldRuleName);
562  if (rule) updateRule(rule);
563 }
564 
565 void RuleEditWidget::slotAddGroup()
566 {
567  TQString grp = groupsBox->currentText();
568  if ( grp.isEmpty() )
569  return;
570  TQString txt = groupsEdit->text().stripWhiteSpace();
571  if ( txt == ".*" || txt.isEmpty() ) groupsEdit->setText(grp);
572  else groupsEdit->setText(txt + ";" + grp);
573 }
574 
575 void RuleEditWidget::setDirty()
576 {
577  kdDebug(5100) << "RuleEditWidget::setDirty()" << endl;
578  if (dirty) return;
579  dirty = true;
580 }
581 
582 void RuleEditWidget::slotShrink()
583 {
584  emit(shrink());
585 }
586 
587 void RuleEditWidget::slotExpireEditChanged(int value)
588 {
589  expireEdit->setSuffix(i18n(" day", " days", value));
590 }
591 
592 //============================================================================
593 //
594 // class RuleListWidget (the widget for managing a list of rules)
595 //
596 //============================================================================
597 RuleListWidget::RuleListWidget(KScoringManager *m, bool standalone, TQWidget *p, const char *n)
598  : TQWidget(p,n), alone(standalone), manager(m)
599 {
600  kdDebug(5100) << "RuleListWidget::RuleListWidget()" << endl;
601  if (!n) setName("RuleListWidget");
602  TQVBoxLayout *topL = new TQVBoxLayout(this,standalone? 0:5,KDialog::spacingHint());
603  ruleList = new TDEListBox(this);
604  if (standalone) {
605  connect(ruleList,TQT_SIGNAL(doubleClicked(TQListBoxItem*)),
606  this,TQT_SLOT(slotEditRule(TQListBoxItem*)));
607  connect(ruleList,TQT_SIGNAL(returnPressed(TQListBoxItem*)),
608  this,TQT_SLOT(slotEditRule(TQListBoxItem*)));
609  }
610  connect(ruleList, TQT_SIGNAL(currentChanged(TQListBoxItem*)),
611  this, TQT_SLOT(slotRuleSelected(TQListBoxItem*)));
612  topL->addWidget(ruleList);
613 
614  TQHBoxLayout *btnL = new TQHBoxLayout( topL, KDialog::spacingHint() );
615  mRuleUp = new TQPushButton( this );
616  mRuleUp->setPixmap( BarIcon( "go-up", TDEIcon::SizeSmall ) );
617  TQToolTip::add( mRuleUp, i18n("Move rule up") );
618  btnL->addWidget( mRuleUp );
619  connect( mRuleUp, TQT_SIGNAL( clicked() ), TQT_SLOT( slotRuleUp() ) );
620  mRuleDown = new TQPushButton( this );
621  mRuleDown->setPixmap( BarIcon( "go-down", TDEIcon::SizeSmall ) );
622  TQToolTip::add( mRuleDown, i18n("Move rule down") );
623  btnL->addWidget( mRuleDown );
624  connect( mRuleDown, TQT_SIGNAL( clicked() ), TQT_SLOT( slotRuleDown() ) );
625 
626  btnL = new TQHBoxLayout( topL, KDialog::spacingHint() );
627  editRule=0L;
628  newRule = new TQPushButton(this);
629  newRule->setPixmap( BarIcon( "document-new", TDEIcon::SizeSmall ) );
630  TQToolTip::add(newRule,i18n("New rule")),
631  btnL->addWidget(newRule);
632  connect(newRule, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotNewRule()));
633  // if we're standalone, we need an additional edit button
634  if (standalone) {
635  editRule = new TQPushButton(this);
636  editRule->setIconSet( BarIconSet("edit", TDEIcon::SizeSmall) );
637  TQToolTip::add(editRule,i18n("Edit rule"));
638  btnL->addWidget(editRule);
639  connect(editRule,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotEditRule()));
640  }
641  delRule = new TQPushButton(this);
642  delRule->setIconSet( BarIconSet( "edit-delete", TDEIcon::SizeSmall ) );
643  TQToolTip::add(delRule,i18n("Remove rule"));
644  btnL->addWidget(delRule);
645  connect(delRule, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotDelRule()));
646  copyRule = new TQPushButton(this);
647  copyRule->setIconSet(BarIconSet("edit-copy", TDEIcon::SizeSmall));
648  TQToolTip::add(copyRule,i18n("Copy rule"));
649  btnL->addWidget(copyRule);
650  connect(copyRule, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCopyRule()));
651 
652  // the group filter
653  TQBoxLayout *filterL = new TQVBoxLayout(topL,KDialog::spacingHint());
654  KComboBox *filterBox = new KComboBox(this);
655  TQStringList l = m->getGroups();
656  filterBox->insertItem(i18n("<all groups>"));
657  filterBox->insertStringList(l);
658  filterBox->setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed));
659  connect(filterBox,TQT_SIGNAL(activated(const TQString&)),
660  this,TQT_SLOT(slotGroupFilter(const TQString&)));
661  slotGroupFilter(i18n("<all groups>"));
662  TQLabel *lab = new TQLabel(filterBox,i18n("Sho&w only rules for group:"),this);
663  filterL->addWidget(lab);
664  filterL->addWidget(filterBox);
665 
666  connect(manager,TQT_SIGNAL(changedRules()),
667  this,TQT_SLOT(updateRuleList()));
668  connect(manager,TQT_SIGNAL(changedRuleName(const TQString&,const TQString&)),
669  this,TQT_SLOT(slotRuleNameChanged(const TQString&,const TQString&)));
670 
671  updateRuleList();
672  updateButton();
673 }
674 
675 RuleListWidget::~RuleListWidget()
676 {
677 }
678 
679 void RuleListWidget::updateButton()
680 {
681  bool state = ruleList->count() > 0;
682  if(editRule)
683  editRule->setEnabled(state);
684  delRule->setEnabled(state);
685  copyRule->setEnabled(state);
686 
687  TQListBoxItem *item = ruleList->item( ruleList->currentItem() );
688  if ( item ) {
689  mRuleUp->setEnabled( item->prev() != 0 );
690  mRuleDown->setEnabled( item->next() != 0 );
691  }
692 }
693 
694 void RuleListWidget::updateRuleList()
695 {
696  emit leavingRule();
697  kdDebug(5100) << "RuleListWidget::updateRuleList()" << endl;
698  TQString curr = ruleList->currentText();
699  ruleList->clear();
700  if (group == i18n("<all groups>")) {
701  TQStringList l = manager->getRuleNames();
702  ruleList->insertStringList(l);
703  } else {
704  KScoringManager::ScoringRuleList l = manager->getAllRules();
705  for (KScoringRule* rule = l.first(); rule; rule = l.next() ) {
706  if (rule->matchGroup(group)) ruleList->insertItem(rule->getName());
707  }
708  }
709  int index = setCurrentItem(ruleList,curr);
710  if (index <0) {
711  ruleList->setCurrentItem(0);
712  slotRuleSelected(ruleList->currentText());
713  }
714  else {
715  slotRuleSelected(curr);
716  }
717 }
718 
719 void RuleListWidget::updateRuleList(const KScoringRule *rule)
720 {
721  kdDebug(5100) << "RuleListWidget::updateRuleList(" << rule->getName() << ")" << endl;
722  TQString name = rule->getName();
723  updateRuleList();
724  slotRuleSelected(name);
725 }
726 
727 void RuleListWidget::slotRuleNameChanged(const TQString& oldName, const TQString& newName)
728 {
729  int ind = ruleList->currentItem();
730  for (uint i=0;i<ruleList->count();++i)
731  if (ruleList->text(i) == oldName) {
732  ruleList->changeItem(newName,i);
733  ruleList->setCurrentItem(ind);
734  return;
735  }
736 }
737 
738 void RuleListWidget::slotEditRule(const TQString& s)
739 {
740  emit ruleEdited(s);
741 }
742 
743 void RuleListWidget::slotEditRule()
744 {
745  if (ruleList->currentItem() >= 0) {
746  emit ruleEdited(ruleList->currentText());
747  }
748  else if (ruleList->count() == 0)
749  emit ruleEdited(TQString());
750 }
751 
752 void RuleListWidget::slotEditRule(TQListBoxItem* item)
753 {
754  slotEditRule(item->text());
755 }
756 
757 void RuleListWidget::slotGroupFilter(const TQString& s)
758 {
759  group = s;
760  updateRuleList();
761 }
762 
763 void RuleListWidget::slotRuleSelected(const TQString& ruleName)
764 {
765  emit leavingRule();
766  kdDebug(5100) << "RuleListWidget::slotRuleSelected(" << ruleName << ")" << endl;
767  if (ruleName != ruleList->currentText()) {
768  setCurrentItem(ruleList,ruleName);
769  }
770  updateButton();
771  emit ruleSelected(ruleName);
772 }
773 
774 void RuleListWidget::slotRuleSelected(TQListBoxItem *item)
775 {
776  if (!item) return;
777  TQString ruleName = item->text();
778  slotRuleSelected(ruleName);
779 }
780 
781 void RuleListWidget::slotRuleSelected(int index)
782 {
783  uint idx = index;
784  if (idx >= ruleList->count()) return;
785  TQString ruleName = ruleList->text(index);
786  slotRuleSelected(ruleName);
787 }
788 
789 void RuleListWidget::slotNewRule()
790 {
791  emit leavingRule();
792  KScoringRule *rule = manager->addRule();
793  updateRuleList(rule);
794  if (alone) slotEditRule(rule->getName());
795  updateButton();
796 }
797 
798 void RuleListWidget::slotDelRule()
799 {
800  KScoringRule *rule = manager->findRule(ruleList->currentText());
801  if (rule)
802  manager->deleteRule(rule);
803  // goto the next rule
804  if (!alone) slotEditRule();
805  updateButton();
806 }
807 
808 void RuleListWidget::slotCopyRule()
809 {
810  emit leavingRule();
811  TQString ruleName = ruleList->currentText();
812  KScoringRule *rule = manager->findRule(ruleName);
813  if (rule) {
814  KScoringRule *nrule = manager->copyRule(rule);
815  updateRuleList(nrule);
816  slotEditRule(nrule->getName());
817  }
818  updateButton();
819 }
820 
821 void RuleListWidget::slotRuleUp()
822 {
823  KScoringRule *rule = 0, *below = 0;
824  TQListBoxItem *item = ruleList->item( ruleList->currentItem() );
825  if ( item ) {
826  rule = manager->findRule( item->text() );
827  item = item->prev();
828  if ( item )
829  below = manager->findRule( item->text() );
830  }
831  if ( rule && below )
832  manager->moveRuleAbove( rule, below );
833  updateRuleList();
834  updateButton();
835 }
836 
837 void RuleListWidget::slotRuleDown()
838 {
839  KScoringRule *rule = 0, *above = 0;
840  TQListBoxItem *item = ruleList->item( ruleList->currentItem() );
841  if ( item ) {
842  rule = manager->findRule( item->text() );
843  item = item->next();
844  if ( item )
845  above = manager->findRule( item->text() );
846  }
847  if ( rule && above )
848  manager->moveRuleBelow( rule, above );
849  updateRuleList();
850  updateButton();
851 }
852 
853 //============================================================================
854 //
855 // class KScoringEditor (the score edit dialog)
856 //
857 //============================================================================
858 KScoringEditor* KScoringEditor::scoreEditor = 0;
859 
860 KScoringEditor::KScoringEditor(KScoringManager* m,
861  TQWidget *parent, const char *name)
862  : KDialogBase(parent,name,false,i18n("Rule Editor"),Ok|Apply|Cancel,Ok,true), manager(m)
863 {
864  manager->pushRuleList();
865  if (!scoreEditor) scoreEditor = this;
866  kdDebug(5100) << "KScoringEditor::KScoringEditor()" << endl;
867  if (!name) setName("KScoringEditor");
868  // the left side gives an overview about all rules, the right side
869  // shows a detailed view of an selected rule
870  TQWidget *w = new TQWidget(this);
871  setMainWidget(w);
872  TQHBoxLayout *hbl = new TQHBoxLayout(w,0,spacingHint());
873  ruleLister = new RuleListWidget(manager,false,w);
874  hbl->addWidget(ruleLister);
875  ruleEditor = new RuleEditWidget(manager,w);
876  hbl->addWidget(ruleEditor);
877  connect(ruleLister,TQT_SIGNAL(ruleSelected(const TQString&)),
878  ruleEditor, TQT_SLOT(slotEditRule(const TQString&)));
879  connect(ruleLister, TQT_SIGNAL(leavingRule()),
880  ruleEditor, TQT_SLOT(updateRule()));
881  connect(ruleEditor, TQT_SIGNAL(shrink()), TQT_SLOT(slotShrink()));
882  connect(this,TQT_SIGNAL(finished()),TQT_SLOT(slotFinished()));
883  ruleLister->slotRuleSelected(0);
884  resize(550, sizeHint().height());
885 }
886 
887 void KScoringEditor::setDirty()
888 {
889  TQPushButton *applyBtn = actionButton(Apply);
890  applyBtn->setEnabled(true);
891 }
892 
893 KScoringEditor::~KScoringEditor()
894 {
895  scoreEditor = 0;
896 }
897 
898 KScoringEditor* KScoringEditor::createEditor(KScoringManager* m,
899  TQWidget *parent, const char *name)
900 {
901  if (scoreEditor) return scoreEditor;
902  else return new KScoringEditor(m,parent,name);
903 }
904 
905 void KScoringEditor::setRule(KScoringRule* r)
906 {
907  kdDebug(5100) << "KScoringEditor::setRule(" << r->getName() << ")" << endl;
908  TQString ruleName = r->getName();
909  ruleLister->slotRuleSelected(ruleName);
910 }
911 
912 void KScoringEditor::slotShrink()
913 {
914  TQTimer::singleShot(5, this, TQT_SLOT(slotDoShrink()));
915 }
916 
917 void KScoringEditor::slotDoShrink()
918 {
919  updateGeometry();
920  TQApplication::sendPostedEvents();
921  resize(width(),sizeHint().height());
922 }
923 
924 void KScoringEditor::slotApply()
925 {
926  TQString ruleName = ruleLister->currentRule();
927  KScoringRule *rule = manager->findRule(ruleName);
928  if (rule) {
929  ruleEditor->updateRule(rule);
930  ruleLister->updateRuleList(rule);
931  }
932  manager->removeTOS();
933  manager->pushRuleList();
934 }
935 
936 void KScoringEditor::slotOk()
937 {
938  slotApply();
939  manager->removeTOS();
940  KDialogBase::slotOk();
941  manager->editorReady();
942 }
943 
944 void KScoringEditor::slotCancel()
945 {
946  manager->popRuleList();
947  KDialogBase::slotCancel();
948 }
949 
950 void KScoringEditor::slotFinished()
951 {
952  delayedDestruct();
953 }
954 
955 //============================================================================
956 //
957 // class KScoringEditorWidgetDialog (a dialog for the KScoringEditorWidget)
958 //
959 //============================================================================
960 KScoringEditorWidgetDialog::KScoringEditorWidgetDialog(KScoringManager *m, const TQString& r, TQWidget *p, const char *n)
961  : KDialogBase(p,n,true,i18n("Edit Rule"),
962  KDialogBase::Ok|KDialogBase::Apply|KDialogBase::Close,
963  KDialogBase::Ok,true),
964  manager(m), ruleName(r)
965 {
966  TQFrame *f = makeMainWidget();
967  TQBoxLayout *topL = new TQVBoxLayout(f);
968  ruleEditor = new RuleEditWidget(manager,f);
969  connect(ruleEditor, TQT_SIGNAL(shrink()), TQT_SLOT(slotShrink()));
970  topL->addWidget(ruleEditor);
971  ruleEditor->slotEditRule(ruleName);
972  resize(0,0);
973 }
974 
975 void KScoringEditorWidgetDialog::slotApply()
976 {
977  KScoringRule *rule = manager->findRule(ruleName);
978  if (rule) {
979  ruleEditor->updateRule(rule);
980  ruleName = rule->getName();
981  }
982 }
983 
984 void KScoringEditorWidgetDialog::slotOk()
985 {
986  slotApply();
987  KDialogBase::slotOk();
988 }
989 
990 void KScoringEditorWidgetDialog::slotShrink()
991 {
992  TQTimer::singleShot(5, this, TQT_SLOT(slotDoShrink()));
993 }
994 
995 void KScoringEditorWidgetDialog::slotDoShrink()
996 {
997  updateGeometry();
998  TQApplication::sendPostedEvents();
999  resize(width(),sizeHint().height());
1000 }
1001 
1002 //============================================================================
1003 //
1004 // class KScoringEditorWidget (a reusable widget for config dialog...)
1005 //
1006 //============================================================================
1007 KScoringEditorWidget::KScoringEditorWidget(KScoringManager *m,TQWidget *p, const char *n)
1008  : TQWidget(p,n), manager(m)
1009 {
1010  TQBoxLayout *topL = new TQVBoxLayout(this);
1011  ruleLister = new RuleListWidget(manager,true,this);
1012  topL->addWidget(ruleLister);
1013  connect(ruleLister,TQT_SIGNAL(ruleEdited(const TQString&)),
1014  this,TQT_SLOT(slotRuleEdited(const TQString &)));
1015 }
1016 
1017 KScoringEditorWidget::~KScoringEditorWidget()
1018 {
1019  manager->editorReady();
1020 }
1021 
1022 void KScoringEditorWidget::slotRuleEdited(const TQString& ruleName)
1023 {
1024  KScoringEditorWidgetDialog dlg(manager,ruleName,this);
1025  dlg.exec();
1026  ruleLister->updateRuleList();
1027 }
1028 
1029 #include "kscoringeditor.moc"
Base class for other Action classes.
Definition: kscoring.h:84
this widget implements the action editor
void clearWidget(TQWidget *)
Called to clear a given widget.
TQWidget * createWidget(TQWidget *parent)
Because QT 2.x does not support signals/slots in template classes, we are forced to emulate this by f...
this widget implements the conditions editor
TQWidget * createWidget(TQWidget *)
Because QT 2.x does not support signals/slots in template classes, we are forced to emulate this by f...
void clearWidget(TQWidget *)
Called to clear a given widget.
Widget that manages a list of other widgets (incl.
Definition: kwidgetlister.h:66
virtual void setNumberOfShownWidgetsTo(int aNum)
Sets the number of widgets on scrren to exactly aNum.
virtual void slotClear()
Called whenever the user clicks on the 'clear' button.
void widgetRemoved()
This signal is emitted whenever a widget was removed.
TQPtrList< TQWidget > mWidgetList
The list of widgets.
virtual void addWidgetAtEnd(TQWidget *w=0)
Adds a single widget.
This widget implements the rule editor.
This widget shows a list of rules with buttons for copy, delete aso.
this widget implements an editor for one action.
this widget implements an editor for one condition.