• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • widgets
knuminput.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 * Initial implementation:
3 * Copyright (c) 1997 Patrick Dowler <dowler@morgul.fsh.uvic.ca>
4 * Rewritten and maintained by:
5 * Copyright (c) 2000 Dirk Mueller <mueller@kde.org>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#include "knuminput.h"
24
25#include <config.h>
26#ifdef HAVE_LIMITS_H
27#include <limits.h>
28#endif
29
30#include <cmath>
31
32#include <QtGui/QApplication>
33#include <QtGui/QLabel>
34#include <QtGui/QLineEdit>
35#include <QtGui/QResizeEvent>
36#include <QtGui/QSlider>
37
38#include <kdebug.h>
39#include <kdialog.h>
40#include <klocalizedstring.h>
41
42static inline int calcDiffByTen(int x, int y)
43{
44 // calculate ( x - y ) / 10 without overflowing ints:
45 return (x / 10) - (y / 10) + (x % 10 - y % 10) / 10;
46}
47
48// ----------------------------------------------------------------------------
49
50class KNumInputPrivate
51{
52public:
53 KNumInputPrivate(KNumInput *q, KNumInput *below = 0) :
54 q(q),
55 previousNumInput(0),
56 nextNumInput(0),
57 column1Width(0),
58 column2Width(0),
59 label(0),
60 slider(0),
61 labelAlignment(0)
62 {
63 if (below) {
64 nextNumInput = below->d->nextNumInput;
65 previousNumInput = below;
66 below->d->nextNumInput = q;
67 if (nextNumInput) {
68 nextNumInput->d->previousNumInput = q;
69 }
70 }
71 }
72
73 static KNumInputPrivate *get(const KNumInput *i) {
74 return i->d;
75 }
76
77 KNumInput *q;
78 KNumInput* previousNumInput, *nextNumInput;
79 int column1Width, column2Width;
80
81 QLabel* label;
82 QSlider* slider;
83 QSize sliderSize, labelSize;
84
85 Qt::Alignment labelAlignment;
86};
87
88
89#define K_USING_KNUMINPUT_P(_d) KNumInputPrivate *_d = KNumInputPrivate::get(this)
90
91KNumInput::KNumInput(QWidget* parent)
92 : QWidget(parent), d(new KNumInputPrivate(this))
93{
94 setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
95 setFocusPolicy(Qt::StrongFocus);
96}
97
98#ifndef KDE_NO_DEPRECATED
99KNumInput::KNumInput(QWidget* parent, KNumInput* below)
100 : QWidget(parent), d(new KNumInputPrivate(this, below))
101{
102 setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
103 setFocusPolicy(Qt::StrongFocus);
104}
105#endif
106
107KNumInput::~KNumInput()
108{
109 if (d->previousNumInput) {
110 d->previousNumInput->d->nextNumInput = d->nextNumInput;
111 }
112
113 if (d->nextNumInput) {
114 d->nextNumInput->d->previousNumInput = d->previousNumInput;
115 }
116
117 delete d;
118}
119
120QSlider *KNumInput::slider() const
121{
122 return d->slider;
123}
124
125bool KNumInput::showSlider() const
126{
127 return d->slider;
128}
129
130void KNumInput::setLabel(const QString & label, Qt::Alignment a)
131{
132 if (label.isEmpty()) {
133 delete d->label;
134 d->label = 0;
135 d->labelAlignment = 0;
136 } else {
137 if (!d->label) {
138 d->label = new QLabel(this);
139 }
140 d->label->setText(label);
141 d->label->setObjectName("KNumInput::QLabel");
142 d->label->setAlignment(a);
143 // if no vertical alignment set, use Top alignment
144 if (!(a & (Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter))) {
145 a |= Qt::AlignTop;
146 }
147 d->labelAlignment = a;
148 }
149
150 layout(true);
151}
152
153QString KNumInput::label() const
154{
155 return d->label ? d->label->text() : QString();
156}
157
158void KNumInput::layout(bool deep)
159{
160 int w1 = d->column1Width;
161 int w2 = d->column2Width;
162
163 // label sizeHint
164 d->labelSize = (d->label ? d->label->sizeHint() : QSize(0, 0));
165
166 if (d->label && (d->labelAlignment & Qt::AlignVCenter)) {
167 d->column1Width = d->labelSize.width() + 4;
168 } else {
169 d->column1Width = 0;
170 }
171
172 // slider sizeHint
173 d->sliderSize = (d->slider ? d->slider->sizeHint() : QSize(0, 0));
174
175 doLayout();
176
177 if (!deep) {
178 d->column1Width = w1;
179 d->column2Width = w2;
180 return;
181 }
182
183 w2 = d->column2Width;
184
185 KNumInput* p = d->previousNumInput;
186 while (p) {
187 p->doLayout();
188 w1 = qMax(w1, p->d->column1Width);
189 w2 = qMax(w2, p->d->column2Width);
190 p = p->d->previousNumInput;
191 }
192
193 p = d->nextNumInput;
194 while (p) {
195 p->doLayout();
196 w1 = qMax(w1, p->d->column1Width);
197 w2 = qMax(w2, p->d->column2Width);
198 p = p->d->nextNumInput;
199 }
200
201 p = this;
202 while (p) {
203 p->d->column1Width = w1;
204 p->d->column2Width = w2;
205 p = p->d->previousNumInput;
206 }
207
208 p = d->nextNumInput;
209 while (p) {
210 p->d->column1Width = w1;
211 p->d->column2Width = w2;
212 p = p->d->nextNumInput;
213 }
214
215// kDebug() << "w1 " << w1 << " w2 " << w2;
216}
217
218QSize KNumInput::sizeHint() const
219{
220 return minimumSizeHint();
221}
222
223void KNumInput::setSteps(int minor, int major)
224{
225 if (d->slider) {
226 d->slider->setSingleStep(minor);
227 d->slider->setPageStep(major);
228 }
229}
230
231
232// ----------------------------------------------------------------------------
233
234class KIntSpinBox::KIntSpinBoxPrivate
235{
236public:
237 KIntSpinBoxPrivate(KIntSpinBox *q, int val_base = 10): q(q), val_base(val_base)
238 {
239 connect(q, SIGNAL(valueChanged(int)), q, SLOT(updateSuffix(int)));
240 }
241
242 void updateSuffix(int value)
243 {
244 if (!pluralSuffix.isEmpty()) {
245 KLocalizedString s = pluralSuffix;
246 q->setSuffix(s.subs(value).toString());
247 }
248 }
249
250 KIntSpinBox *q;
251 int val_base;
252 KLocalizedString pluralSuffix;
253};
254
255KIntSpinBox::KIntSpinBox(QWidget *parent)
256 : QSpinBox(parent), d(new KIntSpinBoxPrivate(this))
257{
258 setValue(0);
259}
260
261KIntSpinBox::~KIntSpinBox()
262{
263 delete d;
264}
265
266KIntSpinBox::KIntSpinBox(int lower, int upper, int singleStep, int value, QWidget *parent, int base)
267 : QSpinBox(parent), d(new KIntSpinBoxPrivate(this, base))
268{
269 setRange(lower, upper);
270 setSingleStep(singleStep);
271 setValue(value);
272}
273
274void KIntSpinBox::setBase(int base)
275{
276 d->val_base = base;
277}
278
279
280int KIntSpinBox::base() const
281{
282 return d->val_base;
283}
284
285QString KIntSpinBox::textFromValue(int v) const
286{
287 return QString::number(v, d->val_base);
288}
289
290int KIntSpinBox::valueFromText(const QString &text) const
291{
292 bool ok;
293 QString theText = text;
294 if (theText.startsWith(prefix())) {
295 theText.remove(0, prefix().length());
296 }
297 if (theText.endsWith(suffix())) {
298 theText.chop(suffix().length());
299 }
300 return theText.trimmed().toInt(&ok, d->val_base);
301}
302
303void KIntSpinBox::setEditFocus(bool mark)
304{
305 lineEdit()->setFocus();
306 if (mark) {
307 lineEdit()->selectAll();
308 }
309}
310
311void KIntSpinBox::setSuffix(const KLocalizedString& suffix)
312{
313 d->pluralSuffix = suffix;
314 if (suffix.isEmpty())
315 setSuffix(QString());
316 else
317 d->updateSuffix(value());
318}
319
320// ----------------------------------------------------------------------------
321
322class KIntNumInput::KIntNumInputPrivate
323{
324public:
325 KIntNumInput *q;
326 int referencePoint;
327 short blockRelative;
328 KIntSpinBox* intSpinBox;
329 QSize intSpinBoxSize;
330
331 KIntNumInputPrivate(KIntNumInput *q, int r)
332 : q(q),
333 referencePoint(r),
334 blockRelative(0) {}
335};
336
337
338#ifndef KDE_NO_DEPRECATED
339KIntNumInput::KIntNumInput(KNumInput* below, int val, QWidget *parent, int _base)
340 : KNumInput(parent, below)
341 , d(new KIntNumInputPrivate(this, val))
342{
343 init(val, _base);
344}
345#endif
346
347KIntNumInput::KIntNumInput(QWidget *parent)
348 : KNumInput(parent)
349 , d(new KIntNumInputPrivate(this, 0))
350{
351 init(0, 10);
352}
353
354KIntNumInput::KIntNumInput(int val, QWidget *parent, int _base)
355 : KNumInput(parent)
356 , d(new KIntNumInputPrivate(this, val))
357{
358 init(val, _base);
359}
360
361QSpinBox *KIntNumInput::spinBox() const
362{
363 return d->intSpinBox;
364}
365
366void KIntNumInput::init(int val, int _base)
367{
368 d->intSpinBox = new KIntSpinBox(INT_MIN, INT_MAX, 1, val, this, _base);
369 d->intSpinBox->setObjectName("KIntNumInput::KIntSpinBox");
370 // the KIntValidator is broken beyond believe for
371 // spinboxes which have suffix or prefix texts, so
372 // better don't use it unless absolutely necessary
373
374 if (_base != 10) {
375 kWarning() << "WARNING: Validation is broken in KIntNumInput! Needs to be fixed.";
376// d->intSpinBox->setValidator(new KIntValidator(this, _base, "KNumInput::KIntValidator"));
377 }
378
379 connect(d->intSpinBox, SIGNAL(valueChanged(int)), SLOT(spinValueChanged(int)));
380 connect(this, SIGNAL(valueChanged(int)),
381 SLOT(slotEmitRelativeValueChanged(int)));
382
383 setFocusProxy(d->intSpinBox);
384 layout(true);
385}
386
387void KIntNumInput::setReferencePoint(int ref)
388{
389 // clip to valid range:
390 ref = qMin(maximum(), qMax(minimum(), ref));
391 d->referencePoint = ref;
392}
393
394int KIntNumInput::referencePoint() const
395{
396 return d->referencePoint;
397}
398
399void KIntNumInput::spinValueChanged(int val)
400{
401 K_USING_KNUMINPUT_P(priv);
402
403 if (priv->slider) {
404 priv->slider->setValue(val);
405 }
406
407 emit valueChanged(val);
408}
409
410void KIntNumInput::slotEmitRelativeValueChanged(int value)
411{
412 if (d->blockRelative || !d->referencePoint) {
413 return;
414 }
415 emit relativeValueChanged(double(value) / double(d->referencePoint));
416}
417
418void KIntNumInput::setSliderEnabled(bool slider)
419{
420 K_USING_KNUMINPUT_P(priv);
421 if (slider) {
422 if (!priv->slider) {
423 priv->slider = new QSlider(Qt::Horizontal, this);
424 connect(priv->slider, SIGNAL(valueChanged(int)),
425 d->intSpinBox, SLOT(setValue(int)));
426 priv->slider->setTickPosition(QSlider::TicksBelow);
427 layout(true);
428 }
429
430 const int value = d->intSpinBox->value();
431 priv->slider->setRange(d->intSpinBox->minimum(), d->intSpinBox->maximum());
432 priv->slider->setPageStep(d->intSpinBox->singleStep());
433 priv->slider->setValue(value);
434
435 // calculate (upper-lower)/10 without overflowing int's:
436 const int major = calcDiffByTen(d->intSpinBox->maximum(), d->intSpinBox->minimum());
437
438 priv->slider->setSingleStep(d->intSpinBox->singleStep());
439 priv->slider->setPageStep(qMax(1, major));
440 priv->slider->setTickInterval(major);
441 } else {
442 if (priv->slider) {
443 layout(true);
444 }
445 delete priv->slider;
446 priv->slider = 0;
447 }
448}
449
450void KIntNumInput::setRange(int lower, int upper, int singleStep)
451{
452 if (upper < lower || singleStep <= 0) {
453 kWarning() << "WARNING: KIntNumInput::setRange() called with bad arguments. Ignoring call...";
454 return;
455 }
456
457 d->intSpinBox->setMinimum(lower);
458 d->intSpinBox->setMaximum(upper);
459 d->intSpinBox->setSingleStep(singleStep);
460
461 singleStep = d->intSpinBox->singleStep(); // maybe QRangeControl didn't like our lineStep?
462
463 // check that reference point is still inside valid range:
464 setReferencePoint(referencePoint());
465
466 layout(true);
467
468 // update slider information if it's shown
469 K_USING_KNUMINPUT_P(priv);
470 setSliderEnabled(priv->slider);
471}
472
473#ifndef KDE_NO_DEPRECATED
474void KIntNumInput::setRange(int lower, int upper, int singleStep, bool slider)
475{
476 setRange(lower, upper, singleStep);
477 setSliderEnabled(slider);
478}
479#endif
480
481void KIntNumInput::setMinimum(int min)
482{
483 setRange(min, d->intSpinBox->maximum(), d->intSpinBox->singleStep());
484}
485
486int KIntNumInput::minimum() const
487{
488 return d->intSpinBox->minimum();
489}
490
491void KIntNumInput::setMaximum(int max)
492{
493 setRange(d->intSpinBox->minimum(), max, d->intSpinBox->singleStep());
494}
495
496int KIntNumInput::maximum() const
497{
498 return d->intSpinBox->maximum();
499}
500
501int KIntNumInput::singleStep() const
502{
503 return d->intSpinBox->singleStep();
504}
505
506void KIntNumInput::setSingleStep(int singleStep)
507{
508 d->intSpinBox->setSingleStep(singleStep);
509}
510
511void KIntNumInput::setSuffix(const QString &suffix)
512{
513 d->intSpinBox->setSuffix(suffix);
514
515 layout(true);
516}
517
518void KIntNumInput::setSuffix(const KLocalizedString& suffix)
519{
520 d->intSpinBox->setSuffix(suffix);
521 layout(true);
522}
523
524QString KIntNumInput::suffix() const
525{
526 return d->intSpinBox->suffix();
527}
528
529void KIntNumInput::setPrefix(const QString &prefix)
530{
531 d->intSpinBox->setPrefix(prefix);
532
533 layout(true);
534}
535
536QString KIntNumInput::prefix() const
537{
538 return d->intSpinBox->prefix();
539}
540
541void KIntNumInput::setEditFocus(bool mark)
542{
543 d->intSpinBox->setEditFocus(mark);
544}
545
546QSize KIntNumInput::minimumSizeHint() const
547{
548 K_USING_KNUMINPUT_P(priv);
549 ensurePolished();
550
551 int w;
552 int h;
553
554 h = qMax(d->intSpinBoxSize.height(), priv->sliderSize.height());
555
556 // if in extra row, then count it here
557 if (priv->label && (priv->labelAlignment & (Qt::AlignBottom | Qt::AlignTop))) {
558 h += 4 + priv->labelSize.height();
559 } else {
560 // label is in the same row as the other widgets
561 h = qMax(h, priv->labelSize.height() + 2);
562 }
563
564 w = priv->slider ? priv->slider->sizeHint().width() + KDialog::spacingHint() : 0;
565 w += priv->column1Width + priv->column2Width;
566
567 if (priv->labelAlignment & (Qt::AlignTop | Qt::AlignBottom)) {
568 w = qMax(w, priv->labelSize.width() + 4);
569 }
570
571 return QSize(w, h);
572}
573
574void KIntNumInput::doLayout()
575{
576 K_USING_KNUMINPUT_P(priv);
577
578 d->intSpinBoxSize = d->intSpinBox->sizeHint();
579 priv->column2Width = d->intSpinBoxSize.width();
580
581 if (priv->label) {
582 priv->label->setBuddy(d->intSpinBox);
583 }
584}
585
586void KIntNumInput::resizeEvent(QResizeEvent* e)
587{
588 K_USING_KNUMINPUT_P(priv);
589
590 int w = priv->column1Width;
591 int h = 0;
592
593 if (priv->label && (priv->labelAlignment & Qt::AlignTop)) {
594 priv->label->setGeometry(0, 0, e->size().width(), priv->labelSize.height());
595 h += priv->labelSize.height() + KDialog::spacingHint();
596 }
597
598 if (priv->label && (priv->labelAlignment & Qt::AlignVCenter)) {
599 priv->label->setGeometry(0, 0, w, d->intSpinBoxSize.height());
600 }
601
602 if (qApp->layoutDirection() == Qt::RightToLeft) {
603 d->intSpinBox->setGeometry(w, h, priv->slider ? priv->column2Width : qMax(priv->column2Width, e->size().width() - w), d->intSpinBoxSize.height());
604 w += priv->column2Width + KDialog::spacingHint();
605
606 if (priv->slider) {
607 priv->slider->setGeometry(w, h, e->size().width() - w, d->intSpinBoxSize.height() + KDialog::spacingHint());
608 }
609 } else if (priv->slider) {
610 priv->slider->setGeometry(w, h, e->size().width() - (w + priv->column2Width + KDialog::spacingHint()), d->intSpinBoxSize.height() + KDialog::spacingHint());
611 d->intSpinBox->setGeometry(w + priv->slider->size().width() + KDialog::spacingHint(), h, priv->column2Width, d->intSpinBoxSize.height());
612 } else {
613 d->intSpinBox->setGeometry(w, h, qMax(priv->column2Width, e->size().width() - w), d->intSpinBoxSize.height());
614 }
615
616 h += d->intSpinBoxSize.height() + 2;
617
618 if (priv->label && (priv->labelAlignment & Qt::AlignBottom)) {
619 priv->label->setGeometry(0, h, priv->labelSize.width(), priv->labelSize.height());
620 }
621}
622
623KIntNumInput::~KIntNumInput()
624{
625 delete d;
626}
627
628void KIntNumInput::setValue(int val)
629{
630 d->intSpinBox->setValue(val);
631 // slider value is changed by spinValueChanged
632}
633
634void KIntNumInput::setRelativeValue(double r)
635{
636 if (!d->referencePoint) {
637 return;
638 }
639 ++d->blockRelative;
640 setValue(qRound(d->referencePoint * r + 0.5));
641 --d->blockRelative;
642}
643
644double KIntNumInput::relativeValue() const
645{
646 if (!d->referencePoint) {
647 return 0;
648 }
649 return double(value()) / double(d->referencePoint);
650}
651
652int KIntNumInput::value() const
653{
654 return d->intSpinBox->value();
655}
656
657void KIntNumInput::setSpecialValueText(const QString& text)
658{
659 d->intSpinBox->setSpecialValueText(text);
660 layout(true);
661}
662
663QString KIntNumInput::specialValueText() const
664{
665 return d->intSpinBox->specialValueText();
666}
667
668void KIntNumInput::setLabel(const QString & label, Qt::Alignment a)
669{
670 K_USING_KNUMINPUT_P(priv);
671
672 KNumInput::setLabel(label, a);
673
674 if (priv->label) {
675 priv->label->setBuddy(d->intSpinBox);
676 }
677}
678
679// ----------------------------------------------------------------------------
680
681class KDoubleNumInput::KDoubleNumInputPrivate
682{
683public:
684 KDoubleNumInputPrivate(double r)
685 : spin(0),
686 referencePoint(r),
687 blockRelative(0),
688 exponentRatio(1.0) {}
689 QDoubleSpinBox * spin;
690 double referencePoint;
691 short blockRelative;
692 QSize editSize;
693 QString specialValue;
694 double exponentRatio;
695};
696
697KDoubleNumInput::KDoubleNumInput(QWidget *parent)
698 : KNumInput(parent)
699 , d(new KDoubleNumInputPrivate(0.0))
700
701{
702 init(0.0, 0.0, 9999.0, 0.01, 2);
703}
704
705KDoubleNumInput::KDoubleNumInput(double lower, double upper, double value, QWidget *parent,
706 double singleStep, int precision)
707 : KNumInput(parent)
708 , d(new KDoubleNumInputPrivate(value))
709{
710 init(value, lower, upper, singleStep, precision);
711}
712
713#ifndef KDE_NO_DEPRECATED
714KDoubleNumInput::KDoubleNumInput(KNumInput *below,
715 double lower, double upper, double value, QWidget *parent,
716 double singleStep, int precision)
717 : KNumInput(parent, below)
718 , d(new KDoubleNumInputPrivate(value))
719{
720 init(value, lower, upper, singleStep, precision);
721}
722#endif
723
724KDoubleNumInput::~KDoubleNumInput()
725{
726 delete d;
727}
728
729QString KDoubleNumInput::specialValueText() const
730{
731 return d->specialValue;
732}
733
734
735void KDoubleNumInput::init(double value, double lower, double upper,
736 double singleStep, int precision)
737{
738 d->spin = new QDoubleSpinBox(this);
739 d->spin->setRange(lower, upper);
740 d->spin->setSingleStep(singleStep);
741 d->spin->setValue(value);
742 d->spin->setDecimals(precision);
743
744 d->spin->setObjectName("KDoubleNumInput::QDoubleSpinBox");
745 setFocusProxy(d->spin);
746 connect(d->spin, SIGNAL(valueChanged(double)),
747 this, SIGNAL(valueChanged(double)));
748 connect(this, SIGNAL(valueChanged(double)),
749 this, SLOT(slotEmitRelativeValueChanged(double)));
750
751 updateLegacyMembers();
752
753 layout(true);
754}
755
756void KDoubleNumInput::updateLegacyMembers()
757{
758 d->specialValue = specialValueText();
759}
760
761double KDoubleNumInput::mapSliderToSpin(int val) const
762{
763 K_USING_KNUMINPUT_P(priv);
764
765 // map [slidemin,slidemax] to [spinmin,spinmax]
766 const double spinmin = d->spin->minimum();
767 const double spinmax = d->spin->maximum();
768 const double slidemin = priv->slider->minimum(); // cast int to double to avoid
769 const double slidemax = priv->slider->maximum(); // overflow in rel denominator
770 const double rel = (double(val) - slidemin) / (slidemax - slidemin);
771 Q_ASSERT(d->exponentRatio > 0.0);
772 return spinmin + pow(rel, d->exponentRatio ) * (spinmax - spinmin);
773}
774
775void KDoubleNumInput::sliderMoved(int val)
776{
777 d->spin->setValue(mapSliderToSpin(val));
778}
779
780void KDoubleNumInput::spinBoxChanged(double val)
781{
782 K_USING_KNUMINPUT_P(priv);
783
784 const double spinmin = d->spin->minimum();
785 const double spinmax = d->spin->maximum();
786 const double slidemin = priv->slider->minimum(); // cast int to double to avoid
787 const double slidemax = priv->slider->maximum(); // overflow in rel denominator
788
789 Q_ASSERT(d->exponentRatio > 0.0);
790 const double rel = pow((val - spinmin) / (spinmax - spinmin) , 1.0 / d->exponentRatio);
791
792 if (priv->slider) {
793 priv->slider->blockSignals(true);
794 priv->slider->setValue(qRound(slidemin + rel * (slidemax - slidemin)));
795 priv->slider->blockSignals(false);
796 }
797}
798
799void KDoubleNumInput::slotEmitRelativeValueChanged(double value)
800{
801 if (!d->referencePoint) {
802 return;
803 }
804 emit relativeValueChanged(value / d->referencePoint);
805}
806
807QSize KDoubleNumInput::minimumSizeHint() const
808{
809 K_USING_KNUMINPUT_P(priv);
810
811 ensurePolished();
812
813 int w;
814 int h;
815
816 h = qMax(d->editSize.height(), priv->sliderSize.height());
817
818 // if in extra row, then count it here
819 if (priv->label && (priv->labelAlignment & (Qt::AlignBottom | Qt::AlignTop))) {
820 h += 4 + priv->labelSize.height();
821 } else {
822 // label is in the same row as the other widgets
823 h = qMax(h, priv->labelSize.height() + 2);
824 }
825
826 w = priv->slider ? priv->slider->sizeHint().width() + KDialog::spacingHint() : 0;
827 w += priv->column1Width + priv->column2Width;
828
829 if (priv->labelAlignment & (Qt::AlignTop | Qt::AlignBottom)) {
830 w = qMax(w, priv->labelSize.width() + 4);
831 }
832
833 return QSize(w, h);
834}
835
836void KDoubleNumInput::resizeEvent(QResizeEvent* e)
837{
838 K_USING_KNUMINPUT_P(priv);
839
840 int w = priv->column1Width;
841 int h = 0;
842
843 if (priv->label && (priv->labelAlignment & Qt::AlignTop)) {
844 priv->label->setGeometry(0, 0, e->size().width(), priv->labelSize.height());
845 h += priv->labelSize.height() + 4;
846 }
847
848 if (priv->label && (priv->labelAlignment & Qt::AlignVCenter)) {
849 priv->label->setGeometry(0, 0, w, d->editSize.height());
850 }
851
852 if (qApp->layoutDirection() == Qt::RightToLeft) {
853 d->spin->setGeometry(w, h, priv->slider ? priv->column2Width
854 : e->size().width() - w, d->editSize.height());
855 w += priv->column2Width + KDialog::spacingHint();
856
857 if (priv->slider)
858 priv->slider->setGeometry(w, h, e->size().width() - w, d->editSize.height() + KDialog::spacingHint());
859 } else if (priv->slider) {
860 priv->slider->setGeometry(w, h, e->size().width() -
861 (priv->column1Width + priv->column2Width + KDialog::spacingHint()),
862 d->editSize.height() + KDialog::spacingHint());
863 d->spin->setGeometry(w + priv->slider->width() + KDialog::spacingHint(), h,
864 priv->column2Width, d->editSize.height());
865 } else {
866 d->spin->setGeometry(w, h, e->size().width() - w, d->editSize.height());
867 }
868
869 h += d->editSize.height() + 2;
870
871 if (priv->label && (priv->labelAlignment & Qt::AlignBottom)) {
872 priv->label->setGeometry(0, h, priv->labelSize.width(), priv->labelSize.height());
873 }
874}
875
876void KDoubleNumInput::doLayout()
877{
878 K_USING_KNUMINPUT_P(priv);
879
880 d->editSize = d->spin->sizeHint();
881 priv->column2Width = d->editSize.width();
882}
883
884void KDoubleNumInput::setValue(double val)
885{
886 d->spin->setValue(val);
887}
888
889void KDoubleNumInput::setRelativeValue(double r)
890{
891 if (!d->referencePoint) {
892 return;
893 }
894 ++d->blockRelative;
895 setValue(r * d->referencePoint);
896 --d->blockRelative;
897}
898
899void KDoubleNumInput::setReferencePoint(double ref)
900{
901 // clip to valid range:
902 ref = qMin(maximum(), qMax(minimum(), ref));
903 d->referencePoint = ref;
904}
905
906void KDoubleNumInput::setRange(double lower, double upper, double singleStep,
907 bool slider)
908{
909 K_USING_KNUMINPUT_P(priv);
910
911 if (priv->slider) {
912 // don't update the slider to avoid an endless recursion
913 QDoubleSpinBox * spin = d->spin;
914 disconnect(spin, SIGNAL(valueChanged(double)),
915 priv->slider, SLOT(setValue(int)));
916 }
917 d->spin->setRange(lower, upper);
918 d->spin->setSingleStep(singleStep);
919
920 setSliderEnabled(slider);
921
922 setReferencePoint(referencePoint());
923
924 layout(true);
925 updateLegacyMembers();
926}
927
928void KDoubleNumInput::setSliderEnabled(bool enabled)
929{
930 K_USING_KNUMINPUT_P(priv);
931 if (enabled) {
932 QDoubleSpinBox * spin = d->spin;
933 const double range = spin->maximum() - spin->minimum();
934 const double steps = range * pow(10.0, spin->decimals());
935 if (!priv->slider) {
936 priv->slider = new QSlider(Qt::Horizontal, this);
937 priv->slider->setTickPosition(QSlider::TicksBelow);
938 // feedback line: when one moves, the other moves, too:
939 connect(priv->slider, SIGNAL(valueChanged(int)),
940 SLOT(sliderMoved(int)));
941 layout(true);
942 }
943 if (steps > 1000 || d->exponentRatio != 1.0) {
944 priv->slider->setRange(0, 1000);
945 priv->slider->setSingleStep(1);
946 priv->slider->setPageStep(50);
947 } else {
948 const int singleSteps = qRound(steps);
949 priv->slider->setRange(0, singleSteps);
950 priv->slider->setSingleStep(1);
951 const int pageSteps = qBound(1, singleSteps / 20, 10);
952 priv->slider->setPageStep(pageSteps);
953 }
954 spinBoxChanged(spin->value());
955 connect(spin, SIGNAL(valueChanged(double)), SLOT(spinBoxChanged(double)));
956 } else {
957 if (priv->slider) {
958 layout(true);
959 }
960 delete priv->slider;
961 priv->slider = 0;
962 }
963}
964
965
966void KDoubleNumInput::setMinimum(double min)
967{
968 K_USING_KNUMINPUT_P(priv);
969 setRange(min, maximum(), d->spin->singleStep(), priv->slider);
970}
971
972double KDoubleNumInput::minimum() const
973{
974 return d->spin->minimum();
975}
976
977void KDoubleNumInput::setMaximum(double max)
978{
979 K_USING_KNUMINPUT_P(priv);
980 setRange(minimum(), max, d->spin->singleStep(), priv->slider);
981}
982
983double KDoubleNumInput::maximum() const
984{
985 return d->spin->maximum();
986}
987
988double KDoubleNumInput::singleStep() const
989{
990 return d->spin->singleStep();
991}
992
993void KDoubleNumInput::setSingleStep(double singleStep)
994{
995 d->spin->setSingleStep(singleStep);
996}
997
998double KDoubleNumInput::value() const
999{
1000 return d->spin->value();
1001}
1002
1003double KDoubleNumInput::relativeValue() const
1004{
1005 if (!d->referencePoint) {
1006 return 0;
1007 }
1008 return value() / d->referencePoint;
1009}
1010
1011double KDoubleNumInput::referencePoint() const
1012{
1013 return d->referencePoint;
1014}
1015
1016QString KDoubleNumInput::suffix() const
1017{
1018 return d->spin->suffix();
1019}
1020
1021QString KDoubleNumInput::prefix() const
1022{
1023 return d->spin->prefix();
1024}
1025
1026void KDoubleNumInput::setSuffix(const QString &suffix)
1027{
1028 d->spin->setSuffix(suffix);
1029
1030 layout(true);
1031}
1032
1033void KDoubleNumInput::setPrefix(const QString &prefix)
1034{
1035 d->spin->setPrefix(prefix);
1036
1037 layout(true);
1038}
1039
1040void KDoubleNumInput::setDecimals(int decimals)
1041{
1042 d->spin->setDecimals(decimals);
1043
1044 layout(true);
1045}
1046
1047int KDoubleNumInput::decimals() const
1048{
1049 return d->spin->decimals();
1050}
1051
1052void KDoubleNumInput::setSpecialValueText(const QString& text)
1053{
1054 d->spin->setSpecialValueText(text);
1055
1056 layout(true);
1057 updateLegacyMembers();
1058}
1059
1060void KDoubleNumInput::setLabel(const QString & label, Qt::Alignment a)
1061{
1062 K_USING_KNUMINPUT_P(priv);
1063
1064 KNumInput::setLabel(label, a);
1065
1066 if (priv->label) {
1067 priv->label->setBuddy(d->spin);
1068 }
1069}
1070
1071double KDoubleNumInput::exponentRatio() const
1072{
1073 return d->exponentRatio;
1074}
1075
1076void KDoubleNumInput::setExponentRatio(double dbl)
1077{
1078 Q_ASSERT(dbl > 0.0);
1079 if(dbl > 0.0) {
1080 d->exponentRatio = dbl;
1081 spinBoxChanged( d->spin->value() ); // used to reset the value of the slider
1082 } else {
1083 kError() << "ExponentRatio need to be strictly positive.";
1084 }
1085}
1086
1087
1088#include "knuminput.moc"
KDialog::spacingHint
static int spacingHint()
Returns the number of pixels that should be used between widgets inside a dialog according to the KDE...
Definition: kdialog.cpp:432
KDoubleNumInput::setDecimals
void setDecimals(int decimals)
Specifies the number of digits to use.
Definition: knuminput.cpp:1040
KDoubleNumInput::singleStep
double singleStep
Definition: knuminput.h:456
KDoubleNumInput::suffix
QString suffix
Definition: knuminput.h:457
KDoubleNumInput::value
double value
Definition: knuminput.h:453
KDoubleNumInput::specialValueText
QString specialValueText
Definition: knuminput.h:459
KDoubleNumInput::setSliderEnabled
void setSliderEnabled(bool enabled)
Definition: knuminput.cpp:928
KDoubleNumInput::maximum
double maximum
Definition: knuminput.h:455
KDoubleNumInput::relativeValueChanged
void relativeValueChanged(double)
This is an overloaded member function, provided for convenience.
KDoubleNumInput::prefix
QString prefix
Definition: knuminput.h:458
KDoubleNumInput::relativeValue
double relativeValue
Definition: knuminput.h:462
KDoubleNumInput::setValue
void setValue(double)
Sets the value of the control.
Definition: knuminput.cpp:884
KDoubleNumInput::doLayout
virtual void doLayout()
You need to overwrite this method and implement your layout calculations there.
Definition: knuminput.cpp:876
KDoubleNumInput::setPrefix
void setPrefix(const QString &prefix)
Sets the prefix to be displayed to prefix.
Definition: knuminput.cpp:1033
KDoubleNumInput::setSuffix
void setSuffix(const QString &suffix)
Sets the suffix to be displayed to suffix.
Definition: knuminput.cpp:1026
KDoubleNumInput::minimumSizeHint
virtual QSize minimumSizeHint() const
Definition: knuminput.cpp:807
KDoubleNumInput::setMaximum
void setMaximum(double max)
Sets the maximum value.
Definition: knuminput.cpp:977
KDoubleNumInput::setRange
void setRange(double min, double max, double singleStep=1, bool slider=true)
Definition: knuminput.cpp:906
KDoubleNumInput::decimals
int decimals
Definition: knuminput.h:460
KDoubleNumInput::setReferencePoint
void setReferencePoint(double ref)
Sets the reference Point to ref.
Definition: knuminput.cpp:899
KDoubleNumInput::setSpecialValueText
void setSpecialValueText(const QString &text)
Sets the special value text.
Definition: knuminput.cpp:1052
KDoubleNumInput::resizeEvent
void resizeEvent(QResizeEvent *)
Definition: knuminput.cpp:836
KDoubleNumInput::setRelativeValue
void setRelativeValue(double)
Sets the value in units of referencePoint.
Definition: knuminput.cpp:889
KDoubleNumInput::setLabel
virtual void setLabel(const QString &label, Qt::Alignment a=Qt::AlignLeft|Qt::AlignTop)
Sets the text and alignment of the main description label.
Definition: knuminput.cpp:1060
KDoubleNumInput::minimum
double minimum
Definition: knuminput.h:454
KDoubleNumInput::KDoubleNumInput
KDoubleNumInput(QWidget *parent=0)
Constructs an input control for double values with initial value 0.00.
Definition: knuminput.cpp:697
KDoubleNumInput::setMinimum
void setMinimum(double min)
Sets the minimum value.
Definition: knuminput.cpp:966
KDoubleNumInput::~KDoubleNumInput
virtual ~KDoubleNumInput()
destructor
Definition: knuminput.cpp:724
KDoubleNumInput::exponentRatio
double exponentRatio
Definition: knuminput.h:464
KDoubleNumInput::setSingleStep
void setSingleStep(double singleStep)
Definition: knuminput.cpp:993
KDoubleNumInput::referencePoint
double referencePoint
Definition: knuminput.h:461
KDoubleNumInput::setExponentRatio
void setExponentRatio(double dbl)
Definition: knuminput.cpp:1076
KDoubleNumInput::valueChanged
void valueChanged(double)
Emitted every time the value changes (by calling setValue() or by user interaction).
KIntNumInput
An input widget for integer numbers, consisting of a spinbox and a slider.
Definition: knuminput.h:173
KIntNumInput::setEditFocus
void setEditFocus(bool mark=true)
sets focus to the edit widget and marks all text in if mark == true
Definition: knuminput.cpp:541
KIntNumInput::setRelativeValue
void setRelativeValue(double)
Sets the value in units of the referencePoint.
Definition: knuminput.cpp:634
KIntNumInput::setRange
void setRange(int min, int max, int singleStep=1)
Sets the allowed input range and the step size for the slider and the spin box.
Definition: knuminput.cpp:450
KIntNumInput::specialValueText
QString specialValueText
Definition: knuminput.h:183
KIntNumInput::KIntNumInput
KIntNumInput(QWidget *parent=0)
Constructs an input control for integer values with base 10 and initial value 0.
Definition: knuminput.cpp:347
KIntNumInput::spinBox
QSpinBox * spinBox() const
Definition: knuminput.cpp:361
KIntNumInput::~KIntNumInput
virtual ~KIntNumInput()
Destructor.
Definition: knuminput.cpp:623
KIntNumInput::setSuffix
void setSuffix(const QString &suffix)
Sets the suffix to suffix.
Definition: knuminput.cpp:511
KIntNumInput::doLayout
virtual void doLayout()
You need to overwrite this method and implement your layout calculations there.
Definition: knuminput.cpp:574
KIntNumInput::prefix
QString prefix
Definition: knuminput.h:182
KIntNumInput::referencePoint
int referencePoint
Definition: knuminput.h:179
KIntNumInput::relativeValue
double relativeValue
Definition: knuminput.h:180
KIntNumInput::value
int value
Definition: knuminput.h:175
KIntNumInput::minimumSizeHint
virtual QSize minimumSizeHint() const
This method returns the minimum size necessary to display the control.
Definition: knuminput.cpp:546
KIntNumInput::suffix
QString suffix
Definition: knuminput.h:181
KIntNumInput::resizeEvent
void resizeEvent(QResizeEvent *)
Definition: knuminput.cpp:586
KIntNumInput::setValue
void setValue(int)
Sets the value of the control.
Definition: knuminput.cpp:628
KIntNumInput::maximum
int maximum
Definition: knuminput.h:177
KIntNumInput::relativeValueChanged
void relativeValueChanged(double)
Emitted whenever valueChanged is.
KIntNumInput::singleStep
int singleStep
Definition: knuminput.h:178
KIntNumInput::setSingleStep
void setSingleStep(int step)
Definition: knuminput.cpp:506
KIntNumInput::setMaximum
void setMaximum(int max)
Sets the maximum value.
Definition: knuminput.cpp:491
KIntNumInput::minimum
int minimum
Definition: knuminput.h:176
KIntNumInput::setLabel
virtual void setLabel(const QString &label, Qt::Alignment a=Qt::AlignLeft|Qt::AlignTop)
Sets the text and alignment of the main description label.
Definition: knuminput.cpp:668
KIntNumInput::setSliderEnabled
void setSliderEnabled(bool enabled=true)
Definition: knuminput.cpp:418
KIntNumInput::setReferencePoint
void setReferencePoint(int)
Sets the reference point for relativeValue.
Definition: knuminput.cpp:387
KIntNumInput::valueChanged
void valueChanged(int)
Emitted every time the value changes (by calling setValue() or by user interaction).
KIntNumInput::setSpecialValueText
void setSpecialValueText(const QString &text)
Sets the special value text.
Definition: knuminput.cpp:657
KIntNumInput::setPrefix
void setPrefix(const QString &prefix)
Sets the prefix to prefix.
Definition: knuminput.cpp:529
KIntNumInput::setMinimum
void setMinimum(int min)
Sets the minimum value.
Definition: knuminput.cpp:481
KIntSpinBox
A QSpinBox with support for arbitrary base numbers.
Definition: knuminput.h:718
KIntSpinBox::~KIntSpinBox
virtual ~KIntSpinBox()
Destructor.
Definition: knuminput.cpp:261
KIntSpinBox::setBase
void setBase(int base)
Sets the base in which the numbers in the spin box are represented.
Definition: knuminput.cpp:274
KIntSpinBox::textFromValue
virtual QString textFromValue(int) const
Overloaded the method in QSpinBox to make use of the base given in the constructor.
Definition: knuminput.cpp:285
KIntSpinBox::setEditFocus
void setEditFocus(bool mark)
sets focus and optionally marks all text
Definition: knuminput.cpp:303
KIntSpinBox::base
int base
Definition: knuminput.h:720
KIntSpinBox::KIntSpinBox
KIntSpinBox(QWidget *parent=0)
Constructor.
Definition: knuminput.cpp:255
KIntSpinBox::setSuffix
void setSuffix(const KLocalizedString &suffix)
Sets the suffix to suffix.
Definition: knuminput.cpp:311
KIntSpinBox::valueFromText
virtual int valueFromText(const QString &text) const
Overloaded the method in QSpinBox to make use of the base given in the constructor.
Definition: knuminput.cpp:290
KLocalizedString
KLocalizedString::toString
QString toString() const
KLocalizedString::subs
KLocalizedString subs(const QString &a, int fieldWidth=0, const QChar &fillChar=QLatin1Char(' ')) const
KLocalizedString::isEmpty
bool isEmpty() const
KNumInput
You need to inherit from this class if you want to implement K*NumInput for a different variable type...
Definition: knuminput.h:44
KNumInput::layout
void layout(bool deep)
Call this function whenever you change something in the geometry of your KNumInput child.
Definition: knuminput.cpp:158
KNumInput::doLayout
virtual void doLayout()=0
You need to overwrite this method and implement your layout calculations there.
KNumInput::slider
QSlider * slider() const
Definition: knuminput.cpp:120
KNumInput::label
QString label
Definition: knuminput.h:46
KNumInput::setLabel
virtual void setLabel(const QString &label, Qt::Alignment a=Qt::AlignLeft|Qt::AlignTop)
Sets the text and alignment of the main description label.
Definition: knuminput.cpp:130
KNumInput::sizeHint
virtual QSize sizeHint() const
Returns a size which fits the contents of the control.
Definition: knuminput.cpp:218
KNumInput::setSteps
void setSteps(int minor, int major)
Sets the spacing of tickmarks for the slider.
Definition: knuminput.cpp:223
KNumInput::~KNumInput
~KNumInput()
Destructor.
Definition: knuminput.cpp:107
KNumInput::showSlider
bool showSlider() const
Definition: knuminput.cpp:125
KNumInput::KNumInput
KNumInput(QWidget *parent=0)
Default constructor.
Definition: knuminput.cpp:91
QLabel
QWidget
kWarning
#define kWarning
kdebug.h
kdialog.h
klocalizedstring.h
K_USING_KNUMINPUT_P
#define K_USING_KNUMINPUT_P(_d)
Definition: knuminput.cpp:89
calcDiffByTen
static int calcDiffByTen(int x, int y)
Definition: knuminput.cpp:42
knuminput.h
prefix
QString prefix()
ref
void ref()
KStandardShortcut::label
QString label(StandardShortcut id)
Returns a localized label for user-visible display.
Definition: kstandardshortcut.cpp:267
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal