1 // File: QtxDblSpinBox.cxx
2 // Author: Sergey TELKOV
4 #include "QtxDblSpinBox.h"
7 #include <qvalidator.h>
8 #include <qapplication.h>
11 Class: QtxDblSpinBox::Validator [internal]
12 Descr: Validator for QtxDblSpinBox (getted from Trolltech Qt - SpinBoxValidator)
15 class QtxDblSpinBox::Validator : public QDoubleValidator
18 Validator( QtxDblSpinBox* sb, const char* name )
19 : QDoubleValidator( sb, name ), spinBox( sb ) {}
21 virtual State validate( QString& str, int& pos ) const;
24 QtxDblSpinBox* spinBox;
27 QValidator::State QtxDblSpinBox::Validator::validate( QString& str, int& pos ) const
29 QString pref = spinBox->prefix();
30 QString suff = spinBox->suffix();
31 uint overhead = pref.length() + suff.length();
32 State state = Invalid;
35 state = QDoubleValidator::validate( str, pos );
38 if ( str.length() >= overhead && str.startsWith( pref ) &&
39 str.right( suff.length() ) == suff )
41 QString core = str.mid( pref.length(), str.length() - overhead );
42 int corePos = pos - pref.length();
43 state = QDoubleValidator::validate( core, corePos );
44 pos = corePos + pref.length();
45 str.replace( pref.length(), str.length() - overhead, core );
49 state = QDoubleValidator::validate( str, pos );
50 if ( state == Invalid )
52 QString special = spinBox->specialValueText().stripWhiteSpace();
53 QString candidate = str.stripWhiteSpace();
54 if ( special.startsWith( candidate ) )
56 if ( candidate.length() == special.length() )
69 Descr: Spin box for real numbers.
72 QtxDblSpinBox::QtxDblSpinBox( QWidget* parent, const char* name )
73 : QSpinBox( parent, name ),
78 myMin = QRangeControl::minValue();
79 myMax = QRangeControl::maxValue();
80 myStep = QRangeControl::lineStep();
82 setValidator( new Validator( this, "double_spinbox_validator" ) );
86 connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
89 QtxDblSpinBox::QtxDblSpinBox( double min, double max, double step, QWidget* parent, const char* name )
90 : QSpinBox( parent, name ),
99 setValidator( new Validator( this, "double_spinbox_validator" ) );
103 connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
106 QtxDblSpinBox::~QtxDblSpinBox()
110 double QtxDblSpinBox::minValue() const
115 double QtxDblSpinBox::maxValue() const
120 void QtxDblSpinBox::setMinValue( int min )
122 setMinValue( (double)min );
125 void QtxDblSpinBox::setMinValue( double min )
134 void QtxDblSpinBox::setMaxValue( int max )
136 setMaxValue( (double)max );
139 void QtxDblSpinBox::setMaxValue( double max )
148 void QtxDblSpinBox::setRange( int min, int max )
150 setRange( (double)min, (double)max );
153 void QtxDblSpinBox::setRange( double min, double max )
155 if ( myMin != min || myMax != max )
163 double QtxDblSpinBox::lineStep() const
168 void QtxDblSpinBox::setLineStep( int step )
170 setLineStep( (double)step );
173 void QtxDblSpinBox::setLineStep( double step )
178 double QtxDblSpinBox::value() const
183 void QtxDblSpinBox::setValue( int val )
185 setValue( (double)val );
188 void QtxDblSpinBox::setValue( double val )
191 double prevVal = myValue;
192 myValue = bound( val );
193 if ( prevVal != myValue )
197 void QtxDblSpinBox::stepUp()
200 if ( wrapping() && myValue + myStep > myMax )
203 setValue( myValue + myStep );
206 void QtxDblSpinBox::stepDown()
209 if ( wrapping() && myValue - myStep < myMin )
212 setValue( myValue - myStep );
215 int QtxDblSpinBox::precision() const
220 void QtxDblSpinBox::setPrecision( const int prec )
222 int newPrec = QMAX( prec, 0 );
223 int oldPrec = QMAX( myPrecision, 0 );
225 if ( newPrec != oldPrec )
229 bool QtxDblSpinBox::isCleared() const
234 void QtxDblSpinBox::setCleared( const bool on )
236 if ( myCleared == on )
243 void QtxDblSpinBox::selectAll()
246 QSpinBox::selectAll();
248 editor()->selectAll();
252 bool QtxDblSpinBox::eventFilter( QObject* o, QEvent* e )
254 if ( !myCleared || o != editor() || !editor()->text().stripWhiteSpace().isEmpty() )
255 return QSpinBox::eventFilter( o, e );
257 if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Leave || e->type() == QEvent::Hide )
260 if ( e->type() == QEvent::KeyPress &&
261 ( ((QKeyEvent*)e)->key() == Key_Tab || ((QKeyEvent*)e)->key() == Key_BackTab ) )
263 QApplication::sendEvent( this, e );
267 return QSpinBox::eventFilter( o, e );
270 void QtxDblSpinBox::updateDisplay()
275 bool isBlock = myBlocked;
278 QString txt = currentValueText();
280 if ( myValue >= myMax )
281 QSpinBox::setValue( QSpinBox::maxValue() );
282 else if ( myValue <= myMin )
283 QSpinBox::setValue( QSpinBox::minValue() );
285 QSpinBox::setValue( ( QSpinBox::minValue() + QSpinBox::maxValue() ) / 2 );
287 QSpinBox::updateDisplay();
289 editor()->setText( myCleared ? QString::null : txt );
294 void QtxDblSpinBox::interpretText()
301 if ( !specialValueText().isEmpty() )
303 QString s = QString( text() ).stripWhiteSpace();
304 QString t = QString( specialValueText() ).stripWhiteSpace();
312 newVal = mapTextToDoubleValue( &ok );
318 void QtxDblSpinBox::valueChange()
321 emit valueChanged( value() );
322 emit valueChanged( currentValueText() );
325 void QtxDblSpinBox::rangeChange()
327 double min = QMIN( myMin, myMax );
328 double max = QMAX( myMin, myMax );
331 if ( validator()->inherits( "QDoubleValidator" ) )
332 ((QDoubleValidator*)validator())->setRange( myMin, myMax );
334 if ( myMin == myMax )
335 QSpinBox::setRange( 0, 0 );
337 QSpinBox::setRange( 0, 2 );
343 QString QtxDblSpinBox::currentValueText()
346 if ( (myValue == minValue()) && !specialValueText().isEmpty() )
347 s = specialValueText();
351 s.append( mapValueToText( myValue ) );
352 s.append( suffix() );
357 QString QtxDblSpinBox::mapValueToText( double v )
360 s.setNum( v, myPrecision < 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
364 QString QtxDblSpinBox::mapValueToText( int )
367 s.setNum( myValue, myPrecision < 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
371 double QtxDblSpinBox::mapTextToDoubleValue( bool* ok )
374 double newVal = s.toDouble( ok );
375 if ( !(*ok) && !( !prefix() && !suffix() ) )
378 newVal = s.toDouble( ok );
383 double QtxDblSpinBox::bound( double val )
386 if ( newVal > myMax )
388 if ( newVal < myMin )
393 void QtxDblSpinBox::leaveEvent( QEvent* e )
396 QSpinBox::leaveEvent( e );
399 void QtxDblSpinBox::wheelEvent( QWheelEvent* e )
404 QSpinBox::wheelEvent( e );
408 void QtxDblSpinBox::onTextChanged( const QString& str )
410 bool isBlock = myBlocked;