/* This file is part of the KDE libraries * Initial implementation: * Copyright (c) 1997 Patrick Dowler * Rewritten and maintained by: * Copyright (c) 2000 Dirk Mueller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "knuminput.h" #include #ifdef HAVE_LIMITS_H #include #endif #include #include #include #include #include #include #include #include #include static inline int calcDiffByTen(int x, int y) { // calculate ( x - y ) / 10 without overflowing ints: return (x / 10) - (y / 10) + (x % 10 - y % 10) / 10; } // ---------------------------------------------------------------------------- class KNumInputPrivate { public: KNumInputPrivate(KNumInput *q, KNumInput *below = 0) : q(q), previousNumInput(0), nextNumInput(0), column1Width(0), column2Width(0), label(0), slider(0), labelAlignment(0) { if (below) { nextNumInput = below->d->nextNumInput; previousNumInput = below; below->d->nextNumInput = q; if (nextNumInput) { nextNumInput->d->previousNumInput = q; } } } static KNumInputPrivate *get(const KNumInput *i) { return i->d; } KNumInput *q; KNumInput* previousNumInput, *nextNumInput; int column1Width, column2Width; QLabel* label; QSlider* slider; QSize sliderSize, labelSize; Qt::Alignment labelAlignment; }; #define K_USING_KNUMINPUT_P(_d) KNumInputPrivate *_d = KNumInputPrivate::get(this) KNumInput::KNumInput(QWidget* parent) : QWidget(parent), d(new KNumInputPrivate(this)) { setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); setFocusPolicy(Qt::StrongFocus); } KNumInput::~KNumInput() { if (d->previousNumInput) { d->previousNumInput->d->nextNumInput = d->nextNumInput; } if (d->nextNumInput) { d->nextNumInput->d->previousNumInput = d->previousNumInput; } delete d; } QSlider *KNumInput::slider() const { return d->slider; } bool KNumInput::showSlider() const { return d->slider; } void KNumInput::setLabel(const QString & label, Qt::Alignment a) { if (label.isEmpty()) { delete d->label; d->label = 0; d->labelAlignment = 0; } else { if (!d->label) { d->label = new QLabel(this); } d->label->setText(label); d->label->setObjectName("KNumInput::QLabel"); d->label->setAlignment(a); // if no vertical alignment set, use Top alignment if (!(a & (Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter))) { a |= Qt::AlignTop; } d->labelAlignment = a; } layout(true); } QString KNumInput::label() const { return d->label ? d->label->text() : QString(); } void KNumInput::layout(bool deep) { int w1 = d->column1Width; int w2 = d->column2Width; // label sizeHint d->labelSize = (d->label ? d->label->sizeHint() : QSize(0, 0)); if (d->label && (d->labelAlignment & Qt::AlignVCenter)) { d->column1Width = d->labelSize.width() + 4; } else { d->column1Width = 0; } // slider sizeHint d->sliderSize = (d->slider ? d->slider->sizeHint() : QSize(0, 0)); doLayout(); if (!deep) { d->column1Width = w1; d->column2Width = w2; return; } w2 = d->column2Width; KNumInput* p = d->previousNumInput; while (p) { p->doLayout(); w1 = qMax(w1, p->d->column1Width); w2 = qMax(w2, p->d->column2Width); p = p->d->previousNumInput; } p = d->nextNumInput; while (p) { p->doLayout(); w1 = qMax(w1, p->d->column1Width); w2 = qMax(w2, p->d->column2Width); p = p->d->nextNumInput; } p = this; while (p) { p->d->column1Width = w1; p->d->column2Width = w2; p = p->d->previousNumInput; } p = d->nextNumInput; while (p) { p->d->column1Width = w1; p->d->column2Width = w2; p = p->d->nextNumInput; } // kDebug() << "w1 " << w1 << " w2 " << w2; } QSize KNumInput::sizeHint() const { return minimumSizeHint(); } void KNumInput::setSteps(int minor, int major) { if (d->slider) { d->slider->setSingleStep(minor); d->slider->setPageStep(major); } } // ---------------------------------------------------------------------------- class KIntSpinBox::KIntSpinBoxPrivate { public: KIntSpinBoxPrivate(KIntSpinBox *q, int val_base = 10): q(q), val_base(val_base) { connect(q, SIGNAL(valueChanged(int)), q, SLOT(updateSuffix(int))); } void updateSuffix(int value) { if (!pluralSuffix.isEmpty()) { KLocalizedString s = pluralSuffix; q->setSuffix(s.subs(value).toString()); } } KIntSpinBox *q; int val_base; KLocalizedString pluralSuffix; }; KIntSpinBox::KIntSpinBox(QWidget *parent) : QSpinBox(parent), d(new KIntSpinBoxPrivate(this)) { setValue(0); } KIntSpinBox::~KIntSpinBox() { delete d; } KIntSpinBox::KIntSpinBox(int lower, int upper, int singleStep, int value, QWidget *parent, int base) : QSpinBox(parent), d(new KIntSpinBoxPrivate(this, base)) { setRange(lower, upper); setSingleStep(singleStep); setValue(value); } void KIntSpinBox::setBase(int base) { d->val_base = base; } int KIntSpinBox::base() const { return d->val_base; } QString KIntSpinBox::textFromValue(int v) const { return QString::number(v, d->val_base); } int KIntSpinBox::valueFromText(const QString &text) const { bool ok; QString theText = text; if (theText.startsWith(prefix())) { theText.remove(0, prefix().length()); } if (theText.endsWith(suffix())) { theText.chop(suffix().length()); } return theText.trimmed().toInt(&ok, d->val_base); } void KIntSpinBox::setEditFocus(bool mark) { lineEdit()->setFocus(); if (mark) { lineEdit()->selectAll(); } } void KIntSpinBox::setSuffix(const KLocalizedString& suffix) { d->pluralSuffix = suffix; if (suffix.isEmpty()) setSuffix(QString()); else d->updateSuffix(value()); } // ---------------------------------------------------------------------------- class KIntNumInput::KIntNumInputPrivate { public: KIntNumInput *q; int referencePoint; short blockRelative; KIntSpinBox* intSpinBox; QSize intSpinBoxSize; KIntNumInputPrivate(KIntNumInput *q, int r) : q(q), referencePoint(r), blockRelative(0) {} }; KIntNumInput::KIntNumInput(QWidget *parent) : KNumInput(parent) , d(new KIntNumInputPrivate(this, 0)) { init(0, 10); } KIntNumInput::KIntNumInput(int val, QWidget *parent, int _base) : KNumInput(parent) , d(new KIntNumInputPrivate(this, val)) { init(val, _base); } QSpinBox *KIntNumInput::spinBox() const { return d->intSpinBox; } void KIntNumInput::init(int val, int _base) { d->intSpinBox = new KIntSpinBox(INT_MIN, INT_MAX, 1, val, this, _base); d->intSpinBox->setObjectName("KIntNumInput::KIntSpinBox"); // the KIntValidator is broken beyond believe for // spinboxes which have suffix or prefix texts, so // better don't use it unless absolutely necessary if (_base != 10) { kWarning() << "WARNING: Validation is broken in KIntNumInput! Needs to be fixed."; // d->intSpinBox->setValidator(new KIntValidator(this, _base, "KNumInput::KIntValidator")); } connect(d->intSpinBox, SIGNAL(valueChanged(int)), SLOT(spinValueChanged(int))); connect(this, SIGNAL(valueChanged(int)), SLOT(slotEmitRelativeValueChanged(int))); setFocusProxy(d->intSpinBox); layout(true); } void KIntNumInput::setReferencePoint(int ref) { // clip to valid range: ref = qMin(maximum(), qMax(minimum(), ref)); d->referencePoint = ref; } int KIntNumInput::referencePoint() const { return d->referencePoint; } void KIntNumInput::spinValueChanged(int val) { K_USING_KNUMINPUT_P(priv); if (priv->slider) { priv->slider->setValue(val); } emit valueChanged(val); } void KIntNumInput::slotEmitRelativeValueChanged(int value) { if (d->blockRelative || !d->referencePoint) { return; } emit relativeValueChanged(double(value) / double(d->referencePoint)); } void KIntNumInput::setSliderEnabled(bool slider) { K_USING_KNUMINPUT_P(priv); if (slider) { if (!priv->slider) { priv->slider = new QSlider(Qt::Horizontal, this); connect(priv->slider, SIGNAL(valueChanged(int)), d->intSpinBox, SLOT(setValue(int))); priv->slider->setTickPosition(QSlider::TicksBelow); layout(true); } const int value = d->intSpinBox->value(); priv->slider->setRange(d->intSpinBox->minimum(), d->intSpinBox->maximum()); priv->slider->setPageStep(d->intSpinBox->singleStep()); priv->slider->setValue(value); // calculate (upper-lower)/10 without overflowing int's: const int major = calcDiffByTen(d->intSpinBox->maximum(), d->intSpinBox->minimum()); priv->slider->setSingleStep(d->intSpinBox->singleStep()); priv->slider->setPageStep(qMax(1, major)); priv->slider->setTickInterval(major); } else { if (priv->slider) { layout(true); } delete priv->slider; priv->slider = 0; } } void KIntNumInput::setRange(int lower, int upper, int singleStep) { if (upper < lower || singleStep <= 0) { kWarning() << "WARNING: KIntNumInput::setRange() called with bad arguments. Ignoring call..."; return; } d->intSpinBox->setMinimum(lower); d->intSpinBox->setMaximum(upper); d->intSpinBox->setSingleStep(singleStep); singleStep = d->intSpinBox->singleStep(); // maybe QRangeControl didn't like our lineStep? // check that reference point is still inside valid range: setReferencePoint(referencePoint()); layout(true); // update slider information if it's shown K_USING_KNUMINPUT_P(priv); setSliderEnabled(priv->slider); } void KIntNumInput::setMinimum(int min) { setRange(min, d->intSpinBox->maximum(), d->intSpinBox->singleStep()); } int KIntNumInput::minimum() const { return d->intSpinBox->minimum(); } void KIntNumInput::setMaximum(int max) { setRange(d->intSpinBox->minimum(), max, d->intSpinBox->singleStep()); } int KIntNumInput::maximum() const { return d->intSpinBox->maximum(); } int KIntNumInput::singleStep() const { return d->intSpinBox->singleStep(); } void KIntNumInput::setSingleStep(int singleStep) { d->intSpinBox->setSingleStep(singleStep); } void KIntNumInput::setSuffix(const QString &suffix) { d->intSpinBox->setSuffix(suffix); layout(true); } void KIntNumInput::setSuffix(const KLocalizedString& suffix) { d->intSpinBox->setSuffix(suffix); layout(true); } QString KIntNumInput::suffix() const { return d->intSpinBox->suffix(); } void KIntNumInput::setPrefix(const QString &prefix) { d->intSpinBox->setPrefix(prefix); layout(true); } QString KIntNumInput::prefix() const { return d->intSpinBox->prefix(); } void KIntNumInput::setEditFocus(bool mark) { d->intSpinBox->setEditFocus(mark); } QSize KIntNumInput::minimumSizeHint() const { K_USING_KNUMINPUT_P(priv); ensurePolished(); int w; int h; h = qMax(d->intSpinBoxSize.height(), priv->sliderSize.height()); // if in extra row, then count it here if (priv->label && (priv->labelAlignment & (Qt::AlignBottom | Qt::AlignTop))) { h += 4 + priv->labelSize.height(); } else { // label is in the same row as the other widgets h = qMax(h, priv->labelSize.height() + 2); } w = priv->slider ? priv->slider->sizeHint().width() + KDialog::spacingHint() : 0; w += priv->column1Width + priv->column2Width; if (priv->labelAlignment & (Qt::AlignTop | Qt::AlignBottom)) { w = qMax(w, priv->labelSize.width() + 4); } return QSize(w, h); } void KIntNumInput::doLayout() { K_USING_KNUMINPUT_P(priv); d->intSpinBoxSize = d->intSpinBox->sizeHint(); priv->column2Width = d->intSpinBoxSize.width(); if (priv->label) { priv->label->setBuddy(d->intSpinBox); } } void KIntNumInput::resizeEvent(QResizeEvent* e) { K_USING_KNUMINPUT_P(priv); int w = priv->column1Width; int h = 0; if (priv->label && (priv->labelAlignment & Qt::AlignTop)) { priv->label->setGeometry(0, 0, e->size().width(), priv->labelSize.height()); h += priv->labelSize.height() + KDialog::spacingHint(); } if (priv->label && (priv->labelAlignment & Qt::AlignVCenter)) { priv->label->setGeometry(0, 0, w, d->intSpinBoxSize.height()); } if (qApp->layoutDirection() == Qt::RightToLeft) { d->intSpinBox->setGeometry(w, h, priv->slider ? priv->column2Width : qMax(priv->column2Width, e->size().width() - w), d->intSpinBoxSize.height()); w += priv->column2Width + KDialog::spacingHint(); if (priv->slider) { priv->slider->setGeometry(w, h, e->size().width() - w, d->intSpinBoxSize.height() + KDialog::spacingHint()); } } else if (priv->slider) { priv->slider->setGeometry(w, h, e->size().width() - (w + priv->column2Width + KDialog::spacingHint()), d->intSpinBoxSize.height() + KDialog::spacingHint()); d->intSpinBox->setGeometry(w + priv->slider->size().width() + KDialog::spacingHint(), h, priv->column2Width, d->intSpinBoxSize.height()); } else { d->intSpinBox->setGeometry(w, h, qMax(priv->column2Width, e->size().width() - w), d->intSpinBoxSize.height()); } h += d->intSpinBoxSize.height() + 2; if (priv->label && (priv->labelAlignment & Qt::AlignBottom)) { priv->label->setGeometry(0, h, priv->labelSize.width(), priv->labelSize.height()); } } KIntNumInput::~KIntNumInput() { delete d; } void KIntNumInput::setValue(int val) { d->intSpinBox->setValue(val); // slider value is changed by spinValueChanged } void KIntNumInput::setRelativeValue(double r) { if (!d->referencePoint) { return; } ++d->blockRelative; setValue(qRound(d->referencePoint * r + 0.5)); --d->blockRelative; } double KIntNumInput::relativeValue() const { if (!d->referencePoint) { return 0; } return double(value()) / double(d->referencePoint); } int KIntNumInput::value() const { return d->intSpinBox->value(); } void KIntNumInput::setSpecialValueText(const QString& text) { d->intSpinBox->setSpecialValueText(text); layout(true); } QString KIntNumInput::specialValueText() const { return d->intSpinBox->specialValueText(); } void KIntNumInput::setLabel(const QString & label, Qt::Alignment a) { K_USING_KNUMINPUT_P(priv); KNumInput::setLabel(label, a); if (priv->label) { priv->label->setBuddy(d->intSpinBox); } } // ---------------------------------------------------------------------------- class KDoubleNumInput::KDoubleNumInputPrivate { public: KDoubleNumInputPrivate(double r) : spin(0), referencePoint(r), blockRelative(0), exponentRatio(1.0) {} QDoubleSpinBox * spin; double referencePoint; short blockRelative; QSize editSize; QString specialValue; double exponentRatio; }; KDoubleNumInput::KDoubleNumInput(QWidget *parent) : KNumInput(parent) , d(new KDoubleNumInputPrivate(0.0)) { init(0.0, 0.0, 9999.0, 0.01, 2); } KDoubleNumInput::KDoubleNumInput(double lower, double upper, double value, QWidget *parent, double singleStep, int precision) : KNumInput(parent) , d(new KDoubleNumInputPrivate(value)) { init(value, lower, upper, singleStep, precision); } KDoubleNumInput::~KDoubleNumInput() { delete d; } QString KDoubleNumInput::specialValueText() const { return d->specialValue; } void KDoubleNumInput::init(double value, double lower, double upper, double singleStep, int precision) { d->spin = new QDoubleSpinBox(this); d->spin->setRange(lower, upper); d->spin->setSingleStep(singleStep); d->spin->setValue(value); d->spin->setDecimals(precision); d->spin->setObjectName("KDoubleNumInput::QDoubleSpinBox"); setFocusProxy(d->spin); connect(d->spin, SIGNAL(valueChanged(double)), this, SIGNAL(valueChanged(double))); connect(this, SIGNAL(valueChanged(double)), this, SLOT(slotEmitRelativeValueChanged(double))); updateLegacyMembers(); layout(true); } void KDoubleNumInput::updateLegacyMembers() { d->specialValue = specialValueText(); } double KDoubleNumInput::mapSliderToSpin(int val) const { K_USING_KNUMINPUT_P(priv); // map [slidemin,slidemax] to [spinmin,spinmax] const double spinmin = d->spin->minimum(); const double spinmax = d->spin->maximum(); const double slidemin = priv->slider->minimum(); // cast int to double to avoid const double slidemax = priv->slider->maximum(); // overflow in rel denominator const double rel = (double(val) - slidemin) / (slidemax - slidemin); Q_ASSERT(d->exponentRatio > 0.0); return spinmin + pow(rel, d->exponentRatio ) * (spinmax - spinmin); } void KDoubleNumInput::sliderMoved(int val) { d->spin->setValue(mapSliderToSpin(val)); } void KDoubleNumInput::spinBoxChanged(double val) { K_USING_KNUMINPUT_P(priv); const double spinmin = d->spin->minimum(); const double spinmax = d->spin->maximum(); const double slidemin = priv->slider->minimum(); // cast int to double to avoid const double slidemax = priv->slider->maximum(); // overflow in rel denominator Q_ASSERT(d->exponentRatio > 0.0); const double rel = pow((val - spinmin) / (spinmax - spinmin) , 1.0 / d->exponentRatio); if (priv->slider) { priv->slider->blockSignals(true); priv->slider->setValue(qRound(slidemin + rel * (slidemax - slidemin))); priv->slider->blockSignals(false); } } void KDoubleNumInput::slotEmitRelativeValueChanged(double value) { if (!d->referencePoint) { return; } emit relativeValueChanged(value / d->referencePoint); } QSize KDoubleNumInput::minimumSizeHint() const { K_USING_KNUMINPUT_P(priv); ensurePolished(); int w; int h; h = qMax(d->editSize.height(), priv->sliderSize.height()); // if in extra row, then count it here if (priv->label && (priv->labelAlignment & (Qt::AlignBottom | Qt::AlignTop))) { h += 4 + priv->labelSize.height(); } else { // label is in the same row as the other widgets h = qMax(h, priv->labelSize.height() + 2); } w = priv->slider ? priv->slider->sizeHint().width() + KDialog::spacingHint() : 0; w += priv->column1Width + priv->column2Width; if (priv->labelAlignment & (Qt::AlignTop | Qt::AlignBottom)) { w = qMax(w, priv->labelSize.width() + 4); } return QSize(w, h); } void KDoubleNumInput::resizeEvent(QResizeEvent* e) { K_USING_KNUMINPUT_P(priv); int w = priv->column1Width; int h = 0; if (priv->label && (priv->labelAlignment & Qt::AlignTop)) { priv->label->setGeometry(0, 0, e->size().width(), priv->labelSize.height()); h += priv->labelSize.height() + 4; } if (priv->label && (priv->labelAlignment & Qt::AlignVCenter)) { priv->label->setGeometry(0, 0, w, d->editSize.height()); } if (qApp->layoutDirection() == Qt::RightToLeft) { d->spin->setGeometry(w, h, priv->slider ? priv->column2Width : e->size().width() - w, d->editSize.height()); w += priv->column2Width + KDialog::spacingHint(); if (priv->slider) priv->slider->setGeometry(w, h, e->size().width() - w, d->editSize.height() + KDialog::spacingHint()); } else if (priv->slider) { priv->slider->setGeometry(w, h, e->size().width() - (priv->column1Width + priv->column2Width + KDialog::spacingHint()), d->editSize.height() + KDialog::spacingHint()); d->spin->setGeometry(w + priv->slider->width() + KDialog::spacingHint(), h, priv->column2Width, d->editSize.height()); } else { d->spin->setGeometry(w, h, e->size().width() - w, d->editSize.height()); } h += d->editSize.height() + 2; if (priv->label && (priv->labelAlignment & Qt::AlignBottom)) { priv->label->setGeometry(0, h, priv->labelSize.width(), priv->labelSize.height()); } } void KDoubleNumInput::doLayout() { K_USING_KNUMINPUT_P(priv); d->editSize = d->spin->sizeHint(); priv->column2Width = d->editSize.width(); } void KDoubleNumInput::setValue(double val) { d->spin->setValue(val); } void KDoubleNumInput::setRelativeValue(double r) { if (!d->referencePoint) { return; } ++d->blockRelative; setValue(r * d->referencePoint); --d->blockRelative; } void KDoubleNumInput::setReferencePoint(double ref) { // clip to valid range: ref = qMin(maximum(), qMax(minimum(), ref)); d->referencePoint = ref; } void KDoubleNumInput::setRange(double lower, double upper, double singleStep, bool slider) { K_USING_KNUMINPUT_P(priv); if (priv->slider) { // don't update the slider to avoid an endless recursion QDoubleSpinBox * spin = d->spin; disconnect(spin, SIGNAL(valueChanged(double)), priv->slider, SLOT(setValue(int))); } d->spin->setRange(lower, upper); d->spin->setSingleStep(singleStep); setSliderEnabled(slider); setReferencePoint(referencePoint()); layout(true); updateLegacyMembers(); } void KDoubleNumInput::setSliderEnabled(bool enabled) { K_USING_KNUMINPUT_P(priv); if (enabled) { QDoubleSpinBox * spin = d->spin; const double range = spin->maximum() - spin->minimum(); const double steps = range * pow(10.0, spin->decimals()); if (!priv->slider) { priv->slider = new QSlider(Qt::Horizontal, this); priv->slider->setTickPosition(QSlider::TicksBelow); // feedback line: when one moves, the other moves, too: connect(priv->slider, SIGNAL(valueChanged(int)), SLOT(sliderMoved(int))); layout(true); } if (steps > 1000 || d->exponentRatio != 1.0) { priv->slider->setRange(0, 1000); priv->slider->setSingleStep(1); priv->slider->setPageStep(50); } else { const int singleSteps = qRound(steps); priv->slider->setRange(0, singleSteps); priv->slider->setSingleStep(1); const int pageSteps = qBound(1, singleSteps / 20, 10); priv->slider->setPageStep(pageSteps); } spinBoxChanged(spin->value()); connect(spin, SIGNAL(valueChanged(double)), SLOT(spinBoxChanged(double))); } else { if (priv->slider) { layout(true); } delete priv->slider; priv->slider = 0; } } void KDoubleNumInput::setMinimum(double min) { K_USING_KNUMINPUT_P(priv); setRange(min, maximum(), d->spin->singleStep(), priv->slider); } double KDoubleNumInput::minimum() const { return d->spin->minimum(); } void KDoubleNumInput::setMaximum(double max) { K_USING_KNUMINPUT_P(priv); setRange(minimum(), max, d->spin->singleStep(), priv->slider); } double KDoubleNumInput::maximum() const { return d->spin->maximum(); } double KDoubleNumInput::singleStep() const { return d->spin->singleStep(); } void KDoubleNumInput::setSingleStep(double singleStep) { d->spin->setSingleStep(singleStep); } double KDoubleNumInput::value() const { return d->spin->value(); } double KDoubleNumInput::relativeValue() const { if (!d->referencePoint) { return 0; } return value() / d->referencePoint; } double KDoubleNumInput::referencePoint() const { return d->referencePoint; } QString KDoubleNumInput::suffix() const { return d->spin->suffix(); } QString KDoubleNumInput::prefix() const { return d->spin->prefix(); } void KDoubleNumInput::setSuffix(const QString &suffix) { d->spin->setSuffix(suffix); layout(true); } void KDoubleNumInput::setPrefix(const QString &prefix) { d->spin->setPrefix(prefix); layout(true); } void KDoubleNumInput::setDecimals(int decimals) { d->spin->setDecimals(decimals); layout(true); } int KDoubleNumInput::decimals() const { return d->spin->decimals(); } void KDoubleNumInput::setSpecialValueText(const QString& text) { d->spin->setSpecialValueText(text); layout(true); updateLegacyMembers(); } void KDoubleNumInput::setLabel(const QString & label, Qt::Alignment a) { K_USING_KNUMINPUT_P(priv); KNumInput::setLabel(label, a); if (priv->label) { priv->label->setBuddy(d->spin); } } double KDoubleNumInput::exponentRatio() const { return d->exponentRatio; } void KDoubleNumInput::setExponentRatio(double dbl) { Q_ASSERT(dbl > 0.0); if(dbl > 0.0) { d->exponentRatio = dbl; spinBoxChanged( d->spin->value() ); // used to reset the value of the slider } else { kError() << "ExponentRatio need to be strictly positive."; } } #include "moc_knuminput.cpp"