~l3on/ubuntu/oneiric/qwt/fix-921430

« back to all changes in this revision

Viewing changes to qwt-5.0.2/src/qwt_picker.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2007-10-05 15:20:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20071005152041-qmybqh4fj9jejyo2
Tags: 5.0.2-2
* Handle nostrip build option. (Closes: #437877)
* Build libqwt5-doc package in binary-indep target. (Closes: #443110)

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
#include <qapplication.h>
 
11
#include <qevent.h>
 
12
#include <qpainter.h>
 
13
#include <qframe.h>
 
14
#include <qcursor.h>
 
15
#include <qbitmap.h>
 
16
#include "qwt_math.h"
 
17
#include "qwt_painter.h"
 
18
#include "qwt_picker_machine.h"
 
19
#include "qwt_picker.h"
 
20
#if QT_VERSION < 0x040000
 
21
#include <qguardedptr.h>
 
22
#else
 
23
#include <qpointer.h>
 
24
#endif
 
25
 
 
26
#if QT_VERSION >= 0x040300
 
27
/*
 
28
  With Qt >= 4.3 drawing of the tracker can be implemented in an
 
29
  easier, using the textRect as mask. Because calculating
 
30
  a QRegion from a QBitmask is expensive operation ( especially for
 
31
  longer texts !) this implementation is much faster too.
 
32
  Also the result looks much better.
 
33
*/
 
34
#define USE_TRACKER_RECT_MASK
 
35
#endif
 
36
 
 
37
#ifndef USE_TRACKER_RECT_MASK
 
38
#define USE_TRACKER_BACKGROUND
 
39
#endif
 
40
 
 
41
class QwtPicker::PrivateData
 
42
{
 
43
public:
 
44
    class PickerWidget: public QWidget
 
45
    {
 
46
    public:
 
47
        enum Type
 
48
        {
 
49
            RubberBand,
 
50
            Text
 
51
        };
 
52
        PickerWidget(QwtPicker *, QWidget *, Type);
 
53
        virtual void updateMask();
 
54
 
 
55
#ifdef USE_TRACKER_BACKGROUND
 
56
        /*
 
57
           Internal flag, that is needed for tracker texts with a
 
58
           background. This flag has been introduced in Qwt 5.0.2 to avoid
 
59
           incompatible API changes. In Qwt 5.1 will be a cleaner solution.
 
60
         */
 
61
        mutable bool d_hasTrackerBackground;
 
62
#endif
 
63
    protected:
 
64
        virtual void paintEvent(QPaintEvent *);
 
65
 
 
66
        QwtPicker *d_picker;
 
67
        Type d_type;
 
68
    };
 
69
 
 
70
    bool enabled;
 
71
 
 
72
    QwtPickerMachine *stateMachine;
 
73
 
 
74
    int selectionFlags;
 
75
    QwtPicker::ResizeMode resizeMode;
 
76
 
 
77
    QwtPicker::RubberBand rubberBand;
 
78
    QPen rubberBandPen;
 
79
 
 
80
    QwtPicker::DisplayMode trackerMode;
 
81
    QPen trackerPen;
 
82
    QFont trackerFont;
 
83
 
 
84
    QwtPolygon selection;
 
85
    bool isActive;
 
86
    QPoint labelPosition;
 
87
 
 
88
    bool mouseTracking; // used to save previous value
 
89
 
 
90
    /*
 
91
      On X11 the widget below the picker widgets gets paint events
 
92
      with a region that is the bounding rect of the mask, if it is complex.
 
93
      In case of (f.e) a CrossRubberBand and a text this creates complete
 
94
      repaints of the widget. So we better use two different widgets.
 
95
     */
 
96
     
 
97
#if QT_VERSION < 0x040000
 
98
    QGuardedPtr<PickerWidget> rubberBandWidget;
 
99
    QGuardedPtr<PickerWidget> trackerWidget;
 
100
#else
 
101
    QPointer<PickerWidget> rubberBandWidget;
 
102
    QPointer<PickerWidget> trackerWidget;
 
103
#endif
 
104
};
 
105
 
 
106
QwtPicker::PrivateData::PickerWidget::PickerWidget(
 
107
        QwtPicker *picker, QWidget *parent, Type type):
 
108
    QWidget(parent),
 
109
    d_picker(picker),
 
110
    d_type(type)
 
111
{
 
112
#if QT_VERSION >= 0x040000
 
113
    setAttribute(Qt::WA_TransparentForMouseEvents);
 
114
    setAttribute(Qt::WA_NoSystemBackground);
 
115
    setFocusPolicy(Qt::NoFocus);
 
116
#else
 
117
    setBackgroundMode(Qt::NoBackground);
 
118
    setFocusPolicy(QWidget::NoFocus);
 
119
    setMouseTracking(true);
 
120
#endif
 
121
    hide();
 
122
}
 
123
 
 
124
void QwtPicker::PrivateData::PickerWidget::updateMask()
 
125
{
 
126
    QRegion mask;
 
127
 
 
128
    if ( d_type == RubberBand )
 
129
    {
 
130
        QBitmap bm(width(), height());
 
131
        bm.fill(Qt::color0);
 
132
 
 
133
        QPainter painter(&bm);
 
134
        QPen pen = d_picker->rubberBandPen();
 
135
        pen.setColor(Qt::color1);
 
136
        painter.setPen(pen);
 
137
 
 
138
        d_picker->drawRubberBand(&painter);
 
139
 
 
140
        mask = QRegion(bm);
 
141
    }
 
142
    if ( d_type == Text )
 
143
    {
 
144
#ifdef USE_TRACKER_RECT_MASK
 
145
        QBitmap bm(width(), height());
 
146
        QPainter painter(&bm);
 
147
        painter.setFont(font());
 
148
        mask = d_picker->trackerRect(&painter);
 
149
#else
 
150
        QBitmap bm(width(), height());
 
151
        bm.fill(Qt::color0);
 
152
 
 
153
        QPainter painter(&bm);
 
154
        painter.setFont(font());
 
155
 
 
156
        QPen pen = d_picker->trackerPen();
 
157
        pen.setColor(Qt::color1);
 
158
        painter.setPen(pen);
 
159
 
 
160
        d_picker->drawTracker(&painter);
 
161
 
 
162
        mask = QRegion(bm);
 
163
#endif
 
164
    }
 
165
 
 
166
#if QT_VERSION < 0x040000
 
167
    QWidget *w = parentWidget();
 
168
    const bool doUpdate = w->isUpdatesEnabled();
 
169
    const Qt::BackgroundMode bgMode = w->backgroundMode();
 
170
    w->setUpdatesEnabled(false);
 
171
    if ( bgMode != Qt::NoBackground )
 
172
        w->setBackgroundMode(Qt::NoBackground);
 
173
#endif
 
174
 
 
175
    setMask(mask);
 
176
 
 
177
#if QT_VERSION < 0x040000
 
178
    if ( bgMode != Qt::NoBackground )
 
179
        w->setBackgroundMode(bgMode);
 
180
 
 
181
    w->setUpdatesEnabled(doUpdate);
 
182
#endif
 
183
 
 
184
    setShown(!mask.isEmpty());
 
185
}
 
186
 
 
187
void QwtPicker::PrivateData::PickerWidget::paintEvent(QPaintEvent *e)
 
188
{
 
189
    QPainter painter(this);
 
190
 
 
191
    if ( d_type == RubberBand )
 
192
    {
 
193
        painter.setClipRegion(e->region());
 
194
        painter.setPen(d_picker->rubberBandPen());
 
195
        d_picker->drawRubberBand(&painter);
 
196
    }
 
197
 
 
198
    if ( d_type == Text )
 
199
    {
 
200
        painter.setClipRegion(e->region());
 
201
 
 
202
        bool doDrawTracker = true;
 
203
#ifndef USE_TRACKER_RECT_MASK
 
204
#ifdef USE_TRACKER_BACKGROUND
 
205
        doDrawTracker = d_hasTrackerBackground;
 
206
#else
 
207
        doDrawTracker = false;
 
208
#endif
 
209
#endif
 
210
#if QT_VERSION < 0x040000
 
211
    if ( !doDrawTracker && QPainter::redirect(this) )
 
212
    {
 
213
        // setMask + painter redirection doesn't work
 
214
        doDrawTracker = true;
 
215
    }
 
216
#endif
 
217
        if ( doDrawTracker )
 
218
        {
 
219
            painter.setPen(d_picker->trackerPen());
 
220
            d_picker->drawTracker(&painter);
 
221
        }
 
222
        else
 
223
            painter.fillRect(e->rect(), QBrush(d_picker->trackerPen().color()));
 
224
    }
 
225
}
 
226
 
 
227
/*!
 
228
  Constructor
 
229
 
 
230
  Creates an picker that is enabled, but where selection flag
 
231
  is set to NoSelection, rubberband and tracker are disabled.
 
232
  
 
233
  \param parent Parent widget, that will be observed
 
234
 */
 
235
 
 
236
QwtPicker::QwtPicker(QWidget *parent):
 
237
    QObject(parent)
 
238
{
 
239
    init(parent, NoSelection, NoRubberBand, AlwaysOff);
 
240
}
 
241
 
 
242
/*!
 
243
  Constructor
 
244
 
 
245
  \param selectionFlags Or'd value of SelectionType, RectSelectionType and 
 
246
                        SelectionMode
 
247
  \param rubberBand Rubberband style
 
248
  \param trackerMode Tracker mode
 
249
  \param parent Parent widget, that will be observed
 
250
 */
 
251
QwtPicker::QwtPicker(int selectionFlags, RubberBand rubberBand,
 
252
        DisplayMode trackerMode, QWidget *parent):
 
253
    QObject(parent)
 
254
{
 
255
    init(parent, selectionFlags, rubberBand, trackerMode);
 
256
}
 
257
 
 
258
//! Destructor
 
259
QwtPicker::~QwtPicker()
 
260
{
 
261
    setMouseTracking(false);
 
262
    delete d_data->stateMachine;
 
263
    delete d_data->rubberBandWidget;
 
264
    delete d_data->trackerWidget;
 
265
    delete d_data;
 
266
}
 
267
 
 
268
//! Init the picker, used by the constructors
 
269
void QwtPicker::init(QWidget *parent, int selectionFlags, 
 
270
    RubberBand rubberBand, DisplayMode trackerMode)
 
271
{
 
272
    d_data = new PrivateData;
 
273
 
 
274
    d_data->rubberBandWidget = NULL;
 
275
    d_data->trackerWidget = NULL;
 
276
 
 
277
    d_data->rubberBand = rubberBand;
 
278
    d_data->enabled = false;
 
279
    d_data->resizeMode = Stretch;
 
280
    d_data->trackerMode = AlwaysOff;
 
281
    d_data->isActive = false;
 
282
    d_data->labelPosition = QPoint(-1, -1);
 
283
    d_data->mouseTracking = false;
 
284
 
 
285
    d_data->stateMachine = NULL;
 
286
    setSelectionFlags(selectionFlags);
 
287
 
 
288
    if ( parent )
 
289
    {
 
290
#if QT_VERSION >= 0x040000
 
291
        if ( parent->focusPolicy() == Qt::NoFocus )
 
292
            parent->setFocusPolicy(Qt::WheelFocus);
 
293
#else
 
294
        if ( parent->focusPolicy() == QWidget::NoFocus )
 
295
            parent->setFocusPolicy(QWidget::WheelFocus);
 
296
#endif
 
297
 
 
298
        d_data->trackerFont = parent->font();
 
299
        d_data->mouseTracking = parent->hasMouseTracking();
 
300
        setEnabled(true);
 
301
    }
 
302
    setTrackerMode(trackerMode);
 
303
}
 
304
 
 
305
/*!
 
306
   Set a state machine and delete the previous one
 
307
*/
 
308
void QwtPicker::setStateMachine(QwtPickerMachine *stateMachine)
 
309
{
 
310
    if ( d_data->stateMachine != stateMachine )
 
311
    {
 
312
        if ( isActive() )
 
313
            end(false);
 
314
 
 
315
        delete d_data->stateMachine;
 
316
        d_data->stateMachine = stateMachine;
 
317
 
 
318
        if ( d_data->stateMachine )
 
319
            d_data->stateMachine->reset();
 
320
    }
 
321
}
 
322
 
 
323
/*!
 
324
   Create a state machine depending on the selection flags.
 
325
 
 
326
   - PointSelection | ClickSelection\n
 
327
     QwtPickerClickPointMachine()
 
328
   - PointSelection | DragSelection\n
 
329
     QwtPickerDragPointMachine()
 
330
   - RectSelection | ClickSelection\n
 
331
     QwtPickerClickRectMachine()
 
332
   - RectSelection | DragSelection\n
 
333
     QwtPickerDragRectMachine()
 
334
   - PolygonSelection\n
 
335
     QwtPickerPolygonMachine()
 
336
 
 
337
   \sa setSelectionFlags()
 
338
*/
 
339
QwtPickerMachine *QwtPicker::stateMachine(int flags) const
 
340
{
 
341
    if ( flags & PointSelection )
 
342
    {
 
343
        if ( flags & ClickSelection )
 
344
            return new QwtPickerClickPointMachine;
 
345
        else
 
346
            return new QwtPickerDragPointMachine;
 
347
    }
 
348
    if ( flags & RectSelection )
 
349
    {
 
350
        if ( flags & ClickSelection )
 
351
            return new QwtPickerClickRectMachine;
 
352
        else
 
353
            return new QwtPickerDragRectMachine;
 
354
    }
 
355
    if ( flags & PolygonSelection )
 
356
    {
 
357
        return new QwtPickerPolygonMachine();
 
358
    }
 
359
    return NULL;
 
360
}
 
361
 
 
362
//! Return the parent widget, where the selection happens
 
363
QWidget *QwtPicker::parentWidget()
 
364
{
 
365
    QObject *obj = parent();
 
366
    if ( obj && obj->isWidgetType() )
 
367
        return (QWidget *)obj;
 
368
 
 
369
    return NULL;
 
370
}
 
371
 
 
372
//! Return the parent widget, where the selection happens
 
373
const QWidget *QwtPicker::parentWidget() const
 
374
{
 
375
    QObject *obj = parent();
 
376
    if ( obj && obj->isWidgetType() )
 
377
        return (QWidget *)obj;
 
378
 
 
379
    return NULL;
 
380
}
 
381
 
 
382
/*!
 
383
  Set the selection flags
 
384
 
 
385
  \param flags Or'd value of SelectionType, RectSelectionType and 
 
386
               SelectionMode. The default value is NoSelection.
 
387
 
 
388
  \sa selectionFlags(), SelectionType, RectSelectionType, SelectionMode
 
389
*/
 
390
 
 
391
void QwtPicker::setSelectionFlags(int flags)
 
392
{
 
393
    d_data->selectionFlags = flags;
 
394
    setStateMachine(stateMachine(flags));
 
395
}
 
396
 
 
397
/*!
 
398
  \return Selection flags, an Or'd value of SelectionType, RectSelectionType and
 
399
          SelectionMode.
 
400
  \sa setSelectionFlags(), SelectionType, RectSelectionType, SelectionMode
 
401
*/
 
402
int QwtPicker::selectionFlags() const
 
403
{
 
404
    return d_data->selectionFlags;
 
405
}
 
406
 
 
407
/*!
 
408
  Set the rubberband style 
 
409
 
 
410
  \param rubberBand Rubberband style
 
411
         The default value is NoRubberBand.
 
412
 
 
413
  \sa rubberBand(), RubberBand, setRubberBandPen()
 
414
*/
 
415
void QwtPicker::setRubberBand(RubberBand rubberBand)
 
416
{
 
417
    d_data->rubberBand = rubberBand;
 
418
}
 
419
 
 
420
/*!
 
421
  \return Rubberband style
 
422
  \sa setRubberBand(), RubberBand, rubberBandPen()
 
423
*/
 
424
QwtPicker::RubberBand QwtPicker::rubberBand() const
 
425
{
 
426
    return d_data->rubberBand;
 
427
}
 
428
 
 
429
/*!
 
430
  \brief Set the display mode of the tracker.
 
431
 
 
432
  A tracker displays information about current position of
 
433
  the cursor as a string. The display mode controls
 
434
  if the tracker has to be displayed whenever the observed
 
435
  widget has focus and cursor (AlwaysOn), never (AlwaysOff), or
 
436
  only when the selection is active (ActiveOnly).
 
437
  
 
438
  \param mode Tracker display mode
 
439
 
 
440
  \warning In case of AlwaysOn, mouseTracking will be enabled
 
441
           for the observed widget.
 
442
  \sa trackerMode(), DisplayMode
 
443
*/
 
444
 
 
445
void QwtPicker::setTrackerMode(DisplayMode mode)
 
446
{   
 
447
    if ( d_data->trackerMode != mode )
 
448
    {
 
449
        d_data->trackerMode = mode;
 
450
        setMouseTracking(d_data->trackerMode == AlwaysOn);
 
451
    }
 
452
}   
 
453
 
 
454
/*!
 
455
  \return Tracker display mode
 
456
  \sa setTrackerMode(), DisplayMode
 
457
*/
 
458
QwtPicker::DisplayMode QwtPicker::trackerMode() const
 
459
{   
 
460
    return d_data->trackerMode;
 
461
}   
 
462
 
 
463
/*!
 
464
  \brief Set the resize mode.
 
465
 
 
466
  The resize mode controls what to do with the selected points of an active
 
467
  selection when the observed widget is resized.
 
468
 
 
469
  Stretch means the points are scaled according to the new
 
470
  size, KeepSize means the points remain unchanged.
 
471
 
 
472
  The default mode is Stretch.
 
473
 
 
474
  \param mode Resize mode
 
475
  \sa resizeMode(), ResizeMode
 
476
*/
 
477
void QwtPicker::setResizeMode(ResizeMode mode)
 
478
{
 
479
    d_data->resizeMode = mode;
 
480
}   
 
481
 
 
482
/*!
 
483
  \return Resize mode
 
484
  \sa setResizeMode(), ResizeMode
 
485
*/
 
486
 
 
487
QwtPicker::ResizeMode QwtPicker::resizeMode() const
 
488
{   
 
489
    return d_data->resizeMode;
 
490
}
 
491
 
 
492
/*!
 
493
  \brief En/disable the picker
 
494
 
 
495
  When enabled is true an event filter is installed for
 
496
  the observed widget, otherwise the event filter is removed.
 
497
 
 
498
  \param enabled true or false
 
499
  \sa isEnabled(), eventFilter()
 
500
*/
 
501
void QwtPicker::setEnabled(bool enabled)
 
502
{
 
503
    if ( d_data->enabled != enabled )
 
504
    {
 
505
        d_data->enabled = enabled;
 
506
 
 
507
        QWidget *w = parentWidget();
 
508
        if ( w )
 
509
        {
 
510
            if ( enabled )
 
511
                w->installEventFilter(this);
 
512
            else
 
513
                w->removeEventFilter(this);
 
514
        }
 
515
 
 
516
        updateDisplay();
 
517
    }
 
518
}
 
519
 
 
520
/*!
 
521
  \return true when enabled, false otherwise
 
522
  \sa setEnabled, eventFilter()
 
523
*/
 
524
 
 
525
bool QwtPicker::isEnabled() const
 
526
{
 
527
    return d_data->enabled;
 
528
}
 
529
 
 
530
/*!
 
531
  Set the font for the tracker
 
532
 
 
533
  \param font Tracker font
 
534
  \sa trackerFont(), setTrackerMode(), setTrackerPen()
 
535
*/
 
536
void QwtPicker::setTrackerFont(const QFont &font)
 
537
{
 
538
    if ( font != d_data->trackerFont )
 
539
    {
 
540
        d_data->trackerFont = font;
 
541
        updateDisplay();
 
542
    }
 
543
}
 
544
 
 
545
/*!
 
546
  \return Tracker font
 
547
  \sa setTrackerFont(), trackerMode(), trackerPen()
 
548
*/
 
549
 
 
550
QFont QwtPicker::trackerFont() const
 
551
{
 
552
    return d_data->trackerFont;
 
553
}
 
554
 
 
555
/*!
 
556
  Set the pen for the tracker
 
557
 
 
558
  \param pen Tracker pen
 
559
  \sa trackerPen(), setTrackerMode(), setTrackerFont()
 
560
*/
 
561
void QwtPicker::setTrackerPen(const QPen &pen)
 
562
{
 
563
    if ( pen != d_data->trackerPen )
 
564
    {
 
565
        d_data->trackerPen = pen;
 
566
        updateDisplay();
 
567
    }
 
568
}
 
569
 
 
570
/*!
 
571
  \return Tracker pen
 
572
  \sa setTrackerPen(), trackerMode(), trackerFont()
 
573
*/
 
574
QPen QwtPicker::trackerPen() const
 
575
{
 
576
    return d_data->trackerPen;
 
577
}
 
578
 
 
579
/*!
 
580
  Set the pen for the rubberband
 
581
 
 
582
  \param pen Rubberband pen
 
583
  \sa rubberBandPen(), setRubberBand()
 
584
*/
 
585
void QwtPicker::setRubberBandPen(const QPen &pen)
 
586
{
 
587
    if ( pen != d_data->rubberBandPen )
 
588
    {
 
589
        d_data->rubberBandPen = pen;
 
590
        updateDisplay();
 
591
    }
 
592
}
 
593
 
 
594
/*!
 
595
  \return Rubberband pen
 
596
  \sa setRubberBandPen(), rubberBand()
 
597
*/
 
598
QPen QwtPicker::rubberBandPen() const
 
599
{
 
600
    return d_data->rubberBandPen;
 
601
}
 
602
 
 
603
/*!
 
604
   \brief Return the label for a position
 
605
 
 
606
   In case of HLineRubberBand the label is the value of the
 
607
   y position, in case of VLineRubberBand the value of the x position.
 
608
   Otherwise the label contains x and y position separated by a ',' .
 
609
 
 
610
   The format for the string conversion is "%d".
 
611
 
 
612
   \param pos Position
 
613
   \return Converted position as string
 
614
*/
 
615
 
 
616
QwtText QwtPicker::trackerText(const QPoint &pos) const
 
617
{
 
618
    QString label;
 
619
 
 
620
    switch(rubberBand())
 
621
    {
 
622
        case HLineRubberBand:
 
623
            label.sprintf("%d", pos.y());
 
624
            break;
 
625
        case VLineRubberBand:
 
626
            label.sprintf("%d", pos.x());
 
627
            break;
 
628
        default:
 
629
            label.sprintf("%d, %d", pos.x(), pos.y());
 
630
    }
 
631
    return label;
 
632
}
 
633
 
 
634
/*!
 
635
   Draw a rubberband , depending on rubberBand() and selectionFlags()
 
636
 
 
637
   \param painter Painter, initialized with clip rect 
 
638
 
 
639
   \sa rubberBand(), RubberBand, selectionFlags()
 
640
*/
 
641
 
 
642
void QwtPicker::drawRubberBand(QPainter *painter) const
 
643
{
 
644
    if ( !isActive() || rubberBand() == NoRubberBand || 
 
645
        rubberBandPen().style() == Qt::NoPen )
 
646
    {
 
647
        return;
 
648
    }
 
649
 
 
650
    const QRect &pRect = pickRect();
 
651
    const QwtPolygon &pa = d_data->selection;
 
652
 
 
653
    if ( selectionFlags() & PointSelection )
 
654
    {
 
655
        if ( pa.count() < 1 )
 
656
            return;
 
657
 
 
658
        const QPoint pos = pa[0];
 
659
 
 
660
        switch(rubberBand())
 
661
        {
 
662
            case VLineRubberBand:
 
663
                QwtPainter::drawLine(painter, pos.x(),
 
664
                    pRect.top(), pos.x(), pRect.bottom());
 
665
                break;
 
666
 
 
667
            case HLineRubberBand:
 
668
                QwtPainter::drawLine(painter, pRect.left(), 
 
669
                    pos.y(), pRect.right(), pos.y());
 
670
                break;
 
671
 
 
672
            case CrossRubberBand:
 
673
                QwtPainter::drawLine(painter, pos.x(),
 
674
                    pRect.top(), pos.x(), pRect.bottom());
 
675
                QwtPainter::drawLine(painter, pRect.left(), 
 
676
                    pos.y(), pRect.right(), pos.y());
 
677
                break;
 
678
            default:
 
679
                break;
 
680
        }
 
681
    }
 
682
 
 
683
    else if ( selectionFlags() & RectSelection )
 
684
    {
 
685
        if ( pa.count() < 2 )
 
686
            return;
 
687
 
 
688
        QPoint p1 = pa[0];
 
689
        QPoint p2 = pa[int(pa.count() - 1)];
 
690
 
 
691
        if ( selectionFlags() & CenterToCorner )
 
692
        {
 
693
            p1.setX(p1.x() - (p2.x() - p1.x()));
 
694
            p1.setY(p1.y() - (p2.y() - p1.y()));
 
695
        }
 
696
        else if ( selectionFlags() & CenterToRadius )
 
697
        {
 
698
            const int radius = qwtMax(qwtAbs(p2.x() - p1.x()), 
 
699
                qwtAbs(p2.y() - p1.y()));
 
700
            p2.setX(p1.x() + radius);
 
701
            p2.setY(p1.y() + radius);
 
702
            p1.setX(p1.x() - radius);
 
703
            p1.setY(p1.y() - radius);
 
704
        }
 
705
 
 
706
#if QT_VERSION < 0x040000
 
707
        const QRect rect = QRect(p1, p2).normalize();
 
708
#else
 
709
        const QRect rect = QRect(p1, p2).normalized();
 
710
#endif
 
711
        switch(rubberBand())
 
712
        {
 
713
            case EllipseRubberBand:
 
714
                QwtPainter::drawEllipse(painter, rect);
 
715
                break;
 
716
            case RectRubberBand:
 
717
                QwtPainter::drawRect(painter, rect);
 
718
                break;
 
719
            default:
 
720
                break;
 
721
        }
 
722
    }
 
723
    else if ( selectionFlags() & PolygonSelection )
 
724
    {
 
725
        if ( rubberBand() == PolygonRubberBand )
 
726
            painter->drawPolyline(pa);
 
727
    }
 
728
}
 
729
 
 
730
/*!
 
731
   Draw the tracker
 
732
 
 
733
   \param painter Painter
 
734
   \sa trackerRect(), trackerText()
 
735
*/
 
736
 
 
737
void QwtPicker::drawTracker(QPainter *painter) const
 
738
{
 
739
    const QRect textRect = trackerRect(painter);
 
740
    if ( !textRect.isEmpty() )
 
741
    {
 
742
        QwtText label = trackerText(d_data->labelPosition);
 
743
        if ( !label.isEmpty() )
 
744
        {
 
745
#ifdef USE_TRACKER_BACKGROUND
 
746
            if ( label.testPaintAttribute(QwtText::PaintBackground) )
 
747
            {
 
748
                if ( d_data->trackerWidget )
 
749
                    d_data->trackerWidget->d_hasTrackerBackground = true;
 
750
                
 
751
                if ( painter->pen() != trackerPen() &&
 
752
                    painter->pen().color() == Qt::color1 )
 
753
                {
 
754
                    /*
 
755
                      Hack time: we know, that we are painting to get the
 
756
                      region for the mask. The text is always inside the
 
757
                      textRect and on a QBitmap everything is painted in
 
758
                      Qt::color1. That's why we don't have to paint the text.
 
759
                     */
 
760
                    painter->fillRect(textRect, Qt::color1);
 
761
                    return;
 
762
                }
 
763
            }
 
764
            else
 
765
            {
 
766
                if ( d_data->trackerWidget )
 
767
                    d_data->trackerWidget->d_hasTrackerBackground = false;
 
768
            }
 
769
#endif
 
770
 
 
771
#if defined(Q_WS_MAC)
 
772
#if QT_VERSION >= 0x040000 && QT_VERSION < 0x040300
 
773
            // Antialiased fonts are broken on the Mac.
 
774
            painter->save();
 
775
            painter->setRenderHint(QPainter::TextAntialiasing, false);
 
776
#else
 
777
            QFont fnt = label.usedFont(painter->font());
 
778
            fnt.setStyleStrategy(QFont::NoAntialias);
 
779
            label.setFont(fnt);
 
780
#endif
 
781
#endif
 
782
            label.draw(painter, textRect);
 
783
 
 
784
#if defined(Q_WS_MAC)
 
785
#if QT_VERSION >= 0x040000 && QT_VERSION < 0x040300
 
786
            painter->restore();
 
787
#endif
 
788
#endif
 
789
        }
 
790
    }
 
791
}
 
792
 
 
793
QRect QwtPicker::trackerRect(QPainter *painter) const
 
794
{
 
795
    if ( trackerMode() == AlwaysOff || 
 
796
        (trackerMode() == ActiveOnly && !isActive() ) )
 
797
    {
 
798
        return QRect();
 
799
    }
 
800
 
 
801
    if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 )
 
802
        return QRect();
 
803
 
 
804
    QwtText text = trackerText(d_data->labelPosition);
 
805
    if ( text.isEmpty() )
 
806
        return QRect();
 
807
 
 
808
    QRect textRect(QPoint(0, 0), text.textSize(painter->font()));
 
809
 
 
810
    const QPoint &pos = d_data->labelPosition;
 
811
 
 
812
    int alignment = 0;
 
813
    if ( isActive() && d_data->selection.count() > 1 
 
814
        && rubberBand() != NoRubberBand )
 
815
    {
 
816
        const QPoint last = 
 
817
            d_data->selection[int(d_data->selection.count()) - 2];
 
818
 
 
819
        alignment |= (pos.x() >= last.x()) ? Qt::AlignRight : Qt::AlignLeft;
 
820
        alignment |= (pos.y() > last.y()) ? Qt::AlignBottom : Qt::AlignTop;
 
821
    }
 
822
    else
 
823
        alignment = Qt::AlignTop | Qt::AlignRight;
 
824
 
 
825
    const int margin = 5;
 
826
 
 
827
    int x = pos.x();
 
828
    if ( alignment & Qt::AlignLeft )
 
829
        x -= textRect.width() + margin;
 
830
    else if ( alignment & Qt::AlignRight )
 
831
        x += margin;
 
832
 
 
833
    int y = pos.y();
 
834
    if ( alignment & Qt::AlignBottom )
 
835
        y += margin;
 
836
    else if ( alignment & Qt::AlignTop )
 
837
        y -= textRect.height() + margin;
 
838
    
 
839
    textRect.moveTopLeft(QPoint(x, y));
 
840
 
 
841
    int right = qwtMin(textRect.right(), pickRect().right() - margin);
 
842
    int bottom = qwtMin(textRect.bottom(), pickRect().bottom() - margin);
 
843
    textRect.moveBottomRight(QPoint(right, bottom));
 
844
 
 
845
    int left = qwtMax(textRect.left(), pickRect().left() + margin);
 
846
    int top = qwtMax(textRect.top(), pickRect().top() + margin);
 
847
    textRect.moveTopLeft(QPoint(left, top));
 
848
 
 
849
    return textRect;
 
850
}
 
851
 
 
852
/*!
 
853
  \brief Event filter
 
854
 
 
855
  When isEnabled() == true all events of the observed widget are filtered.
 
856
  Mouse and keyboard events are translated into widgetMouse- and widgetKey-
 
857
  and widgetWheel-events. Paint and Resize events are handled to keep 
 
858
  rubberband and tracker up to date.
 
859
 
 
860
  \sa event(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
 
861
      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
 
862
      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
 
863
*/
 
864
bool QwtPicker::eventFilter(QObject *o, QEvent *e)
 
865
{
 
866
    if ( o && o == parentWidget() )
 
867
    {
 
868
        switch(e->type())
 
869
        {
 
870
            case QEvent::Resize:
 
871
            {
 
872
                const QResizeEvent *re = (QResizeEvent *)e;
 
873
                if ( d_data->resizeMode == Stretch )
 
874
                    stretchSelection(re->oldSize(), re->size());
 
875
 
 
876
                if ( d_data->rubberBandWidget )
 
877
                    d_data->rubberBandWidget->resize(re->size());
 
878
             
 
879
                if ( d_data->trackerWidget )
 
880
                    d_data->trackerWidget->resize(re->size());
 
881
                break;
 
882
            }
 
883
            case QEvent::Leave:
 
884
                widgetLeaveEvent(e);
 
885
                break;
 
886
            case QEvent::MouseButtonPress:
 
887
                widgetMousePressEvent((QMouseEvent *)e);
 
888
                break;
 
889
            case QEvent::MouseButtonRelease:
 
890
                widgetMouseReleaseEvent((QMouseEvent *)e);
 
891
                break;
 
892
            case QEvent::MouseButtonDblClick:
 
893
                widgetMouseDoubleClickEvent((QMouseEvent *)e);
 
894
                break;
 
895
            case QEvent::MouseMove:
 
896
                widgetMouseMoveEvent((QMouseEvent *)e);
 
897
                break;
 
898
            case QEvent::KeyPress:
 
899
                widgetKeyPressEvent((QKeyEvent *)e);
 
900
                break;
 
901
            case QEvent::KeyRelease:
 
902
                widgetKeyReleaseEvent((QKeyEvent *)e);
 
903
                break;
 
904
            case QEvent::Wheel:
 
905
                widgetWheelEvent((QWheelEvent *)e);
 
906
                break;
 
907
            default:
 
908
                break;
 
909
        }
 
910
    }
 
911
    return false;
 
912
}
 
913
 
 
914
/*!
 
915
  Handle a mouse press event for the observed widget.
 
916
 
 
917
  Begin and/or end a selection depending on the selection flags.
 
918
 
 
919
  \sa QwtPicker, selectionFlags()
 
920
  \sa eventFilter(), widgetMouseReleaseEvent(),
 
921
      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
 
922
      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
 
923
*/
 
924
void QwtPicker::widgetMousePressEvent(QMouseEvent *e)
 
925
{
 
926
    transition(e);
 
927
}
 
928
 
 
929
/*!
 
930
  Handle a mouse move event for the observed widget.
 
931
 
 
932
  Move the last point of the selection in case of isActive() == true
 
933
 
 
934
  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
 
935
      widgetMouseDoubleClickEvent(),
 
936
      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
 
937
*/
 
938
void QwtPicker::widgetMouseMoveEvent(QMouseEvent *e)
 
939
{
 
940
    if ( pickRect().contains(e->pos()) )
 
941
        d_data->labelPosition = e->pos();
 
942
    else
 
943
        d_data->labelPosition = QPoint(-1, -1);
 
944
 
 
945
    if ( !isActive() )
 
946
        updateDisplay();
 
947
 
 
948
    transition(e);
 
949
}
 
950
 
 
951
/*!
 
952
  Handle a leave event for the observed widget.
 
953
 
 
954
  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
 
955
      widgetMouseDoubleClickEvent(),
 
956
      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
 
957
*/
 
958
void QwtPicker::widgetLeaveEvent(QEvent *)   
 
959
{
 
960
    d_data->labelPosition = QPoint(-1, -1);
 
961
    if ( !isActive() )
 
962
        updateDisplay();
 
963
}
 
964
 
 
965
/*!
 
966
  Handle a mouse relase event for the observed widget.
 
967
 
 
968
  End a selection depending on the selection flags.
 
969
 
 
970
  \sa QwtPicker, selectionFlags()
 
971
  \sa eventFilter(), widgetMousePressEvent(), 
 
972
      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
 
973
      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
 
974
*/
 
975
void QwtPicker::widgetMouseReleaseEvent(QMouseEvent *e)
 
976
{
 
977
    transition(e);
 
978
}
 
979
 
 
980
/*!
 
981
  Handle mouse double click event for the observed widget.
 
982
 
 
983
  Empty implementation, does nothing.
 
984
 
 
985
  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
 
986
      widgetMouseMoveEvent(),
 
987
      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
 
988
*/
 
989
void QwtPicker::widgetMouseDoubleClickEvent(QMouseEvent *me)
 
990
{
 
991
    transition(me);
 
992
}
 
993
    
 
994
 
 
995
/*!
 
996
  Handle a wheel event for the observed widget.
 
997
 
 
998
  Move the last point of the selection in case of isActive() == true
 
999
 
 
1000
  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
 
1001
      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
 
1002
      widgetKeyPressEvent(), widgetKeyReleaseEvent()
 
1003
*/
 
1004
void QwtPicker::widgetWheelEvent(QWheelEvent *e)
 
1005
{
 
1006
    if ( pickRect().contains(e->pos()) )
 
1007
        d_data->labelPosition = e->pos();
 
1008
    else
 
1009
        d_data->labelPosition = QPoint(-1, -1);
 
1010
 
 
1011
    updateDisplay();
 
1012
 
 
1013
    transition(e);
 
1014
}
 
1015
 
 
1016
/*!
 
1017
  Handle a key press event for the observed widget.
 
1018
 
 
1019
  Selections can be completely done by the keyboard. The arrow keys
 
1020
  move the cursor, the abort key aborts a selection. All other keys
 
1021
  are handled by the current state machine.
 
1022
 
 
1023
  \sa QwtPicker, selectionFlags()
 
1024
  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
 
1025
      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
 
1026
      widgetWheelEvent(), widgetKeyReleaseEvent(), stateMachine(),
 
1027
      QwtEventPattern::KeyPatternCode
 
1028
*/
 
1029
void QwtPicker::widgetKeyPressEvent(QKeyEvent *ke)
 
1030
{
 
1031
    int dx = 0;
 
1032
    int dy = 0;
 
1033
 
 
1034
    int offset = 1;
 
1035
    if ( ke->isAutoRepeat() )
 
1036
        offset = 5;
 
1037
 
 
1038
    if ( keyMatch(KeyLeft, ke) )
 
1039
        dx = -offset;
 
1040
    else if ( keyMatch(KeyRight, ke) )
 
1041
        dx = offset;
 
1042
    else if ( keyMatch(KeyUp, ke) )
 
1043
        dy = -offset;
 
1044
    else if ( keyMatch(KeyDown, ke) )
 
1045
        dy = offset;
 
1046
    else if ( keyMatch(KeyAbort, ke) )
 
1047
    {
 
1048
        if ( d_data->stateMachine )
 
1049
            d_data->stateMachine->reset();
 
1050
 
 
1051
        if (isActive())
 
1052
            end(false);
 
1053
    }
 
1054
    else
 
1055
        transition(ke);
 
1056
 
 
1057
    if ( dx != 0 || dy != 0 )
 
1058
    {
 
1059
        const QRect rect = pickRect();
 
1060
        const QPoint pos = parentWidget()->mapFromGlobal(QCursor::pos());
 
1061
 
 
1062
        int x = pos.x() + dx;
 
1063
        x = qwtMax(rect.left(), x);
 
1064
        x = qwtMin(rect.right(), x);
 
1065
 
 
1066
        int y = pos.y() + dy;
 
1067
        y = qwtMax(rect.top(), y);
 
1068
        y = qwtMin(rect.bottom(), y);
 
1069
 
 
1070
        QCursor::setPos(parentWidget()->mapToGlobal(QPoint(x, y)));
 
1071
    }
 
1072
}
 
1073
 
 
1074
/*!
 
1075
  Handle a key release event for the observed widget.
 
1076
 
 
1077
  Passes the event to the state machine.
 
1078
 
 
1079
  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
 
1080
      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
 
1081
      widgetWheelEvent(), widgetKeyPressEvent(), stateMachine()
 
1082
*/
 
1083
void QwtPicker::widgetKeyReleaseEvent(QKeyEvent *ke)
 
1084
{
 
1085
    transition(ke);
 
1086
}
 
1087
 
 
1088
/*!
 
1089
  Passes an event to the state machine and executes the resulting 
 
1090
  commands. Append and Move commands use the current position
 
1091
  of the cursor (QCursor::pos()).
 
1092
 
 
1093
  \param e Event
 
1094
*/
 
1095
void QwtPicker::transition(const QEvent *e)
 
1096
{
 
1097
    if ( !d_data->stateMachine )
 
1098
        return;
 
1099
 
 
1100
    QwtPickerMachine::CommandList commandList =
 
1101
        d_data->stateMachine->transition(*this, e);
 
1102
 
 
1103
    QPoint pos;
 
1104
    switch(e->type())
 
1105
    {
 
1106
        case QEvent::MouseButtonDblClick:
 
1107
        case QEvent::MouseButtonPress:
 
1108
        case QEvent::MouseButtonRelease:
 
1109
        case QEvent::MouseMove:
 
1110
        {
 
1111
            const QMouseEvent *me = (QMouseEvent *)e;
 
1112
            pos = me->pos();
 
1113
            break;
 
1114
        }
 
1115
        default:
 
1116
            pos = parentWidget()->mapFromGlobal(QCursor::pos());
 
1117
    }
 
1118
 
 
1119
    for ( uint i = 0; i < (uint)commandList.count(); i++ )
 
1120
    {
 
1121
        switch(commandList[i])
 
1122
        {
 
1123
            case QwtPickerMachine::Begin:
 
1124
            {
 
1125
                begin();
 
1126
                break;
 
1127
            }
 
1128
            case QwtPickerMachine::Append:
 
1129
            {
 
1130
                append(pos);
 
1131
                break;
 
1132
            }
 
1133
            case QwtPickerMachine::Move:
 
1134
            {
 
1135
                move(pos);
 
1136
                break;
 
1137
            }
 
1138
            case QwtPickerMachine::End:
 
1139
            {
 
1140
                end();
 
1141
                break;
 
1142
            }
 
1143
        }
 
1144
    }
 
1145
}
 
1146
 
 
1147
/*!
 
1148
  Open a selection setting the state to active
 
1149
 
 
1150
  \sa isActive, end(), append(), move()
 
1151
*/
 
1152
void QwtPicker::begin()
 
1153
{
 
1154
    if ( d_data->isActive )
 
1155
        return;
 
1156
 
 
1157
    d_data->selection.resize(0);
 
1158
    d_data->isActive = true;
 
1159
 
 
1160
    if ( trackerMode() != AlwaysOff )
 
1161
    {
 
1162
        if ( d_data->labelPosition.x() < 0 || d_data->labelPosition.y() < 0 ) 
 
1163
        {
 
1164
            QWidget *w = parentWidget();
 
1165
            if ( w )
 
1166
                d_data->labelPosition = w->mapFromGlobal(QCursor::pos());
 
1167
        }
 
1168
    }
 
1169
 
 
1170
    updateDisplay();
 
1171
    setMouseTracking(true);
 
1172
}
 
1173
 
 
1174
/*!
 
1175
  \brief Close a selection setting the state to inactive.
 
1176
 
 
1177
  The selection is validated and maybe fixed by QwtPicker::accept().
 
1178
 
 
1179
  \param ok If true, complete the selection and emit a selected signal
 
1180
            otherwise discard the selection.
 
1181
  \return true if the selection is accepted, false otherwise
 
1182
  \sa isActive, begin(), append(), move(), selected(), accept()
 
1183
*/
 
1184
bool QwtPicker::end(bool ok)
 
1185
{
 
1186
    if ( d_data->isActive )
 
1187
    {
 
1188
        setMouseTracking(false);
 
1189
 
 
1190
        d_data->isActive = false;
 
1191
 
 
1192
        if ( trackerMode() == ActiveOnly )
 
1193
            d_data->labelPosition = QPoint(-1, -1);
 
1194
 
 
1195
        if ( ok )
 
1196
            ok = accept(d_data->selection);
 
1197
 
 
1198
        if ( ok )
 
1199
            emit selected(d_data->selection);
 
1200
        else
 
1201
            d_data->selection.resize(0);
 
1202
 
 
1203
        updateDisplay();
 
1204
    }
 
1205
    else
 
1206
        ok = false;
 
1207
 
 
1208
    return ok;
 
1209
}
 
1210
 
 
1211
/*!
 
1212
  Append a point to the selection and update rubberband and tracker.
 
1213
  The appended() signal is emitted.
 
1214
 
 
1215
  \param pos Additional point
 
1216
 
 
1217
  \sa isActive, begin(), end(), move(), appended()
 
1218
*/
 
1219
void QwtPicker::append(const QPoint &pos)
 
1220
{
 
1221
    if ( d_data->isActive )
 
1222
    {
 
1223
        const int idx = d_data->selection.count();
 
1224
        d_data->selection.resize(idx + 1);
 
1225
        d_data->selection[idx] = pos;
 
1226
 
 
1227
        updateDisplay();
 
1228
 
 
1229
        emit appended(pos);
 
1230
    }
 
1231
}
 
1232
 
 
1233
/*!
 
1234
  Move the last point of the selection
 
1235
  The moved() signal is emitted.
 
1236
 
 
1237
  \param pos New position
 
1238
  \sa isActive, begin(), end(), append()
 
1239
 
 
1240
*/
 
1241
void QwtPicker::move(const QPoint &pos)
 
1242
{
 
1243
    if ( d_data->isActive )
 
1244
    {
 
1245
        const int idx = d_data->selection.count() - 1;
 
1246
        if ( idx >= 0 )
 
1247
        {
 
1248
            if ( d_data->selection[idx] != pos )
 
1249
            {
 
1250
                d_data->selection[idx] = pos;
 
1251
 
 
1252
                updateDisplay();
 
1253
 
 
1254
                emit moved(pos);
 
1255
            }
 
1256
        }
 
1257
    }
 
1258
}
 
1259
 
 
1260
bool QwtPicker::accept(QwtPolygon &) const
 
1261
{
 
1262
    return true;
 
1263
}
 
1264
 
 
1265
/*!
 
1266
  A picker is active between begin() and end().
 
1267
  \return true if the selection is active.
 
1268
*/
 
1269
bool QwtPicker::isActive() const 
 
1270
{
 
1271
    return d_data->isActive;
 
1272
}
 
1273
 
 
1274
//!  Return Selected points
 
1275
const QwtPolygon &QwtPicker::selection() const
 
1276
{
 
1277
    return d_data->selection;
 
1278
}
 
1279
 
 
1280
/*!
 
1281
  Scale the selection by the ratios of oldSize and newSize
 
1282
  The changed() signal is emitted.
 
1283
 
 
1284
  \param oldSize Previous size
 
1285
  \param newSize Current size
 
1286
 
 
1287
  \sa ResizeMode, setResizeMode(), resizeMode()
 
1288
*/
 
1289
void QwtPicker::stretchSelection(const QSize &oldSize, const QSize &newSize)
 
1290
{
 
1291
    const double xRatio =
 
1292
        double(newSize.width()) / double(oldSize.width());
 
1293
    const double yRatio =
 
1294
        double(newSize.height()) / double(oldSize.height());
 
1295
 
 
1296
    for ( int i = 0; i < int(d_data->selection.count()); i++ )
 
1297
    {
 
1298
        QPoint &p = d_data->selection[i];
 
1299
        p.setX(qRound(p.x() * xRatio));
 
1300
        p.setY(qRound(p.y() * yRatio));
 
1301
 
 
1302
        emit changed(d_data->selection);
 
1303
    }
 
1304
}
 
1305
 
 
1306
/*!
 
1307
  Set mouse tracking for the observed widget.
 
1308
 
 
1309
  In case of enable is true, the previous value
 
1310
  is saved, that is restored when enable is false.
 
1311
 
 
1312
  \warning Even when enable is false, mouse tracking might be restored
 
1313
           to true. When mouseTracking for the observed widget
 
1314
           has been changed directly by QWidget::setMouseTracking
 
1315
           while mouse tracking has been set to true, this value can't
 
1316
           be restored.
 
1317
*/
 
1318
 
 
1319
void QwtPicker::setMouseTracking(bool enable)
 
1320
{
 
1321
    QWidget *widget = parentWidget();
 
1322
    if ( !widget )
 
1323
        return;
 
1324
 
 
1325
    if ( enable )
 
1326
    {
 
1327
        d_data->mouseTracking = widget->hasMouseTracking();
 
1328
        widget->setMouseTracking(true);
 
1329
    }
 
1330
    else
 
1331
    {
 
1332
        widget->setMouseTracking(d_data->mouseTracking);
 
1333
    }
 
1334
}
 
1335
 
 
1336
/*!
 
1337
  Find the area of the observed widget, where selection might happen.
 
1338
 
 
1339
  \return QFrame::contentsRect() if it is a QFrame, QWidget::rect() otherwise.
 
1340
*/
 
1341
QRect QwtPicker::pickRect() const
 
1342
{
 
1343
    QRect rect;
 
1344
 
 
1345
    const QWidget *widget = parentWidget();
 
1346
    if ( !widget )
 
1347
        return rect;
 
1348
 
 
1349
    if ( widget->inherits("QFrame") )
 
1350
        rect = ((QFrame *)widget)->contentsRect();
 
1351
    else
 
1352
        rect = widget->rect();
 
1353
 
 
1354
    return rect;
 
1355
}
 
1356
 
 
1357
void QwtPicker::updateDisplay()
 
1358
{
 
1359
    QWidget *w = parentWidget();
 
1360
 
 
1361
    bool showRubberband = false;
 
1362
    bool showTracker = false;
 
1363
    if ( w && w->isVisible() && d_data->enabled )
 
1364
    {
 
1365
        if ( rubberBand() != NoRubberBand && isActive() &&
 
1366
            rubberBandPen().style() != Qt::NoPen )
 
1367
        {
 
1368
            showRubberband = true;
 
1369
        }
 
1370
 
 
1371
        if ( trackerMode() == AlwaysOn ||
 
1372
            (trackerMode() == ActiveOnly && isActive() ) )
 
1373
        {
 
1374
            if ( trackerPen() != Qt::NoPen )
 
1375
                showTracker = true;
 
1376
        }
 
1377
    }
 
1378
 
 
1379
#if QT_VERSION < 0x040000
 
1380
    QGuardedPtr<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
 
1381
#else
 
1382
    QPointer<PrivateData::PickerWidget> &rw = d_data->rubberBandWidget;
 
1383
#endif
 
1384
    if ( showRubberband )
 
1385
    {
 
1386
        if ( rw.isNull() )
 
1387
        {
 
1388
            rw = new PrivateData::PickerWidget(
 
1389
                this, w, PrivateData::PickerWidget::RubberBand);
 
1390
            rw->resize(w->size());
 
1391
        }
 
1392
        rw->updateMask();
 
1393
        rw->update(); // Needed, when the mask doesn't change
 
1394
    }
 
1395
    else
 
1396
        delete rw;
 
1397
 
 
1398
#if QT_VERSION < 0x040000
 
1399
    QGuardedPtr<PrivateData::PickerWidget> &tw = d_data->trackerWidget;
 
1400
#else
 
1401
    QPointer<PrivateData::PickerWidget> &tw = d_data->trackerWidget;
 
1402
#endif
 
1403
    if ( showTracker )
 
1404
    {
 
1405
        if ( tw.isNull() )
 
1406
        {
 
1407
            tw = new PrivateData::PickerWidget(
 
1408
                this, w, PrivateData::PickerWidget::Text);
 
1409
            tw->resize(w->size());
 
1410
        }
 
1411
        tw->updateMask();
 
1412
        tw->update(); // Needed, when the mask doesn't change
 
1413
    }
 
1414
    else
 
1415
        delete tw;
 
1416
}
 
1417
 
 
1418
const QWidget *QwtPicker::rubberBandWidget() const
 
1419
{
 
1420
    return d_data->rubberBandWidget;
 
1421
}
 
1422
 
 
1423
const QWidget *QwtPicker::trackerWidget() const
 
1424
{
 
1425
    return d_data->trackerWidget;
 
1426
}
 
1427