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" ) );
87 QtxDblSpinBox::QtxDblSpinBox( double min, double max, double step, QWidget* parent, const char* name )
88 : QSpinBox( parent, name ),
97 setValidator( new Validator( this, "double_spinbox_validator" ) );
102 QtxDblSpinBox::~QtxDblSpinBox()
106 double QtxDblSpinBox::minValue() const
111 double QtxDblSpinBox::maxValue() const
116 void QtxDblSpinBox::setMinValue( int min )
118 setMinValue( (double)min );
121 void QtxDblSpinBox::setMinValue( double min )
130 void QtxDblSpinBox::setMaxValue( int max )
132 setMaxValue( (double)max );
135 void QtxDblSpinBox::setMaxValue( double max )
144 void QtxDblSpinBox::setRange( int min, int max )
146 setRange( (double)min, (double)max );
149 void QtxDblSpinBox::setRange( double min, double max )
151 if ( myMin != min || myMax != max )
159 double QtxDblSpinBox::lineStep() const
164 void QtxDblSpinBox::setLineStep( int step )
166 setLineStep( (double)step );
169 void QtxDblSpinBox::setLineStep( double step )
174 double QtxDblSpinBox::value() const
179 void QtxDblSpinBox::setValue( int val )
181 setValue( (double)val );
184 void QtxDblSpinBox::setValue( double val )
187 double prevVal = myValue;
188 myValue = bound( val );
189 if ( prevVal != myValue )
193 void QtxDblSpinBox::stepUp()
196 if ( wrapping() && myValue + myStep > myMax )
199 setValue( myValue + myStep );
202 void QtxDblSpinBox::stepDown()
205 if ( wrapping() && myValue - myStep < myMin )
208 setValue( myValue - myStep );
211 int QtxDblSpinBox::precision() const
216 void QtxDblSpinBox::setPrecision( const int prec )
218 int newPrec = QMAX( prec, 0 );
219 int oldPrec = QMAX( myPrecision, 0 );
221 if ( newPrec != oldPrec )
225 bool QtxDblSpinBox::isCleared() const
230 void QtxDblSpinBox::setCleared( const bool on )
232 if ( myCleared == on )
239 void QtxDblSpinBox::selectAll()
242 QSpinBox::selectAll();
244 editor()->selectAll();
248 bool QtxDblSpinBox::eventFilter( QObject* o, QEvent* e )
250 if ( !myCleared || o != editor() || !editor()->text().stripWhiteSpace().isEmpty() )
251 return QSpinBox::eventFilter( o, e );
253 if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Leave || e->type() == QEvent::Hide )
256 if ( e->type() == QEvent::KeyPress &&
257 ( ((QKeyEvent*)e)->key() == Key_Tab || ((QKeyEvent*)e)->key() == Key_BackTab ) )
259 QApplication::sendEvent( this, e );
263 return QSpinBox::eventFilter( o, e );
266 void QtxDblSpinBox::updateDisplay()
271 bool isBlock = myBlocked;
274 QString txt = currentValueText();
276 if ( myValue >= myMax )
277 QSpinBox::setValue( QSpinBox::maxValue() );
278 else if ( myValue <= myMin )
279 QSpinBox::setValue( QSpinBox::minValue() );
281 QSpinBox::setValue( ( QSpinBox::minValue() + QSpinBox::maxValue() ) / 2 );
283 QSpinBox::updateDisplay();
285 editor()->setText( myCleared ? QString::null : txt );
290 void QtxDblSpinBox::interpretText()
297 if ( !specialValueText().isEmpty() )
299 QString s = QString( text() ).stripWhiteSpace();
300 QString t = QString( specialValueText() ).stripWhiteSpace();
308 newVal = mapTextToDoubleValue( &ok );
314 void QtxDblSpinBox::valueChange()
317 emit valueChanged( value() );
318 emit valueChanged( currentValueText() );
321 void QtxDblSpinBox::rangeChange()
323 double min = QMIN( myMin, myMax );
324 double max = QMAX( myMin, myMax );
327 if ( validator()->inherits( "QDoubleValidator" ) )
328 ((QDoubleValidator*)validator())->setRange( myMin, myMax );
330 if ( myMin == myMax )
331 QSpinBox::setRange( 0, 0 );
333 QSpinBox::setRange( 0, 2 );
339 QString QtxDblSpinBox::currentValueText()
342 if ( (myValue == minValue()) && !specialValueText().isEmpty() )
343 s = specialValueText();
347 s.append( mapValueToText( myValue ) );
348 s.append( suffix() );
353 QString QtxDblSpinBox::mapValueToText( double v )
356 s.setNum( v, myPrecision < 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
360 QString QtxDblSpinBox::mapValueToText( int )
363 s.setNum( myValue, myPrecision < 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
367 double QtxDblSpinBox::mapTextToDoubleValue( bool* ok )
370 double newVal = s.toDouble( ok );
371 if ( !(*ok) && !( !prefix() && !suffix() ) )
374 newVal = s.toDouble( ok );
379 double QtxDblSpinBox::bound( double val )
382 if ( newVal > myMax )
384 if ( newVal < myMin )
389 void QtxDblSpinBox::leaveEvent( QEvent* e )
392 QSpinBox::leaveEvent( e );
395 void QtxDblSpinBox::wheelEvent( QWheelEvent* e )
400 QSpinBox::wheelEvent( e );