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

KDEUI

  • sources
  • kde-4.14
  • kdelibs
  • 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 
42 static 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 
50 class KNumInputPrivate
51 {
52 public:
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 
91 KNumInput::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
99 KNumInput::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 
107 KNumInput::~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 
120 QSlider *KNumInput::slider() const
121 {
122  return d->slider;
123 }
124 
125 bool KNumInput::showSlider() const
126 {
127  return d->slider;
128 }
129 
130 void 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 
153 QString KNumInput::label() const
154 {
155  return d->label ? d->label->text() : QString();
156 }
157 
158 void 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 
218 QSize KNumInput::sizeHint() const
219 {
220  return minimumSizeHint();
221 }
222 
223 void 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 
234 class KIntSpinBox::KIntSpinBoxPrivate
235 {
236 public:
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 
255 KIntSpinBox::KIntSpinBox(QWidget *parent)
256  : QSpinBox(parent), d(new KIntSpinBoxPrivate(this))
257 {
258  setValue(0);
259 }
260 
261 KIntSpinBox::~KIntSpinBox()
262 {
263  delete d;
264 }
265 
266 KIntSpinBox::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 
274 void KIntSpinBox::setBase(int base)
275 {
276  d->val_base = base;
277 }
278 
279 
280 int KIntSpinBox::base() const
281 {
282  return d->val_base;
283 }
284 
285 QString KIntSpinBox::textFromValue(int v) const
286 {
287  return QString::number(v, d->val_base);
288 }
289 
290 int 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 
303 void KIntSpinBox::setEditFocus(bool mark)
304 {
305  lineEdit()->setFocus();
306  if (mark) {
307  lineEdit()->selectAll();
308  }
309 }
310 
311 void 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 
322 class KIntNumInput::KIntNumInputPrivate
323 {
324 public:
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
339 KIntNumInput::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 
347 KIntNumInput::KIntNumInput(QWidget *parent)
348  : KNumInput(parent)
349  , d(new KIntNumInputPrivate(this, 0))
350 {
351  init(0, 10);
352 }
353 
354 KIntNumInput::KIntNumInput(int val, QWidget *parent, int _base)
355  : KNumInput(parent)
356  , d(new KIntNumInputPrivate(this, val))
357 {
358  init(val, _base);
359 }
360 
361 QSpinBox *KIntNumInput::spinBox() const
362 {
363  return d->intSpinBox;
364 }
365 
366 void 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 
387 void KIntNumInput::setReferencePoint(int ref)
388 {
389  // clip to valid range:
390  ref = qMin(maximum(), qMax(minimum(), ref));
391  d->referencePoint = ref;
392 }
393 
394 int KIntNumInput::referencePoint() const
395 {
396  return d->referencePoint;
397 }
398 
399 void 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 
410 void KIntNumInput::slotEmitRelativeValueChanged(int value)
411 {
412  if (d->blockRelative || !d->referencePoint) {
413  return;
414  }
415  emit relativeValueChanged(double(value) / double(d->referencePoint));
416 }
417 
418 void 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 
450 void 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
474 void KIntNumInput::setRange(int lower, int upper, int singleStep, bool slider)
475 {
476  setRange(lower, upper, singleStep);
477  setSliderEnabled(slider);
478 }
479 #endif
480 
481 void KIntNumInput::setMinimum(int min)
482 {
483  setRange(min, d->intSpinBox->maximum(), d->intSpinBox->singleStep());
484 }
485 
486 int KIntNumInput::minimum() const
487 {
488  return d->intSpinBox->minimum();
489 }
490 
491 void KIntNumInput::setMaximum(int max)
492 {
493  setRange(d->intSpinBox->minimum(), max, d->intSpinBox->singleStep());
494 }
495 
496 int KIntNumInput::maximum() const
497 {
498  return d->intSpinBox->maximum();
499 }
500 
501 int KIntNumInput::singleStep() const
502 {
503  return d->intSpinBox->singleStep();
504 }
505 
506 void KIntNumInput::setSingleStep(int singleStep)
507 {
508  d->intSpinBox->setSingleStep(singleStep);
509 }
510 
511 void KIntNumInput::setSuffix(const QString &suffix)
512 {
513  d->intSpinBox->setSuffix(suffix);
514 
515  layout(true);
516 }
517 
518 void KIntNumInput::setSuffix(const KLocalizedString& suffix)
519 {
520  d->intSpinBox->setSuffix(suffix);
521  layout(true);
522 }
523 
524 QString KIntNumInput::suffix() const
525 {
526  return d->intSpinBox->suffix();
527 }
528 
529 void KIntNumInput::setPrefix(const QString &prefix)
530 {
531  d->intSpinBox->setPrefix(prefix);
532 
533  layout(true);
534 }
535 
536 QString KIntNumInput::prefix() const
537 {
538  return d->intSpinBox->prefix();
539 }
540 
541 void KIntNumInput::setEditFocus(bool mark)
542 {
543  d->intSpinBox->setEditFocus(mark);
544 }
545 
546 QSize 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 
574 void 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 
586 void 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 
623 KIntNumInput::~KIntNumInput()
624 {
625  delete d;
626 }
627 
628 void KIntNumInput::setValue(int val)
629 {
630  d->intSpinBox->setValue(val);
631  // slider value is changed by spinValueChanged
632 }
633 
634 void 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 
644 double KIntNumInput::relativeValue() const
645 {
646  if (!d->referencePoint) {
647  return 0;
648  }
649  return double(value()) / double(d->referencePoint);
650 }
651 
652 int KIntNumInput::value() const
653 {
654  return d->intSpinBox->value();
655 }
656 
657 void KIntNumInput::setSpecialValueText(const QString& text)
658 {
659  d->intSpinBox->setSpecialValueText(text);
660  layout(true);
661 }
662 
663 QString KIntNumInput::specialValueText() const
664 {
665  return d->intSpinBox->specialValueText();
666 }
667 
668 void 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 
681 class KDoubleNumInput::KDoubleNumInputPrivate
682 {
683 public:
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 
697 KDoubleNumInput::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 
705 KDoubleNumInput::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
714 KDoubleNumInput::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 
724 KDoubleNumInput::~KDoubleNumInput()
725 {
726  delete d;
727 }
728 
729 QString KDoubleNumInput::specialValueText() const
730 {
731  return d->specialValue;
732 }
733 
734 
735 void 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 
756 void KDoubleNumInput::updateLegacyMembers()
757 {
758  d->specialValue = specialValueText();
759 }
760 
761 double 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 
775 void KDoubleNumInput::sliderMoved(int val)
776 {
777  d->spin->setValue(mapSliderToSpin(val));
778 }
779 
780 void 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 
799 void KDoubleNumInput::slotEmitRelativeValueChanged(double value)
800 {
801  if (!d->referencePoint) {
802  return;
803  }
804  emit relativeValueChanged(value / d->referencePoint);
805 }
806 
807 QSize 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 
836 void 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 
876 void KDoubleNumInput::doLayout()
877 {
878  K_USING_KNUMINPUT_P(priv);
879 
880  d->editSize = d->spin->sizeHint();
881  priv->column2Width = d->editSize.width();
882 }
883 
884 void KDoubleNumInput::setValue(double val)
885 {
886  d->spin->setValue(val);
887 }
888 
889 void 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 
899 void KDoubleNumInput::setReferencePoint(double ref)
900 {
901  // clip to valid range:
902  ref = qMin(maximum(), qMax(minimum(), ref));
903  d->referencePoint = ref;
904 }
905 
906 void 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 
928 void 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 
966 void KDoubleNumInput::setMinimum(double min)
967 {
968  K_USING_KNUMINPUT_P(priv);
969  setRange(min, maximum(), d->spin->singleStep(), priv->slider);
970 }
971 
972 double KDoubleNumInput::minimum() const
973 {
974  return d->spin->minimum();
975 }
976 
977 void KDoubleNumInput::setMaximum(double max)
978 {
979  K_USING_KNUMINPUT_P(priv);
980  setRange(minimum(), max, d->spin->singleStep(), priv->slider);
981 }
982 
983 double KDoubleNumInput::maximum() const
984 {
985  return d->spin->maximum();
986 }
987 
988 double KDoubleNumInput::singleStep() const
989 {
990  return d->spin->singleStep();
991 }
992 
993 void KDoubleNumInput::setSingleStep(double singleStep)
994 {
995  d->spin->setSingleStep(singleStep);
996 }
997 
998 double KDoubleNumInput::value() const
999 {
1000  return d->spin->value();
1001 }
1002 
1003 double KDoubleNumInput::relativeValue() const
1004 {
1005  if (!d->referencePoint) {
1006  return 0;
1007  }
1008  return value() / d->referencePoint;
1009 }
1010 
1011 double KDoubleNumInput::referencePoint() const
1012 {
1013  return d->referencePoint;
1014 }
1015 
1016 QString KDoubleNumInput::suffix() const
1017 {
1018  return d->spin->suffix();
1019 }
1020 
1021 QString KDoubleNumInput::prefix() const
1022 {
1023  return d->spin->prefix();
1024 }
1025 
1026 void KDoubleNumInput::setSuffix(const QString &suffix)
1027 {
1028  d->spin->setSuffix(suffix);
1029 
1030  layout(true);
1031 }
1032 
1033 void KDoubleNumInput::setPrefix(const QString &prefix)
1034 {
1035  d->spin->setPrefix(prefix);
1036 
1037  layout(true);
1038 }
1039 
1040 void KDoubleNumInput::setDecimals(int decimals)
1041 {
1042  d->spin->setDecimals(decimals);
1043 
1044  layout(true);
1045 }
1046 
1047 int KDoubleNumInput::decimals() const
1048 {
1049  return d->spin->decimals();
1050 }
1051 
1052 void KDoubleNumInput::setSpecialValueText(const QString& text)
1053 {
1054  d->spin->setSpecialValueText(text);
1055 
1056  layout(true);
1057  updateLegacyMembers();
1058 }
1059 
1060 void 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 
1071 double KDoubleNumInput::exponentRatio() const
1072 {
1073  return d->exponentRatio;
1074 }
1075 
1076 void 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"
QWidget::layout
QLayout * layout() const
KIntNumInput::setMinimum
void setMinimum(int min)
Sets the minimum value.
Definition: knuminput.cpp:481
KIntNumInput::relativeValue
double relativeValue() const
kdialog.h
knuminput.h
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
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
KIntNumInput::minimum
int minimum() const
QResizeEvent
QWidget
KDoubleNumInput::setPrefix
void setPrefix(const QString &prefix)
Sets the prefix to be displayed to prefix.
Definition: knuminput.cpp:1033
KDoubleNumInput::minimum
double minimum() const
KDoubleNumInput::specialValueText
QString specialValueText() const
KIntSpinBox::~KIntSpinBox
virtual ~KIntSpinBox()
Destructor.
Definition: knuminput.cpp:261
QSize::width
int width() const
KLocalizedString::toString
QString toString() const
kdebug.h
KNumInput::showSlider
bool showSlider() const
Definition: knuminput.cpp:125
KIntNumInput::relativeValueChanged
void relativeValueChanged(double)
Emitted whenever valueChanged is.
QSpinBox::suffix
QString suffix() const
KDoubleNumInput::setSingleStep
void setSingleStep(double singleStep)
Definition: knuminput.cpp:993
KDoubleNumInput::minimumSizeHint
virtual QSize minimumSizeHint() const
Definition: knuminput.cpp:807
KIntNumInput::setSpecialValueText
void setSpecialValueText(const QString &text)
Sets the special value text.
Definition: knuminput.cpp:657
QWidget::setFocusPolicy
void setFocusPolicy(Qt::FocusPolicy policy)
KNumInput::sizeHint
virtual QSize sizeHint() const
Returns a size which fits the contents of the control.
Definition: knuminput.cpp:218
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
KDoubleNumInput::resizeEvent
void resizeEvent(QResizeEvent *)
Definition: knuminput.cpp:836
KIntNumInput::setMaximum
void setMaximum(int max)
Sets the maximum value.
Definition: knuminput.cpp:491
KStandardShortcut::label
QString label(StandardShortcut id)
Returns a localized label for user-visible display.
Definition: kstandardshortcut.cpp:267
KIntNumInput::prefix
QString prefix() const
QSpinBox::prefix
QString prefix() const
QSizePolicy
KDoubleNumInput::referencePoint
double referencePoint() const
KDoubleNumInput::setSpecialValueText
void setSpecialValueText(const QString &text)
Sets the special value text.
Definition: knuminput.cpp:1052
KDoubleNumInput::setMaximum
void setMaximum(double max)
Sets the maximum value.
Definition: knuminput.cpp:977
QWidget::ensurePolished
void ensurePolished() const
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KIntSpinBox::KIntSpinBox
KIntSpinBox(QWidget *parent=0)
Constructor.
Definition: knuminput.cpp:255
QWidget::minimumSizeHint
virtual QSize minimumSizeHint() const
double
KIntNumInput::setRelativeValue
void setRelativeValue(double)
Sets the value in units of the referencePoint.
Definition: knuminput.cpp:634
QString::remove
QString & remove(int position, int n)
KIntNumInput::KIntNumInputPrivate
friend class KIntNumInputPrivate
Definition: knuminput.h:415
KIntSpinBox::KIntSpinBoxPrivate
friend class KIntSpinBoxPrivate
Definition: knuminput.h:792
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
QString::chop
void chop(int n)
Qt::Alignment
typedef Alignment
KDoubleNumInput::exponentRatio
double exponentRatio() const
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QSlider
K_USING_KNUMINPUT_P
#define K_USING_KNUMINPUT_P(_d)
Definition: knuminput.cpp:89
KNumInput
You need to inherit from this class if you want to implement K*NumInput for a different variable type...
Definition: knuminput.h:43
QAbstractSpinBox::text
QString text() const
QSpinBox::setRange
void setRange(int minimum, int maximum)
KNumInput::~KNumInput
~KNumInput()
Destructor.
Definition: knuminput.cpp:107
KDoubleNumInput::valueChanged
void valueChanged(double)
Emitted every time the value changes (by calling setValue() or by user interaction).
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
KDoubleNumInput::doLayout
virtual void doLayout()
You need to overwrite this method and implement your layout calculations there.
Definition: knuminput.cpp:876
QSpinBox::valueChanged
void valueChanged(int i)
KLocalizedString::isEmpty
bool isEmpty() const
KDoubleNumInput::singleStep
double singleStep() const
KNumInput::slider
QSlider * slider() const
Definition: knuminput.cpp:120
QDoubleSpinBox
QString::number
QString number(int n, int base)
KIntNumInput::suffix
QString suffix() const
KDoubleNumInput::setRange
void setRange(double min, double max, double singleStep=1, bool slider=true)
Definition: knuminput.cpp:906
KDoubleNumInput::maximum
double maximum() const
KIntNumInput::value
int value() const
KIntSpinBox::base
int base() const
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
KNumInput::KNumInput
KNumInput(QWidget *parent=0)
Default constructor.
Definition: knuminput.cpp:91
QWidget::setFocus
void setFocus()
KDoubleNumInput::setSuffix
void setSuffix(const QString &suffix)
Sets the suffix to be displayed to suffix.
Definition: knuminput.cpp:1026
QString::toInt
int toInt(bool *ok, int base) const
KIntNumInput::resizeEvent
void resizeEvent(QResizeEvent *)
Definition: knuminput.cpp:586
QAbstractSpinBox::lineEdit
QLineEdit * lineEdit() const
QWidget::setFocusProxy
void setFocusProxy(QWidget *w)
QString::isEmpty
bool isEmpty() const
QString::trimmed
QString trimmed() const
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QDoubleSpinBox::decimals
decimals
KIntNumInput::referencePoint
int referencePoint() const
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QDoubleSpinBox::value
value
KIntNumInput::maximum
int maximum() const
QString
QLineEdit::selectAll
void selectAll()
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
KDoubleNumInput::relativeValueChanged
void relativeValueChanged(double)
This is an overloaded member function, provided for convenience.
KIntNumInput::setSingleStep
void setSingleStep(int step)
Definition: knuminput.cpp:506
QSpinBox::setSingleStep
void setSingleStep(int val)
QSpinBox
KIntNumInput::setSliderEnabled
void setSliderEnabled(bool enabled=true)
Definition: knuminput.cpp:418
KDoubleNumInput::setRelativeValue
void setRelativeValue(double)
Sets the value in units of referencePoint.
Definition: knuminput.cpp:889
KDoubleNumInput::KDoubleNumInputPrivate
friend class KDoubleNumInputPrivate
Definition: knuminput.h:696
QResizeEvent::size
const QSize & size() const
QSize
KIntNumInput::setSuffix
void setSuffix(const QString &suffix)
Sets the suffix to suffix.
Definition: knuminput.cpp:511
KStandardGuiItem::ok
KGuiItem ok()
Returns the 'Ok' gui item.
Definition: kstandardguiitem.cpp:107
KIntNumInput::specialValueText
QString specialValueText() const
KDoubleNumInput::KDoubleNumInput
KDoubleNumInput(QWidget *parent=0)
Constructs an input control for double values with initial value 0.00.
Definition: knuminput.cpp:697
calcDiffByTen
static int calcDiffByTen(int x, int y)
Definition: knuminput.cpp:42
KDoubleNumInput::prefix
QString prefix() const
KDoubleNumInput::setReferencePoint
void setReferencePoint(double ref)
Sets the reference Point to ref.
Definition: knuminput.cpp:899
KIntSpinBox
A QSpinBox with support for arbitrary base numbers.
Definition: knuminput.h:717
KDoubleNumInput::~KDoubleNumInput
virtual ~KDoubleNumInput()
destructor
Definition: knuminput.cpp:724
klocalizedstring.h
QSpinBox::value
int value() const
KDoubleNumInput::setValue
void setValue(double)
Sets the value of the control.
Definition: knuminput.cpp:884
KIntSpinBox::setBase
void setBase(int base)
Sets the base in which the numbers in the spin box are represented.
Definition: knuminput.cpp:274
KIntSpinBox::setEditFocus
void setEditFocus(bool mark)
sets focus and optionally marks all text
Definition: knuminput.cpp:303
KIntNumInput::valueChanged
void valueChanged(int)
Emitted every time the value changes (by calling setValue() or by user interaction).
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KLocalizedString::subs
KLocalizedString subs(int a, int fieldWidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const
KDoubleNumInput::decimals
int decimals() const
KDoubleNumInput::setDecimals
void setDecimals(int decimals)
Specifies the number of digits to use.
Definition: knuminput.cpp:1040
KIntNumInput::doLayout
virtual void doLayout()
You need to overwrite this method and implement your layout calculations there.
Definition: knuminput.cpp:574
KDoubleNumInput::relativeValue
double relativeValue() const
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
QDoubleSpinBox::minimum
minimum
KIntNumInput::singleStep
int singleStep() const
KDoubleNumInput::setExponentRatio
void setExponentRatio(double dbl)
Definition: knuminput.cpp:1076
KIntNumInput::setPrefix
void setPrefix(const QString &prefix)
Sets the prefix to prefix.
Definition: knuminput.cpp:529
KDoubleNumInput::value
double value() const
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
KNumInput::label
QString label() const
KDoubleNumInput::setMinimum
void setMinimum(double min)
Sets the minimum value.
Definition: knuminput.cpp:966
KNumInput::doLayout
virtual void doLayout()=0
You need to overwrite this method and implement your layout calculations there.
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KIntNumInput::~KIntNumInput
virtual ~KIntNumInput()
Destructor.
Definition: knuminput.cpp:623
QLabel
KDoubleNumInput::suffix
QString suffix() const
KIntSpinBox::setSuffix
void setSuffix(const KLocalizedString &suffix)
Sets the suffix to suffix.
Definition: knuminput.cpp:311
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
KLocalizedString
KNumInput::setSteps
void setSteps(int minor, int major)
Sets the spacing of tickmarks for the slider.
Definition: knuminput.cpp:223
QDoubleSpinBox::maximum
maximum
KIntNumInput::minimumSizeHint
virtual QSize minimumSizeHint() const
This method returns the minimum size necessary to display the control.
Definition: knuminput.cpp:546
KIntNumInput::setReferencePoint
void setReferencePoint(int)
Sets the reference point for relativeValue.
Definition: knuminput.cpp:387
KIntNumInput::setValue
void setValue(int)
Sets the value of the control.
Definition: knuminput.cpp:628
KDoubleNumInput::setSliderEnabled
void setSliderEnabled(bool enabled)
Definition: knuminput.cpp:928
KIntNumInput
An input widget for integer numbers, consisting of a spinbox and a slider.
Definition: knuminput.h:172
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:23:59 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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