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