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