mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-24 10:52:52 +00:00
1134 lines
33 KiB
C++
1134 lines
33 KiB
C++
/*
|
|
kscoringeditor.cpp
|
|
|
|
Copyright (c) 2001 Mathias Waack <mathias@atoll-net.de>
|
|
Copyright (C) 2005 by Volker Krause <vkrause@kde.org>
|
|
|
|
Author: Mathias Waack <mathias@atoll-net.de>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
|
|
*/
|
|
|
|
#undef QT_NO_COMPAT
|
|
|
|
#include "kscoringeditor.h"
|
|
#include "kscoring.h"
|
|
|
|
#include <KDebug>
|
|
#include <KColorCombo>
|
|
#include <KComboBox>
|
|
#include <KIconLoader>
|
|
#include <KIntSpinBox>
|
|
#include <KLineEdit>
|
|
#include <KLocale>
|
|
#include <kregexpeditorinterface.h>
|
|
#include <KServiceTypeTrader>
|
|
#include <KPushButton>
|
|
|
|
#include <QLabel>
|
|
#include <QPushButton>
|
|
#include <QLayout>
|
|
#include <QCheckBox>
|
|
#include <QRadioButton>
|
|
#include <QApplication>
|
|
#include <QTimer>
|
|
#include <QButtonGroup>
|
|
#include <QGroupBox>
|
|
#include <QGridLayout>
|
|
#include <QFrame>
|
|
#include <QHBoxLayout>
|
|
#include <QBoxLayout>
|
|
#include <QVBoxLayout>
|
|
|
|
using namespace KPIM;
|
|
|
|
static int setCurrentItem( K3ListBox *box, const QString &s )
|
|
{
|
|
int cnt = box->count();
|
|
for ( int i=0; i<cnt; ++i ) {
|
|
if ( box->text( i ) == s ) {
|
|
box->setCurrentItem( i );
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class SingleConditionWidget (editor for one condition, used in ConditionEditWidget)
|
|
//
|
|
//============================================================================
|
|
SingleConditionWidget::SingleConditionWidget( KScoringManager *m, QWidget *p, const char * )
|
|
: QFrame( p ), manager( m )
|
|
{
|
|
QBoxLayout *topL = new QVBoxLayout( this );
|
|
topL->setMargin( 5 );
|
|
QBoxLayout *firstRow = new QHBoxLayout();
|
|
topL->addItem( firstRow );
|
|
neg = new QCheckBox( i18n( "Not" ), this );
|
|
neg->setToolTip( i18n( "Negate this condition" ) );
|
|
firstRow->addWidget( neg );
|
|
headers = new KComboBox( this );
|
|
headers->addItems( manager->getDefaultHeaders() );
|
|
headers->setEditable( true );
|
|
headers->setToolTip( i18n( "Select the header to match this condition against" ) );
|
|
firstRow->addWidget( headers, 1 );
|
|
matches = new KComboBox( this );
|
|
matches->addItems( KScoringExpression::conditionNames() );
|
|
matches->setToolTip( i18n( "Select the type of match" ) );
|
|
firstRow->addWidget( matches, 1 );
|
|
connect( matches, SIGNAL(activated(int)), SLOT(toggleRegExpButton(int)) );
|
|
QHBoxLayout *secondRow = new QHBoxLayout();
|
|
secondRow->setSpacing( 1 );
|
|
topL->addItem( secondRow );
|
|
|
|
expr = new KLineEdit( this );
|
|
expr->setToolTip( i18n( "The condition for the match" ) );
|
|
// reserve space for at least 20 characters
|
|
expr->setMinimumWidth( fontMetrics().maxWidth() * 20 );
|
|
secondRow->addWidget( expr );
|
|
regExpButton = new QPushButton( i18n( "Edit..." ), this );
|
|
secondRow->addWidget( regExpButton );
|
|
connect( regExpButton, SIGNAL(clicked()), SLOT(showRegExpDialog()) );
|
|
|
|
regExpButton->setEnabled(!KServiceTypeTrader::self()->query( "KRegExpEditor/KRegExpEditor" ).isEmpty());
|
|
|
|
// occupy at much width as possible
|
|
setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
|
|
setFrameStyle( Box | Sunken );
|
|
setLineWidth( 1 );
|
|
}
|
|
|
|
SingleConditionWidget::~SingleConditionWidget()
|
|
{}
|
|
|
|
void SingleConditionWidget::setCondition( KScoringExpression *e )
|
|
{
|
|
neg->setChecked( e->isNeg() );
|
|
headers->setItemText( headers->currentIndex(), e->getHeader() );
|
|
matches->setCurrentItem( KScoringExpression::getNameForCondition( e->getCondition() ) );
|
|
toggleRegExpButton( matches->currentIndex() );
|
|
expr->setText( e->getExpression() );
|
|
}
|
|
|
|
KScoringExpression *SingleConditionWidget::createCondition() const
|
|
{
|
|
QString head = headers->currentText();
|
|
QString match = matches->currentText();
|
|
int condType = KScoringExpression::getConditionForName( match );
|
|
match = KScoringExpression::getTypeString( condType );
|
|
QString cond = expr->text();
|
|
QString negs = ( neg->isChecked() ) ? "1" : "0";
|
|
return new KScoringExpression( head, match, cond, negs );
|
|
}
|
|
|
|
void SingleConditionWidget::clear()
|
|
{
|
|
neg->setChecked( false );
|
|
expr->clear();
|
|
}
|
|
|
|
void SingleConditionWidget::toggleRegExpButton( int selected )
|
|
{
|
|
bool isRegExp = ( KScoringExpression::MATCH == selected ||
|
|
KScoringExpression::MATCHCS == selected ) &&
|
|
!KServiceTypeTrader::self()->query( "KRegExpEditor/KRegExpEditor" ).isEmpty();
|
|
regExpButton->setEnabled( isRegExp );
|
|
}
|
|
|
|
void SingleConditionWidget::showRegExpDialog()
|
|
{
|
|
QDialog *editorDialog =
|
|
KServiceTypeTrader::createInstanceFromQuery<QDialog>(
|
|
"KRegExpEditor/KRegExpEditor", QString() );
|
|
if ( editorDialog ) {
|
|
KRegExpEditorInterface *editor = qobject_cast<KRegExpEditorInterface *>( editorDialog );
|
|
Q_ASSERT( editor ); // This should not fail!
|
|
editor->setRegExp( expr->text() );
|
|
editorDialog->exec();
|
|
expr->setText( editor->regExp() );
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class ConditionEditWidget (the widget to edit the conditions of a rule)
|
|
//
|
|
//============================================================================
|
|
ConditionEditWidget::ConditionEditWidget( KScoringManager *m, QWidget *p, const char* )
|
|
: KWidgetLister( 1, 8, p ), manager( m )
|
|
{
|
|
// create one initial widget
|
|
addWidgetAtEnd();
|
|
}
|
|
|
|
ConditionEditWidget::~ConditionEditWidget()
|
|
{}
|
|
|
|
QWidget *ConditionEditWidget::createWidget( QWidget *parent )
|
|
{
|
|
return new SingleConditionWidget( manager, parent );
|
|
}
|
|
|
|
void ConditionEditWidget::clearWidget( QWidget *w )
|
|
{
|
|
SingleActionWidget *sw = qobject_cast<SingleActionWidget *>(w);
|
|
Q_ASSERT( w );
|
|
if ( sw ) {
|
|
sw->clear();
|
|
}
|
|
}
|
|
|
|
void ConditionEditWidget::slotEditRule( KScoringRule *rule )
|
|
{
|
|
KScoringRule::ScoreExprList l;
|
|
if ( rule ) {
|
|
l = rule->getExpressions();
|
|
}
|
|
if ( !rule || l.count() == 0 ) {
|
|
slotClear();
|
|
} else {
|
|
setNumberOfShownWidgetsTo( l.count() );
|
|
KScoringExpression *e = l.first();
|
|
QList<QWidget*> widgetList = widgets();
|
|
QList<QWidget*>::ConstIterator it = widgetList.constBegin();
|
|
while ( e && it != widgetList.constEnd() ) {
|
|
SingleConditionWidget *scw = qobject_cast<SingleConditionWidget *>( *it );
|
|
scw->setCondition( e );
|
|
e = l.next();
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConditionEditWidget::updateRule( KScoringRule *rule )
|
|
{
|
|
rule->cleanExpressions();
|
|
foreach ( QWidget* w, widgets() ) {
|
|
SingleConditionWidget *saw = qobject_cast<SingleConditionWidget*>( w );
|
|
if ( saw ) {
|
|
rule->addExpression( saw->createCondition() );
|
|
} else {
|
|
kWarning(5100) <<"there is a widget in ConditionEditWidget"
|
|
<< "which isn't a KPIM::SingleConditionWidget";
|
|
}
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class SingleActionWidget (editor for one action, used in ActionEditWidget)
|
|
//
|
|
//============================================================================
|
|
SingleActionWidget::SingleActionWidget( KScoringManager *m, QWidget *p, const char *n )
|
|
: QWidget( p ), notifyEditor( 0 ), scoreEditor( 0 ),
|
|
colorEditor( 0 ), manager( m )
|
|
{
|
|
setObjectName( n );
|
|
QHBoxLayout *topL = new QHBoxLayout( this );
|
|
topL->setMargin( 0 );
|
|
topL->setSpacing( 5 );
|
|
|
|
types = new KComboBox( this );
|
|
types->setEditable( false );
|
|
topL->addWidget( types );
|
|
stack = new QStackedWidget( this );
|
|
topL->addWidget( stack );
|
|
|
|
dummyLabel = new QLabel( i18n( "Select an action." ), stack );
|
|
stack->insertWidget( 0, dummyLabel );
|
|
|
|
// init widget stack and the types combo box
|
|
int index = 1;
|
|
types->addItem( QString() );
|
|
QStringList l = ActionBase::userNames();
|
|
for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
|
|
QString name = *it;
|
|
int feature = ActionBase::getTypeForUserName( name );
|
|
if ( manager->hasFeature( feature ) ) {
|
|
types->addItem( name );
|
|
QWidget *w = 0;
|
|
switch( feature ) {
|
|
case ActionBase::SETSCORE:
|
|
w = scoreEditor = new KIntSpinBox( stack );
|
|
scoreEditor->setRange( -99999, 99999 );
|
|
scoreEditor->setValue( 30 );
|
|
break;
|
|
case ActionBase::NOTIFY:
|
|
w = notifyEditor = new KLineEdit( stack );
|
|
break;
|
|
case ActionBase::COLOR:
|
|
w = colorEditor = new KColorCombo( stack );
|
|
break;
|
|
case ActionBase::MARKASREAD:
|
|
w = new QLabel( stack ); // empty dummy
|
|
break;
|
|
}
|
|
if ( w ) {
|
|
stack->insertWidget( index++, w );
|
|
}
|
|
}
|
|
}
|
|
|
|
connect( types, SIGNAL(activated(int)), stack, SLOT(setCurrentIndex(int)) );
|
|
|
|
// raise the dummy label
|
|
types->setCurrentIndex( 0 );
|
|
stack->setCurrentWidget( dummyLabel );
|
|
}
|
|
|
|
SingleActionWidget::~SingleActionWidget()
|
|
{
|
|
}
|
|
|
|
void SingleActionWidget::setAction( ActionBase *act )
|
|
{
|
|
kDebug(5100) <<"SingleActionWidget::setAction()";
|
|
|
|
int index = types->findText( act->userName() );
|
|
if( index == -1 ) {
|
|
kWarning(5100) <<"unknown action in SingleActionWidget::setAction()";
|
|
index = 0;
|
|
}
|
|
|
|
types->setCurrentIndex( index );
|
|
stack->setCurrentIndex( index );
|
|
switch( act->getType() ) {
|
|
case ActionBase::SETSCORE:
|
|
scoreEditor->setValue( act->getValueString().toInt() );
|
|
break;
|
|
case ActionBase::NOTIFY:
|
|
notifyEditor->setText( act->getValueString() );
|
|
break;
|
|
case ActionBase::COLOR:
|
|
colorEditor->setColor( QColor( act->getValueString() ) );
|
|
break;
|
|
case ActionBase::MARKASREAD:
|
|
// nothing
|
|
break;
|
|
default:
|
|
kWarning(5100) <<"unknown action type in SingleActionWidget::setAction()";
|
|
}
|
|
}
|
|
|
|
ActionBase *SingleActionWidget::createAction() const
|
|
{
|
|
// no action selected...
|
|
if ( types->currentText().isEmpty() ) {
|
|
return 0;
|
|
}
|
|
|
|
int type = ActionBase::getTypeForUserName( types->currentText() );
|
|
switch ( type ) {
|
|
case ActionBase::SETSCORE:
|
|
return new ActionSetScore( scoreEditor->value() );
|
|
case ActionBase::NOTIFY:
|
|
return new ActionNotify( notifyEditor->text() );
|
|
case ActionBase::COLOR:
|
|
return new ActionColor( colorEditor->color().name() );
|
|
case ActionBase::MARKASREAD:
|
|
return new ActionMarkAsRead();
|
|
default:
|
|
kWarning(5100) <<"unknown action type in SingleActionWidget::getValue()";
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void SingleActionWidget::clear()
|
|
{
|
|
if ( scoreEditor ) {
|
|
scoreEditor->setValue( 0 );
|
|
}
|
|
if ( notifyEditor ) {
|
|
notifyEditor->clear();
|
|
}
|
|
if ( colorEditor ) {
|
|
colorEditor->setCurrentIndex( 0 );
|
|
}
|
|
|
|
types->setCurrentIndex( 0 );
|
|
stack->setCurrentWidget( dummyLabel );
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class ActionEditWidget (the widget to edit the actions of a rule)
|
|
//
|
|
//============================================================================
|
|
ActionEditWidget::ActionEditWidget( KScoringManager *m, QWidget *p, const char* )
|
|
: KWidgetLister( 1, 8, p ), manager( m )
|
|
{
|
|
// create one initial widget
|
|
addWidgetAtEnd();
|
|
}
|
|
|
|
ActionEditWidget::~ActionEditWidget()
|
|
{}
|
|
|
|
QWidget *ActionEditWidget::createWidget( QWidget *parent )
|
|
{
|
|
return new SingleActionWidget( manager, parent );
|
|
}
|
|
|
|
void ActionEditWidget::slotEditRule( KScoringRule *rule )
|
|
{
|
|
KScoringRule::ActionList l;
|
|
if ( rule ) {
|
|
l = rule->getActions();
|
|
}
|
|
if ( !rule || l.count() == 0 ) {
|
|
slotClear();
|
|
} else {
|
|
setNumberOfShownWidgetsTo( l.count() );
|
|
ActionBase *act = l.first();
|
|
QList<QWidget*> widgetList = widgets();
|
|
QList<QWidget*>::ConstIterator it = widgetList.constBegin();
|
|
while ( act && it != widgetList.constEnd() ) {
|
|
SingleActionWidget *saw = qobject_cast<SingleActionWidget*>( *it );
|
|
saw->setAction( act );
|
|
act = l.next();
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionEditWidget::updateRule( KScoringRule *rule )
|
|
{
|
|
rule->cleanActions();
|
|
foreach ( QWidget *w, widgets() ) {
|
|
SingleActionWidget *saw = qobject_cast<SingleActionWidget*>( w );
|
|
if (saw) {
|
|
ActionBase *act = saw->createAction();
|
|
if ( act ) {
|
|
rule->addAction( act );
|
|
}
|
|
} else {
|
|
kWarning(5100) <<"there is a widget in ActionEditWidget"
|
|
<< "which isn't a KPIM::SingleActionWidget";
|
|
}
|
|
}
|
|
}
|
|
|
|
void ActionEditWidget::clearWidget( QWidget *w )
|
|
{
|
|
SingleActionWidget *sw = qobject_cast<SingleActionWidget *>(w);
|
|
Q_ASSERT( w );
|
|
if ( sw ) {
|
|
sw->clear();
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class RuleEditWidget (the widget to edit one rule)
|
|
//
|
|
//============================================================================
|
|
RuleEditWidget::RuleEditWidget( KScoringManager *m, QWidget *p, const char *n )
|
|
: QWidget( p ), dirty( false ), manager( m ), oldRuleName( QString() )
|
|
{
|
|
kDebug(5100) <<"RuleEditWidget::RuleEditWidget()";
|
|
|
|
setObjectName( n != 0 ? n : "RuleEditWidget" );
|
|
|
|
QVBoxLayout *topLayout = new QVBoxLayout( this );
|
|
topLayout->setMargin( 5 );
|
|
topLayout->setSpacing( KDialog::spacingHint() );
|
|
|
|
//------------- Name, Servers, Groups ---------------------
|
|
QGroupBox *groupB = new QGroupBox( i18n( "Properties" ), this );
|
|
topLayout->addWidget( groupB );
|
|
QGridLayout *groupL = new QGridLayout( groupB );
|
|
groupL->setMargin( 8 );
|
|
groupL->setSpacing( 5 );
|
|
|
|
groupL->addItem( new QSpacerItem( 0, fontMetrics().lineSpacing() - 4 ), 0, 0 );
|
|
|
|
// name
|
|
ruleNameEdit = new KLineEdit( groupB );
|
|
groupL->addWidget( ruleNameEdit, 1, 1 );
|
|
QLabel *ruleNameLabel = new QLabel( i18nc( "@label rule name", "&Name:" ), groupB );
|
|
ruleNameLabel->setBuddy( ruleNameEdit );
|
|
ruleNameLabel->setObjectName( "ruleNameLabel" );
|
|
groupL->addWidget( ruleNameLabel, 1, 0 );
|
|
|
|
// groups
|
|
groupsEdit = new KLineEdit( groupB );
|
|
groupL->addWidget( groupsEdit, 2, 1 );
|
|
QLabel *groupsLabel = new QLabel( i18n( "&Groups:" ), groupB );
|
|
groupsLabel->setBuddy( groupsEdit );
|
|
groupsLabel->setObjectName( "groupsLabel" );
|
|
groupL->addWidget( groupsLabel, 2, 0 );
|
|
|
|
QPushButton *groupsBtn = new QPushButton( i18n( "A&dd Group" ), groupB );
|
|
connect( groupsBtn, SIGNAL(clicked()), SLOT(slotAddGroup()) );
|
|
groupL->addWidget( groupsBtn, 3, 0 );
|
|
|
|
groupsBox = new KComboBox( false, groupB );
|
|
groupsBox->setDuplicatesEnabled( false );
|
|
groupsBox->addItems( manager->getGroups() );
|
|
groupsBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
|
|
groupL->addWidget( groupsBox, 3, 1 );
|
|
|
|
// expires
|
|
expireCheck = new QCheckBox( i18n( "&Expire rule automatically" ), groupB );
|
|
groupL->addWidget( expireCheck, 4, 0, 1, 2 );
|
|
expireEdit = new KIntSpinBox( groupB );
|
|
expireEdit->setRange( 1, 9999 );
|
|
expireEdit->setValue( 30 );
|
|
slotExpireEditChanged(30 );
|
|
connect( expireEdit, SIGNAL(valueChanged(int)), SLOT(slotExpireEditChanged(int)) );
|
|
groupL->addWidget( expireEdit, 5, 1 );
|
|
expireLabel = new QLabel( i18n( "&Rule is valid for:" ), groupB );
|
|
expireLabel->setBuddy( expireEdit );
|
|
expireLabel->setObjectName( "expireLabel" );
|
|
groupL->addWidget( expireLabel, 5, 0 );
|
|
expireLabel->setEnabled( false );
|
|
expireEdit->setEnabled( false );
|
|
|
|
connect( expireCheck, SIGNAL(toggled(bool)), expireLabel, SLOT(setEnabled(bool)) );
|
|
connect( expireCheck, SIGNAL(toggled(bool)), expireEdit, SLOT(setEnabled(bool)) );
|
|
|
|
//------------- Conditions ---------------------
|
|
QGroupBox *groupConds = new QGroupBox( i18n( "Conditions" ), this );
|
|
topLayout->addWidget( groupConds );
|
|
QGridLayout *condL = new QGridLayout( groupConds );
|
|
condL->setMargin( 8 );
|
|
condL->setSpacing( 5 );
|
|
|
|
condL->addItem( new QSpacerItem( 0, fontMetrics().lineSpacing() - 4 ), 0, 0 );
|
|
|
|
QButtonGroup *buttonGroup = new QButtonGroup( groupConds );
|
|
|
|
linkModeAnd = new QRadioButton( i18n( "Match a&ll conditions" ), groupConds );
|
|
buttonGroup->addButton( linkModeAnd );
|
|
condL->addWidget( linkModeAnd, 1, 0 );
|
|
linkModeOr = new QRadioButton( i18n( "Matc&h any condition" ), groupConds );
|
|
buttonGroup->addButton( linkModeOr );
|
|
condL->addWidget( linkModeOr, 1, 1 );
|
|
linkModeAnd->setChecked( true );
|
|
|
|
condEditor = new ConditionEditWidget( manager, groupConds );
|
|
condL->addWidget( condEditor, 2, 0, 1, 2 );
|
|
connect( condEditor, SIGNAL(widgetRemoved()), this, SLOT(slotShrink()) );
|
|
|
|
//------------- Actions ---------------------
|
|
QGroupBox *groupActions = new QGroupBox( i18n( "Actions" ), this );
|
|
topLayout->addWidget( groupActions );
|
|
QBoxLayout *actionL = new QVBoxLayout( groupActions );
|
|
actionL->setMargin( 8 );
|
|
actionL->setSpacing( 5 );
|
|
actionL->addSpacing( fontMetrics().lineSpacing() - 4 );
|
|
actionEditor = new ActionEditWidget( manager, groupActions );
|
|
actionL->addWidget( actionEditor );
|
|
connect( actionEditor, SIGNAL(widgetRemoved()), this, SLOT(slotShrink()) );
|
|
|
|
topLayout->addStretch( 1 );
|
|
|
|
kDebug(5100) <<"constructed RuleEditWidget";
|
|
}
|
|
|
|
RuleEditWidget::~RuleEditWidget()
|
|
{
|
|
}
|
|
|
|
void RuleEditWidget::slotEditRule( const QString &ruleName )
|
|
{
|
|
KScoringRule *rule = manager->findRule( ruleName );
|
|
if ( !rule ) {
|
|
kDebug(5100) <<"no rule for ruleName" << ruleName;
|
|
clearContents();
|
|
return;
|
|
}
|
|
oldRuleName = rule->getName();
|
|
ruleNameEdit->setText( rule->getName() );
|
|
groupsEdit->setText( rule->getGroups().join( ";" ) );
|
|
|
|
bool b = rule->getExpireDate().isValid();
|
|
expireCheck->setChecked( b );
|
|
expireEdit->setEnabled( b );
|
|
expireLabel->setEnabled( b );
|
|
if ( b ) {
|
|
expireEdit->setValue( QDate::currentDate().daysTo( rule->getExpireDate() ) );
|
|
} else {
|
|
expireEdit->setValue( 30 );
|
|
}
|
|
if ( rule->getLinkMode() == KScoringRule::AND ) {
|
|
linkModeAnd->setChecked( true );
|
|
} else {
|
|
linkModeOr->setChecked( true );
|
|
}
|
|
|
|
condEditor->slotEditRule( rule );
|
|
actionEditor->slotEditRule( rule );
|
|
|
|
kDebug(5100) <<"RuleEditWidget::slotEditRule() ready";
|
|
}
|
|
|
|
void RuleEditWidget::clearContents()
|
|
{
|
|
ruleNameEdit->setText( "" );
|
|
groupsEdit->setText( "" );
|
|
expireCheck->setChecked( false );
|
|
expireEdit->setValue( 30 );
|
|
expireEdit->setEnabled( false );
|
|
condEditor->slotEditRule( 0 );
|
|
actionEditor->slotEditRule( 0 );
|
|
oldRuleName.clear();
|
|
}
|
|
|
|
void RuleEditWidget::updateRule( KScoringRule *rule )
|
|
{
|
|
oldRuleName.clear();
|
|
QString groups = groupsEdit->text();
|
|
if ( groups.isEmpty() ) {
|
|
rule->setGroups( QStringList( ".*" ) );
|
|
} else {
|
|
rule->setGroups( groups.split( ';', QString::SkipEmptyParts ) );
|
|
}
|
|
bool b = expireCheck->isChecked();
|
|
if ( b ) {
|
|
rule->setExpireDate( QDate::currentDate().addDays( expireEdit->value() ) );
|
|
} else {
|
|
rule->setExpireDate( QDate() );
|
|
}
|
|
actionEditor->updateRule( rule );
|
|
rule->setLinkMode( linkModeAnd->isChecked() ? KScoringRule::AND : KScoringRule::OR );
|
|
condEditor->updateRule( rule );
|
|
if ( rule->getName() != ruleNameEdit->text() ) {
|
|
manager->setRuleName( rule, ruleNameEdit->text() );
|
|
}
|
|
}
|
|
|
|
void RuleEditWidget::updateRule()
|
|
{
|
|
KScoringRule *rule = manager->findRule( oldRuleName );
|
|
if ( rule ) {
|
|
updateRule( rule );
|
|
}
|
|
}
|
|
|
|
void RuleEditWidget::slotAddGroup()
|
|
{
|
|
QString grp = groupsBox->currentText();
|
|
if ( grp.isEmpty() ) {
|
|
return;
|
|
}
|
|
QString txt = groupsEdit->text().trimmed();
|
|
if ( txt == ".*" || txt.isEmpty() ) {
|
|
groupsEdit->setText( grp );
|
|
} else {
|
|
groupsEdit->setText( txt + ';' + grp );
|
|
}
|
|
}
|
|
|
|
void RuleEditWidget::setDirty()
|
|
{
|
|
kDebug(5100) <<"RuleEditWidget::setDirty()";
|
|
if ( dirty ) {
|
|
return;
|
|
}
|
|
dirty = true;
|
|
}
|
|
|
|
void RuleEditWidget::slotShrink()
|
|
{
|
|
emit( shrink() );
|
|
}
|
|
|
|
void RuleEditWidget::slotExpireEditChanged( int value )
|
|
{
|
|
expireEdit->setSuffix( i18np( " day", " days", value ) );
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class RuleListWidget (the widget for managing a list of rules)
|
|
//
|
|
//============================================================================
|
|
RuleListWidget::RuleListWidget( KScoringManager *m, bool standalone, QWidget *p, const char *n )
|
|
: QWidget( p ), alone( standalone ), manager( m )
|
|
{
|
|
kDebug(5100) <<"RuleListWidget::RuleListWidget()";
|
|
setObjectName( n != 0 ? n : "RuleListWidget" );
|
|
QVBoxLayout *topL = new QVBoxLayout( this );
|
|
topL->setMargin( standalone ? 0 : 5 );
|
|
topL->setSpacing( KDialog::spacingHint() );
|
|
|
|
ruleList = new K3ListBox( this );
|
|
if ( standalone ) {
|
|
connect( ruleList, SIGNAL(doubleClicked(Q3ListBoxItem*)),
|
|
this, SLOT(slotEditRule(Q3ListBoxItem*)) );
|
|
connect( ruleList, SIGNAL(returnPressed(Q3ListBoxItem*)),
|
|
this, SLOT(slotEditRule(Q3ListBoxItem*)) );
|
|
}
|
|
connect( ruleList, SIGNAL(currentChanged(Q3ListBoxItem*)),
|
|
this, SLOT(slotRuleSelected(Q3ListBoxItem*)) );
|
|
topL->addWidget( ruleList );
|
|
|
|
QHBoxLayout *btnL = new QHBoxLayout();
|
|
btnL->setSpacing( KDialog::spacingHint() );
|
|
|
|
topL->addItem( btnL );
|
|
|
|
mRuleUp = new QPushButton( this );
|
|
mRuleUp->setIcon( KIcon( "go-up" ) );
|
|
mRuleUp->setToolTip( i18n( "Move rule up" ) );
|
|
btnL->addWidget( mRuleUp );
|
|
connect( mRuleUp, SIGNAL(clicked()), SLOT(slotRuleUp()) );
|
|
mRuleDown = new QPushButton( this );
|
|
mRuleDown->setIcon( KIcon( "go-down" ) );
|
|
mRuleDown->setToolTip( i18n( "Move rule down" ) );
|
|
btnL->addWidget( mRuleDown );
|
|
connect( mRuleDown, SIGNAL(clicked()), SLOT(slotRuleDown()) );
|
|
|
|
btnL = new QHBoxLayout();
|
|
btnL->setSpacing( KDialog::spacingHint() );
|
|
|
|
topL->addItem( btnL );
|
|
|
|
editRule = 0;
|
|
newRule = new QPushButton( this );
|
|
newRule->setIcon( KIcon( "document-new" ) );
|
|
newRule->setToolTip( i18n( "New rule" ) ),
|
|
btnL->addWidget( newRule );
|
|
connect( newRule, SIGNAL(clicked()), this, SLOT(slotNewRule()) );
|
|
// if we're standalone, we need an additional edit button
|
|
if ( standalone ) {
|
|
editRule = new QPushButton( this );
|
|
editRule->setIcon( KIcon( "document-properties" ) );
|
|
editRule->setToolTip( i18n( "Edit rule" ) );
|
|
btnL->addWidget( editRule );
|
|
connect( editRule, SIGNAL(clicked()), this, SLOT(slotEditRule()) );
|
|
}
|
|
delRule = new QPushButton( this );
|
|
delRule->setIcon( KIcon( "edit-delete" ) );
|
|
delRule->setToolTip( i18n( "Remove rule" ) );
|
|
btnL->addWidget( delRule );
|
|
connect( delRule, SIGNAL(clicked()), this, SLOT(slotDelRule()) );
|
|
copyRule = new QPushButton( this );
|
|
copyRule->setIcon( KIcon( "edit-copy" ) );
|
|
copyRule->setToolTip( i18n( "Copy rule" ) );
|
|
btnL->addWidget( copyRule );
|
|
connect( copyRule, SIGNAL(clicked()), this, SLOT(slotCopyRule()) );
|
|
|
|
// the group filter
|
|
QBoxLayout *filterL = new QVBoxLayout();
|
|
topL->addItem( filterL );
|
|
filterL->setSpacing( KDialog::spacingHint() );
|
|
|
|
KComboBox *filterBox = new KComboBox( this );
|
|
QStringList l = m->getGroups();
|
|
filterBox->addItem( i18n( "<placeholder>all groups</placeholder>" ) );
|
|
filterBox->addItems( l );
|
|
filterBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
|
|
connect( filterBox, SIGNAL(activated(QString)),
|
|
this, SLOT(slotGroupFilter(QString)) );
|
|
slotGroupFilter( i18n( "<placeholder>all groups</placeholder>" ) );
|
|
QLabel *lab = new QLabel( i18n( "Sho&w only rules for group:" ), this );
|
|
lab->setBuddy( filterBox );
|
|
|
|
filterL->addWidget( lab );
|
|
filterL->addWidget( filterBox );
|
|
|
|
connect( manager, SIGNAL(changedRules()), this, SLOT(updateRuleList()) );
|
|
connect( manager, SIGNAL(changedRuleName(QString,QString)),
|
|
this, SLOT(slotRuleNameChanged(QString,QString)) );
|
|
|
|
updateRuleList();
|
|
updateButton();
|
|
}
|
|
|
|
RuleListWidget::~RuleListWidget()
|
|
{
|
|
}
|
|
|
|
void RuleListWidget::updateButton()
|
|
{
|
|
bool state = ruleList->count() > 0;
|
|
if( editRule ) {
|
|
editRule->setEnabled( state );
|
|
}
|
|
delRule->setEnabled( state );
|
|
copyRule->setEnabled( state );
|
|
|
|
Q3ListBoxItem *item = ruleList->item( ruleList->currentItem() );
|
|
if ( item ) {
|
|
mRuleUp->setEnabled( item->prev() != 0 );
|
|
mRuleDown->setEnabled( item->next() != 0 );
|
|
}
|
|
}
|
|
|
|
void RuleListWidget::updateRuleList()
|
|
{
|
|
emit leavingRule();
|
|
kDebug(5100) <<"RuleListWidget::updateRuleList()";
|
|
QString curr = ruleList->currentText();
|
|
ruleList->clear();
|
|
if ( group == i18n( "<placeholder>all groups</placeholder>" ) ) {
|
|
QStringList l = manager->getRuleNames();
|
|
ruleList->insertStringList( l );
|
|
} else {
|
|
KScoringManager::ScoringRuleList l = manager->getAllRules();
|
|
for ( KScoringRule *rule = l.first(); rule; rule = l.next() ) {
|
|
if ( rule->matchGroup( group ) ) {
|
|
ruleList->insertItem( rule->getName() );
|
|
}
|
|
}
|
|
}
|
|
int index = setCurrentItem( ruleList, curr );
|
|
if ( index < 0 ) {
|
|
ruleList->setCurrentItem( 0 );
|
|
slotRuleSelected( ruleList->currentText() );
|
|
} else {
|
|
slotRuleSelected( curr );
|
|
}
|
|
}
|
|
|
|
void RuleListWidget::updateRuleList( const KScoringRule *rule )
|
|
{
|
|
kDebug(5100) <<"RuleListWidget::updateRuleList(" << rule->getName() <<")";
|
|
QString name = rule->getName();
|
|
updateRuleList();
|
|
slotRuleSelected(name);
|
|
}
|
|
|
|
void RuleListWidget::slotRuleNameChanged( const QString &oldName, const QString &newName )
|
|
{
|
|
int ind = ruleList->currentItem();
|
|
for ( uint i=0; i<ruleList->count(); ++i ) {
|
|
if ( ruleList->text(i) == oldName ) {
|
|
ruleList->changeItem( newName, i );
|
|
ruleList->setCurrentItem( ind );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RuleListWidget::slotEditRule( const QString &s )
|
|
{
|
|
emit ruleEdited( s );
|
|
}
|
|
|
|
void RuleListWidget::slotEditRule()
|
|
{
|
|
if ( ruleList->currentItem() >= 0 ) {
|
|
emit ruleEdited( ruleList->currentText() );
|
|
} else if ( ruleList->count() == 0 ) {
|
|
emit ruleEdited( QString() );
|
|
}
|
|
}
|
|
|
|
void RuleListWidget::slotEditRule( Q3ListBoxItem *item )
|
|
{
|
|
slotEditRule( item->text() );
|
|
}
|
|
|
|
void RuleListWidget::slotGroupFilter( const QString &s )
|
|
{
|
|
group = s;
|
|
updateRuleList();
|
|
}
|
|
|
|
void RuleListWidget::slotRuleSelected( const QString &ruleName )
|
|
{
|
|
emit leavingRule();
|
|
kDebug(5100) <<"RuleListWidget::slotRuleSelected(" << ruleName <<")";
|
|
if ( ruleName != ruleList->currentText() ) {
|
|
setCurrentItem( ruleList, ruleName );
|
|
}
|
|
updateButton();
|
|
emit ruleSelected( ruleName );
|
|
}
|
|
|
|
void RuleListWidget::slotRuleSelected( Q3ListBoxItem *item )
|
|
{
|
|
if ( !item ) {
|
|
return;
|
|
}
|
|
QString ruleName = item->text();
|
|
slotRuleSelected( ruleName );
|
|
}
|
|
|
|
void RuleListWidget::slotRuleSelected( int index )
|
|
{
|
|
uint idx = index;
|
|
if ( idx >= ruleList->count() ) {
|
|
return;
|
|
}
|
|
QString ruleName = ruleList->text( index );
|
|
slotRuleSelected( ruleName );
|
|
}
|
|
|
|
void RuleListWidget::slotNewRule()
|
|
{
|
|
emit leavingRule();
|
|
KScoringRule *rule = manager->addRule();
|
|
updateRuleList( rule );
|
|
if ( alone ) {
|
|
slotEditRule( rule->getName() );
|
|
}
|
|
updateButton();
|
|
}
|
|
|
|
void RuleListWidget::slotDelRule()
|
|
{
|
|
KScoringRule *rule = manager->findRule( ruleList->currentText() );
|
|
if ( rule ) {
|
|
manager->deleteRule( rule );
|
|
}
|
|
// goto the next rule
|
|
if ( !alone ) {
|
|
slotEditRule();
|
|
}
|
|
updateButton();
|
|
}
|
|
|
|
void RuleListWidget::slotCopyRule()
|
|
{
|
|
emit leavingRule();
|
|
QString ruleName = ruleList->currentText();
|
|
KScoringRule *rule = manager->findRule( ruleName );
|
|
if ( rule ) {
|
|
KScoringRule *nrule = manager->copyRule( rule );
|
|
updateRuleList( nrule );
|
|
slotEditRule( nrule->getName() );
|
|
}
|
|
updateButton();
|
|
}
|
|
|
|
void RuleListWidget::slotRuleUp()
|
|
{
|
|
KScoringRule *rule = 0, *below = 0;
|
|
Q3ListBoxItem *item = ruleList->item( ruleList->currentItem() );
|
|
if ( item ) {
|
|
rule = manager->findRule( item->text() );
|
|
item = item->prev();
|
|
if ( item ) {
|
|
below = manager->findRule( item->text() );
|
|
}
|
|
}
|
|
if ( rule && below ) {
|
|
manager->moveRuleAbove( rule, below );
|
|
}
|
|
updateRuleList();
|
|
updateButton();
|
|
}
|
|
|
|
void RuleListWidget::slotRuleDown()
|
|
{
|
|
KScoringRule *rule = 0, *above = 0;
|
|
Q3ListBoxItem *item = ruleList->item( ruleList->currentItem() );
|
|
if ( item ) {
|
|
rule = manager->findRule( item->text() );
|
|
item = item->next();
|
|
if ( item ) {
|
|
above = manager->findRule( item->text() );
|
|
}
|
|
}
|
|
if ( rule && above ) {
|
|
manager->moveRuleBelow( rule, above );
|
|
}
|
|
updateRuleList();
|
|
updateButton();
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class KScoringEditor (the score edit dialog)
|
|
//
|
|
//============================================================================
|
|
KScoringEditor *KScoringEditor::scoreEditor = 0;
|
|
|
|
KScoringEditor::KScoringEditor( KScoringManager *m, QWidget *parent )
|
|
: KDialog( parent ), manager( m )
|
|
{
|
|
setCaption( i18n( "Rule Editor" ) );
|
|
setButtons( Ok|Apply|Cancel );
|
|
setDefaultButton( Ok );
|
|
setModal( false );
|
|
showButtonSeparator( true );
|
|
manager->pushRuleList();
|
|
if ( !scoreEditor ) {
|
|
scoreEditor = this;
|
|
}
|
|
kDebug(5100) <<"KScoringEditor::KScoringEditor()";
|
|
// the left side gives an overview about all rules, the right side
|
|
// shows a detailed view of an selected rule
|
|
QWidget *w = new QWidget( this );
|
|
setMainWidget( w );
|
|
QHBoxLayout *hbl = new QHBoxLayout( w );
|
|
hbl->setMargin( 0 );
|
|
hbl->setSpacing( spacingHint() );
|
|
|
|
ruleLister = new RuleListWidget( manager, false, w );
|
|
hbl->addWidget( ruleLister );
|
|
ruleEditor = new RuleEditWidget( manager, w );
|
|
hbl->addWidget( ruleEditor );
|
|
connect( ruleLister, SIGNAL(ruleSelected(QString)),
|
|
ruleEditor, SLOT(slotEditRule(QString)) );
|
|
connect( ruleLister, SIGNAL(leavingRule()), ruleEditor, SLOT(updateRule()) );
|
|
connect( ruleEditor, SIGNAL(shrink()), SLOT(slotShrink()) );
|
|
connect( this, SIGNAL(finished()), SLOT(slotFinished()) );
|
|
connect( this, SIGNAL(okClicked()), SLOT(slotOk()) );
|
|
connect( this, SIGNAL(cancelClicked()), SLOT(slotCancel()) );
|
|
connect( this, SIGNAL(applyClicked()), SLOT(slotApply()) );
|
|
ruleLister->slotRuleSelected( 0 );
|
|
resize( 550, sizeHint().height() );
|
|
}
|
|
|
|
void KScoringEditor::setDirty()
|
|
{
|
|
enableButton( Apply, true );
|
|
}
|
|
|
|
KScoringEditor::~KScoringEditor()
|
|
{
|
|
scoreEditor = 0;
|
|
}
|
|
|
|
KScoringEditor *KScoringEditor::createEditor( KScoringManager *m, QWidget *parent )
|
|
{
|
|
if ( scoreEditor ) {
|
|
return scoreEditor;
|
|
} else {
|
|
return new KScoringEditor( m, parent );
|
|
}
|
|
}
|
|
|
|
void KScoringEditor::setRule( KScoringRule *r )
|
|
{
|
|
kDebug(5100) <<"KScoringEditor::setRule(" << r->getName() <<")";
|
|
QString ruleName = r->getName();
|
|
ruleLister->slotRuleSelected( ruleName );
|
|
}
|
|
|
|
void KScoringEditor::slotShrink()
|
|
{
|
|
QTimer::singleShot( 5, this, SLOT(slotDoShrink()) );
|
|
}
|
|
|
|
void KScoringEditor::slotDoShrink()
|
|
{
|
|
updateGeometry();
|
|
QApplication::sendPostedEvents();
|
|
resize( width(), sizeHint().height() );
|
|
}
|
|
|
|
void KScoringEditor::slotApply()
|
|
{
|
|
QString ruleName = ruleLister->currentRule();
|
|
KScoringRule *rule = manager->findRule( ruleName );
|
|
if ( rule ) {
|
|
ruleEditor->updateRule( rule );
|
|
ruleLister->updateRuleList( rule );
|
|
}
|
|
manager->removeTOS();
|
|
manager->pushRuleList();
|
|
}
|
|
|
|
void KScoringEditor::slotOk()
|
|
{
|
|
slotApply();
|
|
manager->removeTOS();
|
|
manager->editorReady();
|
|
}
|
|
|
|
void KScoringEditor::slotCancel()
|
|
{
|
|
manager->popRuleList();
|
|
KDialog::reject();
|
|
}
|
|
|
|
void KScoringEditor::slotFinished()
|
|
{
|
|
delayedDestruct();
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class KScoringEditorWidgetDialog (a dialog for the KScoringEditorWidget)
|
|
//
|
|
//============================================================================
|
|
KScoringEditorWidgetDialog::KScoringEditorWidgetDialog( KScoringManager *m,
|
|
const QString &r,
|
|
QWidget *p )
|
|
: KDialog( p ), manager( m ), ruleName( r )
|
|
{
|
|
setCaption( i18n( "Edit Rule" ) );
|
|
setButtons( KDialog::Ok|KDialog::Apply|KDialog::Cancel );
|
|
setDefaultButton( KDialog::Ok );
|
|
setModal( true );
|
|
showButtonSeparator( true );
|
|
QFrame *f = new QFrame( this );
|
|
setMainWidget( f );
|
|
QBoxLayout *topL = new QVBoxLayout( f );
|
|
ruleEditor = new RuleEditWidget( manager, f );
|
|
connect( ruleEditor, SIGNAL(shrink()), SLOT(slotShrink()) );
|
|
connect( this, SIGNAL(okClicked()), SLOT(slotOk()) );
|
|
topL->addWidget( ruleEditor );
|
|
ruleEditor->slotEditRule( ruleName );
|
|
resize( 0, 0 );
|
|
}
|
|
|
|
void KScoringEditorWidgetDialog::slotApply()
|
|
{
|
|
KScoringRule *rule = manager->findRule( ruleName );
|
|
if ( rule ) {
|
|
ruleEditor->updateRule( rule );
|
|
ruleName = rule->getName();
|
|
}
|
|
}
|
|
|
|
void KScoringEditorWidgetDialog::slotOk()
|
|
{
|
|
slotApply();
|
|
KDialog::accept();
|
|
}
|
|
|
|
void KScoringEditorWidgetDialog::slotShrink()
|
|
{
|
|
QTimer::singleShot( 5, this, SLOT(slotDoShrink()) );
|
|
}
|
|
|
|
void KScoringEditorWidgetDialog::slotDoShrink()
|
|
{
|
|
updateGeometry();
|
|
QApplication::sendPostedEvents();
|
|
resize( width(), sizeHint().height() );
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// class KScoringEditorWidget (a reusable widget for config dialog...)
|
|
//
|
|
//============================================================================
|
|
KScoringEditorWidget::KScoringEditorWidget( KScoringManager *m, QWidget *p, const char *n )
|
|
: QWidget( p ), manager( m )
|
|
{
|
|
setObjectName( n );
|
|
QBoxLayout *topL = new QVBoxLayout( this );
|
|
ruleLister = new RuleListWidget( manager, true, this );
|
|
topL->addWidget( ruleLister );
|
|
connect( ruleLister, SIGNAL(ruleEdited(QString)),
|
|
this, SLOT(slotRuleEdited(QString)) );
|
|
}
|
|
|
|
KScoringEditorWidget::~KScoringEditorWidget()
|
|
{
|
|
manager->editorReady();
|
|
}
|
|
|
|
void KScoringEditorWidget::slotRuleEdited( const QString &ruleName )
|
|
{
|
|
KScoringEditorWidgetDialog dlg( manager, ruleName, this );
|
|
dlg.exec();
|
|
ruleLister->updateRuleList();
|
|
}
|
|
|