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

« back to all changes in this revision

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