4 Copyright (c) 2001 Mathias Waack <mathias@atoll-net.de>
5 Copyright (C) 2005 by Volker Krause <vkrause@kde.org>
7 Author: Mathias Waack <mathias@atoll-net.de>
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
20 #include "kscoringeditor.h"
24 #include <KColorCombo>
26 #include <KIconLoader>
27 #include <KIntSpinBox>
30 #include <kregexpeditorinterface.h>
31 #include <KServiceTypeTrader>
32 #include <KPushButton>
35 #include <QPushButton>
38 #include <QRadioButton>
39 #include <QApplication>
41 #include <QButtonGroup>
43 #include <QGridLayout>
45 #include <QHBoxLayout>
47 #include <QVBoxLayout>
51 static int setCurrentItem( K3ListBox
*box
, const QString
&s
)
53 int cnt
= box
->count();
54 for ( int i
=0; i
<cnt
; ++i
) {
55 if ( box
->text( i
) == s
) {
56 box
->setCurrentItem( i
);
63 //============================================================================
65 // class SingleConditionWidget (editor for one condition, used in ConditionEditWidget)
67 //============================================================================
68 SingleConditionWidget::SingleConditionWidget( KScoringManager
*m
, QWidget
*p
, const char * )
69 : QFrame( p
), manager( m
)
71 QBoxLayout
*topL
= new QVBoxLayout( this );
73 QBoxLayout
*firstRow
= new QHBoxLayout();
74 topL
->addItem( firstRow
);
75 neg
= new QCheckBox( i18n( "Not" ), this );
76 neg
->setToolTip( i18n( "Negate this condition" ) );
77 firstRow
->addWidget( neg
);
78 headers
= new KComboBox( this );
79 headers
->addItems( manager
->getDefaultHeaders() );
80 headers
->setEditable( true );
81 headers
->setToolTip( i18n( "Select the header to match this condition against" ) );
82 firstRow
->addWidget( headers
, 1 );
83 matches
= new KComboBox( this );
84 matches
->addItems( KScoringExpression::conditionNames() );
85 matches
->setToolTip( i18n( "Select the type of match" ) );
86 firstRow
->addWidget( matches
, 1 );
87 connect( matches
, SIGNAL(activated(int)), SLOT(toggleRegExpButton(int)) );
88 QHBoxLayout
*secondRow
= new QHBoxLayout();
89 secondRow
->setSpacing( 1 );
90 topL
->addItem( secondRow
);
92 expr
= new KLineEdit( this );
93 expr
->setToolTip( i18n( "The condition for the match" ) );
94 // reserve space for at least 20 characters
95 expr
->setMinimumWidth( fontMetrics().maxWidth() * 20 );
96 secondRow
->addWidget( expr
);
97 regExpButton
= new QPushButton( i18n( "Edit..." ), this );
98 secondRow
->addWidget( regExpButton
);
99 connect( regExpButton
, SIGNAL(clicked()), SLOT(showRegExpDialog()) );
101 regExpButton
->setEnabled(!KServiceTypeTrader::self()->query( "KRegExpEditor/KRegExpEditor" ).isEmpty());
103 // occupy at much width as possible
104 setSizePolicy( QSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Fixed
) );
105 setFrameStyle( Box
| Sunken
);
109 SingleConditionWidget::~SingleConditionWidget()
112 void SingleConditionWidget::setCondition( KScoringExpression
*e
)
114 neg
->setChecked( e
->isNeg() );
115 headers
->setItemText( headers
->currentIndex(), e
->getHeader() );
116 matches
->setCurrentItem( KScoringExpression::getNameForCondition( e
->getCondition() ) );
117 toggleRegExpButton( matches
->currentIndex() );
118 expr
->setText( e
->getExpression() );
121 KScoringExpression
*SingleConditionWidget::createCondition() const
123 QString head
= headers
->currentText();
124 QString match
= matches
->currentText();
125 int condType
= KScoringExpression::getConditionForName( match
);
126 match
= KScoringExpression::getTypeString( condType
);
127 QString cond
= expr
->text();
128 QString negs
= ( neg
->isChecked() ) ? "1" : "0";
129 return new KScoringExpression( head
, match
, cond
, negs
);
132 void SingleConditionWidget::clear()
134 neg
->setChecked( false );
138 void SingleConditionWidget::toggleRegExpButton( int selected
)
140 bool isRegExp
= ( KScoringExpression::MATCH
== selected
||
141 KScoringExpression::MATCHCS
== selected
) &&
142 !KServiceTypeTrader::self()->query( "KRegExpEditor/KRegExpEditor" ).isEmpty();
143 regExpButton
->setEnabled( isRegExp
);
146 void SingleConditionWidget::showRegExpDialog()
148 QDialog
*editorDialog
=
149 KServiceTypeTrader::createInstanceFromQuery
<QDialog
>(
150 "KRegExpEditor/KRegExpEditor", QString() );
151 if ( editorDialog
) {
152 KRegExpEditorInterface
*editor
= qobject_cast
<KRegExpEditorInterface
*>( editorDialog
);
153 Q_ASSERT( editor
); // This should not fail!
154 editor
->setRegExp( expr
->text() );
155 editorDialog
->exec();
156 expr
->setText( editor
->regExp() );
160 //============================================================================
162 // class ConditionEditWidget (the widget to edit the conditions of a rule)
164 //============================================================================
165 ConditionEditWidget::ConditionEditWidget( KScoringManager
*m
, QWidget
*p
, const char* )
166 : KWidgetLister( 1, 8, p
), manager( m
)
168 // create one initial widget
172 ConditionEditWidget::~ConditionEditWidget()
175 QWidget
*ConditionEditWidget::createWidget( QWidget
*parent
)
177 return new SingleConditionWidget( manager
, parent
);
180 void ConditionEditWidget::clearWidget( QWidget
*w
)
182 SingleActionWidget
*sw
= qobject_cast
<SingleActionWidget
*>(w
);
189 void ConditionEditWidget::slotEditRule( KScoringRule
*rule
)
191 KScoringRule::ScoreExprList l
;
193 l
= rule
->getExpressions();
195 if ( !rule
|| l
.count() == 0 ) {
198 setNumberOfShownWidgetsTo( l
.count() );
199 KScoringExpression
*e
= l
.first();
200 QList
<QWidget
*> widgetList
= widgets();
201 QList
<QWidget
*>::ConstIterator it
= widgetList
.constBegin();
202 while ( e
&& it
!= widgetList
.constEnd() ) {
203 SingleConditionWidget
*scw
= qobject_cast
<SingleConditionWidget
*>( *it
);
204 scw
->setCondition( e
);
211 void ConditionEditWidget::updateRule( KScoringRule
*rule
)
213 rule
->cleanExpressions();
214 foreach ( QWidget
* w
, widgets() ) {
215 SingleConditionWidget
*saw
= qobject_cast
<SingleConditionWidget
*>( w
);
217 rule
->addExpression( saw
->createCondition() );
219 kWarning(5100) <<"there is a widget in ConditionEditWidget"
220 << "which isn't a KPIM::SingleConditionWidget";
225 //============================================================================
227 // class SingleActionWidget (editor for one action, used in ActionEditWidget)
229 //============================================================================
230 SingleActionWidget::SingleActionWidget( KScoringManager
*m
, QWidget
*p
, const char *n
)
231 : QWidget( p
), notifyEditor( 0 ), scoreEditor( 0 ),
232 colorEditor( 0 ), manager( m
)
235 QHBoxLayout
*topL
= new QHBoxLayout( this );
236 topL
->setMargin( 0 );
237 topL
->setSpacing( 5 );
239 types
= new KComboBox( this );
240 types
->setEditable( false );
241 topL
->addWidget( types
);
242 stack
= new QStackedWidget( this );
243 topL
->addWidget( stack
);
245 dummyLabel
= new QLabel( i18n( "Select an action." ), stack
);
246 stack
->insertWidget( 0, dummyLabel
);
248 // init widget stack and the types combo box
250 types
->addItem( QString() );
251 QStringList l
= ActionBase::userNames();
252 for ( QStringList::Iterator it
= l
.begin(); it
!= l
.end(); ++it
) {
254 int feature
= ActionBase::getTypeForUserName( name
);
255 if ( manager
->hasFeature( feature
) ) {
256 types
->addItem( name
);
259 case ActionBase::SETSCORE
:
260 w
= scoreEditor
= new KIntSpinBox( stack
);
261 scoreEditor
->setRange( -99999, 99999 );
262 scoreEditor
->setValue( 30 );
264 case ActionBase::NOTIFY
:
265 w
= notifyEditor
= new KLineEdit( stack
);
267 case ActionBase::COLOR
:
268 w
= colorEditor
= new KColorCombo( stack
);
270 case ActionBase::MARKASREAD
:
271 w
= new QLabel( stack
); // empty dummy
275 stack
->insertWidget( index
++, w
);
280 connect( types
, SIGNAL(activated(int)), stack
, SLOT(setCurrentIndex(int)) );
282 // raise the dummy label
283 types
->setCurrentIndex( 0 );
284 stack
->setCurrentWidget( dummyLabel
);
287 SingleActionWidget::~SingleActionWidget()
291 void SingleActionWidget::setAction( ActionBase
*act
)
293 kDebug(5100) <<"SingleActionWidget::setAction()";
295 int index
= types
->findText( act
->userName() );
297 kWarning(5100) <<"unknown action in SingleActionWidget::setAction()";
301 types
->setCurrentIndex( index
);
302 stack
->setCurrentIndex( index
);
303 switch( act
->getType() ) {
304 case ActionBase::SETSCORE
:
305 scoreEditor
->setValue( act
->getValueString().toInt() );
307 case ActionBase::NOTIFY
:
308 notifyEditor
->setText( act
->getValueString() );
310 case ActionBase::COLOR
:
311 colorEditor
->setColor( QColor( act
->getValueString() ) );
313 case ActionBase::MARKASREAD
:
317 kWarning(5100) <<"unknown action type in SingleActionWidget::setAction()";
321 ActionBase
*SingleActionWidget::createAction() const
323 // no action selected...
324 if ( types
->currentText().isEmpty() ) {
328 int type
= ActionBase::getTypeForUserName( types
->currentText() );
330 case ActionBase::SETSCORE
:
331 return new ActionSetScore( scoreEditor
->value() );
332 case ActionBase::NOTIFY
:
333 return new ActionNotify( notifyEditor
->text() );
334 case ActionBase::COLOR
:
335 return new ActionColor( colorEditor
->color().name() );
336 case ActionBase::MARKASREAD
:
337 return new ActionMarkAsRead();
339 kWarning(5100) <<"unknown action type in SingleActionWidget::getValue()";
344 void SingleActionWidget::clear()
347 scoreEditor
->setValue( 0 );
349 if ( notifyEditor
) {
350 notifyEditor
->clear();
353 colorEditor
->setCurrentIndex( 0 );
356 types
->setCurrentIndex( 0 );
357 stack
->setCurrentWidget( dummyLabel
);
360 //============================================================================
362 // class ActionEditWidget (the widget to edit the actions of a rule)
364 //============================================================================
365 ActionEditWidget::ActionEditWidget( KScoringManager
*m
, QWidget
*p
, const char* )
366 : KWidgetLister( 1, 8, p
), manager( m
)
368 // create one initial widget
372 ActionEditWidget::~ActionEditWidget()
375 QWidget
*ActionEditWidget::createWidget( QWidget
*parent
)
377 return new SingleActionWidget( manager
, parent
);
380 void ActionEditWidget::slotEditRule( KScoringRule
*rule
)
382 KScoringRule::ActionList l
;
384 l
= rule
->getActions();
386 if ( !rule
|| l
.count() == 0 ) {
389 setNumberOfShownWidgetsTo( l
.count() );
390 ActionBase
*act
= l
.first();
391 QList
<QWidget
*> widgetList
= widgets();
392 QList
<QWidget
*>::ConstIterator it
= widgetList
.constBegin();
393 while ( act
&& it
!= widgetList
.constEnd() ) {
394 SingleActionWidget
*saw
= qobject_cast
<SingleActionWidget
*>( *it
);
395 saw
->setAction( act
);
402 void ActionEditWidget::updateRule( KScoringRule
*rule
)
404 rule
->cleanActions();
405 foreach ( QWidget
*w
, widgets() ) {
406 SingleActionWidget
*saw
= qobject_cast
<SingleActionWidget
*>( w
);
408 ActionBase
*act
= saw
->createAction();
410 rule
->addAction( act
);
413 kWarning(5100) <<"there is a widget in ActionEditWidget"
414 << "which isn't a KPIM::SingleActionWidget";
419 void ActionEditWidget::clearWidget( QWidget
*w
)
421 SingleActionWidget
*sw
= qobject_cast
<SingleActionWidget
*>(w
);
428 //============================================================================
430 // class RuleEditWidget (the widget to edit one rule)
432 //============================================================================
433 RuleEditWidget::RuleEditWidget( KScoringManager
*m
, QWidget
*p
, const char *n
)
434 : QWidget( p
), dirty( false ), manager( m
), oldRuleName( QString() )
436 kDebug(5100) <<"RuleEditWidget::RuleEditWidget()";
438 setObjectName( n
!= 0 ? n
: "RuleEditWidget" );
440 QVBoxLayout
*topLayout
= new QVBoxLayout( this );
441 topLayout
->setMargin( 5 );
442 topLayout
->setSpacing( KDialog::spacingHint() );
444 //------------- Name, Servers, Groups ---------------------
445 QGroupBox
*groupB
= new QGroupBox( i18n( "Properties" ), this );
446 topLayout
->addWidget( groupB
);
447 QGridLayout
*groupL
= new QGridLayout( groupB
);
448 groupL
->setMargin( 8 );
449 groupL
->setSpacing( 5 );
451 groupL
->addItem( new QSpacerItem( 0, fontMetrics().lineSpacing() - 4 ), 0, 0 );
454 ruleNameEdit
= new KLineEdit( groupB
);
455 groupL
->addWidget( ruleNameEdit
, 1, 1 );
456 QLabel
*ruleNameLabel
= new QLabel( i18nc( "@label rule name", "&Name:" ), groupB
);
457 ruleNameLabel
->setBuddy( ruleNameEdit
);
458 ruleNameLabel
->setObjectName( "ruleNameLabel" );
459 groupL
->addWidget( ruleNameLabel
, 1, 0 );
462 groupsEdit
= new KLineEdit( groupB
);
463 groupL
->addWidget( groupsEdit
, 2, 1 );
464 QLabel
*groupsLabel
= new QLabel( i18n( "&Groups:" ), groupB
);
465 groupsLabel
->setBuddy( groupsEdit
);
466 groupsLabel
->setObjectName( "groupsLabel" );
467 groupL
->addWidget( groupsLabel
, 2, 0 );
469 QPushButton
*groupsBtn
= new QPushButton( i18n( "A&dd Group" ), groupB
);
470 connect( groupsBtn
, SIGNAL(clicked()), SLOT(slotAddGroup()) );
471 groupL
->addWidget( groupsBtn
, 3, 0 );
473 groupsBox
= new KComboBox( false, groupB
);
474 groupsBox
->setDuplicatesEnabled( false );
475 groupsBox
->addItems( manager
->getGroups() );
476 groupsBox
->setSizePolicy( QSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Fixed
) );
477 groupL
->addWidget( groupsBox
, 3, 1 );
480 expireCheck
= new QCheckBox( i18n( "&Expire rule automatically" ), groupB
);
481 groupL
->addWidget( expireCheck
, 4, 0, 1, 2 );
482 expireEdit
= new KIntSpinBox( groupB
);
483 expireEdit
->setRange( 1, 9999 );
484 expireEdit
->setValue( 30 );
485 slotExpireEditChanged(30 );
486 connect( expireEdit
, SIGNAL(valueChanged(int)), SLOT(slotExpireEditChanged(int)) );
487 groupL
->addWidget( expireEdit
, 5, 1 );
488 expireLabel
= new QLabel( i18n( "&Rule is valid for:" ), groupB
);
489 expireLabel
->setBuddy( expireEdit
);
490 expireLabel
->setObjectName( "expireLabel" );
491 groupL
->addWidget( expireLabel
, 5, 0 );
492 expireLabel
->setEnabled( false );
493 expireEdit
->setEnabled( false );
495 connect( expireCheck
, SIGNAL(toggled(bool)), expireLabel
, SLOT(setEnabled(bool)) );
496 connect( expireCheck
, SIGNAL(toggled(bool)), expireEdit
, SLOT(setEnabled(bool)) );
498 //------------- Conditions ---------------------
499 QGroupBox
*groupConds
= new QGroupBox( i18n( "Conditions" ), this );
500 topLayout
->addWidget( groupConds
);
501 QGridLayout
*condL
= new QGridLayout( groupConds
);
502 condL
->setMargin( 8 );
503 condL
->setSpacing( 5 );
505 condL
->addItem( new QSpacerItem( 0, fontMetrics().lineSpacing() - 4 ), 0, 0 );
507 QButtonGroup
*buttonGroup
= new QButtonGroup( groupConds
);
509 linkModeAnd
= new QRadioButton( i18n( "Match a&ll conditions" ), groupConds
);
510 buttonGroup
->addButton( linkModeAnd
);
511 condL
->addWidget( linkModeAnd
, 1, 0 );
512 linkModeOr
= new QRadioButton( i18n( "Matc&h any condition" ), groupConds
);
513 buttonGroup
->addButton( linkModeOr
);
514 condL
->addWidget( linkModeOr
, 1, 1 );
515 linkModeAnd
->setChecked( true );
517 condEditor
= new ConditionEditWidget( manager
, groupConds
);
518 condL
->addWidget( condEditor
, 2, 0, 1, 2 );
519 connect( condEditor
, SIGNAL(widgetRemoved()), this, SLOT(slotShrink()) );
521 //------------- Actions ---------------------
522 QGroupBox
*groupActions
= new QGroupBox( i18n( "Actions" ), this );
523 topLayout
->addWidget( groupActions
);
524 QBoxLayout
*actionL
= new QVBoxLayout( groupActions
);
525 actionL
->setMargin( 8 );
526 actionL
->setSpacing( 5 );
527 actionL
->addSpacing( fontMetrics().lineSpacing() - 4 );
528 actionEditor
= new ActionEditWidget( manager
, groupActions
);
529 actionL
->addWidget( actionEditor
);
530 connect( actionEditor
, SIGNAL(widgetRemoved()), this, SLOT(slotShrink()) );
532 topLayout
->addStretch( 1 );
534 kDebug(5100) <<"constructed RuleEditWidget";
537 RuleEditWidget::~RuleEditWidget()
541 void RuleEditWidget::slotEditRule( const QString
&ruleName
)
543 KScoringRule
*rule
= manager
->findRule( ruleName
);
545 kDebug(5100) <<"no rule for ruleName" << ruleName
;
549 oldRuleName
= rule
->getName();
550 ruleNameEdit
->setText( rule
->getName() );
551 groupsEdit
->setText( rule
->getGroups().join( ";" ) );
553 bool b
= rule
->getExpireDate().isValid();
554 expireCheck
->setChecked( b
);
555 expireEdit
->setEnabled( b
);
556 expireLabel
->setEnabled( b
);
558 expireEdit
->setValue( QDate::currentDate().daysTo( rule
->getExpireDate() ) );
560 expireEdit
->setValue( 30 );
562 if ( rule
->getLinkMode() == KScoringRule::AND
) {
563 linkModeAnd
->setChecked( true );
565 linkModeOr
->setChecked( true );
568 condEditor
->slotEditRule( rule
);
569 actionEditor
->slotEditRule( rule
);
571 kDebug(5100) <<"RuleEditWidget::slotEditRule() ready";
574 void RuleEditWidget::clearContents()
576 ruleNameEdit
->setText( "" );
577 groupsEdit
->setText( "" );
578 expireCheck
->setChecked( false );
579 expireEdit
->setValue( 30 );
580 expireEdit
->setEnabled( false );
581 condEditor
->slotEditRule( 0 );
582 actionEditor
->slotEditRule( 0 );
586 void RuleEditWidget::updateRule( KScoringRule
*rule
)
589 QString groups
= groupsEdit
->text();
590 if ( groups
.isEmpty() ) {
591 rule
->setGroups( QStringList( ".*" ) );
593 rule
->setGroups( groups
.split( ';', QString::SkipEmptyParts
) );
595 bool b
= expireCheck
->isChecked();
597 rule
->setExpireDate( QDate::currentDate().addDays( expireEdit
->value() ) );
599 rule
->setExpireDate( QDate() );
601 actionEditor
->updateRule( rule
);
602 rule
->setLinkMode( linkModeAnd
->isChecked() ? KScoringRule::AND
: KScoringRule::OR
);
603 condEditor
->updateRule( rule
);
604 if ( rule
->getName() != ruleNameEdit
->text() ) {
605 manager
->setRuleName( rule
, ruleNameEdit
->text() );
609 void RuleEditWidget::updateRule()
611 KScoringRule
*rule
= manager
->findRule( oldRuleName
);
617 void RuleEditWidget::slotAddGroup()
619 QString grp
= groupsBox
->currentText();
620 if ( grp
.isEmpty() ) {
623 QString txt
= groupsEdit
->text().trimmed();
624 if ( txt
== ".*" || txt
.isEmpty() ) {
625 groupsEdit
->setText( grp
);
627 groupsEdit
->setText( txt
+ ';' + grp
);
631 void RuleEditWidget::setDirty()
633 kDebug(5100) <<"RuleEditWidget::setDirty()";
640 void RuleEditWidget::slotShrink()
645 void RuleEditWidget::slotExpireEditChanged( int value
)
647 expireEdit
->setSuffix( i18np( " day", " days", value
) );
650 //============================================================================
652 // class RuleListWidget (the widget for managing a list of rules)
654 //============================================================================
655 RuleListWidget::RuleListWidget( KScoringManager
*m
, bool standalone
, QWidget
*p
, const char *n
)
656 : QWidget( p
), alone( standalone
), manager( m
)
658 kDebug(5100) <<"RuleListWidget::RuleListWidget()";
659 setObjectName( n
!= 0 ? n
: "RuleListWidget" );
660 QVBoxLayout
*topL
= new QVBoxLayout( this );
661 topL
->setMargin( standalone
? 0 : 5 );
662 topL
->setSpacing( KDialog::spacingHint() );
664 ruleList
= new K3ListBox( this );
666 connect( ruleList
, SIGNAL(doubleClicked(Q3ListBoxItem
*)),
667 this, SLOT(slotEditRule(Q3ListBoxItem
*)) );
668 connect( ruleList
, SIGNAL(returnPressed(Q3ListBoxItem
*)),
669 this, SLOT(slotEditRule(Q3ListBoxItem
*)) );
671 connect( ruleList
, SIGNAL(currentChanged(Q3ListBoxItem
*)),
672 this, SLOT(slotRuleSelected(Q3ListBoxItem
*)) );
673 topL
->addWidget( ruleList
);
675 QHBoxLayout
*btnL
= new QHBoxLayout();
676 btnL
->setSpacing( KDialog::spacingHint() );
678 topL
->addItem( btnL
);
680 mRuleUp
= new QPushButton( this );
681 mRuleUp
->setIcon( KIcon( "go-up" ) );
682 mRuleUp
->setToolTip( i18n( "Move rule up" ) );
683 btnL
->addWidget( mRuleUp
);
684 connect( mRuleUp
, SIGNAL(clicked()), SLOT(slotRuleUp()) );
685 mRuleDown
= new QPushButton( this );
686 mRuleDown
->setIcon( KIcon( "go-down" ) );
687 mRuleDown
->setToolTip( i18n( "Move rule down" ) );
688 btnL
->addWidget( mRuleDown
);
689 connect( mRuleDown
, SIGNAL(clicked()), SLOT(slotRuleDown()) );
691 btnL
= new QHBoxLayout();
692 btnL
->setSpacing( KDialog::spacingHint() );
694 topL
->addItem( btnL
);
697 newRule
= new QPushButton( this );
698 newRule
->setIcon( KIcon( "document-new" ) );
699 newRule
->setToolTip( i18n( "New rule" ) ),
700 btnL
->addWidget( newRule
);
701 connect( newRule
, SIGNAL(clicked()), this, SLOT(slotNewRule()) );
702 // if we're standalone, we need an additional edit button
704 editRule
= new QPushButton( this );
705 editRule
->setIcon( KIcon( "document-properties" ) );
706 editRule
->setToolTip( i18n( "Edit rule" ) );
707 btnL
->addWidget( editRule
);
708 connect( editRule
, SIGNAL(clicked()), this, SLOT(slotEditRule()) );
710 delRule
= new QPushButton( this );
711 delRule
->setIcon( KIcon( "edit-delete" ) );
712 delRule
->setToolTip( i18n( "Remove rule" ) );
713 btnL
->addWidget( delRule
);
714 connect( delRule
, SIGNAL(clicked()), this, SLOT(slotDelRule()) );
715 copyRule
= new QPushButton( this );
716 copyRule
->setIcon( KIcon( "edit-copy" ) );
717 copyRule
->setToolTip( i18n( "Copy rule" ) );
718 btnL
->addWidget( copyRule
);
719 connect( copyRule
, SIGNAL(clicked()), this, SLOT(slotCopyRule()) );
722 QBoxLayout
*filterL
= new QVBoxLayout();
723 topL
->addItem( filterL
);
724 filterL
->setSpacing( KDialog::spacingHint() );
726 KComboBox
*filterBox
= new KComboBox( this );
727 QStringList l
= m
->getGroups();
728 filterBox
->addItem( i18n( "<placeholder>all groups</placeholder>" ) );
729 filterBox
->addItems( l
);
730 filterBox
->setSizePolicy( QSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Fixed
) );
731 connect( filterBox
, SIGNAL(activated(QString
)),
732 this, SLOT(slotGroupFilter(QString
)) );
733 slotGroupFilter( i18n( "<placeholder>all groups</placeholder>" ) );
734 QLabel
*lab
= new QLabel( i18n( "Sho&w only rules for group:" ), this );
735 lab
->setBuddy( filterBox
);
737 filterL
->addWidget( lab
);
738 filterL
->addWidget( filterBox
);
740 connect( manager
, SIGNAL(changedRules()), this, SLOT(updateRuleList()) );
741 connect( manager
, SIGNAL(changedRuleName(QString
,QString
)),
742 this, SLOT(slotRuleNameChanged(QString
,QString
)) );
748 RuleListWidget::~RuleListWidget()
752 void RuleListWidget::updateButton()
754 bool state
= ruleList
->count() > 0;
756 editRule
->setEnabled( state
);
758 delRule
->setEnabled( state
);
759 copyRule
->setEnabled( state
);
761 Q3ListBoxItem
*item
= ruleList
->item( ruleList
->currentItem() );
763 mRuleUp
->setEnabled( item
->prev() != 0 );
764 mRuleDown
->setEnabled( item
->next() != 0 );
768 void RuleListWidget::updateRuleList()
771 kDebug(5100) <<"RuleListWidget::updateRuleList()";
772 QString curr
= ruleList
->currentText();
774 if ( group
== i18n( "<placeholder>all groups</placeholder>" ) ) {
775 QStringList l
= manager
->getRuleNames();
776 ruleList
->insertStringList( l
);
778 KScoringManager::ScoringRuleList l
= manager
->getAllRules();
779 for ( KScoringRule
*rule
= l
.first(); rule
; rule
= l
.next() ) {
780 if ( rule
->matchGroup( group
) ) {
781 ruleList
->insertItem( rule
->getName() );
785 int index
= setCurrentItem( ruleList
, curr
);
787 ruleList
->setCurrentItem( 0 );
788 slotRuleSelected( ruleList
->currentText() );
790 slotRuleSelected( curr
);
794 void RuleListWidget::updateRuleList( const KScoringRule
*rule
)
796 kDebug(5100) <<"RuleListWidget::updateRuleList(" << rule
->getName() <<")";
797 QString name
= rule
->getName();
799 slotRuleSelected(name
);
802 void RuleListWidget::slotRuleNameChanged( const QString
&oldName
, const QString
&newName
)
804 int ind
= ruleList
->currentItem();
805 for ( uint i
=0; i
<ruleList
->count(); ++i
) {
806 if ( ruleList
->text(i
) == oldName
) {
807 ruleList
->changeItem( newName
, i
);
808 ruleList
->setCurrentItem( ind
);
814 void RuleListWidget::slotEditRule( const QString
&s
)
816 emit
ruleEdited( s
);
819 void RuleListWidget::slotEditRule()
821 if ( ruleList
->currentItem() >= 0 ) {
822 emit
ruleEdited( ruleList
->currentText() );
823 } else if ( ruleList
->count() == 0 ) {
824 emit
ruleEdited( QString() );
828 void RuleListWidget::slotEditRule( Q3ListBoxItem
*item
)
830 slotEditRule( item
->text() );
833 void RuleListWidget::slotGroupFilter( const QString
&s
)
839 void RuleListWidget::slotRuleSelected( const QString
&ruleName
)
842 kDebug(5100) <<"RuleListWidget::slotRuleSelected(" << ruleName
<<")";
843 if ( ruleName
!= ruleList
->currentText() ) {
844 setCurrentItem( ruleList
, ruleName
);
847 emit
ruleSelected( ruleName
);
850 void RuleListWidget::slotRuleSelected( Q3ListBoxItem
*item
)
855 QString ruleName
= item
->text();
856 slotRuleSelected( ruleName
);
859 void RuleListWidget::slotRuleSelected( int index
)
862 if ( idx
>= ruleList
->count() ) {
865 QString ruleName
= ruleList
->text( index
);
866 slotRuleSelected( ruleName
);
869 void RuleListWidget::slotNewRule()
872 KScoringRule
*rule
= manager
->addRule();
873 updateRuleList( rule
);
875 slotEditRule( rule
->getName() );
880 void RuleListWidget::slotDelRule()
882 KScoringRule
*rule
= manager
->findRule( ruleList
->currentText() );
884 manager
->deleteRule( rule
);
886 // goto the next rule
893 void RuleListWidget::slotCopyRule()
896 QString ruleName
= ruleList
->currentText();
897 KScoringRule
*rule
= manager
->findRule( ruleName
);
899 KScoringRule
*nrule
= manager
->copyRule( rule
);
900 updateRuleList( nrule
);
901 slotEditRule( nrule
->getName() );
906 void RuleListWidget::slotRuleUp()
908 KScoringRule
*rule
= 0, *below
= 0;
909 Q3ListBoxItem
*item
= ruleList
->item( ruleList
->currentItem() );
911 rule
= manager
->findRule( item
->text() );
914 below
= manager
->findRule( item
->text() );
917 if ( rule
&& below
) {
918 manager
->moveRuleAbove( rule
, below
);
924 void RuleListWidget::slotRuleDown()
926 KScoringRule
*rule
= 0, *above
= 0;
927 Q3ListBoxItem
*item
= ruleList
->item( ruleList
->currentItem() );
929 rule
= manager
->findRule( item
->text() );
932 above
= manager
->findRule( item
->text() );
935 if ( rule
&& above
) {
936 manager
->moveRuleBelow( rule
, above
);
942 //============================================================================
944 // class KScoringEditor (the score edit dialog)
946 //============================================================================
947 KScoringEditor
*KScoringEditor::scoreEditor
= 0;
949 KScoringEditor::KScoringEditor( KScoringManager
*m
, QWidget
*parent
)
950 : KDialog( parent
), manager( m
)
952 setCaption( i18n( "Rule Editor" ) );
953 setButtons( Ok
|Apply
|Cancel
);
954 setDefaultButton( Ok
);
956 showButtonSeparator( true );
957 manager
->pushRuleList();
958 if ( !scoreEditor
) {
961 kDebug(5100) <<"KScoringEditor::KScoringEditor()";
962 // the left side gives an overview about all rules, the right side
963 // shows a detailed view of an selected rule
964 QWidget
*w
= new QWidget( this );
966 QHBoxLayout
*hbl
= new QHBoxLayout( w
);
968 hbl
->setSpacing( spacingHint() );
970 ruleLister
= new RuleListWidget( manager
, false, w
);
971 hbl
->addWidget( ruleLister
);
972 ruleEditor
= new RuleEditWidget( manager
, w
);
973 hbl
->addWidget( ruleEditor
);
974 connect( ruleLister
, SIGNAL(ruleSelected(QString
)),
975 ruleEditor
, SLOT(slotEditRule(QString
)) );
976 connect( ruleLister
, SIGNAL(leavingRule()), ruleEditor
, SLOT(updateRule()) );
977 connect( ruleEditor
, SIGNAL(shrink()), SLOT(slotShrink()) );
978 connect( this, SIGNAL(finished()), SLOT(slotFinished()) );
979 connect( this, SIGNAL(okClicked()), SLOT(slotOk()) );
980 connect( this, SIGNAL(cancelClicked()), SLOT(slotCancel()) );
981 connect( this, SIGNAL(applyClicked()), SLOT(slotApply()) );
982 ruleLister
->slotRuleSelected( 0 );
983 resize( 550, sizeHint().height() );
986 void KScoringEditor::setDirty()
988 enableButton( Apply
, true );
991 KScoringEditor::~KScoringEditor()
996 KScoringEditor
*KScoringEditor::createEditor( KScoringManager
*m
, QWidget
*parent
)
1001 return new KScoringEditor( m
, parent
);
1005 void KScoringEditor::setRule( KScoringRule
*r
)
1007 kDebug(5100) <<"KScoringEditor::setRule(" << r
->getName() <<")";
1008 QString ruleName
= r
->getName();
1009 ruleLister
->slotRuleSelected( ruleName
);
1012 void KScoringEditor::slotShrink()
1014 QTimer::singleShot( 5, this, SLOT(slotDoShrink()) );
1017 void KScoringEditor::slotDoShrink()
1020 QApplication::sendPostedEvents();
1021 resize( width(), sizeHint().height() );
1024 void KScoringEditor::slotApply()
1026 QString ruleName
= ruleLister
->currentRule();
1027 KScoringRule
*rule
= manager
->findRule( ruleName
);
1029 ruleEditor
->updateRule( rule
);
1030 ruleLister
->updateRuleList( rule
);
1032 manager
->removeTOS();
1033 manager
->pushRuleList();
1036 void KScoringEditor::slotOk()
1039 manager
->removeTOS();
1040 manager
->editorReady();
1043 void KScoringEditor::slotCancel()
1045 manager
->popRuleList();
1049 void KScoringEditor::slotFinished()
1054 //============================================================================
1056 // class KScoringEditorWidgetDialog (a dialog for the KScoringEditorWidget)
1058 //============================================================================
1059 KScoringEditorWidgetDialog::KScoringEditorWidgetDialog( KScoringManager
*m
,
1062 : KDialog( p
), manager( m
), ruleName( r
)
1064 setCaption( i18n( "Edit Rule" ) );
1065 setButtons( KDialog::Ok
|KDialog::Apply
|KDialog::Cancel
);
1066 setDefaultButton( KDialog::Ok
);
1068 showButtonSeparator( true );
1069 QFrame
*f
= new QFrame( this );
1071 QBoxLayout
*topL
= new QVBoxLayout( f
);
1072 ruleEditor
= new RuleEditWidget( manager
, f
);
1073 connect( ruleEditor
, SIGNAL(shrink()), SLOT(slotShrink()) );
1074 connect( this, SIGNAL(okClicked()), SLOT(slotOk()) );
1075 topL
->addWidget( ruleEditor
);
1076 ruleEditor
->slotEditRule( ruleName
);
1080 void KScoringEditorWidgetDialog::slotApply()
1082 KScoringRule
*rule
= manager
->findRule( ruleName
);
1084 ruleEditor
->updateRule( rule
);
1085 ruleName
= rule
->getName();
1089 void KScoringEditorWidgetDialog::slotOk()
1095 void KScoringEditorWidgetDialog::slotShrink()
1097 QTimer::singleShot( 5, this, SLOT(slotDoShrink()) );
1100 void KScoringEditorWidgetDialog::slotDoShrink()
1103 QApplication::sendPostedEvents();
1104 resize( width(), sizeHint().height() );
1107 //============================================================================
1109 // class KScoringEditorWidget (a reusable widget for config dialog...)
1111 //============================================================================
1112 KScoringEditorWidget::KScoringEditorWidget( KScoringManager
*m
, QWidget
*p
, const char *n
)
1113 : QWidget( p
), manager( m
)
1116 QBoxLayout
*topL
= new QVBoxLayout( this );
1117 ruleLister
= new RuleListWidget( manager
, true, this );
1118 topL
->addWidget( ruleLister
);
1119 connect( ruleLister
, SIGNAL(ruleEdited(QString
)),
1120 this, SLOT(slotRuleEdited(QString
)) );
1123 KScoringEditorWidget::~KScoringEditorWidget()
1125 manager
->editorReady();
1128 void KScoringEditorWidget::slotRuleEdited( const QString
&ruleName
)
1130 KScoringEditorWidgetDialog
dlg( manager
, ruleName
, this );
1132 ruleLister
->updateRuleList();
1135 #include "kscoringeditor.moc"