diff options
-rw-r--r-- | demos/textedit/textedit.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qcssparser.cpp | 10 | ||||
-rw-r--r-- | src/gui/text/qcssparser_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 7 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentlayout.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qtextformat.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextformat.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qtextlist.cpp | 49 | ||||
-rw-r--r-- | src/gui/text/qtextodfwriter.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qtextlist/tst_qtextlist.cpp | 36 |
11 files changed, 129 insertions, 7 deletions
diff --git a/demos/textedit/textedit.cpp b/demos/textedit/textedit.cpp index 17516b4..5eee855 100644 --- a/demos/textedit/textedit.cpp +++ b/demos/textedit/textedit.cpp @@ -336,6 +336,8 @@ void TextEdit::setupTextActions() comboStyle->addItem("Ordered List (Decimal)"); comboStyle->addItem("Ordered List (Alpha lower)"); comboStyle->addItem("Ordered List (Alpha upper)"); + comboStyle->addItem("Ordered List (Roman lower)"); + comboStyle->addItem("Ordered List (Roman upper)"); connect(comboStyle, SIGNAL(activated(int)), this, SLOT(textStyle(int))); @@ -573,6 +575,12 @@ void TextEdit::textStyle(int styleIndex) case 6: style = QTextListFormat::ListUpperAlpha; break; + case 7: + style = QTextListFormat::ListLowerRoman; + break; + case 8: + style = QTextListFormat::ListUpperRoman; + break; } cursor.beginEditBlock(); diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index ab69e5c..db5ed7c 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -199,6 +199,7 @@ static const QCssKnownValue values[NumKnownValues - 1] = { { "link", Value_Link }, { "link-visited", Value_LinkVisited }, { "lower-alpha", Value_LowerAlpha }, + { "lower-roman", Value_LowerRoman }, { "lowercase", Value_Lowercase }, { "medium", Value_Medium }, { "mid", Value_Mid }, @@ -230,6 +231,7 @@ static const QCssKnownValue values[NumKnownValues - 1] = { { "transparent", Value_Transparent }, { "underline", Value_Underline }, { "upper-alpha", Value_UpperAlpha }, + { "upper-roman", Value_UpperRoman }, { "uppercase", Value_Uppercase }, { "wave", Value_Wave }, { "window", Value_Window }, @@ -239,10 +241,10 @@ static const QCssKnownValue values[NumKnownValues - 1] = { }; //Map id to strings as they appears in the 'values' array above -static const short indexOfId[NumKnownValues] = { 0, 40, 47, 41, 48, 53, 34, 26, 68, 69, 25, 42, 5, 62, 46, - 29, 57, 58, 27, 50, 60, 6, 10, 38, 55, 19, 13, 17, 18, 20, 21, 49, 24, 45, 65, 36, 3, 2, 39, 61, 16, - 11, 56, 14, 32, 63, 54, 64, 33, 67, 8, 28, 37, 12, 35, 59, 7, 9, 4, 66, 52, 22, 23, 30, 31, 1, 15, 0, - 51, 44, 43 }; +static const short indexOfId[NumKnownValues] = { 0, 41, 48, 42, 49, 54, 35, 26, 70, 71, 25, 43, 5, 63, 47, + 29, 58, 59, 27, 51, 61, 6, 10, 39, 56, 19, 13, 17, 18, 20, 21, 50, 24, 46, 67, 37, 3, 2, 40, 62, 16, + 11, 57, 14, 32, 64, 33, 65, 55, 66, 34, 69, 8, 28, 38, 12, 36, 60, 7, 9, 4, 68, 53, 22, 23, 30, 31, + 1, 15, 0, 52, 45, 44 }; QString Value::toString() const { diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 8056f4d..b07acd5 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -223,6 +223,8 @@ enum KnownValue { Value_Decimal, Value_LowerAlpha, Value_UpperAlpha, + Value_LowerRoman, + Value_UpperRoman, Value_SmallCaps, Value_Uppercase, Value_Lowercase, diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 3287f31..3531699 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2416,7 +2416,10 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment) static bool isOrderedList(int style) { return style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha - || style == QTextListFormat::ListUpperAlpha; + || style == QTextListFormat::ListUpperAlpha + || style == QTextListFormat::ListUpperRoman + || style == QTextListFormat::ListLowerRoman + ; } void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) @@ -2513,6 +2516,8 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block) case QTextListFormat::ListSquare: html += QLatin1String("<ul type=\"square\""); break; case QTextListFormat::ListLowerAlpha: html += QLatin1String("<ol type=\"a\""); break; case QTextListFormat::ListUpperAlpha: html += QLatin1String("<ol type=\"A\""); break; + case QTextListFormat::ListLowerRoman: html += QLatin1String("<ol type=\"i\""); break; + case QTextListFormat::ListUpperRoman: html += QLatin1String("<ol type=\"I\""); break; default: html += QLatin1String("<ul"); // ### should not happen } diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 125d74c..f1d9091 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1383,6 +1383,8 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p case QTextListFormat::ListDecimal: case QTextListFormat::ListLowerAlpha: case QTextListFormat::ListUpperAlpha: + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: itemText = static_cast<QTextList *>(object)->itemText(bl); size.setWidth(fontMetrics.width(itemText)); size.setHeight(fontMetrics.height()); @@ -1426,7 +1428,9 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p switch (style) { case QTextListFormat::ListDecimal: case QTextListFormat::ListLowerAlpha: - case QTextListFormat::ListUpperAlpha: { + case QTextListFormat::ListUpperAlpha: + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: { QTextLayout layout(itemText, font, q->paintDevice()); layout.setCacheEnabled(true); QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute); diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 9bc62b1..4e43418 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -2078,6 +2078,8 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const \value ListDecimal decimal values in ascending order \value ListLowerAlpha lower case Latin characters in alphabetical order \value ListUpperAlpha upper case Latin characters in alphabetical order + \value ListLowerRoman lower case roman numerals (supports up to 4999 items only) + \value ListUpperRoman upper case roman numerals (supports up to 4999 items only) \omitvalue ListStyleUndefined */ diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index d269687..9697105 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -604,6 +604,8 @@ public: ListDecimal = -4, ListLowerAlpha = -5, ListUpperAlpha = -6, + ListLowerRoman = -7, + ListUpperRoman = -8, ListStyleUndefined = 0 }; diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 1bff162..a88cd17 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1206,6 +1206,8 @@ void QTextHtmlParserNode::setListStyle(const QVector<QCss::Value> &cssValues) case QCss::Value_Decimal: hasOwnListStyle = true; listStyle = QTextListFormat::ListDecimal; break; case QCss::Value_LowerAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerAlpha; break; case QCss::Value_UpperAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperAlpha; break; + case QCss::Value_LowerRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerRoman; break; + case QCss::Value_UpperRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperRoman; break; default: break; } } @@ -1540,6 +1542,10 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes) node->listStyle = QTextListFormat::ListLowerAlpha; } else if (value == QLatin1String("A")) { node->listStyle = QTextListFormat::ListUpperAlpha; + } else if (value == QLatin1String("i")) { + node->listStyle = QTextListFormat::ListLowerRoman; + } else if (value == QLatin1String("I")) { + node->listStyle = QTextListFormat::ListUpperRoman; } else { value = value.toLower(); if (value == QLatin1String("square")) diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index addd7a5..02b1c63 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -212,6 +212,55 @@ QString QTextList::itemText(const QTextBlock &blockIt) const } } break; + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: + { + if (item < 5000) { + QByteArray romanNumeral; + + // works for up to 4999 items + static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm"; + static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM"; + QByteArray romanSymbols; // wrap to have "mid" + if (style == QTextListFormat::ListLowerRoman) + romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower)); + else + romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper)); + + int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 }; + int n = item; + for (int i = 12; i >= 0; n %= c[i], i--) { + int q = n / c[i]; + if (q > 0) { + int startDigit = i + (i+3)/4; + int numDigits; + if (i % 4) { + // c[i] == 4|5|9|40|50|90|400|500|900 + if ((i-2) % 4) { + // c[i] == 4|9|40|90|400|900 => with substraction (IV, IX, XL, XC, ...) + numDigits = 2; + } + else { + // c[i] == 5|50|500 (V, L, D) + numDigits = 1; + } + } + else { + // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...) + numDigits = q; + } + + romanNumeral.append(romanSymbols.mid(startDigit, numDigits)); + } + } + result = QString::fromLatin1(romanNumeral); + } + else { + result = QLatin1String("?"); + } + + } + break; default: Q_ASSERT(false); } diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index b0c16ee..883cf80 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -174,6 +174,10 @@ static QString bulletChar(QTextListFormat::Style style) return QString::fromLatin1("a"); case QTextListFormat::ListUpperAlpha: return QString::fromLatin1("A"); + case QTextListFormat::ListLowerRoman: + return QString::fromLatin1("i"); + case QTextListFormat::ListUpperRoman: + return QString::fromLatin1("I"); default: case QTextListFormat::ListStyleUndefined: return QString(); @@ -619,7 +623,9 @@ void QTextOdfWriter::writeListFormat(QXmlStreamWriter &writer, QTextListFormat f QTextListFormat::Style style = format.style(); if (style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha - || style == QTextListFormat::ListUpperAlpha) { + || style == QTextListFormat::ListUpperAlpha + || style == QTextListFormat::ListLowerRoman + || style == QTextListFormat::ListUpperRoman) { writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-number")); writer.writeAttribute(styleNS, QString::fromLatin1("num-format"), bulletChar(style)); writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), QString::fromLatin1(".")); diff --git a/tests/auto/qtextlist/tst_qtextlist.cpp b/tests/auto/qtextlist/tst_qtextlist.cpp index 658b8bb..e41d3be 100644 --- a/tests/auto/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/qtextlist/tst_qtextlist.cpp @@ -67,6 +67,8 @@ private slots: void item(); void autoNumbering(); void autoNumberingRTL(); + void romanNumbering(); + void romanNumberingLimit(); void formatChange(); void cursorNavigation(); void partialRemoval(); @@ -142,6 +144,40 @@ void tst_QTextList::autoNumberingRTL() QVERIFY(cursor.currentList()->itemText(cursor.block()) == ".B"); } +void tst_QTextList::romanNumbering() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListUpperRoman); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 4998; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 4999); + + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4998); + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "MMMMCMXCIX."); +} + +void tst_QTextList::romanNumberingLimit() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerRoman); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 4999; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 5000); + + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4999); + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "?."); +} + void tst_QTextList::formatChange() { // testing the formatChanged slot in QTextListManager |