]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxDoubleSpinBox.cxx
Salome HOME
87d5b6008bcc823aa522d5c8faf72a87f4743016
[modules/gui.git] / src / Qtx / QtxDoubleSpinBox.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:      QtxDoubleSpinBox.cxx
23 // Author:    Sergey TELKOV
24 //
25 #include "QtxDoubleSpinBox.h"
26
27 #include <QLineEdit>
28 #include <QDoubleValidator>
29
30 /*!
31   \class QtxDoubleSpinBox
32   \brief Enhanced version of the Qt's double spin box.
33
34   The QtxDoubleSpinBox class represents the widget for entering the
35   floating point values. In addition to the functionality provided by
36   QDoubleSpinBox, this class supports "cleared" state - this is the
37   state corresponding to "None" (or empty) entered value.
38
39   To set "cleared" state use setCleared() method. To check if the spin
40   box stores "cleared" state, use isCleared() method.
41   For example:
42   \code
43   if (myDblSpinBox->isCleared()) {
44     ... // process "None" state
45   }
46   else {
47     double value = myDblSpinBox->value();
48     ... // process entered value
49   }
50   \endcode
51 */
52
53 /*!
54   \brief Constructor.
55
56   Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value,
57   a step value of 1.0 and a precision of 2 decimal places. 
58   The value is initially set to 0.00.
59
60   \param parent parent object
61 */
62 QtxDoubleSpinBox::QtxDoubleSpinBox( QWidget* parent )
63 : QDoubleSpinBox( parent ),
64   myCleared( false ),
65   myPrecision(0)
66 {
67   connect( lineEdit(), SIGNAL( textChanged( const QString& ) ), 
68            this, SLOT( onTextChanged( const QString& ) ) );
69 }
70
71 /*!
72   \brief Constructor.
73
74   Constructs a spin box with specified minimum, maximum and step value.
75   The precision is set to 2 decimal places. 
76   The value is initially set to the minimum value.
77
78   \param min spin box minimum possible value
79   \param max spin box maximum possible value
80   \param step spin box increment/decrement value
81   \param parent parent object
82 */
83 QtxDoubleSpinBox::QtxDoubleSpinBox( double min, double max, double step, QWidget* parent )
84 : QDoubleSpinBox( parent ),
85   myCleared( false ),
86   myPrecision( 0 )
87 {
88   setMinimum( min );
89   setMaximum( max );
90   setSingleStep( step );
91
92   connect( lineEdit(), SIGNAL( textChanged( const QString& ) ), 
93            this, SLOT( onTextChanged( const QString& ) ) );
94 }
95
96 /*!
97   \brief Constructor.
98
99   Constructs a spin box with specified minimum, maximum and step value.
100   The precision is set to 2 decimal places. 
101   The value is initially set to the minimum value.
102
103   \param min spin box minimum possible value
104   \param max spin box maximum possible value
105   \param step spin box increment/decrement value
106   \param parent parent object
107 */
108 QtxDoubleSpinBox::QtxDoubleSpinBox( double min, double max, double step, int prec, int dec, QWidget* parent )
109 : QDoubleSpinBox( parent ),
110   myCleared( false ),
111   myPrecision( prec )
112 {
113   setDecimals( dec );
114   setMinimum( min );
115   setMaximum( max );
116   setSingleStep( step );
117
118   connect( lineEdit(), SIGNAL( textChanged( const QString& ) ), 
119            this, SLOT( onTextChanged( const QString& ) ) );
120 }
121
122 /*!
123   \brief Destructor.
124 */
125 QtxDoubleSpinBox::~QtxDoubleSpinBox()
126 {
127 }
128
129 /*!
130   \brief Check if spin box is in the "cleared" state.
131   \return \c true if spin box is cleared
132   \sa setCleared()
133 */
134 bool QtxDoubleSpinBox::isCleared() const
135 {
136   return myCleared;
137 }
138
139 /*!
140   \brief Change "cleared" status of the spin box.
141   \param on new "cleared" status
142   \sa isCleared()
143 */
144 void QtxDoubleSpinBox::setCleared( const bool on )
145 {
146   if ( myCleared == on )
147     return;
148   
149   myCleared = on;
150   setSpecialValueText( specialValueText() );
151 }
152
153 /*!
154   \brief Set precision of the spin box
155   
156   If precision value is less than 0, the 'g' format is used for value output,
157   otherwise 'f' format is used.
158
159   \param prec new precision value.
160   \sa precision()
161 */
162 void QtxDoubleSpinBox::setPrecision( const int prec )
163 {
164   int newPrec = qMax( prec, 0 );
165   int oldPrec = qMax( myPrecision, 0 );
166   myPrecision = prec;
167   if ( newPrec != oldPrec )
168     update();
169 }
170
171 /*!
172   \brief Get precision value of the spin box
173   \return current prevision value
174   \sa setPrecision()
175 */
176 int QtxDoubleSpinBox::getPrecision() const
177 {
178   return myPrecision;
179 }
180
181 /*!
182   \brief Interpret text entered by the user as a value.
183   \param text text entered by the user
184   \return mapped value
185   \sa textFromValue()
186 */
187 double QtxDoubleSpinBox::valueFromText( const QString& text ) const
188 {
189   if (myPrecision < 0)
190     return text.toDouble();
191
192   return QDoubleSpinBox::valueFromText(text);
193 }
194
195 /*!
196   \brief This function is used by the spin box whenever it needs to display
197   the given value.
198
199   \param val spin box value
200   \return text representation of the value
201   \sa valueFromText()
202 */
203 QString QtxDoubleSpinBox::textFromValue( double val ) const
204 {
205   QString s = QLocale().toString( val, myPrecision >= 0 ? 'f' : 'g', myPrecision == 0 ? 6 : qAbs( myPrecision ) );
206   return removeTrailingZeroes( s );
207 }
208
209 /*!
210   \brief Return source string with removed leading and trailing zeros.
211   \param str source string
212   \return resulting string
213 */
214 QString QtxDoubleSpinBox::removeTrailingZeroes( const QString& src ) const
215 {
216   QString delim( QLocale().decimalPoint() );
217
218   int idx = src.lastIndexOf( delim );
219   if ( idx == -1 )
220     return src;
221
222   QString iPart = src.left( idx );
223   QString fPart = src.mid( idx + 1 );
224
225   while ( !fPart.isEmpty() && fPart.at( fPart.length() - 1 ) == '0' )
226     fPart.remove( fPart.length() - 1, 1 );
227
228   QString res = iPart;
229   if ( !fPart.isEmpty() )
230     res += delim + fPart;
231
232   return res;
233 }
234
235 /*!
236   \brief Perform \a steps increment/decrement steps.
237   
238   The \a steps value can be any integer number. If it is > 0,
239   the value incrementing is done, otherwise value is decremented
240   \a steps times.  
241
242   \param steps number of increment/decrement steps
243 */
244 void QtxDoubleSpinBox::stepBy( int steps )
245 {
246   myCleared = false;
247
248   QDoubleSpinBox::stepBy( steps );
249 }
250
251 /*!
252   \brief This function is used to determine whether input is valid.
253   \param str currently entered value
254   \param pos cursor position in the string
255   \return validating operation result
256 */
257 QValidator::State QtxDoubleSpinBox::validate( QString& str, int& pos ) const
258 {
259   if (myPrecision >= 0)
260     return QDoubleSpinBox::validate(str, pos);
261
262   QString pref = this->prefix();
263   QString suff = this->suffix();
264   uint overhead = pref.length() + suff.length();
265   QValidator::State state = QValidator::Invalid;
266
267   QDoubleValidator v (NULL);
268   v.setDecimals( decimals() );
269   v.setBottom( minimum() );
270   v.setTop( maximum() );
271   v.setNotation( QDoubleValidator::ScientificNotation );
272
273   if ( overhead == 0 )
274     state = v.validate( str, pos );
275   else
276     {
277       if ( str.length() >= overhead && str.startsWith( pref ) &&
278            str.right( suff.length() ) == suff )
279         {
280           QString core = str.mid( pref.length(), str.length() - overhead );
281           int corePos = pos - pref.length();
282           state = v.validate( core, corePos );
283           pos = corePos + pref.length();
284           str.replace( pref.length(), str.length() - overhead, core );
285         }
286       else
287         {
288           state = v.validate( str, pos );
289           if ( state == QValidator::Invalid )
290             {
291               QString special = this->specialValueText().trimmed();
292               QString candidate = str.trimmed();
293               if ( special.startsWith( candidate ) )
294                 {
295                   if ( candidate.length() == special.length() )
296                     state = QValidator::Acceptable;
297                   else
298                     state = QValidator::Intermediate;
299                 }
300             }
301         }
302     }
303   return state;
304 }
305
306 /*!
307   \brief Called when user enters the text in the spin box.
308   \param txt current spin box text (not used)
309 */
310 void QtxDoubleSpinBox::onTextChanged( const QString& /*txt*/ )
311 {
312   myCleared = false;
313 }