From e58a29bdaecd81738ac487fe9a669a9adeeb8caa Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 20 May 2022 23:49:04 +0200 Subject: [PATCH] Use CSS classes on html list items for checkbox support If we replace the bullet character with a UC checkbox character, it looks ok in a browser, and the HTML parser can recover the BlockMarker attribute from the css class. [ChangeLog][QtGui][Text] Checkbox list items can now be read and written in both HTML and Markdown, including conversions. Task-number: QTBUG-103714 Change-Id: Ic6b74512075cd4ac16d6f80fdf55b221447491a9 Reviewed-by: Qt CI Bot Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit eee9d252028c4b3b743c77a406cd6939eda3962f) Reviewed-by: Volker Hilsheimer --- src/gui/text/qtextdocument.cpp | 16 +++++++- src/gui/text/qtexthtmlparser.cpp | 8 ++++ .../text/qtextdocument/tst_qtextdocument.cpp | 41 ++++++++++++------- .../tst_qtextmarkdownwriter.cpp | 3 ++ 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 71511257f51..463026ed238 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2372,6 +2372,8 @@ QString QTextHtmlExporter::toHtml(ExportMode mode) html += ""_L1; html += ""_L1; + html += "\">\n"_L1; } html += "blockFormat.setMarker(QTextBlockFormat::MarkerType::Unchecked); + else if (value == "checked"_L1) + node->blockFormat.setMarker(QTextBlockFormat::MarkerType::Checked); + } + break; case Html_a: if (key == "href"_L1) node->charFormat.setAnchorHref(value); diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index ad9e1965b6c..d10027b7a01 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -274,6 +274,8 @@ void tst_QTextDocument::init() "" "\n"); htmlHead = htmlHead.arg(defaultFont.family()) @@ -1371,7 +1373,7 @@ void tst_QTextDocument::toHtml_data() QTest::newRow("lists") << QTextDocumentFragment(&doc) << QString("EMPTYBLOCK") + - QString("
  • Blubb
  • \n
  • Blah
"); + QString("
    \n
  • Blubb
  • \n
  • Blah
"); } { @@ -1394,7 +1396,7 @@ void tst_QTextDocument::toHtml_data() QTest::newRow("charfmt-for-list-item") << QTextDocumentFragment(&doc) << QString("EMPTYBLOCK") + - QString("
  • Blubb
  • \n
  • Blah
"); + QString("
    \n
  • Blubb
  • \n
  • Blah
"); } { @@ -1424,7 +1426,7 @@ void tst_QTextDocument::toHtml_data() QTest::newRow("list-indent") << QTextDocumentFragment(&doc) << QString("EMPTYBLOCK") + - QString("
  • Blah
"); + QString("
    \n
  • Blah
"); } { @@ -1712,7 +1714,7 @@ void tst_QTextDocument::toHtml_data() QTest::newRow("list-ul-margin") << QTextDocumentFragment(&doc) << QString("EMPTYBLOCK") + - QString("
  • Blah
"); + QString("
    \n
  • Blah
"); } { CREATE_DOC_AND_CURSOR(); @@ -1722,12 +1724,12 @@ void tst_QTextDocument::toHtml_data() cursor.insertHtml(listHtml); QTest::newRow("nested-lists-one") << QTextDocumentFragment(&doc) - << QString("
  • \n
  • " - "item-1
  • \n
  • item-2\n
    • \n
    • item-2\n
        \n
      • item-2.1
      • \n
      • item-2.2\n
        • item-2.2.1
      • \n" - "
      • item-2.3\n
        • " + "DEFAULTULSTYLE 3;\">\n
        • item-2.2.1
      • \n" + "
      • item-2.3\n
          \n
        • " "item-2.3.1
    • \n
    • item-3
    "); } { @@ -1736,9 +1738,9 @@ void tst_QTextDocument::toHtml_data() cursor.insertHtml(listHtml); QTest::newRow("nested-lists-two") << QTextDocumentFragment(&doc) - << QString("
    • \n
    • " - "item-1
    • \n
    • item-2\n
      • \n
      • item-2\n
          \n
        • item-2.1
      "); } { @@ -1748,9 +1750,9 @@ void tst_QTextDocument::toHtml_data() cursor.insertHtml(listHtml); QTest::newRow("nested-lists-three") << QTextDocumentFragment(&doc) - << QString("
      • \n
      • " - "item-1
      • \n
      • item-2\n
        • \n
        • item-2\n
            \n
          • item-2.1
          • \n
          • item-2.2
          " "
        "); } @@ -1761,12 +1763,23 @@ void tst_QTextDocument::toHtml_data() cursor.insertHtml(listHtml); QTest::newRow("not-nested-list") << QTextDocumentFragment(&doc) - << QString("
        • \n
        • " - "item-1.1
        • \n
        • item-1.2
        \n
          " + "item-1.1\n
        • item-1.2
        \n
          \n" "
        • item-2.1
        "); } + { + CREATE_DOC_AND_CURSOR(); + const QString listHtml = "
        • bullet
        • unchecked item
        • checked item
        "; + cursor.insertHtml(listHtml); + + QTest::newRow("list with and without checkboxes") << QTextDocumentFragment(&doc) + << QString("
          \n" + "
        • bullet
        • \n" + "
        • unchecked item
        • \n" + "
        • checked item
        "); + } } void tst_QTextDocument::toHtml() diff --git a/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp b/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp index b258869dfd5..2b6b1ecca50 100644 --- a/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp +++ b/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp @@ -502,6 +502,9 @@ void tst_QTextMarkdownWriter::fromHtml_data() QTest::newRow("preformats with embedded backticks") << "
        none `one` ``two``
        plain
        ```three``` ````four````
        plain" << "```\nnone `one` ``two``\n\n```\nplain\n\n```\n```three``` ````four````\n\n```\nplain\n\n"; + QTest::newRow("list items with and without checkboxes") << + "
        • bullet
        • unchecked item
        • checked item
        " << + "- bullet\n- [ ] unchecked item\n- [x] checked item\n"; } void tst_QTextMarkdownWriter::fromHtml()