util/src/gui/widgets/qabstractslider.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 
       
    52 QT_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 
       
   213 QAbstractSliderPrivate::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 #endif
       
   223 {
       
   224 }
       
   225 
       
   226 QAbstractSliderPrivate::~QAbstractSliderPrivate()
       
   227 {
       
   228 }
       
   229 
       
   230 /*!
       
   231     Sets the slider's minimum to \a min and its maximum to \a max.
       
   232 
       
   233     If \a max is smaller than \a min, \a min becomes the only legal
       
   234     value.
       
   235 
       
   236     \sa minimum maximum
       
   237 */
       
   238 void QAbstractSlider::setRange(int min, int max)
       
   239 {
       
   240     Q_D(QAbstractSlider);
       
   241     int oldMin = d->minimum;
       
   242     int oldMax = d->maximum;
       
   243     d->minimum = min;
       
   244     d->maximum = qMax(min, max);
       
   245     if (oldMin != d->minimum || oldMax != d->maximum) {
       
   246         sliderChange(SliderRangeChange);
       
   247         emit rangeChanged(d->minimum, d->maximum);
       
   248         setValue(d->value); // re-bound
       
   249     }
       
   250 }
       
   251 
       
   252 
       
   253 void QAbstractSliderPrivate::setSteps(int single, int page)
       
   254 {
       
   255     Q_Q(QAbstractSlider);
       
   256     singleStep = qAbs(single);
       
   257     pageStep = qAbs(page);
       
   258     q->sliderChange(QAbstractSlider::SliderStepsChange);
       
   259 }
       
   260 
       
   261 /*!
       
   262     Constructs an abstract slider.
       
   263 
       
   264     The \a parent arguments is sent to the QWidget constructor.
       
   265 
       
   266     The \l minimum defaults to 0, the \l maximum to 99, with a \l
       
   267     singleStep size of 1 and a \l pageStep size of 10, and an initial
       
   268     \l value of 0.
       
   269 */
       
   270 QAbstractSlider::QAbstractSlider(QWidget *parent)
       
   271     :QWidget(*new QAbstractSliderPrivate, parent, 0)
       
   272 {
       
   273 }
       
   274 
       
   275 /*! \internal */
       
   276 QAbstractSlider::QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent)
       
   277     :QWidget(dd, parent, 0)
       
   278 {
       
   279 }
       
   280 
       
   281 /*!
       
   282     Destroys the slider.
       
   283 */
       
   284 QAbstractSlider::~QAbstractSlider()
       
   285 {
       
   286 }
       
   287 
       
   288 /*!
       
   289     \property QAbstractSlider::orientation
       
   290     \brief the orientation of the slider
       
   291 
       
   292     The orientation must be \l Qt::Vertical (the default) or \l
       
   293     Qt::Horizontal.
       
   294 */
       
   295 void QAbstractSlider::setOrientation(Qt::Orientation orientation)
       
   296 {
       
   297     Q_D(QAbstractSlider);
       
   298     if (d->orientation == orientation)
       
   299         return;
       
   300 
       
   301     d->orientation = orientation;
       
   302     if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) {
       
   303         QSizePolicy sp = sizePolicy();
       
   304         sp.transpose();
       
   305         setSizePolicy(sp);
       
   306         setAttribute(Qt::WA_WState_OwnSizePolicy, false);
       
   307     }
       
   308     update();
       
   309     updateGeometry();
       
   310 }
       
   311 
       
   312 Qt::Orientation QAbstractSlider::orientation() const
       
   313 {
       
   314     Q_D(const QAbstractSlider);
       
   315     return d->orientation;
       
   316 }
       
   317 
       
   318 
       
   319 /*!
       
   320     \property QAbstractSlider::minimum
       
   321     \brief the sliders's minimum value
       
   322 
       
   323     When setting this property, the \l maximum is adjusted if
       
   324     necessary to ensure that the range remains valid. Also the
       
   325     slider's current value is adjusted to be within the new range.
       
   326 
       
   327 */
       
   328 
       
   329 void QAbstractSlider::setMinimum(int min)
       
   330 {
       
   331     Q_D(QAbstractSlider);
       
   332     setRange(min, qMax(d->maximum, min));
       
   333 }
       
   334 
       
   335 int QAbstractSlider::minimum() const
       
   336 {
       
   337     Q_D(const QAbstractSlider);
       
   338     return d->minimum;
       
   339 }
       
   340 
       
   341 
       
   342 /*!
       
   343     \property QAbstractSlider::maximum
       
   344     \brief the slider's maximum value
       
   345 
       
   346     When setting this property, the \l minimum is adjusted if
       
   347     necessary to ensure that the range remains valid.  Also the
       
   348     slider's current value is adjusted to be within the new range.
       
   349 
       
   350 
       
   351 */
       
   352 
       
   353 void QAbstractSlider::setMaximum(int max)
       
   354 {
       
   355     Q_D(QAbstractSlider);
       
   356     setRange(qMin(d->minimum, max), max);
       
   357 }
       
   358 
       
   359 int QAbstractSlider::maximum() const
       
   360 {
       
   361     Q_D(const QAbstractSlider);
       
   362     return d->maximum;
       
   363 }
       
   364 
       
   365 
       
   366 
       
   367 /*!
       
   368     \property QAbstractSlider::singleStep
       
   369     \brief the single step.
       
   370 
       
   371     The smaller of two natural steps that an
       
   372     abstract sliders provides and typically corresponds to the user
       
   373     pressing an arrow key.
       
   374 
       
   375     If the property is modified during an auto repeating key event, behavior
       
   376     is undefined.
       
   377 
       
   378     \sa pageStep
       
   379 */
       
   380 
       
   381 void QAbstractSlider::setSingleStep(int step)
       
   382 {
       
   383     Q_D(QAbstractSlider);
       
   384     if (step != d->singleStep)
       
   385         d->setSteps(step, d->pageStep);
       
   386 }
       
   387 
       
   388 int QAbstractSlider::singleStep() const
       
   389 {
       
   390     Q_D(const QAbstractSlider);
       
   391     return d->singleStep;
       
   392 }
       
   393 
       
   394 
       
   395 /*!
       
   396     \property QAbstractSlider::pageStep
       
   397     \brief the page step.
       
   398 
       
   399     The larger of two natural steps that an abstract slider provides
       
   400     and typically corresponds to the user pressing PageUp or PageDown.
       
   401 
       
   402     \sa singleStep
       
   403 */
       
   404 
       
   405 void QAbstractSlider::setPageStep(int step)
       
   406 {
       
   407     Q_D(QAbstractSlider);
       
   408     if (step != d->pageStep)
       
   409         d->setSteps(d->singleStep, step);
       
   410 }
       
   411 
       
   412 int QAbstractSlider::pageStep() const
       
   413 {
       
   414     Q_D(const QAbstractSlider);
       
   415     return d->pageStep;
       
   416 }
       
   417 
       
   418 /*!
       
   419     \property QAbstractSlider::tracking
       
   420     \brief whether slider tracking is enabled
       
   421 
       
   422     If tracking is enabled (the default), the slider emits the
       
   423     valueChanged() signal while the slider is being dragged. If
       
   424     tracking is disabled, the slider emits the valueChanged() signal
       
   425     only when the user releases the slider.
       
   426 
       
   427     \sa sliderDown
       
   428 */
       
   429 void QAbstractSlider::setTracking(bool enable)
       
   430 {
       
   431     Q_D(QAbstractSlider);
       
   432     d->tracking = enable;
       
   433 }
       
   434 
       
   435 bool QAbstractSlider::hasTracking() const
       
   436 {
       
   437     Q_D(const QAbstractSlider);
       
   438     return d->tracking;
       
   439 }
       
   440 
       
   441 
       
   442 /*!
       
   443     \property QAbstractSlider::sliderDown
       
   444     \brief whether the slider is pressed down.
       
   445 
       
   446     The property is set by subclasses in order to let the abstract
       
   447     slider know whether or not \l tracking has any effect.
       
   448 
       
   449     Changing the slider down property emits the sliderPressed() and
       
   450     sliderReleased() signals.
       
   451 
       
   452 */
       
   453 void QAbstractSlider::setSliderDown(bool down)
       
   454 {
       
   455     Q_D(QAbstractSlider);
       
   456     bool doEmit = d->pressed != down;
       
   457 
       
   458     d->pressed = down;
       
   459 
       
   460     if (doEmit) {
       
   461         if (down)
       
   462             emit sliderPressed();
       
   463         else
       
   464             emit sliderReleased();
       
   465     }
       
   466 
       
   467     if (!down && d->position != d->value)
       
   468         triggerAction(SliderMove);
       
   469 }
       
   470 
       
   471 bool QAbstractSlider::isSliderDown() const
       
   472 {
       
   473     Q_D(const QAbstractSlider);
       
   474     return d->pressed;
       
   475 }
       
   476 
       
   477 
       
   478 /*!
       
   479     \property QAbstractSlider::sliderPosition
       
   480     \brief the current slider position
       
   481 
       
   482     If \l tracking is enabled (the default), this is identical to \l value.
       
   483 */
       
   484 void QAbstractSlider::setSliderPosition(int position)
       
   485 {
       
   486     Q_D(QAbstractSlider);
       
   487     position = d->bound(position);
       
   488     if (position == d->position)
       
   489         return;
       
   490     d->position = position;
       
   491     if (!d->tracking)
       
   492         update();
       
   493     if (d->pressed)
       
   494         emit sliderMoved(position);
       
   495     if (d->tracking && !d->blocktracking)
       
   496         triggerAction(SliderMove);
       
   497 }
       
   498 
       
   499 int QAbstractSlider::sliderPosition() const
       
   500 {
       
   501     Q_D(const QAbstractSlider);
       
   502     return d->position;
       
   503 }
       
   504 
       
   505 
       
   506 /*!
       
   507     \property QAbstractSlider::value
       
   508     \brief the slider's current value
       
   509 
       
   510     The slider forces the value to be within the legal range: \l
       
   511     minimum <= \c value <= \l maximum.
       
   512 
       
   513     Changing the value also changes the \l sliderPosition.
       
   514 */
       
   515 
       
   516 
       
   517 int QAbstractSlider::value() const
       
   518 {
       
   519     Q_D(const QAbstractSlider);
       
   520     return d->value;
       
   521 }
       
   522 
       
   523 void QAbstractSlider::setValue(int value)
       
   524 {
       
   525     Q_D(QAbstractSlider);
       
   526     value = d->bound(value);
       
   527     if (d->value == value && d->position == value)
       
   528         return;
       
   529     d->value = value;
       
   530     if (d->position != value) {
       
   531         d->position = value;
       
   532         if (d->pressed)
       
   533             emit sliderMoved((d->position = value));
       
   534     }
       
   535 #ifndef QT_NO_ACCESSIBILITY
       
   536     QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
       
   537 #endif
       
   538     sliderChange(SliderValueChange);
       
   539     emit valueChanged(value);
       
   540 }
       
   541 
       
   542 /*!
       
   543     \property QAbstractSlider::invertedAppearance
       
   544     \brief whether or not a slider shows its values inverted.
       
   545 
       
   546     If this property is false (the default), the minimum and maximum will
       
   547     be shown in its classic position for the inherited widget. If the
       
   548     value is true, the minimum and maximum appear at their opposite location.
       
   549 
       
   550     Note: This property makes most sense for sliders and dials. For
       
   551     scroll bars, the visual effect of the scroll bar subcontrols depends on
       
   552     whether or not the styles understand inverted appearance; most styles
       
   553     ignore this property for scroll bars.
       
   554 */
       
   555 
       
   556 bool QAbstractSlider::invertedAppearance() const
       
   557 {
       
   558     Q_D(const QAbstractSlider);
       
   559     return d->invertedAppearance;
       
   560 }
       
   561 
       
   562 void QAbstractSlider::setInvertedAppearance(bool invert)
       
   563 {
       
   564     Q_D(QAbstractSlider);
       
   565     d->invertedAppearance = invert;
       
   566     update();
       
   567 }
       
   568 
       
   569 
       
   570 /*!
       
   571     \property QAbstractSlider::invertedControls
       
   572     \brief whether or not the slider inverts its wheel and key events.
       
   573 
       
   574     If this property is false, scrolling the mouse wheel "up" and using keys
       
   575     like page up will increase the slider's value towards its maximum. Otherwise
       
   576     pressing page up will move value towards the slider's minimum.
       
   577 */
       
   578 
       
   579 
       
   580 bool QAbstractSlider::invertedControls() const
       
   581 {
       
   582     Q_D(const QAbstractSlider);
       
   583     return d->invertedControls;
       
   584 }
       
   585 
       
   586 void QAbstractSlider::setInvertedControls(bool invert)
       
   587 {
       
   588     Q_D(QAbstractSlider);
       
   589     d->invertedControls = invert;
       
   590 }
       
   591 
       
   592 /*!  Triggers a slider \a action.  Possible actions are \l
       
   593   SliderSingleStepAdd, \l SliderSingleStepSub, \l SliderPageStepAdd,
       
   594   \l SliderPageStepSub, \l SliderToMinimum, \l SliderToMaximum, and \l
       
   595   SliderMove.
       
   596 
       
   597   \sa actionTriggered()
       
   598  */
       
   599 void QAbstractSlider::triggerAction(SliderAction action)
       
   600 {
       
   601     Q_D(QAbstractSlider);
       
   602     d->blocktracking = true;
       
   603     switch (action) {
       
   604     case SliderSingleStepAdd:
       
   605         setSliderPosition(d->overflowSafeAdd(d->effectiveSingleStep()));
       
   606         break;
       
   607     case SliderSingleStepSub:
       
   608         setSliderPosition(d->overflowSafeAdd(-d->effectiveSingleStep()));
       
   609         break;
       
   610     case SliderPageStepAdd:
       
   611         setSliderPosition(d->overflowSafeAdd(d->pageStep));
       
   612         break;
       
   613     case SliderPageStepSub:
       
   614         setSliderPosition(d->overflowSafeAdd(-d->pageStep));
       
   615         break;
       
   616     case SliderToMinimum:
       
   617         setSliderPosition(d->minimum);
       
   618         break;
       
   619     case SliderToMaximum:
       
   620         setSliderPosition(d->maximum);
       
   621         break;
       
   622     case SliderMove:
       
   623     case SliderNoAction:
       
   624         break;
       
   625     };
       
   626     emit actionTriggered(action);
       
   627     d->blocktracking = false;
       
   628     setValue(d->position);
       
   629 }
       
   630 
       
   631 /*!  Sets action \a action to be triggered repetitively in intervals
       
   632 of \a repeatTime, after an initial delay of \a thresholdTime.
       
   633 
       
   634 \sa triggerAction() repeatAction()
       
   635  */
       
   636 void QAbstractSlider::setRepeatAction(SliderAction action, int thresholdTime, int repeatTime)
       
   637 {
       
   638     Q_D(QAbstractSlider);
       
   639     if ((d->repeatAction = action) == SliderNoAction) {
       
   640         d->repeatActionTimer.stop();
       
   641     } else {
       
   642         d->repeatActionTime = repeatTime;
       
   643         d->repeatActionTimer.start(thresholdTime, this);
       
   644     }
       
   645 }
       
   646 
       
   647 /*!
       
   648   Returns the current repeat action.
       
   649   \sa setRepeatAction()
       
   650  */
       
   651 QAbstractSlider::SliderAction QAbstractSlider::repeatAction() const
       
   652 {
       
   653     Q_D(const QAbstractSlider);
       
   654     return d->repeatAction;
       
   655 }
       
   656 
       
   657 /*!\reimp
       
   658  */
       
   659 void QAbstractSlider::timerEvent(QTimerEvent *e)
       
   660 {
       
   661     Q_D(QAbstractSlider);
       
   662     if (e->timerId() == d->repeatActionTimer.timerId()) {
       
   663         if (d->repeatActionTime) { // was threshold time, use repeat time next time
       
   664             d->repeatActionTimer.start(d->repeatActionTime, this);
       
   665             d->repeatActionTime = 0;
       
   666         }
       
   667         if (d->repeatAction == SliderPageStepAdd)
       
   668             d->setAdjustedSliderPosition(d->overflowSafeAdd(d->pageStep));
       
   669         else if (d->repeatAction == SliderPageStepSub)
       
   670             d->setAdjustedSliderPosition(d->overflowSafeAdd(-d->pageStep));
       
   671         else
       
   672             triggerAction(d->repeatAction);
       
   673     }
       
   674 }
       
   675 
       
   676 /*!
       
   677     Reimplement this virtual function to track slider changes such as
       
   678     \l SliderRangeChange, \l SliderOrientationChange, \l
       
   679     SliderStepsChange, or \l SliderValueChange. The default
       
   680     implementation only updates the display and ignores the \a change
       
   681     parameter.
       
   682  */
       
   683 void QAbstractSlider::sliderChange(SliderChange)
       
   684 {
       
   685     update();
       
   686 }
       
   687 
       
   688 bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta)
       
   689 {
       
   690     Q_Q(QAbstractSlider);
       
   691     int stepsToScroll = 0;
       
   692     // in Qt scrolling to the right gives negative values.
       
   693     if (orientation == Qt::Horizontal)
       
   694         delta = -delta;
       
   695     qreal offset = qreal(delta) / 120;
       
   696 
       
   697     if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier)) {
       
   698         // Scroll one page regardless of delta:
       
   699         stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep);
       
   700         offset_accumulated = 0;
       
   701     } else {
       
   702         // Calculate how many lines to scroll. Depending on what delta is (and
       
   703         // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
       
   704         // only scroll whole lines, so we keep the reminder until next event.
       
   705         qreal stepsToScrollF =
       
   706 #ifndef QT_NO_WHEELEVENT
       
   707                 QApplication::wheelScrollLines() *
       
   708 #endif
       
   709                 offset * effectiveSingleStep();
       
   710         // Check if wheel changed direction since last event:
       
   711         if (offset_accumulated != 0 && (offset / offset_accumulated) < 0)
       
   712             offset_accumulated = 0;
       
   713 
       
   714         offset_accumulated += stepsToScrollF;
       
   715         stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep);
       
   716         offset_accumulated -= int(offset_accumulated);
       
   717         if (stepsToScroll == 0)
       
   718             return false;
       
   719     }
       
   720 
       
   721     if (invertedControls)
       
   722         stepsToScroll = -stepsToScroll;
       
   723 
       
   724     int prevValue = value;
       
   725     position = overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
       
   726     q->triggerAction(QAbstractSlider::SliderMove);
       
   727 
       
   728     if (prevValue == value) {
       
   729         offset_accumulated = 0;
       
   730         return false;
       
   731     }
       
   732     return true;
       
   733 }
       
   734 
       
   735 /*!
       
   736     \reimp
       
   737 */
       
   738 #ifndef QT_NO_WHEELEVENT
       
   739 void QAbstractSlider::wheelEvent(QWheelEvent * e)
       
   740 {
       
   741     Q_D(QAbstractSlider);
       
   742     e->ignore();
       
   743     int delta = e->delta();
       
   744     if (d->scrollByDelta(e->orientation(), e->modifiers(), delta))
       
   745         e->accept();
       
   746 }
       
   747 
       
   748 #endif
       
   749 
       
   750 /*!
       
   751     \reimp
       
   752 */
       
   753 void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
       
   754 {
       
   755     Q_D(QAbstractSlider);
       
   756     SliderAction action = SliderNoAction;
       
   757 #ifdef QT_KEYPAD_NAVIGATION
       
   758     if (ev->isAutoRepeat()) {
       
   759         if (d->firstRepeat.isNull())
       
   760             d->firstRepeat = QTime::currentTime();
       
   761         else if (1 == d->repeatMultiplier) {
       
   762             // This is the interval in milli seconds which one key repetition
       
   763             // takes.
       
   764             const int repeatMSecs = d->firstRepeat.msecsTo(QTime::currentTime());
       
   765 
       
   766             /**
       
   767              * The time it takes to currently navigate the whole slider.
       
   768              */
       
   769             const qreal currentTimeElapse = (qreal(maximum()) / singleStep()) * repeatMSecs;
       
   770 
       
   771             /**
       
   772              * This is an arbitrarily determined constant in msecs that
       
   773              * specifies how long time it should take to navigate from the
       
   774              * start to the end(excluding starting key auto repeat).
       
   775              */
       
   776             const int SliderRepeatElapse = 2500;
       
   777 
       
   778             d->repeatMultiplier = currentTimeElapse / SliderRepeatElapse;
       
   779         }
       
   780 
       
   781     }
       
   782     else if (!d->firstRepeat.isNull()) {
       
   783         d->firstRepeat = QTime();
       
   784         d->repeatMultiplier = 1;
       
   785     }
       
   786 
       
   787 #endif
       
   788 
       
   789     switch (ev->key()) {
       
   790 #ifdef QT_KEYPAD_NAVIGATION
       
   791         case Qt::Key_Select:
       
   792             if (QApplication::keypadNavigationEnabled())
       
   793                 setEditFocus(!hasEditFocus());
       
   794             else
       
   795                 ev->ignore();
       
   796             break;
       
   797         case Qt::Key_Back:
       
   798             if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
       
   799                 setValue(d->origValue);
       
   800                 setEditFocus(false);
       
   801             } else
       
   802                 ev->ignore();
       
   803             break;
       
   804 #endif
       
   805 
       
   806         // It seems we need to use invertedAppearance for Left and right, otherwise, things look weird.
       
   807         case Qt::Key_Left:
       
   808 #ifdef QT_KEYPAD_NAVIGATION
       
   809             // In QApplication::KeypadNavigationDirectional, we want to change the slider
       
   810             // value if there is no left/right navigation possible and if this slider is not
       
   811             // inside a tab widget.
       
   812             if (QApplication::keypadNavigationEnabled()
       
   813                     && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
       
   814                     || d->orientation == Qt::Vertical
       
   815                     || !hasEditFocus()
       
   816                     && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
       
   817                 ev->ignore();
       
   818                 return;
       
   819             }
       
   820             if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
       
   821                 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
       
   822             else
       
   823 #endif
       
   824             if (isRightToLeft())
       
   825                 action = d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd;
       
   826             else
       
   827                 action = !d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd;
       
   828             break;
       
   829         case Qt::Key_Right:
       
   830 #ifdef QT_KEYPAD_NAVIGATION
       
   831             // Same logic as in Qt::Key_Left
       
   832             if (QApplication::keypadNavigationEnabled()
       
   833                     && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
       
   834                     || d->orientation == Qt::Vertical
       
   835                     || !hasEditFocus()
       
   836                     && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
       
   837                 ev->ignore();
       
   838                 return;
       
   839             }
       
   840             if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
       
   841                 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
       
   842             else
       
   843 #endif
       
   844             if (isRightToLeft())
       
   845                 action = d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub;
       
   846             else
       
   847                 action = !d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub;
       
   848             break;
       
   849         case Qt::Key_Up:
       
   850 #ifdef QT_KEYPAD_NAVIGATION
       
   851             // In QApplication::KeypadNavigationDirectional, we want to change the slider
       
   852             // value if there is no up/down navigation possible.
       
   853             if (QApplication::keypadNavigationEnabled()
       
   854                     && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
       
   855                     || d->orientation == Qt::Horizontal
       
   856                     || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
       
   857                 ev->ignore();
       
   858                 break;
       
   859             }
       
   860 #endif
       
   861             action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
       
   862             break;
       
   863         case Qt::Key_Down:
       
   864 #ifdef QT_KEYPAD_NAVIGATION
       
   865             // Same logic as in Qt::Key_Up
       
   866             if (QApplication::keypadNavigationEnabled()
       
   867                     && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
       
   868                     || d->orientation == Qt::Horizontal
       
   869                     || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
       
   870                 ev->ignore();
       
   871                 break;
       
   872             }
       
   873 #endif
       
   874             action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
       
   875             break;
       
   876         case Qt::Key_PageUp:
       
   877             action = d->invertedControls ? SliderPageStepSub : SliderPageStepAdd;
       
   878             break;
       
   879         case Qt::Key_PageDown:
       
   880             action = d->invertedControls ? SliderPageStepAdd : SliderPageStepSub;
       
   881             break;
       
   882         case Qt::Key_Home:
       
   883             action = SliderToMinimum;
       
   884             break;
       
   885         case Qt::Key_End:
       
   886             action = SliderToMaximum;
       
   887             break;
       
   888         default:
       
   889             ev->ignore();
       
   890             break;
       
   891     }
       
   892     if (action)
       
   893         triggerAction(action);
       
   894 }
       
   895 
       
   896 /*!
       
   897     \reimp
       
   898 */
       
   899 void QAbstractSlider::changeEvent(QEvent *ev)
       
   900 {
       
   901     Q_D(QAbstractSlider);
       
   902     switch (ev->type()) {
       
   903     case QEvent::EnabledChange:
       
   904         if (!isEnabled()) {
       
   905             d->repeatActionTimer.stop();
       
   906             setSliderDown(false);
       
   907         }
       
   908         // fall through...
       
   909     default:
       
   910         QWidget::changeEvent(ev);
       
   911     }
       
   912 }
       
   913 
       
   914 /*!
       
   915     \reimp
       
   916 */
       
   917 bool QAbstractSlider::event(QEvent *e)
       
   918 {
       
   919 #ifdef QT_KEYPAD_NAVIGATION
       
   920     Q_D(QAbstractSlider);
       
   921     switch (e->type()) {
       
   922     case QEvent::FocusIn:
       
   923         d->origValue = d->value;
       
   924         break;
       
   925     default:
       
   926         break;
       
   927     }
       
   928 #endif
       
   929 
       
   930     return QWidget::event(e);
       
   931 }
       
   932 
       
   933 /*! \fn int QAbstractSlider::minValue() const
       
   934 
       
   935     Use minimum() instead.
       
   936 */
       
   937 
       
   938 /*! \fn int QAbstractSlider::maxValue() const
       
   939 
       
   940     Use maximum() instead.
       
   941 */
       
   942 
       
   943 /*! \fn int QAbstractSlider::lineStep() const
       
   944 
       
   945     Use singleStep() instead.
       
   946 */
       
   947 
       
   948 /*! \fn void QAbstractSlider::setMinValue(int v)
       
   949 
       
   950     Use setMinimum() instead.
       
   951 */
       
   952 
       
   953 /*! \fn void QAbstractSlider::setMaxValue(int v)
       
   954 
       
   955     Use setMaximum() instead.
       
   956 */
       
   957 
       
   958 /*! \fn void QAbstractSlider::setLineStep(int v)
       
   959 
       
   960     Use setSingleStep() instead.
       
   961 */
       
   962 
       
   963 /*! \fn void QAbstractSlider::addPage()
       
   964 
       
   965     Use triggerAction(QAbstractSlider::SliderPageStepAdd) instead.
       
   966 */
       
   967 
       
   968 /*! \fn void QAbstractSlider::subtractPage()
       
   969 
       
   970     Use triggerAction(QAbstractSlider::SliderPageStepSub) instead.
       
   971 */
       
   972 
       
   973 /*! \fn void QAbstractSlider::addLine()
       
   974 
       
   975     Use triggerAction(QAbstractSlider::SliderSingleStepAdd) instead.
       
   976 */
       
   977 
       
   978 /*! \fn void QAbstractSlider::subtractLine()
       
   979 
       
   980     Use triggerAction(QAbstractSlider::SliderSingleStepSub) instead.
       
   981 */
       
   982 
       
   983 /*! \fn void QAbstractSlider::setSteps(int single, int page)
       
   984 
       
   985     Use setSingleStep(\a single) followed by setPageStep(\a page)
       
   986     instead.
       
   987 */
       
   988 
       
   989 QT_END_NAMESPACE