##// END OF EJS Templates
fix: legend detaching/attaching now invalidates chart layout
sauimone -
r2392:ca970450e5ca
parent child
Show More
@@ -1,594 +1,596
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qlegend.h"
21 #include "qlegend.h"
22 #include "qlegend_p.h"
22 #include "qlegend_p.h"
23 #include "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26 #include "legendlayout_p.h"
26 #include "legendlayout_p.h"
27 #include "chartpresenter_p.h"
27 #include "chartpresenter_p.h"
28 #include "chartlayout_p.h"
28 #include "chartlayout_p.h"
29 #include "qlegendmarker.h"
29 #include "qlegendmarker.h"
30 #include "qlegendmarker_p.h"
30 #include "qlegendmarker_p.h"
31 #include "legendmarkeritem_p.h"
31 #include "legendmarkeritem_p.h"
32 #include "chartdataset_p.h"
32 #include "chartdataset_p.h"
33 #include <QPainter>
33 #include <QPainter>
34 #include <QPen>
34 #include <QPen>
35 #include <QGraphicsItemGroup>
35 #include <QGraphicsItemGroup>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 /*!
39 /*!
40 \class QLegend
40 \class QLegend
41 \brief Legend object
41 \brief Legend object
42 \mainclass
42 \mainclass
43
43
44 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
44 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
45 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
45 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
46 handle the drawing manually.
46 handle the drawing manually.
47 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
47 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
48
48
49 \image examples_percentbarchart_legend.png
49 \image examples_percentbarchart_legend.png
50
50
51 \sa QChart
51 \sa QChart
52 */
52 */
53 /*!
53 /*!
54 \qmlclass Legend QLegend
54 \qmlclass Legend QLegend
55 \brief Legend is part of QtCommercial Chart QML API.
55 \brief Legend is part of QtCommercial Chart QML API.
56
56
57 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
57 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
58 series have been changed. Legend is used via ChartView class. For example:
58 series have been changed. Legend is used via ChartView class. For example:
59 \code
59 \code
60 ChartView {
60 ChartView {
61 legend.visible: true
61 legend.visible: true
62 legend.alignment: Qt.AlignBottom
62 legend.alignment: Qt.AlignBottom
63 // Add a few series...
63 // Add a few series...
64 }
64 }
65 \endcode
65 \endcode
66
66
67 \image examples_percentbarchart_legend.png
67 \image examples_percentbarchart_legend.png
68
68
69 Please note that there is no QML API available for modifying legend markers, unlike in the Qt API of Charts.
69 Please note that there is no QML API available for modifying legend markers, unlike in the Qt API of Charts.
70 The use case of modifying markers can be implemented for example by creating your own custom legend. For an example
70 The use case of modifying markers can be implemented for example by creating your own custom legend. For an example
71 on how to do this, see \l {demos/qmlcustomlegend}{Qml Custom Demo} application.
71 on how to do this, see \l {demos/qmlcustomlegend}{Qml Custom Demo} application.
72 */
72 */
73
73
74 /*!
74 /*!
75 \property QLegend::alignment
75 \property QLegend::alignment
76 \brief The alignment of the legend.
76 \brief The alignment of the legend.
77
77
78 Legend paints on the defined position in the chart. The following alignments are supported:
78 Legend paints on the defined position in the chart. The following alignments are supported:
79 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
79 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
80 */
80 */
81 /*!
81 /*!
82 \qmlproperty Qt.Alignment Legend::alignment
82 \qmlproperty Qt.Alignment Legend::alignment
83 \brief The alignment of the legend.
83 \brief The alignment of the legend.
84
84
85 Legend paints on the defined position in the chart. The following alignments are supported:
85 Legend paints on the defined position in the chart. The following alignments are supported:
86 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
86 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
87 */
87 */
88
88
89 /*!
89 /*!
90 \property QLegend::backgroundVisible
90 \property QLegend::backgroundVisible
91 Whether the legend background is visible or not.
91 Whether the legend background is visible or not.
92 */
92 */
93 /*!
93 /*!
94 \qmlproperty bool Legend::backgroundVisible
94 \qmlproperty bool Legend::backgroundVisible
95 Whether the legend background is visible or not.
95 Whether the legend background is visible or not.
96 */
96 */
97
97
98 /*!
98 /*!
99 \property QLegend::color
99 \property QLegend::color
100 The color of the legend, i.e. the background (brush) color. Note that if you change the color
100 The color of the legend, i.e. the background (brush) color. Note that if you change the color
101 of the legend, the style of the legend brush is set to Qt::SolidPattern.
101 of the legend, the style of the legend brush is set to Qt::SolidPattern.
102 */
102 */
103 /*!
103 /*!
104 \qmlproperty color Legend::color
104 \qmlproperty color Legend::color
105 The color of the legend, i.e. the background (brush) color.
105 The color of the legend, i.e. the background (brush) color.
106 */
106 */
107
107
108 /*!
108 /*!
109 \property QLegend::borderColor
109 \property QLegend::borderColor
110 The border color of the legend, i.e. the line color.
110 The border color of the legend, i.e. the line color.
111 */
111 */
112 /*!
112 /*!
113 \qmlproperty color Legend::borderColor
113 \qmlproperty color Legend::borderColor
114 The border color of the legend, i.e. the line color.
114 The border color of the legend, i.e. the line color.
115 */
115 */
116
116
117 /*!
117 /*!
118 \property QLegend::font
118 \property QLegend::font
119 The font of markers used by legend
119 The font of markers used by legend
120 */
120 */
121 /*!
121 /*!
122 \qmlproperty Font Legend::font
122 \qmlproperty Font Legend::font
123 The font of markers used by legend
123 The font of markers used by legend
124 */
124 */
125
125
126 /*!
126 /*!
127 \property QLegend::labelColor
127 \property QLegend::labelColor
128 The color of brush used to draw labels.
128 The color of brush used to draw labels.
129 */
129 */
130 /*!
130 /*!
131 \qmlproperty color QLegend::labelColor
131 \qmlproperty color QLegend::labelColor
132 The color of brush used to draw labels.
132 The color of brush used to draw labels.
133 */
133 */
134
134
135 /*!
135 /*!
136 \fn void QLegend::backgroundVisibleChanged(bool)
136 \fn void QLegend::backgroundVisibleChanged(bool)
137 The visibility of the legend background changed to \a visible.
137 The visibility of the legend background changed to \a visible.
138 */
138 */
139
139
140 /*!
140 /*!
141 \fn void QLegend::colorChanged(QColor)
141 \fn void QLegend::colorChanged(QColor)
142 The color of the legend background changed to \a color.
142 The color of the legend background changed to \a color.
143 */
143 */
144
144
145 /*!
145 /*!
146 \fn void QLegend::borderColorChanged(QColor)
146 \fn void QLegend::borderColorChanged(QColor)
147 The border color of the legend background changed to \a color.
147 The border color of the legend background changed to \a color.
148 */
148 */
149
149
150 /*!
150 /*!
151 \fn void QLegend::fontChanged(QFont)
151 \fn void QLegend::fontChanged(QFont)
152 The font of markers of the legend changed to \a font.
152 The font of markers of the legend changed to \a font.
153 */
153 */
154
154
155 /*!
155 /*!
156 \fn void QLegend::labelColorChanged(QColor color)
156 \fn void QLegend::labelColorChanged(QColor color)
157 This signal is emitted when the color of brush used to draw labels has changed to \a color.
157 This signal is emitted when the color of brush used to draw labels has changed to \a color.
158 */
158 */
159
159
160 QLegend::QLegend(QChart *chart): QGraphicsWidget(chart),
160 QLegend::QLegend(QChart *chart): QGraphicsWidget(chart),
161 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter, chart, this))
161 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter, chart, this))
162 {
162 {
163 setZValue(ChartPresenter::LegendZValue);
163 setZValue(ChartPresenter::LegendZValue);
164 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
164 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
165 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesAdded(QAbstractSeries*)));
165 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesAdded(QAbstractSeries*)));
166 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesRemoved(QAbstractSeries*)));
166 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesRemoved(QAbstractSeries*)));
167 setLayout(d_ptr->m_layout);
167 setLayout(d_ptr->m_layout);
168 }
168 }
169
169
170 /*!
170 /*!
171 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
171 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
172 */
172 */
173 QLegend::~QLegend()
173 QLegend::~QLegend()
174 {
174 {
175 }
175 }
176
176
177 /*!
177 /*!
178 \internal
178 \internal
179 */
179 */
180 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
180 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
181 {
181 {
182 Q_UNUSED(option)
182 Q_UNUSED(option)
183 Q_UNUSED(widget)
183 Q_UNUSED(widget)
184
184
185 if (!d_ptr->m_backgroundVisible)
185 if (!d_ptr->m_backgroundVisible)
186 return;
186 return;
187
187
188 painter->setOpacity(opacity());
188 painter->setOpacity(opacity());
189 painter->setPen(d_ptr->m_pen);
189 painter->setPen(d_ptr->m_pen);
190 painter->setBrush(d_ptr->m_brush);
190 painter->setBrush(d_ptr->m_brush);
191 painter->drawRoundRect(rect(), d_ptr->roundness(rect().width()), d_ptr->roundness(rect().height()));
191 painter->drawRoundRect(rect(), d_ptr->roundness(rect().width()), d_ptr->roundness(rect().height()));
192 }
192 }
193
193
194
194
195 /*!
195 /*!
196 Sets the \a brush of legend. Brush affects the background of legend.
196 Sets the \a brush of legend. Brush affects the background of legend.
197 */
197 */
198 void QLegend::setBrush(const QBrush &brush)
198 void QLegend::setBrush(const QBrush &brush)
199 {
199 {
200 if (d_ptr->m_brush != brush) {
200 if (d_ptr->m_brush != brush) {
201 d_ptr->m_brush = brush;
201 d_ptr->m_brush = brush;
202 update();
202 update();
203 emit colorChanged(brush.color());
203 emit colorChanged(brush.color());
204 }
204 }
205 }
205 }
206
206
207 /*!
207 /*!
208 Returns the brush used by legend.
208 Returns the brush used by legend.
209 */
209 */
210 QBrush QLegend::brush() const
210 QBrush QLegend::brush() const
211 {
211 {
212 return d_ptr->m_brush;
212 return d_ptr->m_brush;
213 }
213 }
214
214
215 void QLegend::setColor(QColor color)
215 void QLegend::setColor(QColor color)
216 {
216 {
217 QBrush b = d_ptr->m_brush;
217 QBrush b = d_ptr->m_brush;
218 if (b.style() != Qt::SolidPattern || b.color() != color) {
218 if (b.style() != Qt::SolidPattern || b.color() != color) {
219 b.setStyle(Qt::SolidPattern);
219 b.setStyle(Qt::SolidPattern);
220 b.setColor(color);
220 b.setColor(color);
221 setBrush(b);
221 setBrush(b);
222 }
222 }
223 }
223 }
224
224
225 QColor QLegend::color()
225 QColor QLegend::color()
226 {
226 {
227 return d_ptr->m_brush.color();
227 return d_ptr->m_brush.color();
228 }
228 }
229
229
230 /*!
230 /*!
231 Sets the \a pen of legend. Pen affects the legend borders.
231 Sets the \a pen of legend. Pen affects the legend borders.
232 */
232 */
233 void QLegend::setPen(const QPen &pen)
233 void QLegend::setPen(const QPen &pen)
234 {
234 {
235 if (d_ptr->m_pen != pen) {
235 if (d_ptr->m_pen != pen) {
236 d_ptr->m_pen = pen;
236 d_ptr->m_pen = pen;
237 update();
237 update();
238 emit borderColorChanged(pen.color());
238 emit borderColorChanged(pen.color());
239 }
239 }
240 }
240 }
241
241
242 /*!
242 /*!
243 Returns the pen used by legend
243 Returns the pen used by legend
244 */
244 */
245
245
246 QPen QLegend::pen() const
246 QPen QLegend::pen() const
247 {
247 {
248 return d_ptr->m_pen;
248 return d_ptr->m_pen;
249 }
249 }
250
250
251 void QLegend::setFont(const QFont &font)
251 void QLegend::setFont(const QFont &font)
252 {
252 {
253 if (d_ptr->m_font != font) {
253 if (d_ptr->m_font != font) {
254 d_ptr->m_font = font;
254 d_ptr->m_font = font;
255 foreach (QLegendMarker *marker, d_ptr->markers()) {
255 foreach (QLegendMarker *marker, d_ptr->markers()) {
256 marker->setFont(d_ptr->m_font);
256 marker->setFont(d_ptr->m_font);
257 }
257 }
258 layout()->invalidate();
258 layout()->invalidate();
259 emit fontChanged(font);
259 emit fontChanged(font);
260 }
260 }
261 }
261 }
262
262
263 QFont QLegend::font() const
263 QFont QLegend::font() const
264 {
264 {
265 return d_ptr->m_font;
265 return d_ptr->m_font;
266 }
266 }
267
267
268 void QLegend::setBorderColor(QColor color)
268 void QLegend::setBorderColor(QColor color)
269 {
269 {
270 QPen p = d_ptr->m_pen;
270 QPen p = d_ptr->m_pen;
271 if (p.color() != color) {
271 if (p.color() != color) {
272 p.setColor(color);
272 p.setColor(color);
273 setPen(p);
273 setPen(p);
274 }
274 }
275 }
275 }
276
276
277 QColor QLegend::borderColor()
277 QColor QLegend::borderColor()
278 {
278 {
279 return d_ptr->m_pen.color();
279 return d_ptr->m_pen.color();
280 }
280 }
281
281
282 /*!
282 /*!
283 Set brush used to draw labels to \a brush.
283 Set brush used to draw labels to \a brush.
284 */
284 */
285 void QLegend::setLabelBrush(const QBrush &brush)
285 void QLegend::setLabelBrush(const QBrush &brush)
286 {
286 {
287 if (d_ptr->m_labelBrush != brush) {
287 if (d_ptr->m_labelBrush != brush) {
288 d_ptr->m_labelBrush = brush;
288 d_ptr->m_labelBrush = brush;
289 foreach (QLegendMarker *marker, d_ptr->markers()) {
289 foreach (QLegendMarker *marker, d_ptr->markers()) {
290 marker->setLabelBrush(d_ptr->m_labelBrush);
290 marker->setLabelBrush(d_ptr->m_labelBrush);
291 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
291 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
292 // instead of mapping it from label brush color
292 // instead of mapping it from label brush color
293 marker->setPen(brush.color());
293 marker->setPen(brush.color());
294 }
294 }
295 emit labelColorChanged(brush.color());
295 emit labelColorChanged(brush.color());
296 }
296 }
297 }
297 }
298
298
299 /*!
299 /*!
300 Brush used to draw labels.
300 Brush used to draw labels.
301 */
301 */
302 QBrush QLegend::labelBrush() const
302 QBrush QLegend::labelBrush() const
303 {
303 {
304 return d_ptr->m_labelBrush;
304 return d_ptr->m_labelBrush;
305 }
305 }
306
306
307 void QLegend::setLabelColor(QColor color)
307 void QLegend::setLabelColor(QColor color)
308 {
308 {
309 QBrush b = d_ptr->m_labelBrush;
309 QBrush b = d_ptr->m_labelBrush;
310 if (b.style() != Qt::SolidPattern || b.color() != color) {
310 if (b.style() != Qt::SolidPattern || b.color() != color) {
311 b.setStyle(Qt::SolidPattern);
311 b.setStyle(Qt::SolidPattern);
312 b.setColor(color);
312 b.setColor(color);
313 setLabelBrush(b);
313 setLabelBrush(b);
314 }
314 }
315 }
315 }
316
316
317 QColor QLegend::labelColor() const
317 QColor QLegend::labelColor() const
318 {
318 {
319 return d_ptr->m_labelBrush.color();
319 return d_ptr->m_labelBrush.color();
320 }
320 }
321
321
322
322
323 void QLegend::setAlignment(Qt::Alignment alignment)
323 void QLegend::setAlignment(Qt::Alignment alignment)
324 {
324 {
325 if (d_ptr->m_alignment != alignment) {
325 if (d_ptr->m_alignment != alignment) {
326 d_ptr->m_alignment = alignment;
326 d_ptr->m_alignment = alignment;
327 layout()->invalidate();
327 layout()->invalidate();
328 }
328 }
329 }
329 }
330
330
331 Qt::Alignment QLegend::alignment() const
331 Qt::Alignment QLegend::alignment() const
332 {
332 {
333 return d_ptr->m_alignment;
333 return d_ptr->m_alignment;
334 }
334 }
335
335
336 /*!
336 /*!
337 Detaches the legend from chart. Chart won't change layout of the legend.
337 Detaches the legend from chart. Chart won't change layout of the legend.
338 */
338 */
339 void QLegend::detachFromChart()
339 void QLegend::detachFromChart()
340 {
340 {
341 d_ptr->m_attachedToChart = false;
341 d_ptr->m_attachedToChart = false;
342 layout()->invalidate();
342 // layout()->invalidate();
343 d_ptr->m_chart->layout()->invalidate();
343 setParent(0);
344 setParent(0);
344
345
345 }
346 }
346
347
347 /*!
348 /*!
348 Attaches the legend to chart. Chart may change layout of the legend.
349 Attaches the legend to chart. Chart may change layout of the legend.
349 */
350 */
350 void QLegend::attachToChart()
351 void QLegend::attachToChart()
351 {
352 {
352 d_ptr->m_attachedToChart = true;
353 d_ptr->m_attachedToChart = true;
353 layout()->invalidate();
354 // layout()->invalidate();
355 d_ptr->m_chart->layout()->invalidate();
354 setParent(d_ptr->m_chart);
356 setParent(d_ptr->m_chart);
355 }
357 }
356
358
357 /*!
359 /*!
358 Returns true, if legend is attached to chart.
360 Returns true, if legend is attached to chart.
359 */
361 */
360 bool QLegend::isAttachedToChart()
362 bool QLegend::isAttachedToChart()
361 {
363 {
362 return d_ptr->m_attachedToChart;
364 return d_ptr->m_attachedToChart;
363 }
365 }
364
366
365 /*!
367 /*!
366 Sets the visibility of legend background to \a visible
368 Sets the visibility of legend background to \a visible
367 */
369 */
368 void QLegend::setBackgroundVisible(bool visible)
370 void QLegend::setBackgroundVisible(bool visible)
369 {
371 {
370 if (d_ptr->m_backgroundVisible != visible) {
372 if (d_ptr->m_backgroundVisible != visible) {
371 d_ptr->m_backgroundVisible = visible;
373 d_ptr->m_backgroundVisible = visible;
372 update();
374 update();
373 emit backgroundVisibleChanged(visible);
375 emit backgroundVisibleChanged(visible);
374 }
376 }
375 }
377 }
376
378
377 /*!
379 /*!
378 Returns the visibility of legend background
380 Returns the visibility of legend background
379 */
381 */
380 bool QLegend::isBackgroundVisible() const
382 bool QLegend::isBackgroundVisible() const
381 {
383 {
382 return d_ptr->m_backgroundVisible;
384 return d_ptr->m_backgroundVisible;
383 }
385 }
384
386
385 /*!
387 /*!
386 Returns the list of markers in legend. The list can be filtered with \a series parameter.
388 Returns the list of markers in legend. The list can be filtered with \a series parameter.
387 If \a series is given, only markers related to that series are returned.
389 If \a series is given, only markers related to that series are returned.
388 */
390 */
389 QList<QLegendMarker*> QLegend::markers(QAbstractSeries *series) const
391 QList<QLegendMarker*> QLegend::markers(QAbstractSeries *series) const
390 {
392 {
391 return d_ptr->markers(series);
393 return d_ptr->markers(series);
392 }
394 }
393
395
394 /*!
396 /*!
395 \internal \a event see QGraphicsWidget for details
397 \internal \a event see QGraphicsWidget for details
396 */
398 */
397 void QLegend::hideEvent(QHideEvent *event)
399 void QLegend::hideEvent(QHideEvent *event)
398 {
400 {
399 if (isAttachedToChart())
401 if (isAttachedToChart())
400 d_ptr->m_presenter->layout()->invalidate();
402 d_ptr->m_presenter->layout()->invalidate();
401 QGraphicsWidget::hideEvent(event);
403 QGraphicsWidget::hideEvent(event);
402 }
404 }
403 /*!
405 /*!
404 \internal \a event see QGraphicsWidget for details
406 \internal \a event see QGraphicsWidget for details
405 */
407 */
406 void QLegend::showEvent(QShowEvent *event)
408 void QLegend::showEvent(QShowEvent *event)
407 {
409 {
408 if (isAttachedToChart()) {
410 if (isAttachedToChart()) {
409 d_ptr->items()->setVisible(false);
411 d_ptr->items()->setVisible(false);
410 layout()->invalidate();
412 layout()->invalidate();
411 }
413 }
412 QGraphicsWidget::showEvent(event);
414 QGraphicsWidget::showEvent(event);
413 //layout activation will show the items
415 //layout activation will show the items
414 }
416 }
415
417
416 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
418 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
417
419
418 QLegendPrivate::QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q)
420 QLegendPrivate::QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q)
419 : q_ptr(q),
421 : q_ptr(q),
420 m_presenter(presenter),
422 m_presenter(presenter),
421 m_layout(new LegendLayout(q)),
423 m_layout(new LegendLayout(q)),
422 m_chart(chart),
424 m_chart(chart),
423 m_items(new QGraphicsItemGroup(q)),
425 m_items(new QGraphicsItemGroup(q)),
424 m_alignment(Qt::AlignTop),
426 m_alignment(Qt::AlignTop),
425 m_brush(QBrush()),
427 m_brush(QBrush()),
426 m_pen(QPen()),
428 m_pen(QPen()),
427 m_labelBrush(QBrush()),
429 m_labelBrush(QBrush()),
428 m_diameter(5),
430 m_diameter(5),
429 m_attachedToChart(true),
431 m_attachedToChart(true),
430 m_backgroundVisible(false)
432 m_backgroundVisible(false)
431 {
433 {
432 m_items->setHandlesChildEvents(false);
434 m_items->setHandlesChildEvents(false);
433 }
435 }
434
436
435 QLegendPrivate::~QLegendPrivate()
437 QLegendPrivate::~QLegendPrivate()
436 {
438 {
437
439
438 }
440 }
439
441
440 void QLegendPrivate::setOffset(const QPointF &offset)
442 void QLegendPrivate::setOffset(const QPointF &offset)
441 {
443 {
442 m_layout->setOffset(offset.x(), offset.y());
444 m_layout->setOffset(offset.x(), offset.y());
443 }
445 }
444
446
445 QPointF QLegendPrivate::offset() const
447 QPointF QLegendPrivate::offset() const
446 {
448 {
447 return m_layout->offset();
449 return m_layout->offset();
448 }
450 }
449
451
450 int QLegendPrivate::roundness(qreal size)
452 int QLegendPrivate::roundness(qreal size)
451 {
453 {
452 return 100 * m_diameter / int(size);
454 return 100 * m_diameter / int(size);
453 }
455 }
454
456
455 QList<QLegendMarker*> QLegendPrivate::markers(QAbstractSeries *series)
457 QList<QLegendMarker*> QLegendPrivate::markers(QAbstractSeries *series)
456 {
458 {
457 // Return all markers
459 // Return all markers
458 if (!series) {
460 if (!series) {
459 return m_markers;
461 return m_markers;
460 }
462 }
461
463
462 // Create filtered list
464 // Create filtered list
463 QList<QLegendMarker *> markers;
465 QList<QLegendMarker *> markers;
464 foreach (QLegendMarker *marker, m_markers) {
466 foreach (QLegendMarker *marker, m_markers) {
465 if (marker->series() == series) {
467 if (marker->series() == series) {
466 markers.append(marker);
468 markers.append(marker);
467 }
469 }
468 }
470 }
469 return markers;
471 return markers;
470 }
472 }
471
473
472 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series)
474 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series)
473 {
475 {
474 if (m_series.contains(series)) {
476 if (m_series.contains(series)) {
475 return;
477 return;
476 }
478 }
477
479
478 QList<QLegendMarker*> newMarkers = series->d_ptr->createLegendMarkers(q_ptr);
480 QList<QLegendMarker*> newMarkers = series->d_ptr->createLegendMarkers(q_ptr);
479 decorateMarkers(newMarkers);
481 decorateMarkers(newMarkers);
480 addMarkers(newMarkers);
482 addMarkers(newMarkers);
481
483
482 QObject::connect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
484 QObject::connect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
483 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
485 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
484
486
485 m_series.append(series);
487 m_series.append(series);
486 m_items->setVisible(false);
488 m_items->setVisible(false);
487 m_layout->invalidate();
489 m_layout->invalidate();
488 }
490 }
489
491
490 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
492 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
491 {
493 {
492 if (m_series.contains(series)) {
494 if (m_series.contains(series)) {
493 m_series.removeOne(series);
495 m_series.removeOne(series);
494 }
496 }
495
497
496 // Find out, which markers to remove
498 // Find out, which markers to remove
497 QList<QLegendMarker *> removed;
499 QList<QLegendMarker *> removed;
498 foreach (QLegendMarker *m, m_markers) {
500 foreach (QLegendMarker *m, m_markers) {
499 if (m->series() == series) {
501 if (m->series() == series) {
500 removed << m;
502 removed << m;
501 }
503 }
502 }
504 }
503 removeMarkers(removed);
505 removeMarkers(removed);
504
506
505 QObject::disconnect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
507 QObject::disconnect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
506 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
508 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
507
509
508 m_layout->invalidate();
510 m_layout->invalidate();
509 }
511 }
510
512
511 void QLegendPrivate::handleSeriesVisibleChanged()
513 void QLegendPrivate::handleSeriesVisibleChanged()
512 {
514 {
513 QAbstractSeries *series = qobject_cast<QAbstractSeries *> (sender());
515 QAbstractSeries *series = qobject_cast<QAbstractSeries *> (sender());
514 Q_ASSERT(series);
516 Q_ASSERT(series);
515
517
516 foreach (QLegendMarker *marker, m_markers) {
518 foreach (QLegendMarker *marker, m_markers) {
517 if (marker->series() == series) {
519 if (marker->series() == series) {
518 marker->setVisible(series->isVisible());
520 marker->setVisible(series->isVisible());
519 }
521 }
520 }
522 }
521 m_layout->invalidate();
523 m_layout->invalidate();
522 }
524 }
523
525
524 void QLegendPrivate::handleCountChanged()
526 void QLegendPrivate::handleCountChanged()
525 {
527 {
526 // Here we handle the changes in marker count.
528 // Here we handle the changes in marker count.
527 // Can happen for example when pieslice(s) have been added to or removed from pieseries.
529 // Can happen for example when pieslice(s) have been added to or removed from pieseries.
528
530
529 QAbstractSeriesPrivate *series = qobject_cast<QAbstractSeriesPrivate *> (sender());
531 QAbstractSeriesPrivate *series = qobject_cast<QAbstractSeriesPrivate *> (sender());
530 QList<QLegendMarker *> createdMarkers = series->createLegendMarkers(q_ptr);
532 QList<QLegendMarker *> createdMarkers = series->createLegendMarkers(q_ptr);
531
533
532 // Find out removed markers and created markers
534 // Find out removed markers and created markers
533 QList<QLegendMarker *> removedMarkers;
535 QList<QLegendMarker *> removedMarkers;
534 foreach (QLegendMarker *oldMarker, m_markers) {
536 foreach (QLegendMarker *oldMarker, m_markers) {
535 // we have marker, which is related to sender.
537 // we have marker, which is related to sender.
536 if (oldMarker->series() == series->q_ptr) {
538 if (oldMarker->series() == series->q_ptr) {
537 bool found = false;
539 bool found = false;
538 foreach(QLegendMarker *newMarker, createdMarkers) {
540 foreach(QLegendMarker *newMarker, createdMarkers) {
539 // New marker considered existing if:
541 // New marker considered existing if:
540 // - d_ptr->relatedObject() is same for both markers.
542 // - d_ptr->relatedObject() is same for both markers.
541 if (newMarker->d_ptr->relatedObject() == oldMarker->d_ptr->relatedObject()) {
543 if (newMarker->d_ptr->relatedObject() == oldMarker->d_ptr->relatedObject()) {
542 // Delete the new marker, since we already have existing marker, that might be connected on user side.
544 // Delete the new marker, since we already have existing marker, that might be connected on user side.
543 found = true;
545 found = true;
544 createdMarkers.removeOne(newMarker);
546 createdMarkers.removeOne(newMarker);
545 delete newMarker;
547 delete newMarker;
546 }
548 }
547 }
549 }
548 if (!found) {
550 if (!found) {
549 // No related object found for marker, add to removedMarkers list
551 // No related object found for marker, add to removedMarkers list
550 removedMarkers << oldMarker;
552 removedMarkers << oldMarker;
551 }
553 }
552 }
554 }
553 }
555 }
554
556
555 removeMarkers(removedMarkers);
557 removeMarkers(removedMarkers);
556 decorateMarkers(createdMarkers);
558 decorateMarkers(createdMarkers);
557 addMarkers(createdMarkers);
559 addMarkers(createdMarkers);
558
560
559 q_ptr->layout()->invalidate();
561 q_ptr->layout()->invalidate();
560 }
562 }
561
563
562 void QLegendPrivate::addMarkers(QList<QLegendMarker *> markers)
564 void QLegendPrivate::addMarkers(QList<QLegendMarker *> markers)
563 {
565 {
564 foreach (QLegendMarker *marker, markers) {
566 foreach (QLegendMarker *marker, markers) {
565 m_items->addToGroup(marker->d_ptr.data()->item());
567 m_items->addToGroup(marker->d_ptr.data()->item());
566 m_markers << marker;
568 m_markers << marker;
567 m_markerHash.insert(marker->d_ptr->item(), marker);
569 m_markerHash.insert(marker->d_ptr->item(), marker);
568 }
570 }
569 }
571 }
570
572
571 void QLegendPrivate::removeMarkers(QList<QLegendMarker *> markers)
573 void QLegendPrivate::removeMarkers(QList<QLegendMarker *> markers)
572 {
574 {
573 foreach (QLegendMarker *marker, markers) {
575 foreach (QLegendMarker *marker, markers) {
574 marker->d_ptr->item()->setVisible(false);
576 marker->d_ptr->item()->setVisible(false);
575 m_items->removeFromGroup(marker->d_ptr->item());
577 m_items->removeFromGroup(marker->d_ptr->item());
576 m_markers.removeOne(marker);
578 m_markers.removeOne(marker);
577 m_markerHash.remove(marker->d_ptr->item());
579 m_markerHash.remove(marker->d_ptr->item());
578 delete marker;
580 delete marker;
579 }
581 }
580 }
582 }
581
583
582 void QLegendPrivate::decorateMarkers(QList<QLegendMarker *> markers)
584 void QLegendPrivate::decorateMarkers(QList<QLegendMarker *> markers)
583 {
585 {
584 foreach (QLegendMarker *marker, markers) {
586 foreach (QLegendMarker *marker, markers) {
585 marker->setFont(m_font);
587 marker->setFont(m_font);
586 marker->setLabelBrush(m_labelBrush);
588 marker->setLabelBrush(m_labelBrush);
587 }
589 }
588 }
590 }
589
591
590
592
591 #include "moc_qlegend.cpp"
593 #include "moc_qlegend.cpp"
592 #include "moc_qlegend_p.cpp"
594 #include "moc_qlegend_p.cpp"
593
595
594 QTCOMMERCIALCHART_END_NAMESPACE
596 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now