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