source: trunk/src/gui/widgets/qabstractslider.cpp@ 846

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 28.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <qapplication.h>
43#include "qabstractslider.h"
44#include "qevent.h"
45#include "qabstractslider_p.h"
46#include "qdebug.h"
47#ifndef QT_NO_ACCESSIBILITY
48#include "qaccessible.h"
49#endif
50#include <limits.h>
51
52QT_BEGIN_NAMESPACE
53
54/*!
55 \class QAbstractSlider
56 \brief The QAbstractSlider class provides an integer value within a range.
57
58 \ingroup abstractwidgets
59
60 The class is designed as a common super class for widgets like
61 QScrollBar, QSlider and QDial.
62
63 Here are the main properties of the class:
64
65 \list 1
66
67 \i \l value: The bounded integer that QAbstractSlider maintains.
68
69 \i \l minimum: The lowest possible value.
70
71 \i \l maximum: The highest possible value.
72
73 \i \l singleStep: The smaller of two natural steps that an
74 abstract sliders provides and typically corresponds to the user
75 pressing an arrow key.
76
77 \i \l pageStep: The larger of two natural steps that an abstract
78 slider provides and typically corresponds to the user pressing
79 PageUp or PageDown.
80
81 \i \l tracking: Whether slider tracking is enabled.
82
83 \i \l sliderPosition: The current position of the slider. If \l
84 tracking is enabled (the default), this is identical to \l value.
85
86 \endlist
87
88 Unity (1) may be viewed as a third step size. setValue() lets you
89 set the current value to any integer in the allowed range, not
90 just minimum() + \e n * singleStep() for integer values of \e n.
91 Some widgets may allow the user to set any value at all; others
92 may just provide multiples of singleStep() or pageStep().
93
94 QAbstractSlider emits a comprehensive set of signals:
95
96 \table
97 \header \i Signal \i Emitted when
98 \row \i \l valueChanged()
99 \i the value has changed. The \l tracking
100 determines whether this signal is emitted during user
101 interaction.
102 \row \i \l sliderPressed()
103 \i the user starts to drag the slider.
104 \row \i \l sliderMoved()
105 \i the user drags the slider.
106 \row \i \l sliderReleased()
107 \i the user releases the slider.
108 \row \i \l actionTriggered()
109 \i a slider action was triggerd.
110 \row \i \l rangeChanged()
111 \i a the range has changed.
112 \endtable
113
114 QAbstractSlider provides a virtual sliderChange() function that is
115 well suited for updating the on-screen representation of
116 sliders. By calling triggerAction(), subclasses trigger slider
117 actions. Two helper functions QStyle::sliderPositionFromValue() and
118 QStyle::sliderValueFromPosition() help subclasses and styles to map
119 screen coordinates to logical range values.
120
121 \sa QAbstractSpinBox, QSlider, QDial, QScrollBar, {Sliders Example}
122*/
123
124/*!
125 \enum QAbstractSlider::SliderAction
126
127 \value SliderNoAction
128 \value SliderSingleStepAdd
129 \value SliderSingleStepSub
130 \value SliderPageStepAdd
131 \value SliderPageStepSub
132 \value SliderToMinimum
133 \value SliderToMaximum
134 \value SliderMove
135
136*/
137
138/*!
139 \fn void QAbstractSlider::valueChanged(int value)
140
141 This signal is emitted when the slider value has changed, with the
142 new slider \a value as argument.
143*/
144
145/*!
146 \fn void QAbstractSlider::sliderPressed()
147
148 This signal is emitted when the user presses the slider with the
149 mouse, or programmatically when setSliderDown(true) is called.
150
151 \sa sliderReleased(), sliderMoved(), isSliderDown()
152*/
153
154/*!
155 \fn void QAbstractSlider::sliderMoved(int value)
156
157 This signal is emitted when sliderDown is true and the slider moves. This
158 usually happens when the user is dragging the slider. The \a value
159 is the new slider position.
160
161 This signal is emitted even when tracking is turned off.
162
163 \sa setTracking(), valueChanged(), isSliderDown(),
164 sliderPressed(), sliderReleased()
165*/
166
167/*!
168 \fn void QAbstractSlider::sliderReleased()
169
170 This signal is emitted when the user releases the slider with the
171 mouse, or programmatically when setSliderDown(false) is called.
172
173 \sa sliderPressed() sliderMoved() sliderDown
174*/
175
176/*!
177 \fn void QAbstractSlider::rangeChanged(int min, int max)
178
179 This signal is emitted when the slider range has changed, with \a
180 min being the new minimum, and \a max being the new maximum.
181
182 \sa minimum, maximum
183*/
184
185/*!
186 \fn void QAbstractSlider::actionTriggered(int action)
187
188 This signal is emitted when the slider action \a action is
189 triggered. Actions are \l SliderSingleStepAdd, \l
190 SliderSingleStepSub, \l SliderPageStepAdd, \l SliderPageStepSub,
191 \l SliderToMinimum, \l SliderToMaximum, and \l SliderMove.
192
193 When the signal is emitted, the \l sliderPosition has been
194 adjusted according to the action, but the \l value has not yet
195 been propagated (meaning the valueChanged() signal was not yet
196 emitted), and the visual display has not been updated. In slots
197 connected to this signal you can thus safely adjust any action by
198 calling setSliderPosition() yourself, based on both the action and
199 the slider's value.
200
201 \sa triggerAction()
202*/
203
204/*!
205 \enum QAbstractSlider::SliderChange
206
207 \value SliderRangeChange
208 \value SliderOrientationChange
209 \value SliderStepsChange
210 \value SliderValueChange
211*/
212
213QAbstractSliderPrivate::QAbstractSliderPrivate()
214 : minimum(0), maximum(99), pageStep(10), value(0), position(0), pressValue(-1),
215 singleStep(1), offset_accumulated(0), tracking(true),
216 blocktracking(false), pressed(false),
217 invertedAppearance(false), invertedControls(false),
218 orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
219#ifdef QT_KEYPAD_NAVIGATION
220 , isAutoRepeating(false)
221 , repeatMultiplier(1)
222{
223 firstRepeat.invalidate();
224#else
225{
226#endif
227
228}
229
230QAbstractSliderPrivate::~QAbstractSliderPrivate()
231{
232}
233
234/*!
235 Sets the slider's minimum to \a min and its maximum to \a max.
236
237 If \a max is smaller than \a min, \a min becomes the only legal
238 value.
239
240 \sa minimum maximum
241*/
242void QAbstractSlider::setRange(int min, int max)
243{
244 Q_D(QAbstractSlider);
245 int oldMin = d->minimum;
246 int oldMax = d->maximum;
247 d->minimum = min;
248 d->maximum = qMax(min, max);
249 if (oldMin != d->minimum || oldMax != d->maximum) {
250 sliderChange(SliderRangeChange);
251 emit rangeChanged(d->minimum, d->maximum);
252 setValue(d->value); // re-bound
253 }
254}
255
256
257void QAbstractSliderPrivate::setSteps(int single, int page)
258{
259 Q_Q(QAbstractSlider);
260 singleStep = qAbs(single);
261 pageStep = qAbs(page);
262 q->sliderChange(QAbstractSlider::SliderStepsChange);
263}
264
265/*!
266 Constructs an abstract slider.
267
268 The \a parent arguments is sent to the QWidget constructor.
269
270 The \l minimum defaults to 0, the \l maximum to 99, with a \l
271 singleStep size of 1 and a \l pageStep size of 10, and an initial
272 \l value of 0.
273*/
274QAbstractSlider::QAbstractSlider(QWidget *parent)
275 :QWidget(*new QAbstractSliderPrivate, parent, 0)
276{
277}
278
279/*! \internal */
280QAbstractSlider::QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent)
281 :QWidget(dd, parent, 0)
282{
283}
284
285/*!
286 Destroys the slider.
287*/
288QAbstractSlider::~QAbstractSlider()
289{
290}
291
292/*!
293 \property QAbstractSlider::orientation
294 \brief the orientation of the slider
295
296 The orientation must be \l Qt::Vertical (the default) or \l
297 Qt::Horizontal.
298*/
299void QAbstractSlider::setOrientation(Qt::Orientation orientation)
300{
301 Q_D(QAbstractSlider);
302 if (d->orientation == orientation)
303 return;
304
305 d->orientation = orientation;
306 if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) {
307 QSizePolicy sp = sizePolicy();
308 sp.transpose();
309 setSizePolicy(sp);
310 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
311 }
312 update();
313 updateGeometry();
314}
315
316Qt::Orientation QAbstractSlider::orientation() const
317{
318 Q_D(const QAbstractSlider);
319 return d->orientation;
320}
321
322
323/*!
324 \property QAbstractSlider::minimum
325 \brief the sliders's minimum value
326
327 When setting this property, the \l maximum is adjusted if
328 necessary to ensure that the range remains valid. Also the
329 slider's current value is adjusted to be within the new range.
330
331*/
332
333void QAbstractSlider::setMinimum(int min)
334{
335 Q_D(QAbstractSlider);
336 setRange(min, qMax(d->maximum, min));
337}
338
339int QAbstractSlider::minimum() const
340{
341 Q_D(const QAbstractSlider);
342 return d->minimum;
343}
344
345
346/*!
347 \property QAbstractSlider::maximum
348 \brief the slider's maximum value
349
350 When setting this property, the \l minimum is adjusted if
351 necessary to ensure that the range remains valid. Also the
352 slider's current value is adjusted to be within the new range.
353
354
355*/
356
357void QAbstractSlider::setMaximum(int max)
358{
359 Q_D(QAbstractSlider);
360 setRange(qMin(d->minimum, max), max);
361}
362
363int QAbstractSlider::maximum() const
364{
365 Q_D(const QAbstractSlider);
366 return d->maximum;
367}
368
369
370
371/*!
372 \property QAbstractSlider::singleStep
373 \brief the single step.
374
375 The smaller of two natural steps that an
376 abstract sliders provides and typically corresponds to the user
377 pressing an arrow key.
378
379 If the property is modified during an auto repeating key event, behavior
380 is undefined.
381
382 \sa pageStep
383*/
384
385void QAbstractSlider::setSingleStep(int step)
386{
387 Q_D(QAbstractSlider);
388 if (step != d->singleStep)
389 d->setSteps(step, d->pageStep);
390}
391
392int QAbstractSlider::singleStep() const
393{
394 Q_D(const QAbstractSlider);
395 return d->singleStep;
396}
397
398
399/*!
400 \property QAbstractSlider::pageStep
401 \brief the page step.
402
403 The larger of two natural steps that an abstract slider provides
404 and typically corresponds to the user pressing PageUp or PageDown.
405
406 \sa singleStep
407*/
408
409void QAbstractSlider::setPageStep(int step)
410{
411 Q_D(QAbstractSlider);
412 if (step != d->pageStep)
413 d->setSteps(d->singleStep, step);
414}
415
416int QAbstractSlider::pageStep() const
417{
418 Q_D(const QAbstractSlider);
419 return d->pageStep;
420}
421
422/*!
423 \property QAbstractSlider::tracking
424 \brief whether slider tracking is enabled
425
426 If tracking is enabled (the default), the slider emits the
427 valueChanged() signal while the slider is being dragged. If
428 tracking is disabled, the slider emits the valueChanged() signal
429 only when the user releases the slider.
430
431 \sa sliderDown
432*/
433void QAbstractSlider::setTracking(bool enable)
434{
435 Q_D(QAbstractSlider);
436 d->tracking = enable;
437}
438
439bool QAbstractSlider::hasTracking() const
440{
441 Q_D(const QAbstractSlider);
442 return d->tracking;
443}
444
445
446/*!
447 \property QAbstractSlider::sliderDown
448 \brief whether the slider is pressed down.
449
450 The property is set by subclasses in order to let the abstract
451 slider know whether or not \l tracking has any effect.
452
453 Changing the slider down property emits the sliderPressed() and
454 sliderReleased() signals.
455
456*/
457void QAbstractSlider::setSliderDown(bool down)
458{
459 Q_D(QAbstractSlider);
460 bool doEmit = d->pressed != down;
461
462 d->pressed = down;
463
464 if (doEmit) {
465 if (down)
466 emit sliderPressed();
467 else
468 emit sliderReleased();
469 }
470
471 if (!down && d->position != d->value)
472 triggerAction(SliderMove);
473}
474
475bool QAbstractSlider::isSliderDown() const
476{
477 Q_D(const QAbstractSlider);
478 return d->pressed;
479}
480
481
482/*!
483 \property QAbstractSlider::sliderPosition
484 \brief the current slider position
485
486 If \l tracking is enabled (the default), this is identical to \l value.
487*/
488void QAbstractSlider::setSliderPosition(int position)
489{
490 Q_D(QAbstractSlider);
491 position = d->bound(position);
492 if (position == d->position)
493 return;
494 d->position = position;
495 if (!d->tracking)
496 update();
497 if (d->pressed)
498 emit sliderMoved(position);
499 if (d->tracking && !d->blocktracking)
500 triggerAction(SliderMove);
501}
502
503int QAbstractSlider::sliderPosition() const
504{
505 Q_D(const QAbstractSlider);
506 return d->position;
507}
508
509
510/*!
511 \property QAbstractSlider::value
512 \brief the slider's current value
513
514 The slider forces the value to be within the legal range: \l
515 minimum <= \c value <= \l maximum.
516
517 Changing the value also changes the \l sliderPosition.
518*/
519
520
521int QAbstractSlider::value() const
522{
523 Q_D(const QAbstractSlider);
524 return d->value;
525}
526
527void QAbstractSlider::setValue(int value)
528{
529 Q_D(QAbstractSlider);
530 value = d->bound(value);
531 if (d->value == value && d->position == value)
532 return;
533 d->value = value;
534 if (d->position != value) {
535 d->position = value;
536 if (d->pressed)
537 emit sliderMoved((d->position = value));
538 }
539#ifndef QT_NO_ACCESSIBILITY
540 QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
541#endif
542 sliderChange(SliderValueChange);
543 emit valueChanged(value);
544}
545
546/*!
547 \property QAbstractSlider::invertedAppearance
548 \brief whether or not a slider shows its values inverted.
549
550 If this property is false (the default), the minimum and maximum will
551 be shown in its classic position for the inherited widget. If the
552 value is true, the minimum and maximum appear at their opposite location.
553
554 Note: This property makes most sense for sliders and dials. For
555 scroll bars, the visual effect of the scroll bar subcontrols depends on
556 whether or not the styles understand inverted appearance; most styles
557 ignore this property for scroll bars.
558*/
559
560bool QAbstractSlider::invertedAppearance() const
561{
562 Q_D(const QAbstractSlider);
563 return d->invertedAppearance;
564}
565
566void QAbstractSlider::setInvertedAppearance(bool invert)
567{
568 Q_D(QAbstractSlider);
569 d->invertedAppearance = invert;
570 update();
571}
572
573
574/*!
575 \property QAbstractSlider::invertedControls
576 \brief whether or not the slider inverts its wheel and key events.
577
578 If this property is false, scrolling the mouse wheel "up" and using keys
579 like page up will increase the slider's value towards its maximum. Otherwise
580 pressing page up will move value towards the slider's minimum.
581*/
582
583
584bool QAbstractSlider::invertedControls() const
585{
586 Q_D(const QAbstractSlider);
587 return d->invertedControls;
588}
589
590void QAbstractSlider::setInvertedControls(bool invert)
591{
592 Q_D(QAbstractSlider);
593 d->invertedControls = invert;
594}
595
596/*! Triggers a slider \a action. Possible actions are \l
597 SliderSingleStepAdd, \l SliderSingleStepSub, \l SliderPageStepAdd,
598 \l SliderPageStepSub, \l SliderToMinimum, \l SliderToMaximum, and \l
599 SliderMove.
600
601 \sa actionTriggered()
602 */
603void QAbstractSlider::triggerAction(SliderAction action)
604{
605 Q_D(QAbstractSlider);
606 d->blocktracking = true;
607 switch (action) {
608 case SliderSingleStepAdd:
609 setSliderPosition(d->overflowSafeAdd(d->effectiveSingleStep()));
610 break;
611 case SliderSingleStepSub:
612 setSliderPosition(d->overflowSafeAdd(-d->effectiveSingleStep()));
613 break;
614 case SliderPageStepAdd:
615 setSliderPosition(d->overflowSafeAdd(d->pageStep));
616 break;
617 case SliderPageStepSub:
618 setSliderPosition(d->overflowSafeAdd(-d->pageStep));
619 break;
620 case SliderToMinimum:
621 setSliderPosition(d->minimum);
622 break;
623 case SliderToMaximum:
624 setSliderPosition(d->maximum);
625 break;
626 case SliderMove:
627 case SliderNoAction:
628 break;
629 };
630 emit actionTriggered(action);
631 d->blocktracking = false;
632 setValue(d->position);
633}
634
635/*! Sets action \a action to be triggered repetitively in intervals
636of \a repeatTime, after an initial delay of \a thresholdTime.
637
638\sa triggerAction() repeatAction()
639 */
640void QAbstractSlider::setRepeatAction(SliderAction action, int thresholdTime, int repeatTime)
641{
642 Q_D(QAbstractSlider);
643 if ((d->repeatAction = action) == SliderNoAction) {
644 d->repeatActionTimer.stop();
645 } else {
646 d->repeatActionTime = repeatTime;
647 d->repeatActionTimer.start(thresholdTime, this);
648 }
649}
650
651/*!
652 Returns the current repeat action.
653 \sa setRepeatAction()
654 */
655QAbstractSlider::SliderAction QAbstractSlider::repeatAction() const
656{
657 Q_D(const QAbstractSlider);
658 return d->repeatAction;
659}
660
661/*!\reimp
662 */
663void QAbstractSlider::timerEvent(QTimerEvent *e)
664{
665 Q_D(QAbstractSlider);
666 if (e->timerId() == d->repeatActionTimer.timerId()) {
667 if (d->repeatActionTime) { // was threshold time, use repeat time next time
668 d->repeatActionTimer.start(d->repeatActionTime, this);
669 d->repeatActionTime = 0;
670 }
671 if (d->repeatAction == SliderPageStepAdd)
672 d->setAdjustedSliderPosition(d->overflowSafeAdd(d->pageStep));
673 else if (d->repeatAction == SliderPageStepSub)
674 d->setAdjustedSliderPosition(d->overflowSafeAdd(-d->pageStep));
675 else
676 triggerAction(d->repeatAction);
677 }
678}
679
680/*!
681 Reimplement this virtual function to track slider changes such as
682 \l SliderRangeChange, \l SliderOrientationChange, \l
683 SliderStepsChange, or \l SliderValueChange. The default
684 implementation only updates the display and ignores the \a change
685 parameter.
686 */
687void QAbstractSlider::sliderChange(SliderChange)
688{
689 update();
690}
691
692bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta)
693{
694 Q_Q(QAbstractSlider);
695 int stepsToScroll = 0;
696 // in Qt scrolling to the right gives negative values.
697 if (orientation == Qt::Horizontal)
698 delta = -delta;
699 qreal offset = qreal(delta) / 120;
700
701 if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier)) {
702 // Scroll one page regardless of delta:
703 stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep);
704 offset_accumulated = 0;
705 } else {
706 // Calculate how many lines to scroll. Depending on what delta is (and
707 // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
708 // only scroll whole lines, so we keep the reminder until next event.
709 qreal stepsToScrollF =
710#ifndef QT_NO_WHEELEVENT
711 QApplication::wheelScrollLines() *
712#endif
713 offset * effectiveSingleStep();
714 // Check if wheel changed direction since last event:
715 if (offset_accumulated != 0 && (offset / offset_accumulated) < 0)
716 offset_accumulated = 0;
717
718 offset_accumulated += stepsToScrollF;
719#ifndef Q_WS_MAC
720 // Don't scroll more than one page in any case:
721 stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep);
722#else
723 // Native UI-elements on Mac can scroll hundreds of lines at a time as
724 // a result of acceleration. So keep the same behaviour in Qt, and
725 // don't restrict stepsToScroll to certain maximum (pageStep):
726 stepsToScroll = int(offset_accumulated);
727#endif
728 offset_accumulated -= int(offset_accumulated);
729 if (stepsToScroll == 0)
730 return false;
731 }
732
733 if (invertedControls)
734 stepsToScroll = -stepsToScroll;
735
736 int prevValue = value;
737 position = overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
738 q->triggerAction(QAbstractSlider::SliderMove);
739
740 if (prevValue == value) {
741 offset_accumulated = 0;
742 return false;
743 }
744 return true;
745}
746
747/*!
748 \reimp
749*/
750#ifndef QT_NO_WHEELEVENT
751void QAbstractSlider::wheelEvent(QWheelEvent * e)
752{
753 Q_D(QAbstractSlider);
754 e->ignore();
755 int delta = e->delta();
756 if (d->scrollByDelta(e->orientation(), e->modifiers(), delta))
757 e->accept();
758}
759
760#endif
761
762/*!
763 \reimp
764*/
765void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
766{
767 Q_D(QAbstractSlider);
768 SliderAction action = SliderNoAction;
769#ifdef QT_KEYPAD_NAVIGATION
770 if (ev->isAutoRepeat()) {
771 if (!d->firstRepeat.isValid())
772 d->firstRepeat.start();
773 else if (1 == d->repeatMultiplier) {
774 // This is the interval in milli seconds which one key repetition
775 // takes.
776 const int repeatMSecs = d->firstRepeat.elapsed();
777
778 /**
779 * The time it takes to currently navigate the whole slider.
780 */
781 const qreal currentTimeElapse = (qreal(maximum()) / singleStep()) * repeatMSecs;
782
783 /**
784 * This is an arbitrarily determined constant in msecs that
785 * specifies how long time it should take to navigate from the
786 * start to the end(excluding starting key auto repeat).
787 */
788 const int SliderRepeatElapse = 2500;
789
790 d->repeatMultiplier = currentTimeElapse / SliderRepeatElapse;
791 }
792
793 }
794 else if (d->firstRepeat.isValid()) {
795 d->firstRepeat.invalidate();
796 d->repeatMultiplier = 1;
797 }
798
799#endif
800
801 switch (ev->key()) {
802#ifdef QT_KEYPAD_NAVIGATION
803 case Qt::Key_Select:
804 if (QApplication::keypadNavigationEnabled())
805 setEditFocus(!hasEditFocus());
806 else
807 ev->ignore();
808 break;
809 case Qt::Key_Back:
810 if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
811 setValue(d->origValue);
812 setEditFocus(false);
813 } else
814 ev->ignore();
815 break;
816#endif
817
818 // It seems we need to use invertedAppearance for Left and right, otherwise, things look weird.
819 case Qt::Key_Left:
820#ifdef QT_KEYPAD_NAVIGATION
821 // In QApplication::KeypadNavigationDirectional, we want to change the slider
822 // value if there is no left/right navigation possible and if this slider is not
823 // inside a tab widget.
824 if (QApplication::keypadNavigationEnabled()
825 && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
826 || d->orientation == Qt::Vertical
827 || !hasEditFocus()
828 && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
829 ev->ignore();
830 return;
831 }
832 if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
833 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
834 else
835#endif
836 if (isRightToLeft())
837 action = d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd;
838 else
839 action = !d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd;
840 break;
841 case Qt::Key_Right:
842#ifdef QT_KEYPAD_NAVIGATION
843 // Same logic as in Qt::Key_Left
844 if (QApplication::keypadNavigationEnabled()
845 && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
846 || d->orientation == Qt::Vertical
847 || !hasEditFocus()
848 && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
849 ev->ignore();
850 return;
851 }
852 if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
853 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
854 else
855#endif
856 if (isRightToLeft())
857 action = d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub;
858 else
859 action = !d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub;
860 break;
861 case Qt::Key_Up:
862#ifdef QT_KEYPAD_NAVIGATION
863 // In QApplication::KeypadNavigationDirectional, we want to change the slider
864 // value if there is no up/down navigation possible.
865 if (QApplication::keypadNavigationEnabled()
866 && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
867 || d->orientation == Qt::Horizontal
868 || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
869 ev->ignore();
870 break;
871 }
872#endif
873 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
874 break;
875 case Qt::Key_Down:
876#ifdef QT_KEYPAD_NAVIGATION
877 // Same logic as in Qt::Key_Up
878 if (QApplication::keypadNavigationEnabled()
879 && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
880 || d->orientation == Qt::Horizontal
881 || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
882 ev->ignore();
883 break;
884 }
885#endif
886 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
887 break;
888 case Qt::Key_PageUp:
889 action = d->invertedControls ? SliderPageStepSub : SliderPageStepAdd;
890 break;
891 case Qt::Key_PageDown:
892 action = d->invertedControls ? SliderPageStepAdd : SliderPageStepSub;
893 break;
894 case Qt::Key_Home:
895 action = SliderToMinimum;
896 break;
897 case Qt::Key_End:
898 action = SliderToMaximum;
899 break;
900 default:
901 ev->ignore();
902 break;
903 }
904 if (action)
905 triggerAction(action);
906}
907
908/*!
909 \reimp
910*/
911void QAbstractSlider::changeEvent(QEvent *ev)
912{
913 Q_D(QAbstractSlider);
914 switch (ev->type()) {
915 case QEvent::EnabledChange:
916 if (!isEnabled()) {
917 d->repeatActionTimer.stop();
918 setSliderDown(false);
919 }
920 // fall through...
921 default:
922 QWidget::changeEvent(ev);
923 }
924}
925
926/*!
927 \reimp
928*/
929bool QAbstractSlider::event(QEvent *e)
930{
931#ifdef QT_KEYPAD_NAVIGATION
932 Q_D(QAbstractSlider);
933 switch (e->type()) {
934 case QEvent::FocusIn:
935 d->origValue = d->value;
936 break;
937 default:
938 break;
939 }
940#endif
941
942 return QWidget::event(e);
943}
944
945/*! \fn int QAbstractSlider::minValue() const
946
947 Use minimum() instead.
948*/
949
950/*! \fn int QAbstractSlider::maxValue() const
951
952 Use maximum() instead.
953*/
954
955/*! \fn int QAbstractSlider::lineStep() const
956
957 Use singleStep() instead.
958*/
959
960/*! \fn void QAbstractSlider::setMinValue(int v)
961
962 Use setMinimum() instead.
963*/
964
965/*! \fn void QAbstractSlider::setMaxValue(int v)
966
967 Use setMaximum() instead.
968*/
969
970/*! \fn void QAbstractSlider::setLineStep(int v)
971
972 Use setSingleStep() instead.
973*/
974
975/*! \fn void QAbstractSlider::addPage()
976
977 Use triggerAction(QAbstractSlider::SliderPageStepAdd) instead.
978*/
979
980/*! \fn void QAbstractSlider::subtractPage()
981
982 Use triggerAction(QAbstractSlider::SliderPageStepSub) instead.
983*/
984
985/*! \fn void QAbstractSlider::addLine()
986
987 Use triggerAction(QAbstractSlider::SliderSingleStepAdd) instead.
988*/
989
990/*! \fn void QAbstractSlider::subtractLine()
991
992 Use triggerAction(QAbstractSlider::SliderSingleStepSub) instead.
993*/
994
995/*! \fn void QAbstractSlider::setSteps(int single, int page)
996
997 Use setSingleStep(\a single) followed by setPageStep(\a page)
998 instead.
999*/
1000
1001QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.