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

« back to all changes in this revision

Viewing changes to qwt-5.1.2/src/qwt_plot.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2009-04-12 23:25:58 UTC
  • mfrom: (1.1.4 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090412232558-3bl06x785yr8xm8u
Tags: 5.1.2-1
* New upstream release.
* Bump compat/debhelper to 7.
* Bump Standards-Version to 3.8.1. No changes needed.
* Invert Maintainers and Uploaders field.
* Fix lintian warnings:
  - dh_clean _k deprecated.
  - missing dependency on libc.

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 <qpainter.h>
 
11
#if QT_VERSION < 0x040000
 
12
#include <qguardedptr.h>
 
13
#include <qfocusdata.h>
 
14
#else
 
15
#include <qpointer.h>
 
16
#include <qpaintengine.h>
 
17
#endif
 
18
#include <qapplication.h>
 
19
#include <qevent.h>
 
20
#include "qwt_plot.h"
 
21
#include "qwt_plot_dict.h"
 
22
#include "qwt_plot_layout.h"
 
23
#include "qwt_scale_widget.h"
 
24
#include "qwt_scale_engine.h"
 
25
#include "qwt_text_label.h"
 
26
#include "qwt_legend.h"
 
27
#include "qwt_dyngrid_layout.h"
 
28
#include "qwt_plot_canvas.h"
 
29
#include "qwt_paint_buffer.h"
 
30
 
 
31
class QwtPlot::PrivateData
 
32
{
 
33
public:
 
34
#if QT_VERSION < 0x040000
 
35
    QGuardedPtr<QwtTextLabel> lblTitle;
 
36
    QGuardedPtr<QwtPlotCanvas> canvas;
 
37
    QGuardedPtr<QwtLegend> legend;
 
38
#else
 
39
    QPointer<QwtTextLabel> lblTitle;
 
40
    QPointer<QwtPlotCanvas> canvas;
 
41
    QPointer<QwtLegend> legend;
 
42
#endif
 
43
    QwtPlotLayout *layout;
 
44
 
 
45
    bool autoReplot;
 
46
};
 
47
 
 
48
/*!
 
49
  \brief Constructor
 
50
  \param parent Parent widget
 
51
 */
 
52
QwtPlot::QwtPlot(QWidget *parent):
 
53
    QFrame(parent)
 
54
{
 
55
    initPlot(QwtText());
 
56
}
 
57
 
 
58
/*!
 
59
  \brief Constructor
 
60
  \param title Title text
 
61
  \param parent Parent widget
 
62
 */
 
63
QwtPlot::QwtPlot(const QwtText &title, QWidget *parent):
 
64
    QFrame(parent)
 
65
{
 
66
    initPlot(title);
 
67
}
 
68
 
 
69
#if QT_VERSION < 0x040000
 
70
/*!
 
71
  \brief Constructor
 
72
  \param parent Parent widget
 
73
  \param name Object name
 
74
 */
 
75
QwtPlot::QwtPlot(QWidget *parent, const char *name):
 
76
    QFrame(parent, name)
 
77
{   
 
78
    initPlot(QwtText());
 
79
}   
 
80
#endif
 
81
 
 
82
 
 
83
//! Destructor
 
84
QwtPlot::~QwtPlot()
 
85
{
 
86
    detachItems(QwtPlotItem::Rtti_PlotItem, autoDelete());
 
87
 
 
88
    delete d_data->layout;
 
89
    deleteAxesData();
 
90
    delete d_data;
 
91
}
 
92
 
 
93
/*!
 
94
  \brief Initializes a QwtPlot instance
 
95
  \param title Title text
 
96
 */
 
97
void QwtPlot::initPlot(const QwtText &title)
 
98
{
 
99
    d_data = new PrivateData;
 
100
 
 
101
#if QT_VERSION < 0x040000
 
102
    setWFlags(Qt::WNoAutoErase);
 
103
#endif 
 
104
 
 
105
    d_data->layout = new QwtPlotLayout;
 
106
 
 
107
    d_data->autoReplot = false;
 
108
 
 
109
    d_data->lblTitle = new QwtTextLabel(title, this);
 
110
    d_data->lblTitle->setFont(QFont(fontInfo().family(), 14, QFont::Bold));
 
111
 
 
112
    QwtText text(title);
 
113
    int flags = Qt::AlignCenter;
 
114
#if QT_VERSION < 0x040000
 
115
    flags |= Qt::WordBreak | Qt::ExpandTabs;
 
116
#else
 
117
    flags |= Qt::TextWordWrap;
 
118
#endif
 
119
    text.setRenderFlags(flags);
 
120
    d_data->lblTitle->setText(text);
 
121
 
 
122
    d_data->legend = NULL;
 
123
 
 
124
    initAxesData();
 
125
 
 
126
    d_data->canvas = new QwtPlotCanvas(this);
 
127
    d_data->canvas->setFrameStyle(QFrame::Panel|QFrame::Sunken);
 
128
    d_data->canvas->setLineWidth(2);
 
129
    d_data->canvas->setMidLineWidth(0);
 
130
 
 
131
    updateTabOrder();
 
132
 
 
133
    setSizePolicy(QSizePolicy::MinimumExpanding, 
 
134
        QSizePolicy::MinimumExpanding);
 
135
}
 
136
 
 
137
/*!
 
138
  \brief Adds handling of layout requests
 
139
*/
 
140
bool QwtPlot::event(QEvent *e)
 
141
{
 
142
    bool ok = QFrame::event(e);
 
143
    switch(e->type())
 
144
    {
 
145
#if QT_VERSION < 0x040000
 
146
        case QEvent::LayoutHint:
 
147
#else
 
148
        case QEvent::LayoutRequest:
 
149
#endif
 
150
            updateLayout();
 
151
            break;
 
152
#if QT_VERSION >= 0x040000
 
153
        case QEvent::PolishRequest:
 
154
            polish();
 
155
            break;
 
156
#endif
 
157
        default:;
 
158
    }
 
159
    return ok;
 
160
}
 
161
 
 
162
//! Replots the plot if QwtPlot::autoReplot() is \c true.
 
163
void QwtPlot::autoRefresh()
 
164
{
 
165
    if (d_data->autoReplot)
 
166
        replot();
 
167
}
 
168
 
 
169
/*!
 
170
  \brief Set or reset the autoReplot option
 
171
 
 
172
  If the autoReplot option is set, the plot will be
 
173
  updated implicitly by manipulating member functions.
 
174
  Since this may be time-consuming, it is recommended
 
175
  to leave this option switched off and call replot()
 
176
  explicitly if necessary.
 
177
 
 
178
  The autoReplot option is set to false by default, which
 
179
  means that the user has to call replot() in order to make
 
180
  changes visible.
 
181
  \param tf \c true or \c false. Defaults to \c true.
 
182
  \sa replot()
 
183
*/
 
184
void QwtPlot::setAutoReplot(bool tf)
 
185
{
 
186
    d_data->autoReplot = tf;
 
187
}
 
188
 
 
189
//! \return true if the autoReplot option is set.
 
190
bool QwtPlot::autoReplot() const
 
191
{
 
192
    return d_data->autoReplot; 
 
193
}
 
194
 
 
195
/*!
 
196
  Change the plot's title
 
197
  \param title New title
 
198
*/
 
199
void QwtPlot::setTitle(const QString &title)
 
200
{
 
201
    if ( title != d_data->lblTitle->text().text() )
 
202
    {
 
203
        d_data->lblTitle->setText(title);
 
204
        updateLayout();
 
205
    }
 
206
}
 
207
 
 
208
/*!
 
209
  Change the plot's title
 
210
  \param title New title
 
211
*/
 
212
void QwtPlot::setTitle(const QwtText &title)
 
213
{
 
214
    if ( title != d_data->lblTitle->text() )
 
215
    {
 
216
        d_data->lblTitle->setText(title);
 
217
        updateLayout();
 
218
    }
 
219
}
 
220
 
 
221
//! \return the plot's title
 
222
QwtText QwtPlot::title() const
 
223
{
 
224
    return d_data->lblTitle->text();
 
225
}
 
226
 
 
227
//! \return the plot's title
 
228
QwtPlotLayout *QwtPlot::plotLayout()
 
229
{
 
230
    return d_data->layout;
 
231
}
 
232
 
 
233
//! \return the plot's titel label.
 
234
const QwtPlotLayout *QwtPlot::plotLayout() const
 
235
{
 
236
    return d_data->layout;
 
237
}
 
238
 
 
239
//! \return the plot's titel label.
 
240
QwtTextLabel *QwtPlot::titleLabel()
 
241
{
 
242
    return d_data->lblTitle;
 
243
}
 
244
 
 
245
/*!
 
246
  \return the plot's titel label.
 
247
*/
 
248
const QwtTextLabel *QwtPlot::titleLabel() const
 
249
{
 
250
    return d_data->lblTitle;
 
251
}
 
252
 
 
253
/*!
 
254
  \return the plot's legend
 
255
  \sa insertLegend()
 
256
*/
 
257
QwtLegend *QwtPlot::legend()
 
258
 
259
    return d_data->legend;
 
260
}   
 
261
 
 
262
/*!
 
263
  \return the plot's legend
 
264
  \sa insertLegend()
 
265
*/
 
266
const QwtLegend *QwtPlot::legend() const
 
267
 
268
    return d_data->legend;
 
269
}   
 
270
 
 
271
 
 
272
/*!
 
273
  \return the plot's canvas
 
274
*/
 
275
QwtPlotCanvas *QwtPlot::canvas()
 
276
 
277
    return d_data->canvas;
 
278
}   
 
279
 
 
280
/*!
 
281
  \return the plot's canvas
 
282
*/
 
283
const QwtPlotCanvas *QwtPlot::canvas() const
 
284
 
285
    return d_data->canvas;
 
286
}
 
287
 
 
288
//! Polish
 
289
void QwtPlot::polish()
 
290
{
 
291
    replot();
 
292
 
 
293
#if QT_VERSION < 0x040000
 
294
    QFrame::polish();
 
295
#endif
 
296
}
 
297
 
 
298
/*!  
 
299
  Return sizeHint
 
300
  \sa minimumSizeHint()
 
301
*/
 
302
 
 
303
QSize QwtPlot::sizeHint() const
 
304
{
 
305
    int dw = 0;
 
306
    int dh = 0;
 
307
    for ( int axisId = 0; axisId < axisCnt; axisId++ )
 
308
    {
 
309
        if ( axisEnabled(axisId) )
 
310
        {   
 
311
            const int niceDist = 40;
 
312
            const QwtScaleWidget *scaleWidget = axisWidget(axisId);
 
313
            const QwtScaleDiv &scaleDiv = scaleWidget->scaleDraw()->scaleDiv();
 
314
            const int majCnt = scaleDiv.ticks(QwtScaleDiv::MajorTick).count();
 
315
 
 
316
            if ( axisId == yLeft || axisId == yRight )
 
317
            {
 
318
                int hDiff = (majCnt - 1) * niceDist 
 
319
                    - scaleWidget->minimumSizeHint().height();
 
320
                if ( hDiff > dh )
 
321
                    dh = hDiff;
 
322
            }
 
323
            else
 
324
            {
 
325
                int wDiff = (majCnt - 1) * niceDist 
 
326
                    - scaleWidget->minimumSizeHint().width();
 
327
                if ( wDiff > dw )
 
328
                    dw = wDiff;
 
329
            }
 
330
        }
 
331
    }
 
332
    return minimumSizeHint() + QSize(dw, dh);
 
333
}
 
334
 
 
335
/*!
 
336
  \brief Return a minimum size hint
 
337
*/
 
338
QSize QwtPlot::minimumSizeHint() const
 
339
{
 
340
    QSize hint = d_data->layout->minimumSizeHint(this);
 
341
    hint += QSize(2 * frameWidth(), 2 * frameWidth());
 
342
 
 
343
    return hint;
 
344
}
 
345
 
 
346
//! Resize and update internal layout
 
347
void QwtPlot::resizeEvent(QResizeEvent *e)
 
348
{
 
349
    QFrame::resizeEvent(e);
 
350
    updateLayout();
 
351
}
 
352
 
 
353
/*!
 
354
  \brief Redraw the plot
 
355
 
 
356
  If the autoReplot option is not set (which is the default)
 
357
  or if any curves are attached to raw data, the plot has to
 
358
  be refreshed explicitly in order to make changes visible.
 
359
 
 
360
  \sa setAutoReplot()
 
361
  \warning Calls canvas()->repaint, take care of infinite recursions
 
362
*/
 
363
void QwtPlot::replot()
 
364
{
 
365
    bool doAutoReplot = autoReplot();
 
366
    setAutoReplot(false);
 
367
 
 
368
    updateAxes();
 
369
 
 
370
    /*
 
371
      Maybe the layout needs to be updated, because of changed
 
372
      axes labels. We need to process them here before painting
 
373
      to avoid that scales and canvas get out of sync.
 
374
     */
 
375
#if QT_VERSION >= 0x040000
 
376
    QApplication::sendPostedEvents(this, QEvent::LayoutRequest);
 
377
#else
 
378
    QApplication::sendPostedEvents(this, QEvent::LayoutHint);
 
379
#endif
 
380
 
 
381
    QwtPlotCanvas &canvas = *d_data->canvas;
 
382
 
 
383
    canvas.invalidatePaintCache();
 
384
 
 
385
    /*
 
386
      In case of cached or packed painting the canvas
 
387
      is repainted completely and doesn't need to be erased.
 
388
     */
 
389
    const bool erase = 
 
390
        !canvas.testPaintAttribute(QwtPlotCanvas::PaintPacked) 
 
391
        && !canvas.testPaintAttribute(QwtPlotCanvas::PaintCached);
 
392
 
 
393
#if QT_VERSION >= 0x040000
 
394
    const bool noBackgroundMode = canvas.testAttribute(Qt::WA_NoBackground);
 
395
    if ( !erase && !noBackgroundMode )
 
396
        canvas.setAttribute(Qt::WA_NoBackground, true);
 
397
 
 
398
    canvas.repaint(canvas.contentsRect());
 
399
 
 
400
    if ( !erase && !noBackgroundMode )
 
401
        canvas.setAttribute(Qt::WA_NoBackground, false);
 
402
#else
 
403
    canvas.repaint(canvas.contentsRect(), erase);
 
404
#endif
 
405
 
 
406
    setAutoReplot(doAutoReplot);
 
407
}
 
408
 
 
409
/*!
 
410
  \brief Adjust plot content to its current size.
 
411
  \sa resizeEvent()
 
412
*/
 
413
void QwtPlot::updateLayout()
 
414
{
 
415
    d_data->layout->activate(this, contentsRect());
 
416
 
 
417
    //
 
418
    // resize and show the visible widgets
 
419
    //
 
420
    if (!d_data->lblTitle->text().isEmpty())
 
421
    {
 
422
        d_data->lblTitle->setGeometry(d_data->layout->titleRect());
 
423
        if (!d_data->lblTitle->isVisible())
 
424
            d_data->lblTitle->show();
 
425
    }
 
426
    else
 
427
        d_data->lblTitle->hide();
 
428
 
 
429
    for (int axisId = 0; axisId < axisCnt; axisId++ )
 
430
    {
 
431
        if (axisEnabled(axisId) )
 
432
        {
 
433
            axisWidget(axisId)->setGeometry(d_data->layout->scaleRect(axisId));
 
434
 
 
435
            if ( axisId == xBottom || axisId == xTop )
 
436
            {
 
437
                QRegion r(d_data->layout->scaleRect(axisId));
 
438
                if ( axisEnabled(yLeft) )
 
439
                    r = r.subtract(QRegion(d_data->layout->scaleRect(yLeft)));
 
440
                if ( axisEnabled(yRight) )
 
441
                    r = r.subtract(QRegion(d_data->layout->scaleRect(yRight)));
 
442
                r.translate(-d_data->layout->scaleRect(axisId).x(), 
 
443
                    -d_data->layout->scaleRect(axisId).y());
 
444
 
 
445
                axisWidget(axisId)->setMask(r);
 
446
            }
 
447
            if (!axisWidget(axisId)->isVisible())
 
448
                axisWidget(axisId)->show();
 
449
        }
 
450
        else
 
451
            axisWidget(axisId)->hide();
 
452
    }
 
453
 
 
454
    if ( d_data->legend && 
 
455
        d_data->layout->legendPosition() != ExternalLegend )
 
456
    {
 
457
        if (d_data->legend->itemCount() > 0)
 
458
        {
 
459
            d_data->legend->setGeometry(d_data->layout->legendRect());
 
460
            d_data->legend->show();
 
461
        }
 
462
        else
 
463
            d_data->legend->hide();
 
464
    }
 
465
 
 
466
    d_data->canvas->setGeometry(d_data->layout->canvasRect());
 
467
}
 
468
 
 
469
/*! 
 
470
   Update the focus tab order
 
471
 
 
472
   The order is changed so that the canvas will be in front of the
 
473
   first legend item, or behind the last legend item - depending
 
474
   on the position of the legend.
 
475
*/
 
476
 
 
477
void QwtPlot::updateTabOrder()
 
478
{
 
479
#if QT_VERSION >= 0x040000
 
480
    using namespace Qt; // QWidget::NoFocus/Qt::NoFocus
 
481
#else
 
482
    if ( d_data->canvas->focusPolicy() == NoFocus )
 
483
        return;
 
484
#endif
 
485
    if ( d_data->legend.isNull()  
 
486
        || d_data->layout->legendPosition() == ExternalLegend
 
487
        || d_data->legend->legendItems().count() == 0 )
 
488
    {
 
489
        return;
 
490
    }
 
491
 
 
492
    // Depending on the position of the legend the 
 
493
    // tab order will be changed that the canvas is
 
494
    // next to the last legend item, or before
 
495
    // the first one. 
 
496
 
 
497
    const bool canvasFirst = 
 
498
        d_data->layout->legendPosition() == QwtPlot::BottomLegend ||
 
499
        d_data->layout->legendPosition() == QwtPlot::RightLegend;
 
500
 
 
501
    QWidget *previous = NULL; 
 
502
 
 
503
    QWidget *w;
 
504
#if QT_VERSION >= 0x040000
 
505
    w = d_data->canvas;
 
506
    while ( ( w = w->nextInFocusChain() ) != d_data->canvas )
 
507
#else
 
508
    if ( focusData() == NULL )
 
509
        return;
 
510
 
 
511
    while ( focusData()->next() != d_data->canvas );
 
512
    while ( (w = focusData()->next()) != d_data->canvas )
 
513
#endif
 
514
    {
 
515
        bool isLegendItem = false;
 
516
        if ( w->focusPolicy() != NoFocus 
 
517
            && w->parent() && w->parent() == d_data->legend->contentsWidget() )
 
518
        {
 
519
            isLegendItem = true;
 
520
        }
 
521
 
 
522
        if ( canvasFirst )
 
523
        {
 
524
            if ( isLegendItem )
 
525
                break;
 
526
 
 
527
            previous = w;
 
528
        }
 
529
        else
 
530
        {
 
531
            if ( isLegendItem )
 
532
                previous = w;
 
533
            else
 
534
            {
 
535
                if ( previous )
 
536
                    break;
 
537
            }
 
538
        }
 
539
    }
 
540
 
 
541
    if ( previous && previous != d_data->canvas)
 
542
        setTabOrder(previous, d_data->canvas);
 
543
}
 
544
 
 
545
/*! 
 
546
  Redraw the canvas.
 
547
  \param painter Painter used for drawing
 
548
 
 
549
  \warning drawCanvas calls drawItems what is also used
 
550
           for printing. Applications that like to add individual
 
551
           plot items better overload drawItems()
 
552
  \sa drawItems()
 
553
*/
 
554
void QwtPlot::drawCanvas(QPainter *painter)
 
555
{
 
556
    QwtScaleMap maps[axisCnt];
 
557
    for ( int axisId = 0; axisId < axisCnt; axisId++ )
 
558
        maps[axisId] = canvasMap(axisId);
 
559
 
 
560
    drawItems(painter, 
 
561
        d_data->canvas->contentsRect(), maps, QwtPlotPrintFilter());
 
562
}
 
563
 
 
564
/*! 
 
565
  Redraw the canvas items.
 
566
  \param painter Painter used for drawing
 
567
  \param rect Bounding rectangle where to paint
 
568
  \param map QwtPlot::axisCnt maps, mapping between plot and paint device coordinates
 
569
  \param pfilter Plot print filter
 
570
*/
 
571
 
 
572
void QwtPlot::drawItems(QPainter *painter, const QRect &rect, 
 
573
        const QwtScaleMap map[axisCnt], 
 
574
        const QwtPlotPrintFilter &pfilter) const
 
575
{
 
576
    const QwtPlotItemList& itmList = itemList();
 
577
    for ( QwtPlotItemIterator it = itmList.begin();
 
578
        it != itmList.end(); ++it )
 
579
    {
 
580
        QwtPlotItem *item = *it;
 
581
        if ( item && item->isVisible() )
 
582
        {
 
583
            if ( !(pfilter.options() & QwtPlotPrintFilter::PrintGrid)
 
584
                && item->rtti() == QwtPlotItem::Rtti_PlotGrid )
 
585
            {
 
586
                continue;
 
587
            }
 
588
 
 
589
            painter->save();
 
590
 
 
591
#if QT_VERSION >= 0x040000
 
592
            painter->setRenderHint(QPainter::Antialiasing,
 
593
                item->testRenderHint(QwtPlotItem::RenderAntialiased) );
 
594
#endif
 
595
 
 
596
            item->draw(painter, 
 
597
                map[item->xAxis()], map[item->yAxis()],
 
598
                rect);
 
599
 
 
600
            painter->restore();
 
601
        }
 
602
    }
 
603
}
 
604
 
 
605
/*!
 
606
  \param axisId Axis
 
607
  \return Map for the axis on the canvas. With this map pixel coordinates can
 
608
          translated to plot coordinates and vice versa.
 
609
  \sa QwtScaleMap, transform(), invTransform()
 
610
  
 
611
*/
 
612
QwtScaleMap QwtPlot::canvasMap(int axisId) const
 
613
{
 
614
    QwtScaleMap map;
 
615
    if ( !d_data->canvas )
 
616
        return map;
 
617
 
 
618
    map.setTransformation(axisScaleEngine(axisId)->transformation());
 
619
 
 
620
    const QwtScaleDiv *sd = axisScaleDiv(axisId);
 
621
    map.setScaleInterval(sd->lBound(), sd->hBound());
 
622
 
 
623
    if ( axisEnabled(axisId) )
 
624
    {
 
625
        const QwtScaleWidget *s = axisWidget(axisId);
 
626
        if ( axisId == yLeft || axisId == yRight )
 
627
        {
 
628
            int y = s->y() + s->startBorderDist() - d_data->canvas->y();
 
629
            int h = s->height() - s->startBorderDist() - s->endBorderDist();
 
630
            map.setPaintInterval(y + h, y);
 
631
        }
 
632
        else
 
633
        {
 
634
            int x = s->x() + s->startBorderDist() - d_data->canvas->x();
 
635
            int w = s->width() - s->startBorderDist() - s->endBorderDist();
 
636
            map.setPaintInterval(x, x + w);
 
637
        }
 
638
    }
 
639
    else
 
640
    {
 
641
        const int margin = plotLayout()->canvasMargin(axisId);
 
642
 
 
643
        const QRect &canvasRect = d_data->canvas->contentsRect();
 
644
        if ( axisId == yLeft || axisId == yRight )
 
645
        {
 
646
            map.setPaintInterval(canvasRect.bottom() - margin, 
 
647
                canvasRect.top() + margin);
 
648
        }
 
649
        else
 
650
        {
 
651
            map.setPaintInterval(canvasRect.left() + margin, 
 
652
                canvasRect.right() - margin);
 
653
        }
 
654
    }
 
655
    return map;
 
656
}
 
657
 
 
658
/*!
 
659
  Change the margin of the plot. The margin is the space
 
660
  around all components.
 
661
 
 
662
  \param margin new margin
 
663
  \sa QwtPlotLayout::setMargin(), margin(), plotLayout()
 
664
*/
 
665
void QwtPlot::setMargin(int margin)
 
666
{
 
667
    if ( margin < 0 )
 
668
        margin = 0;
 
669
 
 
670
    if ( margin != d_data->layout->margin() )
 
671
    {
 
672
        d_data->layout->setMargin(margin);
 
673
        updateLayout();
 
674
    }
 
675
}
 
676
 
 
677
/*!
 
678
    \return margin
 
679
    \sa setMargin(), QwtPlotLayout::margin(), plotLayout()
 
680
*/
 
681
int QwtPlot::margin() const
 
682
{
 
683
    return d_data->layout->margin();
 
684
}
 
685
 
 
686
/*!
 
687
  \brief Change the background of the plotting area
 
688
  
 
689
  Sets c to QColorGroup::Background of all colorgroups of 
 
690
  the palette of the canvas. Using canvas()->setPalette()
 
691
  is a more powerful way to set these colors.
 
692
  \param c new background color
 
693
*/
 
694
void QwtPlot::setCanvasBackground(const QColor &c)
 
695
{
 
696
    QPalette p = d_data->canvas->palette();
 
697
 
 
698
    for ( int i = 0; i < QPalette::NColorGroups; i++ )
 
699
    {
 
700
#if QT_VERSION < 0x040000
 
701
        p.setColor((QPalette::ColorGroup)i, QColorGroup::Background, c);
 
702
#else
 
703
        p.setColor((QPalette::ColorGroup)i, QPalette::Background, c);
 
704
#endif
 
705
    }
 
706
 
 
707
    canvas()->setPalette(p);
 
708
}
 
709
 
 
710
/*!
 
711
  Nothing else than: canvas()->palette().color(
 
712
        QPalette::Normal, QColorGroup::Background);
 
713
  
 
714
  \return the background color of the plotting area.
 
715
*/
 
716
const QColor & QwtPlot::canvasBackground() const
 
717
{
 
718
#if QT_VERSION < 0x040000
 
719
    return canvas()->palette().color(
 
720
        QPalette::Normal, QColorGroup::Background);
 
721
#else
 
722
    return canvas()->palette().color(
 
723
        QPalette::Normal, QPalette::Background);
 
724
#endif
 
725
}
 
726
 
 
727
/*!
 
728
  \brief Change the border width of the plotting area
 
729
  Nothing else than canvas()->setLineWidth(w), 
 
730
  left for compatibility only.
 
731
  \param w new border width
 
732
*/
 
733
void QwtPlot::setCanvasLineWidth(int w)
 
734
{
 
735
    canvas()->setLineWidth(w);
 
736
    updateLayout();
 
737
}
 
738
 
 
739
/*! 
 
740
  Nothing else than: canvas()->lineWidth(), 
 
741
  left for compatibility only.
 
742
  \return the border width of the plotting area
 
743
*/
 
744
int QwtPlot::canvasLineWidth() const
 
745
 
746
    return canvas()->lineWidth();
 
747
}
 
748
 
 
749
/*!
 
750
  \return \c true if the specified axis exists, otherwise \c false
 
751
  \param axisId axis index
 
752
 */
 
753
bool QwtPlot::axisValid(int axisId)
 
754
{
 
755
    return ((axisId >= QwtPlot::yLeft) && (axisId < QwtPlot::axisCnt));
 
756
}
 
757
 
 
758
/*!
 
759
  Called internally when the legend has been clicked on.
 
760
  Emits a legendClicked() signal.
 
761
*/
 
762
void QwtPlot::legendItemClicked()
 
763
{
 
764
    if ( d_data->legend && sender()->isWidgetType() )
 
765
    {
 
766
        QwtPlotItem *plotItem = 
 
767
            (QwtPlotItem*)d_data->legend->find((QWidget *)sender());
 
768
        if ( plotItem )
 
769
            emit legendClicked(plotItem);
 
770
    }
 
771
}
 
772
 
 
773
/*!
 
774
  Called internally when the legend has been checked
 
775
  Emits a legendClicked() signal.
 
776
*/
 
777
void QwtPlot::legendItemChecked(bool on)
 
778
{
 
779
    if ( d_data->legend && sender()->isWidgetType() )
 
780
    {
 
781
        QwtPlotItem *plotItem = 
 
782
            (QwtPlotItem*)d_data->legend->find((QWidget *)sender());
 
783
        if ( plotItem )
 
784
            emit legendChecked(plotItem, on);
 
785
    }
 
786
}
 
787
 
 
788
//! Remove all curves and markers
 
789
void QwtPlot::clear()
 
790
{
 
791
    detachItems(QwtPlotItem::Rtti_PlotCurve);
 
792
    detachItems(QwtPlotItem::Rtti_PlotMarker);
 
793
}
 
794
 
 
795
/*!
 
796
  \brief Insert a legend
 
797
 
 
798
  If the position legend is \c QwtPlot::LeftLegend or \c QwtPlot::RightLegend
 
799
  the legend will be organized in one column from top to down. 
 
800
  Otherwise the legend items will be placed in a table 
 
801
  with a best fit number of columns from left to right.
 
802
 
 
803
  If pos != QwtPlot::ExternalLegend the plot widget will become 
 
804
  parent of the legend. It will be deleted when the plot is deleted, 
 
805
  or another legend is set with insertLegend().
 
806
       
 
807
  \param legend Legend
 
808
  \param pos The legend's position. For top/left position the number
 
809
             of colums will be limited to 1, otherwise it will be set to
 
810
             unlimited. 
 
811
 
 
812
  \param ratio Ratio between legend and the bounding rect
 
813
               of title, canvas and axes. The legend will be shrinked
 
814
               if it would need more space than the given ratio.
 
815
               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
 
816
               it will be reset to the default ratio.
 
817
               The default vertical/horizontal ratio is 0.33/0.5.
 
818
 
 
819
  \sa legend(), QwtPlotLayout::legendPosition(), 
 
820
      QwtPlotLayout::setLegendPosition()
 
821
*/
 
822
void QwtPlot::insertLegend(QwtLegend *legend, 
 
823
    QwtPlot::LegendPosition pos, double ratio)
 
824
{
 
825
    d_data->layout->setLegendPosition(pos, ratio);
 
826
 
 
827
    if ( legend != d_data->legend )
 
828
    {
 
829
        if ( d_data->legend && d_data->legend->parent() == this )
 
830
            delete d_data->legend;
 
831
 
 
832
        d_data->legend = legend;
 
833
 
 
834
        if ( d_data->legend )
 
835
        {
 
836
            if ( pos != ExternalLegend )
 
837
            {
 
838
                if ( d_data->legend->parent() != this )
 
839
                {
 
840
#if QT_VERSION < 0x040000
 
841
                    d_data->legend->reparent(this, QPoint(0, 0));
 
842
#else
 
843
                    d_data->legend->setParent(this);
 
844
#endif
 
845
                }
 
846
            }
 
847
 
 
848
            const QwtPlotItemList& itmList = itemList();
 
849
            for ( QwtPlotItemIterator it = itmList.begin();
 
850
                it != itmList.end(); ++it )
 
851
            {
 
852
                (*it)->updateLegend(d_data->legend);
 
853
            }
 
854
 
 
855
            QLayout *l = d_data->legend->contentsWidget()->layout();
 
856
            if ( l && l->inherits("QwtDynGridLayout") )
 
857
            {
 
858
                QwtDynGridLayout *tl = (QwtDynGridLayout *)l;
 
859
                switch(d_data->layout->legendPosition())
 
860
                {
 
861
                    case LeftLegend:
 
862
                    case RightLegend:
 
863
                        tl->setMaxCols(1); // 1 column: align vertical
 
864
                        break;
 
865
                    case TopLegend:
 
866
                    case BottomLegend:
 
867
                        tl->setMaxCols(0); // unlimited
 
868
                        break;
 
869
                    case ExternalLegend:
 
870
                        break;
 
871
                }
 
872
            }
 
873
        }
 
874
        updateTabOrder();
 
875
    }
 
876
 
 
877
    updateLayout();
 
878
}