1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 // File: QtxDblSpinBox.cxx
20 // Author: Sergey TELKOV
22 #include "QtxDblSpinBox.h"
24 #include <qlineedit.h>
25 #include <qvalidator.h>
26 #include <qapplication.h>
31 \class QtxDblSpinBox::Validator [internal]
32 Validator for QtxDblSpinBox (getted from Trolltech Qt - SpinBoxValidator)
34 class QtxDblSpinBox::Validator : public QDoubleValidator
37 Validator( QtxDblSpinBox* sb, const char* name )
38 : QDoubleValidator( sb, name ), spinBox( sb ) {}
40 virtual State validate( QString& str, int& pos ) const;
43 QtxDblSpinBox* spinBox;
48 Checks string and \return QValidator::State
50 QValidator::State QtxDblSpinBox::Validator::validate( QString& str, int& pos ) const
52 QString pref = spinBox->prefix();
53 QString suff = spinBox->suffix();
54 uint overhead = pref.length() + suff.length();
55 State state = Invalid;
58 state = QDoubleValidator::validate( str, pos );
61 if ( str.length() >= overhead && str.startsWith( pref ) &&
62 str.right( suff.length() ) == suff )
64 QString core = str.mid( pref.length(), str.length() - overhead );
65 int corePos = pos - pref.length();
66 state = QDoubleValidator::validate( core, corePos );
67 pos = corePos + pref.length();
68 str.replace( pref.length(), str.length() - overhead, core );
72 state = QDoubleValidator::validate( str, pos );
73 if ( state == Invalid )
75 QString special = spinBox->specialValueText().stripWhiteSpace();
76 QString candidate = str.stripWhiteSpace();
77 if ( special.startsWith( candidate ) )
79 if ( candidate.length() == special.length() )
93 QtxDblSpinBox::QtxDblSpinBox( QWidget* parent, const char* name )
94 : QSpinBox( parent, name ),
101 myStep = QRangeControl::lineStep();
103 setValidator( new Validator( this, "double_spinbox_validator" ) );
107 connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
113 QtxDblSpinBox::QtxDblSpinBox( double min, double max, double step, QWidget* parent, const char* name )
114 : QSpinBox( parent, name ),
123 setValidator( new Validator( this, "double_spinbox_validator" ) );
127 connect( editor(), SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
133 QtxDblSpinBox::~QtxDblSpinBox()
138 \return min value of spin box
140 double QtxDblSpinBox::minValue() const
146 \return max value of spin box
148 double QtxDblSpinBox::maxValue() const
154 Changes min value of spin box
155 \param min - new min value
157 void QtxDblSpinBox::setMinValue( int min )
159 setMinValue( (double)min );
163 Changes min value of spin box
164 \param min - new min value
166 void QtxDblSpinBox::setMinValue( double min )
176 Changes max value of spin box
177 \param max - new max value
179 void QtxDblSpinBox::setMaxValue( int max )
181 setMaxValue( (double)max );
185 Changes max value of spin box
186 \param max - new max value
188 void QtxDblSpinBox::setMaxValue( double max )
198 Changes min and max value of spin box
199 \param min - new min value
200 \param max - new max value
202 void QtxDblSpinBox::setRange( int min, int max )
204 setRange( (double)min, (double)max );
208 Changes min and max value of spin box
209 \param min - new min value
210 \param max - new max value
212 void QtxDblSpinBox::setRange( double min, double max )
214 if ( myMin != min || myMax != max )
223 \return step of spin box
225 double QtxDblSpinBox::lineStep() const
231 Changes step of spin box
232 \param step - new step
234 void QtxDblSpinBox::setLineStep( int step )
236 setLineStep( (double)step );
240 Changes step of spin box
241 \param step - new step
243 void QtxDblSpinBox::setLineStep( double step )
249 \return value of spin box
251 double QtxDblSpinBox::value() const
259 Changes value of spin box
260 \param val - new value of spin box
262 void QtxDblSpinBox::setValue( int val )
264 setValue( (double)val );
268 Changes value of spin box
269 \param val - new value of spin box
271 void QtxDblSpinBox::setValue( double val )
274 double prevVal = myValue;
275 myValue = bound( val );
276 if ( prevVal != myValue )
283 void QtxDblSpinBox::stepUp()
286 if ( wrapping() && myValue + myStep > myMax )
289 setValue( myValue + myStep );
293 Subtracks step from value
295 void QtxDblSpinBox::stepDown()
298 if ( wrapping() && myValue - myStep < myMin )
301 setValue( myValue - myStep );
305 \return number of digit after comma
307 int QtxDblSpinBox::precision() const
313 Changes number of digit after comma
314 \param prec - new digit number
316 void QtxDblSpinBox::setPrecision( const int prec )
318 int newPrec = QMAX( prec, 0 );
319 int oldPrec = QMAX( myPrecision, 0 );
321 if ( newPrec != oldPrec )
326 \return true if spin box is cleared
328 bool QtxDblSpinBox::isCleared() const
334 Changes cleared status of spin box
335 \param on - new status
337 void QtxDblSpinBox::setCleared( const bool on )
339 if ( myCleared == on )
347 Selects all content of spin box editor
349 void QtxDblSpinBox::selectAll()
352 QSpinBox::selectAll();
354 editor()->selectAll();
359 Custom event filter, updates text of spin box editor
361 bool QtxDblSpinBox::eventFilter( QObject* o, QEvent* e )
363 if ( !myCleared || o != editor() || !editor()->text().stripWhiteSpace().isEmpty() )
365 bool state = QSpinBox::eventFilter( o, e );
366 if ( e->type() == QEvent::FocusOut && o == editor() )
371 if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Leave || e->type() == QEvent::Hide )
374 if ( e->type() == QEvent::KeyPress &&
375 ( ((QKeyEvent*)e)->key() == Key_Tab || ((QKeyEvent*)e)->key() == Key_BackTab ) )
377 QApplication::sendEvent( this, e );
381 return QSpinBox::eventFilter( o, e );
385 Updates text of editor
387 void QtxDblSpinBox::updateDisplay()
392 bool upd = editor()->isUpdatesEnabled();
393 editor()->setUpdatesEnabled( false );
395 bool isBlock = myBlocked;
398 QString txt = currentValueText();
400 if ( myValue >= myMax )
401 QSpinBox::setValue( QSpinBox::maxValue() );
402 else if ( myValue <= myMin )
403 QSpinBox::setValue( QSpinBox::minValue() );
405 QSpinBox::setValue( ( QSpinBox::minValue() + QSpinBox::maxValue() ) / 2 );
407 QSpinBox::updateDisplay();
409 editor()->setUpdatesEnabled( upd );
411 editor()->setText( myCleared ? QString::null : txt );
412 if ( !myCleared && editor()->hasFocus() )
414 if ( editor()->text() == specialValueText() )
415 editor()->selectAll();
417 editor()->setSelection( prefix().length(), editor()->text().length() - prefix().length() - suffix().length() );
420 editor()->setCursorPosition( 0 );
426 Sets double value by text in editor
428 void QtxDblSpinBox::interpretText()
435 if ( !specialValueText().isEmpty() )
437 QString s = QString( text() ).stripWhiteSpace();
438 QString t = QString( specialValueText() ).stripWhiteSpace();
446 newVal = mapTextToDoubleValue( &ok );
453 Emits signal "valueChanged"
455 void QtxDblSpinBox::valueChange()
458 emit valueChanged( myValue );
459 emit valueChanged( currentValueText() );
463 Attune parameters on range changing
465 void QtxDblSpinBox::rangeChange()
467 double min = QMIN( myMin, myMax );
468 double max = QMAX( myMin, myMax );
471 QDoubleValidator* v = ::qt_cast<QDoubleValidator*>( validator() );
473 v->setRange( myMin, myMax );
475 if ( myMin == myMax )
476 QSpinBox::setRange( 0, 0 );
478 QSpinBox::setRange( 0, 2 );
485 \return text of editor
487 QString QtxDblSpinBox::currentValueText()
490 if ( (myValue == minValue()) && !specialValueText().isEmpty() )
491 s = specialValueText();
495 s.append( mapValueToText( myValue ) );
496 s.append( suffix() );
502 Converts number to string
503 \param v - number to be converted
505 QString QtxDblSpinBox::mapValueToText( double v )
508 s.setNum( v, myPrecision >= 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
509 return removeTrailingZeroes( s );
513 Converts value to string
515 QString QtxDblSpinBox::mapValueToText( int )
518 s.setNum( myValue, myPrecision >= 0 ? 'f' : 'g', myPrecision == 0 ? 6 : QABS( myPrecision ) );
519 return removeTrailingZeroes( s );
523 Converts current text of editor to double
525 double QtxDblSpinBox::mapTextToDoubleValue( bool* ok )
528 double newVal = s.toDouble( ok );
529 if ( !(*ok) && !( !prefix() && !suffix() ) )
532 newVal = s.toDouble( ok );
538 \return value corrected in accordance with borders
539 \param val - value to be corrected
541 double QtxDblSpinBox::bound( double val )
544 if ( newVal > myMax )
546 if ( newVal < myMin )
552 Custom handler for leave event
554 void QtxDblSpinBox::leaveEvent( QEvent* e )
557 QSpinBox::leaveEvent( e );
561 Custom handler for wheel event
563 void QtxDblSpinBox::wheelEvent( QWheelEvent* e )
568 QSpinBox::wheelEvent( e );
573 SLOT: called if text is changed
575 void QtxDblSpinBox::onTextChanged( const QString& str )
582 \return string without excess zeros in start and in end
584 QString QtxDblSpinBox::removeTrailingZeroes( const QString& src ) const
586 QString delim( "." );
588 int idx = src.findRev( delim );
592 QString iPart = src.left( idx );
593 QString fPart = src.mid( idx + 1 );
595 while ( !fPart.isEmpty() && fPart.at( fPart.length() - 1 ) == '0' )
596 fPart.remove( fPart.length() - 1, 1 );
599 if ( !fPart.isEmpty() )
600 res += delim + fPart;