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 )
267 : referencePoint( 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,
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;
913 TQValidator::State KDoubleSpinBoxValidator::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;
1110 base::setValue( base::minValue() );
1112 base::setValue( base::maxValue() );
1115 base::setValue( d->mapToInt( value, &ok ) );
1121 return d->mapToDouble( base::minValue() );
1126 int min = d->mapToInt( value, &ok );
1127 base::setMinValue( min );
1133 return d->mapToDouble( base::maxValue() );
1138 int max = d->mapToInt( value, &ok );
1139 base::setMaxValue( max );
1144 return d->mapToDouble( base::lineStep() );
1150 base::setLineStep( 1 );
1152 base::setLineStep( kMax( d->mapToInt( step, &ok ), 1 ) );
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" );
1189 base::setValidator( 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"
void setPrecision(int precision)
Equivalent to setPrecision( precision, false ); Needed since Qt's moc doesn't ignore trailing paramet...
virtual ~KIntSpinBox()
Destructor.
static KLocale * locale()
virtual TQValidator::State validate(TQString &input, int &pos) const
Overloaded for internal reasons.
void setRange(double lower, double upper, double step=0.01, int precision=2)
Sets a new range for the spin box values.
bool acceptLocalizedNumbers() const
A spin box for fractional numbers.
void setMinValue(double value)
Sets the lower bound of the range to value, subject to the contraints that value is first rounded to ...
KIntSpinBox(TQWidget *parent=0, const char *name=0)
Constructor.
static int spacingHint()
Return the number of pixels you shall use between widgets inside a dialog according to the KDE standa...
kdbgstream kdWarning(int area=0)
virtual void setValue(double value)
Sets the current value to value, subject to the constraints that value is first rounded to the curren...
TQValidator for integers.
A locale-aware QDoubleValidator.
virtual void setAcceptLocalizedNumbers(bool accept)
Sets whether to use and accept localized numbers as returned by KLocale::formatNumber() ...
A TQSpinBox with support for arbitrary base numbers.
virtual int mapTextToValue(bool *)
Overloaded the method in QSpinBox to make use of the base given in the constructor.
TQString formatNumber(double num, int precision=-1) const
virtual TQString mapValueToText(int)
Overloaded the method in QSpinBox to make use of the base given in the constructor.
void setBase(int base)
Sets the base in which the numbers in the spin box are represented.
void setEditFocus(bool mark)
sets focus and optionally marks all text
KDoubleSpinBox(TQWidget *parent=0, const char *name=0)
Constructs a KDoubleSpinBox with parent parent and default values for range and value (whatever QRang...
kndbgstream & endl(kndbgstream &s)
void setValidator(const TQValidator *)
Overridden to ignore any setValidator() calls.
void setLineStep(double step)
Sets the step size for clicking the up/down buttons to step, subject to the constraints that step is ...
void valueChanged(double value)
Emitted whenever TQSpinBox::valueChanged( int ) is emitted.
void setMaxValue(double value)
Sets the upper bound of the range to value, subject to the contraints that value is first rounded to ...
double readNumber(const TQString &numStr, bool *ok=0) const