00001
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 <tqlineedit.h>
00023 #include <tqobjectlist.h>
00024 #include "spinbox.moc"
00025
00026
00027 SpinBox::SpinBox(TQWidget* parent, const char* name)
00028 : TQSpinBox(0, 99999, 1, parent, name),
00029 mMinValue(TQSpinBox::minValue()),
00030 mMaxValue(TQSpinBox::maxValue())
00031 {
00032 init();
00033 }
00034
00035 SpinBox::SpinBox(int minValue, int maxValue, int step, TQWidget* parent, const char* name)
00036 : TQSpinBox(minValue, maxValue, step, parent, name),
00037 mMinValue(minValue),
00038 mMaxValue(maxValue)
00039 {
00040 init();
00041 }
00042
00043 void SpinBox::init()
00044 {
00045 int step = TQSpinBox::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 TQObjectList* spinwidgets = queryList(TQSPINWIDGET_OBJECT_NAME_STRING, 0, false, true);
00060 TQSpinWidget* spin = (TQSpinWidget*)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(), TQT_SIGNAL(textChanged(const TQString&)), TQT_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, mCurrentButton);
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 TQSpinBox::setMinValue(val);
00092 mShiftMinBound = false;
00093 }
00094
00095 void SpinBox::setMaxValue(int val)
00096 {
00097 mMaxValue = val;
00098 TQSpinBox::setMaxValue(val);
00099 mShiftMaxBound = false;
00100 }
00101
00102 void SpinBox::setLineStep(int step)
00103 {
00104 mLineStep = step;
00105 if (!mShiftMouse)
00106 TQSpinBox::setLineStep(step);
00107 }
00108
00109 void SpinBox::setLineShiftStep(int step)
00110 {
00111 mLineShiftStep = step;
00112 if (mShiftMouse)
00113 TQSpinBox::setLineStep(step);
00114 }
00115
00116 void SpinBox::stepUp()
00117 {
00118 int step = TQSpinBox::lineStep();
00119 addValue(step);
00120 emit stepped(step);
00121 }
00122
00123 void SpinBox::stepDown()
00124 {
00125 int step = -TQSpinBox::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 ? TQSpinBox::maxValue() : mMaxValue;
00139 int minval = current ? TQSpinBox::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 TQSpinBox::setMinValue(mMinValue);
00167 mShiftMinBound = false;
00168 }
00169 if (mShiftMaxBound && val <= mMaxValue)
00170 {
00171
00172 TQSpinBox::setMaxValue(mMaxValue);
00173 mShiftMaxBound = false;
00174 }
00175
00176 bool focus = !mSelectOnStep && hasFocus();
00177 if (focus)
00178 clearFocus();
00179 TQSpinBox::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 TQSpinBox::updateDisplay();
00197 }
00198
00199
00200
00201
00202 bool SpinBox::eventFilter(TQObject* obj, TQEvent* e)
00203 {
00204 if (TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(editor()))
00205 {
00206 int step = 0;
00207 bool shift = false;
00208 switch (e->type())
00209 {
00210 case TQEvent::KeyPress:
00211 {
00212
00213 TQKeyEvent* ke = (TQKeyEvent*)e;
00214 int key = ke->key();
00215 if (key == TQt::Key_Up)
00216 step = 1;
00217 else if (key == TQt::Key_Down)
00218 step = -1;
00219 shift = ((ke->state() & (TQt::ShiftButton | TQt::AltButton)) == TQt::ShiftButton);
00220 break;
00221 }
00222 case TQEvent::Wheel:
00223 {
00224 TQWheelEvent* we = (TQWheelEvent*)e;
00225 step = (we->delta() > 0) ? 1 : -1;
00226 shift = ((we->state() & (TQt::ShiftButton | TQt::AltButton)) == TQt::ShiftButton);
00227 break;
00228 }
00229 #if KDE_IS_VERSION(3,1,90)
00230 case TQEvent::Leave:
00231 if (mEdited)
00232 interpretText();
00233 break;
00234 #endif
00235 default:
00236 break;
00237 }
00238 if (step)
00239 {
00240 if (mReadOnly)
00241 return true;
00242 if (shift)
00243 {
00244
00245 int val = value();
00246 if (step > 0)
00247 step = mLineShiftStep - val % mLineShiftStep;
00248 else
00249 step = - ((val + mLineShiftStep - 1) % mLineShiftStep + 1);
00250 }
00251 else
00252 step = (step > 0) ? mLineStep : -mLineStep;
00253 addValue(step, false);
00254 return true;
00255 }
00256 }
00257 else
00258 {
00259 int etype = e->type();
00260 switch (etype)
00261 {
00262 case TQEvent::MouseButtonPress:
00263 case TQEvent::MouseButtonDblClick:
00264 {
00265 TQMouseEvent* me = (TQMouseEvent*)e;
00266 if (me->button() == Qt::LeftButton)
00267 {
00268
00269 if (mReadOnly)
00270 return true;
00271 mCurrentButton = whichButton(me->pos());
00272 if (mCurrentButton == NO_BUTTON)
00273 return true;
00274 bool shift = (me->state() & (TQt::ShiftButton | TQt::AltButton)) == TQt::ShiftButton;
00275 if (setShiftStepping(shift, mCurrentButton))
00276 return true;
00277 return false;
00278 }
00279 break;
00280 }
00281 case TQEvent::MouseButtonRelease:
00282 {
00283 TQMouseEvent* me = (TQMouseEvent*)e;
00284 if (me->button() == Qt::LeftButton && mShiftMouse)
00285 {
00286 setShiftStepping(false, mCurrentButton);
00287 return false;
00288 }
00289 break;
00290 }
00291 case TQEvent::MouseMove:
00292 {
00293 TQMouseEvent* me = (TQMouseEvent*)e;
00294 if (me->state() & Qt::LeftButton)
00295 {
00296
00297 if (mReadOnly)
00298 return true;
00299 int newButton = whichButton(me->pos());
00300 if (newButton != mCurrentButton)
00301 {
00302
00303
00304 mCurrentButton = newButton;
00305 bool shift = (me->state() & (TQt::ShiftButton | TQt::AltButton)) == TQt::ShiftButton;
00306 if (setShiftStepping(shift, mCurrentButton))
00307 return true;
00308 }
00309 return false;
00310 }
00311 break;
00312 }
00313 case TQEvent::Wheel:
00314 {
00315 TQWheelEvent* we = (TQWheelEvent*)e;
00316 bool shift = (we->state() & (TQt::ShiftButton | TQt::AltButton)) == TQt::ShiftButton;
00317 if (setShiftStepping(shift, (we->delta() > 0 ? UP : DOWN)))
00318 return true;
00319 return false;
00320 }
00321 case TQEvent::KeyPress:
00322 case TQEvent::KeyRelease:
00323 case TQEvent::AccelOverride:
00324 {
00325 TQKeyEvent* ke = (TQKeyEvent*)e;
00326 int key = ke->key();
00327 int state = ke->state();
00328 if ((state & Qt::LeftButton)
00329 && (key == TQt::Key_Shift || key == TQt::Key_Alt))
00330 {
00331
00332 if (mReadOnly)
00333 return true;
00334 state ^= (key == TQt::Key_Shift) ? TQt::ShiftButton : TQt::AltButton;
00335 bool shift = (state & (TQt::ShiftButton | TQt::AltButton)) == TQt::ShiftButton;
00336 if ((!shift && mShiftMouse) || (shift && !mShiftMouse))
00337 {
00338
00339
00340 if (setShiftStepping(shift, mCurrentButton))
00341 return true;
00342 }
00343 }
00344 break;
00345 }
00346 }
00347 }
00348 return TQSpinBox::eventFilter(obj, e);
00349 }
00350
00351
00352
00353
00354 bool SpinBox::setShiftStepping(bool shift, int currentButton)
00355 {
00356 if (currentButton == NO_BUTTON)
00357 shift = false;
00358 if (shift && !mShiftMouse)
00359 {
00360
00361
00362
00363
00364
00365 int val = value();
00366 int step = (currentButton == UP) ? mLineShiftStep : (currentButton == DOWN) ? -mLineShiftStep : 0;
00367 int adjust = shiftStepAdjustment(val, step);
00368 mShiftMouse = true;
00369 if (adjust)
00370 {
00371
00372
00373
00374
00375
00376
00377 if (!wrapping())
00378 {
00379
00380
00381
00382 int newval = val + adjust + step;
00383 int svt = specialValueText().isEmpty() ? 0 : 1;
00384 int minval = mMinValue + svt;
00385 if (newval <= minval || newval >= mMaxValue)
00386 {
00387
00388 if (svt && newval <= mMinValue && val == mMinValue)
00389 newval = mMinValue;
00390 else
00391 newval = (newval <= minval) ? minval : mMaxValue;
00392 TQSpinBox::setValue(newval);
00393 emit stepped(step);
00394 return true;
00395 }
00396
00397
00398
00399 int tempval = val + adjust;
00400 if (tempval < mMinValue)
00401 {
00402 TQSpinBox::setMinValue(tempval);
00403 mShiftMinBound = true;
00404 }
00405 else if (tempval > mMaxValue)
00406 {
00407 TQSpinBox::setMaxValue(tempval);
00408 mShiftMaxBound = true;
00409 }
00410 }
00411
00412
00413 mSuppressSignals = true;
00414 bool blocked = signalsBlocked();
00415 blockSignals(true);
00416 addValue(adjust, true);
00417 blockSignals(blocked);
00418 mSuppressSignals = false;
00419 }
00420 TQSpinBox::setLineStep(mLineShiftStep);
00421 }
00422 else if (!shift && mShiftMouse)
00423 {
00424
00425 TQSpinBox::setLineStep(mLineStep);
00426 TQSpinBox::setMinValue(mMinValue);
00427 TQSpinBox::setMaxValue(mMaxValue);
00428 mShiftMinBound = mShiftMaxBound = false;
00429 mShiftMouse = false;
00430 }
00431 return false;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 int SpinBox::shiftStepAdjustment(int oldValue, int shiftStep)
00446 {
00447 if (oldValue == 0 || shiftStep == 0)
00448 return 0;
00449 if (shiftStep > 0)
00450 {
00451 if (oldValue >= 0)
00452 return -(oldValue % shiftStep);
00453 else
00454 return (-oldValue - 1) % shiftStep + 1 - shiftStep;
00455 }
00456 else
00457 {
00458 shiftStep = -shiftStep;
00459 if (oldValue >= 0)
00460 return shiftStep - ((oldValue - 1) % shiftStep + 1);
00461 else
00462 return (-oldValue) % shiftStep;
00463 }
00464 }
00465
00466
00467
00468
00469 int SpinBox::whichButton(const TQPoint& pos)
00470 {
00471 if (upRect().contains(pos))
00472 return UP;
00473 if (downRect().contains(pos))
00474 return DOWN;
00475 return NO_BUTTON;
00476 }