39 #include <tqapplication.h> 41 #include <tqlineedit.h> 44 #include <tqspinbox.h> 47 #include <tdeglobal.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 = TQMAX(w1, p->m_colw1);
156 w2 = TQMAX(w2, p->m_colw2);
163 w1 = TQMAX(w1, p->m_colw1);
164 w2 = TQMAX(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 + TQMAX(m_sizeSpin.height(), m_sizeSlider.height());
431 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
432 h += 4 + m_sizeLabel.height();
435 h = TQMAX(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 = TQMAX(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 : TQMAX(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, TQMAX(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 + TQMAX(m_sizeEdit.height(), m_sizeSlider.height());
672 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
673 h += 4 + m_sizeLabel.height();
676 h = TQMAX(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 = TQMAX(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->setLineStep(slstep);
773 m_slider->setValue(slvalue);
775 m_slider =
new TQSlider(slmin, slmax, slstep, slvalue,
776 Qt::Horizontal,
this);
777 m_slider->setTickmarks(TQSlider::Below);
780 TQT_SLOT(sliderMoved(
int)) );
783 m_slider, TQT_SLOT(
setValue(
int)) );
785 int major = calcDiffByTen( slmax, slmin );
786 if ( !major ) major = slstep;
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 );
868 return d->spin->precision();
873 d->spin->setSpecialValueText( text );
876 updateLegacyMembers();
884 m_label->setBuddy(d->spin);
894 KDoubleSpinBoxValidator(
double bottom,
double top,
int decimals,
KDoubleSpinBox* sb,
const char *name )
895 :
KDoubleValidator( bottom, top, decimals, TQT_TQOBJECT(sb), name ), spinBox( sb ) { }
897 virtual State validate( TQString& str,
int& pos )
const;
903 TQValidator::State KDoubleSpinBoxValidator::validate( TQString& str,
int& pos )
const 905 TQString pref = spinBox->prefix();
906 TQString suff = spinBox->suffix();
907 TQString suffStriped = suff.stripWhiteSpace();
908 uint overhead = pref.length() + suff.length();
909 State state = Invalid;
911 if ( overhead == 0 ) {
914 bool stripedVersion =
false;
915 if ( str.length() >= overhead && str.startsWith(pref)
916 && (str.endsWith(suff)
917 || (stripedVersion = str.endsWith(suffStriped))) ) {
918 if ( stripedVersion )
919 overhead = pref.length() + suffStriped.length();
920 TQString core = str.mid( pref.length(), str.length() - overhead );
921 int corePos = pos - pref.length();
923 pos = corePos + pref.length();
924 str.replace( pref.length(), str.length() - overhead, core );
927 if ( state == Invalid ) {
929 TQString special = spinBox->specialValueText().stripWhiteSpace();
930 TQString candidate = str.stripWhiteSpace();
932 if ( special.startsWith(candidate) ) {
933 if ( candidate.length() == special.length() ) {
936 state = Intermediate;
955 class KDoubleSpinBox::Private {
957 Private(
int precision=1 )
958 : mPrecision( precision ),
965 for (
int i = 0 ; i < mPrecision ; ++i ) f *= 10;
969 double basicStep()
const {
970 return 1.0/double(factor());
973 int mapToInt(
double value,
bool * ok )
const {
975 const double f = factor();
976 if ( value >
double(INT_MAX) / f ) {
977 kdWarning() <<
"KDoubleSpinBox: can't represent value " << value
978 <<
"in terms of fixed-point numbers with precision " 979 << mPrecision <<
endl;
982 }
else if ( value <
double(INT_MIN) / f ) {
983 kdWarning() <<
"KDoubleSpinBox: can't represent value " << value
984 <<
"in terms of fixed-point numbers with precision " 985 << mPrecision <<
endl;
990 return int( value * f + ( value < 0 ? -0.5 : 0.5 ) );
994 double mapToDouble(
int value )
const {
995 return double(value) * basicStep();
999 KDoubleSpinBoxValidator * mValidator;
1003 : TQSpinBox( parent, name )
1005 editor()->setAlignment( Qt::AlignRight );
1008 connect(
this, TQT_SIGNAL(
valueChanged(
int)), TQT_SLOT(slotValueChanged(
int)) );
1012 double value,
int precision,
1013 TQWidget * parent,
const char * name )
1014 : TQSpinBox( parent, name )
1016 editor()->setAlignment( Qt::AlignRight );
1018 setRange( lower, upper, step, precision );
1020 connect(
this, TQT_SIGNAL(
valueChanged(
int)), TQT_SLOT(slotValueChanged(
int)) );
1023 KDoubleSpinBox::~KDoubleSpinBox() {
1028 if ( !d->mValidator )
return true;
1030 return d->mValidator->acceptLocalizedNumbers();
1034 if ( !d->mValidator ) updateValidator();
1035 d->mValidator->setAcceptLocalizedNumbers( accept );
1040 lower = kMin(upper, lower);
1041 upper = kMax(upper, lower);
1049 return d->mPrecision;
1057 if ( precision < 1 )
return;
1059 int maxPrec = maxPrecision();
1060 if ( precision > maxPrec )
1061 precision = maxPrec;
1067 int KDoubleSpinBox::maxPrecision()
const {
1073 if ( maxAbsValue == 0 )
return 6;
1075 return int( floor( log10(
double(INT_MAX) / maxAbsValue ) ) );
1079 return d->mapToDouble( base::value() );
1083 if ( value == this->
value() )
return;
1085 base::setValue( base::minValue() );
1087 base::setValue( base::maxValue() );
1090 base::setValue( d->mapToInt( value, &ok ) );
1096 return d->mapToDouble( base::minValue() );
1101 int min = d->mapToInt( value, &ok );
1102 base::setMinValue( min );
1108 return d->mapToDouble( base::maxValue() );
1113 int max = d->mapToInt( value, &ok );
1114 base::setMaxValue( max );
1119 return d->mapToDouble( base::lineStep() );
1125 base::setLineStep( 1 );
1127 base::setLineStep( kMax( d->mapToInt( step, &ok ), 1 ) );
1130 TQString KDoubleSpinBox::mapValueToText(
int value ) {
1133 ->
formatNumber( d->mapToDouble( value ), d->mPrecision );
1135 return TQString().setNum( d->mapToDouble( value ),
'f', d->mPrecision );
1138 int KDoubleSpinBox::mapTextToValue(
bool * ok ) {
1143 value = cleanText().toDouble( ok );
1144 if ( !*ok )
return 0;
1149 return d->mapToInt( value, ok );
1156 void KDoubleSpinBox::slotValueChanged(
int value ) {
1160 void KDoubleSpinBox::updateValidator() {
1161 if ( !d->mValidator ) {
1163 this,
"d->mValidator" );
1164 base::setValidator( d->mValidator );
1169 void KNumInput::virtual_hook(
int,
void* )
1172 void KIntNumInput::virtual_hook(
int id,
void* data )
1173 { KNumInput::virtual_hook(
id, data ); }
1175 void KDoubleNumInput::virtual_hook(
int id,
void* data )
1176 { KNumInput::virtual_hook(
id, data ); }
1178 void KIntSpinBox::virtual_hook(
int,
void* )
1181 void KDoubleSpinBox::virtual_hook(
int,
void* )
1184 #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.
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.
double readNumber(const TQString &numStr, bool *ok=0) const
virtual void setAcceptLocalizedNumbers(bool accept)
Sets whether to use and accept localized numbers as returned by TDELocale::formatNumber() ...
static TDELocale * locale()
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.
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 ...
TQString formatNumber(double num, int precision=-1) const