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