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