kalarm/lib
spinbox.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <kdeversion.h>
00022 #include <qlineedit.h>
00023 #include <qobjectlist.h>
00024 #include "spinbox.moc"
00025
00026
00027 SpinBox::SpinBox(QWidget* parent, const char* name)
00028 : QSpinBox(0, 99999, 1, parent, name),
00029 mMinValue(QSpinBox::minValue()),
00030 mMaxValue(QSpinBox::maxValue())
00031 {
00032 init();
00033 }
00034
00035 SpinBox::SpinBox(int minValue, int maxValue, int step, QWidget* parent, const char* name)
00036 : QSpinBox(minValue, maxValue, step, parent, name),
00037 mMinValue(minValue),
00038 mMaxValue(maxValue)
00039 {
00040 init();
00041 }
00042
00043 void SpinBox::init()
00044 {
00045 int step = QSpinBox::lineStep();
00046 mLineStep = step;
00047 mLineShiftStep = step;
00048 mCurrentButton = NO_BUTTON;
00049 mShiftMouse = false;
00050 mShiftMinBound = false;
00051 mShiftMaxBound = false;
00052 mSelectOnStep = true;
00053 mReadOnly = false;
00054 mSuppressSignals = false;
00055 mEdited = false;
00056
00057
00058
00059 QObjectList* spinwidgets = queryList("QSpinWidget", 0, false, true);
00060 QSpinWidget* spin = (QSpinWidget*)spinwidgets->getFirst();
00061 if (spin)
00062 spin->installEventFilter(this);
00063 delete spinwidgets;
00064 editor()->installEventFilter(this);
00065
00066 #if KDE_IS_VERSION(3,1,90)
00067
00068 connect(editor(), SIGNAL(textChanged(const QString&)), SLOT(textEdited()));
00069 #endif
00070 }
00071
00072 void SpinBox::setReadOnly(bool ro)
00073 {
00074 if ((int)ro != (int)mReadOnly)
00075 {
00076 mReadOnly = ro;
00077 editor()->setReadOnly(ro);
00078 if (ro)
00079 setShiftStepping(false);
00080 }
00081 }
00082
00083 int SpinBox::bound(int val) const
00084 {
00085 return (val < mMinValue) ? mMinValue : (val > mMaxValue) ? mMaxValue : val;
00086 }
00087
00088 void SpinBox::setMinValue(int val)
00089 {
00090 mMinValue = val;
00091 QSpinBox::setMinValue(val);
00092 mShiftMinBound = false;
00093 }
00094
00095 void SpinBox::setMaxValue(int val)
00096 {
00097 mMaxValue = val;
00098 QSpinBox::setMaxValue(val);
00099 mShiftMaxBound = false;
00100 }
00101
00102 void SpinBox::setLineStep(int step)
00103 {
00104 mLineStep = step;
00105 if (!mShiftMouse)
00106 QSpinBox::setLineStep(step);
00107 }
00108
00109 void SpinBox::setLineShiftStep(int step)
00110 {
00111 mLineShiftStep = step;
00112 if (mShiftMouse)
00113 QSpinBox::setLineStep(step);
00114 }
00115
00116 void SpinBox::stepUp()
00117 {
00118 int step = QSpinBox::lineStep();
00119 addValue(step);
00120 emit stepped(step);
00121 }
00122
00123 void SpinBox::stepDown()
00124 {
00125 int step = -QSpinBox::lineStep();
00126 addValue(step);
00127 emit stepped(step);
00128 }
00129
00130
00131
00132
00133
00134
00135 void SpinBox::addValue(int change, bool current)
00136 {
00137 int newval = value() + change;
00138 int maxval = current ? QSpinBox::maxValue() : mMaxValue;
00139 int minval = current ? QSpinBox::minValue() : mMinValue;
00140 if (wrapping())
00141 {
00142 int range = maxval - minval + 1;
00143 if (newval > maxval)
00144 newval = minval + (newval - maxval - 1) % range;
00145 else if (newval < minval)
00146 newval = maxval - (minval - 1 - newval) % range;
00147 }
00148 else
00149 {
00150 if (newval > maxval)
00151 newval = maxval;
00152 else if (newval < minval)
00153 newval = minval;
00154 }
00155 setValue(newval);
00156 }
00157
00158 void SpinBox::valueChange()
00159 {
00160 if (!mSuppressSignals)
00161 {
00162 int val = value();
00163 if (mShiftMinBound && val >= mMinValue)
00164 {
00165
00166 QSpinBox::setMinValue(mMinValue);
00167 mShiftMinBound = false;
00168 }
00169 if (mShiftMaxBound && val <= mMaxValue)
00170 {
00171
00172 QSpinBox::setMaxValue(mMaxValue);
00173 mShiftMaxBound = false;
00174 }
00175
00176 bool focus = !mSelectOnStep && hasFocus();
00177 if (focus)
00178 clearFocus();
00179 QSpinBox::valueChange();
00180 if (focus)
00181 setFocus();
00182 }
00183 }
00184
00185
00186
00187
00188 void SpinBox::textEdited()
00189 {
00190 mEdited = true;
00191 }
00192
00193 void SpinBox::updateDisplay()
00194 {
00195 mEdited = false;
00196 QSpinBox::updateDisplay();
00197 }
00198
00199
00200
00201
00202 bool SpinBox::eventFilter(QObject* obj, QEvent* e)
00203 {
00204 if (obj == editor())
00205 {
00206 if (e->type() == QEvent::KeyPress)
00207 {
00208
00209 QKeyEvent* ke = (QKeyEvent*)e;
00210 int key = ke->key();
00211 if (key == Qt::Key_Up || key == Qt::Key_Down)
00212 {
00213 if (mReadOnly)
00214 return true;
00215 int step;
00216 if ((ke->state() & (Qt::ShiftButton | Qt::AltButton)) == Qt::ShiftButton)
00217 {
00218
00219 int val = value();
00220 if (key == Qt::Key_Up)
00221 step = mLineShiftStep - val % mLineShiftStep;
00222 else
00223 step = - ((val + mLineShiftStep - 1) % mLineShiftStep + 1);
00224 }
00225 else
00226 step = (key == Qt::Key_Up) ? mLineStep : -mLineStep;
00227 addValue(step, false);
00228 return true;
00229 }
00230 }
00231 #if KDE_IS_VERSION(3,1,90)
00232 else if (e->type() == QEvent::Leave)
00233 {
00234 if (mEdited)
00235 interpretText();
00236 }
00237 #endif
00238 }
00239 else
00240 {
00241 int etype = e->type();
00242 switch (etype)
00243 {
00244 case QEvent::MouseButtonPress:
00245 case QEvent::MouseButtonDblClick:
00246 {
00247 QMouseEvent* me = (QMouseEvent*)e;
00248 if (me->button() == Qt::LeftButton)
00249 {
00250
00251 if (mReadOnly)
00252 return true;
00253 mCurrentButton = whichButton(me->pos());
00254 if (mCurrentButton == NO_BUTTON)
00255 return true;
00256 bool shift = (me->state() & (Qt::ShiftButton | Qt::AltButton)) == Qt::ShiftButton;
00257 if (setShiftStepping(shift))
00258 return true;
00259 return false;
00260 }
00261 break;
00262 }
00263 case QEvent::MouseButtonRelease:
00264 {
00265 QMouseEvent* me = (QMouseEvent*)e;
00266 if (me->button() == Qt::LeftButton && mShiftMouse)
00267 {
00268 setShiftStepping(false);
00269 return false;
00270 }
00271 break;
00272 }
00273 case QEvent::MouseMove:
00274 {
00275 QMouseEvent* me = (QMouseEvent*)e;
00276 if (me->state() & Qt::LeftButton)
00277 {
00278
00279 if (mReadOnly)
00280 return true;
00281 int newButton = whichButton(me->pos());
00282 if (newButton != mCurrentButton)
00283 {
00284
00285
00286 mCurrentButton = newButton;
00287 bool shift = (me->state() & (Qt::ShiftButton | Qt::AltButton)) == Qt::ShiftButton;
00288 if (setShiftStepping(shift))
00289 return true;
00290 }
00291 return false;
00292 }
00293 break;
00294 }
00295 case QEvent::KeyPress:
00296 case QEvent::KeyRelease:
00297 case QEvent::AccelOverride:
00298 {
00299 QKeyEvent* ke = (QKeyEvent*)e;
00300 int key = ke->key();
00301 int state = ke->state();
00302 if ((state & Qt::LeftButton)
00303 && (key == Qt::Key_Shift || key == Qt::Key_Alt))
00304 {
00305
00306 if (mReadOnly)
00307 return true;
00308 state ^= (key == Qt::Key_Shift) ? Qt::ShiftButton : Qt::AltButton;
00309 bool shift = (state & (Qt::ShiftButton | Qt::AltButton)) == Qt::ShiftButton;
00310 if (!shift && mShiftMouse || shift && !mShiftMouse)
00311 {
00312
00313
00314 if (setShiftStepping(shift))
00315 return true;
00316 }
00317 }
00318 break;
00319 }
00320 }
00321 }
00322 return QSpinBox::eventFilter(obj, e);
00323 }
00324
00325
00326
00327
00328 bool SpinBox::setShiftStepping(bool shift)
00329 {
00330 if (mCurrentButton == NO_BUTTON)
00331 shift = false;
00332 if (shift && !mShiftMouse)
00333 {
00334
00335
00336
00337
00338
00339 int val = value();
00340 int step = (mCurrentButton == UP) ? mLineShiftStep : (mCurrentButton == DOWN) ? -mLineShiftStep : 0;
00341 int adjust = shiftStepAdjustment(val, step);
00342 mShiftMouse = true;
00343 if (adjust)
00344 {
00345
00346
00347
00348
00349
00350
00351 if (!wrapping())
00352 {
00353
00354
00355
00356 int newval = val + adjust + step;
00357 int svt = specialValueText().isEmpty() ? 0 : 1;
00358 int minval = mMinValue + svt;
00359 if (newval <= minval || newval >= mMaxValue)
00360 {
00361
00362 if (svt && newval <= mMinValue && val == mMinValue)
00363 newval = mMinValue;
00364 else
00365 newval = (newval <= minval) ? minval : mMaxValue;
00366 QSpinBox::setValue(newval);
00367 emit stepped(step);
00368 return true;
00369 }
00370
00371
00372
00373 int tempval = val + adjust;
00374 if (tempval < mMinValue)
00375 {
00376 QSpinBox::setMinValue(tempval);
00377 mShiftMinBound = true;
00378 }
00379 else if (tempval > mMaxValue)
00380 {
00381 QSpinBox::setMaxValue(tempval);
00382 mShiftMaxBound = true;
00383 }
00384 }
00385
00386
00387 mSuppressSignals = true;
00388 bool blocked = signalsBlocked();
00389 blockSignals(true);
00390 addValue(adjust, true);
00391 blockSignals(blocked);
00392 mSuppressSignals = false;
00393 }
00394 QSpinBox::setLineStep(mLineShiftStep);
00395 }
00396 else if (!shift && mShiftMouse)
00397 {
00398
00399 QSpinBox::setLineStep(mLineStep);
00400 QSpinBox::setMinValue(mMinValue);
00401 QSpinBox::setMaxValue(mMaxValue);
00402 mShiftMinBound = mShiftMaxBound = false;
00403 mShiftMouse = false;
00404 }
00405 return false;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 int SpinBox::shiftStepAdjustment(int oldValue, int shiftStep)
00420 {
00421 if (oldValue == 0 || shiftStep == 0)
00422 return 0;
00423 if (shiftStep > 0)
00424 {
00425 if (oldValue >= 0)
00426 return -(oldValue % shiftStep);
00427 else
00428 return (-oldValue - 1) % shiftStep + 1 - shiftStep;
00429 }
00430 else
00431 {
00432 shiftStep = -shiftStep;
00433 if (oldValue >= 0)
00434 return shiftStep - ((oldValue - 1) % shiftStep + 1);
00435 else
00436 return (-oldValue) % shiftStep;
00437 }
00438 }
00439
00440
00441
00442
00443 int SpinBox::whichButton(const QPoint& pos)
00444 {
00445 if (upRect().contains(pos))
00446 return UP;
00447 if (downRect().contains(pos))
00448 return DOWN;
00449 return NO_BUTTON;
00450 }
|