diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 17 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentfragment.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextformat.cpp | 30 | ||||
-rw-r--r-- | src/gui/text/qtextformat.h | 9 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextlist.cpp | 23 | ||||
-rw-r--r-- | src/gui/text/qtextmarkdownimporter.cpp | 3 | ||||
-rw-r--r-- | src/gui/text/qtextmarkdownwriter.cpp | 4 |
9 files changed, 77 insertions, 14 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 3572988e3e..e5dc5136cb 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2996,18 +2996,25 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block) if (list->itemNumber(block) == 0) { // first item? emit <ul> or appropriate const QTextListFormat format = list->format(); const int style = format.style(); + bool ordered = false; switch (style) { - case QTextListFormat::ListDecimal: html += "<ol"_L1; break; case QTextListFormat::ListDisc: html += "<ul"_L1; break; case QTextListFormat::ListCircle: html += "<ul type=\"circle\""_L1; break; case QTextListFormat::ListSquare: html += "<ul type=\"square\""_L1; break; - case QTextListFormat::ListLowerAlpha: html += "<ol type=\"a\""_L1; break; - case QTextListFormat::ListUpperAlpha: html += "<ol type=\"A\""_L1; break; - case QTextListFormat::ListLowerRoman: html += "<ol type=\"i\""_L1; break; - case QTextListFormat::ListUpperRoman: html += "<ol type=\"I\""_L1; break; + case QTextListFormat::ListDecimal: html += "<ol"_L1; ordered = true; break; + case QTextListFormat::ListLowerAlpha: html += "<ol type=\"a\""_L1; ordered = true; break; + case QTextListFormat::ListUpperAlpha: html += "<ol type=\"A\""_L1; ordered = true; break; + case QTextListFormat::ListLowerRoman: html += "<ol type=\"i\""_L1; ordered = true; break; + case QTextListFormat::ListUpperRoman: html += "<ol type=\"I\""_L1; ordered = true; break; default: html += "<ul"_L1; // ### should not happen } + if (ordered && format.start() != 1) { + html += " start=\""_L1; + html += QString::number(format.start()); + html += u'"'; + } + QString styleString = QString::fromLatin1("margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px;"); if (format.hasProperty(QTextFormat::ListIndent)) { diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index 7d8b2eaa93..9e99992929 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -699,6 +699,8 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processSpecialNodes() listFmt.setNumberPrefix(currentNode->textListNumberPrefix); if (!currentNode->textListNumberSuffix.isNull()) listFmt.setNumberSuffix(currentNode->textListNumberSuffix); + if (currentNode->listStart != 1) + listFmt.setStart(currentNode->listStart); ++indent; if (currentNode->hasCssListIndent) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 508d472062..8be3a0d442 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -2610,7 +2610,8 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const The style used to decorate each item is set with setStyle() and can be read with the style() function. The style controls the type of bullet points and numbering scheme used for items in the list. Note that lists that use the - decimal numbering scheme begin counting at 1 rather than 0. + decimal numbering scheme begin counting at 1 rather than 0, unless it has + been overridden via setStart(). Style properties can be set to further configure the appearance of list items; for example, the ListNumberPrefix and ListNumberSuffix properties @@ -2647,6 +2648,7 @@ QTextListFormat::QTextListFormat() : QTextFormat(ListFormat) { setIndent(1); + setStart(1); } /*! @@ -2751,6 +2753,32 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) */ /*! + \fn void QTextListFormat::setStart(int start) + \since 6.6 + + Sets the list format's \a start index. + + This allows you to start a list with an index other than 1. This can be + used with all sorted list types: for example if the style() is + QTextListFormat::ListLowerAlpha and start() is \c 4, the first list item + begins with "d". It does not have any effect on unsorted list types. + + The default start is \c 1. + + \sa start() +*/ + +/*! + \fn int QTextListFormat::start() const + \since 6.6 + + Returns the number to be shown by the first list item, if the style() is + QTextListFormat::ListDecimal, or to offset other sorted list types. + + \sa setStart() +*/ + +/*! \class QTextFrameFormat \reentrant diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index 02c66279e2..c009d328cb 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -188,6 +188,7 @@ public: ListIndent = 0x3001, ListNumberPrefix = 0x3002, ListNumberSuffix = 0x3003, + ListStart = 0x3004, // table and frame properties FrameBorder = 0x4000, @@ -753,6 +754,9 @@ public: inline QString numberSuffix() const { return stringProperty(ListNumberSuffix); } + inline void setStart(int indent); + inline int start() const { return intProperty(ListStart); } + protected: explicit QTextListFormat(const QTextFormat &fmt); friend class QTextFormat; @@ -772,6 +776,11 @@ inline void QTextListFormat::setNumberPrefix(const QString &np) inline void QTextListFormat::setNumberSuffix(const QString &ns) { setProperty(ListNumberSuffix, ns); } +inline void QTextListFormat::setStart(int astart) +{ + setProperty(ListStart, astart); +} + class Q_GUI_EXPORT QTextImageFormat : public QTextCharFormat { public: diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 55c64bb256..16e2d7bd3a 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1634,6 +1634,8 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes) else if (value == "none"_L1) node->listStyle = QTextListFormat::ListStyleUndefined; } + } else if (key == "start"_L1) { + setIntAttribute(&node->listStart, value); } break; case Html_li: diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h index 0085c01e87..ecbc238171 100644 --- a/src/gui/text/qtexthtmlparser_p.h +++ b/src/gui/text/qtexthtmlparser_p.h @@ -150,6 +150,7 @@ struct QTextHtmlParserNode { uint displayMode : 3; // QTextHtmlElement::DisplayMode uint hasHref : 1; QTextListFormat::Style listStyle; + int listStart = 1; QString textListNumberPrefix; QString textListNumberSuffix; QString imageName; diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index 8b4b308d0c..90a6cf8867 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -147,6 +147,9 @@ QString QTextList::itemText(const QTextBlock &blockIt) const QString numberPrefix; QString numberSuffix = u"."_s; + // the number of the item might be offset by start, which defaults to 1 + const int itemNumber = item + format().start() - 1; + if (format().hasProperty(QTextFormat::ListNumberPrefix)) numberPrefix = format().numberPrefix(); if (format().hasProperty(QTextFormat::ListNumberSuffix)) @@ -154,15 +157,21 @@ QString QTextList::itemText(const QTextBlock &blockIt) const switch (style) { case QTextListFormat::ListDecimal: - result = QString::number(item); + result = QString::number(itemNumber); break; // from the old richtext case QTextListFormat::ListLowerAlpha: case QTextListFormat::ListUpperAlpha: { + // match the html default behavior of falling back to decimal numbers + if (itemNumber < 1) { + result = QString::number(itemNumber); + break; + } + const char baseChar = style == QTextListFormat::ListUpperAlpha ? 'A' : 'a'; - int c = item; + int c = itemNumber; while (c > 0) { c--; result.prepend(QChar::fromUcs2(baseChar + (c % 26))); @@ -173,7 +182,10 @@ QString QTextList::itemText(const QTextBlock &blockIt) const case QTextListFormat::ListLowerRoman: case QTextListFormat::ListUpperRoman: { - if (item < 5000) { + // match the html default behavior of falling back to decimal numbers + if (itemNumber < 1) { + result = QString::number(itemNumber); + } else if (itemNumber < 5000) { QByteArray romanNumeral; // works for up to 4999 items @@ -186,7 +198,7 @@ QString QTextList::itemText(const QTextBlock &blockIt) const romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper)); int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 }; - int n = item; + int n = itemNumber; for (int i = 12; i >= 0; n %= c[i], i--) { int q = n / c[i]; if (q > 0) { @@ -212,8 +224,7 @@ QString QTextList::itemText(const QTextBlock &blockIt) const } } result = QString::fromLatin1(romanNumeral); - } - else { + } else { result = u"?"_s; } diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp index 8838568fd0..bb95678ef1 100644 --- a/src/gui/text/qtextmarkdownimporter.cpp +++ b/src/gui/text/qtextmarkdownimporter.cpp @@ -227,7 +227,8 @@ int QTextMarkdownImporter::cbEnterBlock(int blockType, void *det) m_listFormat.setIndent(m_listStack.size() + 1); m_listFormat.setNumberSuffix(QChar::fromLatin1(detail->mark_delimiter)); m_listFormat.setStyle(QTextListFormat::ListDecimal); - qCDebug(lcMD, "OL xx%d level %d", detail->mark_delimiter, int(m_listStack.size()) + 1); + m_listFormat.setStart(detail->start); + qCDebug(lcMD, "OL xx%d level %d start %d", detail->mark_delimiter, int(m_listStack.size()) + 1, detail->start); } break; case MD_BLOCK_TD: { MD_BLOCK_TD_DETAIL *detail = static_cast<MD_BLOCK_TD_DETAIL *>(det); diff --git a/src/gui/text/qtextmarkdownwriter.cpp b/src/gui/text/qtextmarkdownwriter.cpp index f535ff8aa8..5fb67ccc67 100644 --- a/src/gui/text/qtextmarkdownwriter.cpp +++ b/src/gui/text/qtextmarkdownwriter.cpp @@ -344,7 +344,9 @@ int QTextMarkdownWriter::writeBlock(const QTextBlock &block, bool wrap, bool ign if (block.textList()) { // it's a list-item auto fmt = block.textList()->format(); const int listLevel = fmt.indent(); - const int number = block.textList()->itemNumber(block) + 1; + // Negative numbers don't start a list in Markdown, so ignore them. + const int start = fmt.start() >= 0 ? fmt.start() : 1; + const int number = block.textList()->itemNumber(block) + start; QByteArray bullet = " "; bool numeric = false; switch (fmt.style()) { |