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 <kdebug.h>
00023 #include <kglobal.h>
00024 #include <klocale.h>
00025 #include <qpushbutton.h>
00026 #include <qlayout.h>
00027 
00028 
00029 // ----------------------------------------------------------------
00030 //                          Support classes
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]+)$"); // Letters or spaces at end
00046     const int res = regexp.search( s );
00047 
00048     if ( res == -1 )
00049     {
00050         // Nothing like an unit? The user is probably editing the unit
00051         kdDebug(30004) << "Intermediate (no unit)" << endl;
00052         return Intermediate;
00053     }
00054 
00055     // ### TODO: are all the QString::stripWhiteSpace really necessary?
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             // Probably the user is trying to edit the unit
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     /* KLocale::readNumber wants the thousand separator exactly at 1000.
00101        But when editing, it might be anywhere. So we need to remove it. */
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     // TODO: emit valueChanged ONLY if the value was out-of-bounds
00140     // This will allow the 'user' dialog to set a dirty bool and ensure
00141     // a proper value is getting saved.
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 )//, m_lowerInPoints( lower ), m_upperInPoints( upper )
00315 {
00316     QGridLayout *layout = new QGridLayout( this, 2, 3 );
00317     //layout->setMargin( 2 );
00318     QPushButton *up = new QPushButton( "+", this );
00319     //up->setFlat( true );
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 
KDE Logo
This file is part of the documentation for lib Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:40:13 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003