@@ -36,12 +36,19 | |||||
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() |
|
47 | ~StaticDummyTextDeleter() | |
|
48 | { | |||
|
49 | delete dummyTextItem; | |||
|
50 | delete truncateMatcher; | |||
|
51 | } | |||
45 | }; |
|
52 | }; | |
46 | StaticDummyTextDeleter staticDummyTextDeleter; |
|
53 | StaticDummyTextDeleter staticDummyTextDeleter; | |
47 |
|
54 | |||
@@ -416,23 +423,60 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qr | |||||
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 |
|
|
437 | while (truncatedString.length() > 1) { | |
431 |
|
438 | int chopIndex(-1); | ||
432 | truncatedString.remove(removeIndex, removeCount); |
|
439 | int chopCount(1); | |
433 | boundingRect = textBoundingRect(font, truncatedString, angle); |
|
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 | } | |||
|
453 | ||||
|
454 | // Binary search for best fit | |||
|
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 |
? |
|
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 |
General Comments 0
You need to be logged in to leave comments.
Login now