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 const QString num ( QString( "%1%2").arg( KGlobal::locale()->formatNumber( value, m_precision ), KoUnit::unitName( m_unit ) ) ); 00134 kdDebug(30004) << "getVisibleText: " << QString::number( value, 'f', 12 ) << " => " << num << endl; 00135 return num; 00136 } 00137 00138 double KoUnitDoubleBase::toDouble( const QString& str, bool* ok ) 00139 { 00140 QString str2( str ); 00141 /* KLocale::readNumber wants the thousand separator exactly at 1000. 00142 But when editing, it might be anywhere. So we need to remove it. */ 00143 const QString sep( KGlobal::locale()->thousandsSeparator() ); 00144 if ( !sep.isEmpty() ) 00145 str2.remove( sep ); 00146 const double dbl = KGlobal::locale()->readNumber( str2, ok ); 00147 if ( ok ) 00148 kdDebug(30004) << "toDouble:" << str << ": => :" << str2 << ": => " << QString::number( dbl, 'f', 12 ) << endl; 00149 else 00150 kdWarning(30004) << "toDouble error:" << str << ": => :" << str2 << ":" << endl; 00151 return dbl; 00152 } 00153 00154 KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent, double lower, double upper, double step, double value, KoUnit::Unit unit, unsigned int precision, const char *name ) 00155 : KDoubleSpinBox( lower, upper, step, value, precision, parent, name ), KoUnitDoubleBase( unit, precision ) 00156 { 00157 m_validator = new KoUnitDoubleValidator( this, this ); 00158 QSpinBox::setValidator( m_validator ); 00159 setAcceptLocalizedNumbers( true ); 00160 setUnit( unit ); 00161 } 00162 00163 void 00164 KoUnitDoubleSpinBox::changeValue( double val ) 00165 { 00166 KDoubleSpinBox::setValue( val ); 00167 } 00168 00169 void 00170 KoUnitDoubleSpinBox::setUnit( KoUnit::Unit unit ) 00171 { 00172 double oldvalue = KoUnit::ptFromUnit( value(), m_unit ); 00173 setMinValue( KoUnit::ptToUnit( KoUnit::ptFromUnit( minValue(), m_unit ), unit ) ); 00174 setMaxValue( KoUnit::ptToUnit( KoUnit::ptFromUnit( maxValue(), m_unit ), unit ) ); 00175 KDoubleSpinBox::setValue( KoUnit::ptToUnit( oldvalue, unit ) ); 00176 m_unit = unit; 00177 setSuffix( KoUnit::unitName( unit ) ); 00178 } 00179 00180 00181 KoUnitDoubleLineEdit::KoUnitDoubleLineEdit( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit, unsigned int precision, const char *name ) 00182 : KLineEdit( parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ) 00183 { 00184 setAlignment( Qt::AlignRight ); 00185 m_validator = new KoUnitDoubleValidator( this, this ); 00186 setValidator( m_validator ); 00187 changeValue( value ); 00188 } 00189 00190 void 00191 KoUnitDoubleLineEdit::changeValue( double value ) 00192 { 00193 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value ); 00194 setText( getVisibleText( m_value ) ); 00195 } 00196 00197 void 00198 KoUnitDoubleLineEdit::setUnit( KoUnit::Unit unit ) 00199 { 00200 KoUnit::Unit old = m_unit; 00201 m_unit = unit; 00202 m_lower = KoUnit::ptToUnit( KoUnit::ptFromUnit( m_lower, old ), unit ); 00203 m_upper = KoUnit::ptToUnit( KoUnit::ptFromUnit( m_upper, old ), unit ); 00204 changeValue( KoUnit::ptToUnit( KoUnit::ptFromUnit( m_value, old ), unit ) ); 00205 } 00206 00207 bool 00208 KoUnitDoubleLineEdit::eventFilter( QObject* o, QEvent* ev ) 00209 { 00210 if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide ) 00211 { 00212 bool ok; 00213 const double value = KoUnitDoubleBase::toDouble( text(), &ok ); 00214 changeValue( value ); 00215 return false; 00216 } 00217 else 00218 return QLineEdit::eventFilter( o, ev ); 00219 } 00220 00221 00222 00223 KoUnitDoubleComboBox::KoUnitDoubleComboBox( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit, unsigned int precision, const char *name ) 00224 : KComboBox( true, parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ) 00225 { 00226 lineEdit()->setAlignment( Qt::AlignRight ); 00227 m_validator = new KoUnitDoubleValidator( this, this ); 00228 lineEdit()->setValidator( m_validator ); 00229 changeValue( value ); 00230 connect( this, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) ); 00231 } 00232 00233 void 00234 KoUnitDoubleComboBox::changeValue( double value ) 00235 { 00236 QString oldLabel = lineEdit()->text(); 00237 updateValue( value ); 00238 if( lineEdit()->text() != oldLabel ) 00239 emit valueChanged( m_value ); 00240 } 00241 00242 void 00243 KoUnitDoubleComboBox::updateValue( double value ) 00244 { 00245 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value ); 00246 lineEdit()->setText( getVisibleText( m_value ) ); 00247 } 00248 00249 void 00250 KoUnitDoubleComboBox::insertItem( double value, int index ) 00251 { 00252 KComboBox::insertItem( getVisibleText( value ), index ); 00253 } 00254 00255 void 00256 KoUnitDoubleComboBox::slotActivated( int index ) 00257 { 00258 double oldvalue = m_value; 00259 bool ok; 00260 const double value = KoUnitDoubleBase::toDouble( text( index ), &ok ); 00261 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value ); 00262 if( m_value != oldvalue ) 00263 emit valueChanged( m_value ); 00264 } 00265 00266 void 00267 KoUnitDoubleComboBox::setUnit( KoUnit::Unit unit ) 00268 { 00269 KoUnit::Unit old = m_unit; 00270 m_unit = unit; 00271 m_lower = KoUnit::ptToUnit( KoUnit::ptFromUnit( m_lower, old ), unit ); 00272 m_upper = KoUnit::ptToUnit( KoUnit::ptFromUnit( m_upper, old ), unit ); 00273 changeValue( KoUnit::ptToUnit( getUserValue( m_value, old ), unit ) ); 00274 } 00275 00276 bool 00277 KoUnitDoubleComboBox::eventFilter( QObject* o, QEvent* ev ) 00278 { 00279 if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide ) 00280 { 00281 bool ok; 00282 const double value = KoUnitDoubleBase::toDouble( lineEdit()->text(), &ok ); 00283 changeValue( value ); 00284 return false; 00285 } 00286 else 00287 return QComboBox::eventFilter( o, ev ); 00288 } 00289 00290 KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox( QWidget *parent, double lower, double upper, double step, double value, KoUnit::Unit unit, unsigned int precision, const char *name ) 00291 : QWidget( parent ), m_step( step ) 00292 { 00293 QGridLayout *layout = new QGridLayout( this, 2, 3 ); 00294 //layout->setMargin( 2 ); 00295 QPushButton *up = new QPushButton( "+", this ); 00296 //up->setFlat( true ); 00297 up->setMaximumHeight( 15 ); 00298 up->setMaximumWidth( 15 ); 00299 layout->addWidget( up, 0, 0 ); 00300 connect( up, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) ); 00301 00302 QPushButton *down = new QPushButton( "-", this ); 00303 down->setMaximumHeight( 15 ); 00304 down->setMaximumWidth( 15 ); 00305 layout->addWidget( down, 1, 0 ); 00306 connect( down, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) ); 00307 00308 m_combo = new KoUnitDoubleComboBox( this, lower, upper, value, unit, precision, name ); 00309 connect( m_combo, SIGNAL( valueChanged( double ) ), this, SIGNAL( valueChanged( double ) ) ); 00310 layout->addMultiCellWidget( m_combo, 0, 1, 2, 2 ); 00311 } 00312 00313 void 00314 KoUnitDoubleSpinComboBox::slotUpClicked() 00315 { 00316 m_combo->changeValue( m_combo->value() + m_step ); 00317 } 00318 00319 void 00320 KoUnitDoubleSpinComboBox::slotDownClicked() 00321 { 00322 m_combo->changeValue( m_combo->value() - m_step ); 00323 } 00324 00325 void 00326 KoUnitDoubleSpinComboBox::insertItem( double value, int index ) 00327 { 00328 m_combo->insertItem( value, index ); 00329 } 00330 00331 void 00332 KoUnitDoubleSpinComboBox::updateValue( double value ) 00333 { 00334 m_combo->updateValue( value ); 00335 } 00336 00337 double 00338 KoUnitDoubleSpinComboBox::value() const 00339 { 00340 return m_combo->value(); 00341 } 00342
KDE Logo
This file is part of the documentation for lib Library Version 1.3.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Sep 28 04:04:02 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003