source: vendor/trolltech/current/src/widgets/qspinbox.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 28.8 KB
Line 
1/****************************************************************************
2** $Id: qspinbox.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QSpinBox widget class
5**
6** Created : 970101
7**
8** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
9**
10** This file is part of the widgets module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qspinbox.h"
39#ifndef QT_NO_SPINBOX
40
41#include "qcursor.h"
42#include "qpushbutton.h"
43#include "qpainter.h"
44#include "qbitmap.h"
45#include "qlineedit.h"
46#include "qvalidator.h"
47#include "qpixmapcache.h"
48#include "qapplication.h"
49#include "qstyle.h"
50#if defined(QT_ACCESSIBILITY_SUPPORT)
51#include "qaccessible.h"
52#endif
53
54class QSpinBoxPrivate
55{
56public:
57 QSpinBoxPrivate() {}
58 QSpinWidget* controls;
59 uint selreq : 1;
60};
61
62class QSpinBoxValidator : public QIntValidator
63{
64public:
65 QSpinBoxValidator( QSpinBox *sb, const char *name )
66 : QIntValidator( sb, name ), spinBox( sb ) { }
67
68 virtual State validate( QString& str, int& pos ) const;
69
70private:
71 QSpinBox *spinBox;
72};
73
74QValidator::State QSpinBoxValidator::validate( QString& str, int& pos ) const
75{
76 QString pref = spinBox->prefix();
77 QString suff = spinBox->suffix();
78 QString suffStriped = suff.stripWhiteSpace();
79 uint overhead = pref.length() + suff.length();
80 State state = Invalid;
81
82 ((QIntValidator *) this)->setRange( spinBox->minValue(),
83 spinBox->maxValue() );
84 if ( overhead == 0 ) {
85 state = QIntValidator::validate( str, pos );
86 } else {
87 bool stripedVersion = FALSE;
88 if ( str.length() >= overhead && str.startsWith(pref)
89 && (str.endsWith(suff)
90 || (stripedVersion = str.endsWith(suffStriped))) ) {
91 if ( stripedVersion )
92 overhead = pref.length() + suffStriped.length();
93 QString core = str.mid( pref.length(), str.length() - overhead );
94 int corePos = pos - pref.length();
95 state = QIntValidator::validate( core, corePos );
96 pos = corePos + pref.length();
97 str.replace( pref.length(), str.length() - overhead, core );
98 } else {
99 state = QIntValidator::validate( str, pos );
100 if ( state == Invalid ) {
101 // stripWhiteSpace(), cf. QSpinBox::interpretText()
102 QString special = spinBox->specialValueText().stripWhiteSpace();
103 QString candidate = str.stripWhiteSpace();
104
105 if ( special.startsWith(candidate) ) {
106 if ( candidate.length() == special.length() ) {
107 state = Acceptable;
108 } else {
109 state = Intermediate;
110 }
111 }
112 }
113 }
114 }
115 return state;
116}
117
118/*!
119 \class QSpinBox
120 \brief The QSpinBox class provides a spin box widget (spin button).
121
122 \ingroup basic
123 \mainclass
124
125 QSpinBox allows the user to choose a value either by clicking the
126 up/down buttons to increase/decrease the value currently displayed
127 or by typing the value directly into the spin box. If the value is
128 entered directly into the spin box, Enter (or Return) must be
129 pressed to apply the new value. The value is usually an integer.
130
131 Every time the value changes QSpinBox emits the valueChanged()
132 signal. The current value can be fetched with value() and set
133 with setValue().
134
135 The spin box keeps the value within a numeric range, and to
136 multiples of the lineStep() size (see QRangeControl for details).
137 Clicking the up/down buttons or using the keyboard accelerator's
138 up and down arrows will increase or decrease the current value in
139 steps of size lineStep(). The minimum and maximum value and the
140 step size can be set using one of the constructors, and can be
141 changed later with setMinValue(), setMaxValue() and setLineStep().
142
143 Most spin boxes are directional, but QSpinBox can also operate as
144 a circular spin box, i.e. if the range is 0-99 and the current
145 value is 99, clicking "up" will give 0. Use setWrapping() if you
146 want circular behavior.
147
148 The displayed value can be prepended and appended with arbitrary
149 strings indicating, for example, currency or the unit of
150 measurement. See setPrefix() and setSuffix(). The text in the spin
151 box is retrieved with text() (which includes any prefix() and
152 suffix()), or with cleanText() (which has no prefix(), no suffix()
153 and no leading or trailing whitespace). currentValueText() returns
154 the spin box's current value as text.
155
156 Normally the spin box displays up and down arrows in the buttons.
157 You can use setButtonSymbols() to change the display to show
158 <b>+</b> and <b>-</b> symbols if you prefer. In either case the up
159 and down arrow keys work as expected.
160
161 It is often desirable to give the user a special (often default)
162 choice in addition to the range of numeric values. See
163 setSpecialValueText() for how to do this with QSpinBox.
164
165 The default \l QWidget::focusPolicy() is StrongFocus.
166
167 If using prefix(), suffix() and specialValueText() don't provide
168 enough control, you can ignore them and subclass QSpinBox instead.
169
170 QSpinBox can easily be subclassed to allow the user to input
171 things other than an integer value as long as the allowed input
172 can be mapped to a range of integers. This can be done by
173 overriding the virtual functions mapValueToText() and
174 mapTextToValue(), and setting another suitable validator using
175 setValidator().
176
177 For example, these functions could be changed so that the user
178 provided values from 0.0 to 10.0, or -1 to signify 'Auto', while
179 the range of integers used inside the program would be -1 to 100:
180
181 \code
182 class MySpinBox : public QSpinBox
183 {
184 Q_OBJECT
185 public:
186 ...
187
188 QString mapValueToText( int value )
189 {
190 if ( value == -1 ) // special case
191 return QString( "Auto" );
192
193 return QString( "%1.%2" ) // 0.0 to 10.0
194 .arg( value / 10 ).arg( value % 10 );
195 }
196
197 int mapTextToValue( bool *ok )
198 {
199 if ( text() == "Auto" ) // special case
200 return -1;
201
202 return (int) ( 10 * text().toFloat() ); // 0 to 100
203 }
204 };
205 \endcode
206
207 <img src=qspinbox-m.png> <img src=qspinbox-w.png>
208
209 \sa QScrollBar QSlider
210 \link guibooks.html#fowler GUI Design Handbook: Spin Box \endlink
211*/
212
213
214/*!
215 Constructs a spin box with the default QRangeControl range and
216 step values. It is called \a name and has parent \a parent.
217
218 \sa minValue(), maxValue(), setRange(), lineStep(), setSteps()
219*/
220
221QSpinBox::QSpinBox( QWidget * parent , const char *name )
222 : QWidget( parent, name, WNoAutoErase ),
223 QRangeControl()
224{
225 initSpinBox();
226}
227
228
229/*!
230 Constructs a spin box that allows values from \a minValue to \a
231 maxValue inclusive, with step amount \a step. The value is
232 initially set to \a minValue.
233
234 The spin box is called \a name and has parent \a parent.
235
236 \sa minValue(), maxValue(), setRange(), lineStep(), setSteps()
237*/
238
239QSpinBox::QSpinBox( int minValue, int maxValue, int step, QWidget* parent,
240 const char* name )
241 : QWidget( parent, name, WNoAutoErase ),
242 QRangeControl( minValue, maxValue, step, step, minValue )
243{
244 initSpinBox();
245}
246
247/*
248 \internal Initialization.
249*/
250
251void QSpinBox::initSpinBox()
252{
253 d = new QSpinBoxPrivate;
254
255 d->controls = new QSpinWidget( this, "controls" );
256 connect( d->controls, SIGNAL( stepUpPressed() ), SLOT( stepUp() ) );
257 connect( d->controls, SIGNAL( stepDownPressed() ), SLOT( stepDown() ) );
258
259 wrap = FALSE;
260 edited = FALSE;
261 d->selreq = FALSE;
262
263 validate = new QSpinBoxValidator( this, "validator" );
264 vi = new QLineEdit( this, "qt_spinbox_edit" );
265 d->controls->setEditWidget( vi );
266 vi->setValidator( validate );
267 vi->installEventFilter( this );
268 vi->setFrame( FALSE );
269 setFocusProxy( vi );
270
271 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
272 setBackgroundMode( PaletteBackground, PaletteBase );
273
274 updateDisplay();
275
276 connect( vi, SIGNAL(textChanged(const QString&)), SLOT(textChanged()) );
277}
278
279/*!
280 Destroys the spin box, freeing all memory and other resources.
281*/
282
283QSpinBox::~QSpinBox()
284{
285 delete d;
286}
287
288
289/*!
290 \property QSpinBox::text
291 \brief the spin box's text, including any prefix() and suffix()
292
293 There is no default text.
294
295 \sa value()
296*/
297
298QString QSpinBox::text() const
299{
300 return vi->text();
301}
302
303
304
305/*!
306 \property QSpinBox::cleanText
307 \brief the spin box's text with no prefix(), suffix() or leading
308 or trailing whitespace.
309
310 \sa text, prefix, suffix
311*/
312
313QString QSpinBox::cleanText() const
314{
315 QString s = QString(text()).stripWhiteSpace();
316 if ( !prefix().isEmpty() ) {
317 QString px = QString(prefix()).stripWhiteSpace();
318 int len = px.length();
319 if ( len && s.left(len) == px ) // Remove _only_ if it is the prefix
320 s.remove( (uint)0, len );
321 }
322 if ( !suffix().isEmpty() ) {
323 QString sx = QString(suffix()).stripWhiteSpace();
324 int len = sx.length();
325 if ( len && s.right(len) == sx ) // Remove _only_ if it is the suffix
326 s.truncate( s.length() - len );
327 }
328 return s.stripWhiteSpace();
329}
330
331
332/*!
333 \property QSpinBox::specialValueText
334 \brief the special-value text
335
336 If set, the spin box will display this text instead of a numeric
337 value whenever the current value is equal to minVal(). Typical use
338 is to indicate that this choice has a special (default) meaning.
339
340 For example, if your spin box allows the user to choose the margin
341 width in a print dialog and your application is able to
342 automatically choose a good margin width, you can set up the spin
343 box like this:
344 \code
345 QSpinBox marginBox( -1, 20, 1, parent, "marginBox" );
346 marginBox->setSuffix( " mm" );
347 marginBox->setSpecialValueText( "Auto" );
348 \endcode
349 The user will then be able to choose a margin width from 0-20
350 millimeters or select "Auto" to leave it to the application to
351 choose. Your code must then interpret the spin box value of -1 as
352 the user requesting automatic margin width.
353
354 All values are displayed with the prefix() and suffix() (if set),
355 \e except for the special value, which only shows the special
356 value text.
357
358 To turn off the special-value text display, call this function
359 with an empty string. The default is no special-value text, i.e.
360 the numeric value is shown as usual.
361
362 If no special-value text is set, specialValueText() returns
363 QString::null.
364*/
365
366void QSpinBox::setSpecialValueText( const QString &text )
367{
368 specText = text;
369 updateDisplay();
370}
371
372
373QString QSpinBox::specialValueText() const
374{
375 if ( specText.isEmpty() )
376 return QString::null;
377 else
378 return specText;
379}
380
381
382/*!
383 \property QSpinBox::prefix
384 \brief the spin box's prefix
385
386 The prefix is prepended to the start of the displayed value.
387 Typical use is to display a unit of measurement or a currency
388 symbol. For example:
389
390 \code
391 sb->setPrefix( "$" );
392 \endcode
393
394 To turn off the prefix display, set this property to an empty
395 string. The default is no prefix. The prefix is not displayed for
396 the minValue() if specialValueText() is not empty.
397
398 If no prefix is set, prefix() returns QString::null.
399
400 \sa suffix()
401*/
402
403void QSpinBox::setPrefix( const QString &text )
404{
405 pfix = text;
406 updateDisplay();
407}
408
409
410QString QSpinBox::prefix() const
411{
412 if ( pfix.isEmpty() )
413 return QString::null;
414 else
415 return pfix;
416}
417
418
419/*!
420 \property QSpinBox::suffix
421 \brief the suffix of the spin box
422
423 The suffix is appended to the end of the displayed value. Typical
424 use is to display a unit of measurement or a currency symbol. For
425 example:
426
427 \code
428 sb->setSuffix( " km" );
429 \endcode
430
431 To turn off the suffix display, set this property to an empty
432 string. The default is no suffix. The suffix is not displayed for
433 the minValue() if specialValueText() is not empty.
434
435 If no suffix is set, suffix() returns a QString::null.
436
437 \sa prefix()
438*/
439
440void QSpinBox::setSuffix( const QString &text )
441{
442 sfix = text;
443 updateDisplay();
444}
445
446QString QSpinBox::suffix() const
447{
448 if ( sfix.isEmpty() )
449 return QString::null;
450 else
451 return sfix;
452}
453
454
455/*!
456 \property QSpinBox::wrapping
457 \brief whether it is possible to step the value from the highest
458 value to the lowest value and vice versa
459
460 By default, wrapping is turned off.
461
462 If you have a range of 0..100 and wrapping is off when the user
463 reaches 100 and presses the Up Arrow nothing will happen; but if
464 wrapping is on the value will change from 100 to 0, then to 1,
465 etc. When wrapping is on, navigating past the highest value takes
466 you to the lowest and vice versa.
467
468 \sa minValue, maxValue, setRange()
469*/
470
471void QSpinBox::setWrapping( bool on )
472{
473 wrap = on;
474 updateDisplay();
475}
476
477bool QSpinBox::wrapping() const
478{
479 return wrap;
480}
481
482/*!
483 \reimp
484*/
485QSize QSpinBox::sizeHint() const
486{
487 constPolish();
488 QSize sz = vi->sizeHint();
489 int h = sz.height();
490 QFontMetrics fm( font() );
491 int w = 35;
492 int wx = fm.width( ' ' )*2;
493 QString s;
494 s = prefix() + ( (QSpinBox*)this )->mapValueToText( minValue() ) + suffix();
495 w = QMAX( w, fm.width( s ) + wx);
496 s = prefix() + ( (QSpinBox*)this )->mapValueToText( maxValue() ) + suffix();
497 w = QMAX(w, fm.width( s ) + wx );
498 if ( !specialValueText().isEmpty() ) {
499 s = specialValueText();
500 w = QMAX( w, fm.width( s ) + wx );
501 }
502 return style().sizeFromContents(QStyle::CT_SpinBox, this,
503 QSize( w + d->controls->downRect().width(),
504 h + style().pixelMetric( QStyle::PM_DefaultFrameWidth ) * 2).
505 expandedTo( QApplication::globalStrut() ));
506}
507
508
509/*!
510 \reimp
511*/
512QSize QSpinBox::minimumSizeHint() const
513{
514 int w = vi->minimumSizeHint().width() + d->controls->downRect().width();
515 int h = QMAX( vi->minimumSizeHint().height(), d->controls->minimumSizeHint().height() );
516 return QSize( w, h );
517}
518
519// Does the layout of the lineedit and the buttons
520
521void QSpinBox::arrangeWidgets()
522{
523 d->controls->arrange();
524}
525
526/*!
527 \property QSpinBox::value
528 \brief the value of the spin box
529
530 \sa QRangeControl::setValue()
531*/
532
533void QSpinBox::setValue( int value )
534{
535 edited = FALSE; // we ignore anything entered and not yet interpreted
536 QRangeControl::setValue( value );
537 updateDisplay();
538}
539
540int QSpinBox::value() const
541{
542 QSpinBox * that = (QSpinBox *) this;
543 if ( edited ) {
544 that->edited = FALSE; // avoid recursion
545 that->interpretText();
546 }
547 return QRangeControl::value();
548}
549
550
551/*!
552 Increases the spin box's value by one lineStep(), wrapping as
553 necessary if wrapping() is TRUE. This is the same as clicking on
554 the pointing-up button and can be used for keyboard accelerators,
555 for example.
556
557 \sa stepDown(), addLine(), lineStep(), setSteps(), setValue(), value()
558*/
559
560void QSpinBox::stepUp()
561{
562 if ( edited )
563 interpretText();
564 if ( wrapping() && ( value()+lineStep() > maxValue() ) )
565 setValue( minValue() );
566 else
567 addLine();
568}
569
570
571/*!
572 Decreases the spin box's value one lineStep(), wrapping as
573 necessary if wrapping() is TRUE. This is the same as clicking on
574 the pointing-down button and can be used for keyboard
575 accelerators, for example.
576
577 \sa stepUp(), subtractLine(), lineStep(), setSteps(), setValue(), value()
578*/
579
580void QSpinBox::stepDown()
581{
582 if ( edited )
583 interpretText();
584 if ( wrapping() && ( value()-lineStep() < minValue() ) )
585 setValue( maxValue() );
586 else
587 subtractLine();
588}
589
590
591/*!
592 \fn void QSpinBox::valueChanged( int value )
593
594 This signal is emitted every time the value of the spin box
595 changes; the new value is passed in \a value. This signal will be
596 emitted as a result of a call to setValue(), or because the user
597 changed the value by using a keyboard accelerator or mouse click,
598 etc.
599
600 Note that the valueChanged() signal is emitted \e every time, not
601 just for the "last" step; i.e. if the user clicks "up" three
602 times, this signal is emitted three times.
603
604 \sa value()
605*/
606
607
608/*!
609 \fn void QSpinBox::valueChanged( const QString& valueText )
610
611 \overload
612
613 This signal is emitted whenever the valueChanged( int ) signal is
614 emitted, i.e. every time the value of the spin box changes
615 (whatever the cause, e.g. by setValue(), by a keyboard
616 accelerator, by mouse clicks, etc.).
617
618 The \a valueText parameter is the same string that is displayed in
619 the edit field of the spin box.
620
621 \sa value() prefix() suffix() specialValueText()
622*/
623
624
625
626/*!
627 Intercepts and handles the events coming to the embedded QLineEdit
628 that have special meaning for the QSpinBox. The object is passed
629 as \a o and the event is passed as \a ev.
630*/
631
632bool QSpinBox::eventFilter( QObject* o, QEvent* ev )
633{
634 if (o != vi)
635 return QWidget::eventFilter(o,ev);
636
637 if ( ev->type() == QEvent::KeyPress ) {
638 QKeyEvent* k = (QKeyEvent*)ev;
639
640 bool retval = FALSE; // workaround for MSVC++ optimization bug
641 if( (k->key() == Key_Tab) || (k->key() == Key_BackTab) ){
642 if ( k->state() & Qt::ControlButton )
643 return FALSE;
644 if ( edited )
645 interpretText();
646 qApp->sendEvent( this, ev );
647 retval = TRUE;
648 } if ( k->key() == Key_Up ) {
649 stepUp();
650 retval = TRUE;
651 } else if ( k->key() == Key_Down ) {
652 stepDown();
653 retval = TRUE;
654 } else if ( k->key() == Key_Enter || k->key() == Key_Return ) {
655 interpretText();
656 return FALSE;
657 }
658 if ( retval )
659 return retval;
660 } else if ( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Hide ) {
661 if ( edited ) {
662 interpretText();
663 }
664 return FALSE;
665 }
666 return FALSE;
667}
668
669/*!
670 \reimp
671 */
672void QSpinBox::setEnabled( bool enabled )
673{
674 QWidget::setEnabled( enabled );
675 updateDisplay();
676}
677
678/*!
679 \reimp
680*/
681void QSpinBox::leaveEvent( QEvent* )
682{
683}
684
685
686/*!
687 \reimp
688*/
689void QSpinBox::resizeEvent( QResizeEvent* )
690{
691 d->controls->resize( width(), height() );
692}
693
694/*!
695 \reimp
696*/
697#ifndef QT_NO_WHEELEVENT
698void QSpinBox::wheelEvent( QWheelEvent * e )
699{
700 e->accept();
701 static float offset = 0;
702 static QSpinBox* offset_owner = 0;
703 if (offset_owner != this) {
704 offset_owner = this;
705 offset = 0;
706 }
707 offset += -e->delta()/120;
708 if (QABS(offset) < 1)
709 return;
710 int ioff = int(offset);
711 int i;
712 for (i=0; i<QABS(ioff); i++)
713 offset > 0 ? stepDown() : stepUp();
714 offset -= ioff;
715}
716#endif
717
718/*!
719 This virtual function is called by QRangeControl whenever the
720 value has changed. The QSpinBox reimplementation updates the
721 display and emits the valueChanged() signals; if you need
722 additional processing, either reimplement this or connect to one
723 of the valueChanged() signals.
724*/
725
726void QSpinBox::valueChange()
727{
728 d->selreq = hasFocus();
729 updateDisplay();
730 d->selreq = FALSE;
731 emit valueChanged( value() );
732 emit valueChanged( currentValueText() );
733#if defined(QT_ACCESSIBILITY_SUPPORT)
734 QAccessible::updateAccessibility( this, 0, QAccessible::ValueChanged );
735#endif
736}
737
738
739/*!
740 This virtual function is called by QRangeControl whenever the
741 range has changed. It adjusts the default validator and updates
742 the display; if you need additional processing, you can
743 reimplement this function.
744*/
745
746void QSpinBox::rangeChange()
747{
748 updateDisplay();
749}
750
751
752/*!
753 Sets the validator to \a v. The validator controls what keyboard
754 input is accepted when the user is editing in the value field. The
755 default is to use a suitable QIntValidator.
756
757 Use setValidator(0) to turn off input validation (entered input
758 will still be kept within the spin box's range).
759*/
760
761void QSpinBox::setValidator( const QValidator* v )
762{
763 if ( vi )
764 vi->setValidator( v );
765}
766
767
768/*!
769 Returns the validator that constrains editing for this spin box if
770 there is any; otherwise returns 0.
771
772 \sa setValidator() QValidator
773*/
774
775const QValidator * QSpinBox::validator() const
776{
777 return vi ? vi->validator() : 0;
778}
779
780/*!
781 Updates the contents of the embedded QLineEdit to reflect the
782 current value using mapValueToText(). Also enables/disables the
783 up/down push buttons accordingly.
784
785 \sa mapValueToText()
786*/
787void QSpinBox::updateDisplay()
788{
789 vi->setUpdatesEnabled( FALSE );
790 vi->setText( currentValueText() );
791 if ( d->selreq && isVisible() && ( hasFocus() || vi->hasFocus() ) ) {
792 selectAll();
793 } else {
794 if ( !suffix().isEmpty() && vi->text().endsWith(suffix()) )
795 vi->setCursorPosition( vi->text().length() - suffix().length() );
796 }
797 vi->setUpdatesEnabled( TRUE );
798 vi->repaint( FALSE ); // immediate repaint needed for some reason
799 edited = FALSE;
800
801 bool upEnabled = isEnabled() && ( wrapping() || value() < maxValue() );
802 bool downEnabled = isEnabled() && ( wrapping() || value() > minValue() );
803
804 d->controls->setUpEnabled( upEnabled );
805 d->controls->setDownEnabled( downEnabled );
806 vi->setEnabled( isEnabled() );
807 repaint( FALSE );
808}
809
810
811/*!
812 QSpinBox calls this after the user has manually edited the
813 contents of the spin box (i.e. by typing in the embedded
814 QLineEdit, rather than using the up/down buttons/keys).
815
816 The default implementation of this function interprets the new
817 text using mapTextToValue(). If mapTextToValue() is successful, it
818 changes the spin box's value; if not, the value is left unchanged.
819
820 \sa editor()
821*/
822
823void QSpinBox::interpretText()
824{
825 bool ok = TRUE;
826 bool done = FALSE;
827 int newVal = 0;
828 if ( !specialValueText().isEmpty() ) {
829 QString s = text().stripWhiteSpace();
830 QString t = specialValueText().stripWhiteSpace();
831 if ( s == t ) {
832 newVal = minValue();
833 done = TRUE;
834 }
835 }
836 if ( !done )
837 newVal = mapTextToValue( &ok );
838 if ( ok )
839 setValue( newVal );
840 updateDisplay(); // sometimes redundant
841}
842
843
844/*!
845 Returns the geometry of the "up" button.
846*/
847
848QRect QSpinBox::upRect() const
849{
850 return d->controls->upRect();
851}
852
853
854/*!
855 Returns the geometry of the "down" button.
856*/
857
858QRect QSpinBox::downRect() const
859{
860 return d->controls->downRect();
861}
862
863
864/*!
865 Returns a pointer to the embedded QLineEdit.
866*/
867
868QLineEdit* QSpinBox::editor() const
869{
870 return vi;
871}
872
873
874/*!
875 This slot is called whenever the user edits the spin box's text.
876*/
877
878void QSpinBox::textChanged()
879{
880 edited = TRUE; // this flag is cleared in updateDisplay()
881}
882
883
884/*!
885 This virtual function is used by the spin box whenever it needs to
886 display value \a v. The default implementation returns a string
887 containing \a v printed in the standard way. Reimplementations may
888 return anything. (See the example in the detailed description.)
889
890 Note that Qt does not call this function for specialValueText()
891 and that neither prefix() nor suffix() are included in the return
892 value.
893
894 If you reimplement this, you may also need to reimplement
895 mapTextToValue().
896
897 \sa updateDisplay(), mapTextToValue()
898*/
899
900QString QSpinBox::mapValueToText( int v )
901{
902 QString s;
903 s.setNum( v );
904 return s;
905}
906
907
908/*!
909 This virtual function is used by the spin box whenever it needs to
910 interpret text entered by the user as a value. The text is
911 available as text() and as cleanText(), and this function must
912 parse it if possible. If \a ok is not 0: if it parses the text
913 successfully, \a *ok is set to TRUE; otherwise \a *ok is set to
914 FALSE.
915
916 Subclasses that need to display spin box values in a non-numeric
917 way need to reimplement this function.
918
919 Note that Qt handles specialValueText() separately; this function
920 is only concerned with the other values.
921
922 The default implementation tries to interpret the text() as an
923 integer in the standard way and returns the integer value.
924
925 \sa interpretText(), mapValueToText()
926*/
927
928int QSpinBox::mapTextToValue( bool* ok )
929{
930 QString s = text();
931 int newVal = s.toInt( ok );
932 if ( !(*ok) && !( !prefix() && !suffix() ) ) {// Try removing any pre/suffix
933 s = cleanText();
934 newVal = s.toInt( ok );
935 }
936 return newVal;
937}
938
939
940/*!
941 Returns the full text calculated from the current value, including
942 any prefix and suffix. If there is special value text and the
943 value is minValue() the specialValueText() is returned.
944*/
945
946QString QSpinBox::currentValueText()
947{
948 QString s;
949 if ( (value() == minValue()) && !specialValueText().isEmpty() ) {
950 s = specialValueText();
951 } else {
952 s = prefix();
953 s.append( mapValueToText( value() ) );
954 s.append( suffix() );
955 }
956 return s;
957}
958
959/*!
960 \reimp
961*/
962
963void QSpinBox::styleChange( QStyle& old )
964{
965 arrangeWidgets();
966 QWidget::styleChange( old );
967}
968
969
970/*!
971 \enum QSpinBox::ButtonSymbols
972
973 This enum type determines what the buttons in a spin box show.
974
975 \value UpDownArrows the buttons show little arrows in the classic
976 style.
977
978 \value PlusMinus the buttons show <b>+</b> and <b>-</b> symbols.
979
980 \sa QSpinBox::buttonSymbols
981*/
982
983/*!
984 \property QSpinBox::buttonSymbols
985
986 \brief the current button symbol mode
987
988 The possible values can be either \c UpDownArrows or \c PlusMinus.
989 The default is \c UpDownArrows.
990
991 \sa ButtonSymbols
992*/
993
994void QSpinBox::setButtonSymbols( ButtonSymbols newSymbols )
995{
996 if ( buttonSymbols() == newSymbols )
997 return;
998
999 switch ( newSymbols ) {
1000 case UpDownArrows:
1001 d->controls->setButtonSymbols( QSpinWidget::UpDownArrows );
1002 break;
1003 case PlusMinus:
1004 d->controls->setButtonSymbols( QSpinWidget::PlusMinus );
1005 break;
1006 }
1007 // repaint( FALSE );
1008}
1009
1010QSpinBox::ButtonSymbols QSpinBox::buttonSymbols() const
1011{
1012 switch( d->controls->buttonSymbols() ) {
1013 case QSpinWidget::UpDownArrows:
1014 return UpDownArrows;
1015 case QSpinWidget::PlusMinus:
1016 return PlusMinus;
1017 }
1018 return UpDownArrows;
1019}
1020
1021/*!
1022 \property QSpinBox::minValue
1023
1024 \brief the minimum value of the spin box
1025
1026 When setting this property, \l QSpinBox::maxValue is adjusted, if
1027 necessary, to ensure that the range remains valid.
1028
1029 \sa setRange() setSpecialValueText()
1030*/
1031
1032int QSpinBox::minValue() const
1033{
1034 return QRangeControl::minValue();
1035}
1036
1037void QSpinBox::setMinValue( int minVal )
1038{
1039 QRangeControl::setMinValue( minVal );
1040}
1041
1042/*!
1043 \property QSpinBox::maxValue
1044 \brief the maximum value of the spin box
1045
1046 When setting this property, \l QSpinBox::minValue is adjusted, if
1047 necessary, to ensure that the range remains valid.
1048
1049 \sa setRange() setSpecialValueText()
1050*/
1051
1052int QSpinBox::maxValue() const
1053{
1054 return QRangeControl::maxValue();
1055}
1056
1057void QSpinBox::setMaxValue( int maxVal )
1058{
1059 QRangeControl::setMaxValue( maxVal );
1060}
1061
1062/*!
1063 \property QSpinBox::lineStep
1064 \brief the line step
1065
1066 When the user uses the arrows to change the spin box's value the
1067 value will be incremented/decremented by the amount of the line
1068 step.
1069
1070 The setLineStep() function calls the virtual stepChange() function
1071 if the new line step is different from the previous setting.
1072
1073 \sa QRangeControl::setSteps() setRange()
1074*/
1075
1076int QSpinBox::lineStep() const
1077{
1078 return QRangeControl::lineStep();
1079}
1080
1081void QSpinBox::setLineStep( int i )
1082{
1083 setSteps( i, pageStep() );
1084}
1085
1086/*!
1087 Selects all the text in the spin box's editor.
1088*/
1089
1090void QSpinBox::selectAll()
1091{
1092 int overhead = prefix().length() + suffix().length();
1093 if ( !overhead || currentValueText() == specialValueText() ) {
1094 vi->selectAll();
1095 } else {
1096 vi->setSelection( prefix().length(), vi->text().length() - overhead );
1097 }
1098}
1099
1100#endif
Note: See TracBrowser for help on using the repository browser.