You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kspread/dialogs/kspread_dlg_conditional.cpp

680 lines
20 KiB

/* This file is part of the KDE project
Copyright (C) 2002-2003 Norbert Andres <nandres@web.de>
(C) 2002-2003 Philipp Mueller <philipp.mueller@gmx.de>
(C) 2002 John Dailey <dailey@vt.edu>
(C) 1999-2001 Laurent Montel <montel@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "kspread_dlg_conditional.h"
#include "kspread_condition.h"
#include "kspread_canvas.h"
#include "kspread_cell.h"
#include "kspread_doc.h"
#include "selection.h"
#include "kspread_sheet.h"
#include "kspread_style.h"
#include "kspread_style_manager.h"
#include "kspread_view.h"
#include <kcombobox.h>
#include <kdebug.h>
#include <klineedit.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <KoGlobal.h>
#include <tqgroupbox.h>
#include <tqlabel.h>
#include <tqlayout.h>
using namespace KSpread;
ConditionalWidget::ConditionalWidget( TQWidget* parent, const char* name, WFlags fl )
: TQWidget( parent, name, fl )
{
TQGridLayout * Form1Layout = new TQGridLayout( this, 1, 1, 11, 6, "Form1Layout");
TQGroupBox * groupBox1_3 = new TQGroupBox( this, "groupBox1_3" );
groupBox1_3->setColumnLayout(0, TQt::Vertical );
groupBox1_3->layout()->setSpacing( KDialog::spacingHint() );
groupBox1_3->layout()->setMargin( KDialog::marginHint() );
TQGridLayout * groupBox1_3Layout = new TQGridLayout( groupBox1_3->layout() );
groupBox1_3Layout->setAlignment( TQt::AlignTop );
TQLabel * textLabel1_3 = new TQLabel( groupBox1_3, "textLabel1_3" );
groupBox1_3Layout->addWidget( textLabel1_3, 0, 0 );
m_condition_3 = new TQComboBox( false, groupBox1_3, "m_condition_3" );
groupBox1_3Layout->addWidget( m_condition_3, 0, 1 );
m_firstValue_3 = new KLineEdit( groupBox1_3, "m_firstValue_3" );
m_firstValue_3->setEnabled( false );
groupBox1_3Layout->addWidget( m_firstValue_3, 0, 2 );
m_secondValue_3 = new KLineEdit( groupBox1_3, "m_secondValue_3" );
m_secondValue_3->setEnabled( false );
groupBox1_3Layout->addWidget( m_secondValue_3, 0, 3 );
m_style_3 = new TQComboBox( false, groupBox1_3, "m_style_3" );
m_style_3->setEnabled( false );
groupBox1_3Layout->addWidget( m_style_3, 1, 1 );
TQLabel * textLabel2_3 = new TQLabel( groupBox1_3, "textLabel2_3" );
groupBox1_3Layout->addWidget( textLabel2_3, 1, 0 );
TQSpacerItem * spacer = new TQSpacerItem( 41, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
groupBox1_3Layout->addItem( spacer, 1, 2 );
TQSpacerItem * spacer_2 = new TQSpacerItem( 61, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
groupBox1_3Layout->addItem( spacer_2, 1, 3 );
Form1Layout->addWidget( groupBox1_3, 2, 0 );
TQGroupBox * groupBox1_2 = new TQGroupBox( this, "groupBox1_2" );
groupBox1_2->setColumnLayout(0, TQt::Vertical );
groupBox1_2->layout()->setSpacing( KDialog::spacingHint() );
groupBox1_2->layout()->setMargin( KDialog::marginHint() );
TQGridLayout * groupBox1_2Layout = new TQGridLayout( groupBox1_2->layout() );
groupBox1_2Layout->setAlignment( TQt::AlignTop );
TQLabel * textLabel1_2 = new TQLabel( groupBox1_2, "textLabel1_2" );
groupBox1_2Layout->addWidget( textLabel1_2, 0, 0 );
TQLabel * textLabel2_2 = new TQLabel( groupBox1_2, "textLabel2_2" );
groupBox1_2Layout->addWidget( textLabel2_2, 1, 0 );
m_condition_2 = new TQComboBox( false, groupBox1_2, "m_condition_2" );
groupBox1_2Layout->addWidget( m_condition_2, 0, 1 );
m_style_2 = new TQComboBox( false, groupBox1_2, "m_style_2" );
m_style_2->setEnabled( false );
groupBox1_2Layout->addWidget( m_style_2, 1, 1 );
m_firstValue_2 = new KLineEdit( groupBox1_2, "m_firstValue_2" );
m_firstValue_2->setEnabled( false );
groupBox1_2Layout->addWidget( m_firstValue_2, 0, 2 );
m_secondValue_2 = new KLineEdit( groupBox1_2, "m_secondValue_2" );
m_secondValue_2->setEnabled( false );
groupBox1_2Layout->addWidget( m_secondValue_2, 0, 3 );
TQSpacerItem * spacer_3 = new TQSpacerItem( 41, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
groupBox1_2Layout->addItem( spacer_3, 1, 2 );
TQSpacerItem * spacer_4 = new TQSpacerItem( 61, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
groupBox1_2Layout->addItem( spacer_4, 1, 3 );
Form1Layout->addWidget( groupBox1_2, 1, 0 );
TQGroupBox * groupBox1_1 = new TQGroupBox( this, "groupBox1_1" );
groupBox1_1->setColumnLayout(0, TQt::Vertical );
groupBox1_1->layout()->setSpacing( KDialog::spacingHint() );
groupBox1_1->layout()->setMargin( KDialog::marginHint() );
TQGridLayout * groupBox1_1Layout = new TQGridLayout( groupBox1_1->layout() );
groupBox1_1Layout->setAlignment( TQt::AlignTop );
TQLabel * textLabel1_1 = new TQLabel( groupBox1_1, "textLabel1_2_2" );
groupBox1_1Layout->addWidget( textLabel1_1, 0, 0 );
TQLabel * textLabel2_1 = new TQLabel( groupBox1_1, "textLabel2_2_2" );
groupBox1_1Layout->addWidget( textLabel2_1, 1, 0 );
m_condition_1 = new TQComboBox( false, groupBox1_1, "m_condition_1" );
groupBox1_1Layout->addWidget( m_condition_1, 0, 1 );
m_style_1 = new TQComboBox( false, groupBox1_1, "m_style_1" );
m_style_1->setEnabled( false );
groupBox1_1Layout->addWidget( m_style_1, 1, 1 );
m_firstValue_1 = new KLineEdit( groupBox1_1, "m_firstValue_1" );
m_firstValue_1->setEnabled( false );
groupBox1_1Layout->addWidget( m_firstValue_1, 0, 2 );
m_secondValue_1 = new KLineEdit( groupBox1_1, "m_secondValue_1" );
m_secondValue_1->setEnabled( false );
groupBox1_1Layout->addWidget( m_secondValue_1, 0, 3 );
TQSpacerItem * spacer_5 = new TQSpacerItem( 41, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
groupBox1_1Layout->addItem( spacer_5, 1, 2 );
TQSpacerItem * spacer_6 = new TQSpacerItem( 61, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
groupBox1_1Layout->addItem( spacer_6, 1, 3 );
Form1Layout->addWidget( groupBox1_1, 0, 0 );
resize( TQSize(702, 380).expandedTo( minimumSizeHint() ) );
clearWState( WState_Polished );
TQStringList list;
list += i18n( "<none>" );
list += i18n( "equal to" );
list += i18n( "greater than" );
list += i18n( "less than" );
list += i18n( "equal to or greater than" );
list += i18n( "equal to or less than" );
list += i18n( "between" );
list += i18n( "outside range" );
list += i18n( "different to" );
m_condition_1->clear();
m_condition_2->clear();
m_condition_3->clear();
m_condition_1->insertStringList( list );
m_condition_2->insertStringList( list );
m_condition_3->insertStringList( list );
groupBox1_1->setTitle( i18n( "First Condition" ) );
groupBox1_2->setTitle( i18n( "Second Condition" ) );
groupBox1_3->setTitle( i18n( "Third Condition" ) );
textLabel1_1->setText( i18n( "Cell is" ) );
textLabel1_2->setText( i18n( "Cell is" ) );
textLabel1_3->setText( i18n( "Cell is" ) );
textLabel2_1->setText( i18n( "Cell style" ) );
textLabel2_2->setText( i18n( "Cell style" ) );
textLabel2_3->setText( i18n( "Cell style" ) );
connect( m_condition_1, TQ_SIGNAL( highlighted( const TQString & ) ), this, TQ_SLOT( slotTextChanged1( const TQString & ) ) );
connect( m_condition_2, TQ_SIGNAL( highlighted( const TQString & ) ), this, TQ_SLOT( slotTextChanged2( const TQString & ) ) );
connect( m_condition_3, TQ_SIGNAL( highlighted( const TQString & ) ), this, TQ_SLOT( slotTextChanged3( const TQString & ) ) );
}
ConditionalWidget::~ConditionalWidget()
{
}
void ConditionalWidget::slotTextChanged1( const TQString & text )
{
if ( text == i18n( "<none>" ) )
{
m_firstValue_1->setEnabled( false );
m_secondValue_1->setEnabled( false );
m_style_1->setEnabled( false );
}
else
{
m_condition_2->setEnabled( true );
m_style_1->setEnabled( true );
if ( ( text == i18n( "between" ) ) || ( text == i18n( "different from" ) ) )
{
m_firstValue_1->setEnabled( true );
m_secondValue_1->setEnabled( true );
}
else
{
m_firstValue_1->setEnabled( true );
m_secondValue_1->setEnabled( false );
}
}
}
void ConditionalWidget::slotTextChanged2( const TQString & text )
{
if ( text == i18n( "<none>" ) )
{
m_firstValue_2->setEnabled( false );
m_secondValue_2->setEnabled( false );
m_style_2->setEnabled( false );
}
else
{
m_condition_3->setEnabled( true );
m_style_2->setEnabled( true );
if ( ( text == i18n( "between" ) ) || ( text == i18n( "different from" ) ) )
{
m_firstValue_2->setEnabled( true );
m_secondValue_2->setEnabled( true );
}
else
{
m_firstValue_2->setEnabled( true );
m_secondValue_2->setEnabled( false );
}
}
}
void ConditionalWidget::slotTextChanged3( const TQString & text )
{
if ( text == i18n( "<none>" ) )
{
m_firstValue_3->setEnabled( false );
m_secondValue_3->setEnabled( false );
m_style_3->setEnabled( false );
}
else
{
m_style_3->setEnabled( true );
if ( ( text == i18n( "between" ) ) || ( text == i18n( "different from" ) ) )
{
m_firstValue_3->setEnabled( true );
m_secondValue_3->setEnabled( true );
}
else
{
m_firstValue_3->setEnabled( true );
m_secondValue_3->setEnabled( false );
}
}
}
/**
* ConditionalDialog
* Sets conditional cell formattings.
*/
ConditionalDialog::ConditionalDialog( View * parent, const char * name,
const TQRect & marker )
: KDialogBase( parent, name, true, "", KDialogBase::Ok | KDialogBase::Cancel,
KDialogBase::Ok, false ),
m_view( parent ),
m_dlg( new ConditionalWidget( this ) ),
m_marker( marker )
{
TQStringList list( m_view->doc()->styleManager()->styleNames() );
m_dlg->m_style_1->insertStringList( list );
m_dlg->m_style_2->insertStringList( list );
m_dlg->m_style_3->insertStringList( list );
setCaption( i18n( "Conditional Cell Attributes" ) );
setButtonBoxOrientation(TQt::Vertical );
setMainWidget( m_dlg );
init();
}
void ConditionalDialog::init()
{
TQValueList<Conditional> conditionList;
TQValueList<Conditional> otherList;
bool found;
int numCondition;
TQValueList<Conditional>::iterator it1;
TQValueList<Conditional>::iterator it2;
Cell * obj = m_view->activeSheet()->cellAt( m_marker.left(),
m_marker.top() );
conditionList = obj->conditionList();
/* this is the list, but only display the conditions common to all selected
cells*/
for ( int x = m_marker.left(); x <= m_marker.right(); x++ )
{
for ( int y = m_marker.top(); y <= m_marker.bottom(); y++ )
{
Cell * obj2 = m_view->activeSheet()->cellAt( x, y );
otherList = obj2->conditionList();
it1 = conditionList.begin();
while ( it1 != conditionList.end() )
{
kdDebug() << "Here" << endl;
found = false;
for ( it2 = otherList.begin(); !found && it2 != otherList.end(); ++it2 )
{
kdDebug() << "Found: " << found << endl;
found = ( (*it1).val1 == (*it2).val1 &&
(*it1).val2 == (*it2).val2 &&
(*it1).cond == (*it2).cond );
if ( (*it1).strVal1 && !(*it2).strVal1 )
found = false;
if ( !(*it1).strVal1 && (*it2).strVal1 )
found = false;
if ( (*it1).strVal1 && (*it2).strVal1
&& ( *(*it1).strVal1 != *(*it2).strVal1 ) )
found = false;
if ( !found )
continue;
if ( (*it1).strVal2 && !(*it2).strVal2 )
found = false;
if ( !(*it1).strVal2 && (*it2).strVal2 )
found = false;
if ( (*it1).strVal2 && (*it2).strVal2
&& ( *(*it1).strVal2 != *(*it2).strVal2 ) )
found = false;
if ( !found )
continue;
if ( (*it1).colorcond && !(*it2).colorcond )
found = false;
if ( !(*it1).colorcond && (*it2).colorcond )
found = false;
if ( (*it1).colorcond && (*it2).colorcond
&& ( *(*it1).colorcond != *(*it2).colorcond ) )
found = false;
if ( !found )
continue;
if ( (*it1).fontcond && !(*it2).fontcond )
found = false;
if ( !(*it1).fontcond && (*it2).fontcond )
found = false;
if ( (*it1).fontcond && (*it2).fontcond
&& ( *(*it1).fontcond != *(*it2).fontcond ) )
found = false;
if ( !found )
continue;
if ( (*it1).styleName && !(*it2).styleName )
found = false;
if ( !(*it1).styleName && (*it2).styleName )
found = false;
if ( (*it1).styleName && (*it2).styleName
&& ( *(*it1).styleName != *(*it2).styleName ) )
found = false;
}
if ( !found ) /* if it's not here, don't display this condition */
{
it1 = conditionList.remove( it1 );
}
else
{
++it1;
}
}
}
}
kdDebug() << "Conditions: " << conditionList.size() << endl;
m_dlg->m_condition_2->setEnabled( false );
m_dlg->m_condition_3->setEnabled( false );
m_dlg->m_style_1->setEnabled( false );
m_dlg->m_style_2->setEnabled( false );
m_dlg->m_style_3->setEnabled( false );
numCondition = 0;
for ( it1 = conditionList.begin(); numCondition < 3 && it1 != conditionList.end(); ++it1 )
{
init( *it1, numCondition );
++numCondition;
}
}
void ConditionalDialog::init( Conditional const & tmp, int numCondition )
{
kdDebug() << "Adding " << numCondition << endl;
TQComboBox * cb = 0;
TQComboBox * sb = 0;
KLineEdit * kl1 = 0;
KLineEdit * kl2 = 0;
TQString value;
switch( numCondition )
{
case 0:
cb = m_dlg->m_condition_1;
sb = m_dlg->m_style_1;
kl1 = m_dlg->m_firstValue_1;
kl2 = m_dlg->m_secondValue_1;
break;
case 1:
cb = m_dlg->m_condition_2;
sb = m_dlg->m_style_2;
kl1 = m_dlg->m_firstValue_2;
kl2 = m_dlg->m_secondValue_2;
break;
case 2:
cb = m_dlg->m_condition_3;
sb = m_dlg->m_style_3;
kl1 = m_dlg->m_firstValue_3;
kl2 = m_dlg->m_secondValue_3;
break;
default:
return;
}
if ( tmp.styleName )
{
sb->setCurrentText( *tmp.styleName );
sb->setEnabled( true );
}
switch( tmp.cond )
{
case Conditional::None :
break;
case Conditional::Equal :
cb->setCurrentItem( 1 );
break;
case Conditional::Superior :
cb->setCurrentItem( 2 );
break;
case Conditional::Inferior :
cb->setCurrentItem( 3 );
break;
case Conditional::SuperiorEqual :
cb->setCurrentItem( 4 );
break;
case Conditional::InferiorEqual :
cb->setCurrentItem( 5 );
break;
case Conditional::Between :
cb->setCurrentItem(6);
if ( tmp.strVal2 )
kl2->setText( *tmp.strVal2 );
else
{
value = value.setNum( tmp.val2 );
kl2->setText( value );
}
break;
case Conditional::Different :
cb->setCurrentItem(7);
if ( tmp.strVal2 )
kl2->setText( *tmp.strVal2 );
else
{
value = value.setNum( tmp.val2 );
kl2->setText( value );
}
break;
case Conditional::DifferentTo :
cb->setCurrentItem(8);
break;
}
if ( tmp.cond != Conditional::None )
{
kl1->setEnabled( true );
if ( tmp.strVal1 )
kl1->setText( *tmp.strVal1 );
else
{
value = value.setNum( tmp.val1 );
kl1->setText( value );
}
}
}
Conditional::Type ConditionalDialog::typeOfCondition( TQComboBox const * const cb ) const
{
Conditional::Type result = Conditional::None;
switch( cb->currentItem() )
{
case 0 :
result = Conditional::None;
break;
case 1 :
result = Conditional::Equal;
break;
case 2 :
result = Conditional::Superior;
break;
case 3 :
result = Conditional::Inferior;
break;
case 4 :
result = Conditional::SuperiorEqual;
break;
case 5 :
result = Conditional::InferiorEqual;
break;
case 6 :
result = Conditional::Between;
break;
case 7 :
result = Conditional::Different;
break;
case 8 :
result = Conditional::DifferentTo;
break;
default:
kdDebug(36001) << "Error in list" << endl;
break;
}
return result;
}
bool ConditionalDialog::checkInputData( KLineEdit const * const edit1,
KLineEdit const * const edit2 )
{
bool b1 = false;
bool b2 = false;
if ( !edit2->isEnabled() )
return true;
edit1->text().toDouble( &b1 );
edit2->text().toDouble( &b2 );
if ( b1 != b2 )
{
if ( b1 )
KMessageBox::sorry( 0, i18n( "If the first value is a number, the second value also has to be a number." ) );
else
KMessageBox::sorry( 0, i18n( "If the first value is a string, the second value also has to be a string." ) );
return false;
}
return true;
}
bool ConditionalDialog::checkInputData()
{
if ( m_dlg->m_firstValue_1->isEnabled() && !checkInputData( m_dlg->m_firstValue_1, m_dlg->m_secondValue_1 ) )
return false;
if ( m_dlg->m_firstValue_2->isEnabled() && !checkInputData( m_dlg->m_firstValue_2, m_dlg->m_secondValue_2 ) )
return false;
if ( m_dlg->m_firstValue_3->isEnabled() && !checkInputData( m_dlg->m_firstValue_3, m_dlg->m_secondValue_3 ) )
return false;
return true;
}
bool ConditionalDialog::getCondition( Conditional & newCondition, const TQComboBox * cb,
const KLineEdit * edit1, const KLineEdit * edit2,
const TQComboBox * sb, Style * style )
{
if ( !cb->isEnabled() )
return false;
newCondition.cond = typeOfCondition( cb );
if ( newCondition.cond == Conditional::None )
return false;
bool ok = false;
double d1 = edit1->text().toDouble( &ok );
double d2 = 0.0;
TQString * s1 = 0;
TQString * s2 = 0;
TQString * sn = 0;
if ( ok )
{
if ( edit2->isEnabled() )
d2 = edit2->text().toDouble( &ok );
// values are already checked...
}
else
{
d1 = 0.0;
s1 = new TQString( edit1->text() );
if ( edit2->isEnabled() )
s2 = new TQString( edit2->text() );
}
sn = new TQString( sb->currentText() );
newCondition.val1 = d1;
newCondition.val2 = d2;
newCondition.strVal1 = s1;
newCondition.strVal2 = s2;
newCondition.fontcond = 0;
newCondition.colorcond = 0;
newCondition.styleName = sn;
newCondition.style = style;
return true;
}
void ConditionalDialog::slotOk()
{
kdDebug() << "slotOk" << endl;
if ( !checkInputData() )
return;
kdDebug() << "Input data is valid" << endl;
m_view->doc()->emitBeginOperation( false );
StyleManager * manager = m_view->doc()->styleManager();
TQValueList<Conditional> newList;
Conditional newCondition;
if ( getCondition( newCondition, m_dlg->m_condition_1, m_dlg->m_firstValue_1,
m_dlg->m_secondValue_1, m_dlg->m_style_1, manager->style( m_dlg->m_style_1->currentText() ) ) )
newList.append( newCondition );
if ( getCondition( newCondition, m_dlg->m_condition_2, m_dlg->m_firstValue_2,
m_dlg->m_secondValue_2, m_dlg->m_style_2, manager->style( m_dlg->m_style_2->currentText() ) ) )
newList.append( newCondition );
if ( getCondition( newCondition, m_dlg->m_condition_3, m_dlg->m_firstValue_3,
m_dlg->m_secondValue_3, m_dlg->m_style_3, manager->style( m_dlg->m_style_3->currentText() ) ) )
newList.append( newCondition );
kdDebug() << "Setting conditional list" << endl;
m_view->activeSheet()->setConditional( m_view->selectionInfo(), newList );
m_view->slotUpdateView( m_view->activeSheet(), *m_view->selectionInfo() );
accept();
}
#include "kspread_dlg_conditional.moc"