00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "knuminput.h"
00024
00025 #include <config.h>
00026 #ifdef HAVE_LIMITS_H
00027 #include <limits.h>
00028 #endif
00029
00030 #include <QtGui/QApplication>
00031 #include <QtGui/QLabel>
00032 #include <QtGui/QLineEdit>
00033 #include <QtGui/QResizeEvent>
00034 #include <QtGui/QSlider>
00035
00036 #include <kdebug.h>
00037 #include <kdialog.h>
00038
00039 static inline int calcDiffByTen(int x, int y)
00040 {
00041
00042 return (x / 10) - (y / 10) + (x % 10 - y % 10) / 10;
00043 }
00044
00045
00046
00047 class KNumInputPrivate
00048 {
00049 public:
00050 KNumInputPrivate(KNumInput *q, KNumInput *below = 0) :
00051 q(q),
00052 previousNumInput(0),
00053 nextNumInput(0),
00054 column1Width(0),
00055 column2Width(0),
00056 label(0),
00057 slider(0),
00058 labelAlignment(0)
00059 {
00060 if (below) {
00061 nextNumInput = below->d->nextNumInput;
00062 previousNumInput = below;
00063 below->d->nextNumInput = q;
00064 if (nextNumInput) {
00065 nextNumInput->d->previousNumInput = q;
00066 }
00067 }
00068 }
00069
00070 static KNumInputPrivate *get(const KNumInput *i) {
00071 return i->d;
00072 }
00073
00074 KNumInput *q;
00075 KNumInput* previousNumInput, *nextNumInput;
00076 int column1Width, column2Width;
00077
00078 QLabel* label;
00079 QSlider* slider;
00080 QSize sliderSize, labelSize;
00081
00082 Qt::Alignment labelAlignment;
00083 };
00084
00085
00086 #define K_USING_KNUMINPUT_P(_d) KNumInputPrivate *_d = KNumInputPrivate::get(this)
00087
00088 KNumInput::KNumInput(QWidget* parent)
00089 : QWidget(parent), d(new KNumInputPrivate(this))
00090 {
00091 setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
00092 }
00093
00094 KNumInput::KNumInput(QWidget* parent, KNumInput* below)
00095 : QWidget(parent), d(new KNumInputPrivate(this, below))
00096 {
00097 setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
00098 }
00099
00100 KNumInput::~KNumInput()
00101 {
00102 if (d->previousNumInput) {
00103 d->previousNumInput->d->nextNumInput = d->nextNumInput;
00104 }
00105
00106 if (d->nextNumInput) {
00107 d->nextNumInput->d->previousNumInput = d->previousNumInput;
00108 }
00109
00110 delete d;
00111 }
00112
00113 QSlider *KNumInput::slider() const
00114 {
00115 return d->slider;
00116 }
00117
00118 bool KNumInput::showSlider() const
00119 {
00120 return d->slider;
00121 }
00122
00123 void KNumInput::setLabel(const QString & label, Qt::Alignment a)
00124 {
00125 if (label.isEmpty()) {
00126 delete d->label;
00127 d->label = 0;
00128 d->labelAlignment = 0;
00129 } else {
00130 if (!d->label) {
00131 d->label = new QLabel(this);
00132 }
00133 d->label->setText(label);
00134 d->label->setObjectName("KNumInput::QLabel");
00135 d->label->setAlignment(a);
00136
00137 if (!(a & (Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter))) {
00138 a |= Qt::AlignTop;
00139 }
00140 d->labelAlignment = a;
00141 }
00142
00143 layout(true);
00144 }
00145
00146 QString KNumInput::label() const
00147 {
00148 return d->label ? d->label->text() : QString();
00149 }
00150
00151 void KNumInput::layout(bool deep)
00152 {
00153 int w1 = d->column1Width;
00154 int w2 = d->column2Width;
00155
00156
00157 d->labelSize = (d->label ? d->label->sizeHint() : QSize(0, 0));
00158
00159 if (d->label && (d->labelAlignment & Qt::AlignVCenter)) {
00160 d->column1Width = d->labelSize.width() + 4;
00161 } else {
00162 d->column1Width = 0;
00163 }
00164
00165
00166 d->sliderSize = (d->slider ? d->slider->sizeHint() : QSize(0, 0));
00167
00168 doLayout();
00169
00170 if (!deep) {
00171 d->column1Width = w1;
00172 d->column2Width = w2;
00173 return;
00174 }
00175
00176 KNumInput* p = this;
00177 while (p) {
00178 p->doLayout();
00179 w1 = qMax(w1, p->d->column1Width);
00180 w2 = qMax(w2, p->d->column2Width);
00181 p = p->d->previousNumInput;
00182 }
00183
00184 p = d->nextNumInput;
00185 while (p) {
00186 p->doLayout();
00187 w1 = qMax(w1, p->d->column1Width);
00188 w2 = qMax(w2, p->d->column2Width);
00189 p = p->d->nextNumInput;
00190 }
00191
00192 p = this;
00193 while (p) {
00194 p->d->column1Width = w1;
00195 p->d->column2Width = w2;
00196 p = p->d->previousNumInput;
00197 }
00198
00199 p = d->nextNumInput;
00200 while (p) {
00201 p->d->column1Width = w1;
00202 p->d->column2Width = w2;
00203 p = p->d->nextNumInput;
00204 }
00205
00206
00207 }
00208
00209 QSize KNumInput::sizeHint() const
00210 {
00211 return minimumSizeHint();
00212 }
00213
00214 void KNumInput::setSteps(int minor, int major)
00215 {
00216 if (d->slider) {
00217 d->slider->setSingleStep(minor);
00218 d->slider->setPageStep(major);
00219 }
00220 }
00221
00222
00223
00224
00225 class KIntSpinBox::KIntSpinBoxPrivate
00226 {
00227 public:
00228 KIntSpinBoxPrivate(KIntSpinBox *q, int val_base = 10): q(q), val_base(val_base) {}
00229
00230 KIntSpinBox *q;
00231 int val_base;
00232 };
00233
00234 KIntSpinBox::KIntSpinBox(QWidget *parent)
00235 : QSpinBox(parent), d(new KIntSpinBoxPrivate(this))
00236 {
00237 lineEdit()->setAlignment(Qt::AlignRight);
00238 setValue(0);
00239 }
00240
00241 KIntSpinBox::~KIntSpinBox()
00242 {
00243 delete d;
00244 }
00245
00246 KIntSpinBox::KIntSpinBox(int lower, int upper, int step, int value, QWidget *parent, int base)
00247 : QSpinBox(parent), d(new KIntSpinBoxPrivate(this, base))
00248 {
00249 setRange(lower, upper);
00250 setSingleStep(step);
00251 lineEdit()->setAlignment(Qt::AlignRight);
00252 setValue(value);
00253 }
00254
00255 void KIntSpinBox::setBase(int base)
00256 {
00257 d->val_base = base;
00258 }
00259
00260
00261 int KIntSpinBox::base() const
00262 {
00263 return d->val_base;
00264 }
00265
00266 QString KIntSpinBox::textFromValue(int v) const
00267 {
00268 return QString::number(v, d->val_base);
00269 }
00270
00271 int KIntSpinBox::valueFromText(const QString &text) const
00272 {
00273 bool ok;
00274 QString theText = text;
00275 if (theText.endsWith(suffix())) {
00276 theText.chop(suffix().length());
00277 }
00278 return theText.toInt(&ok, d->val_base);
00279 }
00280
00281 void KIntSpinBox::setEditFocus(bool mark)
00282 {
00283 lineEdit()->setFocus();
00284 if (mark) {
00285 lineEdit()->selectAll();
00286 }
00287 }
00288
00289
00290
00291
00292 class KIntNumInput::KIntNumInputPrivate
00293 {
00294 public:
00295 KIntNumInput *q;
00296 int referencePoint;
00297 short blockRelative;
00298 KIntSpinBox* intSpinBox;
00299 QSize intSpinBoxSize;
00300
00301 KIntNumInputPrivate(KIntNumInput *q, int r)
00302 : q(q),
00303 referencePoint(r),
00304 blockRelative(0) {}
00305 };
00306
00307
00308 KIntNumInput::KIntNumInput(KNumInput* below, int val, QWidget *parent, int _base)
00309 : KNumInput(parent, below)
00310 , d(new KIntNumInputPrivate(this, val))
00311 {
00312 init(val, _base);
00313 }
00314
00315 KIntNumInput::KIntNumInput(QWidget *parent)
00316 : KNumInput(parent)
00317 , d(new KIntNumInputPrivate(this, 0))
00318 {
00319 init(0, 10);
00320 }
00321
00322 KIntNumInput::KIntNumInput(int val, QWidget *parent, int _base)
00323 : KNumInput(parent)
00324 , d(new KIntNumInputPrivate(this, val))
00325 {
00326 init(val, _base);
00327 }
00328
00329 QSpinBox *KIntNumInput::spinBox() const
00330 {
00331 return d->intSpinBox;
00332 }
00333
00334 void KIntNumInput::init(int val, int _base)
00335 {
00336 d->intSpinBox = new KIntSpinBox(INT_MIN, INT_MAX, 1, val, this, _base);
00337 d->intSpinBox->setObjectName("KIntNumInput::KIntSpinBox");
00338
00339
00340
00341
00342 if (_base != 10) {
00343 kWarning() << "WARNING: Validation is broken in KIntNumInput! Needs to be fixed.";
00344
00345 }
00346
00347 connect(d->intSpinBox, SIGNAL(valueChanged(int)), SLOT(spinValueChanged(int)));
00348 connect(this, SIGNAL(valueChanged(int)),
00349 SLOT(slotEmitRelativeValueChanged(int)));
00350
00351 setFocusProxy(d->intSpinBox);
00352 layout(true);
00353 }
00354
00355 void KIntNumInput::setReferencePoint(int ref)
00356 {
00357
00358 ref = qMin(maximum(), qMax(minimum(), ref));
00359 d->referencePoint = ref;
00360 }
00361
00362 int KIntNumInput::referencePoint() const
00363 {
00364 return d->referencePoint;
00365 }
00366
00367 void KIntNumInput::spinValueChanged(int val)
00368 {
00369 K_USING_KNUMINPUT_P(priv);
00370
00371 if (priv->slider) {
00372 priv->slider->setValue(val);
00373 }
00374
00375 emit valueChanged(val);
00376 }
00377
00378 void KIntNumInput::slotEmitRelativeValueChanged(int value)
00379 {
00380 if (d->blockRelative || !d->referencePoint) {
00381 return;
00382 }
00383 emit relativeValueChanged(double(value) / double(d->referencePoint));
00384 }
00385
00386 void KIntNumInput::setSliderEnabled(bool slider)
00387 {
00388 K_USING_KNUMINPUT_P(priv);
00389 if (slider) {
00390 if (!priv->slider) {
00391 priv->slider = new QSlider(Qt::Horizontal, this);
00392 connect(priv->slider, SIGNAL(valueChanged(int)),
00393 d->intSpinBox, SLOT(setValue(int)));
00394 priv->slider->setTickPosition(QSlider::TicksBelow);
00395 }
00396
00397 const int value = d->intSpinBox->value();
00398 priv->slider->setRange(d->intSpinBox->minimum(), d->intSpinBox->maximum());
00399 priv->slider->setPageStep(d->intSpinBox->singleStep());
00400 priv->slider->setValue(value);
00401
00402
00403 const int major = calcDiffByTen(d->intSpinBox->maximum(), d->intSpinBox->minimum());
00404
00405 priv->slider->setSingleStep(d->intSpinBox->singleStep());
00406 priv->slider->setPageStep(major);
00407 priv->slider->setTickInterval(major);
00408 } else {
00409 delete priv->slider;
00410 priv->slider = 0;
00411 }
00412 }
00413
00414 void KIntNumInput::setRange(int lower, int upper, int step)
00415 {
00416 upper = qMax(upper, lower);
00417 lower = qMin(upper, lower);
00418 d->intSpinBox->setMinimum(lower);
00419 d->intSpinBox->setMaximum(upper);
00420 d->intSpinBox->setSingleStep(step);
00421
00422 step = d->intSpinBox->singleStep();
00423
00424
00425 setReferencePoint(referencePoint());
00426
00427 layout(true);
00428 }
00429
00430 void KIntNumInput::setRange(int lower, int upper, int step, bool slider)
00431 {
00432 setRange(lower, upper, step);
00433 setSliderEnabled(slider);
00434 }
00435
00436 void KIntNumInput::setMinimum(int min)
00437 {
00438 setRange(min, d->intSpinBox->maximum(), d->intSpinBox->singleStep());
00439 }
00440
00441 int KIntNumInput::minimum() const
00442 {
00443 return d->intSpinBox->minimum();
00444 }
00445
00446 void KIntNumInput::setMaximum(int max)
00447 {
00448 setRange(d->intSpinBox->minimum(), max, d->intSpinBox->singleStep());
00449 }
00450
00451 int KIntNumInput::maximum() const
00452 {
00453 return d->intSpinBox->maximum();
00454 }
00455
00456 void KIntNumInput::setSuffix(const QString &suffix)
00457 {
00458 d->intSpinBox->setSuffix(suffix);
00459
00460 layout(true);
00461 }
00462
00463 QString KIntNumInput::suffix() const
00464 {
00465 return d->intSpinBox->suffix();
00466 }
00467
00468 void KIntNumInput::setPrefix(const QString &prefix)
00469 {
00470 d->intSpinBox->setPrefix(prefix);
00471
00472 layout(true);
00473 }
00474
00475 QString KIntNumInput::prefix() const
00476 {
00477 return d->intSpinBox->prefix();
00478 }
00479
00480 void KIntNumInput::setEditFocus(bool mark)
00481 {
00482 d->intSpinBox->setEditFocus(mark);
00483 }
00484
00485 QSize KIntNumInput::minimumSizeHint() const
00486 {
00487 K_USING_KNUMINPUT_P(priv);
00488 ensurePolished();
00489
00490 int w;
00491 int h;
00492
00493 h = 2 + qMax(d->intSpinBoxSize.height(), priv->sliderSize.height());
00494
00495
00496 if (priv->label && (priv->labelAlignment & (Qt::AlignBottom | Qt::AlignTop))) {
00497 h += 4 + priv->labelSize.height();
00498 } else {
00499
00500 h = qMax(h, priv->labelSize.height() + 2);
00501 }
00502
00503 w = priv->slider ? priv->slider->sizeHint().width() + 8 : 0;
00504 w += priv->column1Width + priv->column2Width;
00505
00506 if (priv->labelAlignment & (Qt::AlignTop | Qt::AlignBottom)) {
00507 w = qMax(w, priv->labelSize.width() + 4);
00508 }
00509
00510 return QSize(w, h);
00511 }
00512
00513 void KIntNumInput::doLayout()
00514 {
00515 K_USING_KNUMINPUT_P(priv);
00516
00517 d->intSpinBoxSize = d->intSpinBox->sizeHint();
00518 priv->column2Width = d->intSpinBoxSize.width();
00519
00520 if (priv->label) {
00521 priv->label->setBuddy(d->intSpinBox);
00522 }
00523 }
00524
00525 void KIntNumInput::resizeEvent(QResizeEvent* e)
00526 {
00527 K_USING_KNUMINPUT_P(priv);
00528
00529 int w = priv->column1Width;
00530 int h = 0;
00531
00532 if (priv->label && (priv->labelAlignment & Qt::AlignTop)) {
00533 priv->label->setGeometry(0, 0, e->size().width(), priv->labelSize.height());
00534 h += priv->labelSize.height() + KDialog::spacingHint();
00535 }
00536
00537 if (priv->label && (priv->labelAlignment & Qt::AlignVCenter)) {
00538 priv->label->setGeometry(0, 0, w, d->intSpinBoxSize.height());
00539 }
00540
00541 if (qApp->layoutDirection()) {
00542 d->intSpinBox->setGeometry(w, h, priv->slider ? priv->column2Width : qMax(priv->column2Width, e->size().width() - w), d->intSpinBoxSize.height());
00543 w += priv->column2Width + 8;
00544
00545 if (priv->slider) {
00546 priv->slider->setGeometry(w, h, e->size().width() - w, d->intSpinBoxSize.height() + KDialog::spacingHint());
00547 }
00548 } else if (priv->slider) {
00549 priv->slider->setGeometry(w, h, e->size().width() - (w + priv->column2Width + KDialog::spacingHint()), d->intSpinBoxSize.height() + KDialog::spacingHint());
00550 d->intSpinBox->setGeometry(w + priv->slider->size().width() + KDialog::spacingHint(), h, priv->column2Width, d->intSpinBoxSize.height());
00551 } else {
00552 d->intSpinBox->setGeometry(w, h, qMax(priv->column2Width, e->size().width() - w), d->intSpinBoxSize.height());
00553 }
00554
00555 h += d->intSpinBoxSize.height() + 2;
00556
00557 if (priv->label && (priv->labelAlignment & Qt::AlignBottom)) {
00558 priv->label->setGeometry(0, h, priv->labelSize.width(), priv->labelSize.height());
00559 }
00560 }
00561
00562 KIntNumInput::~KIntNumInput()
00563 {
00564 delete d;
00565 }
00566
00567 void KIntNumInput::setValue(int val)
00568 {
00569 d->intSpinBox->setValue(val);
00570
00571 }
00572
00573 void KIntNumInput::setRelativeValue(double r)
00574 {
00575 if (!d->referencePoint) {
00576 return;
00577 }
00578 ++d->blockRelative;
00579 setValue(qRound(d->referencePoint * r + 0.5));
00580 --d->blockRelative;
00581 }
00582
00583 double KIntNumInput::relativeValue() const
00584 {
00585 if (!d->referencePoint) {
00586 return 0;
00587 }
00588 return double(value()) / double(d->referencePoint);
00589 }
00590
00591 int KIntNumInput::value() const
00592 {
00593 return d->intSpinBox->value();
00594 }
00595
00596 void KIntNumInput::setSpecialValueText(const QString& text)
00597 {
00598 d->intSpinBox->setSpecialValueText(text);
00599 layout(true);
00600 }
00601
00602 QString KIntNumInput::specialValueText() const
00603 {
00604 return d->intSpinBox->specialValueText();
00605 }
00606
00607 void KIntNumInput::setLabel(const QString & label, Qt::Alignment a)
00608 {
00609 K_USING_KNUMINPUT_P(priv);
00610
00611 KNumInput::setLabel(label, a);
00612
00613 if (priv->label) {
00614 priv->label->setBuddy(d->intSpinBox);
00615 }
00616 }
00617
00618
00619
00620 class KDoubleNumInput::KDoubleNumInputPrivate
00621 {
00622 public:
00623 KDoubleNumInputPrivate(double r)
00624 : spin(0),
00625 referencePoint(r),
00626 blockRelative(0) {}
00627 QDoubleSpinBox * spin;
00628 double referencePoint;
00629 short blockRelative;
00630 QSize editSize;
00631 QString specialValue;
00632 };
00633
00634 KDoubleNumInput::KDoubleNumInput(QWidget *parent)
00635 : KNumInput(parent)
00636 , d(new KDoubleNumInputPrivate(0.0))
00637
00638 {
00639 init(0.0, 0.0, 9999.0, 0.01, 2);
00640 }
00641
00642 KDoubleNumInput::KDoubleNumInput(double lower, double upper, double value, QWidget *parent,
00643 double step, int precision)
00644 : KNumInput(parent)
00645 , d(new KDoubleNumInputPrivate(value))
00646 {
00647 init(value, lower, upper, step, precision);
00648 }
00649
00650 KDoubleNumInput::KDoubleNumInput(KNumInput *below,
00651 double lower, double upper, double value, QWidget *parent,
00652 double step, int precision)
00653 : KNumInput(parent, below)
00654 , d(new KDoubleNumInputPrivate(value))
00655 {
00656 init(value, lower, upper, step, precision);
00657 }
00658
00659 KDoubleNumInput::~KDoubleNumInput()
00660 {
00661 delete d;
00662 }
00663
00664 QString KDoubleNumInput::specialValueText() const
00665 {
00666 return d->specialValue;
00667 }
00668
00669
00670 void KDoubleNumInput::init(double value, double lower, double upper,
00671 double step, int precision)
00672 {
00673 d->spin = new QDoubleSpinBox(this);
00674 d->spin->setRange(lower, upper);
00675 d->spin->setSingleStep(step);
00676 d->spin->setValue(value);
00677 d->spin->setDecimals(precision);
00678 d->spin->setAlignment(Qt::AlignRight);
00679
00680 d->spin->setObjectName("KDoubleNumInput::QDoubleSpinBox");
00681 setFocusProxy(d->spin);
00682 connect(d->spin, SIGNAL(valueChanged(double)),
00683 this, SIGNAL(valueChanged(double)));
00684 connect(this, SIGNAL(valueChanged(double)),
00685 this, SLOT(slotEmitRelativeValueChanged(double)));
00686
00687 updateLegacyMembers();
00688
00689 layout(true);
00690 }
00691
00692 void KDoubleNumInput::updateLegacyMembers()
00693 {
00694 d->specialValue = specialValueText();
00695 }
00696
00697 double KDoubleNumInput::mapSliderToSpin(int val) const
00698 {
00699 K_USING_KNUMINPUT_P(priv);
00700
00701
00702 const double spinmin = d->spin->minimum();
00703 const double spinmax = d->spin->maximum();
00704 const double slidemin = priv->slider->minimum();
00705 const double slidemax = priv->slider->maximum();
00706 const double rel = (double(val) - slidemin) / (slidemax - slidemin);
00707 return spinmin + rel * (spinmax - spinmin);
00708 }
00709
00710 void KDoubleNumInput::sliderMoved(int val)
00711 {
00712 d->spin->setValue(mapSliderToSpin(val));
00713 }
00714
00715 void KDoubleNumInput::spinBoxChanged(double val)
00716 {
00717 K_USING_KNUMINPUT_P(priv);
00718
00719 const double spinmin = d->spin->minimum();
00720 const double spinmax = d->spin->maximum();
00721 const double slidemin = priv->slider->minimum();
00722 const double slidemax = priv->slider->maximum();
00723
00724 const double rel = (val - spinmin) / (spinmax - spinmin);
00725
00726 if (priv->slider) {
00727 priv->slider->blockSignals(true);
00728 priv->slider->setValue(qRound(slidemin + rel * (slidemax - slidemin)));
00729 priv->slider->blockSignals(false);
00730 }
00731 }
00732
00733 void KDoubleNumInput::slotEmitRelativeValueChanged(double value)
00734 {
00735 if (!d->referencePoint) {
00736 return;
00737 }
00738 emit relativeValueChanged(value / d->referencePoint);
00739 }
00740
00741 QSize KDoubleNumInput::minimumSizeHint() const
00742 {
00743 K_USING_KNUMINPUT_P(priv);
00744
00745 ensurePolished();
00746
00747 int w;
00748 int h;
00749
00750 h = 2 + qMax(d->editSize.height(), priv->sliderSize.height());
00751
00752
00753 if (priv->label && (priv->labelAlignment & (Qt::AlignBottom | Qt::AlignTop))) {
00754 h += 4 + priv->labelSize.height();
00755 } else {
00756
00757 h = qMax(h, priv->labelSize.height() + 2);
00758 }
00759
00760 w = priv->slider ? priv->slider->sizeHint().width() + 8 : 0;
00761 w += priv->column1Width + priv->column2Width;
00762
00763 if (priv->labelAlignment & (Qt::AlignTop | Qt::AlignBottom)) {
00764 w = qMax(w, priv->labelSize.width() + 4);
00765 }
00766
00767 return QSize(w, h);
00768 }
00769
00770 void KDoubleNumInput::resizeEvent(QResizeEvent* e)
00771 {
00772 K_USING_KNUMINPUT_P(priv);
00773
00774 int w = priv->column1Width;
00775 int h = 0;
00776
00777 if (priv->label && (priv->labelAlignment & Qt::AlignTop)) {
00778 priv->label->setGeometry(0, 0, e->size().width(), priv->labelSize.height());
00779 h += priv->labelSize.height() + 4;
00780 }
00781
00782 if (priv->label && (priv->labelAlignment & Qt::AlignVCenter)) {
00783 priv->label->setGeometry(0, 0, w, d->editSize.height());
00784 }
00785
00786 if (qApp->layoutDirection()) {
00787 d->spin->setGeometry(w, h, priv->slider ? priv->column2Width
00788 : e->size().width() - w, d->editSize.height());
00789 w += priv->column2Width + KDialog::spacingHint();
00790
00791 if (priv->slider)
00792 priv->slider->setGeometry(w, h, e->size().width() - w, d->editSize.height() + KDialog::spacingHint());
00793 } else if (priv->slider) {
00794 priv->slider->setGeometry(w, h, e->size().width() -
00795 (priv->column1Width + priv->column2Width + KDialog::spacingHint()),
00796 d->editSize.height() + KDialog::spacingHint());
00797 d->spin->setGeometry(w + priv->slider->width() + KDialog::spacingHint(), h,
00798 priv->column2Width, d->editSize.height());
00799 } else {
00800 d->spin->setGeometry(w, h, e->size().width() - w, d->editSize.height());
00801 }
00802
00803 h += d->editSize.height() + 2;
00804
00805 if (priv->label && (priv->labelAlignment & Qt::AlignBottom)) {
00806 priv->label->setGeometry(0, h, priv->labelSize.width(), priv->labelSize.height());
00807 }
00808 }
00809
00810 void KDoubleNumInput::doLayout()
00811 {
00812 K_USING_KNUMINPUT_P(priv);
00813
00814 d->editSize = d->spin->sizeHint();
00815 priv->column2Width = d->editSize.width();
00816 }
00817
00818 void KDoubleNumInput::setValue(double val)
00819 {
00820 d->spin->setValue(val);
00821 }
00822
00823 void KDoubleNumInput::setRelativeValue(double r)
00824 {
00825 if (!d->referencePoint) {
00826 return;
00827 }
00828 ++d->blockRelative;
00829 setValue(r * d->referencePoint);
00830 --d->blockRelative;
00831 }
00832
00833 void KDoubleNumInput::setReferencePoint(double ref)
00834 {
00835
00836 ref = qMin(maximum(), qMax(minimum(), ref));
00837 d->referencePoint = ref;
00838 }
00839
00840 void KDoubleNumInput::setRange(double lower, double upper, double step,
00841 bool slider)
00842 {
00843 K_USING_KNUMINPUT_P(priv);
00844
00845 if (priv->slider) {
00846
00847 QDoubleSpinBox * spin = d->spin;
00848 disconnect(spin, SIGNAL(valueChanged(double)),
00849 priv->slider, SLOT(setValue(int)));
00850 }
00851 d->spin->setRange(lower, upper);
00852 d->spin->setSingleStep(step);
00853
00854 if (slider) {
00855
00856 QDoubleSpinBox * spin = d->spin;
00857 double multiplicator = 1.0;
00858 if (spin->maximum() - spin->minimum() < 10.0) {
00859 multiplicator = 10 / (spin->maximum() - spin->minimum());
00860 }
00861 const int slmax = qRound(spin->maximum() * multiplicator);
00862 const int slmin = qRound(spin->minimum() * multiplicator);
00863 const int slvalue = qRound(spin->value() * multiplicator);
00864 const int slstep = qRound(spin->singleStep() * multiplicator);
00865 if (!priv->slider) {
00866 priv->slider = new QSlider(Qt::Horizontal, this);
00867 priv->slider->setTickPosition(QSlider::TicksBelow);
00868
00869 connect(priv->slider, SIGNAL(valueChanged(int)),
00870 SLOT(sliderMoved(int)));
00871 }
00872 priv->slider->setRange(slmin, slmax);
00873 priv->slider->setSingleStep(slstep);
00874 priv->slider->setValue(slvalue);
00875 connect(spin, SIGNAL(valueChanged(double)), SLOT(spinBoxChanged(double)));
00876
00877 int major = calcDiffByTen(slmax, slmin);
00878 if (!major) {
00879 major = slstep;
00880 }
00881 priv->slider->setTickInterval(major);
00882 } else {
00883 delete priv->slider;
00884 priv->slider = 0;
00885 }
00886
00887 setReferencePoint(referencePoint());
00888
00889 layout(true);
00890 updateLegacyMembers();
00891 }
00892
00893 void KDoubleNumInput::setMinimum(double min)
00894 {
00895 K_USING_KNUMINPUT_P(priv);
00896 setRange(min, maximum(), d->spin->singleStep(), priv->slider);
00897 }
00898
00899 double KDoubleNumInput::minimum() const
00900 {
00901 return d->spin->minimum();
00902 }
00903
00904 void KDoubleNumInput::setMaximum(double max)
00905 {
00906 K_USING_KNUMINPUT_P(priv);
00907 setRange(minimum(), max, d->spin->singleStep(), priv->slider);
00908 }
00909
00910 double KDoubleNumInput::maximum() const
00911 {
00912 return d->spin->maximum();
00913 }
00914
00915 double KDoubleNumInput::value() const
00916 {
00917 return d->spin->value();
00918 }
00919
00920 double KDoubleNumInput::relativeValue() const
00921 {
00922 if (!d->referencePoint) {
00923 return 0;
00924 }
00925 return value() / d->referencePoint;
00926 }
00927
00928 double KDoubleNumInput::referencePoint() const
00929 {
00930 return d->referencePoint;
00931 }
00932
00933 QString KDoubleNumInput::suffix() const
00934 {
00935 return d->spin->suffix();
00936 }
00937
00938 QString KDoubleNumInput::prefix() const
00939 {
00940 return d->spin->prefix();
00941 }
00942
00943 void KDoubleNumInput::setSuffix(const QString &suffix)
00944 {
00945 d->spin->setSuffix(suffix);
00946
00947 layout(true);
00948 }
00949
00950 void KDoubleNumInput::setPrefix(const QString &prefix)
00951 {
00952 d->spin->setPrefix(prefix);
00953
00954 layout(true);
00955 }
00956
00957 void KDoubleNumInput::setDecimals(int decimals)
00958 {
00959 d->spin->setDecimals(decimals);
00960
00961 layout(true);
00962 }
00963
00964 int KDoubleNumInput::decimals() const
00965 {
00966 return d->spin->decimals();
00967 }
00968
00969 void KDoubleNumInput::setSpecialValueText(const QString& text)
00970 {
00971 d->spin->setSpecialValueText(text);
00972
00973 layout(true);
00974 updateLegacyMembers();
00975 }
00976
00977 void KDoubleNumInput::setLabel(const QString & label, Qt::Alignment a)
00978 {
00979 K_USING_KNUMINPUT_P(priv);
00980
00981 KNumInput::setLabel(label, a);
00982
00983 if (priv->label) {
00984 priv->label->setBuddy(d->spin);
00985 }
00986 }
00987
00988 #include "knuminput.moc"