23 #include "spinbox.moc"
27 #include <QApplication>
29 #include <QStyleOptionSpinBox>
31 #include <QMouseEvent>
56 int step = QSpinBox::singleStep();
58 mLineShiftStep = step;
59 mCurrentButton = NO_BUTTON;
61 mShiftMinBound =
false;
62 mShiftMaxBound =
false;
66 mSuppressSignals =
false;
69 lineEdit()->installEventFilter(
this);
72 connect(lineEdit(), SIGNAL(textChanged(QString)), SLOT(textEdited()));
73 connect(
this, SIGNAL(valueChanged(
int)), SLOT(valueChange()));
78 if ((
int)ro != (
int)mReadOnly)
81 lineEdit()->setReadOnly(ro);
83 setShiftStepping(
false, mCurrentButton);
89 return (val < mMinValue) ? mMinValue : (val > mMaxValue) ? mMaxValue : val;
95 QSpinBox::setMinimum(val);
96 mShiftMinBound =
false;
102 QSpinBox::setMaximum(val);
103 mShiftMaxBound =
false;
110 QSpinBox::setSingleStep(step);
115 mLineShiftStep = step;
117 QSpinBox::setSingleStep(step);
122 int increment = steps * QSpinBox::singleStep();
134 int newval = value() + change;
135 int maxval = current ? QSpinBox::maximum() : mMaxValue;
136 int minval = current ? QSpinBox::minimum() : mMinValue;
139 int range = maxval - minval + 1;
141 newval = minval + (newval - maxval - 1) % range;
142 else if (newval < minval)
143 newval = maxval - (minval - 1 - newval) % range;
149 else if (newval < minval)
155 void SpinBox::valueChange()
157 if (!mSuppressSignals)
160 if (mShiftMinBound && val >= mMinValue)
163 QSpinBox::setMinimum(mMinValue);
164 mShiftMinBound =
false;
166 if (mShiftMaxBound && val <= mMaxValue)
169 QSpinBox::setMaximum(mMaxValue);
170 mShiftMaxBound =
false;
173 if (!mSelectOnStep && hasFocus())
174 lineEdit()->deselect();
181 void SpinBox::textEdited()
191 if (obj == lineEdit())
196 case QEvent::KeyPress:
199 QKeyEvent* ke = (QKeyEvent*)e;
201 if (key == Qt::Key_Up)
203 else if (key == Qt::Key_Down)
209 QWheelEvent* we = (QWheelEvent*)e;
210 step = (we->delta() > 0) ? 1 : -1;
220 QInputEvent* ie = (QInputEvent*)e;
221 if ((ie->modifiers() & (Qt::ShiftModifier | Qt::AltModifier)) == Qt::ShiftModifier)
226 step = mLineShiftStep - val % mLineShiftStep;
228 step = - ((val + mLineShiftStep - 1) % mLineShiftStep + 1);
231 step = (step > 0) ? mLineStep : -mLineStep;
236 return QSpinBox::eventFilter(obj, e);
246 QSpinBox::focusOutEvent(e);
252 QSpinBox::mousePressEvent(e);
258 QSpinBox::mouseDoubleClickEvent(e);
261 bool SpinBox::clickEvent(QMouseEvent* e)
263 if (e->button() == Qt::LeftButton)
268 mCurrentButton = whichButton(e->pos());
269 if (mCurrentButton == NO_BUTTON)
274 bool shift = (e->modifiers() & (Qt::ShiftModifier | Qt::AltModifier)) == Qt::ShiftModifier;
275 if (setShiftStepping(shift, mCurrentButton))
288 bool shift = (e->modifiers() & (Qt::ShiftModifier | Qt::AltModifier)) == Qt::ShiftModifier;
289 if (setShiftStepping(shift, (e->delta() > 0 ? UP : DOWN)))
294 QSpinBox::wheelEvent(e);
299 if (e->button() == Qt::LeftButton && mShiftMouse)
300 setShiftStepping(
false, mCurrentButton);
301 QSpinBox::mouseReleaseEvent(e);
306 if (e->buttons() & Qt::LeftButton)
311 int newButton = whichButton(e->pos());
312 if (newButton != mCurrentButton)
316 mCurrentButton = newButton;
317 bool shift = (e->modifiers() & (Qt::ShiftModifier | Qt::AltModifier)) == Qt::ShiftModifier;
318 if (setShiftStepping(shift, mCurrentButton))
325 QSpinBox::mouseMoveEvent(e);
331 QSpinBox::keyPressEvent(e);
337 QSpinBox::keyReleaseEvent(e);
340 bool SpinBox::keyEvent(QKeyEvent* e)
343 int state = e->modifiers();
344 if ((QApplication::mouseButtons() & Qt::LeftButton)
345 && (key == Qt::Key_Shift || key == Qt::Key_Alt))
350 bool shift = (state & (Qt::ShiftModifier | Qt::AltModifier)) == Qt::ShiftModifier;
351 if ((!shift && mShiftMouse) || (shift && !mShiftMouse))
355 if (setShiftStepping(shift, mCurrentButton))
368 bool SpinBox::setShiftStepping(
bool shift,
int currentButton)
370 if (currentButton == NO_BUTTON)
372 if (shift && !mShiftMouse)
380 int step = (currentButton == UP) ? mLineShiftStep : (currentButton == DOWN) ? -mLineShiftStep : 0;
396 int newval = val + adjust + step;
397 int svt = specialValueText().isEmpty() ? 0 : 1;
398 int minval = mMinValue + svt;
399 if (newval <= minval || newval >= mMaxValue)
402 if (svt && newval <= mMinValue && val == mMinValue)
405 newval = (newval <= minval) ? minval : mMaxValue;
406 QSpinBox::setValue(newval);
413 int tempval = val + adjust;
414 if (tempval < mMinValue)
416 QSpinBox::setMinimum(tempval);
417 mShiftMinBound =
true;
419 else if (tempval > mMaxValue)
421 QSpinBox::setMaximum(tempval);
422 mShiftMaxBound =
true;
427 mSuppressSignals =
true;
428 bool blocked = signalsBlocked();
431 blockSignals(blocked);
432 mSuppressSignals =
false;
434 QSpinBox::setSingleStep(mLineShiftStep);
436 else if (!shift && mShiftMouse)
439 QSpinBox::setSingleStep(mLineStep);
440 QSpinBox::setMinimum(mMinValue);
441 QSpinBox::setMaximum(mMaxValue);
442 mShiftMinBound = mShiftMaxBound =
false;
461 if (oldValue == 0 || shiftStep == 0)
466 return -(oldValue % shiftStep);
468 return (-oldValue - 1) % shiftStep + 1 - shiftStep;
472 shiftStep = -shiftStep;
474 return shiftStep - ((oldValue - 1) % shiftStep + 1);
476 return (-oldValue) % shiftStep;
483 int SpinBox::whichButton(
const QPoint& pos)
485 QStyleOptionSpinBox option;
487 if (style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxUp).contains(pos))
489 if (style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxDown).contains(pos))
496 QStyleOptionSpinBox option;
498 return style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxUp);
503 QStyleOptionSpinBox option;
505 return style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxDown);
510 QStyleOptionSpinBox option;
512 return style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxUp)
513 | style()->subControlRect(QStyle::CC_SpinBox, &option, QStyle::SC_SpinBoxDown);
520 QStyleOptionSpinBox option;
522 QPainter painter(
this);
523 style()->drawComplexControl(QStyle::CC_SpinBox, &option, &painter,
this);
526 QSpinBox::paintEvent(pe);
533 so.subControls = mUpDownOnly ? (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown | QStyle::SC_SpinBoxFrame)
534 : (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown | QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField);
535 so.buttonSymbols = buttonSymbols();
536 so.frame = hasFrame();
537 so.stepEnabled = stepEnabled();
QRect upRect() const
Returns the rectangle containing the up arrow.
QRect downRect() const
Returns the rectangle containing the down arrow.
void initStyleOption(QStyleOptionSpinBox &) const
Initialise a QStyleOptionSpinBox with this instance's details.
void setSingleStep(int step)
Sets the unshifted step increment, i.e.
QRect upDownRect() const
Returns the rectangle containing the up and down arrows.
virtual void paintEvent(QPaintEvent *)
virtual void focusOutEvent(QFocusEvent *)
virtual void keyPressEvent(QKeyEvent *)
void setMinimum(int val)
Sets the minimum value of the spin box.
virtual void mousePressEvent(QMouseEvent *)
virtual void mouseReleaseEvent(QMouseEvent *)
virtual void mouseDoubleClickEvent(QMouseEvent *)
virtual bool eventFilter(QObject *, QEvent *)
Receives events destined for the spin widget or for the edit field.
void setRange(int minValue, int maxValue)
Sets the minimum and maximum values of the spin box.
SpinBox(QWidget *parent=0)
Constructor.
virtual void keyReleaseEvent(QKeyEvent *)
void stepped(int step)
Signal emitted when the spin box's value is stepped (by the shifted or unshifted increment).
virtual int shiftStepAdjustment(int oldValue, int shiftStep)
Returns the initial adjustment to the value for a shift step up or down.
void addValue(int change)
Adds a value to the current value of the spin box.
void setMaximum(int val)
Sets the maximum value of the spin box.
virtual void stepBy(int steps)
Called whenever the user triggers a step, to adjust the value of the spin box by the unshifted increm...
virtual void wheelEvent(QWheelEvent *)
void setSingleShiftStep(int step)
Sets the shifted step increment, i.e.
int bound(int val) const
Returns the specified value clamped to the range of the spin box.
virtual void mouseMoveEvent(QMouseEvent *)
virtual void setReadOnly(bool readOnly)
Sets whether the spin box can be changed by the user.