00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "qwwlongspinbox.h"
00013
00014 #ifndef WW_NO_SPINBOX
00015
00016 #include <QLineEdit>
00017 #include <QMessageBox>
00018 #include <QStyleOptionSpinBox>
00019 #include <QLocale>
00020 #include <QValidator>
00021 #include "wwglobal_p.h"
00022
00033 class QwwLongSpinBoxPrivate : public QwwPrivate {
00034 public:
00035 WW_DECLARE_PUBLIC(QwwLongSpinBox);
00036 QwwLongSpinBoxPrivate(QwwLongSpinBox *p) : QwwPrivate(p) {
00037 value = 0;
00038 minimum = 0;
00039 maximum = 99;
00040 singlestep = 1;
00041 }
00042 qlonglong value;
00043 qlonglong minimum;
00044 qlonglong maximum;
00045 qlonglong singlestep;
00046 QString prefix;
00047 QString suffix;
00048
00049 void updateEdit();
00050 void updateButtons();
00051 QString textFromValue(qlonglong value) const {
00052 QString s = QLocale().toString(value);
00053 s.remove(QLocale().groupSeparator());
00054 return s;
00055 }
00056 qlonglong valueFromText(const QString &text) const {
00057 QString tmp = text;
00058 if (!prefix.isEmpty() && tmp.startsWith(prefix)) {
00059 tmp.remove(0, prefix.size());
00060 }
00061 if (!suffix.isEmpty() && tmp.endsWith(suffix)) {
00062 tmp.chop(suffix.size());
00063 }
00064 return tmp.toLongLong();
00065 }
00066 };
00067
00071 class QwwLongSpinBoxValidator : public QValidator {
00072 public:
00073 QwwLongSpinBoxValidator(QwwLongSpinBox *sb) : QValidator(sb), m_spinbox(sb) {}
00074 void fixup ( QString & input ) const {
00075 m_spinbox->fixup(input);
00076 }
00077 State validate ( QString & input, int & pos ) const {
00078 if (!m_spinbox->prefix().isEmpty() && !input.startsWith(m_spinbox->prefix())) {
00079 input.prepend(m_spinbox->prefix());
00080 }
00081 if (!m_spinbox->suffix().isEmpty() && !input.endsWith(m_spinbox->suffix())) {
00082 input.append(m_spinbox->suffix());
00083 }
00084 return m_spinbox->validate(input, pos);
00085 }
00086 private:
00087 QwwLongSpinBox *m_spinbox;
00088 };
00089
00090 QwwLongSpinBox::QwwLongSpinBox(QWidget *parent)
00091 : QAbstractSpinBox(parent), QwwPrivatable(new QwwLongSpinBoxPrivate(this)) {
00092 Q_D(QwwLongSpinBox);
00093 d->updateEdit();
00094
00095 lineEdit()->setValidator(new QwwLongSpinBoxValidator(this));
00096 connect(lineEdit(), SIGNAL(textChanged(const QString &)), SLOT(_q_editorTextChanged(const QString &)));
00097 }
00098
00099
00100 QwwLongSpinBox::~QwwLongSpinBox() {
00101 }
00102
00106 qlonglong QwwLongSpinBox::value() const {
00107 Q_D(const QwwLongSpinBox);
00108 return d->value;
00109 }
00110
00114 qlonglong QwwLongSpinBox::minimum() const {
00115 Q_D(const QwwLongSpinBox);
00116 return d->minimum;
00117 }
00118
00122 qlonglong QwwLongSpinBox::maximum() const {
00123 Q_D(const QwwLongSpinBox);
00124 return d->maximum;
00125 }
00126
00130 const QString & QwwLongSpinBox::prefix() const {
00131 Q_D(const QwwLongSpinBox);
00132 return d->prefix;
00133 }
00134
00138 const QString & QwwLongSpinBox::suffix() const {
00139 Q_D(const QwwLongSpinBox);
00140 return d->suffix;
00141 }
00142
00148 QString QwwLongSpinBox::textFromValue(qlonglong value) const {
00149 Q_D(const QwwLongSpinBox);
00150 return d->textFromValue(value);
00151 }
00152
00158 qlonglong QwwLongSpinBox::valueFromText(const QString & text) const {
00159 Q_D(const QwwLongSpinBox);
00160 return d->valueFromText(text);
00161 }
00162
00167 void QwwLongSpinBox::setMaximum(qlonglong v) {
00168 if (maximum()==v)
00169 return;
00170 Q_D(QwwLongSpinBox);
00171 setRange(qMin(d->minimum, v), v);
00172 }
00173
00178 void QwwLongSpinBox::setMinimum(qlonglong v) {
00179 if (minimum()==v)
00180 return;
00181 Q_D(QwwLongSpinBox);
00182 setRange(v, qMax(d->maximum, v));
00183 }
00184
00189 void QwwLongSpinBox::setValue(qlonglong v) {
00190 v = qBound(minimum(), v, maximum());
00191 if (value()==v)
00192 return;
00193 Q_D(QwwLongSpinBox);
00194 d->value = v;
00195 QString textval = d->prefix + textFromValue(v) + d->suffix;
00196 d->updateEdit();
00197 emit valueChanged(v);
00198 emit valueChanged(textval);
00199 }
00200
00205 void QwwLongSpinBox::setPrefix(const QString &p) {
00206 Q_D(QwwLongSpinBox);
00207 d->prefix = p;
00208 d->updateEdit();
00209 }
00210
00215 void QwwLongSpinBox::setSuffix(const QString &s) {
00216 Q_D(QwwLongSpinBox);
00217 d->suffix = s;
00218 d->updateEdit();
00219 }
00220
00225 qlonglong QwwLongSpinBox::singleStep() const {
00226 Q_D(const QwwLongSpinBox);
00227 return d->singlestep;
00228 }
00229
00234 void QwwLongSpinBox::setSingleStep(qlonglong s) {
00235 if (s==0)
00236 return;
00237 Q_D(QwwLongSpinBox);
00238 d->singlestep = s;
00239 }
00240
00246 void QwwLongSpinBox::setRange(qlonglong min, qlonglong max) {
00247 Q_D(QwwLongSpinBox);
00248 d->minimum = min;
00249 d->maximum = max;
00250 if (value()<d->minimum) {
00251 setValue(d->minimum);
00252 } else if (value()>d->maximum) {
00253 setValue(d->maximum);
00254 }
00255 }
00256
00257
00262 void QwwLongSpinBox::stepBy(int steps) {
00263 if (steps==0)
00264 return;
00265 qlonglong nvalue = value()+steps*singleStep();
00266 if (wrapping()) {
00267 qlonglong d = nvalue-maximum();
00268 qlonglong nd = nvalue - minimum();
00269 if (nvalue>value() && d>0) {
00270 nvalue = minimum()+d-1;
00271 } else if (nvalue < value() && nd<0) {
00272 nvalue = maximum()+nd+1;
00273 }
00274 } else {
00275 nvalue = qBound(minimum(), nvalue, maximum());
00276 }
00277 setValue(nvalue);
00278 selectAll();
00279 }
00280
00281
00288 QValidator::State QwwLongSpinBox::validate(QString & input, int & pos) const {
00289 QString tinput = input;
00290 if (!prefix().isEmpty() && tinput.startsWith(prefix()))
00291 tinput.remove(0, prefix().size());
00292 if (!suffix().isEmpty() && tinput.endsWith(suffix()))
00293 tinput.chop(suffix().size());
00294 bool ok;
00295 qlonglong v = tinput.toLongLong(&ok);
00296 if (!ok)
00297 return QValidator::Invalid;
00298 if (v<minimum() || v>maximum())
00299 return QValidator::Invalid;
00300 return QValidator::Acceptable;
00301 }
00302
00303 void QwwLongSpinBox::fixup(QString & input) const {
00304 input.remove(QLocale().groupSeparator());
00305 }
00306
00307
00312 QAbstractSpinBox::StepEnabled QwwLongSpinBox::stepEnabled() const {
00313 if (wrapping())
00314 return StepUpEnabled|StepDownEnabled;
00315 StepEnabled se = 0;
00316 if (value()<maximum()) se |= StepUpEnabled;
00317 if (value()>minimum()) se |= StepDownEnabled;
00318 return se;
00319 }
00320
00321 void QwwLongSpinBoxPrivate::updateEdit() {
00322 Q_Q(QwwLongSpinBox);
00323 QLineEdit *edit = q->lineEdit();
00324 QString textval = prefix + q->textFromValue(value) + suffix;
00325 const bool empty = edit->text().isEmpty();
00326 int cursor = edit->cursorPosition();
00327 const bool sb = edit->blockSignals(true);
00328 edit->setText(textval);
00329 cursor = qBound(prefix.size(), cursor, edit->displayText().size() - suffix.size());
00330 edit->setCursorPosition(empty ? prefix.size() : cursor);
00331 edit->blockSignals(sb);
00332 updateButtons();
00333 }
00334
00335
00336 void QwwLongSpinBoxPrivate::updateButtons() {
00337 Q_Q(QwwLongSpinBox);
00338 QStyleOptionSpinBox opt;
00339 opt.init(q);
00340 opt.activeSubControls = 0;
00341 opt.buttonSymbols = q->buttonSymbols();
00342 opt.subControls = QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown | QStyle::SC_SpinBoxFrame;
00343 opt.stepEnabled = q->stepEnabled();
00344 opt.frame = q->hasFrame();
00345 q->update(q->style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp, q));
00346 q->update(q->style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown, q));
00347 }
00348
00349 void QwwLongSpinBox::_q_editorTextChanged(const QString & t) {
00350
00351 QString tmp = t;
00352 int pos = lineEdit()->cursorPosition();
00353 QValidator::State state = validate(tmp, pos);
00354 if (state==QValidator::Acceptable) {
00355 setValue(valueFromText(tmp));
00356 }
00357 }
00358
00359 #endif // WW_NO_SPINBOX