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