00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qlayout.h>
00013 #include <qlineedit.h>
00014 #include <qvalidator.h>
00015 #include <qevent.h>
00016 #include <qstyle.h>
00017 #include "qwt_math.h"
00018 #include "qwt_counter.h"
00019 #include "qwt_arrow_button.h"
00020
00021 class QwtCounter::PrivateData
00022 {
00023 public:
00024 PrivateData():
00025 blockKeys(false),
00026 keyPressed(false),
00027 editable(true)
00028 {
00029 increment[Button1] = 1;
00030 increment[Button2] = 10;
00031 increment[Button3] = 100;
00032 }
00033
00034 QwtArrowButton *buttonDown[ButtonCnt];
00035 QwtArrowButton *buttonUp[ButtonCnt];
00036 QLineEdit *valueEdit;
00037
00038 int increment[ButtonCnt];
00039 int nButtons;
00040
00041 bool blockKeys;
00042 bool keyPressed;
00043 bool editable;
00044 };
00045
00054 QwtCounter::QwtCounter(QWidget *parent):
00055 QWidget(parent)
00056 {
00057 d_data = new PrivateData;
00058
00059 #if QT_VERSION >= 0x040000
00060 using namespace Qt;
00061 #endif
00062
00063 QHBoxLayout *layout = new QHBoxLayout(this);
00064 layout->setSpacing(0);
00065 layout->setMargin(0);
00066
00067 int i;
00068 for(i = ButtonCnt - 1; i >= 0; i--)
00069 {
00070 QwtArrowButton *btn =
00071 new QwtArrowButton(i+1, Qt::DownArrow,this);
00072 btn->setFocusPolicy(StrongFocus);
00073 btn->installEventFilter(this);
00074 layout->addWidget(btn);
00075
00076 connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00077 connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00078
00079 d_data->buttonDown[i] = btn;
00080 }
00081
00082 d_data->valueEdit = new QLineEdit(this);
00083 d_data->valueEdit->setReadOnly(false);
00084 d_data->valueEdit->setFocusPolicy(StrongFocus);
00085 d_data->valueEdit->setValidator(new QDoubleValidator(d_data->valueEdit));
00086 layout->addWidget(d_data->valueEdit);
00087
00088 #if QT_VERSION >= 0x040000
00089 connect( d_data->valueEdit, SIGNAL(editingFinished()),
00090 SLOT(textChanged()) );
00091 #else
00092 connect( d_data->valueEdit, SIGNAL(returnPressed()), SLOT(textChanged()) );
00093 connect( d_data->valueEdit, SIGNAL(lostFocus()), SLOT(textChanged()) );
00094 #endif
00095
00096 layout->setStretchFactor(d_data->valueEdit, 10);
00097
00098 for(i = 0; i < ButtonCnt; i++)
00099 {
00100 #if QT_VERSION >= 0x040000
00101 using namespace Qt;
00102 #endif
00103 QwtArrowButton *btn =
00104 new QwtArrowButton(i+1, Qt::UpArrow, this);
00105 btn->setFocusPolicy(StrongFocus);
00106 btn->installEventFilter(this);
00107 layout->addWidget(btn);
00108
00109 connect(btn, SIGNAL(released()), SLOT(btnReleased()));
00110 connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
00111
00112 d_data->buttonUp[i] = btn;
00113 }
00114
00115 setNumButtons(2);
00116 setRange(0.0,1.0,0.001);
00117 setValue(0.0);
00118
00119 setSizePolicy(
00120 QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
00121 }
00122
00123 QwtCounter::~QwtCounter()
00124 {
00125 delete d_data;
00126 }
00127
00131 void QwtCounter::polish()
00132 {
00133 const int w = d_data->valueEdit->fontMetrics().width("W") + 8;
00134
00135 for ( int i = 0; i < ButtonCnt; i++ )
00136 {
00137 d_data->buttonDown[i]->setMinimumWidth(w);
00138 d_data->buttonUp[i]->setMinimumWidth(w);
00139 }
00140
00141 #if QT_VERSION < 0x040000
00142 QWidget::polish();
00143 #endif
00144 }
00145
00147 void QwtCounter::textChanged()
00148 {
00149 if ( !d_data->editable )
00150 return;
00151
00152 bool converted = false;
00153
00154 const double value = d_data->valueEdit->text().toDouble(&converted);
00155 if ( converted )
00156 setValue( value );
00157 }
00158
00165 void QwtCounter::setEditable(bool editable)
00166 {
00167 #if QT_VERSION >= 0x040000
00168 using namespace Qt;
00169 #endif
00170 if ( editable == d_data->editable )
00171 return;
00172
00173 d_data->editable = editable;
00174 if ( d_data->editable )
00175 {
00176 d_data->valueEdit->setReadOnly(false);
00177 d_data->valueEdit->setFocusPolicy(StrongFocus);
00178 }
00179 else
00180 {
00181 d_data->valueEdit->setReadOnly(true);
00182 d_data->valueEdit->setFocusPolicy(NoFocus);
00183 }
00184 }
00185
00187 bool QwtCounter::editable() const
00188 {
00189 return d_data->editable;
00190 }
00191
00195 bool QwtCounter::event ( QEvent * e )
00196 {
00197 #if QT_VERSION >= 0x040000
00198 if ( e->type() == QEvent::PolishRequest )
00199 polish();
00200 #endif
00201 return QWidget::event(e);
00202 }
00203
00205 bool QwtCounter::eventFilter(QObject *object, QEvent *e)
00206 {
00207 if ( object->inherits("QPushButton") )
00208 {
00209 if ( e->type() == QEvent::KeyPress )
00210 {
00211 if ( !((QKeyEvent *)e)->isAutoRepeat() )
00212 d_data->keyPressed = true;
00213 }
00214
00215 if ( e->type() == QEvent::KeyRelease )
00216 {
00217 if ( !((QKeyEvent *)e)->isAutoRepeat() )
00218 {
00219 d_data->keyPressed = false;
00220
00221
00222
00223
00224
00225 d_data->blockKeys = false;
00226 }
00227 }
00228 }
00229
00230 return QWidget::eventFilter(object, e);
00231 }
00232
00242 void QwtCounter::setIncSteps(QwtCounter::Button btn, int nSteps)
00243 {
00244 if (( btn >= 0) && (btn < ButtonCnt))
00245 d_data->increment[btn] = nSteps;
00246 }
00247
00254 int QwtCounter::incSteps(QwtCounter::Button btn) const
00255 {
00256 if (( btn >= 0) && (btn < ButtonCnt))
00257 return d_data->increment[btn];
00258
00259 return 0;
00260 }
00261
00269 void QwtCounter::setValue(double v)
00270 {
00271 QwtDoubleRange::setValue(v);
00272
00273 showNum(value());
00274 updateButtons();
00275 }
00276
00280 void QwtCounter::valueChange()
00281 {
00282 if ( isValid() )
00283 showNum(value());
00284 else
00285 d_data->valueEdit->setText(QString::null);
00286
00287 updateButtons();
00288
00289 if ( isValid() )
00290 emit valueChanged(value());
00291 }
00292
00301 void QwtCounter::updateButtons()
00302 {
00303 if ( isValid() )
00304 {
00305
00306
00307
00308
00309 int oldEnabledDown = d_data->buttonDown[0]->isEnabled();
00310 int oldEnabledUp = d_data->buttonUp[0]->isEnabled();
00311
00312 for ( int i = 0; i < ButtonCnt; i++ )
00313 {
00314 d_data->buttonDown[i]->setEnabled(value() > minValue());
00315 d_data->buttonUp[i]->setEnabled(value() < maxValue());
00316 }
00317
00318 QPushButton *focusButton = NULL;
00319 if (oldEnabledDown && !d_data->buttonDown[0]->isEnabled())
00320 focusButton = d_data->buttonUp[0];
00321
00322 if (oldEnabledUp && !d_data->buttonUp[0]->isEnabled())
00323 focusButton = d_data->buttonDown[0];
00324
00325 if ( focusButton )
00326 {
00327 focusButton->setFocus();
00328 if ( d_data->keyPressed )
00329 {
00330
00331 d_data->blockKeys = true;
00332 }
00333 }
00334 }
00335 else
00336 {
00337 for ( int i = 0; i < ButtonCnt; i++ )
00338 {
00339 d_data->buttonDown[i]->setEnabled(false);
00340 d_data->buttonUp[i]->setEnabled(false);
00341 }
00342 }
00343 }
00344
00349 void QwtCounter::setNumButtons(int n)
00350 {
00351 if ( n<0 || n>ButtonCnt )
00352 return;
00353
00354 for ( int i = 0; i < ButtonCnt; i++ )
00355 {
00356 if ( i < n )
00357 {
00358 d_data->buttonDown[i]->show();
00359 d_data->buttonUp[i]->show();
00360 }
00361 else
00362 {
00363 d_data->buttonDown[i]->hide();
00364 d_data->buttonUp[i]->hide();
00365 }
00366 }
00367
00368 d_data->nButtons = n;
00369 }
00370
00374 int QwtCounter::numButtons() const
00375 {
00376 return d_data->nButtons;
00377 }
00378
00380 void QwtCounter::showNum(double d)
00381 {
00382 QString v;
00383 v.setNum(d);
00384
00385 d_data->valueEdit->setText(v);
00386 d_data->valueEdit->setCursorPosition(0);
00387 }
00388
00390 void QwtCounter::btnClicked()
00391 {
00392 if (d_data->blockKeys)
00393 {
00394
00395
00396
00397
00398 return;
00399 }
00400
00401 for ( int i = 0; i < ButtonCnt; i++ )
00402 {
00403 if ( d_data->buttonUp[i] == sender() )
00404 incValue(d_data->increment[i]);
00405
00406 if ( d_data->buttonDown[i] == sender() )
00407 incValue(-d_data->increment[i]);
00408 }
00409 }
00410
00412 void QwtCounter::btnReleased()
00413 {
00414 emit buttonReleased(value());
00415 }
00416
00423 void QwtCounter::rangeChange()
00424 {
00425 updateButtons();
00426 }
00427
00429 QSize QwtCounter::sizeHint() const
00430 {
00431 QString tmp;
00432
00433 int w = tmp.setNum(minValue()).length();
00434 int w1 = tmp.setNum(maxValue()).length();
00435 if ( w1 > w )
00436 w = w1;
00437 w1 = tmp.setNum(minValue() + step()).length();
00438 if ( w1 > w )
00439 w = w1;
00440 w1 = tmp.setNum(maxValue() - step()).length();
00441 if ( w1 > w )
00442 w = w1;
00443
00444 tmp.fill('9', w);
00445
00446 QFontMetrics fm(d_data->valueEdit->font());
00447 w = fm.width(tmp) + 2;
00448 #if QT_VERSION >= 0x040000
00449 if ( d_data->valueEdit->hasFrame() )
00450 w += 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00451 #else
00452 w += 2 * d_data->valueEdit->frameWidth();
00453 #endif
00454
00455
00456
00457
00458 w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width();
00459
00460 const int h = qwtMin(QWidget::sizeHint().height(),
00461 d_data->valueEdit->minimumSizeHint().height());
00462 return QSize(w, h);
00463 }
00464
00466 double QwtCounter::step() const
00467 {
00468 return QwtDoubleRange::step();
00469 }
00470
00472 void QwtCounter::setStep(double s)
00473 {
00474 QwtDoubleRange::setStep(s);
00475 }
00476
00478 double QwtCounter::minVal() const
00479 {
00480 return minValue();
00481 }
00482
00484 void QwtCounter::setMinValue(double m)
00485 {
00486 setRange(m, maxValue(), step());
00487 }
00488
00490 double QwtCounter::maxVal() const
00491 {
00492 return QwtDoubleRange::maxValue();
00493 }
00494
00496 void QwtCounter::setMaxValue(double m)
00497 {
00498 setRange(minValue(), m, step());
00499 }
00500
00502 void QwtCounter::setStepButton1(int nSteps)
00503 {
00504 setIncSteps(Button1, nSteps);
00505 }
00506
00508 int QwtCounter::stepButton1() const
00509 {
00510 return incSteps(Button1);
00511 }
00512
00514 void QwtCounter::setStepButton2(int nSteps)
00515 {
00516 setIncSteps(Button2, nSteps);
00517 }
00518
00520 int QwtCounter::stepButton2() const
00521 {
00522 return incSteps(Button2);
00523 }
00524
00526 void QwtCounter::setStepButton3(int nSteps)
00527 {
00528 setIncSteps(Button3, nSteps);
00529 }
00530
00532 int QwtCounter::stepButton3() const
00533 {
00534 return incSteps(Button3);
00535 }
00536
00537 double QwtCounter::value() const
00538 {
00539 return QwtDoubleRange::value();
00540 }
00541