lib Library API Documentation

koUnitWidgets.cc

00001 /* This file is part of the KDE project 00002 Copyright (C) 2002, Rob Buis(buis@kde.org) 00003 Copyright (C) 2004, Nicolas GOUTTE <goutte@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 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 // Taken from KoUnit::unit of KOffice CVS HEAD 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") /*compat*/ ) 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 // Taken from KoUnit::fromUserValue of KOffice CVS HEAD 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]+)$"); // Letters or spaces at end 00087 const int res = regexp.search( s ); 00088 00089 if ( res == -1 ) 00090 { 00091 // Nothing like an unit? The user is probably editing the unit 00092 kdDebug(30004) << "Intermediate (no unit)" << endl; 00093 return Intermediate; 00094 } 00095 00096 // ### TODO: are all the QString::stripWhiteSpace really necessary? 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 // Probably the user is trying to edit the unit 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 /* KLocale::readNumber wants the thousand separator exactly at 1000. 00147 But when editing, it might be anywhere. So we need to remove it. */ 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 //layout->setMargin( 2 ); 00300 QPushButton *up = new QPushButton( "+", this ); 00301 //up->setFlat( true ); 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
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Nov 17 06:54:19 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003