00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "KoUnitWidgets.h"
00022 #include "KoUnitWidgets.moc"
00023 #include <kdebug.h>
00024 #include <kglobal.h>
00025 #include <klocale.h>
00026 #include <qpushbutton.h>
00027 #include <qlayout.h>
00028
00029
00030
00031
00032
00033
00034 KoUnitDoubleValidator::KoUnitDoubleValidator( KoUnitDoubleBase *base, QObject *parent, const char *name )
00035 : KDoubleValidator( parent, name ), m_base( base )
00036 {
00037 }
00038
00039 QValidator::State
00040 KoUnitDoubleValidator::validate( QString &s, int &pos ) const
00041 {
00042
00043 kdDebug(30004) << "KoUnitDoubleValidator::validate : " << s << " at " << pos << endl;
00044 QValidator::State result = Acceptable;
00045
00046 QRegExp regexp ("([ a-zA-Z]+)$");
00047 const int res = regexp.search( s );
00048
00049 if ( res == -1 )
00050 {
00051
00052 kdDebug(30004) << "Intermediate (no unit)" << endl;
00053 return Intermediate;
00054 }
00055
00056
00057 const QString number ( s.left( res ).stripWhiteSpace() );
00058 const QString unitName ( regexp.cap( 1 ).stripWhiteSpace().lower() );
00059
00060 kdDebug(30004) << "Split:" << number << ":" << unitName << ":" << endl;
00061
00062 bool ok = false;
00063 const double value = m_base->toDouble( number, &ok );
00064 double newVal = 0.0;
00065 if( ok )
00066 {
00067 KoUnit::Unit unit = KoUnit::unit( unitName, &ok );
00068 if ( ok )
00069 newVal = KoUnit::fromUserValue( value, unit );
00070 else
00071 {
00072
00073 kdDebug(30004) << "Intermediate (unknown unit)" << endl;
00074 return Intermediate;
00075 }
00076 }
00077 else
00078 {
00079 kdWarning(30004) << "Not a number: " << number << endl;
00080 return Invalid;
00081 }
00082
00083 newVal = KoUnit::ptToUnit( newVal, m_base->m_unit );
00084
00085 s = m_base->getVisibleText( newVal );
00086
00087 return result;
00088 }
00089
00090
00091 QString KoUnitDoubleBase::getVisibleText( double value ) const
00092 {
00093 const QString num ( QString( "%1%2").arg( KGlobal::locale()->formatNumber( value, m_precision ), KoUnit::unitName( m_unit ) ) );
00094 kdDebug(30004) << "getVisibleText: " << QString::number( value, 'f', 12 ) << " => " << num << endl;
00095 return num;
00096 }
00097
00098 double KoUnitDoubleBase::toDouble( const QString& str, bool* ok ) const
00099 {
00100 QString str2( str );
00101
00102
00103 const QString sep( KGlobal::locale()->thousandsSeparator() );
00104 if ( !sep.isEmpty() )
00105 str2.remove( sep );
00106 str2.remove( KoUnit::unitName( m_unit ) );
00107 const double dbl = KGlobal::locale()->readNumber( str2, ok );
00108 if ( ok )
00109 kdDebug(30004) << "toDouble:" << str << ": => :" << str2 << ": => " << QString::number( dbl, 'f', 12 ) << endl;
00110 else
00111 kdWarning(30004) << "toDouble error:" << str << ": => :" << str2 << ":" << endl;
00112 return dbl;
00113 }
00114
00115
00116
00117
00118
00119
00120 KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent, const char *name )
00121 : KDoubleSpinBox( parent, name ), KoUnitDoubleBase( KoUnit::U_PT, 2 )
00122 , m_lowerInPoints( -9999 )
00123 , m_upperInPoints( 9999 )
00124 , m_stepInPoints( 1 )
00125 {
00126 KDoubleSpinBox::setPrecision( 2 );
00127 m_validator = new KoUnitDoubleValidator( this, this );
00128 QSpinBox::setValidator( m_validator );
00129 setAcceptLocalizedNumbers( true );
00130 setUnit( KoUnit::U_PT );
00131
00132 connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
00133 }
00134
00135
00136 KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent,
00137 double lower, double upper,
00138 double step,
00139 double value,
00140 KoUnit::Unit unit,
00141 unsigned int precision,
00142 const char *name )
00143 : KDoubleSpinBox( lower, upper, step, value, precision, parent, name ),
00144 KoUnitDoubleBase( unit, precision ),
00145 m_lowerInPoints( lower ), m_upperInPoints( upper ), m_stepInPoints( step )
00146 {
00147 m_unit = KoUnit::U_PT;
00148 m_validator = new KoUnitDoubleValidator( this, this );
00149 QSpinBox::setValidator( m_validator );
00150 setAcceptLocalizedNumbers( true );
00151 setUnit( unit );
00152 changeValue( value );
00153 setLineStep( 0.5 );
00154
00155 connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
00156 }
00157
00158 void
00159 KoUnitDoubleSpinBox::changeValue( double val )
00160 {
00161 KDoubleSpinBox::setValue( KoUnit::toUserValue( val, m_unit ) );
00162
00163
00164
00165 }
00166
00167 void KoUnitDoubleSpinBox::privateValueChanged() {
00168 emit valueChangedPt( value () );
00169 }
00170
00171 void
00172 KoUnitDoubleSpinBox::setUnit( KoUnit::Unit unit )
00173 {
00174 double oldvalue = KoUnit::fromUserValue( KDoubleSpinBox::value(), m_unit );
00175 KDoubleSpinBox::setMinValue( KoUnit::toUserValue( m_lowerInPoints, unit ) );
00176 KDoubleSpinBox::setMaxValue( KoUnit::toUserValue( m_upperInPoints, unit ) );
00177 KDoubleSpinBox::setLineStep( KoUnit::toUserValue( m_stepInPoints, unit ) );
00178 KDoubleSpinBox::setValue( KoUnit::ptToUnit( oldvalue, unit ) );
00179 m_unit = unit;
00180 setSuffix( KoUnit::unitName( unit ).prepend( ' ' ) );
00181 }
00182
00183 double KoUnitDoubleSpinBox::value( void ) const
00184 {
00185 return KoUnit::fromUserValue( KDoubleSpinBox::value(), m_unit );
00186 }
00187
00188 void KoUnitDoubleSpinBox::setMinValue( double min )
00189 {
00190 m_lowerInPoints = min;
00191 KDoubleSpinBox::setMinValue( KoUnit::toUserValue( m_lowerInPoints, m_unit ) );
00192 }
00193
00194 void KoUnitDoubleSpinBox::setMaxValue( double max )
00195 {
00196 m_upperInPoints = max;
00197 KDoubleSpinBox::setMaxValue( KoUnit::toUserValue( m_upperInPoints, m_unit ) );
00198 }
00199
00200 void KoUnitDoubleSpinBox::setLineStep( double step )
00201 {
00202 m_stepInPoints = KoUnit::toUserValue(step, KoUnit::U_PT );
00203 KDoubleSpinBox::setLineStep( step );
00204 }
00205
00206 void KoUnitDoubleSpinBox::setLineStepPt( double step )
00207 {
00208 m_stepInPoints = step;
00209 KDoubleSpinBox::setLineStep( KoUnit::toUserValue( m_stepInPoints, m_unit ) );
00210 }
00211
00212 void KoUnitDoubleSpinBox::setMinMaxStep( double min, double max, double step )
00213 {
00214 setMinValue( min );
00215 setMaxValue( max );
00216 setLineStepPt( step );
00217 }
00218
00219
00220
00221
00222 KoUnitDoubleLineEdit::KoUnitDoubleLineEdit( QWidget *parent, const char *name )
00223 : KLineEdit( parent, name ), KoUnitDoubleBase( KoUnit::U_PT, 2 ), m_value( 0.0 ), m_lower( 0.0 ), m_upper( 9999.99 ),
00224 m_lowerInPoints( 0.0 ), m_upperInPoints( 9999.99 )
00225 {
00226 setAlignment( Qt::AlignRight );
00227 m_validator = new KoUnitDoubleValidator( this, this );
00228 setValidator( m_validator );
00229 setUnit( KoUnit::U_PT );
00230 changeValue( KoUnit::ptToUnit( 0.0, KoUnit::U_PT ) );
00231 }
00232
00233 KoUnitDoubleLineEdit::KoUnitDoubleLineEdit( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit,
00234 unsigned int precision, const char *name )
00235 : KLineEdit( parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ),
00236 m_lowerInPoints( lower ), m_upperInPoints( upper )
00237 {
00238 setAlignment( Qt::AlignRight );
00239 m_validator = new KoUnitDoubleValidator( this, this );
00240 setValidator( m_validator );
00241 setUnit( unit );
00242 changeValue( KoUnit::ptToUnit( value, unit ) );
00243 }
00244
00245 void
00246 KoUnitDoubleLineEdit::changeValue( double value )
00247 {
00248 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00249 setText( getVisibleText( m_value ) );
00250 }
00251
00252 void
00253 KoUnitDoubleLineEdit::setUnit( KoUnit::Unit unit )
00254 {
00255 KoUnit::Unit old = m_unit;
00256 m_unit = unit;
00257 m_lower = KoUnit::ptToUnit( m_lowerInPoints, unit );
00258 m_upper = KoUnit::ptToUnit( m_upperInPoints, unit );
00259 changeValue( KoUnit::ptToUnit( KoUnit::fromUserValue( m_value, old ), unit ) );
00260 }
00261
00262 bool
00263 KoUnitDoubleLineEdit::eventFilter( QObject* o, QEvent* ev )
00264 {
00265 #if 0
00266 if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
00267 {
00268 bool ok;
00269 double value = toDouble( text(), &ok );
00270 changeValue( value );
00271 return false;
00272 }
00273 else
00274 #endif
00275 return QLineEdit::eventFilter( o, ev );
00276 }
00277
00278 double KoUnitDoubleLineEdit::value( void ) const
00279 {
00280 return KoUnit::fromUserValue( m_value, m_unit );
00281 }
00282
00283
00284
00285
00286
00287 KoUnitDoubleComboBox::KoUnitDoubleComboBox( QWidget *parent, const char *name )
00288 : KComboBox( true, parent, name ), KoUnitDoubleBase( KoUnit::U_PT, 2 ), m_value( 0.0 ), m_lower( 0.0 ), m_upper( 9999.99 ), m_lowerInPoints( 0.0 ), m_upperInPoints( 9999.99 )
00289 {
00290 lineEdit()->setAlignment( Qt::AlignRight );
00291 m_validator = new KoUnitDoubleValidator( this, this );
00292 lineEdit()->setValidator( m_validator );
00293 setUnit( KoUnit::U_PT );
00294 changeValue( KoUnit::ptToUnit( 0.0, KoUnit::U_PT ) );
00295 connect( this, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) );
00296 }
00297
00298 KoUnitDoubleComboBox::KoUnitDoubleComboBox( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit,
00299 unsigned int precision, const char *name )
00300 : KComboBox( true, parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ),
00301 m_lowerInPoints( lower ), m_upperInPoints( upper )
00302 {
00303 lineEdit()->setAlignment( Qt::AlignRight );
00304 m_validator = new KoUnitDoubleValidator( this, this );
00305 lineEdit()->setValidator( m_validator );
00306 setUnit( unit );
00307 changeValue( KoUnit::ptToUnit( value, unit ) );
00308 connect( this, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) );
00309 }
00310
00311 void
00312 KoUnitDoubleComboBox::changeValue( double value )
00313 {
00314 QString oldLabel = lineEdit()->text();
00315 updateValue( value );
00316 if( lineEdit()->text() != oldLabel )
00317 emit valueChanged( m_value );
00318 }
00319
00320 void
00321 KoUnitDoubleComboBox::updateValue( double value )
00322 {
00323 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00324 lineEdit()->setText( getVisibleText( m_value ) );
00325 }
00326
00327 void
00328 KoUnitDoubleComboBox::insertItem( double value, int index )
00329 {
00330 KComboBox::insertItem( getVisibleText( value ), index );
00331 }
00332
00333 void
00334 KoUnitDoubleComboBox::slotActivated( int index )
00335 {
00336 double oldvalue = m_value;
00337 bool ok;
00338 double value = toDouble( text( index ), &ok );
00339 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00340 if( m_value != oldvalue )
00341 emit valueChanged( m_value );
00342 }
00343
00344 void
00345 KoUnitDoubleComboBox::setUnit( KoUnit::Unit unit )
00346 {
00347 KoUnit::Unit old = m_unit;
00348 m_unit = unit;
00349 m_lower = KoUnit::ptToUnit( m_lowerInPoints, unit );
00350 m_upper = KoUnit::ptToUnit( m_upperInPoints, unit );
00351 changeValue( KoUnit::ptToUnit( KoUnit::fromUserValue( m_value, old ), unit ) );
00352 }
00353
00354 bool
00355 KoUnitDoubleComboBox::eventFilter( QObject* o, QEvent* ev )
00356 {
00357 #if 0
00358 if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
00359 {
00360 bool ok;
00361 double value = toDouble( lineEdit()->text(), &ok );
00362 changeValue( value );
00363 return false;
00364 }
00365 else
00366 #endif
00367 return QComboBox::eventFilter( o, ev );
00368 }
00369
00370 double KoUnitDoubleComboBox::value( void ) const
00371 {
00372 return KoUnit::fromUserValue( m_value, m_unit );
00373 }
00374
00375
00376
00377
00378
00379 KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox( QWidget *parent, const char *name )
00380 : QWidget( parent ), m_step( 1.0 )
00381 {
00382 QGridLayout *layout = new QGridLayout( this, 2, 3 );
00383
00384 QPushButton *up = new QPushButton( "+", this );
00385
00386 up->setMaximumHeight( 15 );
00387 up->setMaximumWidth( 15 );
00388 layout->addWidget( up, 0, 0 );
00389 connect( up, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) );
00390
00391 QPushButton *down = new QPushButton( "-", this );
00392 down->setMaximumHeight( 15 );
00393 down->setMaximumWidth( 15 );
00394 layout->addWidget( down, 1, 0 );
00395 connect( down, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) );
00396
00397 m_combo = new KoUnitDoubleComboBox( this, KoUnit::ptToUnit( 0.0, KoUnit::U_PT ), KoUnit::ptToUnit( 9999.99, KoUnit::U_PT ), 0.0, KoUnit::U_PT, 2, name );
00398 connect( m_combo, SIGNAL( valueChanged( double ) ), this, SIGNAL( valueChanged( double ) ) );
00399 layout->addMultiCellWidget( m_combo, 0, 1, 2, 2 );
00400 }
00401
00402 KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox( QWidget *parent, double lower, double upper, double step, double value,
00403 KoUnit::Unit unit, unsigned int precision, const char *name )
00404 : QWidget( parent ), m_step( step )
00405 {
00406 QGridLayout *layout = new QGridLayout( this, 2, 3 );
00407
00408 QPushButton *up = new QPushButton( "+", this );
00409
00410 up->setMaximumHeight( 15 );
00411 up->setMaximumWidth( 15 );
00412 layout->addWidget( up, 0, 0 );
00413 connect( up, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) );
00414
00415 QPushButton *down = new QPushButton( "-", this );
00416 down->setMaximumHeight( 15 );
00417 down->setMaximumWidth( 15 );
00418 layout->addWidget( down, 1, 0 );
00419 connect( down, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) );
00420
00421 m_combo = new KoUnitDoubleComboBox( this, KoUnit::ptToUnit( lower, unit ), KoUnit::ptToUnit( upper, unit ), value, unit, precision, name );
00422 connect( m_combo, SIGNAL( valueChanged( double ) ), this, SIGNAL( valueChanged( double ) ) );
00423 layout->addMultiCellWidget( m_combo, 0, 1, 2, 2 );
00424 }
00425
00426 void
00427 KoUnitDoubleSpinComboBox::slotUpClicked()
00428 {
00429 m_combo->changeValue( m_combo->value() + m_step );
00430 }
00431
00432 void
00433 KoUnitDoubleSpinComboBox::slotDownClicked()
00434 {
00435 m_combo->changeValue( m_combo->value() - m_step );
00436 }
00437
00438 void
00439 KoUnitDoubleSpinComboBox::insertItem( double value, int index )
00440 {
00441 m_combo->insertItem( value, index );
00442 }
00443
00444 void
00445 KoUnitDoubleSpinComboBox::updateValue( double value )
00446 {
00447 m_combo->updateValue( value );
00448 }
00449
00450 double
00451 KoUnitDoubleSpinComboBox::value() const
00452 {
00453 return m_combo->value();
00454 }
00455