~ubuntu-branches/ubuntu/oneiric/qwt/oneiric-proposed

« back to all changes in this revision

Viewing changes to qwt/src/qwt_counter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2009-07-01 16:08:21 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090701160821-gog44m4w7x2f4u6o
Tags: 5.2.0-1
* New upstream release.
* Add branch pull patch from svn r544.
* Bump Standards-Version to 3.8.2. No changes needed.
* Update installed manpages.
* Use qwt as base name for directory (drop version).
* Add missing warnings patch.
* Rewrite debian/rules: use dh.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 
2
 * Qwt Widget Library
 
3
 * Copyright (C) 1997   Josef Wilgen
 
4
 * Copyright (C) 2002   Uwe Rathmann
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the Qwt License, Version 1.0
 
8
 *****************************************************************************/
 
9
 
 
10
// vim: expandtab
 
11
 
 
12
#include <qlayout.h>
 
13
#include <qlineedit.h>
 
14
#include <qvalidator.h>
 
15
#include <qevent.h>
 
16
#include <qstyle.h>
 
17
#include "qwt_math.h"
 
18
#include "qwt_counter.h"
 
19
#include "qwt_arrow_button.h"
 
20
 
 
21
class QwtCounter::PrivateData
 
22
{
 
23
public:
 
24
    PrivateData():
 
25
        editable(true)
 
26
    {
 
27
        increment[Button1] = 1;
 
28
        increment[Button2] = 10;
 
29
        increment[Button3] = 100;
 
30
    }
 
31
 
 
32
    QwtArrowButton *buttonDown[ButtonCnt];
 
33
    QwtArrowButton *buttonUp[ButtonCnt];
 
34
    QLineEdit *valueEdit;
 
35
 
 
36
    int increment[ButtonCnt];
 
37
    int nButtons;
 
38
 
 
39
    bool editable;
 
40
};
 
41
 
 
42
/*!
 
43
  The default number of buttons is set to 2. The default increments are:
 
44
  \li Button 1: 1 step
 
45
  \li Button 2: 10 steps
 
46
  \li Button 3: 100 steps
 
47
 
 
48
  \param parent
 
49
 */
 
50
QwtCounter::QwtCounter(QWidget *parent):
 
51
    QWidget(parent) 
 
52
{
 
53
    initCounter();
 
54
}
 
55
 
 
56
#if QT_VERSION < 0x040000
 
57
/*!
 
58
  The default number of buttons is set to 2. The default increments are:
 
59
  \li Button 1: 1 step
 
60
  \li Button 2: 10 steps
 
61
  \li Button 3: 100 steps
 
62
 
 
63
  \param parent
 
64
 */
 
65
QwtCounter::QwtCounter(QWidget *parent, const char *name):
 
66
    QWidget(parent, name) 
 
67
{
 
68
    initCounter();
 
69
}
 
70
#endif
 
71
 
 
72
void QwtCounter::initCounter()
 
73
{
 
74
    d_data = new PrivateData;
 
75
 
 
76
#if QT_VERSION >= 0x040000
 
77
    using namespace Qt;
 
78
#endif
 
79
 
 
80
    QHBoxLayout *layout = new QHBoxLayout(this);
 
81
    layout->setSpacing(0);
 
82
    layout->setMargin(0);
 
83
 
 
84
    int i;
 
85
    for(i = ButtonCnt - 1; i >= 0; i--)
 
86
    {
 
87
        QwtArrowButton *btn =
 
88
            new QwtArrowButton(i+1, Qt::DownArrow,this);
 
89
        btn->setFocusPolicy(NoFocus);
 
90
        btn->installEventFilter(this);
 
91
        layout->addWidget(btn);
 
92
 
 
93
        connect(btn, SIGNAL(released()), SLOT(btnReleased()));
 
94
        connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
 
95
 
 
96
        d_data->buttonDown[i] = btn;
 
97
    }
 
98
 
 
99
    d_data->valueEdit = new QLineEdit(this);
 
100
    d_data->valueEdit->setReadOnly(false);
 
101
    d_data->valueEdit->setValidator(new QDoubleValidator(d_data->valueEdit));
 
102
    layout->addWidget(d_data->valueEdit);
 
103
 
 
104
#if QT_VERSION >= 0x040000
 
105
    connect( d_data->valueEdit, SIGNAL(editingFinished()), 
 
106
        SLOT(textChanged()) );
 
107
#else
 
108
    connect( d_data->valueEdit, SIGNAL(returnPressed()), SLOT(textChanged()) );
 
109
    connect( d_data->valueEdit, SIGNAL(lostFocus()), SLOT(textChanged()) );
 
110
#endif
 
111
 
 
112
    layout->setStretchFactor(d_data->valueEdit, 10);
 
113
 
 
114
    for(i = 0; i < ButtonCnt; i++)
 
115
    {
 
116
#if QT_VERSION >= 0x040000
 
117
        using namespace Qt;
 
118
#endif
 
119
        QwtArrowButton *btn =
 
120
            new QwtArrowButton(i+1, Qt::UpArrow, this);
 
121
        btn->setFocusPolicy(NoFocus);
 
122
        btn->installEventFilter(this);
 
123
        layout->addWidget(btn);
 
124
 
 
125
        connect(btn, SIGNAL(released()), SLOT(btnReleased()));
 
126
        connect(btn, SIGNAL(clicked()), SLOT(btnClicked()));
 
127
    
 
128
        d_data->buttonUp[i] = btn;
 
129
    }
 
130
 
 
131
    setNumButtons(2);
 
132
    setRange(0.0,1.0,0.001);
 
133
    setValue(0.0);
 
134
 
 
135
    setSizePolicy(
 
136
        QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
 
137
 
 
138
    setFocusProxy(d_data->valueEdit);
 
139
    setFocusPolicy(StrongFocus);
 
140
}
 
141
 
 
142
//! Destructor
 
143
QwtCounter::~QwtCounter()
 
144
{
 
145
    delete d_data;
 
146
}
 
147
 
 
148
/*!
 
149
  Sets the minimum width for the buttons
 
150
*/
 
151
void QwtCounter::polish()
 
152
{
 
153
    const int w = d_data->valueEdit->fontMetrics().width("W") + 8;
 
154
 
 
155
    for ( int i = 0; i < ButtonCnt; i++ )
 
156
    {
 
157
        d_data->buttonDown[i]->setMinimumWidth(w);
 
158
        d_data->buttonUp[i]->setMinimumWidth(w);
 
159
    }
 
160
 
 
161
#if QT_VERSION < 0x040000
 
162
    QWidget::polish();
 
163
#endif
 
164
}
 
165
 
 
166
//! Set from lineedit
 
167
void QwtCounter::textChanged() 
 
168
{
 
169
    if ( !d_data->editable ) 
 
170
        return;
 
171
 
 
172
    bool converted = false;
 
173
 
 
174
    const double value = d_data->valueEdit->text().toDouble(&converted);
 
175
    if ( converted ) 
 
176
       setValue( value );
 
177
}
 
178
 
 
179
/**
 
180
  \brief Allow/disallow the user to manually edit the value
 
181
 
 
182
  \param editable true enables editing
 
183
  \sa editable()
 
184
*/
 
185
void QwtCounter::setEditable(bool editable)
 
186
{
 
187
#if QT_VERSION >= 0x040000
 
188
    using namespace Qt;
 
189
#endif
 
190
    if ( editable == d_data->editable ) 
 
191
        return;
 
192
 
 
193
    d_data->editable = editable;
 
194
    d_data->valueEdit->setReadOnly(!editable);
 
195
}
 
196
 
 
197
//! returns whether the line edit is edatble. (default is yes)
 
198
bool QwtCounter::editable() const 
 
199
{   
 
200
    return d_data->editable;
 
201
}
 
202
 
 
203
/*!
 
204
   Handle PolishRequest events 
 
205
*/
 
206
bool QwtCounter::event ( QEvent * e ) 
 
207
{
 
208
#if QT_VERSION >= 0x040000
 
209
    if ( e->type() == QEvent::PolishRequest )
 
210
        polish();
 
211
#endif
 
212
    return QWidget::event(e);
 
213
}
 
214
 
 
215
/*!
 
216
  Handle key events
 
217
 
 
218
  - Ctrl + Qt::Key_Home
 
219
    Step to minValue()
 
220
  - Ctrl + Qt::Key_End
 
221
    Step to maxValue()
 
222
  - Qt::Key_Up
 
223
    Increment by incSteps(QwtCounter::Button1)
 
224
  - Qt::Key_Down
 
225
    Decrement by incSteps(QwtCounter::Button1)
 
226
  - Qt::Key_PageUp
 
227
    Increment by incSteps(QwtCounter::Button2)
 
228
  - Qt::Key_PageDown
 
229
    Decrement by incSteps(QwtCounter::Button2)
 
230
  - Shift + Qt::Key_PageUp
 
231
    Increment by incSteps(QwtCounter::Button3)
 
232
  - Shift + Qt::Key_PageDown
 
233
    Decrement by incSteps(QwtCounter::Button3)
 
234
*/
 
235
void QwtCounter::keyPressEvent (QKeyEvent *e)
 
236
{
 
237
    bool accepted = true;
 
238
 
 
239
    switch ( e->key() )
 
240
    {
 
241
        case Qt::Key_Home:
 
242
#if QT_VERSION >= 0x040000
 
243
            if ( e->modifiers() & Qt::ControlModifier )
 
244
#else
 
245
            if ( e->state() & Qt::ControlButton )
 
246
#endif
 
247
                setValue(minValue());
 
248
            else
 
249
                accepted = false;
 
250
            break;
 
251
        case Qt::Key_End:
 
252
#if QT_VERSION >= 0x040000
 
253
            if ( e->modifiers() & Qt::ControlModifier )
 
254
#else
 
255
            if ( e->state() & Qt::ControlButton )
 
256
#endif
 
257
                setValue(maxValue());
 
258
            else
 
259
                accepted = false;
 
260
            break;
 
261
        case Qt::Key_Up:
 
262
            incValue(d_data->increment[0]);
 
263
            break;
 
264
        case Qt::Key_Down:
 
265
            incValue(-d_data->increment[0]);
 
266
            break;
 
267
        case Qt::Key_PageUp:
 
268
        case Qt::Key_PageDown:
 
269
        {
 
270
            int increment = d_data->increment[0];
 
271
            if ( d_data->nButtons >= 2 )
 
272
                increment = d_data->increment[1];
 
273
            if ( d_data->nButtons >= 3 )
 
274
            {
 
275
#if QT_VERSION >= 0x040000
 
276
                if ( e->modifiers() & Qt::ShiftModifier )
 
277
#else
 
278
                if ( e->state() & Qt::ShiftButton )
 
279
#endif
 
280
                    increment = d_data->increment[2];
 
281
            }
 
282
            if ( e->key() == Qt::Key_PageDown )
 
283
                increment = -increment;
 
284
            incValue(increment);
 
285
            break;
 
286
        }
 
287
        default:
 
288
            accepted = false;
 
289
    }
 
290
 
 
291
    if ( accepted )
 
292
    {
 
293
        e->accept();
 
294
        return;
 
295
    }
 
296
 
 
297
    QWidget::keyPressEvent (e);
 
298
}
 
299
 
 
300
/*!
 
301
  Handle wheel events
 
302
  \param e Wheel event
 
303
*/
 
304
void QwtCounter::wheelEvent(QWheelEvent *e)
 
305
{
 
306
    e->accept();
 
307
 
 
308
    if ( d_data->nButtons <= 0 )
 
309
        return;
 
310
 
 
311
    int increment = d_data->increment[0];
 
312
    if ( d_data->nButtons >= 2 )
 
313
    {
 
314
#if QT_VERSION >= 0x040000
 
315
        if ( e->modifiers() & Qt::ControlModifier )
 
316
#else
 
317
        if ( e->state() & Qt::ControlButton )
 
318
#endif
 
319
            increment = d_data->increment[1];
 
320
    }
 
321
    if ( d_data->nButtons >= 3 )
 
322
    {
 
323
#if QT_VERSION >= 0x040000
 
324
        if ( e->modifiers() & Qt::ShiftModifier )
 
325
#else
 
326
        if ( e->state() & Qt::ShiftButton )
 
327
#endif
 
328
            increment = d_data->increment[2];
 
329
    }
 
330
        
 
331
    for ( int i = 0; i < d_data->nButtons; i++ )
 
332
    {
 
333
        if ( d_data->buttonDown[i]->geometry().contains(e->pos()) ||
 
334
            d_data->buttonUp[i]->geometry().contains(e->pos()) )
 
335
        {
 
336
            increment = d_data->increment[i];
 
337
        }
 
338
    }
 
339
 
 
340
    const int wheel_delta = 120;
 
341
 
 
342
    int delta = e->delta();
 
343
    if ( delta >= 2 * wheel_delta )
 
344
        delta /= 2; // Never saw an abs(delta) < 240
 
345
 
 
346
    incValue(delta / wheel_delta * increment);
 
347
}
 
348
 
 
349
/*!
 
350
  Specify the number of steps by which the value
 
351
  is incremented or decremented when a specified button
 
352
  is pushed.
 
353
 
 
354
  \param btn One of \c QwtCounter::Button1, \c QwtCounter::Button2,
 
355
             \c QwtCounter::Button3
 
356
  \param nSteps Number of steps
 
357
*/
 
358
void QwtCounter::setIncSteps(QwtCounter::Button btn, int nSteps)
 
359
{
 
360
    if (( btn >= 0) && (btn < ButtonCnt))
 
361
       d_data->increment[btn] = nSteps;
 
362
}
 
363
 
 
364
/*!
 
365
  \return the number of steps by which a specified button increments the value
 
366
  or 0 if the button is invalid.
 
367
  \param btn One of \c QwtCounter::Button1, \c QwtCounter::Button2,
 
368
  \c QwtCounter::Button3
 
369
*/
 
370
int QwtCounter::incSteps(QwtCounter::Button btn) const
 
371
{
 
372
    if (( btn >= 0) && (btn < ButtonCnt))
 
373
       return d_data->increment[btn];
 
374
 
 
375
    return 0;
 
376
}
 
377
 
 
378
/*!
 
379
  \brief Set a new value
 
380
  \param v new value
 
381
  Calls QwtDoubleRange::setValue and does all visual updates.
 
382
  \sa QwtDoubleRange::setValue()
 
383
*/
 
384
 
 
385
void QwtCounter::setValue(double v)
 
386
{
 
387
    QwtDoubleRange::setValue(v);
 
388
 
 
389
    showNum(value());
 
390
    updateButtons();
 
391
}
 
392
 
 
393
/*!
 
394
  \brief Notify a change of value
 
395
*/
 
396
void QwtCounter::valueChange()
 
397
{
 
398
    if ( isValid() )
 
399
        showNum(value());
 
400
    else
 
401
        d_data->valueEdit->setText(QString::null);
 
402
 
 
403
    updateButtons();
 
404
 
 
405
    if ( isValid() )
 
406
        emit valueChanged(value());
 
407
}
 
408
 
 
409
/*!
 
410
  \brief Update buttons according to the current value
 
411
 
 
412
  When the QwtCounter under- or over-flows, the focus is set to the smallest
 
413
  up- or down-button and counting is disabled.
 
414
 
 
415
  Counting is re-enabled on a button release event (mouse or space bar).
 
416
*/
 
417
void QwtCounter::updateButtons()
 
418
{
 
419
    if ( isValid() )
 
420
    {
 
421
        // 1. save enabled state of the smallest down- and up-button
 
422
        // 2. change enabled state on under- or over-flow
 
423
 
 
424
        for ( int i = 0; i < ButtonCnt; i++ )
 
425
        {
 
426
            d_data->buttonDown[i]->setEnabled(value() > minValue());
 
427
            d_data->buttonUp[i]->setEnabled(value() < maxValue());
 
428
        }
 
429
    }
 
430
    else
 
431
    {
 
432
        for ( int i = 0; i < ButtonCnt; i++ )
 
433
        {
 
434
            d_data->buttonDown[i]->setEnabled(false);
 
435
            d_data->buttonUp[i]->setEnabled(false);
 
436
        }
 
437
    }
 
438
}
 
439
 
 
440
/*!
 
441
  \brief Specify the number of buttons on each side of the label
 
442
  \param n Number of buttons
 
443
*/
 
444
void QwtCounter::setNumButtons(int n)
 
445
{
 
446
    if ( n<0 || n>ButtonCnt )
 
447
        return;
 
448
 
 
449
    for ( int i = 0; i < ButtonCnt; i++ )
 
450
    {
 
451
        if ( i < n )
 
452
        {
 
453
            d_data->buttonDown[i]->show();
 
454
            d_data->buttonUp[i]->show();
 
455
        }
 
456
        else
 
457
        {
 
458
            d_data->buttonDown[i]->hide();
 
459
            d_data->buttonUp[i]->hide();
 
460
        }
 
461
    }
 
462
 
 
463
    d_data->nButtons = n;
 
464
}
 
465
 
 
466
/*!
 
467
    \return The number of buttons on each side of the widget.
 
468
*/
 
469
int QwtCounter::numButtons() const 
 
470
 
471
    return d_data->nButtons; 
 
472
}
 
473
 
 
474
/*!  
 
475
  Display number string
 
476
 
 
477
  \param number Number
 
478
*/
 
479
void QwtCounter::showNum(double number)
 
480
{
 
481
    QString v;
 
482
    v.setNum(number);
 
483
 
 
484
    const int cursorPos = d_data->valueEdit->cursorPosition();
 
485
    d_data->valueEdit->setText(v);
 
486
    d_data->valueEdit->setCursorPosition(cursorPos);
 
487
}
 
488
 
 
489
//!  Button clicked
 
490
void QwtCounter::btnClicked()
 
491
{
 
492
    for ( int i = 0; i < ButtonCnt; i++ )
 
493
    {
 
494
        if ( d_data->buttonUp[i] == sender() )
 
495
            incValue(d_data->increment[i]);
 
496
 
 
497
        if ( d_data->buttonDown[i] == sender() )
 
498
            incValue(-d_data->increment[i]);
 
499
    }
 
500
}
 
501
 
 
502
//!  Button released
 
503
void QwtCounter::btnReleased()
 
504
{
 
505
    emit buttonReleased(value());
 
506
}
 
507
 
 
508
/*!
 
509
  \brief Notify change of range
 
510
 
 
511
  This function updates the enabled property of
 
512
  all buttons contained in QwtCounter.
 
513
*/
 
514
void QwtCounter::rangeChange()
 
515
{
 
516
    updateButtons();
 
517
}
 
518
 
 
519
//! A size hint
 
520
QSize QwtCounter::sizeHint() const
 
521
{
 
522
    QString tmp;
 
523
 
 
524
    int w = tmp.setNum(minValue()).length();
 
525
    int w1 = tmp.setNum(maxValue()).length();
 
526
    if ( w1 > w )
 
527
        w = w1;
 
528
    w1 = tmp.setNum(minValue() + step()).length();
 
529
    if ( w1 > w )
 
530
        w = w1;
 
531
    w1 = tmp.setNum(maxValue() - step()).length();
 
532
    if ( w1 > w )
 
533
        w = w1;
 
534
 
 
535
    tmp.fill('9', w);
 
536
 
 
537
    QFontMetrics fm(d_data->valueEdit->font());
 
538
    w = fm.width(tmp) + 2;
 
539
#if QT_VERSION >= 0x040000
 
540
    if ( d_data->valueEdit->hasFrame() )
 
541
        w += 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
 
542
#else
 
543
    w += 2 * d_data->valueEdit->frameWidth(); 
 
544
#endif
 
545
 
 
546
    // Now we replace default sizeHint contribution of d_data->valueEdit by
 
547
    // what we really need.
 
548
 
 
549
    w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width();
 
550
 
 
551
    const int h = qwtMin(QWidget::sizeHint().height(), 
 
552
        d_data->valueEdit->minimumSizeHint().height());
 
553
    return QSize(w, h);
 
554
}
 
555
 
 
556
//! returns the step size
 
557
double QwtCounter::step() const
 
558
{
 
559
    return QwtDoubleRange::step();
 
560
}
 
561
    
 
562
/*! 
 
563
   Set the step size
 
564
   \param stepSize Step size
 
565
   \sa QwtDoubleRange::setStep()
 
566
*/
 
567
void QwtCounter::setStep(double stepSize)
 
568
{
 
569
    QwtDoubleRange::setStep(stepSize);
 
570
}
 
571
 
 
572
//! returns the minimum value of the range
 
573
double QwtCounter::minVal() const
 
574
{
 
575
    return minValue();
 
576
}
 
577
 
 
578
/*! 
 
579
  Set the minimum value of the range
 
580
 
 
581
  \param value Minimum value
 
582
  \sa setMaxValue(), minVal()
 
583
*/
 
584
void QwtCounter::setMinValue(double value)
 
585
{
 
586
    setRange(value, maxValue(), step());
 
587
}
 
588
 
 
589
//! returns the maximum value of the range
 
590
double QwtCounter::maxVal() const
 
591
{
 
592
    return QwtDoubleRange::maxValue();
 
593
}
 
594
 
 
595
/*! 
 
596
  Set the maximum value of the range
 
597
 
 
598
  \param value Maximum value
 
599
  \sa setMinValue(), maxVal()
 
600
*/
 
601
void QwtCounter::setMaxValue(double value)
 
602
{
 
603
    setRange(minValue(), value, step());
 
604
}
 
605
 
 
606
/*! 
 
607
  Set the number of increment steps for button 1
 
608
  \param nSteps Number of steps
 
609
*/
 
610
void QwtCounter::setStepButton1(int nSteps)
 
611
{
 
612
    setIncSteps(Button1, nSteps);
 
613
}
 
614
 
 
615
//! returns the number of increment steps for button 1
 
616
int QwtCounter::stepButton1() const
 
617
{
 
618
    return incSteps(Button1);
 
619
}
 
620
 
 
621
/*! 
 
622
  Set the number of increment steps for button 2
 
623
  \param nSteps Number of steps
 
624
*/
 
625
void QwtCounter::setStepButton2(int nSteps)
 
626
{
 
627
    setIncSteps(Button2, nSteps);
 
628
}
 
629
 
 
630
//! returns the number of increment steps for button 2
 
631
int QwtCounter::stepButton2() const
 
632
{
 
633
    return incSteps(Button2);
 
634
}
 
635
 
 
636
/*! 
 
637
  Set the number of increment steps for button 3
 
638
  \param nSteps Number of steps
 
639
*/
 
640
void QwtCounter::setStepButton3(int nSteps)
 
641
{
 
642
    setIncSteps(Button3, nSteps);
 
643
}
 
644
 
 
645
//! returns the number of increment steps for button 3
 
646
int QwtCounter::stepButton3() const
 
647
{
 
648
    return incSteps(Button3);
 
649
}
 
650
 
 
651
//! \return Current value
 
652
double QwtCounter::value() const
 
653
{
 
654
    return QwtDoubleRange::value();
 
655
}
 
656