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
180 QtxDblSpinBox* _this = ( QtxDblSpinBox* )this;
185 void QtxDblSpinBox::setValue( int val )
187 setValue( (double)val );
190 void QtxDblSpinBox::setValue( double val )
193 double prevVal = myValue;
194 myValue = bound( val );
195 if ( prevVal != myValue )
199 void QtxDblSpinBox::stepUp()
202 if ( wrapping() && myValue + myStep > myMax )
205 setValue( myValue + myStep );
208 void QtxDblSpinBox::stepDown()
211 if ( wrapping() && myValue - myStep < myMin )
214 setValue( myValue - myStep );
217 int QtxDblSpinBox::precision() const
222 void QtxDblSpinBox::setPrecision( const int prec )
224 int newPrec = QMAX( prec, 0 );
225 int oldPrec = QMAX( myPrecision, 0 );
227 if ( newPrec != oldPrec )
231 bool QtxDblSpinBox::isCleared() const
236 void QtxDblSpinBox::setCleared( const bool on )
238 if ( myCleared == on )
245 void QtxDblSpinBox::selectAll()
248 QSpinBox::selectAll();
250 editor()->selectAll();
254 bool QtxDblSpinBox::eventFilter( QObject* o, QEvent* e )
256 if ( !myCleared || o != editor() || !editor()->text().stripWhiteSpace().isEmpty() )
257 return QSpinBox::eventFilter( o, e );
259 if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Leave || e->type() == QEvent::Hide )
262 if ( e->type() == QEvent::KeyPress &&
263 ( ((QKeyEvent*)e)->key() == Key_Tab || ((QKeyEvent*)e)->key() == Key_BackTab ) )
265 QApplication::sendEvent( this, e );
269 return QSpinBox::eventFilter( o, e );
272 void QtxDblSpinBox::updateDisplay()
277 bool isBlock = myBlocked;
280 QString txt = currentValueText();
282 if ( myValue >= myMax )
283 QSpinBox::setValue( QSpinBox::maxValue() );
284 else if ( myValue <= myMin )
285 QSpinBox::setValue( QSpinBox::minValue() );
287 QSpinBox::setValue( ( QSpinBox::minValue() + QSpinBox::maxValue() ) / 2 );
289 QSpinBox::updateDisplay();
291 editor()->setText( myCleared ? QString::null : txt );
296 void QtxDblSpinBox::interpretText()
303 if ( !specialValueText().isEmpty() )
305 QString s = QString( text() ).stripWhiteSpace();
306 QString t = QString( specialValueText() ).stripWhiteSpace();
314 newVal = mapTextToDoubleValue( &ok );
320 void QtxDblSpinBox::valueChange()
323 emit valueChanged( value() );
324 emit valueChanged( currentValueText() );
327 void QtxDblSpinBox::rangeChange()
329 double min = QMIN( myMin, myMax );
330 double max = QMAX( myMin, myMax );
333 if ( validator()->inherits( "QDoubleValidator" ) )
334 ((QDoubleValidator*)validator())->setRange( myMin, myMax );
336 if ( myMin == myMax )
337 QSpinBox::setRange( 0, 0 );
339 QSpinBox::setRange( 0, 2 );
345 QString QtxDblSpinBox::currentValueText()
348 if ( (myValue == minValue()) && !specialValueText().isEmpty() )
349 s = specialValueText();
353 s.append( mapValueToText( myValue ) );
354 s.append( suffix() );
359 QString QtxDblSpinBox::mapValueToText( double v )
362 s.setNum( v, myPrecision < 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
366 QString QtxDblSpinBox::mapValueToText( int )
369 s.setNum( myValue, myPrecision < 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
373 double QtxDblSpinBox::mapTextToDoubleValue( bool* ok )
376 double newVal = s.toDouble( ok );
377 if ( !(*ok) && !( !prefix() && !suffix() ) )
380 newVal = s.toDouble( ok );
385 double QtxDblSpinBox::bound( double val )
388 if ( newVal > myMax )
390 if ( newVal < myMin )
395 void QtxDblSpinBox::leaveEvent( QEvent* e )
398 QSpinBox::leaveEvent( e );
401 void QtxDblSpinBox::wheelEvent( QWheelEvent* e )
406 QSpinBox::wheelEvent( e );
410 void QtxDblSpinBox::onTextChanged( const QString& str )
412 bool isBlock = myBlocked;