qwwlongspinbox.cpp

00001 //
00002 // C++ Implementation: "long long" value spin box widget
00003 //
00004 // Description:
00005 //
00006 //
00007 // Author: Witold Wysota <wysota@wysota.eu.org>, (C) 2007
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
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 //     void _q_editorTextChanged(const QString & t);
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/*Private*/::_q_editorTextChanged(const QString & t) {
00350 //     WW_Q(QwwLongSpinBox);
00351     QString tmp = t;
00352     int pos = /*q->*/lineEdit()->cursorPosition();
00353     QValidator::State state = /*q->*/validate(tmp, pos);
00354     if (state==QValidator::Acceptable) {
00355         /*q->*/setValue(valueFromText(tmp));
00356     }
00357 }
00358 
00359 #endif // WW_NO_SPINBOX

Generated on Sat Apr 21 21:54:35 2007 for wwWidgets by  doxygen 1.5.1