39 #include <tqapplication.h>
41 #include <tqlineedit.h>
44 #include <tqspinbox.h>
52 #include "knumvalidator.h"
53 #include "knuminput.h"
55 static inline int calcDiffByTen(
int x,
int y ) {
57 return ( x / 10 ) - ( y / 10 ) + ( x % 10 - y % 10 ) / 10;
63 : TQWidget(parent, name)
69 : TQWidget(parent, name)
74 m_next = below->m_next;
78 m_next->m_prev =
this;
82 void KNumInput::init()
85 m_colw1 = m_colw2 = 0;
92 KNumInput::~KNumInput()
95 m_prev->m_next = m_next;
98 m_next->m_prev = m_prev;
103 if(label.isEmpty()) {
109 if (m_label) m_label->setText(label);
110 else m_label =
new TQLabel(label,
this,
"KNumInput::TQLabel");
111 m_label->setAlignment((a & (~(AlignTop|AlignBottom|AlignVCenter)))
114 if(!(a & (AlignTop|AlignBottom|AlignVCenter)))
124 if (m_label)
return m_label->text();
125 return TQString::null;
134 m_sizeLabel = (m_label ? m_label->sizeHint() : TQSize(0,0));
136 if(m_label && (m_alignment & AlignVCenter))
137 m_colw1 = m_sizeLabel.width() + 4;
142 m_sizeSlider = (m_slider ? m_slider->sizeHint() : TQSize(0, 0));
155 w1 = QMAX(w1, p->m_colw1);
156 w2 = QMAX(w2, p->m_colw2);
163 w1 = QMAX(w1, p->m_colw1);
164 w2 = QMAX(w2, p->m_colw2);
187 return TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
192 return minimumSizeHint();
198 m_slider->setSteps( minor, major );
205 : TQSpinBox(0, 99, 1, parent, name)
207 editor()->setAlignment(AlignRight);
218 TQWidget* parent,
const char* name)
219 : TQSpinBox(lower, upper, step, parent, name)
221 editor()->setAlignment(AlignRight);
244 return TQString::number(v, val_base);
249 return cleanText().toInt(ok, val_base);
254 editor()->setFocus();
256 editor()->selectAll();
262 class KIntNumInput::KIntNumInputPrivate {
266 KIntNumInputPrivate(
int r )
268 blockRelative( 0 ) {}
273 int _base,
const char* name)
292 void KIntNumInput::init(
int val,
int _base)
294 d =
new KIntNumInputPrivate( val );
295 m_spin =
new KIntSpinBox(INT_MIN, INT_MAX, 1, val, _base,
this,
"KIntNumInput::KIntSpinBox");
300 m_spin->setValidator(
new KIntValidator(
this, _base,
"KNumInput::KIntValidtr"));
302 connect(m_spin, TQT_SIGNAL(
valueChanged(
int)), TQT_SLOT(spinValueChanged(
int)));
304 TQT_SLOT(slotEmitRelativeValueChanged(
int)));
306 setFocusProxy(m_spin);
313 d->referencePoint = ref;
317 return d->referencePoint;
320 void KIntNumInput::spinValueChanged(
int val)
323 m_slider->setValue(val);
328 void KIntNumInput::slotEmitRelativeValueChanged(
int value ) {
329 if ( d->blockRelative || !d->referencePoint )
return;
335 upper = kMax(upper, lower);
336 lower = kMin(upper, lower);
337 m_spin->setMinValue(lower);
338 m_spin->setMaxValue(upper);
339 m_spin->setLineStep(step);
341 step = m_spin->lineStep();
345 m_slider->setRange(lower, upper);
347 m_slider =
new TQSlider(lower, upper, step, m_spin->value(),
348 Qt::Horizontal,
this);
349 m_slider->setTickmarks(TQSlider::Below);
355 int major = calcDiffByTen( upper, lower );
356 if ( major==0 ) major = step;
358 m_slider->setSteps(step, major);
359 m_slider->setTickInterval(major);
374 setRange(min, m_spin->maxValue(), m_spin->lineStep(), m_slider);
379 return m_spin->minValue();
384 setRange(m_spin->minValue(), max, m_spin->lineStep(), m_slider);
389 return m_spin->maxValue();
394 m_spin->setSuffix(suffix);
401 return m_spin->suffix();
406 m_spin->setPrefix(prefix);
413 return m_spin->prefix();
428 h = 2 + QMAX(m_sizeSpin.height(), m_sizeSlider.height());
431 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
432 h += 4 + m_sizeLabel.height();
435 h = QMAX(h, m_sizeLabel.height() + 2);
437 w = m_slider ? m_slider->sizeHint().width() + 8 : 0;
438 w += m_colw1 + m_colw2;
440 if(m_alignment & (AlignTop|AlignBottom))
441 w = QMAX(w, m_sizeLabel.width() + 4);
448 m_sizeSpin = m_spin->sizeHint();
449 m_colw2 = m_sizeSpin.width();
452 m_label->setBuddy(m_spin);
455 void KIntNumInput::resizeEvent(TQResizeEvent* e)
460 if(m_label && (m_alignment & AlignTop)) {
461 m_label->setGeometry(0, 0, e->size().width(), m_sizeLabel.height());
465 if(m_label && (m_alignment & AlignVCenter))
466 m_label->setGeometry(0, 0, w, m_sizeSpin.height());
468 if (tqApp->reverseLayout())
470 m_spin->setGeometry(w, h, m_slider ? m_colw2 : QMAX(m_colw2, e->size().width() - w), m_sizeSpin.height());
474 m_slider->setGeometry(w, h, e->size().width() - w, m_sizeSpin.height());
477 m_slider->setGeometry(w, h, e->size().width() - (w + m_colw2 +
KDialog::spacingHint()), m_sizeSpin.height());
478 m_spin->setGeometry(w + m_slider->size().width() +
KDialog::spacingHint(), h, m_colw2, m_sizeSpin.height());
481 m_spin->setGeometry(w, h, QMAX(m_colw2, e->size().width() - w), m_sizeSpin.height());
484 h += m_sizeSpin.height() + 2;
486 if(m_label && (m_alignment & AlignBottom))
487 m_label->setGeometry(0, h, m_sizeLabel.width(), m_sizeLabel.height());
497 m_spin->setValue(val);
502 if ( !d->referencePoint )
return;
504 setValue(
int( d->referencePoint * r + 0.5 ) );
509 if ( !d->referencePoint )
return 0;
510 return double(
value() ) / double ( d->referencePoint );
515 return m_spin->value();
520 m_spin->setSpecialValueText(text);
526 return m_spin->specialValueText();
534 m_label->setBuddy(m_spin);
539 class KDoubleNumInput::KDoubleNumInputPrivate {
541 KDoubleNumInputPrivate(
double r )
544 blockRelative ( 0 ) {}
553 init(0.0, 0.0, 9999.0, 0.01, 2);
557 double step,
int precision, TQWidget* parent,
561 init(value, lower, upper, step, precision);
565 double lower,
double upper,
double value,
566 double step,
int precision, TQWidget* parent,
570 init(value, lower, upper, step, precision);
576 init(value, kMin(0.0, value), kMax(0.0, value), 0.01, 2 );
583 init( value, kMin(0.0, value), kMax(0.0, value), 0.01, 2 );
593 bool KDoubleNumInput::eventFilter( TQObject * o, TQEvent * e ) {
594 return KNumInput::eventFilter( o, e );
597 void KDoubleNumInput::resetEditBox() {
605 void KDoubleNumInput::init(
double value,
double lower,
double upper,
606 double step,
int precision )
615 d =
new KDoubleNumInputPrivate( value );
617 d->spin =
new KDoubleSpinBox( lower, upper, step, value, precision,
618 this,
"KDoubleNumInput::d->spin" );
619 setFocusProxy(d->spin);
623 this, TQT_SLOT(slotEmitRelativeValueChanged(
double)) );
625 updateLegacyMembers();
630 void KDoubleNumInput::updateLegacyMembers() {
635 m_step = d->spin->lineStep();
640 double KDoubleNumInput::mapSliderToSpin(
int val )
const
643 double spinmin = d->spin->minValue();
644 double spinmax = d->spin->maxValue();
645 double slidemin = m_slider->minValue();
646 double slidemax = m_slider->maxValue();
647 double rel = ( double(val) - slidemin ) / ( slidemax - slidemin );
648 return spinmin + rel * ( spinmax - spinmin );
651 void KDoubleNumInput::sliderMoved(
int val)
653 d->spin->setValue( mapSliderToSpin( val ) );
656 void KDoubleNumInput::slotEmitRelativeValueChanged(
double value )
658 if ( !d->referencePoint )
return;
662 TQSize KDoubleNumInput::minimumSizeHint()
const
669 h = 2 + QMAX(m_sizeEdit.height(), m_sizeSlider.height());
672 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
673 h += 4 + m_sizeLabel.height();
676 h = QMAX(h, m_sizeLabel.height() + 2);
678 w = m_slider ? m_slider->sizeHint().width() + 8 : 0;
679 w += m_colw1 + m_colw2;
681 if(m_alignment & (AlignTop|AlignBottom))
682 w = QMAX(w, m_sizeLabel.width() + 4);
687 void KDoubleNumInput::resizeEvent(TQResizeEvent* e)
692 if(m_label && (m_alignment & AlignTop)) {
693 m_label->setGeometry(0, 0, e->size().width(), m_sizeLabel.height());
694 h += m_sizeLabel.height() + 4;
697 if(m_label && (m_alignment & AlignVCenter))
698 m_label->setGeometry(0, 0, w, m_sizeEdit.height());
700 if (tqApp->reverseLayout())
702 d->spin->setGeometry(w, h, m_slider ? m_colw2
703 : e->size().width() - w, m_sizeEdit.height());
707 m_slider->setGeometry(w, h, e->size().width() - w, m_sizeEdit.height());
710 m_slider->setGeometry(w, h, e->size().width() -
712 m_sizeEdit.height());
714 m_colw2, m_sizeEdit.height());
717 d->spin->setGeometry(w, h, e->size().width() - w, m_sizeEdit.height());
720 h += m_sizeEdit.height() + 2;
722 if(m_label && (m_alignment & AlignBottom))
723 m_label->setGeometry(0, h, m_sizeLabel.width(), m_sizeLabel.height());
728 m_sizeEdit = d->spin->sizeHint();
729 m_colw2 = m_sizeEdit.width();
734 d->spin->setValue( val );
739 if ( !d->referencePoint )
return;
749 d->referencePoint = ref;
757 TQSpinBox * spin = d->spin;
759 m_slider, TQT_SLOT(
setValue(
int)) );
761 d->spin->setRange( lower, upper, step, d->spin->precision() );
765 TQSpinBox * spin = d->spin;
766 int slmax = spin->maxValue();
767 int slmin = spin->minValue();
768 int slvalue = spin->value();
769 int slstep = spin->lineStep();
771 m_slider->setRange(slmin, slmax);
772 m_slider->setValue(slvalue);
774 m_slider =
new TQSlider(slmin, slmax, slstep, slvalue,
775 Qt::Horizontal,
this);
776 m_slider->setTickmarks(TQSlider::Below);
779 TQT_SLOT(sliderMoved(
int)) );
782 m_slider, TQT_SLOT(
setValue(
int)) );
784 int major = calcDiffByTen( slmax, slmin );
785 if ( !major ) major = slstep;
786 m_slider->setSteps(slstep, major);
787 m_slider->setTickInterval(major);
796 updateLegacyMembers();
806 return d->spin->minValue();
816 return d->spin->maxValue();
821 return d->spin->value();
826 if ( !d->referencePoint )
return 0;
827 return value() / d->referencePoint;
832 return d->referencePoint;
837 return d->spin->suffix();
842 return d->spin->prefix();
847 d->spin->setSuffix( suffix );
854 d->spin->setPrefix( prefix );
861 d->spin->setPrecision( precision );
864 TQSpinBox * spin = d->spin;
865 m_slider->setRange(spin->minValue(), spin->maxValue());
866 m_slider->setValue(spin->value());
867 int major = calcDiffByTen(spin->maxValue(), spin->minValue());
868 if ( !major ) major = spin->lineStep();
869 m_slider->setSteps(spin->lineStep(), major);
870 m_slider->setTickInterval(major);
878 return d->spin->precision();
883 d->spin->setSpecialValueText( text );
886 updateLegacyMembers();
894 m_label->setBuddy(d->spin);
904 KDoubleSpinBoxValidator(
double bottom,
double top,
int decimals,
KDoubleSpinBox* sb,
const char *name )
905 :
KDoubleValidator( bottom, top, decimals, TQT_TQOBJECT(sb), name ), spinBox( sb ) { }
907 virtual State
validate( TQString& str,
int& pos )
const;
915 TQString pref = spinBox->prefix();
916 TQString suff = spinBox->suffix();
917 TQString suffStriped = suff.stripWhiteSpace();
918 uint overhead = pref.length() + suff.length();
919 State state = Invalid;
921 if ( overhead == 0 ) {
924 bool stripedVersion =
false;
925 if ( str.length() >= overhead && str.startsWith(pref)
926 && (str.endsWith(suff)
927 || (stripedVersion = str.endsWith(suffStriped))) ) {
928 if ( stripedVersion )
929 overhead = pref.length() + suffStriped.length();
930 TQString core = str.mid( pref.length(), str.length() - overhead );
931 int corePos = pos - pref.length();
933 pos = corePos + pref.length();
934 str.replace( pref.length(), str.length() - overhead, core );
937 if ( state == Invalid ) {
939 TQString special = spinBox->specialValueText().stripWhiteSpace();
940 TQString candidate = str.stripWhiteSpace();
942 if ( special.startsWith(candidate) ) {
943 if ( candidate.length() == special.length() ) {
946 state = Intermediate;
965 class KDoubleSpinBox::Private {
967 Private(
int precision=1 )
968 : mPrecision( precision ),
975 for (
int i = 0 ; i < mPrecision ; ++i ) f *= 10;
979 double basicStep()
const {
980 return 1.0/double(factor());
983 int mapToInt(
double value,
bool * ok )
const {
985 const double f = factor();
986 if ( value >
double(INT_MAX) / f ) {
987 kdWarning() <<
"KDoubleSpinBox: can't represent value " << value
988 <<
"in terms of fixed-point numbers with precision "
989 << mPrecision <<
endl;
992 }
else if ( value <
double(INT_MIN) / f ) {
993 kdWarning() <<
"KDoubleSpinBox: can't represent value " << value
994 <<
"in terms of fixed-point numbers with precision "
995 << mPrecision <<
endl;
1000 return int( value * f + ( value < 0 ? -0.5 : 0.5 ) );
1004 double mapToDouble(
int value )
const {
1005 return double(value) * basicStep();
1009 KDoubleSpinBoxValidator * mValidator;
1013 : TQSpinBox( parent, name )
1015 editor()->setAlignment( Qt::AlignRight );
1018 connect(
this, TQT_SIGNAL(
valueChanged(
int)), TQT_SLOT(slotValueChanged(
int)) );
1022 double value,
int precision,
1023 TQWidget * parent,
const char * name )
1024 : TQSpinBox( parent, name )
1026 editor()->setAlignment( Qt::AlignRight );
1028 setRange( lower, upper, step, precision );
1030 connect(
this, TQT_SIGNAL(
valueChanged(
int)), TQT_SLOT(slotValueChanged(
int)) );
1033 KDoubleSpinBox::~KDoubleSpinBox() {
1038 if ( !d->mValidator )
return true;
1040 return d->mValidator->acceptLocalizedNumbers();
1044 if ( !d->mValidator ) updateValidator();
1045 d->mValidator->setAcceptLocalizedNumbers( accept );
1050 lower = kMin(upper, lower);
1051 upper = kMax(upper, lower);
1059 return d->mPrecision;
1067 if ( precision < 0 )
return;
1069 int maxPrec = maxPrecision();
1070 if ( precision > maxPrec )
1072 precision = maxPrec;
1076 int oldPrecision = d->mPrecision;
1077 double oldValue =
value();
1082 if (precision != oldPrecision)
1092 int KDoubleSpinBox::maxPrecision()
const {
1098 if ( maxAbsValue == 0 )
return 6;
1100 return int( floor( log10(
double(INT_MAX) / maxAbsValue ) ) );
1104 return d->mapToDouble( base::value() );
1108 if ( value == this->
value() )
return;
1121 return d->mapToDouble( base::minValue() );
1126 int min = d->mapToInt( value, &ok );
1133 return d->mapToDouble( base::maxValue() );
1138 int max = d->mapToInt( value, &ok );
1144 return d->mapToDouble( base::lineStep() );
1155 TQString KDoubleSpinBox::mapValueToText(
int value ) {
1158 ->
formatNumber( d->mapToDouble( value ), d->mPrecision );
1160 return TQString().setNum( d->mapToDouble( value ),
'f', d->mPrecision );
1163 int KDoubleSpinBox::mapTextToValue(
bool * ok ) {
1168 value = cleanText().toDouble( ok );
1169 if ( !*ok )
return 0;
1174 return d->mapToInt( value, ok );
1181 void KDoubleSpinBox::slotValueChanged(
int value ) {
1185 void KDoubleSpinBox::updateValidator() {
1186 if ( !d->mValidator ) {
1188 this,
"d->mValidator" );
1194 void KNumInput::virtual_hook(
int,
void* )
1197 void KIntNumInput::virtual_hook(
int id,
void* data )
1198 { KNumInput::virtual_hook(
id, data ); }
1200 void KDoubleNumInput::virtual_hook(
int id,
void* data )
1201 { KNumInput::virtual_hook(
id, data ); }
1203 void KIntSpinBox::virtual_hook(
int,
void* )
1206 void KDoubleSpinBox::virtual_hook(
int,
void* )
1209 #include "knuminput.moc"