diff --git a/includes/CMakeLists.txt b/includes/CMakeLists.txt index 64e18c4c..477753a1 100644 --- a/includes/CMakeLists.txt +++ b/includes/CMakeLists.txt @@ -136,7 +136,6 @@ install( KInputDialog KComponentData KIntNumInput - KIntSpinBox KIntValidator KJob KJobTrackerInterface diff --git a/includes/KIntSpinBox b/includes/KIntSpinBox deleted file mode 100644 index 13f28b47..00000000 --- a/includes/KIntSpinBox +++ /dev/null @@ -1 +0,0 @@ -#include "../knuminput.h" diff --git a/kdeui/dialogs/kconfigdialogmanager.cpp b/kdeui/dialogs/kconfigdialogmanager.cpp index c76f26f2..24fb59a3 100644 --- a/kdeui/dialogs/kconfigdialogmanager.cpp +++ b/kdeui/dialogs/kconfigdialogmanager.cpp @@ -141,7 +141,6 @@ void KConfigDialogManager::initMaps() s_changedMap->insert( "KUrlComboRequester", SIGNAL(textChanged(QString))); s_changedMap->insert( "KUrlComboBox", SIGNAL(urlActivated(KUrl))); s_changedMap->insert( "KIntNumInput", SIGNAL(valueChanged(int))); - s_changedMap->insert( "KIntSpinBox", SIGNAL(valueChanged(int))); s_changedMap->insert( "KDoubleNumInput", SIGNAL(valueChanged(double))); s_changedMap->insert( "KButtonGroup", SIGNAL(changed(int))); } diff --git a/kdeui/dialogs/kinputdialog.cpp b/kdeui/dialogs/kinputdialog.cpp index fe8f1a2a..37a4abed 100644 --- a/kdeui/dialogs/kinputdialog.cpp +++ b/kdeui/dialogs/kinputdialog.cpp @@ -127,7 +127,11 @@ KInputDialogHelper::KInputDialogHelper( const QString &caption, const QString &l m_label->setAlignment(Qt::AlignTop); layout->addWidget(m_label); - m_intSpinBox = new KIntSpinBox(minValue, maxValue, step, value, frame, base); + m_intSpinBox = new KIntNumInput(frame); + m_intSpinBox->setRange(minValue, maxValue); + m_intSpinBox->setSingleStep(step); + m_intSpinBox->setValue(value); + m_intSpinBox->setBase(base); layout->addWidget(m_intSpinBox); layout->setMargin(0); @@ -156,7 +160,7 @@ KInputDialogHelper::KInputDialogHelper( const QString &caption, const QString &l m_label->setAlignment(Qt::AlignTop); layout->addWidget(m_label); - m_doubleSpinBox = new QDoubleSpinBox(frame); + m_doubleSpinBox = new KDoubleNumInput(frame); m_doubleSpinBox->setRange(minValue, maxValue); m_doubleSpinBox->setSingleStep(step); m_doubleSpinBox->setValue(value); @@ -297,12 +301,12 @@ KLineEdit *KInputDialogHelper::lineEdit() const return m_lineEdit; } -KIntSpinBox *KInputDialogHelper::intSpinBox() const +KIntNumInput *KInputDialogHelper::intSpinBox() const { return m_intSpinBox; } -QDoubleSpinBox *KInputDialogHelper::doubleSpinBox() const +KDoubleNumInput *KInputDialogHelper::doubleSpinBox() const { return m_doubleSpinBox; } diff --git a/kdeui/dialogs/kinputdialog_p.h b/kdeui/dialogs/kinputdialog_p.h index 86e4b8bc..54debef9 100644 --- a/kdeui/dialogs/kinputdialog_p.h +++ b/kdeui/dialogs/kinputdialog_p.h @@ -20,18 +20,17 @@ #ifndef KINPUTDIALOG_P_H #define KINPUTDIALOG_P_H +#include "kdialog.h" +#include "knuminput.h" + #include #include class KComboBox; -#include -class KIntSpinBox; class KLineEdit; class KListWidget; class KTextEdit; -#include - /** * @author Nadeem Hasan */ @@ -60,8 +59,8 @@ class KInputDialogHelper : public KDialog ~KInputDialogHelper(); KLineEdit *lineEdit() const; - KIntSpinBox *intSpinBox() const; - QDoubleSpinBox *doubleSpinBox() const; + KIntNumInput *intSpinBox() const; + KDoubleNumInput *doubleSpinBox() const; KComboBox *comboBox() const; KListWidget *listBox() const; KTextEdit *textEdit() const; @@ -73,8 +72,8 @@ class KInputDialogHelper : public KDialog private: QLabel *m_label; KLineEdit *m_lineEdit; - KIntSpinBox *m_intSpinBox; - QDoubleSpinBox *m_doubleSpinBox; + KIntNumInput *m_intSpinBox; + KDoubleNumInput *m_doubleSpinBox; KComboBox *m_comboBox; KListWidget *m_listBox; KTextEdit *m_textEdit; diff --git a/kdeui/util/knumvalidator.cpp b/kdeui/util/knumvalidator.cpp index e190d086..6a296b23 100644 --- a/kdeui/util/knumvalidator.cpp +++ b/kdeui/util/knumvalidator.cpp @@ -47,7 +47,7 @@ public: int _max; }; -KIntValidator::KIntValidator ( QWidget *parent, int base) +KIntValidator::KIntValidator(QWidget *parent, int base) : QValidator(parent), d(new KIntValidatorPrivate()) { diff --git a/kdeui/util/knumvalidator.h b/kdeui/util/knumvalidator.h index c19e6817..9e33733d 100644 --- a/kdeui/util/knumvalidator.h +++ b/kdeui/util/knumvalidator.h @@ -39,52 +39,56 @@ @author Glen Parker @version 0.0.1 */ -class KDEUI_EXPORT KIntValidator : public QValidator { - - public: +class KDEUI_EXPORT KIntValidator : public QValidator +{ +public: /** * Constructor. Also sets the base value. */ - explicit KIntValidator ( QWidget * parent, int base = 10 ); + explicit KIntValidator(QWidget * parent, int base = 10); /** * Constructor. Also sets the minimum, maximum, and numeric base values. */ - KIntValidator ( int bottom, int top, QWidget * parent, int base = 10 ); - /** - * Destructs the validator. - */ - virtual ~KIntValidator (); + KIntValidator(int bottom, int top, QWidget *parent, int base = 10); + + virtual ~KIntValidator(); + /** * Validates the text, and return the result. Does not modify the parameters. */ - virtual State validate ( QString &, int & ) const; + virtual QValidator::State validate(QString &, int &) const; + /** * Fixes the text if possible, providing a valid string. The parameter may be modified. */ - virtual void fixup ( QString & ) const; + virtual void fixup(QString &) const; /** * Sets the minimum and maximum values allowed. * If @p top is greater than @p bottom, it is set to the value of @p bottom. */ - virtual void setRange ( int bottom, int top ); + virtual void setRange(int bottom, int top); + /** * Sets the numeric base value. @p base must be between 2 and 36. */ - virtual void setBase ( int base ); + virtual void setBase(int base); + /** * Returns the current minimum value allowed. */ - virtual int bottom () const; + virtual int bottom() const; + /** * Returns the current maximum value allowed. */ - virtual int top () const; + virtual int top() const; + /** * Returns the current numeric base. */ - virtual int base () const; + virtual int base() const; - private: +private: class KIntValidatorPrivate; KIntValidatorPrivate * const d; }; @@ -100,32 +104,36 @@ class KDEUI_EXPORT KIntValidator : public QValidator { @author Marc Mutz @see KIntValidator **/ - -class KDEUI_EXPORT KDoubleValidator : public QDoubleValidator { - Q_OBJECT - Q_PROPERTY( bool acceptLocalizedNumbers READ acceptLocalizedNumbers WRITE setAcceptLocalizedNumbers ) +class KDEUI_EXPORT KDoubleValidator : public QDoubleValidator +{ + Q_OBJECT + Q_PROPERTY(bool acceptLocalizedNumbers READ acceptLocalizedNumbers WRITE setAcceptLocalizedNumbers) public: - /** Constuct a locale-aware KDoubleValidator with default range - (whatever QDoubleValidator uses for that) and parent @p - parent */ - explicit KDoubleValidator( QObject * parent ); - /** Constuct a locale-aware KDoubleValidator for range [@p bottom,@p - top] and a precision of @p decimals decimals after the decimal - point. */ - KDoubleValidator( double bottom, double top, int decimals, - QObject * parent ); - /** Destructs the validator. - */ - virtual ~KDoubleValidator(); + /** + Constuct a locale-aware KDoubleValidator with default range + (whatever QDoubleValidator uses for that) and parent @p + parent + */ + explicit KDoubleValidator(QObject *parent); - /** @return whether localized numbers are accepted (default: true) */ - bool acceptLocalizedNumbers() const; - /** Sets whether to accept localized numbers (default: true) */ - void setAcceptLocalizedNumbers( bool accept ); + /** + Constuct a locale-aware KDoubleValidator for range [@p bottom,@p + top] and a precision of @p decimals decimals after the decimal + point. + */ + KDoubleValidator(double bottom, double top, int decimals, QObject *parent); + + virtual ~KDoubleValidator(); + + /** @return whether localized numbers are accepted (default: true) */ + bool acceptLocalizedNumbers() const; + + /** Sets whether to accept localized numbers (default: true) */ + void setAcceptLocalizedNumbers(bool accept); private: - class KDoubleValidatorPrivate; - KDoubleValidatorPrivate * const d; + class KDoubleValidatorPrivate; + KDoubleValidatorPrivate * const d; }; #endif diff --git a/kdeui/widgets/knuminput.cpp b/kdeui/widgets/knuminput.cpp index 2a460ee8..8f662e13 100644 --- a/kdeui/widgets/knuminput.cpp +++ b/kdeui/widgets/knuminput.cpp @@ -1,1053 +1,365 @@ -/* 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. - */ +/* + This file is part of the KDE libraries + Copyright (C) 2024 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + 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 "knumvalidator.h" +#include "kdebug.h" -#include +#include +#include +#include +#include -#include -#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 +class KIntNumInputPrivate { public: - KNumInputPrivate(KNumInput *q, KNumInput *below = 0) : - q(q), - previousNumInput(0), - nextNumInput(0), - column1Width(0), - column2Width(0), - label(0), - slider(0), - labelAlignment(0) + KIntNumInputPrivate() + : validator(nullptr), + slider(nullptr), + spinbox(nullptr) { - if (below) { - nextNumInput = below->d->nextNumInput; - previousNumInput = below; - below->d->nextNumInput = q; - if (nextNumInput) { - nextNumInput->d->previousNumInput = q; - } + } + + void _k_updateSuffix(int value) + { + if (suffix.isEmpty()) { + spinbox->setSuffix(QString()); + } else { + spinbox->setSuffix(suffix.subs(value).toString()); } } - static KNumInputPrivate *get(const KNumInput *i) { - return i->d; - } - - KNumInput *q; - KNumInput* previousNumInput, *nextNumInput; - int column1Width, column2Width; - - QLabel* label; + KIntValidator* validator; QSlider* slider; - QSize sliderSize, labelSize; - - Qt::Alignment labelAlignment; + QSpinBox* spinbox; + KLocalizedString suffix; }; - -#define K_USING_KNUMINPUT_P(_d) KNumInputPrivate *_d = KNumInputPrivate::get(this) - -KNumInput::KNumInput(QWidget* parent) - : QWidget(parent), d(new KNumInputPrivate(this)) +KIntNumInput::KIntNumInput(QWidget* parent) + : QWidget(parent), + d(new KIntNumInputPrivate()) { - 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()); - } + d->validator = new KIntValidator(this); + QHBoxLayout* hboxlayout = new QHBoxLayout(this); + d->slider = new QSlider(this); + d->slider->setVisible(false); + hboxlayout->addWidget(d->slider); + d->spinbox = new QSpinBox(this); + connect( + d->spinbox, SIGNAL(valueChanged(int)), + this, SIGNAL(valueChanged(int)) + ); + connect( + d->spinbox, SIGNAL(valueChanged(int)), + this, SLOT(_k_updateSuffix(int)) + ); + connect( + d->spinbox, SIGNAL(editingFinished()), + this, SIGNAL(editingFinished()) + ); + hboxlayout->addWidget(d->spinbox); + setLayout(hboxlayout); } KIntNumInput::~KIntNumInput() { delete d; } - -void KIntNumInput::setValue(int val) +void KIntNumInput::setRange(int min, int max) { - 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); + d->spinbox->setRange(min, max); } int KIntNumInput::value() const { - return d->intSpinBox->value(); + return d->spinbox->value(); } -void KIntNumInput::setSpecialValueText(const QString& text) +int KIntNumInput::minimum() const { - d->intSpinBox->setSpecialValueText(text); - layout(true); + return d->spinbox->minimum(); +} + +void KIntNumInput::setMinimum(int min) +{ + d->spinbox->setMinimum(min); +} + +int KIntNumInput::maximum() const +{ + return d->spinbox->maximum(); +} + +void KIntNumInput::setMaximum(int max) +{ + d->spinbox->setMaximum(max); +} + +int KIntNumInput::singleStep() const +{ + return d->spinbox->singleStep(); +} + +void KIntNumInput::setSingleStep(int singleStep) +{ + d->spinbox->setSingleStep(singleStep); +} + +QString KIntNumInput::suffix() const +{ + return d->spinbox->suffix(); +} + +QString KIntNumInput::prefix() const +{ + return d->spinbox->prefix(); } QString KIntNumInput::specialValueText() const { - return d->intSpinBox->specialValueText(); + return d->spinbox->specialValueText(); } -void KIntNumInput::setLabel(const QString & label, Qt::Alignment a) +void KIntNumInput::setSpecialValueText(const QString &text) { - K_USING_KNUMINPUT_P(priv); - - KNumInput::setLabel(label, a); - - if (priv->label) { - priv->label->setBuddy(d->intSpinBox); - } + d->spinbox->setSpecialValueText(text); } -// ---------------------------------------------------------------------------- +int KIntNumInput::base() const +{ + return d->validator->base(); +} -class KDoubleNumInput::KDoubleNumInputPrivate +void KIntNumInput::setBase(int base) +{ + d->validator->setBase(base); +} + +bool KIntNumInput::sliderEnabled() const +{ + return d->slider->isVisible(); +} + +void KIntNumInput::setSliderEnabled(bool enabled) +{ + d->slider->setVisible(enabled); +} + +QValidator::State KIntNumInput::validate(QString &input, int &pos) const +{ + return d->validator->validate(input, pos); +} + +void KIntNumInput::fixup(QString &input) const +{ + d->validator->fixup(input); +} + +void KIntNumInput::setValue(int value) +{ + d->spinbox->setValue(value); +} + +void KIntNumInput::setSuffix(const KLocalizedString &suffix) +{ + d->suffix = suffix; + d->_k_updateSuffix(d->spinbox->value()); +} + +void KIntNumInput::setSuffix(const QString &suffix) +{ + d->suffix = KLocalizedString(); + d->spinbox->setSuffix(suffix); +} + +void KIntNumInput::setPrefix(const QString &prefix) +{ + d->spinbox->setPrefix(prefix); +} + + +class 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; + KDoubleNumInputPrivate() + : validator(nullptr), + slider(nullptr), + spinbox(nullptr) + { + } + + void _k_updateSuffix(double value) + { + if (suffix.isEmpty()) { + spinbox->setSuffix(QString()); + } else { + spinbox->setSuffix(suffix.subs(value).toString()); + } + } + + KDoubleValidator* validator; + QSlider* slider; + QDoubleSpinBox* spinbox; + KLocalizedString suffix; }; KDoubleNumInput::KDoubleNumInput(QWidget *parent) - : KNumInput(parent) - , d(new KDoubleNumInputPrivate(0.0)) - + : QWidget(parent), + d(new KDoubleNumInputPrivate()) { - init(0.0, 0.0, 9999.0, 0.01, 2); + d->validator = new KDoubleValidator(this); + QHBoxLayout* hboxlayout = new QHBoxLayout(this); + d->slider = new QSlider(this); + d->slider->setVisible(false); + hboxlayout->addWidget(d->slider); + d->spinbox = new QDoubleSpinBox(this); + connect( + d->spinbox, SIGNAL(valueChanged(double)), + this, SIGNAL(valueChanged(double)) + ); + connect( + d->spinbox, SIGNAL(valueChanged(double)), + this, SLOT(_k_updateSuffix(double)) + ); + connect( + d->spinbox, SIGNAL(editingFinished()), + this, SIGNAL(editingFinished()) + ); + hboxlayout->addWidget(d->spinbox); + setLayout(hboxlayout); } -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 +void KDoubleNumInput::setRange(double min, double max) { - 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); + d->spinbox->setRange(min, max); } double KDoubleNumInput::value() const { - return d->spin->value(); + return d->spinbox->value(); } -double KDoubleNumInput::relativeValue() const +double KDoubleNumInput::minimum() const { - if (!d->referencePoint) { - return 0; - } - return value() / d->referencePoint; + return d->spinbox->minimum(); } -double KDoubleNumInput::referencePoint() const +void KDoubleNumInput::setMinimum(double min) { - return d->referencePoint; + d->spinbox->setMinimum(min); +} + +double KDoubleNumInput::maximum() const +{ + return d->spinbox->maximum(); +} + +void KDoubleNumInput::setMaximum(double max) +{ + d->spinbox->setMaximum(max); +} + +double KDoubleNumInput::singleStep() const +{ + return d->spinbox->singleStep(); +} + +void KDoubleNumInput::setSingleStep(double singleStep) +{ + d->spinbox->setSingleStep(singleStep); } QString KDoubleNumInput::suffix() const { - return d->spin->suffix(); + return d->spinbox->suffix(); } QString KDoubleNumInput::prefix() const { - return d->spin->prefix(); + return d->spinbox->prefix(); } -void KDoubleNumInput::setSuffix(const QString &suffix) +QString KDoubleNumInput::specialValueText() const { - d->spin->setSuffix(suffix); - - layout(true); + return d->spinbox->specialValueText(); } -void KDoubleNumInput::setPrefix(const QString &prefix) +void KDoubleNumInput::setSpecialValueText(const QString &text) { - d->spin->setPrefix(prefix); - - layout(true); -} - -void KDoubleNumInput::setDecimals(int decimals) -{ - d->spin->setDecimals(decimals); - - layout(true); + d->spinbox->setSpecialValueText(text); } int KDoubleNumInput::decimals() const { - return d->spin->decimals(); + return d->spinbox->decimals(); } -void KDoubleNumInput::setSpecialValueText(const QString& text) +void KDoubleNumInput::setDecimals(int decimals) { - d->spin->setSpecialValueText(text); - - layout(true); - updateLegacyMembers(); + d->spinbox->setDecimals(decimals); } -void KDoubleNumInput::setLabel(const QString & label, Qt::Alignment a) +bool KDoubleNumInput::sliderEnabled() const { - K_USING_KNUMINPUT_P(priv); - - KNumInput::setLabel(label, a); - - if (priv->label) { - priv->label->setBuddy(d->spin); - } + return d->slider->isVisible(); } -double KDoubleNumInput::exponentRatio() const +void KDoubleNumInput::setSliderEnabled(bool enabled) { - return d->exponentRatio; + d->slider->setVisible(enabled); } -void KDoubleNumInput::setExponentRatio(double dbl) +QValidator::State KDoubleNumInput::validate(QString &input, int &pos) const { - 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."; - } + return d->validator->validate(input, pos); } +void KDoubleNumInput::fixup(QString &input) const +{ + d->validator->fixup(input); +} + +void KDoubleNumInput::setValue(double value) +{ + d->spinbox->setValue(value); +} + +void KDoubleNumInput::setSuffix(const KLocalizedString &suffix) +{ + d->suffix = suffix; + d->_k_updateSuffix(d->spinbox->value()); +} + +void KDoubleNumInput::setSuffix(const QString &suffix) +{ + d->suffix = KLocalizedString(); + d->spinbox->setSuffix(suffix); +} + +void KDoubleNumInput::setPrefix(const QString &prefix) +{ + d->spinbox->setPrefix(prefix); +} #include "moc_knuminput.cpp" diff --git a/kdeui/widgets/knuminput.h b/kdeui/widgets/knuminput.h index 5e2ff113..5e45d231 100644 --- a/kdeui/widgets/knuminput.h +++ b/kdeui/widgets/knuminput.h @@ -1,729 +1,222 @@ -/* This file is part of the KDE libraries - * Copyright (c) 1997 Patrick Dowler - * Copyright (c) 2000 Dirk Mueller - * Copyright (c) 2002 Marc Mutz - * - * 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. - */ +/* + This file is part of the KDE libraries + Copyright (C) 2024 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + 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. +*/ #ifndef K_NUMINPUT_H #define K_NUMINPUT_H #include +#include -#include -#include - -#include -#include +#include #include -class KIntSpinBox; -class KNumInputPrivate; -class KLocalizedString; +class KIntNumInputPrivate; +class KDoubleNumInputPrivate; + /** - * You need to inherit from this class if you want to implement K*NumInput - * for a different variable type - * - */ -class KDEUI_EXPORT KNumInput : public QWidget -{ - Q_OBJECT - Q_PROPERTY( QString label READ label WRITE setLabel ) -public: - /** - * Default constructor - * @param parent If parent is 0, the new widget becomes a top-level - * window. If parent is another widget, this widget becomes a child - * window inside parent. The new widget is deleted when its parent is deleted. - */ - explicit KNumInput(QWidget* parent=0); - - /** - * Destructor - */ - ~KNumInput(); - - /** - * Sets the text and alignment of the main description label. - * - * @param label The text of the label. - * Use QString() to remove an existing one. - * - * @param a The alignment of the label (Qt::Alignment). - * Default is @p Qt:AlignLeft | @p Qt:AlignTop. - * - * The vertical alignment flags have special meaning with this - * widget: - * - * @li @p Qt:AlignTop The label is placed above the edit/slider - * @li @p Qt:AlignVCenter The label is placed left beside the edit - * @li @p Qt:AlignBottom The label is placed below the edit/slider - * - */ - virtual void setLabel(const QString & label, Qt::Alignment a = Qt::AlignLeft | Qt::AlignTop); - - /** - * @return the text of the label. - */ - QString label() const; - - /** - * @return if the num input has a slider. - */ - bool showSlider() const; - - /** - * Sets the spacing of tickmarks for the slider. - * - * @param minor Minor tickmark separation. - * @param major Major tickmark separation. - */ - void setSteps(int minor, int major); - - /** - * Returns a size which fits the contents of the control. - * - * @return the preferred size necessary to show the control - */ - virtual QSize sizeHint() const; - -protected: - /** - * @return the slider widget. - * @internal - */ - QSlider *slider() const; - - /** - * Call this function whenever you change something in the geometry - * of your KNumInput child. - * - */ - void layout(bool deep); - - /** - * You need to overwrite this method and implement your layout - * calculations there. - * - * See KIntNumInput::doLayout and KDoubleNumInput::doLayout implementation - * for details. - * - */ - virtual void doLayout() = 0; - -private: - friend class KNumInputPrivate; - KNumInputPrivate * const d; - - Q_DISABLE_COPY(KNumInput) -}; - -/* ------------------------------------------------------------------------ */ - -/** - * @short An input widget for integer numbers, consisting of a spinbox and a slider. + * @short An input control for numbers with different base. * * KIntNumInput combines a QSpinBox and optionally a QSlider - * with a label to make an easy to use control for setting some integer - * parameter. This is especially nice for configuration dialogs, - * which can have many such combinated controls. + * with a label to make an easy to use control for setting some float + * parameter. * - * The slider is created only when the user specifies a range - * for the control using the setRange function or when the user - * calls setSliderEnabled. - * - * A special feature of KIntNumInput, designed specifically for - * the situation when there are several KIntNumInputs in a column, - * is that you can specify what portion of the control is taken by the - * QSpinBox (the remaining portion is used by the slider). This makes - * it very simple to have all the sliders in a column be the same size. - * - * It uses KIntValidator validator class. KIntNumInput enforces the - * value to be in the given range, and can display it in any base - * between 2 and 36. - * - * \image html kintnuminput.png "KDE Int Number Input Spinbox" + * @see KDoubleNumInput */ - -class KDEUI_EXPORT KIntNumInput : public KNumInput +class KDEUI_EXPORT KIntNumInput : public QWidget { Q_OBJECT - Q_PROPERTY( int value READ value WRITE setValue NOTIFY valueChanged ) - Q_PROPERTY( int minimum READ minimum WRITE setMinimum ) - Q_PROPERTY( int maximum READ maximum WRITE setMaximum ) - Q_PROPERTY( int singleStep READ singleStep WRITE setSingleStep ) - Q_PROPERTY( int referencePoint READ referencePoint WRITE setReferencePoint ) - Q_PROPERTY( double relativeValue READ relativeValue WRITE setRelativeValue ) - Q_PROPERTY( QString suffix READ suffix WRITE setSuffix ) - Q_PROPERTY( QString prefix READ prefix WRITE setPrefix ) - Q_PROPERTY( QString specialValueText READ specialValueText WRITE setSpecialValueText ) - Q_PROPERTY( bool sliderEnabled READ showSlider WRITE setSliderEnabled ) - + Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY(int minimum READ minimum WRITE setMinimum) + Q_PROPERTY(int maximum READ maximum WRITE setMaximum) + Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep) + Q_PROPERTY(QString suffix READ suffix WRITE setSuffix) + Q_PROPERTY(QString prefix READ prefix WRITE setPrefix) + Q_PROPERTY(QString specialValueText READ specialValueText WRITE setSpecialValueText) + Q_PROPERTY(int base READ base WRITE setBase) + Q_PROPERTY(bool sliderEnabled READ sliderEnabled WRITE setSliderEnabled) public: /** - * Constructs an input control for integer values - * with base 10 and initial value 0. + * Constructs an input control for integer values with initial value 0. */ - explicit KIntNumInput(QWidget *parent=0); - /** - * Constructor - * It constructs a QSpinBox that allows the input of integer numbers - * in the range of -INT_MAX to +INT_MAX. To set a descriptive label, - * use setLabel(). To enforce the value being in a range and optionally to - * attach a slider to it, use setRange(). - * - * @param value initial value for the control - * @param base numeric base used for display - * @param parent parent QWidget - */ - explicit KIntNumInput(int value, QWidget *parent=0,int base = 10); + explicit KIntNumInput(QWidget *parent = nullptr); - /** - * Destructor - * - * - */ virtual ~KIntNumInput(); /** - * @return the current value. + * Spin box proxies */ + void setRange(int min, int max); int value() const; - - /** - * @return the curent value in units of the referencePoint. - */ - double relativeValue() const; - - /** - * @return the current reference point - */ - int referencePoint() const; - - /** - * @return the suffix displayed behind the value. - * @see setSuffix() - */ - QString suffix() const; - /** - * @return the prefix displayed in front of the value. - * @see setPrefix() - */ - QString prefix() const; - /** - * @return the string displayed for a special value. - * @see setSpecialValueText() - */ - QString specialValueText() const; - - /** - * Sets the allowed input range and the step size for the slider and the - * spin box. - * - * @param min minimum value - * @param max maximum value - * @param step step size - */ - void setRange(int min, int max, int singleStep=1); - - /** - * @param enabled Show the slider - * @default enabled - */ - void setSliderEnabled(bool enabled=true); - - /** - * Sets the minimum value. - */ - void setMinimum(int min); - /** - * @return the minimum value. - */ int minimum() const; - /** - * Sets the maximum value. - */ - void setMaximum(int max); - /** - * @return the maximum value. - */ + void setMinimum(int min); int maximum() const; - - /** - * @return the step of the spin box - */ + void setMaximum(int max); int singleStep() const; + void setSingleStep(int singleStep); + QString suffix() const; + QString prefix() const; + QString specialValueText() const; + void setSpecialValueText(const QString &text); /** - * @return the step of the spin box + * @return the base in which numbers in the spin box are represented. */ - void setSingleStep(int step); + int base() const; + /** + * Sets the base in which the numbers in the spin box are represented. + */ + void setBase(int base); /** - * Sets the special value text. If set, the SpinBox will display - * this text instead of the numeric value whenever the current - * value is equal to minVal(). Typically this is used for indicating - * that the choice has a special (default) meaning. + * @return if slider is enabled. + * @see setSliderEnabled() */ - void setSpecialValueText(const QString& text); - - virtual void setLabel(const QString & label, Qt::Alignment a = Qt::AlignLeft | Qt::AlignTop); + bool sliderEnabled() const; /** - * This method returns the minimum size necessary to display the - * control. The minimum size is enough to show all the labels - * in the current font (font change may invalidate the return value). - * - * @return the minimum size necessary to show the control + * @param enabled Show the slider + * @default enabled */ - virtual QSize minimumSizeHint() const; + void setSliderEnabled(bool enabled); + + /** + * Validation overrides + */ + virtual QValidator::State validate(QString &input, int &pos) const; + virtual void fixup(QString &input) const; public Q_SLOTS: /** - * Sets the value of the control. - */ - void setValue(int); - - /** - * Sets the value in units of the referencePoint - */ - void setRelativeValue(double); - - /** - * Sets the reference point for relativeValue. - */ - void setReferencePoint(int); - - /** - * Sets the suffix to @p suffix. - * Use QString() to disable this feature. - * Formatting has to be provided (e.g. a space separator between the - * prepended @p value and the suffix's text has to be provided - * as the first character in the suffix). - * - * @see QSpinBox::setSuffix(), #setPrefix() - */ - void setSuffix(const QString &suffix); - - /** - * Sets the suffix to @p suffix. - * Use this to add a plural-aware suffix, e.g. by using ki18np("singular", "plural"). - * - * @since 4.3 + * Spin box proxies */ + void setValue(int value); void setSuffix(const KLocalizedString &suffix); - - /** - * Sets the prefix to @p prefix. - * Use QString() to disable this feature. - * Formatting has to be provided (see above). - * - * @see QSpinBox::setPrefix(), #setSuffix() - */ + void setSuffix(const QString &suffix); void setPrefix(const QString &prefix); - /** - * sets focus to the edit widget and marks all text in if mark == true - * - */ - void setEditFocus( bool mark = true ); - Q_SIGNALS: - /** - * Emitted every time the value changes (by calling setValue() or - * by user interaction). - */ void valueChanged(int); - - /** - * Emitted whenever valueChanged is. Contains the change - * relative to the referencePoint. - */ - void relativeValueChanged(double); - -private Q_SLOTS: - void spinValueChanged(int); - void slotEmitRelativeValueChanged(int); - -protected: - /** - * @return the spin box widget. - * @internal - */ - QSpinBox *spinBox() const; - - virtual void doLayout(); - void resizeEvent ( QResizeEvent * ); + void editingFinished(); private: - void init(int value, int _base); - -private: - class KIntNumInputPrivate; - friend class KIntNumInputPrivate; - KIntNumInputPrivate * const d; + friend KIntNumInputPrivate; + KIntNumInputPrivate* const d; + + Q_PRIVATE_SLOT(d, void _k_updateSuffix(int value)); Q_DISABLE_COPY(KIntNumInput) }; - - -/* ------------------------------------------------------------------------ */ - /** - * @short An input control for real numbers, consisting of a spinbox and a slider. + * @short An input control for real numbers. * * KDoubleNumInput combines a QSpinBox and optionally a QSlider * with a label to make an easy to use control for setting some float - * parameter. This is especially nice for configuration dialogs, - * which can have many such combinated controls. - * - * The slider is created only when the user specifies a range - * for the control using the setRange function with the slider - * parameter set to "true". - * - * A special feature of KDoubleNumInput, designed specifically for - * the situation when there are several instances in a column, - * is that you can specify what portion of the control is taken by the - * QSpinBox (the remaining portion is used by the slider). This makes - * it very simple to have all the sliders in a column be the same size. - * - * \image html kdoublenuminput.png "KDE Double Number Input Spinbox" + * parameter. * * @see KIntNumInput */ -class KDEUI_EXPORT KDoubleNumInput : public KNumInput +class KDEUI_EXPORT KDoubleNumInput : public QWidget { Q_OBJECT - Q_PROPERTY( double value READ value WRITE setValue NOTIFY valueChanged ) - Q_PROPERTY( double minimum READ minimum WRITE setMinimum ) - Q_PROPERTY( double maximum READ maximum WRITE setMaximum ) - Q_PROPERTY( double singleStep READ singleStep WRITE setSingleStep ) - Q_PROPERTY( QString suffix READ suffix WRITE setSuffix ) - Q_PROPERTY( QString prefix READ prefix WRITE setPrefix ) - Q_PROPERTY( QString specialValueText READ specialValueText WRITE setSpecialValueText ) - Q_PROPERTY( int decimals READ decimals WRITE setDecimals ) - Q_PROPERTY( double referencePoint READ referencePoint WRITE setReferencePoint ) - Q_PROPERTY( double relativeValue READ relativeValue WRITE setRelativeValue ) - Q_PROPERTY( bool sliderEnabled READ showSlider WRITE setSliderEnabled ) - Q_PROPERTY( double exponentRatio READ exponentRatio WRITE setExponentRatio ) - + Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY(double minimum READ minimum WRITE setMinimum) + Q_PROPERTY(double maximum READ maximum WRITE setMaximum) + Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep) + Q_PROPERTY(QString suffix READ suffix WRITE setSuffix) + Q_PROPERTY(QString prefix READ prefix WRITE setPrefix) + Q_PROPERTY(QString specialValueText READ specialValueText WRITE setSpecialValueText) + Q_PROPERTY(int decimals READ decimals WRITE setDecimals) + Q_PROPERTY(bool sliderEnabled READ sliderEnabled WRITE setSliderEnabled) public: /** - * Constructs an input control for double values - * with initial value 0.00. + * Constructs an input control for double values with initial value 0.00. */ - explicit KDoubleNumInput(QWidget *parent = 0); + explicit KDoubleNumInput(QWidget *parent = nullptr); - /** - * Constructor - * - * @param lower lower boundary value - * @param upper upper boundary value - * @param value initial value for the control - * @param singleStep step size to use for up/down arrow clicks - * @param precision number of digits after the decimal point - * @param parent parent QWidget - */ - KDoubleNumInput(double lower, double upper, double value, QWidget *parent=0,double singleStep=0.01, - int precision=2); - - /** - * destructor - */ virtual ~KDoubleNumInput(); - /** - * @return the current value. + * Spin box proxies */ + void setRange(double min, double max); double value() const; - - /** - * @return the suffix. - * @see setSuffix() - */ + double minimum() const; + void setMinimum(double min); + double maximum() const; + void setMaximum(double max); + double singleStep() const; + void setSingleStep(double singleStep); QString suffix() const; - - /** - * @return the prefix. - * @see setPrefix() - */ QString prefix() const; + QString specialValueText() const; + void setSpecialValueText(const QString &text); /** * @return number of decimals. * @see setDecimals() */ int decimals() const; - - /** - * @return the string displayed for a special value. - * @see setSpecialValueText() - */ - QString specialValueText() const; - - /** - * @param min minimum value - * @param max maximum value - * @param singleStep step size for the QSlider - * @param slider whether the slider is created or not - */ - void setRange(double min, double max, double singleStep=1, bool slider=true); - - /** - * @param enabled Show the slider - * @default enabled - */ - void setSliderEnabled(bool enabled); - - /** - * Sets the minimum value. - */ - void setMinimum(double min); - /** - * @return the minimum value. - */ - double minimum() const; - /** - * Sets the maximum value. - */ - void setMaximum(double max); - /** - * @return the maximum value. - */ - double maximum() const; - - /** - * @return the step of the spin box - */ - double singleStep() const; - - /** - * @return the step of the spin box - */ - void setSingleStep(double singleStep); - /** * Specifies the number of digits to use. */ void setDecimals(int decimals); + /** + * @return if slider is enabled. + * @see setSliderEnabled() + */ + bool sliderEnabled() const; /** - * @return the reference point for relativeValue calculation + * @param enabled Show the slider + * @default enabled */ - double referencePoint() const; + void setSliderEnabled(bool enabled); /** - * @return the current value in units of referencePoint. + * Validation overrides */ - double relativeValue() const; + virtual QValidator::State validate(QString &input, int &pos) const; + virtual void fixup(QString &input) const; - /** - * Sets the special value text. If set, the spin box will display - * this text instead of the numeric value whenever the current - * value is equal to minVal(). Typically this is used for indicating - * that the choice has a special (default) meaning. - */ - void setSpecialValueText(const QString& text); - - virtual void setLabel(const QString & label, Qt::Alignment a = Qt::AlignLeft | Qt::AlignTop); - virtual QSize minimumSizeHint() const; - - /** - * @return the value of the exponent use to map the slider to the - * spin box. - */ - double exponentRatio() const; - - /** - * @param dbl the value of the exponent use to map the slider to the - * spin box (dbl need to be strictly positive). - */ - void setExponentRatio(double dbl); public Q_SLOTS: /** - * Sets the value of the control. - */ - void setValue(double); - - /** - * Sets the value in units of referencePoint. - */ - void setRelativeValue(double); - - /** - * Sets the reference Point to @p ref. It @p ref == 0, emitting of - * relativeValueChanged is blocked and relativeValue - * just returns 0. - */ - void setReferencePoint(double ref); - - /** - * Sets the suffix to be displayed to @p suffix. Use QString() to disable - * this feature. Note that the suffix is attached to the value without any - * spacing. So if you prefer to display a space separator, set suffix - * to something like " cm". - * @see setSuffix() + * Spin box proxies */ + void setValue(double value); + void setSuffix(const KLocalizedString &suffix); void setSuffix(const QString &suffix); - - /** - * Sets the prefix to be displayed to @p prefix. Use QString() to disable - * this feature. Note that the prefix is attached to the value without any - * spacing. - * @see setPrefix() - */ void setPrefix(const QString &prefix); Q_SIGNALS: - /** - * Emitted every time the value changes (by calling setValue() or - * by user interaction). - */ void valueChanged(double); - /** - * This is an overloaded member function, provided for - * convenience. It essentially behaves like the above function. - * - * Contains the value in units of referencePoint. - */ - void relativeValueChanged(double); - -private Q_SLOTS: - void sliderMoved(int); - void spinBoxChanged(double); - void slotEmitRelativeValueChanged(double); - -protected: - virtual void doLayout(); - void resizeEvent ( QResizeEvent * ); + void editingFinished(); private: - void init(double value, double lower, double upper, - double singleStep, int precision); - double mapSliderToSpin(int) const; - void updateLegacyMembers(); + friend KDoubleNumInputPrivate; + KDoubleNumInputPrivate* const d; -private: - class KDoubleNumInputPrivate; - friend class KDoubleNumInputPrivate; - KDoubleNumInputPrivate * const d; + Q_PRIVATE_SLOT(d, void _k_updateSuffix(double value)); Q_DISABLE_COPY(KDoubleNumInput) }; - -/* ------------------------------------------------------------------------ */ - -/** - * @short A QSpinBox with support for arbitrary base numbers. - * - * A QSpinBox with support for arbitrary base numbers - * (e.g. hexadecimal). - * - * The class provides an easy interface to use other - * numeric systems than the decimal. - * - * \image html kintspinbox.png "KDE Integer Input Spinboxes with hexadecimal and binary input" - */ -class KDEUI_EXPORT KIntSpinBox : public QSpinBox -{ - Q_OBJECT - Q_PROPERTY( int base READ base WRITE setBase ) - -public: - - /** - * Constructor. - * - * Constructs a widget with an integer inputline with a little scrollbar - * and a slider, with minimal value 0, maximal value 99, step 1, base 10 - * and initial value 0. - */ - explicit KIntSpinBox( QWidget *parent = 0 ); - - /** - * Constructor. - * - * Constructs a widget with an integer inputline with a little scrollbar - * and a slider. - * - * @param lower The lowest valid value. - * @param upper The greatest valid value. - * @param singleStep The step size of the scrollbar. - * @param value The actual value. - * @param base The base of the used number system. - * @param parent The parent of the widget. - */ - KIntSpinBox(int lower, int upper, int singleStep, int value, QWidget *parent,int base = 10); - - /** - * Destructor. - */ - virtual ~KIntSpinBox(); - - /** - * Sets the base in which the numbers in the spin box are represented. - */ - void setBase(int base); - /** - * @return the base in which numbers in the spin box are represented. - */ - int base() const; - /** - * sets focus and optionally marks all text - * - */ - void setEditFocus(bool mark); - - /** - * Sets the suffix to @p suffix. - * Use this to add a plural-aware suffix, e.g. by using ki18np("singular", "plural"). - * - * @since 4.3 - */ - void setSuffix(const KLocalizedString &suffix); - - using QSpinBox::setSuffix; - -protected: - - /** - * Overloaded the method in QSpinBox - * to make use of the base given in the constructor. - */ - virtual QString textFromValue(int) const; - - /** - * Overloaded the method in QSpinBox - * to make use of the base given in the constructor. - */ - virtual int valueFromText(const QString &text) const; - -private: - class KIntSpinBoxPrivate; - friend class KIntSpinBoxPrivate; - KIntSpinBoxPrivate *const d; - - Q_DISABLE_COPY(KIntSpinBox) - Q_PRIVATE_SLOT(d, void updateSuffix(int)) -}; - #endif // K_NUMINPUT_H diff --git a/kdewidgets/kde.widgets b/kdewidgets/kde.widgets index f52e1ebf..810396ec 100644 --- a/kdewidgets/kde.widgets +++ b/kdewidgets/kde.widgets @@ -60,12 +60,6 @@ IncludeFile=kdialogbuttonbox.h Group=Buttons (KDE) DomXML=QDialogButtonBox::Ok|QDialogButtonBox::Cancel -[KDoubleNumInput] -ToolTip=Floating Point Number Input Widget (KDE) -WhatsThis=An input widget for floating point numbers, consisting of a spinbox and a slider. -IncludeFile=knuminput.h -Group=Input (KDE) - [KEditListWidget] ToolTip=Fullfeatured edit box with buttons (KDE) Group=Views (KDE) @@ -111,9 +105,10 @@ WhatsThis=An input widget for integer numbers, consisting of a spinbox and a sli IncludeFile=knuminput.h Group=Input (KDE) -[KIntSpinBox] +[KDoubleNumInput] +ToolTip=Floating Point Number Input Widget (KDE) +WhatsThis=An input widget for floating point numbers, consisting of a spinbox and a slider. IncludeFile=knuminput.h -ToolTip=Enhanced Spinbox for Integer Values (KDE) Group=Input (KDE) [KKeySequenceWidget] diff --git a/kdewidgets/pics/CMakeLists.txt b/kdewidgets/pics/CMakeLists.txt index fd9266cb..d37446e4 100644 --- a/kdewidgets/pics/CMakeLists.txt +++ b/kdewidgets/pics/CMakeLists.txt @@ -7,7 +7,6 @@ install( kfontrequester.png kurlrequester.png kcombobox.png - kintspinbox.png kled.png ksqueezedtextlabel.png kurllabel.png diff --git a/kdewidgets/pics/kintspinbox.png b/kdewidgets/pics/kintspinbox.png deleted file mode 100644 index f43b8646..00000000 Binary files a/kdewidgets/pics/kintspinbox.png and /dev/null differ diff --git a/plasma/widgets/spinbox.cpp b/plasma/widgets/spinbox.cpp index 2dc3d123..b221e9e6 100644 --- a/plasma/widgets/spinbox.cpp +++ b/plasma/widgets/spinbox.cpp @@ -24,10 +24,10 @@ #include "private/style_p.h" #include "private/themedwidgetinterface_p.h" #include "theme.h" +#include "kmimetype.h" +#include "knuminput.h" #include -#include -#include namespace Plasma { @@ -48,7 +48,7 @@ SpinBox::SpinBox(QGraphicsWidget *parent) : QGraphicsProxyWidget(parent), d(new SpinBoxPrivate(this)) { - QDoubleSpinBox *native = new QDoubleSpinBox(); + KDoubleNumInput *native = new KDoubleNumInput(); connect(native, SIGNAL(valueChanged(double)), this, SIGNAL(valueChanged(double))); connect(native, SIGNAL(editingFinished()), this, SIGNAL(editingFinished())); @@ -104,9 +104,9 @@ double SpinBox::value() const return nativeWidget()->value(); } -QDoubleSpinBox *SpinBox::nativeWidget() const +KDoubleNumInput *SpinBox::nativeWidget() const { - return static_cast(widget()); + return static_cast(widget()); } void SpinBox::changeEvent(QEvent *event) diff --git a/plasma/widgets/spinbox.h b/plasma/widgets/spinbox.h index f63dfe87..892660d6 100644 --- a/plasma/widgets/spinbox.h +++ b/plasma/widgets/spinbox.h @@ -21,11 +21,12 @@ #ifndef PLASMA_SPINBOX_H #define PLASMA_SPINBOX_H -#include #include #include +class KDoubleNumInput; + namespace Plasma { @@ -65,7 +66,7 @@ public: /** * @return the native widget wrapped by this SpinBox */ - QDoubleSpinBox *nativeWidget() const; + KDoubleNumInput *nativeWidget() const; protected: void changeEvent(QEvent *event); @@ -96,15 +97,6 @@ public Q_SLOTS: void setValue(double value); Q_SIGNALS: - /** - * This signal is emitted when the user drags the slider. - * - * In fact, it is emitted whenever the sliderMoved(double) signal - * of KIntSpinBox would be emitted. See the Qt documentation for - * more information. - */ - void sliderMoved(double value); - /** * This signal is emitted when the slider value has changed, * with the new slider value as argument.