544QAbstractSpinBox::StepEnabled QAbstractSpinBox::stepEnabled()
const
546 Q_D(
const QAbstractSpinBox);
547 if (d->readOnly || d->type == QMetaType::UnknownType)
550 return StepEnabled(StepUpEnabled | StepDownEnabled);
551 StepEnabled ret = StepNone;
552 if (QAbstractSpinBoxPrivate::variantCompare(d->value, d->maximum) < 0) {
553 ret |= StepUpEnabled;
555 if (QAbstractSpinBoxPrivate::variantCompare(d->value, d->minimum) > 0) {
556 ret |= StepDownEnabled;
619void QAbstractSpinBox::stepBy(
int steps)
621 Q_D(QAbstractSpinBox);
623 const QVariant old = d->value;
624 QString tmp = d->edit->displayText();
625 int cursorPos = d->edit->cursorPosition();
626 bool dontstep =
false;
627 EmitPolicy e = EmitIfChanged;
628 if (d->pendingEmit) {
629 dontstep = validate(tmp, cursorPos) != QValidator::Acceptable;
631 d->interpret(NeverEmit);
637 switch (d->stepType) {
638 case QAbstractSpinBox::StepType::AdaptiveDecimalStepType:
639 singleStep = d->calculateAdaptiveDecimalStep(steps);
642 singleStep = d->singleStep;
644 const auto newVal = d->bound(d->value + (singleStep * steps), old, steps);
645 d->setValue(d->roundValue(newVal), e);
646 }
else if (e == AlwaysEmit) {
647 d->emitSignals(e, old);
649 if (style()->styleHint(QStyle::SH_SpinBox_SelectOnStep,
nullptr,
this,
nullptr))
677void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit)
679 Q_D(QAbstractSpinBox);
686 if (lineEdit == d->edit)
691 setProperty(
"_q_spinbox_lineedit", QVariant::fromValue<QWidget *>(d->edit));
692 if (!d->edit->validator())
693 d->edit->setValidator(d->validator);
695 if (d->edit->parent() !=
this)
696 d->edit->setParent(
this);
698 d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame,
nullptr,
this));
699 d->edit->setFocusProxy(
this);
700 d->edit->setAcceptDrops(
false);
702 if (d->type != QMetaType::UnknownType) {
703 QObjectPrivate::connect(d->edit, &QLineEdit::textChanged,
704 d, &QAbstractSpinBoxPrivate::editorTextChanged);
705 QObjectPrivate::connect(d->edit, &QLineEdit::cursorPositionChanged,
706 d, &QAbstractSpinBoxPrivate::editorCursorPositionChanged);
707 connect(d->edit, &QLineEdit::cursorPositionChanged,
708 this, [
this]() { updateMicroFocus(); });
709 connect(d->edit->d_func()->control, &QWidgetLineControl::updateMicroFocus,
710 this, [
this]() { updateMicroFocus(); });
712 d->updateEditFieldGeometry();
713 d->edit->setContextMenuPolicy(Qt::NoContextMenu);
714 d->edit->d_func()->control->setAccessibleObject(
this);
759bool QAbstractSpinBox::event(QEvent *event)
761 Q_D(QAbstractSpinBox);
762 switch (event->type()) {
763 case QEvent::FontChange:
764 case QEvent::StyleChange:
765 d->cachedSizeHint = d->cachedMinimumSizeHint = QSize();
767 case QEvent::ApplicationLayoutDirectionChange:
768 case QEvent::LayoutDirectionChange:
769 d->updateEditFieldGeometry();
771 case QEvent::HoverEnter:
772 case QEvent::HoverLeave:
773 case QEvent::HoverMove:
774 d->updateHoverControl(
static_cast<
const QHoverEvent *>(event)->position().toPoint());
776 case QEvent::ShortcutOverride:
777 if (d->edit->event(event))
780#ifdef QT_KEYPAD_NAVIGATION
781 case QEvent::EnterEditFocus:
782 case QEvent::LeaveEditFocus:
783 if (QApplicationPrivate::keypadNavigationEnabled()) {
784 const bool b = d->edit->event(event);
785 d->edit->setSelection(d->edit->displayText().size() - d->suffix.size(),0);
786 if (event->type() == QEvent::LeaveEditFocus)
787 emit editingFinished();
793 case QEvent::InputMethod:
794 return d->edit->event(event);
798 return QWidget::event(event);
821void QAbstractSpinBox::changeEvent(QEvent *event)
823 Q_D(QAbstractSpinBox);
825 switch (event->type()) {
826 case QEvent::StyleChange:
827 d->spinClickTimerInterval = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate,
nullptr,
this);
828 d->spinClickThresholdTimerInterval =
829 style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold,
nullptr,
this);
831 d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame,
nullptr,
this));
832 d->stepModifier =
static_cast<Qt::KeyboardModifier>(style()->styleHint(QStyle::SH_SpinBox_StepModifier,
nullptr,
this));
834 d->updateEditFieldGeometry();
836 case QEvent::LocaleChange:
839 case QEvent::EnabledChange:
844 case QEvent::ActivationChange:
845 if (!isActiveWindow()){
848 d->interpret(EmitIfChanged);
854 QWidget::changeEvent(event);
874QSize QAbstractSpinBox::sizeHint()
const
876 Q_D(
const QAbstractSpinBox);
877 if (d->cachedSizeHint.isEmpty()) {
880 const QFontMetrics fm(fontMetrics());
881 int h = d->edit->sizeHint().height();
884 QString fixedContent = d->prefix + d->suffix + u' ';
885 s = d->textFromValue(d->minimum);
888 w = qMax(w, fm.horizontalAdvance(s));
889 s = d->textFromValue(d->maximum);
892 w = qMax(w, fm.horizontalAdvance(s));
894 if (d->specialValueText.size()) {
895 s = d->specialValueText;
896 w = qMax(w, fm.horizontalAdvance(s));
900 QStyleOptionSpinBox opt;
901 initStyleOption(&opt);
903 d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint,
this);
905 return d->cachedSizeHint;
912QSize QAbstractSpinBox::minimumSizeHint()
const
914 Q_D(
const QAbstractSpinBox);
915 if (d->cachedMinimumSizeHint.isEmpty()) {
919 const QFontMetrics fm(fontMetrics());
920 int h = d->edit->minimumSizeHint().height();
924 QString fixedContent = d->prefix + u' ';
925 s = d->textFromValue(d->minimum);
928 w = qMax(w, fm.horizontalAdvance(s));
929 s = d->textFromValue(d->maximum);
932 w = qMax(w, fm.horizontalAdvance(s));
934 if (d->specialValueText.size()) {
935 s = d->specialValueText;
936 w = qMax(w, fm.horizontalAdvance(s));
940 QStyleOptionSpinBox opt;
941 initStyleOption(&opt);
944 d->cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint,
this);
946 return d->cachedMinimumSizeHint;
985void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
987 Q_D(QAbstractSpinBox);
989 d->keyboardModifiers = event->modifiers();
991 if (!event->text().isEmpty() && d->edit->cursorPosition() < d->prefix.size())
992 d->edit->setCursorPosition(d->prefix.size());
995 bool isPgUpOrDown =
false;
996 switch (event->key()) {
998 case Qt::Key_PageDown:
1000 isPgUpOrDown =
true;
1003 case Qt::Key_Down: {
1004#ifdef QT_KEYPAD_NAVIGATION
1005 if (QApplicationPrivate::keypadNavigationEnabled()) {
1007 if (!hasEditFocus() && (event->key() == Qt::Key_Up
1008 || event->key() == Qt::Key_Down)) {
1015 const bool up = (event->key() == Qt::Key_PageUp || event->key() == Qt::Key_Up);
1016 if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled)))
1018 if (!isPgUpOrDown && (event->modifiers() & d->stepModifier))
1022 if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton,
nullptr,
this)) {
1023 d->buttonState = (Keyboard | (up ? Up : Down));
1025 if (!d->spinClickTimer.isActive())
1027 if (event->isAutoRepeat() && !isPgUpOrDown) {
1028 if (!d->spinClickThresholdTimer.isActive() && !d->spinClickTimer.isActive()) {
1029 d->updateState(up,
true);
1032#if QT_CONFIG(accessibility)
1033 QAccessibleValueChangeEvent event(
this, d->value);
1034 QAccessible::updateAccessibility(&event);
1038#ifdef QT_KEYPAD_NAVIGATION
1041 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1047 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1054 case Qt::Key_Return:
1055 d->edit->d_func()->control->clearUndo();
1056 d->interpret(d->keyboardTracking ? AlwaysEmit : EmitIfChanged);
1059 emit editingFinished();
1060 emit returnPressed();
1061 emit d->edit->returnPressed();
1064#ifdef QT_KEYPAD_NAVIGATION
1065 case Qt::Key_Select:
1066 if (QApplicationPrivate::keypadNavigationEnabled()) {
1068 setEditFocus(!hasEditFocus());
1074 if (event->modifiers() & Qt::ControlModifier
1075 && QGuiApplication::platformName() ==
"xcb"_L1) {
1085 if (event->modifiers() & Qt::ShiftModifier) {
1086 int currentPos = d->edit->cursorPosition();
1087 const QString text = d->edit->displayText();
1088 if (event->key() == Qt::Key_End) {
1089 if ((currentPos == 0 && !d->prefix.isEmpty()) || text.size() - d->suffix.size() <= currentPos) {
1092 d->edit->setSelection(currentPos, text.size() - d->suffix.size() - currentPos);
1095 if ((currentPos == text.size() && !d->suffix.isEmpty()) || currentPos <= d->prefix.size()) {
1098 d->edit->setSelection(currentPos, d->prefix.size() - currentPos);
1107#ifndef QT_NO_SHORTCUT
1108 if (event == QKeySequence::SelectAll) {
1117 d->edit->event(event);
1118 if (!d->edit->text().isEmpty())
1121 d->ignoreUpdateEdit =
true;
1240void QAbstractSpinBox::timerEvent(QTimerEvent *event)
1242 Q_D(QAbstractSpinBox);
1244 bool doStep =
false;
1245 if (event->id() == d->spinClickThresholdTimer.id()) {
1246 d->spinClickThresholdTimer.stop();
1247 d->effectiveSpinRepeatRate = d->buttonState & Keyboard
1248 ? QGuiApplication::styleHints()->keyboardAutoRepeatRateF()
1249 : d->spinClickTimerInterval;
1250 d->spinClickTimer.start(d->effectiveSpinRepeatRate,
this);
1252 }
else if (event->id() == d->spinClickTimer.id()) {
1253 if (d->accelerate) {
1254 d->acceleration = d->acceleration + (
int)(d->effectiveSpinRepeatRate * 0.05);
1255 auto interval =
int(d->effectiveSpinRepeatRate - d->acceleration) * 1ms;
1256 if (interval >= 10ms)
1257 d->spinClickTimer.start(interval,
this);
1263 const bool increaseStepRate = d->keyboardModifiers & d->stepModifier;
1264 const StepEnabled st = stepEnabled();
1265 if (d->buttonState & Up) {
1266 if (!(st & StepUpEnabled)) {
1269 stepBy(increaseStepRate ? 10 : 1);
1271 }
else if (d->buttonState & Down) {
1272 if (!(st & StepDownEnabled)) {
1275 stepBy(increaseStepRate ? -10 : -1);
1280 QWidget::timerEvent(event);
1342void QAbstractSpinBox::mouseMoveEvent(QMouseEvent *event)
1344 Q_D(QAbstractSpinBox);
1346 d->keyboardModifiers = event->modifiers();
1347 d->updateHoverControl(event->position().toPoint());
1350 if (d->spinClickTimer.isActive() && d->buttonSymbols != NoButtons) {
1351 const StepEnabled se = stepEnabled();
1352 if ((se & StepUpEnabled) && d->hoverControl == QStyle::SC_SpinBoxUp)
1353 d->updateState(
true);
1354 else if ((se & StepDownEnabled) && d->hoverControl == QStyle::SC_SpinBoxDown)
1355 d->updateState(
false);
1366void QAbstractSpinBox::mousePressEvent(QMouseEvent *event)
1368 Q_D(QAbstractSpinBox);
1370 d->keyboardModifiers = event->modifiers();
1371 if (event->button() != Qt::LeftButton || d->buttonState != None) {
1376 d->updateHoverControl(event->position().toPoint());
1379 const StepEnabled se = (d->buttonSymbols == NoButtons) ? StepEnabled(StepNone) : stepEnabled();
1380 if ((se & StepUpEnabled) && d->hoverControl == QStyle::SC_SpinBoxUp) {
1381 d->updateState(
true);
1382 }
else if ((se & StepDownEnabled) && d->hoverControl == QStyle::SC_SpinBoxDown) {
1383 d->updateState(
false);
1429bool QAbstractSpinBoxPrivate::updateHoverControl(
const QPoint &pos)
1431 Q_Q(QAbstractSpinBox);
1432 QRect lastHoverRect = hoverRect;
1433 QStyle::SubControl lastHoverControl = hoverControl;
1434 bool doesHover = q->testAttribute(Qt::WA_Hover);
1435 if (lastHoverControl != newHoverControl(pos) && doesHover) {
1436 q->update(lastHoverRect);
1437 q->update(hoverRect);
1448QStyle::SubControl QAbstractSpinBoxPrivate::newHoverControl(
const QPoint &pos)
1450 Q_Q(QAbstractSpinBox);
1452 QStyleOptionSpinBox opt;
1453 q->initStyleOption(&opt);
1454 opt.subControls = QStyle::SC_All;
1455 hoverControl = q->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, pos, q);
1456 hoverRect = q->style()->subControlRect(QStyle::CC_SpinBox, &opt, hoverControl, q);
1457 return hoverControl;
1465QString QAbstractSpinBoxPrivate::stripped(
const QString &t,
int *pos)
const
1467 QStringView text(t);
1468 if (specialValueText.size() == 0 || text != specialValueText) {
1470 int size = text.size();
1471 bool changed =
false;
1472 if (prefix.size() && text.startsWith(prefix)) {
1473 from += prefix.size();
1477 if (suffix.size() && text.endsWith(suffix)) {
1478 size -= suffix.size();
1482 text = text.mid(from, size);
1485 const int s = text.size();
1486 text = text.trimmed();
1488 (*pos) -= (s - text.size());
1489 return text.toString();
1493void QAbstractSpinBoxPrivate::updateEditFieldGeometry()
1495 Q_Q(QAbstractSpinBox);
1496 QStyleOptionSpinBox opt;
1497 q->initStyleOption(&opt);
1498 opt.subControls = QStyle::SC_SpinBoxEditField;
1499 edit->setGeometry(q->style()->subControlRect(QStyle::CC_SpinBox, &opt,
1500 QStyle::SC_SpinBoxEditField, q));
1528void QAbstractSpinBoxPrivate::editorTextChanged(
const QString &t)
1530 Q_Q(QAbstractSpinBox);
1532 if (keyboardTracking) {
1534 int pos = edit->cursorPosition();
1535 QValidator::State state = q->validate(tmp, pos);
1536 if (state == QValidator::Acceptable) {
1537 const QVariant v = valueFromText(tmp);
1538 setValue(v, EmitIfChanged, tmp != t);
1539 pendingEmit =
false;
1558void QAbstractSpinBoxPrivate::editorCursorPositionChanged(
int oldpos,
int newpos)
1560 if (!edit->hasSelectedText() && !ignoreCursorPositionChanged && !specialValue()) {
1561 ignoreCursorPositionChanged =
true;
1563 bool allowSelection =
true;
1565 if (newpos < prefix.size() && newpos != 0) {
1567 allowSelection =
false;
1568 pos = prefix.size();
1572 }
else if (newpos > edit->text().size() - suffix.size()
1573 && newpos != edit->text().size()) {
1574 if (oldpos == edit->text().size()) {
1575 pos = edit->text().size() - suffix.size();
1576 allowSelection =
false;
1578 pos = edit->text().size();
1582 const int selSize = edit->selectionStart() >= 0 && allowSelection
1583 ? (edit->selectedText().size()
1584 * (newpos < pos ? -1 : 1)) - newpos + pos
1587 const QSignalBlocker blocker(edit);
1589 edit->setSelection(pos - selSize, selSize);
1591 edit->setCursorPosition(pos);
1594 ignoreCursorPositionChanged =
false;
1604void QAbstractSpinBoxPrivate::init()
1606 Q_Q(QAbstractSpinBox);
1608 q->setLineEdit(
new QLineEdit(q));
1609 edit->setObjectName(
"qt_spinbox_lineedit"_L1);
1610 validator =
new QSpinBoxValidator(q,
this);
1611 edit->setValidator(validator);
1613 QStyleOptionSpinBox opt;
1616 q->initStyleOption(&opt);
1617 spinClickTimerInterval = q->style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, &opt, q);
1618 spinClickThresholdTimerInterval = q->style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, &opt, q);
1619 q->setFocusPolicy(Qt::WheelFocus);
1620 q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::SpinBox));
1621 q->setAttribute(Qt::WA_InputMethodEnabled);
1623 q->setAttribute(Qt::WA_MacShowFocusRect);
1652void QAbstractSpinBoxPrivate::updateState(
bool up,
bool fromKeyboard )
1654 Q_Q(QAbstractSpinBox);
1655 if ((up && (buttonState & Up)) || (!up && (buttonState & Down)))
1658 if (q && (q->stepEnabled() & (up ? QAbstractSpinBox::StepUpEnabled
1659 : QAbstractSpinBox::StepDownEnabled))) {
1660 buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
1661 int steps = up ? 1 : -1;
1662 if (keyboardModifiers & stepModifier)
1665 spinClickThresholdTimer.start(spinClickThresholdTimerInterval * 1ms, q);
1666#if QT_CONFIG(accessibility)
1667 QAccessibleValueChangeEvent event(q, value);
1668 QAccessible::updateAccessibility(&event);
1681void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option)
const
1686 Q_D(
const QAbstractSpinBox);
1687 option->initFrom(
this);
1688 option->activeSubControls = QStyle::SC_None;
1689 option->buttonSymbols = d->buttonSymbols;
1690 option->subControls = QStyle::SC_SpinBoxEditField;
1691 if (style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame,
nullptr,
this))
1692 option->subControls |= QStyle::SC_SpinBoxFrame;
1693 if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
1694 option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
1695 if (d->buttonState & Up) {
1696 option->activeSubControls = QStyle::SC_SpinBoxUp;
1697 }
else if (d->buttonState & Down) {
1698 option->activeSubControls = QStyle::SC_SpinBoxDown;
1702 if (d->buttonState) {
1703 option->state |= QStyle::State_Sunken;
1705 option->activeSubControls = d->hoverControl;
1708 option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds,
nullptr,
this)
1710 : (QAbstractSpinBox::StepDownEnabled|QAbstractSpinBox::StepUpEnabled);
1712 option->frame = d->frame;
1723QVariant QAbstractSpinBoxPrivate::bound(
const QVariant &val,
const QVariant &old,
int steps)
const
1726 if (!wrapping || steps == 0 || old.isNull()) {
1727 if (variantCompare(v, minimum) < 0) {
1728 v = wrapping ? maximum : minimum;
1730 if (variantCompare(v, maximum) > 0) {
1731 v = wrapping ? minimum : maximum;
1734 const bool wasMin = old == minimum;
1735 const bool wasMax = old == maximum;
1736 const int oldcmp = variantCompare(v, old);
1737 const int maxcmp = variantCompare(v, maximum);
1738 const int mincmp = variantCompare(v, minimum);
1739 const bool wrapped = (oldcmp > 0 && steps < 0) || (oldcmp < 0 && steps > 0);
1741 v = ((wasMax && !wrapped && steps > 0) || (steps < 0 && !wasMin && wrapped))
1742 ? minimum : maximum;
1743 }
else if (wrapped && (maxcmp > 0 || mincmp < 0)) {
1744 v = ((wasMax && steps > 0) || (!wasMin && steps < 0)) ? minimum : maximum;
1745 }
else if (mincmp < 0) {
1746 v = (!wasMax && !wasMin ? minimum : maximum);
1789void QAbstractSpinBoxPrivate::updateEdit()
1791 Q_Q(QAbstractSpinBox);
1792 if (type == QMetaType::UnknownType)
1794 const QString newText = specialValue() ? specialValueText : prefix + textFromValue(value) + suffix;
1795 if (newText == edit->displayText() || cleared)
1798 const bool empty = edit->text().isEmpty();
1799 int cursor = edit->cursorPosition();
1800 int selsize = edit->selectedText().size();
1801 const QSignalBlocker blocker(edit);
1802 edit->setText(newText);
1804 if (!specialValue()) {
1805 cursor = qBound(prefix.size(), cursor, edit->displayText().size() - suffix.size());
1808 edit->setSelection(cursor, selsize);
1810 edit->setCursorPosition(empty ? prefix.size() : cursor);
1822void QAbstractSpinBoxPrivate::setRange(
const QVariant &min,
const QVariant &max)
1824 Q_Q(QAbstractSpinBox);
1828 maximum = (variantCompare(min, max) < 0 ? max : min);
1829 cachedSizeHint = QSize();
1830 cachedMinimumSizeHint = QSize();
1833 if (!(bound(value) == value)) {
1834 setValue(bound(value), EmitIfChanged);
1835 }
else if (value == minimum && !specialValueText.isEmpty()) {
1839 q->updateGeometry();
1897void QAbstractSpinBoxPrivate::interpret(EmitPolicy ep)
1899 Q_Q(QAbstractSpinBox);
1900 if (type == QMetaType::UnknownType || cleared)
1903 QVariant v = getZeroVariant();
1904 bool doInterpret =
true;
1905 QString tmp = edit->displayText();
1906 int pos = edit->cursorPosition();
1907 const int oldpos = pos;
1909 if (q->validate(tmp, pos) != QValidator::Acceptable) {
1910 const QString copy = tmp;
1912 qDebug(lcWidgetAbstractSpinBox)
1913 <<
"QAbstractSpinBoxPrivate::interpret() text '"
1914 << edit->displayText()
1915 <<
"' >> '" << copy <<
'\''
1916 <<
"' >> '" << tmp <<
'\'';
1918 doInterpret = tmp != copy && (q->validate(tmp, pos) == QValidator::Acceptable);
1920 v = (correctionMode == QAbstractSpinBox::CorrectToNearestValue
1921 ? variantBound(minimum, v, maximum) : value);
1925 v = valueFromText(tmp);
1928 setValue(v, ep,
true);
1930 edit->setCursorPosition(pos);
1966QValidator::State QSpinBoxValidator::validate(QString &input,
int &pos)
const
1968 if (dptr->specialValueText.size() > 0 && input == dptr->specialValueText)
1969 return QValidator::Acceptable;
1971 if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) {
1972 input.prepend(dptr->prefix);
1973 pos += dptr->prefix.size();
1976 if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix))
1977 input.append(dptr->suffix);
1979 return qptr->validate(input, pos);
2001 if (Q_UNLIKELY(arg1.userType() != arg2.userType()))
2002 qWarning(
"QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
2003 arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
2004 switch (arg1.userType()) {
2005 case QMetaType::Int: {
2006 const int int1 = arg1.toInt();
2007 const int int2 = arg2.toInt();
2008 if (int1 > 0 && (int2 >= INT_MAX - int1)) {
2010 ret = QVariant(INT_MAX);
2011 }
else if (int1 < 0 && (int2 <= INT_MIN - int1)) {
2013 ret = QVariant(INT_MIN);
2015 ret = QVariant(int1 + int2);
2019 case QMetaType::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble());
break;
2020#if QT_CONFIG(datetimeparser)
2021 case QMetaType::QDateTime: {
2022 QDateTime a2 = arg2.toDateTime();
2023 QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATE_MIN.daysTo(a2.date()));
2024 a1.setTime(a1.time().addMSecs(a2.time().msecsSinceStartOfDay()));
2043 if (Q_UNLIKELY(arg1.userType() != arg2.userType()))
2044 qWarning(
"QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
2045 arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
2046 switch (arg1.userType()) {
2047 case QMetaType::Int: ret = QVariant(arg1.toInt() - arg2.toInt());
break;
2048 case QMetaType::Double: ret = QVariant(arg1.toDouble() - arg2.toDouble());
break;
2049 case QMetaType::QDateTime: {
2050 QDateTime a1 = arg1.toDateTime();
2051 QDateTime a2 = arg2.toDateTime();
2052 int days = a2.daysTo(a1);
2053 int secs = a2.secsTo(a1);
2054 int msecs = qMax(0, a1.time().msec() - a2.time().msec());
2055 if (days < 0 || secs < 0 || msecs < 0) {
2058 QDateTime dt = a2.addDays(days).addSecs(secs);
2060 dt.setTime(dt.time().addMSecs(msecs));
2079 switch (arg1.userType()) {
2080 case QMetaType::Int:
2081 ret =
static_cast<
int>(qBound<
double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX));
2083 case QMetaType::Double: ret = QVariant(arg1.toDouble() * multiplier);
break;
2084#if QT_CONFIG(datetimeparser)
2085 case QMetaType::QDateTime: {
2086 double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
2087 const qint64 daysInt = qint64(days);
2089 qint64 msecs = qint64(arg1.toDateTime().time().msecsSinceStartOfDay() * multiplier
2090 + days * (24 * 3600 * 1000));
2091 ret = QDATETIMEEDIT_DATE_MIN.addDays(daysInt).startOfDay().addMSecs(msecs);
2095 default: ret = arg1;
break;
2103double operator/(
const QVariant &arg1,
const QVariant &arg2)
2108 switch (arg1.userType()) {
2109 case QMetaType::Int:
2110 a1 = (
double)arg1.toInt();
2111 a2 = (
double)arg2.toInt();
2113 case QMetaType::Double:
2114 a1 = arg1.toDouble();
2115 a2 = arg2.toDouble();
2117#if QT_CONFIG(datetimeparser)
2118 case QMetaType::QDateTime:
2119 a1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate());
2120 a2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate());
2121 a1 += arg1.toDateTime().time().msecsSinceStartOfDay() / (36e5 * 24);
2122 a2 += arg2.toDateTime().time().msecsSinceStartOfDay() / (36e5 * 24);
2128 return (a1 != 0 && a2 != 0) ? (a1 / a2) : 0.0;
2131int QAbstractSpinBoxPrivate::variantCompare(
const QVariant &arg1,
const QVariant &arg2)
2133 switch (arg2.userType()) {
2134 case QMetaType::QDate:
2135 Q_ASSERT_X(arg1.userType() == QMetaType::QDate,
"QAbstractSpinBoxPrivate::variantCompare",
2136 qPrintable(QString::fromLatin1(
"Internal error 1 (%1)").
2137 arg(QString::fromLatin1(arg1.typeName()))));
2138 if (arg1.toDate() == arg2.toDate()) {
2140 }
else if (arg1.toDate() < arg2.toDate()) {
2145 case QMetaType::QTime:
2146 Q_ASSERT_X(arg1.userType() == QMetaType::QTime,
"QAbstractSpinBoxPrivate::variantCompare",
2147 qPrintable(QString::fromLatin1(
"Internal error 2 (%1)").
2148 arg(QString::fromLatin1(arg1.typeName()))));
2149 if (arg1.toTime() == arg2.toTime()) {
2151 }
else if (arg1.toTime() < arg2.toTime()) {
2158 case QMetaType::QDateTime:
2159 if (arg1.toDateTime() == arg2.toDateTime()) {
2161 }
else if (arg1.toDateTime() < arg2.toDateTime()) {
2166 case QMetaType::Int:
2167 if (arg1.toInt() == arg2.toInt()) {
2169 }
else if (arg1.toInt() < arg2.toInt()) {
2174 case QMetaType::Double:
2175 if (arg1.toDouble() == arg2.toDouble()) {
2177 }
else if (arg1.toDouble() < arg2.toDouble()) {
2182 case QMetaType::UnknownType:
2183 if (arg2.userType() == QMetaType::UnknownType)
2187 Q_ASSERT_X(0,
"QAbstractSpinBoxPrivate::variantCompare",
2188 qPrintable(QString::fromLatin1(
"Internal error 3 (%1 %2)").
2189 arg(QString::fromLatin1(arg1.typeName()),
2190 QString::fromLatin1(arg2.typeName()))));
2195QVariant QAbstractSpinBoxPrivate::variantBound(
const QVariant &min,
2196 const QVariant &value,
2197 const QVariant &max)
2199 Q_ASSERT(variantCompare(min, max) <= 0);
2200 if (variantCompare(min, value) < 0) {
2201 const int compMax = variantCompare(value, max);
2202 return (compMax < 0 ? value : max);