##// END OF EJS Templates
Refactor piechart to avoid using invalid QPieSlice pointers....
Jani Honkonen -
r1053:615ed2b99418
parent child
Show More
@@ -251,18 +251,18 void ChartAnimator::updateLayout(XYChartItem *item, QVector<QPointF> &oldPoints,
251 251 QTimer::singleShot(0, animation, SLOT(start()));
252 252 }
253 253
254 void ChartAnimator::addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
254 void ChartAnimator::addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty)
255 255 {
256 256 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
257 257 Q_ASSERT(animation);
258 animation->addSlice(slice, sliceData, isEmpty);
258 animation->addSlice(sliceItem, sliceData, isEmpty);
259 259 }
260 260
261 void ChartAnimator::removeAnimation(PieChartItem *item, QPieSlice *slice)
261 void ChartAnimator::removeAnimation(PieChartItem *item, PieSliceItem *sliceItem)
262 262 {
263 263 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
264 264 Q_ASSERT(animation);
265 animation->removeSlice(slice);
265 animation->removeSlice(sliceItem);
266 266 }
267 267
268 268 void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout)
@@ -272,11 +272,11 void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout)
272 272 animation->updateValues(layout);
273 273 }
274 274
275 void ChartAnimator::updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData)
275 void ChartAnimator::updateLayout(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData)
276 276 {
277 277 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
278 278 Q_ASSERT(animation);
279 animation->updateValue(slice, sliceData);
279 animation->updateValue(sliceItem, sliceData);
280 280 }
281 281
282 282 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
@@ -59,10 +59,10 public:
59 59 void updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newContorlPoints, int index);
60 60 void updateLayout(ChartAxis *item, QVector<qreal> &layout);
61 61
62 void addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty);
63 void removeAnimation(PieChartItem *item, QPieSlice *slice);
62 void addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty);
63 void removeAnimation(PieChartItem *item, PieSliceItem *sliceItem);
64 64 void updateLayout(PieChartItem *item, const PieLayout &layout);
65 void updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData);
65 void updateLayout(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData);
66 66
67 67 void updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout);
68 68
@@ -38,13 +38,13 PieAnimation::~PieAnimation()
38 38
39 39 void PieAnimation::updateValues(const PieLayout &newValues)
40 40 {
41 foreach (QPieSlice *s, newValues.keys())
41 foreach (PieSliceItem *s, newValues.keys())
42 42 updateValue(s, newValues.value(s));
43 43 }
44 44
45 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceData &sliceData)
45 void PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
46 46 {
47 PieSliceAnimation *animation = m_animations.value(slice);
47 PieSliceAnimation *animation = m_animations.value(sliceItem);
48 48 Q_ASSERT(animation);
49 49 animation->stop();
50 50
@@ -55,10 +55,10 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceData &sliceData)
55 55 QTimer::singleShot(0, animation, SLOT(start()));
56 56 }
57 57
58 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
58 void PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty)
59 59 {
60 PieSliceAnimation *animation = new PieSliceAnimation(m_item, slice);
61 m_animations.insert(slice, animation);
60 PieSliceAnimation *animation = new PieSliceAnimation(sliceItem);
61 m_animations.insert(sliceItem, animation);
62 62
63 63 PieSliceData startValue = sliceData;
64 64 startValue.m_radius = 0;
@@ -74,15 +74,14 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceData &sliceData, boo
74 74 QTimer::singleShot(0, animation, SLOT(start()));
75 75 }
76 76
77 void PieAnimation::removeSlice(QPieSlice *slice)
77 void PieAnimation::removeSlice(PieSliceItem *sliceItem)
78 78 {
79 PieSliceAnimation *animation = m_animations.value(slice);
79 PieSliceAnimation *animation = m_animations.value(sliceItem);
80 80 Q_ASSERT(animation);
81 81 animation->stop();
82 82
83 83 PieSliceData endValue = animation->currentSliceValue();
84 84 endValue.m_radius = 0;
85 // TODO: find the actual angle where this slice disappears
86 85 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
87 86 endValue.m_angleSpan = 0;
88 87
@@ -90,7 +89,10 void PieAnimation::removeSlice(QPieSlice *slice)
90 89 animation->setDuration(1000);
91 90 animation->setEasingCurve(QEasingCurve::OutQuart);
92 91
93 connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete()));
92 // PieSliceItem is the parent of PieSliceAnimation so the animation will be deleted as well..
93 connect(animation, SIGNAL(finished()), sliceItem, SLOT(deleteLater()));
94 m_animations.remove(sliceItem);
95
94 96 QTimer::singleShot(0, animation, SLOT(start()));
95 97 }
96 98
@@ -99,14 +101,6 void PieAnimation::updateCurrentValue(const QVariant &)
99 101 // nothing to do...
100 102 }
101 103
102 void PieAnimation::destroySliceAnimationComplete()
103 {
104 PieSliceAnimation *animation = static_cast<PieSliceAnimation *>(sender());
105 QPieSlice *slice = m_animations.key(animation);
106 m_item->destroySlice(slice);
107 delete m_animations.take(slice);
108 }
109
110 104 #include "moc_pieanimation_p.cpp"
111 105
112 106 QTCOMMERCIALCHART_END_NAMESPACE
@@ -37,19 +37,16 public:
37 37 PieAnimation(PieChartItem *item);
38 38 ~PieAnimation();
39 39 void updateValues(const PieLayout &newValues);
40 void updateValue(QPieSlice *slice, const PieSliceData &newValue);
41 void addSlice(QPieSlice *slice, const PieSliceData &endValue, bool isEmpty);
42 void removeSlice(QPieSlice *slice);
40 void updateValue(PieSliceItem *sliceItem, const PieSliceData &newValue);
41 void addSlice(PieSliceItem *sliceItem, const PieSliceData &endValue, bool isEmpty);
42 void removeSlice(PieSliceItem *sliceItem);
43 43
44 44 public: // from QVariantAnimation
45 45 void updateCurrentValue(const QVariant &value);
46 46
47 public Q_SLOTS:
48 void destroySliceAnimationComplete();
49
50 47 private:
51 48 PieChartItem *m_item;
52 QHash<QPieSlice *, PieSliceAnimation *> m_animations;
49 QHash<PieSliceItem *, PieSliceAnimation *> m_animations;
53 50 };
54 51
55 52 QTCOMMERCIALCHART_END_NAMESPACE
@@ -20,7 +20,6
20 20
21 21 #include "piesliceanimation_p.h"
22 22 #include "piechartitem_p.h"
23 #include "qpieslice.h"
24 23
25 24 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
26 25
@@ -58,10 +57,9 QBrush linearPos(QBrush start, QBrush end, qreal pos)
58 57 return end;
59 58 }
60 59
61 PieSliceAnimation::PieSliceAnimation(PieChartItem *item, QPieSlice *slice)
62 :QVariantAnimation(item),
63 m_item(item),
64 m_slice(slice)
60 PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem)
61 :QVariantAnimation(sliceItem),
62 m_sliceItem(sliceItem)
65 63 {
66 64 }
67 65
@@ -120,7 +118,9 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
120 118 {
121 119 if (state() != QAbstractAnimation::Stopped) { //workaround
122 120 m_currentValue = qVariantValue<PieSliceData>(value);
123 m_item->setLayout(m_slice, m_currentValue);
121 m_sliceItem->setSliceData(m_currentValue);
122 m_sliceItem->updateGeometry();
123 m_sliceItem->update();
124 124 }
125 125 }
126 126
@@ -21,18 +21,17
21 21 #ifndef PIESLICEANIMATION_P_H
22 22 #define PIESLICEANIMATION_P_H
23 23
24 #include "piechartitem_p.h"
25 24 #include <QVariantAnimation>
25 #include "piesliceitem_p.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 class PieChartItem;
30 class QPieSlice;
31 30
32 31 class PieSliceAnimation : public QVariantAnimation
33 32 {
34 33 public:
35 PieSliceAnimation(PieChartItem *item, QPieSlice *slice);
34 PieSliceAnimation(PieSliceItem *sliceItem);
36 35 ~PieSliceAnimation();
37 36 void setValue(const PieSliceData &startValue, const PieSliceData &endValue);
38 37 void updateValue(const PieSliceData &endValue);
@@ -43,8 +42,7 protected:
43 42 void updateCurrentValue(const QVariant &value);
44 43
45 44 private:
46 PieChartItem *m_item;
47 QPieSlice *m_slice;
45 PieSliceItem *m_sliceItem;
48 46 PieSliceData m_currentValue;
49 47 };
50 48
@@ -84,9 +84,9 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
84 84 PieSliceData data = sliceData(s);
85 85
86 86 if (animator())
87 animator()->addAnimation(this, s, data, isEmpty);
87 animator()->addAnimation(this, item, data, isEmpty);
88 88 else
89 setLayout(s, data);
89 setLayout(item, data);
90 90 }
91 91 }
92 92
@@ -94,11 +94,16 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
94 94 {
95 95 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
96 96
97 foreach (QPieSlice *s, slices) {
97 foreach (QPieSlice *slice, slices) {
98
99 PieSliceItem *item = m_slices.value(slice);
100 Q_ASSERT(item);
101 m_slices.remove(slice);
102
98 103 if (animator())
99 animator()->removeAnimation(this, s);
104 animator()->removeAnimation(this, item); // animator deletes the PieSliceItem
100 105 else
101 destroySlice(s);
106 delete item;
102 107 }
103 108 }
104 109
@@ -114,7 +119,7 void PieChartItem::handleSliceChanged()
114 119 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
115 120 Q_ASSERT(m_slices.contains(slice));
116 121 PieSliceData data = sliceData(slice);
117 updateLayout(slice, data);
122 updateLayout(m_slices.value(slice), data);
118 123 update();
119 124 }
120 125
@@ -160,7 +165,7 PieLayout PieChartItem::calculateLayout()
160 165 PieLayout layout;
161 166 foreach (QPieSlice* s, m_series->slices()) {
162 167 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
163 layout.insert(s, sliceData(s));
168 layout.insert(m_slices.value(s), sliceData(s));
164 169 }
165 170 return layout;
166 171 }
@@ -173,38 +178,29 void PieChartItem::applyLayout(const PieLayout &layout)
173 178 setLayout(layout);
174 179 }
175 180
176 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
181 void PieChartItem::updateLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData)
177 182 {
178 183 if (animator())
179 animator()->updateLayout(this, slice, sliceData);
184 animator()->updateLayout(this, sliceItem, sliceData);
180 185 else
181 setLayout(slice, sliceData);
186 setLayout(sliceItem, sliceData);
182 187 }
183 188
184 189 void PieChartItem::setLayout(const PieLayout &layout)
185 190 {
186 foreach (QPieSlice *slice, layout.keys()) {
187 PieSliceItem *item = m_slices.value(slice);
188 Q_ASSERT(item);
189 item->setSliceData(layout.value(slice));
191 foreach (PieSliceItem *item, layout.keys()) {
192 item->setSliceData(layout.value(item));
190 193 item->updateGeometry();
191 194 item->update();
192 195 }
193 196 }
194 197
195 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
196 {
197 // find slice
198 PieSliceItem *item = m_slices.value(slice);
199 Q_ASSERT(item);
200 item->setSliceData(sliceData);
201 item->updateGeometry();
202 item->update();
203 }
204
205 void PieChartItem::destroySlice(QPieSlice *slice)
198 void PieChartItem::setLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData)
206 199 {
207 delete m_slices.take(slice);
200 Q_ASSERT(sliceItem);
201 sliceItem->setSliceData(sliceData);
202 sliceItem->updateGeometry();
203 sliceItem->update();
208 204 }
209 205
210 206 #include "moc_piechartitem_p.cpp"
@@ -30,7 +30,7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30 class QPieSlice;
31 31 class ChartPresenter;
32 32
33 typedef QHash<QPieSlice*, PieSliceData> PieLayout;
33 typedef QHash<PieSliceItem*, PieSliceData> PieLayout;
34 34
35 35 class PieChartItem : public ChartItem
36 36 {
@@ -59,10 +59,9 public:
59 59 PieSliceData sliceData(QPieSlice *slice);
60 60 PieLayout calculateLayout();
61 61 void applyLayout(const PieLayout &layout);
62 void updateLayout(QPieSlice *slice, const PieSliceData &sliceData);
62 void updateLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData);
63 63 void setLayout(const PieLayout &layout);
64 void setLayout(QPieSlice *slice, const PieSliceData &sliceData);
65 void destroySlice(QPieSlice *slice);
64 void setLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData);
66 65
67 66 private:
68 67 friend class PieSliceItem;
General Comments 0
You need to be logged in to leave comments. Login now