38 #include <tqapplication.h>
40 #include <tqlineedit.h>
43 #include <tqspinbox.h>
46 #include <tdeglobal.h>
51 #include "knumvalidator.h"
52 #include "knuminput.h"
54 static inline int calcDiffByTen(
int x,
int y ) {
56 return ( x / 10 ) - ( y / 10 ) + ( x % 10 - y % 10 ) / 10;
62 : TQWidget(parent, name)
68 : TQWidget(parent, name)
73 m_next = below->m_next;
77 m_next->m_prev =
this;
81 void KNumInput::init()
84 m_colw1 = m_colw2 = 0;
91 KNumInput::~KNumInput()
94 m_prev->m_next = m_next;
97 m_next->m_prev = m_prev;
102 if(
label.isEmpty()) {
108 if (m_label) m_label->setText(
label);
109 else m_label =
new TQLabel(
label,
this,
"KNumInput::TQLabel");
110 m_label->setAlignment((a & (~(AlignTop|AlignBottom|AlignVCenter)))
113 if(!(a & (AlignTop|AlignBottom|AlignVCenter)))
123 if (m_label)
return m_label->text();
124 return TQString::null;
133 m_sizeLabel = (m_label ? m_label->sizeHint() : TQSize(0,0));
135 if(m_label && (m_alignment & AlignVCenter))
136 m_colw1 = m_sizeLabel.width() + 4;
141 m_sizeSlider = (m_slider ? m_slider->sizeHint() : TQSize(0, 0));
154 w1 = TQMAX(w1, p->m_colw1);
155 w2 = TQMAX(w2, p->m_colw2);
162 w1 = TQMAX(w1, p->m_colw1);
163 w2 = TQMAX(w2, p->m_colw2);
186 return TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
191 return minimumSizeHint();
197 m_slider->setSteps( minor, major );
204 : TQSpinBox(0, 99, 1, parent, name)
206 editor()->setAlignment(AlignRight);
217 TQWidget* parent,
const char* name)
218 : TQSpinBox(lower, upper, step, parent, name)
220 editor()->setAlignment(AlignRight);
243 return TQString::number(v, val_base);
248 return cleanText().toInt(ok, val_base);
253 editor()->setFocus();
255 editor()->selectAll();
261 class KIntNumInput::KIntNumInputPrivate {
265 KIntNumInputPrivate(
int r )
267 blockRelative( 0 ) {}
272 int _base,
const char* name)
291 void KIntNumInput::init(
int val,
int _base)
293 d =
new KIntNumInputPrivate( val );
294 m_spin =
new KIntSpinBox(INT_MIN, INT_MAX, 1, val, _base,
this,
"KIntNumInput::KIntSpinBox");
299 m_spin->setValidator(
new KIntValidator(
this, _base,
"KNumInput::KIntValidtr"));
301 connect(m_spin, TQ_SIGNAL(
valueChanged(
int)), TQ_SLOT(spinValueChanged(
int)));
303 TQ_SLOT(slotEmitRelativeValueChanged(
int)));
305 setFocusProxy(m_spin);
312 d->referencePoint = ref;
316 return d->referencePoint;
319 void KIntNumInput::spinValueChanged(
int val)
322 m_slider->setValue(val);
327 void KIntNumInput::slotEmitRelativeValueChanged(
int value ) {
328 if ( d->blockRelative || !d->referencePoint )
return;
334 upper = kMax(upper, lower);
335 lower = kMin(upper, lower);
336 m_spin->setMinValue(lower);
337 m_spin->setMaxValue(upper);
338 m_spin->setLineStep(step);
340 step = m_spin->lineStep();
344 m_slider->setRange(lower, upper);
346 m_slider =
new TQSlider(lower, upper, step, m_spin->value(),
347 TQt::Horizontal,
this);
348 m_slider->setTickmarks(TQSlider::Below);
354 int major = calcDiffByTen( upper, lower );
355 if ( major==0 ) major = step;
357 m_slider->setSteps(step, major);
358 m_slider->setTickInterval(major);
373 setRange(min, m_spin->maxValue(), m_spin->lineStep(), m_slider);
378 return m_spin->minValue();
383 setRange(m_spin->minValue(), max, m_spin->lineStep(), m_slider);
388 return m_spin->maxValue();
393 m_spin->setSuffix(
suffix);
400 return m_spin->suffix();
405 m_spin->setPrefix(
prefix);
412 return m_spin->prefix();
427 h = 2 + TQMAX(m_sizeSpin.height(), m_sizeSlider.height());
430 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
431 h += 4 + m_sizeLabel.height();
434 h = TQMAX(h, m_sizeLabel.height() + 2);
436 w = m_slider ? m_slider->sizeHint().width() + 8 : 0;
437 w += m_colw1 + m_colw2;
439 if(m_alignment & (AlignTop|AlignBottom))
440 w = TQMAX(w, m_sizeLabel.width() + 4);
447 m_sizeSpin = m_spin->sizeHint();
448 m_colw2 = m_sizeSpin.width();
451 m_label->setBuddy(m_spin);
454 void KIntNumInput::resizeEvent(TQResizeEvent* e)
459 if(m_label && (m_alignment & AlignTop)) {
460 m_label->setGeometry(0, 0, e->size().width(), m_sizeLabel.height());
464 if(m_label && (m_alignment & AlignVCenter))
465 m_label->setGeometry(0, 0, w, m_sizeSpin.height());
467 if (tqApp->reverseLayout())
469 m_spin->setGeometry(w, h, m_slider ? m_colw2 : TQMAX(m_colw2, e->size().width() - w), m_sizeSpin.height());
473 m_slider->setGeometry(w, h, e->size().width() - w, m_sizeSpin.height());
476 m_slider->setGeometry(w, h, e->size().width() - (w + m_colw2 +
KDialog::spacingHint()), m_sizeSpin.height());
477 m_spin->setGeometry(w + m_slider->size().width() +
KDialog::spacingHint(), h, m_colw2, m_sizeSpin.height());
480 m_spin->setGeometry(w, h, TQMAX(m_colw2, e->size().width() - w), m_sizeSpin.height());
483 h += m_sizeSpin.height() + 2;
485 if(m_label && (m_alignment & AlignBottom))
486 m_label->setGeometry(0, h, m_sizeLabel.width(), m_sizeLabel.height());
496 m_spin->setValue(val);
501 if ( !d->referencePoint )
return;
503 setValue(
int( d->referencePoint * r + 0.5 ) );
508 if ( !d->referencePoint )
return 0;
509 return double(
value() ) / double ( d->referencePoint );
514 return m_spin->value();
519 m_spin->setSpecialValueText(text);
525 return m_spin->specialValueText();
533 m_label->setBuddy(m_spin);
538 class KDoubleNumInput::KDoubleNumInputPrivate {
540 KDoubleNumInputPrivate(
double r )
543 blockRelative ( 0 ) {}
552 init(0.0, 0.0, 9999.0, 0.01, 2);
556 double step,
int precision, TQWidget* parent,
564 double lower,
double upper,
double value,
565 double step,
int precision, TQWidget* parent,
592 bool KDoubleNumInput::eventFilter( TQObject * o, TQEvent * e ) {
593 return KNumInput::eventFilter( o, e );
596 void KDoubleNumInput::resetEditBox() {
604 void KDoubleNumInput::init(
double value,
double lower,
double upper,
605 double step,
int precision )
614 d =
new KDoubleNumInputPrivate(
value );
617 this,
"KDoubleNumInput::d->spin" );
618 setFocusProxy(d->spin);
622 this, TQ_SLOT(slotEmitRelativeValueChanged(
double)) );
624 updateLegacyMembers();
629 void KDoubleNumInput::updateLegacyMembers() {
634 m_step = d->spin->lineStep();
639 double KDoubleNumInput::mapSliderToSpin(
int val )
const
642 double spinmin = d->spin->minValue();
643 double spinmax = d->spin->maxValue();
644 double slidemin = m_slider->minValue();
645 double slidemax = m_slider->maxValue();
646 double rel = ( double(val) - slidemin ) / ( slidemax - slidemin );
647 return spinmin + rel * ( spinmax - spinmin );
650 void KDoubleNumInput::sliderMoved(
int val)
652 d->spin->setValue( mapSliderToSpin( val ) );
655 void KDoubleNumInput::slotEmitRelativeValueChanged(
double value )
657 if ( !d->referencePoint )
return;
661 TQSize KDoubleNumInput::minimumSizeHint()
const
668 h = 2 + TQMAX(m_sizeEdit.height(), m_sizeSlider.height());
671 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
672 h += 4 + m_sizeLabel.height();
675 h = TQMAX(h, m_sizeLabel.height() + 2);
677 w = m_slider ? m_slider->sizeHint().width() + 8 : 0;
678 w += m_colw1 + m_colw2;
680 if(m_alignment & (AlignTop|AlignBottom))
681 w = TQMAX(w, m_sizeLabel.width() + 4);
686 void KDoubleNumInput::resizeEvent(TQResizeEvent* e)
691 if(m_label && (m_alignment & AlignTop)) {
692 m_label->setGeometry(0, 0, e->size().width(), m_sizeLabel.height());
693 h += m_sizeLabel.height() + 4;
696 if(m_label && (m_alignment & AlignVCenter))
697 m_label->setGeometry(0, 0, w, m_sizeEdit.height());
699 if (tqApp->reverseLayout())
701 d->spin->setGeometry(w, h, m_slider ? m_colw2
702 : e->size().width() - w, m_sizeEdit.height());
706 m_slider->setGeometry(w, h, e->size().width() - w, m_sizeEdit.height());
709 m_slider->setGeometry(w, h, e->size().width() -
711 m_sizeEdit.height());
713 m_colw2, m_sizeEdit.height());
716 d->spin->setGeometry(w, h, e->size().width() - w, m_sizeEdit.height());
719 h += m_sizeEdit.height() + 2;
721 if(m_label && (m_alignment & AlignBottom))
722 m_label->setGeometry(0, h, m_sizeLabel.width(), m_sizeLabel.height());
727 m_sizeEdit = d->spin->sizeHint();
728 m_colw2 = m_sizeEdit.width();
733 d->spin->setValue( val );
738 if ( !d->referencePoint )
return;
748 d->referencePoint = ref;
756 TQSpinBox * spin = d->spin;
760 d->spin->setRange( lower, upper, step, d->spin->precision() );
764 TQSpinBox * spin = d->spin;
765 int slmax = spin->maxValue();
766 int slmin = spin->minValue();
767 int slvalue = spin->value();
768 int slstep = spin->lineStep();
770 m_slider->setRange(slmin, slmax);
771 m_slider->setValue(slvalue);
773 m_slider =
new TQSlider(slmin, slmax, slstep, slvalue,
774 TQt::Horizontal,
this);
775 m_slider->setTickmarks(TQSlider::Below);
778 TQ_SLOT(sliderMoved(
int)) );
783 int major = calcDiffByTen( slmax, slmin );
784 if ( !major ) major = slstep;
785 m_slider->setSteps(slstep, major);
786 m_slider->setTickInterval(major);
795 updateLegacyMembers();
805 return d->spin->minValue();
815 return d->spin->maxValue();
820 return d->spin->value();
825 if ( !d->referencePoint )
return 0;
826 return value() / d->referencePoint;
831 return d->referencePoint;
836 return d->spin->suffix();
841 return d->spin->prefix();
846 d->spin->setSuffix(
suffix );
853 d->spin->setPrefix(
prefix );
863 TQSpinBox * spin = d->spin;
864 m_slider->setRange(spin->minValue(), spin->maxValue());
865 m_slider->setValue(spin->value());
866 int major = calcDiffByTen(spin->maxValue(), spin->minValue());
867 if ( !major ) major = spin->lineStep();
868 m_slider->setSteps(spin->lineStep(), major);
869 m_slider->setTickInterval(major);
877 return d->spin->precision();
882 d->spin->setSpecialValueText( text );
885 updateLegacyMembers();
893 m_label->setBuddy(d->spin);
903 KDoubleSpinBoxValidator(
double bottom,
double top,
int decimals,
KDoubleSpinBox* sb,
const char *name )
906 virtual State
validate( TQString& str,
int& pos )
const;
912 TQValidator::State KDoubleSpinBoxValidator::validate( TQString& str,
int& pos )
const
914 TQString pref = spinBox->prefix();
915 TQString suff = spinBox->suffix();
916 TQString suffStriped = suff.stripWhiteSpace();
917 uint overhead = pref.length() + suff.length();
918 State state = Invalid;
920 if ( overhead == 0 ) {
923 bool stripedVersion =
false;
924 if ( str.length() >= overhead && str.startsWith(pref)
925 && (str.endsWith(suff)
926 || (stripedVersion = str.endsWith(suffStriped))) ) {
927 if ( stripedVersion )
928 overhead = pref.length() + suffStriped.length();
929 TQString core = str.mid( pref.length(), str.length() - overhead );
930 int corePos = pos - pref.length();
932 pos = corePos + pref.length();
933 str.replace( pref.length(), str.length() - overhead, core );
936 if ( state == Invalid ) {
938 TQString special = spinBox->specialValueText().stripWhiteSpace();
939 TQString candidate = str.stripWhiteSpace();
941 if ( special.startsWith(candidate) ) {
942 if ( candidate.length() == special.length() ) {
945 state = Intermediate;
964 class KDoubleSpinBox::Private {
974 for (
int i = 0 ; i < mPrecision ; ++i ) f *= 10;
978 double basicStep()
const {
979 return 1.0/double(factor());
982 int mapToInt(
double value,
bool * ok )
const {
984 const double f = factor();
985 if (
value >
double(INT_MAX) / f ) {
987 <<
"in terms of fixed-point numbers with precision "
988 << mPrecision <<
endl;
991 }
else if (
value <
double(INT_MIN) / f ) {
993 <<
"in terms of fixed-point numbers with precision "
994 << mPrecision <<
endl;
999 return int(
value * f + (
value < 0 ? -0.5 : 0.5 ) );
1003 double mapToDouble(
int value )
const {
1004 return double(
value) * basicStep();
1008 KDoubleSpinBoxValidator * mValidator;
1012 : TQSpinBox( parent, name )
1014 editor()->setAlignment( TQt::AlignRight );
1017 connect(
this, TQ_SIGNAL(
valueChanged(
int)), TQ_SLOT(slotValueChanged(
int)) );
1021 double value,
int precision,
1022 TQWidget * parent,
const char * name )
1023 : TQSpinBox( parent, name )
1025 editor()->setAlignment( TQt::AlignRight );
1029 connect(
this, TQ_SIGNAL(
valueChanged(
int)), TQ_SLOT(slotValueChanged(
int)) );
1032 KDoubleSpinBox::~KDoubleSpinBox() {
1037 if ( !d->mValidator )
return true;
1039 return d->mValidator->acceptLocalizedNumbers();
1043 if ( !d->mValidator ) updateValidator();
1044 d->mValidator->setAcceptLocalizedNumbers( accept );
1049 lower = kMin(upper, lower);
1050 upper = kMax(upper, lower);
1058 return d->mPrecision;
1068 int maxPrec = maxPrecision();
1075 int oldPrecision = d->mPrecision;
1076 double oldValue =
value();
1091 int KDoubleSpinBox::maxPrecision()
const {
1097 if ( maxAbsValue == 0 )
return 6;
1099 return int( floor( log10(
double(INT_MAX) / maxAbsValue ) ) );
1103 return d->mapToDouble( base::value() );
1109 base::setValue( base::minValue() );
1111 base::setValue( base::maxValue() );
1114 base::setValue( d->mapToInt(
value, &ok ) );
1120 return d->mapToDouble( base::minValue() );
1125 int min = d->mapToInt(
value, &ok );
1126 base::setMinValue( min );
1132 return d->mapToDouble( base::maxValue() );
1137 int max = d->mapToInt(
value, &ok );
1138 base::setMaxValue( max );
1143 return d->mapToDouble( base::lineStep() );
1149 base::setLineStep( 1 );
1151 base::setLineStep( kMax( d->mapToInt( step, &ok ), 1 ) );
1154 TQString KDoubleSpinBox::mapValueToText(
int value ) {
1159 return TQString().setNum( d->mapToDouble(
value ),
'f', d->mPrecision );
1162 int KDoubleSpinBox::mapTextToValue(
bool * ok ) {
1167 value = cleanText().toDouble( ok );
1168 if ( !*ok )
return 0;
1173 return d->mapToInt(
value, ok );
1180 void KDoubleSpinBox::slotValueChanged(
int value ) {
1184 void KDoubleSpinBox::updateValidator() {
1185 if ( !d->mValidator ) {
1187 this,
"d->mValidator" );
1188 base::setValidator( d->mValidator );
1193 void KNumInput::virtual_hook(
int,
void* )
1196 void KIntNumInput::virtual_hook(
int id,
void* data )
1197 { KNumInput::virtual_hook(
id, data ); }
1199 void KDoubleNumInput::virtual_hook(
int id,
void* data )
1200 { KNumInput::virtual_hook(
id, data ); }
1202 void KIntSpinBox::virtual_hook(
int,
void* )
1205 void KDoubleSpinBox::virtual_hook(
int,
void* )
1208 #include "knuminput.moc"
static int spacingHint()
Return the number of pixels you shall use between widgets inside a dialog according to the KDE standa...
A spin box for fractional numbers.
KDoubleSpinBox(TQWidget *parent=0, const char *name=0)
Constructs a KDoubleSpinBox with parent parent and default values for range and value (whatever QRang...
void setPrecision(int precision)
Equivalent to setPrecision( precision, false ); Needed since Qt's moc doesn't ignore trailing paramet...
void setRange(double lower, double upper, double step=0.01, int precision=2)
Sets a new range for the spin box values.
void setValidator(const TQValidator *)
Overridden to ignore any setValidator() calls.
virtual void setValue(double value)
Sets the current value to value, subject to the constraints that value is first rounded to the curren...
void setMaxValue(double value)
Sets the upper bound of the range to value, subject to the contraints that value is first rounded to ...
void setMinValue(double value)
Sets the lower bound of the range to value, subject to the contraints that value is first rounded to ...
void setLineStep(double step)
Sets the step size for clicking the up/down buttons to step, subject to the constraints that step is ...
virtual void setAcceptLocalizedNumbers(bool accept)
Sets whether to use and accept localized numbers as returned by TDELocale::formatNumber()
void valueChanged(double value)
Emitted whenever TQSpinBox::valueChanged( int ) is emitted.
bool acceptLocalizedNumbers() const
A locale-aware QDoubleValidator.
virtual TQValidator::State validate(TQString &input, int &pos) const
Overloaded for internal reasons.
A TQSpinBox with support for arbitrary base numbers.
virtual ~KIntSpinBox()
Destructor.
void setBase(int base)
Sets the base in which the numbers in the spin box are represented.
virtual TQString mapValueToText(int)
Overloaded the method in QSpinBox to make use of the base given in the constructor.
void setEditFocus(bool mark)
sets focus and optionally marks all text
virtual int mapTextToValue(bool *)
Overloaded the method in QSpinBox to make use of the base given in the constructor.
KIntSpinBox(TQWidget *parent=0, const char *name=0)
Constructor.
TQValidator for integers.
static TDELocale * locale()
TQString formatNumber(double num, int precision=-1) const
double readNumber(const TQString &numStr, bool *ok=0) const
kndbgstream & endl(kndbgstream &s)
kdbgstream kdWarning(int area=0)