@@ -36,12 +36,19 | |||
|
36 | 36 | |
|
37 | 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 | 43 | class StaticDummyTextDeleter |
|
41 | 44 | { |
|
42 | 45 | public: |
|
43 | 46 | StaticDummyTextDeleter() {} |
|
44 |
~StaticDummyTextDeleter() |
|
|
47 | ~StaticDummyTextDeleter() | |
|
48 | { | |
|
49 | delete dummyTextItem; | |
|
50 | delete truncateMatcher; | |
|
51 | } | |
|
45 | 52 | }; |
|
46 | 53 | StaticDummyTextDeleter staticDummyTextDeleter; |
|
47 | 54 | |
@@ -416,23 +423,60 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qr | |||
|
416 | 423 | qreal checkDimension = ((constraintOrientation == Qt::Horizontal) |
|
417 | 424 | ? boundingRect.width() : boundingRect.height()); |
|
418 | 425 | if (checkDimension > maxSize) { |
|
419 | truncatedString.append("..."); | |
|
420 | while (checkDimension > maxSize && truncatedString.length() > 3) { | |
|
421 | // Crude truncation logic - simply remove any html tag completely | |
|
422 | int removeIndex(-1); | |
|
423 | int removeCount(1); | |
|
424 | if (truncatedString.at(truncatedString.length() - 4) == QLatin1Char('>')) { | |
|
425 | removeIndex = truncatedString.lastIndexOf(QLatin1Char('<')); | |
|
426 | if (removeIndex != -1) | |
|
427 | removeCount = truncatedString.length() - 3 - removeIndex; | |
|
428 | } | |
|
429 | if (removeIndex == -1) | |
|
430 |
|
|
|
431 | ||
|
432 | truncatedString.remove(removeIndex, removeCount); | |
|
433 | boundingRect = textBoundingRect(font, truncatedString, angle); | |
|
426 | // It can be assumed that almost any amount of string manipulation is faster | |
|
427 | // than calculating one bounding rectangle, so first prepare a list of truncated strings | |
|
428 | // to try. | |
|
429 | if (!truncateMatcher) | |
|
430 | truncateMatcher = new QRegExp(truncateMatchString); | |
|
431 | QVector<QString> testStrings(text.length()); | |
|
432 | int count(0); | |
|
433 | static QLatin1Char closeTag('>'); | |
|
434 | static QLatin1Char openTag('<'); | |
|
435 | static QLatin1Char semiColon(';'); | |
|
436 | static QLatin1String ellipsis("..."); | |
|
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 | } | |
|
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 | 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