##// END OF EJS Templates
Optimize string truncation algorithm...
Miikka Heikkinen -
r2541:563b21497627
parent child
Show More
@@ -1,444 +1,488
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 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 #include "chartpresenter_p.h"
20 #include "chartpresenter_p.h"
21 #include "qchart.h"
21 #include "qchart.h"
22 #include "chartitem_p.h"
22 #include "chartitem_p.h"
23 #include "qchart_p.h"
23 #include "qchart_p.h"
24 #include "qabstractaxis.h"
24 #include "qabstractaxis.h"
25 #include "qabstractaxis_p.h"
25 #include "qabstractaxis_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "chartanimation_p.h"
27 #include "chartanimation_p.h"
28 #include "qabstractseries_p.h"
28 #include "qabstractseries_p.h"
29 #include "qareaseries.h"
29 #include "qareaseries.h"
30 #include "chartaxiselement_p.h"
30 #include "chartaxiselement_p.h"
31 #include "chartbackground_p.h"
31 #include "chartbackground_p.h"
32 #include "cartesianchartlayout_p.h"
32 #include "cartesianchartlayout_p.h"
33 #include "polarchartlayout_p.h"
33 #include "polarchartlayout_p.h"
34 #include "charttitle_p.h"
34 #include "charttitle_p.h"
35 #include <QTimer>
35 #include <QTimer>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 QGraphicsTextItem *dummyTextItem = 0;
39 static QGraphicsTextItem *dummyTextItem = 0;
40 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
41 static QRegExp *truncateMatcher = 0;
42
40 class StaticDummyTextDeleter
43 class StaticDummyTextDeleter
41 {
44 {
42 public:
45 public:
43 StaticDummyTextDeleter() {}
46 StaticDummyTextDeleter() {}
44 ~StaticDummyTextDeleter() { delete dummyTextItem; }
47 ~StaticDummyTextDeleter()
48 {
49 delete dummyTextItem;
50 delete truncateMatcher;
51 }
45 };
52 };
46 StaticDummyTextDeleter staticDummyTextDeleter;
53 StaticDummyTextDeleter staticDummyTextDeleter;
47
54
48 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
55 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
49 : QObject(chart),
56 : QObject(chart),
50 m_chart(chart),
57 m_chart(chart),
51 m_options(QChart::NoAnimation),
58 m_options(QChart::NoAnimation),
52 m_state(ShowState),
59 m_state(ShowState),
53 m_background(0),
60 m_background(0),
54 m_plotAreaBackground(0),
61 m_plotAreaBackground(0),
55 m_title(0)
62 m_title(0)
56 {
63 {
57 if (type == QChart::ChartTypeCartesian)
64 if (type == QChart::ChartTypeCartesian)
58 m_layout = new CartesianChartLayout(this);
65 m_layout = new CartesianChartLayout(this);
59 else if (type == QChart::ChartTypePolar)
66 else if (type == QChart::ChartTypePolar)
60 m_layout = new PolarChartLayout(this);
67 m_layout = new PolarChartLayout(this);
61 Q_ASSERT(m_layout);
68 Q_ASSERT(m_layout);
62 }
69 }
63
70
64 ChartPresenter::~ChartPresenter()
71 ChartPresenter::~ChartPresenter()
65 {
72 {
66
73
67 }
74 }
68
75
69 void ChartPresenter::setGeometry(const QRectF rect)
76 void ChartPresenter::setGeometry(const QRectF rect)
70 {
77 {
71 if (m_rect != rect) {
78 if (m_rect != rect) {
72 m_rect = rect;
79 m_rect = rect;
73 foreach (ChartItem *chart, m_chartItems) {
80 foreach (ChartItem *chart, m_chartItems) {
74 chart->domain()->setSize(rect.size());
81 chart->domain()->setSize(rect.size());
75 chart->setPos(rect.topLeft());
82 chart->setPos(rect.topLeft());
76 }
83 }
77 }
84 }
78 }
85 }
79
86
80 QRectF ChartPresenter::geometry() const
87 QRectF ChartPresenter::geometry() const
81 {
88 {
82 return m_rect;
89 return m_rect;
83 }
90 }
84
91
85 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
92 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
86 {
93 {
87 axis->d_ptr->initializeGraphics(rootItem());
94 axis->d_ptr->initializeGraphics(rootItem());
88 axis->d_ptr->initializeAnimations(m_options);
95 axis->d_ptr->initializeAnimations(m_options);
89 ChartAxisElement *item = axis->d_ptr->axisItem();
96 ChartAxisElement *item = axis->d_ptr->axisItem();
90 item->setPresenter(this);
97 item->setPresenter(this);
91 item->setThemeManager(m_chart->d_ptr->m_themeManager);
98 item->setThemeManager(m_chart->d_ptr->m_themeManager);
92 m_axisItems<<item;
99 m_axisItems<<item;
93 m_axes<<axis;
100 m_axes<<axis;
94 m_layout->invalidate();
101 m_layout->invalidate();
95 }
102 }
96
103
97 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
104 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
98 {
105 {
99 ChartAxisElement *item = axis->d_ptr->m_item.take();
106 ChartAxisElement *item = axis->d_ptr->m_item.take();
100 item->hide();
107 item->hide();
101 item->disconnect();
108 item->disconnect();
102 item->deleteLater();
109 item->deleteLater();
103 m_axisItems.removeAll(item);
110 m_axisItems.removeAll(item);
104 m_axes.removeAll(axis);
111 m_axes.removeAll(axis);
105 m_layout->invalidate();
112 m_layout->invalidate();
106 }
113 }
107
114
108
115
109 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
116 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
110 {
117 {
111 series->d_ptr->initializeGraphics(rootItem());
118 series->d_ptr->initializeGraphics(rootItem());
112 series->d_ptr->initializeAnimations(m_options);
119 series->d_ptr->initializeAnimations(m_options);
113 ChartItem *chart = series->d_ptr->chartItem();
120 ChartItem *chart = series->d_ptr->chartItem();
114 chart->setPresenter(this);
121 chart->setPresenter(this);
115 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
122 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
116 chart->domain()->setSize(m_rect.size());
123 chart->domain()->setSize(m_rect.size());
117 chart->setPos(m_rect.topLeft());
124 chart->setPos(m_rect.topLeft());
118 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
125 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
119 m_chartItems<<chart;
126 m_chartItems<<chart;
120 m_series<<series;
127 m_series<<series;
121 m_layout->invalidate();
128 m_layout->invalidate();
122 }
129 }
123
130
124 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
131 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
125 {
132 {
126 ChartItem *chart = series->d_ptr->m_item.take();
133 ChartItem *chart = series->d_ptr->m_item.take();
127 chart->hide();
134 chart->hide();
128 chart->disconnect();
135 chart->disconnect();
129 chart->deleteLater();
136 chart->deleteLater();
130 m_chartItems.removeAll(chart);
137 m_chartItems.removeAll(chart);
131 m_series.removeAll(series);
138 m_series.removeAll(series);
132 m_layout->invalidate();
139 m_layout->invalidate();
133 }
140 }
134
141
135 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
142 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
136 {
143 {
137 if (m_options != options) {
144 if (m_options != options) {
138 m_options = options;
145 m_options = options;
139
146
140 foreach(QAbstractSeries* series, m_series){
147 foreach(QAbstractSeries* series, m_series){
141 series->d_ptr->initializeAnimations(m_options);
148 series->d_ptr->initializeAnimations(m_options);
142 }
149 }
143 foreach(QAbstractAxis* axis, m_axes){
150 foreach(QAbstractAxis* axis, m_axes){
144 axis->d_ptr->initializeAnimations(m_options);
151 axis->d_ptr->initializeAnimations(m_options);
145 }
152 }
146 }
153 }
147 }
154 }
148
155
149 void ChartPresenter::setState(State state,QPointF point)
156 void ChartPresenter::setState(State state,QPointF point)
150 {
157 {
151 m_state=state;
158 m_state=state;
152 m_statePoint=point;
159 m_statePoint=point;
153 }
160 }
154
161
155 QChart::AnimationOptions ChartPresenter::animationOptions() const
162 QChart::AnimationOptions ChartPresenter::animationOptions() const
156 {
163 {
157 return m_options;
164 return m_options;
158 }
165 }
159
166
160 void ChartPresenter::createBackgroundItem()
167 void ChartPresenter::createBackgroundItem()
161 {
168 {
162 if (!m_background) {
169 if (!m_background) {
163 m_background = new ChartBackground(rootItem());
170 m_background = new ChartBackground(rootItem());
164 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
171 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
165 m_background->setBrush(QChartPrivate::defaultBrush());
172 m_background->setBrush(QChartPrivate::defaultBrush());
166 m_background->setZValue(ChartPresenter::BackgroundZValue);
173 m_background->setZValue(ChartPresenter::BackgroundZValue);
167 }
174 }
168 }
175 }
169
176
170 void ChartPresenter::createPlotAreaBackgroundItem()
177 void ChartPresenter::createPlotAreaBackgroundItem()
171 {
178 {
172 if (!m_plotAreaBackground) {
179 if (!m_plotAreaBackground) {
173 if (m_chart->chartType() == QChart::ChartTypeCartesian)
180 if (m_chart->chartType() == QChart::ChartTypeCartesian)
174 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
181 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
175 else
182 else
176 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
183 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
177 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
184 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
178 // antialising artifacts with axis lines for some reason.
185 // antialising artifacts with axis lines for some reason.
179 m_plotAreaBackground->setPen(QPen(Qt::transparent));
186 m_plotAreaBackground->setPen(QPen(Qt::transparent));
180 m_plotAreaBackground->setBrush(Qt::NoBrush);
187 m_plotAreaBackground->setBrush(Qt::NoBrush);
181 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
188 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
182 m_plotAreaBackground->setVisible(false);
189 m_plotAreaBackground->setVisible(false);
183 }
190 }
184 }
191 }
185
192
186 void ChartPresenter::createTitleItem()
193 void ChartPresenter::createTitleItem()
187 {
194 {
188 if (!m_title) {
195 if (!m_title) {
189 m_title = new ChartTitle(rootItem());
196 m_title = new ChartTitle(rootItem());
190 m_title->setZValue(ChartPresenter::BackgroundZValue);
197 m_title->setZValue(ChartPresenter::BackgroundZValue);
191 }
198 }
192 }
199 }
193
200
194
201
195 void ChartPresenter::handleAnimationFinished()
202 void ChartPresenter::handleAnimationFinished()
196 {
203 {
197 m_animations.removeAll(qobject_cast<ChartAnimation *>(sender()));
204 m_animations.removeAll(qobject_cast<ChartAnimation *>(sender()));
198 if (m_animations.empty())
205 if (m_animations.empty())
199 emit animationsFinished();
206 emit animationsFinished();
200 }
207 }
201
208
202 void ChartPresenter::startAnimation(ChartAnimation *animation)
209 void ChartPresenter::startAnimation(ChartAnimation *animation)
203 {
210 {
204 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
211 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
205 QObject::connect(animation, SIGNAL(finished()), this, SLOT(handleAnimationFinished()), Qt::UniqueConnection);
212 QObject::connect(animation, SIGNAL(finished()), this, SLOT(handleAnimationFinished()), Qt::UniqueConnection);
206 if (!m_animations.isEmpty())
213 if (!m_animations.isEmpty())
207 m_animations.append(animation);
214 m_animations.append(animation);
208 QTimer::singleShot(0, animation, SLOT(start()));
215 QTimer::singleShot(0, animation, SLOT(start()));
209 }
216 }
210
217
211 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
218 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
212 {
219 {
213 createBackgroundItem();
220 createBackgroundItem();
214 m_background->setBrush(brush);
221 m_background->setBrush(brush);
215 m_layout->invalidate();
222 m_layout->invalidate();
216 }
223 }
217
224
218 QBrush ChartPresenter::backgroundBrush() const
225 QBrush ChartPresenter::backgroundBrush() const
219 {
226 {
220 if (!m_background)
227 if (!m_background)
221 return QBrush();
228 return QBrush();
222 return m_background->brush();
229 return m_background->brush();
223 }
230 }
224
231
225 void ChartPresenter::setBackgroundPen(const QPen &pen)
232 void ChartPresenter::setBackgroundPen(const QPen &pen)
226 {
233 {
227 createBackgroundItem();
234 createBackgroundItem();
228 m_background->setPen(pen);
235 m_background->setPen(pen);
229 m_layout->invalidate();
236 m_layout->invalidate();
230 }
237 }
231
238
232 QPen ChartPresenter::backgroundPen() const
239 QPen ChartPresenter::backgroundPen() const
233 {
240 {
234 if (!m_background)
241 if (!m_background)
235 return QPen();
242 return QPen();
236 return m_background->pen();
243 return m_background->pen();
237 }
244 }
238
245
239 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
246 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
240 {
247 {
241 createPlotAreaBackgroundItem();
248 createPlotAreaBackgroundItem();
242 m_plotAreaBackground->setBrush(brush);
249 m_plotAreaBackground->setBrush(brush);
243 m_layout->invalidate();
250 m_layout->invalidate();
244 }
251 }
245
252
246 QBrush ChartPresenter::plotAreaBackgroundBrush() const
253 QBrush ChartPresenter::plotAreaBackgroundBrush() const
247 {
254 {
248 if (!m_plotAreaBackground)
255 if (!m_plotAreaBackground)
249 return QBrush();
256 return QBrush();
250 return m_plotAreaBackground->brush();
257 return m_plotAreaBackground->brush();
251 }
258 }
252
259
253 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
260 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
254 {
261 {
255 createPlotAreaBackgroundItem();
262 createPlotAreaBackgroundItem();
256 m_plotAreaBackground->setPen(pen);
263 m_plotAreaBackground->setPen(pen);
257 m_layout->invalidate();
264 m_layout->invalidate();
258 }
265 }
259
266
260 QPen ChartPresenter::plotAreaBackgroundPen() const
267 QPen ChartPresenter::plotAreaBackgroundPen() const
261 {
268 {
262 if (!m_plotAreaBackground)
269 if (!m_plotAreaBackground)
263 return QPen();
270 return QPen();
264 return m_plotAreaBackground->pen();
271 return m_plotAreaBackground->pen();
265 }
272 }
266
273
267 void ChartPresenter::setTitle(const QString &title)
274 void ChartPresenter::setTitle(const QString &title)
268 {
275 {
269 createTitleItem();
276 createTitleItem();
270 m_title->setText(title);
277 m_title->setText(title);
271 m_layout->invalidate();
278 m_layout->invalidate();
272 }
279 }
273
280
274 QString ChartPresenter::title() const
281 QString ChartPresenter::title() const
275 {
282 {
276 if (!m_title)
283 if (!m_title)
277 return QString();
284 return QString();
278 return m_title->text();
285 return m_title->text();
279 }
286 }
280
287
281 void ChartPresenter::setTitleFont(const QFont &font)
288 void ChartPresenter::setTitleFont(const QFont &font)
282 {
289 {
283 createTitleItem();
290 createTitleItem();
284 m_title->setFont(font);
291 m_title->setFont(font);
285 m_layout->invalidate();
292 m_layout->invalidate();
286 }
293 }
287
294
288 QFont ChartPresenter::titleFont() const
295 QFont ChartPresenter::titleFont() const
289 {
296 {
290 if (!m_title)
297 if (!m_title)
291 return QFont();
298 return QFont();
292 return m_title->font();
299 return m_title->font();
293 }
300 }
294
301
295 void ChartPresenter::setTitleBrush(const QBrush &brush)
302 void ChartPresenter::setTitleBrush(const QBrush &brush)
296 {
303 {
297 createTitleItem();
304 createTitleItem();
298 m_title->setDefaultTextColor(brush.color());
305 m_title->setDefaultTextColor(brush.color());
299 m_layout->invalidate();
306 m_layout->invalidate();
300 }
307 }
301
308
302 QBrush ChartPresenter::titleBrush() const
309 QBrush ChartPresenter::titleBrush() const
303 {
310 {
304 if (!m_title)
311 if (!m_title)
305 return QBrush();
312 return QBrush();
306 return QBrush(m_title->defaultTextColor());
313 return QBrush(m_title->defaultTextColor());
307 }
314 }
308
315
309 void ChartPresenter::setBackgroundVisible(bool visible)
316 void ChartPresenter::setBackgroundVisible(bool visible)
310 {
317 {
311 createBackgroundItem();
318 createBackgroundItem();
312 m_background->setVisible(visible);
319 m_background->setVisible(visible);
313 }
320 }
314
321
315
322
316 bool ChartPresenter::isBackgroundVisible() const
323 bool ChartPresenter::isBackgroundVisible() const
317 {
324 {
318 if (!m_background)
325 if (!m_background)
319 return false;
326 return false;
320 return m_background->isVisible();
327 return m_background->isVisible();
321 }
328 }
322
329
323 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
330 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
324 {
331 {
325 createPlotAreaBackgroundItem();
332 createPlotAreaBackgroundItem();
326 m_plotAreaBackground->setVisible(visible);
333 m_plotAreaBackground->setVisible(visible);
327 }
334 }
328
335
329 bool ChartPresenter::isPlotAreaBackgroundVisible() const
336 bool ChartPresenter::isPlotAreaBackgroundVisible() const
330 {
337 {
331 if (!m_plotAreaBackground)
338 if (!m_plotAreaBackground)
332 return false;
339 return false;
333 return m_plotAreaBackground->isVisible();
340 return m_plotAreaBackground->isVisible();
334 }
341 }
335
342
336 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
343 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
337 {
344 {
338 createBackgroundItem();
345 createBackgroundItem();
339 m_background->setDropShadowEnabled(enabled);
346 m_background->setDropShadowEnabled(enabled);
340 }
347 }
341
348
342 bool ChartPresenter::isBackgroundDropShadowEnabled() const
349 bool ChartPresenter::isBackgroundDropShadowEnabled() const
343 {
350 {
344 if (!m_background)
351 if (!m_background)
345 return false;
352 return false;
346 return m_background->isDropShadowEnabled();
353 return m_background->isDropShadowEnabled();
347 }
354 }
348
355
349
356
350 AbstractChartLayout *ChartPresenter::layout()
357 AbstractChartLayout *ChartPresenter::layout()
351 {
358 {
352 return m_layout;
359 return m_layout;
353 }
360 }
354
361
355 QLegend *ChartPresenter::legend()
362 QLegend *ChartPresenter::legend()
356 {
363 {
357 return m_chart->legend();
364 return m_chart->legend();
358 }
365 }
359
366
360 void ChartPresenter::setVisible(bool visible)
367 void ChartPresenter::setVisible(bool visible)
361 {
368 {
362 m_chart->setVisible(visible);
369 m_chart->setVisible(visible);
363 }
370 }
364
371
365 ChartBackground *ChartPresenter::backgroundElement()
372 ChartBackground *ChartPresenter::backgroundElement()
366 {
373 {
367 return m_background;
374 return m_background;
368 }
375 }
369
376
370 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
377 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
371 {
378 {
372 return m_plotAreaBackground;
379 return m_plotAreaBackground;
373 }
380 }
374
381
375 QList<ChartAxisElement *> ChartPresenter::axisItems() const
382 QList<ChartAxisElement *> ChartPresenter::axisItems() const
376 {
383 {
377 return m_axisItems;
384 return m_axisItems;
378 }
385 }
379
386
380 QList<ChartItem *> ChartPresenter::chartItems() const
387 QList<ChartItem *> ChartPresenter::chartItems() const
381 {
388 {
382 return m_chartItems;
389 return m_chartItems;
383 }
390 }
384
391
385 ChartTitle *ChartPresenter::titleElement()
392 ChartTitle *ChartPresenter::titleElement()
386 {
393 {
387 return m_title;
394 return m_title;
388 }
395 }
389
396
390 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
397 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
391 {
398 {
392 if (!dummyTextItem)
399 if (!dummyTextItem)
393 dummyTextItem = new QGraphicsTextItem;
400 dummyTextItem = new QGraphicsTextItem;
394
401
395 dummyTextItem->setFont(font);
402 dummyTextItem->setFont(font);
396 dummyTextItem->setHtml(text);
403 dummyTextItem->setHtml(text);
397 QRectF boundingRect = dummyTextItem->boundingRect();
404 QRectF boundingRect = dummyTextItem->boundingRect();
398
405
399 // Take rotation into account
406 // Take rotation into account
400 if (angle) {
407 if (angle) {
401 QTransform transform;
408 QTransform transform;
402 transform.rotate(angle);
409 transform.rotate(angle);
403 boundingRect = transform.mapRect(boundingRect);
410 boundingRect = transform.mapRect(boundingRect);
404 }
411 }
405
412
406 return boundingRect;
413 return boundingRect;
407 }
414 }
408
415
409 // boundingRect parameter returns the rotated bounding rect of the text
416 // boundingRect parameter returns the rotated bounding rect of the text
410 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
417 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
411 qreal maxSize, Qt::Orientation constraintOrientation,
418 qreal maxSize, Qt::Orientation constraintOrientation,
412 QRectF &boundingRect)
419 QRectF &boundingRect)
413 {
420 {
414 QString truncatedString(text);
421 QString truncatedString(text);
415 boundingRect = textBoundingRect(font, truncatedString, angle);
422 boundingRect = textBoundingRect(font, truncatedString, angle);
416 qreal checkDimension = ((constraintOrientation == Qt::Horizontal)
423 qreal checkDimension = ((constraintOrientation == Qt::Horizontal)
417 ? boundingRect.width() : boundingRect.height());
424 ? boundingRect.width() : boundingRect.height());
418 if (checkDimension > maxSize) {
425 if (checkDimension > maxSize) {
419 truncatedString.append("...");
426 // It can be assumed that almost any amount of string manipulation is faster
420 while (checkDimension > maxSize && truncatedString.length() > 3) {
427 // than calculating one bounding rectangle, so first prepare a list of truncated strings
421 // Crude truncation logic - simply remove any html tag completely
428 // to try.
422 int removeIndex(-1);
429 if (!truncateMatcher)
423 int removeCount(1);
430 truncateMatcher = new QRegExp(truncateMatchString);
424 if (truncatedString.at(truncatedString.length() - 4) == QLatin1Char('>')) {
431 QVector<QString> testStrings(text.length());
425 removeIndex = truncatedString.lastIndexOf(QLatin1Char('<'));
432 int count(0);
426 if (removeIndex != -1)
433 static QLatin1Char closeTag('>');
427 removeCount = truncatedString.length() - 3 - removeIndex;
434 static QLatin1Char openTag('<');
428 }
435 static QLatin1Char semiColon(';');
429 if (removeIndex == -1)
436 static QLatin1String ellipsis("...");
430 removeIndex = truncatedString.length() - 4;
437 while (truncatedString.length() > 1) {
438 int chopIndex(-1);
439 int chopCount(1);
440 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
441
442 if (lastChar == closeTag)
443 chopIndex = truncatedString.lastIndexOf(openTag);
444 else if (lastChar == semiColon)
445 chopIndex = truncateMatcher->indexIn(truncatedString, 0);
446
447 if (chopIndex != -1)
448 chopCount = truncatedString.length() - chopIndex;
449 truncatedString.chop(chopCount);
450 testStrings[count] = truncatedString + ellipsis;
451 count++;
452 }
431
453
432 truncatedString.remove(removeIndex, removeCount);
454 // Binary search for best fit
433 boundingRect = textBoundingRect(font, truncatedString, angle);
455 int minIndex(0);
456 int maxIndex(count - 1);
457 int bestIndex(count);
458 QRectF checkRect;
459 while (maxIndex >= minIndex) {
460 int mid = (maxIndex + minIndex) / 2;
461 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
434 checkDimension = ((constraintOrientation == Qt::Horizontal)
462 checkDimension = ((constraintOrientation == Qt::Horizontal)
435 ? boundingRect.width() : boundingRect.height());
463 ? checkRect.width() : checkRect.height());
464 if (checkDimension > maxSize) {
465 // Checked index too large, all under this are also too large
466 minIndex = mid + 1;
467 } else {
468 // Checked index fits, all over this also fit
469 maxIndex = mid - 1;
470 bestIndex = mid;
471 boundingRect = checkRect;
472 }
473 }
474 // Default to "..." if nothing fits
475 if (bestIndex == count) {
476 boundingRect = textBoundingRect(font, ellipsis, angle);
477 truncatedString = ellipsis;
478 } else {
479 truncatedString = testStrings.at(bestIndex);
436 }
480 }
437 }
481 }
438
482
439 return truncatedString;
483 return truncatedString;
440 }
484 }
441
485
442 #include "moc_chartpresenter_p.cpp"
486 #include "moc_chartpresenter_p.cpp"
443
487
444 QTCOMMERCIALCHART_END_NAMESPACE
488 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now