From 046447a6fa686ed076a7df8d27b00abe0811750b Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 18 Apr 2023 20:44:37 +0000 Subject: qdoc: Add status information to the requisites table for types QDoc provides various ways to document the status of an entity; \deprecated, \preliminary, and \modulestate commands. These commands produce a brief sentence describing the status, however, for C++ and QML types, a logical place for this information is also the 'requisites' table at the start of the page. Having the status information in the table makes it more apparent for the reader that they're looking at documentation for a deprecated or preliminary type. For HTML generator, this commit also adds a element that allows additional visuals via CSS (e.g. an icon) for a specific status. Pick-to: 6.5 Fixes: QTBUG-113026 Change-Id: If38a6d51631277a0d98b2cb702acf2598b694643 Reviewed-by: Luca Di Sera --- src/qdoc/qdoc/docbookgenerator.cpp | 8 ++++ src/qdoc/qdoc/generator.cpp | 31 ++++++++++++++ src/qdoc/qdoc/generator.h | 3 ++ src/qdoc/qdoc/htmlgenerator.cpp | 48 ++++++++++++++++++++-- src/qdoc/qdoc/htmlgenerator.h | 2 + .../docbook/qml-qdoc-test-oldtype.xml | 36 ++++++++++++++++ .../docbook/qml-test-nover-typenoversion.xml | 6 +++ .../expected_output/qml-qdoc-test-oldtype.html | 32 +++++++++++++++ .../qml-test-nover-typenoversion.html | 2 +- .../qdoc/generatedoutput/expected_output/test.qhp | 7 ++++ .../expected_output/testtagfile.tags | 4 ++ .../qdoc/generatedoutput/testdata/qml/type.cpp | 7 ++++ .../qdoc/generatedoutput/tst_generatedoutput.cpp | 2 + 13 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-oldtype.xml create mode 100644 tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-oldtype.html diff --git a/src/qdoc/qdoc/docbookgenerator.cpp b/src/qdoc/qdoc/docbookgenerator.cpp index cc75cac07..648a0a43d 100644 --- a/src/qdoc/qdoc/docbookgenerator.cpp +++ b/src/qdoc/qdoc/docbookgenerator.cpp @@ -2825,6 +2825,10 @@ void DocBookGenerator::generateRequisites(const Aggregate *aggregate) generateEndRequisite(); } + // Status. + if (auto status = formatStatus(aggregate, m_qdb); status) + generateRequisite("Status", status.value()); + // Write the elements as a list if not empty. delete m_writer; m_writer = oldWriter; @@ -2928,6 +2932,10 @@ void DocBookGenerator::generateQmlRequisites(const QmlTypeNode *qcn) generateEndRequisite(); } + // Status. + if (auto status = formatStatus(qcn, m_qdb); status) + generateRequisite("Status:", status.value()); + m_writer->writeEndElement(); // variablelist newLine(); } diff --git a/src/qdoc/qdoc/generator.cpp b/src/qdoc/qdoc/generator.cpp index f5df13087..174cb9c8f 100644 --- a/src/qdoc/qdoc/generator.cpp +++ b/src/qdoc/qdoc/generator.cpp @@ -1106,6 +1106,37 @@ QString Generator::formatSince(const Node *node) return node->since(); } +/*! + \internal + Returns a string representing status information of a \a node. + + If a status description is returned, it is one of: + \list + \li 'Deprecated [since ]' (\\deprecated []), + \li 'Preliminary' (\\preliminary), or + \li The description adopted from associated module's state: + \c {\modulestate {}}. + \endlist + + Otherwise, returns \c std::nullopt. +*/ +std::optional formatStatus(const Node *node, QDocDatabase *qdb) +{ + QString status; + + if (node->status() == Node::Deprecated) { + status = u"Deprecated"_s; + if (const auto since = node->deprecatedSince(); !since.isEmpty()) + status += " since %1"_L1.arg(since); + } else if (node->status() == Node::Preliminary) { + status = u"Preliminary"_s; + } else if (const auto collection = qdb->getModuleNode(node); collection) { + status = collection->state(); + } + + return status.isEmpty() ? std::nullopt : std::optional(status); +} + void Generator::generateSince(const Node *node, CodeMarker *marker) { if (!node->since().isEmpty()) { diff --git a/src/qdoc/qdoc/generator.h b/src/qdoc/qdoc/generator.h index fbbff827f..6611cb7b6 100644 --- a/src/qdoc/qdoc/generator.h +++ b/src/qdoc/qdoc/generator.h @@ -13,6 +13,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -198,6 +199,8 @@ protected: QString m_sectionNumber {}; }; +std::optional formatStatus(const Node *node, QDocDatabase *qdb); + QT_END_NAMESPACE #endif diff --git a/src/qdoc/qdoc/htmlgenerator.cpp b/src/qdoc/qdoc/htmlgenerator.cpp index 304989f9c..545541aad 100644 --- a/src/qdoc/qdoc/htmlgenerator.cpp +++ b/src/qdoc/qdoc/htmlgenerator.cpp @@ -36,6 +36,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + bool HtmlGenerator::s_inUnorderedList { false }; HtmlGenerator::HtmlGenerator(FileResolver& file_resolver) : XmlGenerator(file_resolver) {} @@ -1917,10 +1919,11 @@ void HtmlGenerator::generateRequisites(Aggregate *aggregate, CodeMarker *marker) const QString instantiatedByText = "Instantiated By"; const QString qtVariableText = "qmake"; const QString cmakeText = "CMake"; + const QString statusText = "Status"; // The order of the requisites matter - const QStringList requisiteorder { headerText, cmakeText, qtVariableText, sinceText, - instantiatedByText, inheritsText, inheritedBytext }; + const QStringList requisiteorder { headerText, cmakeText, qtVariableText, sinceText, + instantiatedByText, inheritsText, inheritedBytext, statusText }; addIncludeFileToMap(aggregate, marker, requisites, text, headerText); addSinceToMap(aggregate, requisites, &text, sinceText); @@ -1939,6 +1942,9 @@ void HtmlGenerator::generateRequisites(Aggregate *aggregate, CodeMarker *marker) addInheritedByToMap(requisites, &text, inheritedBytext, classe); } + // Add the state description (if any) to the map + addStatusToMap(aggregate, requisites, text, statusText); + if (!requisites.isEmpty()) { // generate the table generateTheTable(requisiteorder, requisites, headerText, aggregate, marker); @@ -2095,6 +2101,38 @@ void HtmlGenerator::addSinceToMap(const Aggregate *aggregate, QMap element, to the \a + * requisites map. + * + * The span element can be used for adding CSS styling/icon associated with a specific status. + * The span class name is constructed by converting the description (sans \\deprecated + * version info) to lowercase and replacing all non-alphanum characters with hyphens. In + * addition, the span has a class \c status. For example, + * 'Tech Preview' -> class="status tech-preview" +*/ +void HtmlGenerator::addStatusToMap(const Aggregate *aggregate, QMap &requisites, + Text &text, const QString &statusText) const +{ + auto status{formatStatus(aggregate, m_qdb)}; + if (!status) + return; + + QString spanClass; + if (aggregate->status() == Node::Deprecated) + spanClass = u"deprecated"_s; // Disregard any version info + else + spanClass = Utilities::canonicalizeFileName(status.value()); + + text.clear(); + text << Atom(Atom::String, status.value()) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_SPAN + + "class=\"status %1\""_L1.arg(spanClass)) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_SPAN); + requisites.insert(statusText, text); +} + /*! * \internal * Adds the includes (from the \\includefile command) to the map. @@ -2130,6 +2168,7 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker) const QString inheritedBytext = "Inherited By:"; const QString inheritsText = "Inherits:"; const QString instantiatesText = "Instantiates:"; + const QString statusText = "Status:"; // add the module name and version to the map QString logicalModuleVersion; @@ -2189,9 +2228,12 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker) requisites.insert(inheritedBytext, text); } + // Add the state description (if any) to the map + addStatusToMap(qcn, requisites, text, statusText); + // The order of the requisites matter const QStringList requisiteorder { importText, sinceText, instantiatesText, inheritsText, - inheritedBytext }; + inheritedBytext, statusText }; if (!requisites.isEmpty()) { // generate the table diff --git a/src/qdoc/qdoc/htmlgenerator.h b/src/qdoc/qdoc/htmlgenerator.h index 3c12ce328..4592e41d7 100644 --- a/src/qdoc/qdoc/htmlgenerator.h +++ b/src/qdoc/qdoc/htmlgenerator.h @@ -107,6 +107,8 @@ private: const QString &headerText); void addSinceToMap(const Aggregate *aggregate, QMap &requisites, Text *text, const QString &sinceText) const; + void addStatusToMap(const Aggregate *aggregate, QMap &requisites, Text &text, + const QString &statusText) const; void addCMakeInfoToMap(const Aggregate *aggregate, QMap &requisites, Text *text, const QString &CMakeInfo) const; void addQtVariableToMap(const Aggregate *aggregate, QMap &requisites, Text *text, diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-oldtype.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-oldtype.xml new file mode 100644 index 000000000..ce2999582 --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-qdoc-test-oldtype.xml @@ -0,0 +1,36 @@ + + + +OldType QML Type +Test +A test project for QDoc build artifacts + +Deprecated old type. +This type is deprecated since 1.0. We strongly advise against using it in new code. +This type was introduced in Qt 1.1. + + + + +Import Statement + +import QDoc.Test 1.1 + + + +Since: + +Qt 1.1 + + + +Status: + +Deprecated since 1.0 + + + + +Detailed Description + + diff --git a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-test-nover-typenoversion.xml b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-test-nover-typenoversion.xml index 676098113..87576add4 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-test-nover-typenoversion.xml +++ b/tests/auto/qdoc/generatedoutput/expected_output/docbook/qml-test-nover-typenoversion.xml @@ -28,6 +28,12 @@ TestDerived + +Status: + +Tech Preview + + Detailed Description diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-oldtype.html b/tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-oldtype.html new file mode 100644 index 000000000..f314ad331 --- /dev/null +++ b/tests/auto/qdoc/generatedoutput/expected_output/qml-qdoc-test-oldtype.html @@ -0,0 +1,32 @@ + + + + + + + OldType QML Type | Test + + +
  • Types
  • +
  • OldType
  • + +

    OldType QML Type

    + +

    Deprecated old type. More...

    + +
    +
    Import Statement: import QDoc.Test 1.1
    Since: Qt 1.1
    Status: Deprecated since 1.0
    + +

    Detailed Description

    + + + diff --git a/tests/auto/qdoc/generatedoutput/expected_output/qml-test-nover-typenoversion.html b/tests/auto/qdoc/generatedoutput/expected_output/qml-test-nover-typenoversion.html index 432085d63..b426c95a9 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/qml-test-nover-typenoversion.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/qml-test-nover-typenoversion.html @@ -23,7 +23,7 @@

    Another QML type documented in a .cpp file. More...

    -
    Import Statement: import Test.NoVer
    Since: Qt 1.1
    Instantiates: TestDerived
      + Import Statement: import Test.NoVer Since: Qt 1.1 Instantiates: TestDerived Status: Tech Preview diff --git a/tests/auto/qdoc/generatedoutput/expected_output/test.qhp b/tests/auto/qdoc/generatedoutput/expected_output/test.qhp index 7ef863788..2070d5635 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/test.qhp +++ b/tests/auto/qdoc/generatedoutput/expected_output/test.qhp @@ -42,6 +42,9 @@
      +
      +
      +
      @@ -72,6 +75,8 @@ + + @@ -172,6 +177,8 @@ qml-qdoc-test-child.html qml-qdoc-test-doctest-members.html qml-qdoc-test-doctest.html + qml-qdoc-test-oldtype-members.html + qml-qdoc-test-oldtype.html qml-qdoc-test-type-members.html qml-qdoc-test-type-obsolete.html qml-qdoc-test-type.html diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testtagfile.tags b/tests/auto/qdoc/generatedoutput/expected_output/testtagfile.tags index 891909786..729ced4c0 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/testtagfile.tags +++ b/tests/auto/qdoc/generatedoutput/expected_output/testtagfile.tags @@ -86,6 +86,10 @@ (bool really) + + QDoc.Test.OldType + qml-qdoc-test-oldtype.html + UIComponents.ProgressBar qml-uicomponents-progressbar.html diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp b/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp index f0d913853..8e4d6e677 100644 --- a/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp +++ b/tests/auto/qdoc/generatedoutput/testdata/qml/type.cpp @@ -41,6 +41,13 @@ \brief Another QML type documented in a .cpp file. */ +/*! + \qmltype OldType + \inqmlmodule QDoc.Test + \brief Deprecated old type. + \deprecated [1.0] +*/ + /*! \qmlproperty int Type::id \readonly diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp index 552ed39cc..f39a87223 100644 --- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp +++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp @@ -242,6 +242,7 @@ void tst_generatedOutput::htmlFromQml() "qml-qdoc-test-type-members.html " "qml-qdoc-test-type-obsolete.html " "qml-qdoc-test-type.html " + "qml-qdoc-test-oldtype.html " "qml-test-nover-typenoversion.html " "qml-test-nover-typenoversion-members.html " "qml-uicomponents-progressbar.html " @@ -332,6 +333,7 @@ void tst_generatedOutput::docBookFromQml() "docbook/qml-qdoc-test-yetanotherchild.xml " "docbook/qml-qdoc-test-doctest.xml " "docbook/qml-qdoc-test-type.xml " + "docbook/qml-qdoc-test-oldtype.xml " "docbook/qml-test-nover-typenoversion.xml " "docbook/qml-uicomponents-progressbar.xml " "docbook/qml-uicomponents-switch.xml " -- cgit v1.2.1