src/gui/widgets/qabstractspinbox.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    63 
    63 
    64 #if defined(Q_WS_X11)
    64 #if defined(Q_WS_X11)
    65 #include <limits.h>
    65 #include <limits.h>
    66 #endif
    66 #endif
    67 
    67 
       
    68 #if defined(Q_OS_SYMBIAN)
       
    69 #include <W32STD.H>
       
    70 #include <private/qt_s60_p.h>
       
    71 #endif
       
    72 
    68 //#define QABSTRACTSPINBOX_QSBDEBUG
    73 //#define QABSTRACTSPINBOX_QSBDEBUG
    69 #ifdef QABSTRACTSPINBOX_QSBDEBUG
    74 #ifdef QABSTRACTSPINBOX_QSBDEBUG
    70 #  define QASBDEBUG qDebug
    75 #  define QASBDEBUG qDebug
    71 #else
    76 #else
    72 #  define QASBDEBUG if (false) qDebug
    77 #  define QASBDEBUG if (false) qDebug
   937 
   942 
   938     if (!event->text().isEmpty() && d->edit->cursorPosition() < d->prefix.size())
   943     if (!event->text().isEmpty() && d->edit->cursorPosition() < d->prefix.size())
   939         d->edit->setCursorPosition(d->prefix.size());
   944         d->edit->setCursorPosition(d->prefix.size());
   940 
   945 
   941     int steps = 1;
   946     int steps = 1;
       
   947     bool isPgUpOrDown = false;
   942     switch (event->key()) {
   948     switch (event->key()) {
   943     case Qt::Key_PageUp:
   949     case Qt::Key_PageUp:
   944     case Qt::Key_PageDown:
   950     case Qt::Key_PageDown:
   945         steps *= 10;
   951         steps *= 10;
       
   952         isPgUpOrDown = true;
   946     case Qt::Key_Up:
   953     case Qt::Key_Up:
   947     case Qt::Key_Down: {
   954     case Qt::Key_Down: {
   948 #ifdef QT_KEYPAD_NAVIGATION
   955 #ifdef QT_KEYPAD_NAVIGATION
   949         if (QApplication::keypadNavigationEnabled()) {
   956         if (QApplication::keypadNavigationEnabled()) {
   950             // Reserve up/down for nav - use left/right for edit.
   957             // Reserve up/down for nav - use left/right for edit.
   962         if (!up)
   969         if (!up)
   963             steps *= -1;
   970             steps *= -1;
   964         if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
   971         if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
   965             d->buttonState = (Keyboard | (up ? Up : Down));
   972             d->buttonState = (Keyboard | (up ? Up : Down));
   966         }
   973         }
   967         stepBy(steps);
   974         if (d->spinClickTimerId == -1)
       
   975             stepBy(steps);
       
   976         if(event->isAutoRepeat() && !isPgUpOrDown) {
       
   977             if(d->spinClickThresholdTimerId == -1 && d->spinClickTimerId == -1) {
       
   978                 d->updateState(up, true);
       
   979             }
       
   980         }
   968 #ifndef QT_NO_ACCESSIBILITY
   981 #ifndef QT_NO_ACCESSIBILITY
   969         QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
   982         QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
   970 #endif
   983 #endif
   971         return;
   984         return;
   972     }
   985     }
  1059 
  1072 
  1060 void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event)
  1073 void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event)
  1061 {
  1074 {
  1062     Q_D(QAbstractSpinBox);
  1075     Q_D(QAbstractSpinBox);
  1063 
  1076 
  1064     if (d->buttonState & Keyboard && !event->isAutoRepeat()
  1077     if (d->buttonState & Keyboard && !event->isAutoRepeat())  {
  1065         && style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
       
  1066         d->reset();
  1078         d->reset();
  1067     } else {
  1079     } else {
  1068         d->edit->event(event);
  1080         d->edit->event(event);
  1069     }
  1081     }
  1070 }
  1082 }
  1146     if (d->pendingEmit)
  1158     if (d->pendingEmit)
  1147         d->interpret(EmitIfChanged);
  1159         d->interpret(EmitIfChanged);
  1148     QWidget::hideEvent(event);
  1160     QWidget::hideEvent(event);
  1149 }
  1161 }
  1150 
  1162 
       
  1163 
       
  1164 /*!
       
  1165     \internal
       
  1166 
       
  1167     Used when acceleration is turned on. We need to get the
       
  1168     keyboard auto repeat rate from OS. This value is used as
       
  1169     argument when starting acceleration related timers.
       
  1170 
       
  1171     Every platform should, either, use native calls to obtain
       
  1172     the value or hard code some reasonable rate.
       
  1173 
       
  1174     Remember that time value should be given in msecs.
       
  1175 */
       
  1176 static int getKeyboardAutoRepeatRate() {
       
  1177     int ret = 30;
       
  1178 #if defined(Q_OS_SYMBIAN)
       
  1179     TTimeIntervalMicroSeconds32 initialTime;
       
  1180     TTimeIntervalMicroSeconds32 time;
       
  1181     S60->wsSession().GetKeyboardRepeatRate(initialTime, time);
       
  1182     ret = time.Int() / 1000; // msecs
       
  1183 #elif defined(Q_OS_WIN) and !defined(Q_OS_WINCE)
       
  1184     DWORD time;
       
  1185     if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0) != FALSE)
       
  1186         ret = static_cast<int>(1000 / static_cast<int>(time)); // msecs
       
  1187 #endif
       
  1188     return ret; // msecs
       
  1189 }
       
  1190 
  1151 /*!
  1191 /*!
  1152     \reimp
  1192     \reimp
  1153 */
  1193 */
  1154 
  1194 
  1155 void QAbstractSpinBox::timerEvent(QTimerEvent *event)
  1195 void QAbstractSpinBox::timerEvent(QTimerEvent *event)
  1158 
  1198 
  1159     bool doStep = false;
  1199     bool doStep = false;
  1160     if (event->timerId() == d->spinClickThresholdTimerId) {
  1200     if (event->timerId() == d->spinClickThresholdTimerId) {
  1161         killTimer(d->spinClickThresholdTimerId);
  1201         killTimer(d->spinClickThresholdTimerId);
  1162         d->spinClickThresholdTimerId = -1;
  1202         d->spinClickThresholdTimerId = -1;
  1163         d->spinClickTimerId = startTimer(d->spinClickTimerInterval);
  1203         d->effectiveSpinRepeatRate = d->buttonState & Keyboard
       
  1204                                      ? getKeyboardAutoRepeatRate()
       
  1205                                      : d->spinClickTimerInterval;
       
  1206         d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate);
  1164         doStep = true;
  1207         doStep = true;
  1165     } else if (event->timerId() == d->spinClickTimerId) {
  1208     } else if (event->timerId() == d->spinClickTimerId) {
  1166         if (d->accelerate) {
  1209         if (d->accelerate) {
  1167             d->acceleration = d->acceleration + (int)(d->spinClickTimerInterval * 0.05);
  1210             d->acceleration = d->acceleration + (int)(d->effectiveSpinRepeatRate * 0.05);
  1168             if (d->spinClickTimerInterval - d->acceleration >= 10) {
  1211             if (d->effectiveSpinRepeatRate - d->acceleration >= 10) {
  1169                 killTimer(d->spinClickTimerId);
  1212                 killTimer(d->spinClickTimerId);
  1170                 d->spinClickTimerId = startTimer(d->spinClickTimerInterval - d->acceleration);
  1213                 d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate - d->acceleration);
  1171             }
  1214             }
  1172         }
  1215         }
  1173         doStep = true;
  1216         doStep = true;
  1174     }
  1217     }
  1175 
  1218 
  1306 */
  1349 */
  1307 
  1350 
  1308 QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
  1351 QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
  1309     : edit(0), type(QVariant::Invalid), spinClickTimerId(-1),
  1352     : edit(0), type(QVariant::Invalid), spinClickTimerId(-1),
  1310       spinClickTimerInterval(100), spinClickThresholdTimerId(-1), spinClickThresholdTimerInterval(-1),
  1353       spinClickTimerInterval(100), spinClickThresholdTimerId(-1), spinClickThresholdTimerInterval(-1),
  1311       buttonState(None), cachedText(QLatin1String("\x01")), cachedState(QValidator::Invalid),
  1354       effectiveSpinRepeatRate(1), buttonState(None), cachedText(QLatin1String("\x01")),
  1312       pendingEmit(false), readOnly(false), wrapping(false),
  1355       cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
  1313       ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
  1356       ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
  1314       cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
  1357       cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
  1315       acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0)
  1358       acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0)
  1316 {
  1359 {
  1317 }
  1360 }
  1552     \internal
  1595     \internal
  1553 
  1596 
  1554     Updates the state of the spinbox.
  1597     Updates the state of the spinbox.
  1555 */
  1598 */
  1556 
  1599 
  1557 void QAbstractSpinBoxPrivate::updateState(bool up)
  1600 void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false */)
  1558 {
  1601 {
  1559     Q_Q(QAbstractSpinBox);
  1602     Q_Q(QAbstractSpinBox);
  1560     if ((up && (buttonState & Up)) || (!up && (buttonState & Down)))
  1603     if ((up && (buttonState & Up)) || (!up && (buttonState & Down)))
  1561         return;
  1604         return;
  1562     reset();
  1605     reset();
  1563     if (q && (q->stepEnabled() & (up ? QAbstractSpinBox::StepUpEnabled
  1606     if (q && (q->stepEnabled() & (up ? QAbstractSpinBox::StepUpEnabled
  1564                                   : QAbstractSpinBox::StepDownEnabled))) {
  1607                                   : QAbstractSpinBox::StepDownEnabled))) {
  1565         spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
  1608         spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
  1566         buttonState = (up ? (Mouse | Up) : (Mouse | Down));
  1609         buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
  1567         q->stepBy(up ? 1 : -1);
  1610         q->stepBy(up ? 1 : -1);
  1568 #ifndef QT_NO_ACCESSIBILITY
  1611 #ifndef QT_NO_ACCESSIBILITY
  1569         QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
  1612         QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
  1570 #endif
  1613 #endif
  1571     }
  1614     }
  1854 QValidator::State QSpinBoxValidator::validate(QString &input, int &pos) const
  1897 QValidator::State QSpinBoxValidator::validate(QString &input, int &pos) const
  1855 {
  1898 {
  1856     if (dptr->specialValueText.size() > 0 && input == dptr->specialValueText)
  1899     if (dptr->specialValueText.size() > 0 && input == dptr->specialValueText)
  1857         return QValidator::Acceptable;
  1900         return QValidator::Acceptable;
  1858 
  1901 
  1859     if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix))
  1902     if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) {
  1860         input.prepend(dptr->prefix);
  1903         input.prepend(dptr->prefix);
       
  1904         pos += dptr->prefix.length();
       
  1905     }
  1861 
  1906 
  1862     if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix))
  1907     if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix))
  1863         input.append(dptr->suffix);
  1908         input.append(dptr->suffix);
  1864 
  1909 
  1865     return qptr->validate(input, pos);
  1910     return qptr->validate(input, pos);