diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index d917bc73fc5..be83642a9a0 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -1113,7 +1113,10 @@ void Generator::generateSince(const Node *node, CodeMarker *marker) if (project.isEmpty()) text << "version"; else - text << project; + text << Atom(Atom::Link, project) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, project) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); text << " " << since[0]; } else { // Reconstruct the string. diff --git a/src/tools/qdoc/generator.h b/src/tools/qdoc/generator.h index 4657f71e1d0..d6ea3fb2f94 100644 --- a/src/tools/qdoc/generator.h +++ b/src/tools/qdoc/generator.h @@ -185,6 +185,17 @@ protected: QString tagFile_; QStack outStreamStack; + void appendFullName(Text& text, + const Node *apparentNode, + const Node *relative, + const Node *actualNode = 0); + void appendFullName(Text& text, + const Node *apparentNode, + const QString& fullName, + const Node *actualNode); + void appendFullNames(Text& text, const NodeList& nodes, const Node* relative); + void appendSortedNames(Text& text, const ClassNode *classe, const QList &classes); + private: static Generator* currentGenerator_; static QStringList exampleDirs; @@ -209,16 +220,6 @@ private: static bool redirectDocumentationToDevNull_; static Passes qdocPass_; - void appendFullName(Text& text, - const Node *apparentNode, - const Node *relative, - const Node *actualNode = 0); - void appendFullName(Text& text, - const Node *apparentNode, - const QString& fullName, - const Node *actualNode); - void appendFullNames(Text& text, const NodeList& nodes, const Node* relative); - void appendSortedNames(Text& text, const ClassNode *classe, const QList &classes); void generateReimplementedFrom(const FunctionNode *func, CodeMarker *marker); QString amp; diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index d5a1647c5a6..b307d9c19b4 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -1114,8 +1114,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) QList
sections; QList
::ConstIterator s; - ClassNode* classe = 0; - QString title; QString rawTitle; QString fullTitle; @@ -1125,7 +1123,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) title = rawTitle + " Namespace"; } else if (inner->type() == Node::Class) { - classe = static_cast(inner); rawTitle = inner->plainName(); fullTitle = inner->plainFullName(); title = rawTitle + " Class"; @@ -1140,16 +1137,9 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) generateTableOfContents(inner,marker,§ions); generateTitle(title, subtitleText, SmallSubTitle, inner, marker); generateBrief(inner, marker); - generateIncludes(inner, marker); + generateRequisites(inner, marker); generateStatus(inner, marker); - if (classe) { - generateInherits(classe, marker); - generateInheritedBy(classe, marker); - if (classe->qmlElement() != 0) - generateInstantiatedBy(classe,marker); - } generateThreadSafeness(inner, marker); - generateSince(inner, marker); out() << "
    \n"; @@ -1530,10 +1520,7 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) const_cast(dn)->setCurrentChild(); ClassNode* cn = qml_cn->classNode(); generateBrief(qml_cn, marker); - generateQmlInherits(qml_cn, marker); - generateQmlInheritedBy(qml_cn, marker); - generateQmlInstantiates(qml_cn, marker); - generateSince(qml_cn, marker); + generateQmlRequisites(qml_cn, marker); QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker); if (!allQmlMembersLink.isEmpty()) { @@ -1839,6 +1826,259 @@ void HtmlGenerator::generateFooter(const Node *node) out() << "\n"; } +/*! +Lists the required imports and includes in a table. +The number of rows is known, so this path is simpler than the generateSection() path. +*/ +void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) +{ + QMap requisites; + Text text; + + const QString headerText = "Header:"; + const QString sinceText = "Since:"; + const QString inheritedBytext = "Inherited By:"; + const QString inheritsText = "Inherits:"; + const QString instantiatedByText = "Instantiated By:"; + + //add the includes to the map + if (!inner->includes().isEmpty()) { + text.clear(); + text << formattingRightMap()[ATOM_FORMATTING_BOLD] + << formattingLeftMap()[ATOM_FORMATTING_TELETYPE] + << highlightedCode(indent(codeIndent, + marker->markedUpIncludes(inner->includes())), + inner) + << formattingRightMap()[ATOM_FORMATTING_TELETYPE]; + requisites.insert(headerText, text); + } + + //The order of the requisites matter + QStringList requisiteorder; + requisiteorder << headerText + << sinceText + << instantiatedByText + << inheritsText + << inheritedBytext; + + //add the since and project into the map + if (!inner->since().isEmpty()) { + text.clear(); + QStringList since = inner->since().split(QLatin1Char(' ')); + if (since.count() == 1) { + // Handle legacy use of \since . + if (project.isEmpty()) + text << "version"; + else + text << Atom(Atom::Link, project) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, project) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + text << " " << since[0]; + } + else { + // Reconstruct the string. + text << " " << since.join(' '); + } + text << Atom::ParaRight; + requisites.insert(sinceText, text); + } + + //add the instantiated-by to the map if the class node is not internal + if (inner->type() == Node::Class) { + ClassNode* classe = static_cast(inner); + if (classe->qmlElement() != 0 && classe->status() != Node::Internal) { + text.clear(); + text << Atom(Atom::LinkNode, CodeMarker::stringForNode(classe->qmlElement())) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, classe->qmlElement()->name()) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + requisites.insert(instantiatedByText, text); + + } + + //add the inherits to the map + QList::ConstIterator r; + int index; + if (!classe->baseClasses().isEmpty()) { + text.clear(); + r = classe->baseClasses().constBegin(); + index = 0; + while (r != classe->baseClasses().constEnd()) { + text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node)) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, (*r).dataTypeWithTemplateArgs) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + + if ((*r).access == Node::Protected) { + text << " (protected)"; + } + else if ((*r).access == Node::Private) { + text << " (private)"; + } + text << separator(index++, classe->baseClasses().count()); + ++r; + } + text << Atom::ParaRight; + requisites.insert(inheritsText, text); + } + + //add the inherited-by to the map + if (!classe->derivedClasses().isEmpty()) { + text.clear(); + text << Atom::ParaLeft; + appendSortedNames(text, classe, classe->derivedClasses()); + text << Atom::ParaRight; + requisites.insert(inheritedBytext, text); + } + + } + + if (!requisites.isEmpty()) { + //generate the table + out() << "\n"; + + QStringList::ConstIterator i; + for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) { + + if (requisites.contains(*i)) { + out() << "" + << ""; + } + } + out() << "
    " + << *i + << " "; + + if (*i == headerText) + out() << requisites.value(*i).toString(); + else + generateText(requisites.value(*i), inner, marker); + out() << "
    "; + } +} + +/*! +Lists the required imports and includes in a table. +The number of rows is known, so this path is simpler than the generateSection() path. +*/ +void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker) +{ + if (!qcn) + return; + QMap requisites; + Text text; + + const QString importText = "Import Statement:"; + const QString sinceText = "Since:"; + const QString inheritedBytext = "Inherited By:"; + const QString inheritsText = "Inherits:"; + const QString instantiatesText = "Instantiates:"; + + //The order of the requisites matter + QStringList requisiteorder; + requisiteorder << importText + << sinceText + << instantiatesText + << inheritsText + << inheritedBytext; + + //add the module name and version to the map + text.clear(); + text << formattingRightMap()[ATOM_FORMATTING_BOLD] + << formattingLeftMap()[ATOM_FORMATTING_TELETYPE] + << "import " + qcn->qmlModuleName() + " " + qcn->qmlModuleVersion() + << formattingRightMap()[ATOM_FORMATTING_TELETYPE]; + requisites.insert(importText, text); + + //add the since and project into the map + if (!qcn->since().isEmpty()) { + text.clear(); + QStringList since = qcn->since().split(QLatin1Char(' ')); + if (since.count() == 1) { + // Handle legacy use of \since . + if (project.isEmpty()) + text << "version"; + else + text << Atom(Atom::Link, project) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, project) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + + text << " " << since[0]; + } + else { + // Reconstruct the string. + text << " " << since.join(' '); + } + text << Atom::ParaRight; + requisites.insert(sinceText, text); + } + + //add the instantiates to the map + ClassNode* cn = qcn->classNode(); + if (cn && (cn->status() != Node::Internal)) { + text.clear(); + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::String, cn->name()); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + requisites.insert(instantiatesText, text); + } + + //add the inherits to the map + const QmlClassNode* base = qcn->qmlBaseNode(); + while (base && base->isInternal()) { + base = base->qmlBaseNode(); + } + if (base) { + text.clear(); + text << Atom::ParaLeft + << Atom(Atom::LinkNode,CodeMarker::stringForNode(base)) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, base->name()) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) + << Atom::ParaRight; + requisites.insert(inheritsText, text); + } + + //add the inherited-by to the map + NodeList subs; + QmlClassNode::subclasses(qcn->name(), subs); + if (!subs.isEmpty()) { + text.clear(); + text << Atom::ParaLeft; + appendSortedQmlNames(text, qcn, subs); + text << Atom::ParaRight; + requisites.insert(inheritedBytext, text); + } + + if (!requisites.isEmpty()) { + //generate the table + out() << "\n"; + + QStringList::ConstIterator i; + for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) { + + if (requisites.contains(*i)) { + out() << "" + << ""; + } + } + out() << "
    " + << *i + << " "; + + if (*i == importText) + out()<
    "; + } +} + void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker, const Node *relative) { diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h index 54747cd6d6e..5592efa9985 100644 --- a/src/tools/qdoc/htmlgenerator.h +++ b/src/tools/qdoc/htmlgenerator.h @@ -139,6 +139,10 @@ private: const Node *relative, CodeMarker *marker); void generateFooter(const Node *node = 0); + void generateRequisites(InnerNode *inner, + CodeMarker *marker); + void generateQmlRequisites(QmlClassNode *qcn, + CodeMarker *marker); void generateBrief(const Node *node, CodeMarker *marker, const Node *relative = 0); @@ -182,6 +186,7 @@ private: void generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker); void generateInstantiatedBy(ClassNode* cn, CodeMarker* marker); + void generateRequisitesTable(const QStringList& requisitesOrder, QMap& requisites); void generateSection(const NodeList& nl, const Node *relative, CodeMarker *marker,