F:/KPlato/koffice/libs/kofficeui/KoUnitWidgets.cpp

Aller à la documentation de ce fichier.
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., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "KoUnitWidgets.h"
00022 #include "KoUnitWidgets.moc"
00023 #include <kdebug.h>
00024 #include <kglobal.h>
00025 #include <klocale.h>
00026 #include <QPushButton>
00027 #include <QGridLayout>
00028 #include <QEvent>
00029 
00030 
00031 // ----------------------------------------------------------------
00032 //                          Support classes
00033 
00034 
00035 KoUnitDoubleValidator::KoUnitDoubleValidator( KoUnitDoubleBase *base, QObject *parent, const char* /*name*/ )
00036 : KDoubleValidator( parent ), m_base( base )
00037 {
00038 }
00039 
00040 QValidator::State
00041 KoUnitDoubleValidator::validate( QString &s, int &pos ) const
00042 {
00043 
00044     kDebug(30004) << "KoUnitDoubleValidator::validate : " << s << " at " << pos << endl;
00045     QValidator::State result = Acceptable;
00046 
00047     QRegExp regexp ("([ a-zA-Z]+)$"); // Letters or spaces at end
00048     const int res = s.indexOf( regexp );
00049 
00050     if ( res == -1 )
00051     {
00052         // Nothing like an unit? The user is probably editing the unit
00053         kDebug(30004) << "Intermediate (no unit)" << endl;
00054         return Intermediate;
00055     }
00056 
00057     // ### TODO: are all the QString::trimmed really necessary?
00058     const QString number ( s.left( res ).trimmed() );
00059     const QString unitName ( regexp.cap( 1 ).trimmed().toLower() );
00060 
00061     kDebug(30004) << "Split:" << number << ":" << unitName << ":" << endl;
00062 
00063     bool ok = false;
00064     const double value = m_base->toDouble( number, &ok );
00065     double newVal = 0.0;
00066     if( ok )
00067     {
00068         KoUnit::Unit unit = KoUnit::unit( unitName, &ok );
00069         if ( ok )
00070             newVal = KoUnit::fromUserValue( value, unit );
00071         else
00072         {
00073             // Probably the user is trying to edit the unit
00074             kDebug(30004) << "Intermediate (unknown unit)" << endl;
00075             return Intermediate;
00076         }
00077     }
00078     else
00079     {
00080         kWarning(30004) << "Not a number: " << number << endl;
00081         return Invalid;
00082     }
00083 
00084     newVal = KoUnit::ptToUnit( newVal, m_base->m_unit );
00085 
00086     s = m_base->getVisibleText( newVal );
00087 
00088     return result;
00089 }
00090 
00091 
00092 QString KoUnitDoubleBase::getVisibleText( double value ) const
00093 {
00094     const QString num ( QString( "%1%2").arg( KGlobal::locale()->formatNumber( value, m_precision ), KoUnit::unitName( m_unit ) ) );
00095     kDebug(30004) << "getVisibleText: " << QString::number( value, 'f', 12 ) << " => " << num << endl;
00096     return num;
00097 }
00098 
00099 double KoUnitDoubleBase::toDouble( const QString& str, bool* ok ) const
00100 {
00101     QString str2( str );
00102     /* KLocale::readNumber wants the thousand separator exactly at 1000.
00103        But when editing, it might be anywhere. So we need to remove it. */
00104     const QString sep( KGlobal::locale()->thousandsSeparator() );
00105     if ( !sep.isEmpty() )
00106         str2.remove( sep );
00107     str2.remove( KoUnit::unitName( m_unit ) );
00108     const double dbl = KGlobal::locale()->readNumber( str2, ok );
00109     if ( ok )
00110       kDebug(30004) << "toDouble:" << str << ": => :" << str2 << ": => " << QString::number( dbl, 'f', 12 ) << endl;
00111     else
00112         kWarning(30004) << "toDouble error:" << str << ": => :" << str2 << ":" << endl;
00113     return dbl;
00114 }
00115 
00116 
00117 // ----------------------------------------------------------------
00118 //                          Widget classes
00119 
00120 
00121 KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent, const char *name )
00122     : KDoubleSpinBox( parent ), KoUnitDoubleBase( KoUnit::U_PT, 2 )
00123     , m_lowerInPoints( -9999 )
00124     , m_upperInPoints( 9999 )
00125     , m_stepInPoints( 1 )
00126 {
00127         setObjectName(name);
00128     KDoubleSpinBox::setPrecision( 2 );
00129     m_validator = new KoUnitDoubleValidator( this, this );
00130     setValidator( m_validator );
00131     setAcceptLocalizedNumbers( true );
00132     setUnit( KoUnit::U_PT );
00133 
00134     connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
00135 }
00136 
00137 
00138 KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent,
00139                                                     double lower, double upper,
00140                                                     double step,
00141                                                     double value,
00142                                                     KoUnit::Unit unit,
00143                                                     unsigned int precision,
00144                                                     const char* /*name*/ )
00145     : KDoubleSpinBox( lower, upper, step, value, parent, precision ),
00146       KoUnitDoubleBase( unit, precision ),
00147     m_lowerInPoints( lower ), m_upperInPoints( upper ), m_stepInPoints( step )
00148 {
00149     m_unit = KoUnit::U_PT;
00150     m_validator = new KoUnitDoubleValidator( this, this );
00151     setValidator( m_validator );
00152     setAcceptLocalizedNumbers( true );
00153     setUnit( unit );
00154     changeValue( value );
00155     setLineStepPt( step );
00156 
00157     connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
00158 }
00159 
00160 void
00161 KoUnitDoubleSpinBox::changeValue( double val )
00162 {
00163     KDoubleSpinBox::setValue( KoUnit::toUserValue( val, m_unit ) );
00164     // TODO: emit valueChanged ONLY if the value was out-of-bounds
00165     // This will allow the 'user' dialog to set a dirty bool and ensure
00166     // a proper value is getting saved.
00167 }
00168 
00169 void KoUnitDoubleSpinBox::privateValueChanged() {
00170     emit valueChangedPt( value () );
00171 }
00172 
00173 void
00174 KoUnitDoubleSpinBox::setUnit( KoUnit::Unit unit )
00175 {
00176     double oldvalue = KoUnit::fromUserValue( KDoubleSpinBox::value(), m_unit );
00177     KDoubleSpinBox::setMinimum( KoUnit::toUserValue( m_lowerInPoints, unit ) );
00178     KDoubleSpinBox::setMaximum( KoUnit::toUserValue( m_upperInPoints, unit ) );
00179     KDoubleSpinBox::setSingleStep( KoUnit::toUserValue( m_stepInPoints, unit ) );
00180     KDoubleSpinBox::setValue( KoUnit::ptToUnit( oldvalue, unit ) );
00181     m_unit = unit;
00182     setSuffix( KoUnit::unitName( unit ).prepend( ' ' ) );
00183 }
00184 
00185 double KoUnitDoubleSpinBox::value( void ) const
00186 {
00187     return KoUnit::fromUserValue( KDoubleSpinBox::value(), m_unit );
00188 }
00189 
00190 void KoUnitDoubleSpinBox::setMinimum( double min )
00191 {
00192   m_lowerInPoints = min;
00193   KDoubleSpinBox::setMinimum( KoUnit::toUserValue( m_lowerInPoints, m_unit ) );
00194 }
00195 
00196 void KoUnitDoubleSpinBox::setMaximum( double max )
00197 {
00198   m_upperInPoints = max;
00199   KDoubleSpinBox::setMaximum( KoUnit::toUserValue( m_upperInPoints, m_unit ) );
00200 }
00201 
00202 void KoUnitDoubleSpinBox::setLineStep( double step )
00203 {
00204   m_stepInPoints = KoUnit::toUserValue(step, KoUnit::U_PT );
00205   KDoubleSpinBox::setSingleStep( step );
00206 }
00207 
00208 void KoUnitDoubleSpinBox::setLineStepPt( double step )
00209 {
00210   m_stepInPoints = step;
00211   KDoubleSpinBox::setSingleStep( KoUnit::toUserValue( m_stepInPoints, m_unit ) );
00212 }
00213 
00214 void KoUnitDoubleSpinBox::setMinMaxStep( double min, double max, double step )
00215 {
00216   setMinimum( min );
00217   setMaximum( max );
00218   setLineStepPt( step );
00219 }
00220 
00221 // ----------------------------------------------------------------
00222 
00223 
00224 KoUnitDoubleLineEdit::KoUnitDoubleLineEdit( QWidget *parent, const char* /*name*/ )
00225     : KLineEdit( parent ), KoUnitDoubleBase( KoUnit::U_PT, 2 ), m_value( 0.0 ), m_lower( 0.0 ), m_upper( 9999.99 ),
00226     m_lowerInPoints( 0.0 ), m_upperInPoints( 9999.99 )
00227 {
00228     setAlignment( Qt::AlignRight );
00229     m_validator = new KoUnitDoubleValidator( this, this );
00230     setValidator( m_validator );
00231     setUnit( KoUnit::U_PT );
00232     changeValue(  KoUnit::ptToUnit( 0.0, KoUnit::U_PT ) );
00233 }
00234 
00235 KoUnitDoubleLineEdit::KoUnitDoubleLineEdit( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit,
00236     unsigned int precision, const char* /*name*/ )
00237     : KLineEdit( parent ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ),
00238     m_lowerInPoints( lower ), m_upperInPoints( upper )
00239 {
00240     setAlignment( Qt::AlignRight );
00241     m_validator = new KoUnitDoubleValidator( this, this );
00242     setValidator( m_validator );
00243     setUnit( unit );
00244     changeValue(  KoUnit::ptToUnit( value, unit ) );
00245 }
00246 
00247 void
00248 KoUnitDoubleLineEdit::changeValue( double value )
00249 {
00250     m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00251     setText( getVisibleText( m_value ) );
00252 }
00253 
00254 void
00255 KoUnitDoubleLineEdit::setUnit( KoUnit::Unit unit )
00256 {
00257     KoUnit::Unit old = m_unit;
00258     m_unit = unit;
00259     m_lower = KoUnit::ptToUnit( m_lowerInPoints, unit );
00260     m_upper = KoUnit::ptToUnit( m_upperInPoints, unit );
00261     changeValue( KoUnit::ptToUnit( KoUnit::fromUserValue( m_value, old ), unit ) );
00262 }
00263 
00264 bool
00265 KoUnitDoubleLineEdit::eventFilter( QObject* o, QEvent* ev )
00266 {
00267 #if 0
00268         if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
00269         {
00270                 bool ok;
00271                 double value = toDouble( text(), &ok );
00272                 changeValue( value );
00273                 return false;
00274         }
00275         else
00276 #endif
00277             return QLineEdit::eventFilter( o, ev );
00278 }
00279 
00280 double KoUnitDoubleLineEdit::value( void ) const
00281 {
00282     return KoUnit::fromUserValue( m_value, m_unit );
00283 }
00284 
00285 
00286 // ----------------------------------------------------------------
00287 
00288 
00289 KoUnitDoubleComboBox::KoUnitDoubleComboBox( QWidget *parent, const char* /*name*/ )
00290      : KComboBox( true, parent ), KoUnitDoubleBase( KoUnit::U_PT, 2 ), m_value( 0.0 ), m_lower( 0.0 ), m_upper( 9999.99 ), m_lowerInPoints( 0.0 ), m_upperInPoints( 9999.99 )
00291 {
00292     lineEdit()->setAlignment( Qt::AlignRight );
00293     m_validator = new KoUnitDoubleValidator( this, this );
00294     lineEdit()->setValidator( m_validator );
00295     setUnit( KoUnit::U_PT );
00296     changeValue(  KoUnit::ptToUnit( 0.0, KoUnit::U_PT ) );
00297     connect( this, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) );
00298 }
00299 
00300 KoUnitDoubleComboBox::KoUnitDoubleComboBox( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit,
00301      unsigned int precision, const char* /*name*/ )
00302      : KComboBox( true, parent ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ),
00303      m_lowerInPoints( lower ), m_upperInPoints( upper )
00304 {
00305     lineEdit()->setAlignment( Qt::AlignRight );
00306     m_validator = new KoUnitDoubleValidator( this, this );
00307     lineEdit()->setValidator( m_validator );
00308     setUnit( unit );
00309     changeValue(  KoUnit::ptToUnit( value, unit ) );
00310     connect( this, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) );
00311 }
00312 
00313 void
00314 KoUnitDoubleComboBox::changeValue( double value )
00315 {
00316     QString oldLabel = lineEdit()->text();
00317     updateValue( value );
00318     if( lineEdit()->text() != oldLabel )
00319         emit valueChanged( m_value );
00320 }
00321 
00322 void
00323 KoUnitDoubleComboBox::updateValue( double value )
00324 {
00325     m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00326     lineEdit()->setText( getVisibleText( m_value ) );
00327 }
00328 
00329 void
00330 KoUnitDoubleComboBox::insertItem( double value, int index )
00331 {
00332     KComboBox::insertItem( index, getVisibleText( value ) );
00333 }
00334 
00335 void
00336 KoUnitDoubleComboBox::slotActivated( int index )
00337 {
00338     double oldvalue = m_value;
00339     bool ok;
00340     double value = toDouble( itemText( index ), &ok );
00341     m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00342     if( m_value != oldvalue )
00343         emit valueChanged( m_value );
00344 }
00345 
00346 void
00347 KoUnitDoubleComboBox::setUnit( KoUnit::Unit unit )
00348 {
00349     KoUnit::Unit old = m_unit;
00350     m_unit = unit;
00351     m_lower = KoUnit::ptToUnit( m_lowerInPoints, unit );
00352     m_upper = KoUnit::ptToUnit( m_upperInPoints, unit );
00353     changeValue( KoUnit::ptToUnit( KoUnit::fromUserValue( m_value, old ), unit ) );
00354 }
00355 
00356 bool
00357 KoUnitDoubleComboBox::eventFilter( QObject* o, QEvent* ev )
00358 {
00359 #if 0
00360         if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
00361         {
00362                 bool ok;
00363                 double value = toDouble( lineEdit()->text(), &ok );
00364                 changeValue( value );
00365                 return false;
00366         }
00367         else
00368 #endif
00369             return QComboBox::eventFilter( o, ev );
00370 }
00371 
00372 double KoUnitDoubleComboBox::value( void ) const
00373 {
00374     return KoUnit::fromUserValue( m_value, m_unit );
00375 }
00376 
00377 
00378 // ----------------------------------------------------------------
00379 
00380 
00381 KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox( QWidget *parent, const char *name )
00382     : QWidget( parent ), m_step( 1.0 )
00383 {
00384     QGridLayout *layout = new QGridLayout( this );
00385     //layout->setMargin( 2 );
00386     QPushButton *up = new QPushButton( "+", this );
00387     //up->setFlat( true );
00388     up->setMaximumHeight( 15 );
00389     up->setMaximumWidth( 15 );
00390     layout->addWidget( up, 0, 0 );
00391     connect( up, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) );
00392 
00393     QPushButton *down = new QPushButton( "-", this );
00394     down->setMaximumHeight( 15 );
00395     down->setMaximumWidth( 15 );
00396     layout->addWidget( down, 1, 0 );
00397     connect( down, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) );
00398 
00399     m_combo = new KoUnitDoubleComboBox( this, KoUnit::ptToUnit( 0.0, KoUnit::U_PT ), KoUnit::ptToUnit( 9999.99, KoUnit::U_PT ), 0.0, KoUnit::U_PT, 2, name );
00400     connect( m_combo, SIGNAL( valueChanged( double ) ), this, SIGNAL( valueChanged( double ) ) );
00401     layout->addWidget( m_combo, 0, 2, 2, 1 );
00402 }
00403 
00404 KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox( QWidget *parent, double lower, double upper, double step, double value,
00405                                                     KoUnit::Unit unit, unsigned int precision, const char *name )
00406     : QWidget( parent ), m_step( step )//, m_lowerInPoints( lower ), m_upperInPoints( upper )
00407 {
00408     QGridLayout *layout = new QGridLayout( this );
00409     //layout->setMargin( 2 );
00410     QPushButton *up = new QPushButton( "+", this );
00411     //up->setFlat( true );
00412     up->setMaximumHeight( 15 );
00413     up->setMaximumWidth( 15 );
00414     layout->addWidget( up, 0, 0 );
00415     connect( up, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) );
00416 
00417     QPushButton *down = new QPushButton( "-", this );
00418     down->setMaximumHeight( 15 );
00419     down->setMaximumWidth( 15 );
00420     layout->addWidget( down, 1, 0 );
00421     connect( down, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) );
00422 
00423     m_combo = new KoUnitDoubleComboBox( this, KoUnit::ptToUnit( lower, unit ), KoUnit::ptToUnit( upper, unit ), value, unit, precision, name );
00424     connect( m_combo, SIGNAL( valueChanged( double ) ), this, SIGNAL( valueChanged( double ) ) );
00425     layout->addWidget( m_combo, 0, 2, 2, 1 );
00426 }
00427 
00428 void
00429 KoUnitDoubleSpinComboBox::slotUpClicked()
00430 {
00431     m_combo->changeValue( m_combo->value() + m_step );
00432 }
00433 
00434 void
00435 KoUnitDoubleSpinComboBox::slotDownClicked()
00436 {
00437     m_combo->changeValue( m_combo->value() - m_step );
00438 }
00439 
00440 void
00441 KoUnitDoubleSpinComboBox::insertItem( double value, int index )
00442 {
00443     m_combo->insertItem( value, index );
00444 }
00445 
00446 void
00447 KoUnitDoubleSpinComboBox::updateValue( double value )
00448 {
00449     m_combo->updateValue( value );
00450 }
00451 
00452 double
00453 KoUnitDoubleSpinComboBox::value() const
00454 {
00455     return m_combo->value();
00456 }
00457 

Généré le Wed Nov 22 23:41:05 2006 pour KPlato par  doxygen 1.5.1-p1