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