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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2008-05-26 10:26:31 UTC
  • mfrom: (1.1.3 upstream) (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526102631-bp95mfccnrb957nx
Tags: 5.1.1-1
New upstream release.

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