diff options
Diffstat (limited to 'src/tools/qdoc/htmlgenerator.cpp')
-rw-r--r-- | src/tools/qdoc/htmlgenerator.cpp | 1377 |
1 files changed, 723 insertions, 654 deletions
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index d1bf34f8e1..243c8090db 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -169,6 +169,9 @@ void HtmlGenerator::initializeGenerator(const Config &config) noNavigationBar = config.getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_NONAVIGATIONBAR); + tocDepth = config.getInt(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_TOCDEPTH); project = config.getString(CONFIG_PROJECT); @@ -264,18 +267,15 @@ QString HtmlGenerator::format() } /*! - Traverses the database generating all the HTML documentation. + Traverses the current tree generating all the HTML documentation. */ -void HtmlGenerator::generateTree() +void HtmlGenerator::generateDocs() { - qdb_->buildCollections(); - Node* qflags = qdb_->findNodeByNameAndType(QStringList("QFlags"), Node::Class, Node::NoSubType); + Node* qflags = qdb_->findClassNode(QStringList("QFlags")); if (qflags) qflagsHref_ = linkForNode(qflags,0); - if (!runPrepareOnly()) { - Generator::generateTree(); - generateCollisionPages(); - } + if (!runPrepareOnly()) + Generator::generateDocs(); if (!runGenerateOnly()) { QString fileBase = project.toLower().simplified().replace(QLatin1Char(' '), QLatin1Char('-')); @@ -304,9 +304,6 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark int skipAhead = 0; static bool in_para = false; - if (Generator::debugging()) { - atom->dump(); - } switch (atom->type()) { case Atom::AbstractLeft: if (relative) @@ -319,15 +316,22 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark case Atom::AutoLink: if (!inLink_ && !inContents_ && !inSectionHeading_) { const Node *node = 0; - QString link = getLink(atom, relative, &node); - if (!link.isEmpty()) { + QString link = getAutoLink(atom, relative, &node); + if (link.isEmpty()) { + if (autolinkErrors()) + relative->doc().location().warning(tr("Can't autolink to '%1'").arg(atom->string())); + } + else if (node && node->status() == Node::Obsolete) { + if ((relative->parent() != node) && !relative->isObsolete()) + link.clear(); + } + if (link.isEmpty()) + out() << protectEnc(atom->string()); + else { beginLink(link, node, relative); generateLink(atom, marker); endLink(); } - else { - out() << protectEnc(atom->string()); - } } else { out() << protectEnc(atom->string()); @@ -336,11 +340,11 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark case Atom::BaseName: break; case Atom::BriefLeft: - if (relative->type() == Node::Document) { - if (relative->subType() != Node::Example) { - skipAhead = skipAtoms(atom, Atom::BriefRight); - break; - } + // Do not output the brief for QML nodes, doc nodes or collections + // (groups, modules, qml module nodes) + if (relative->isQmlType() || relative->isDocNode() || relative->isCollectionNode()) { + skipAhead = skipAtoms(atom, Atom::BriefRight); + break; } out() << "<p>"; @@ -374,7 +378,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark } break; case Atom::BriefRight: - if (relative->type() != Node::Document) + if (!relative->isDocNode()) out() << "</p>\n"; break; case Atom::C: @@ -485,9 +489,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark break; case Atom::AnnotatedList: { - DocNode* dn = qdb_->getGroup(atom->string()); - if (dn) - generateAnnotatedList(relative, marker, dn->members()); + GroupNode* gn = qdb_->getGroup(atom->string()); + if (gn) + generateList(gn, marker, atom->string()); } break; case Atom::GeneratedList: @@ -495,19 +499,25 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark generateAnnotatedList(relative, marker, qdb_->getCppClasses()); } else if (atom->string() == "classes") { - generateCompactList(Generic, relative, qdb_->getCppClasses(), true, QStringLiteral("Q")); + generateCompactList(Generic, relative, qdb_->getCppClasses(), true, QStringLiteral("")); + } + else if (atom->string().contains("classes ")) { + QString rootName = atom->string().mid(atom->string().indexOf("classes") + 7).trimmed(); + generateCompactList(Generic, relative, qdb_->getCppClasses(), true, rootName); + } + else if (atom->string() == "qmlbasictypes") { + generateCompactList(Generic, relative, qdb_->getQmlBasicTypes(), true, QStringLiteral("")); } else if (atom->string() == "qmltypes") { generateCompactList(Generic, relative, qdb_->getQmlTypes(), true, QStringLiteral("")); } else if (atom->string().contains("classesbymodule")) { - QString arg = atom->string().trimmed(); QString moduleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed(); QDocDatabase* qdb = QDocDatabase::qdocDB(); - DocNode* dn = qdb->findModule(moduleName); - if (dn) { + ModuleNode* mn = qdb->findModule(moduleName); + if (mn) { NodeMap m; - dn->getMemberClasses(m); + mn->getMemberClasses(m); if (!m.isEmpty()) { generateAnnotatedList(relative, marker, m); } @@ -550,16 +560,25 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark generateCompactList(Generic, relative, qdb_->getServiceClasses(), false, QStringLiteral("Q")); } else if (atom->string() == "overviews") { - generateOverviewList(relative); + generateList(relative, marker, "overviews"); + } + else if (atom->string() == "cpp-modules") { + generateList(relative, marker, "cpp-modules"); + } + else if (atom->string() == "qml-modules") { + generateList(relative, marker, "qml-modules"); } else if (atom->string() == "namespaces") { generateAnnotatedList(relative, marker, qdb_->getNamespaces()); } else if (atom->string() == "related") { - const DocNode *dn = static_cast<const DocNode *>(relative); - if (dn) - generateAnnotatedList(dn, marker, dn->members()); + generateList(relative, marker, "related"); } +#if 0 + /* + This is not used in Qt5, as of 10/02/2014 + Remove permanently if it is not missed. + */ else if (atom->string() == "relatedinline") { const DocNode *dn = static_cast<const DocNode *>(relative); if (dn && !dn->members().isEmpty()) { @@ -573,6 +592,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark generateBody(node, marker); } } +#endif break; case Atom::SinceList: { @@ -591,10 +611,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark while (n != nsmap.constEnd()) { const Node* node = n.value(); switch (node->type()) { - case Node::Document: - if (node->subType() == Node::QmlClass) { - sections[QmlClass].appendMember((Node*)node); - } + case Node::QmlType: + sections[QmlClass].appendMember((Node*)node); break; case Node::Namespace: sections[Namespace].appendMember((Node*)node); @@ -750,8 +768,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark out() << " alt=\"\""; out() << " />"; helpProjectWriter->addExtraFile(fileName); - if ((relative->type() == Node::Document) && - (relative->subType() == Node::Example)) { + if (relative->isExample()) { const ExampleNode* cen = static_cast<const ExampleNode*>(relative); if (cen->imageFileName().isEmpty()) { ExampleNode* en = const_cast<ExampleNode*>(cen); @@ -794,17 +811,26 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark break; case Atom::Link: { + inObsoleteLink = false; const Node *node = 0; - QString myLink = getLink(atom, relative, &node); - if (myLink.isEmpty()) { - myLink = getCollisionLink(atom); - if (myLink.isEmpty() && !noLinkErrors()) { - relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string())); + QString link = getLink(atom, relative, &node); + if (link.isEmpty() && (node != relative) && !noLinkErrors()) { + relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string())); + } + else { + node = 0; + if (node && node->status() == Node::Obsolete) { + if ((relative->parent() != node) && !relative->isObsolete()) { + inObsoleteLink = true; + if (obsoleteLinks) { + relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") + .arg(atom->string()) + .arg(relative->plainFullName())); + } + } } - else - node = 0; } - beginLink(myLink, node, relative); + beginLink(link, node, relative); skipAhead = 1; } break; @@ -827,21 +853,24 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark out() << "<dl>\n"; } else if (atom->string() == ATOM_LIST_VALUE) { + out() << "<table class=\"valuelist\">"; threeColumnEnumValueTable_ = isThreeColumnEnumValueTable(atom); if (threeColumnEnumValueTable_) { - out() << "<table class=\"valuelist\">"; if (++numTableRows_ % 2 == 1) out() << "<tr valign=\"top\" class=\"odd\">"; else out() << "<tr valign=\"top\" class=\"even\">"; - out() << "<th class=\"tblConst\">Constant</th>" - << "<th class=\"tblval\">Value</th>" - << "<th class=\"tbldscr\">Description</th></tr>\n"; + out() << "<th class=\"tblConst\">Constant</th>"; + + // If not in \enum topic, skip the value column + if (relative->type() == Node::Enum) + out() << "<th class=\"tblval\">Value</th>"; + + out() << "<th class=\"tbldscr\">Description</th></tr>\n"; } else { - out() << "<table class=\"valuelist\">" - << "<tr><th class=\"tblConst\">Constant</th><th class=\"tblVal\">Value</th></tr>\n"; + out() << "<tr><th class=\"tblConst\">Constant</th><th class=\"tblVal\">Value</th></tr>\n"; } } else { @@ -876,19 +905,18 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark // ### Trenton QString t= protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),relative))); - out() << "<tr><td class=\"topAlign\"><tt>" << t << "</tt></td><td class=\"topAlign\">"; + out() << "<tr><td class=\"topAlign\"><tt>" << t << "</tt>"; - QString itemValue; if (relative->type() == Node::Enum) { + out() << "</td><td class=\"topAlign\">"; const EnumNode *enume = static_cast<const EnumNode *>(relative); - itemValue = enume->itemValue(atom->next()->string()); - } - - if (itemValue.isEmpty()) - out() << '?'; - else - out() << "<tt>" << protectEnc(itemValue) << "</tt>"; + QString itemValue = enume->itemValue(atom->next()->string()); + if (itemValue.isEmpty()) + out() << '?'; + else + out() << "<tt>" << protectEnc(itemValue) << "</tt>"; + } skipAhead = 1; } break; @@ -968,10 +996,16 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark break; case Atom::SectionRight: break; - case Atom::SectionHeadingLeft: - out() << "<h" + QString::number(atom->string().toInt() + hOffset(relative)) + QLatin1Char('>'); + case Atom::SectionHeadingLeft: { + int unit = atom->string().toInt() + hOffset(relative); + out() << "<h" + QString::number(unit) + QLatin1Char(' '); + if (unit < 3) { + out() << "id=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString()) << "\""; + } + out() << ">"; inSectionHeading_ = true; break; + } case Atom::SectionHeadingRight: out() << "</h" + QString::number(atom->string().toInt() + hOffset(relative)) + ">\n"; inSectionHeading_ = false; @@ -1117,7 +1151,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark } /*! - Generate a reference page for a C++ class. + Generate a reference page for a C++ class or a C++ namespace. */ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) { @@ -1189,10 +1223,9 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) else { if (!s->members.isEmpty()) { // out() << "<hr />\n"; - out() << "<a name=\"" - << registerRef((*s).name.toLower()) - << "\"></a>" << divNavTop << "\n"; - out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; + QString ref = registerRef((*s).name.toLower()); + out() << "<a name=\"" << ref << "\"></a>" << divNavTop << "\n"; + out() << "<h2 id=\"" << ref << "\">" << protectEnc((*s).name) << "</h2>\n"; generateSection(s->members, inner, marker, CodeMarker::Summary); } if (!s->reimpMembers.isEmpty()) { @@ -1227,13 +1260,14 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) out() << "</ul>\n"; } - out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << '\n'; + QString detailsRef = registerRef("details"); + out() << "<a name=\"" << detailsRef << "\"></a>" << divNavTop << '\n'; if (!inner->doc().isEmpty()) { generateExtractionMark(inner, DetailedDescriptionMark); //out() << "<hr />\n" out() << "<div class=\"descr\">\n" // QTBUG-9504 - << "<h2>" << "Detailed Description" << "</h2>\n"; + << "<h2 id=\"" << detailsRef << "\">" << "Detailed Description" << "</h2>\n"; generateBody(inner, marker); out() << "</div>\n"; // QTBUG-9504 generateAlsoList(inner, marker); @@ -1304,115 +1338,103 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) } /*! - We delayed generation of the disambiguation pages until now, after - all the other pages have been generated. We do this because we might - encounter a link command that tries to link to a target on a QML - component page, but the link doesn't specify the module identifer - for the component, and the component name without a module - identifier is ambiguous. When such a link is found, qdoc can't find - the target, so it appends the target to the NameCollisionNode. After - the tree has been traversed and all these ambiguous links have been - added to the name collision nodes, this function is called. The list - of collision nodes is traversed here, and the disambiguation page for - each collision is generated. The disambiguation page will not only - disambiguate links to the component pages, but it will also disambiguate - links to properties, section headers, etc. + Generate the HTML page for a QML type. \qcn is the QML type. + \marker is the code markeup object. */ -void HtmlGenerator::generateCollisionPages() +void HtmlGenerator::generateQmlTypePage(QmlClassNode* qcn, CodeMarker* marker) { - if (collisionNodes.isEmpty()) - return; + SubTitleSize subTitleSize = LargeSubTitle; + QList<Section>::const_iterator s; + QString htmlTitle = qcn->fullTitle() + " QML Type"; + + generateHeader(htmlTitle, qcn, marker); + QList<Section> sections = marker->qmlSections(qcn, CodeMarker::Summary); + generateTableOfContents(qcn, marker, §ions); + marker = CodeMarker::markerForLanguage(QLatin1String("QML")); + generateTitle(htmlTitle, Text() << qcn->subTitle(), subTitleSize, qcn, marker); + generateBrief(qcn, marker); + generateQmlRequisites(qcn, marker); + + QString allQmlMembersLink = generateAllQmlMembersFile(qcn, marker); + QString obsoleteLink = generateQmlMemberFile(qcn, marker, CodeMarker::Obsolete); + if (!allQmlMembersLink.isEmpty() || !obsoleteLink.isEmpty()) { + out() << "<ul>\n"; + if (!allQmlMembersLink.isEmpty()) { + out() << "<li><a href=\"" << allQmlMembersLink << "\">" + << "List of all members, including inherited members</a></li>\n"; + } + if (!obsoleteLink.isEmpty()) { + out() << "<li><a href=\"" << obsoleteLink << "\">" + << "Obsolete members</a></li>\n"; + } + out() << "</ul>\n"; + } - for (int i=0; i<collisionNodes.size(); ++i) { - NameCollisionNode* ncn = collisionNodes.at(i); - if (!ncn) - continue; + s = sections.constBegin(); + while (s != sections.constEnd()) { + QString ref = registerRef((*s).name.toLower()); + out() << "<a name=\"" << ref + << "\"></a>" << divNavTop << '\n'; + out() << "<h2 id=\"" << ref << "\">" << protectEnc((*s).name) << "</h2>\n"; + generateQmlSummary(*s, qcn, marker); + ++s; + } - NodeList collisions; - const NodeList& nl = ncn->childNodes(); - if (!nl.isEmpty()) { - NodeList::ConstIterator it = nl.constBegin(); - while (it != nl.constEnd()) { - if (!(*it)->isInternal()) - collisions.append(*it); - ++it; - } - } - if (collisions.size() <= 1) - continue; + generateExtractionMark(qcn, DetailedDescriptionMark); + QString detailsRef = registerRef("details"); + out() << "<a name=\"" << detailsRef << "\"></a>" << divNavTop << '\n'; + out() << "<h2 id=\"" << detailsRef << "\">" << "Detailed Description" << "</h2>\n"; + generateBody(qcn, marker); + ClassNode* cn = qcn->classNode(); + if (cn) + generateQmlText(cn->doc().body(), cn, marker, qcn->name()); + generateAlsoList(qcn, marker); + generateExtractionMark(qcn, EndMark); + //out() << "<hr />\n"; - ncn->clearCurrentChild(); - beginSubPage(ncn, Generator::fileName(ncn)); - QString fullTitle = ncn->fullTitle(); - CodeMarker* marker = CodeMarker::markerForFileName(ncn->location().filePath()); - if (ncn->isQmlNode()) { - // Replace the marker with a QML code marker. - if (ncn->isQmlNode()) - marker = CodeMarker::markerForLanguage(QLatin1String("QML")); + sections = marker->qmlSections(qcn,CodeMarker::Detailed); + s = sections.constBegin(); + while (s != sections.constEnd()) { + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; + NodeList::ConstIterator m = (*s).members.constBegin(); + while (m != (*s).members.constEnd()) { + generateDetailedQmlMember(*m, qcn, marker); + out() << "<br/>\n"; + ++m; } + ++s; + } + generateFooter(qcn); +} + +/*! + Generate the HTML page for the QML basic type represented + by the QML basic type node \a qbtn. + */ +void HtmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker) +{ + SubTitleSize subTitleSize = LargeSubTitle; + QList<Section>::const_iterator s; + QString htmlTitle = qbtn->fullTitle() + " QML Basic Type"; - generateHeader(fullTitle, ncn, marker); - if (!fullTitle.isEmpty()) - out() << "<h1 class=\"title\">" << protectEnc(fullTitle) << "</h1>\n"; + marker = CodeMarker::markerForLanguage(QLatin1String("QML")); - NodeMap nm; - for (int i=0; i<collisions.size(); ++i) { - Node* n = collisions.at(i); - QString t; - if (!n->qmlModuleName().isEmpty()) - t = n->qmlModuleName() + "::"; - t += protectEnc(fullTitle); - nm.insertMulti(t,n); - } - generateAnnotatedList(ncn, marker, nm); - - QList<QString> targets; - if (!ncn->linkTargets().isEmpty()) { - QMap<QString,QString>::ConstIterator t = ncn->linkTargets().constBegin(); - while (t != ncn->linkTargets().constEnd()) { - int count = 0; - for (int i=0; i<collisions.size(); ++i) { - InnerNode* n = static_cast<InnerNode*>(collisions.at(i)); - if (n->findChildNodeByName(t.key())) { - ++count; - if (count > 1) { - targets.append(t.key()); - break; - } - } - } - ++t; - } - } - if (!targets.isEmpty()) { - QList<QString>::ConstIterator t = targets.constBegin(); - while (t != targets.constEnd()) { - out() << "<a name=\"" << Doc::canonicalTitle(*t) << "\"></a>"; - out() << "<h2 class=\"title\">" << protectEnc(*t) << "</h2>\n"; - out() << "<ul>\n"; - for (int i=0; i<collisions.size(); ++i) { - InnerNode* n = static_cast<InnerNode*>(collisions.at(i)); - Node* p = n->findChildNodeByName(*t); - if (p) { - QString link = linkForNode(p,0); - QString label; - if (!n->qmlModuleName().isEmpty()) - label = n->qmlModuleName() + "::"; - label += n->name() + "::" + p->name(); - out() << "<li>"; - out() << "<a href=\"" << link << "\">"; - out() << protectEnc(label) << "</a>"; - out() << "</li>\n"; - } - } - out() << "</ul>\n"; - ++t; - } - } + generateHeader(htmlTitle, qbtn, marker); + QList<Section> sections = marker->sections(qbtn, CodeMarker::Summary, CodeMarker::Okay); + generateTableOfContents(qbtn,marker,§ions); + generateTitle(htmlTitle, + Text() << qbtn->subTitle(), + subTitleSize, + qbtn, + marker); + generateExtractionMark(qbtn, DetailedDescriptionMark); + out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504 - generateFooter(ncn); - endSubPage(); - } + generateBody(qbtn, marker); + out() << "</div>\n"; // QTBUG-9504 + generateAlsoList(qbtn, marker); + generateExtractionMark(qbtn, EndMark); + generateFooter(qbtn); } /*! @@ -1437,31 +1459,13 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) QList<Section>::const_iterator s; QString fullTitle = dn->fullTitle(); - if (dn->subType() == Node::QmlBasicType) { - fullTitle = "QML Basic Type: " + fullTitle; - - // Replace the marker with a QML code marker. - marker = CodeMarker::markerForLanguage(QLatin1String("QML")); - } - else if (dn->subType() == Node::QmlClass) { - fullTitle = fullTitle + " QML Type"; - } - generateHeader(fullTitle, dn, marker); /* Generate the TOC for the new doc format. Don't generate a TOC for the home page. */ - QmlClassNode* qml_cn = 0; - if (dn->subType() == Node::QmlClass) { - qml_cn = static_cast<QmlClassNode*>(dn); - sections = marker->qmlSections(qml_cn,CodeMarker::Summary); - generateTableOfContents(dn,marker,§ions); - - // Replace the marker with a QML code marker. - marker = CodeMarker::markerForLanguage(QLatin1String("QML")); - } - else if (dn->subType() != Node::Collision && dn->name() != QString("index.html") && dn->name() != QString("qtexamplesandtutorials.html")) + if ((dn->name() != QString("index.html")) && + (dn->name() != QString("qtexamplesandtutorials.html"))) generateTableOfContents(dn,marker,0); generateTitle(fullTitle, @@ -1470,29 +1474,7 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) dn, marker); - if (dn->subType() == Node::Module) { - // Generate brief text and status for modules. - generateBrief(dn, marker); - generateStatus(dn, marker); - generateSince(dn, marker); - - NodeMap nm; - dn->getMemberNamespaces(nm); - if (!nm.isEmpty()) { - out() << "<a name=\"" << registerRef("namespaces") << "\"></a>" << divNavTop << '\n'; - out() << "<h2>Namespaces</h2>\n"; - generateAnnotatedList(dn, marker, nm); - } - nm.clear(); - dn->getMemberClasses(nm); - if (!nm.isEmpty()) { - out() << "<a name=\"" << registerRef("classes") << "\"></a>" << divNavTop << '\n'; - out() << "<h2>Classes</h2>\n"; - generateAnnotatedList(dn, marker, nm); - } - nm.clear(); - } - else if (dn->subType() == Node::HeaderFile) { + if (dn->subType() == Node::HeaderFile) { // Generate brief text and status for modules. generateBrief(dn, marker); generateStatus(dn, marker); @@ -1522,88 +1504,115 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) out() << "</ul>\n"; } - else if (dn->subType() == Node::QmlClass) { - const_cast<DocNode*>(dn)->setCurrentChild(); - ClassNode* cn = qml_cn->classNode(); - generateBrief(qml_cn, marker); - generateQmlRequisites(qml_cn, marker); - QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker); - if (!allQmlMembersLink.isEmpty()) { - out() << "<ul>\n"; - out() << "<li><a href=\"" << allQmlMembersLink << "\">" - << "List of all members, including inherited members</a></li>\n"; - out() << "</ul>\n"; - } + sections = marker->sections(dn, CodeMarker::Summary, CodeMarker::Okay); + s = sections.constBegin(); + while (s != sections.constEnd()) { + QString ref = registerRef((*s).name); + out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n'; + out() << "<h2 id=\"" << ref << "\">" << protectEnc((*s).name) << "</h2>\n"; + generateSectionList(*s, dn, marker, CodeMarker::Summary); + ++s; + } - s = sections.constBegin(); - while (s != sections.constEnd()) { - out() << "<a name=\"" << registerRef((*s).name.toLower()) - << "\"></a>" << divNavTop << '\n'; - out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; - generateQmlSummary(*s,dn,marker); - ++s; - } + generateExtractionMark(dn, DetailedDescriptionMark); + out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504 - generateExtractionMark(dn, DetailedDescriptionMark); - out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << '\n'; - out() << "<h2>" << "Detailed Description" << "</h2>\n"; - generateBody(dn, marker); - if (cn) - generateQmlText(cn->doc().body(), cn, marker, dn->name()); - generateAlsoList(dn, marker); - generateExtractionMark(dn, EndMark); + generateBody(dn, marker); + out() << "</div>\n"; // QTBUG-9504 + generateAlsoList(dn, marker); + generateExtractionMark(dn, EndMark); + + sections = marker->sections(dn, CodeMarker::Detailed, CodeMarker::Okay); + s = sections.constBegin(); + while (s != sections.constEnd()) { //out() << "<hr />\n"; + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; - sections = marker->qmlSections(qml_cn,CodeMarker::Detailed); - s = sections.constBegin(); - while (s != sections.constEnd()) { - out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; - NodeList::ConstIterator m = (*s).members.constBegin(); - while (m != (*s).members.constEnd()) { - generateDetailedQmlMember(*m, dn, marker); - out() << "<br/>\n"; - ++m; - } - ++s; + NodeList::ConstIterator m = (*s).members.constBegin(); + while (m != (*s).members.constEnd()) { + generateDetailedMember(*m, dn, marker); + ++m; } - generateFooter(dn); - const_cast<DocNode*>(dn)->clearCurrentChild(); - return; + ++s; } + generateFooter(dn); +} - sections = marker->sections(dn, CodeMarker::Summary, CodeMarker::Okay); +/*! + Generate the HTML page for a group, module, or QML module. + */ +void HtmlGenerator::generateCollectionNode(CollectionNode* cn, CodeMarker* marker) +{ + SubTitleSize subTitleSize = LargeSubTitle; + QList<Section> sections; + QList<Section>::const_iterator s; + QString fullTitle = cn->fullTitle(); + QString ref; + + generateHeader(fullTitle, cn, marker); + generateTableOfContents(cn,marker,0); + generateTitle(fullTitle, Text() << cn->subTitle(), subTitleSize, cn, marker); + + if (cn->isModule()) { + // Generate brief text and status for modules. + generateBrief(cn, marker); + generateStatus(cn, marker); + generateSince(cn, marker); + + NodeMap nm; + cn->getMemberNamespaces(nm); + if (!nm.isEmpty()) { + ref = registerRef("namespaces"); + out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n'; + out() << "<h2 id=\"" << ref << "\">Namespaces</h2>\n"; + generateAnnotatedList(cn, marker, nm); + } + nm.clear(); + cn->getMemberClasses(nm); + if (!nm.isEmpty()) { + ref = registerRef("classes"); + out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n'; + out() << "<h2 id=\"" << ref << "\">Classes</h2>\n"; + generateAnnotatedList(cn, marker, nm); + } + nm.clear(); + } + + sections = marker->sections(cn, CodeMarker::Summary, CodeMarker::Okay); s = sections.constBegin(); while (s != sections.constEnd()) { - out() << "<a name=\"" << registerRef((*s).name) << "\"></a>" << divNavTop << '\n'; - out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; - generateSectionList(*s, dn, marker, CodeMarker::Summary); + ref = registerRef((*s).name); + out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n'; + out() << "<h2 id=\"" << ref << "\">" << protectEnc((*s).name) << "</h2>\n"; + generateSectionList(*s, cn, marker, CodeMarker::Summary); ++s; } - Text brief = dn->doc().briefText(); - if (dn->subType() == Node::Module && !brief.isEmpty()) { - generateExtractionMark(dn, DetailedDescriptionMark); - out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << '\n'; + Text brief = cn->doc().briefText(); + if (cn->isModule() && !brief.isEmpty()) { + generateExtractionMark(cn, DetailedDescriptionMark); + ref = registerRef("details"); + out() << "<a name=\"" << ref << "\"></a>" << divNavTop << '\n'; out() << "<div class=\"descr\">\n"; // QTBUG-9504 - out() << "<h2>" << "Detailed Description" << "</h2>\n"; + out() << "<h2 id=\"" << ref << "\">" << "Detailed Description" << "</h2>\n"; } else { - generateExtractionMark(dn, DetailedDescriptionMark); + generateExtractionMark(cn, DetailedDescriptionMark); out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504 } - generateBody(dn, marker); + generateBody(cn, marker); out() << "</div>\n"; // QTBUG-9504 - generateAlsoList(dn, marker); - generateExtractionMark(dn, EndMark); + generateAlsoList(cn, marker); + generateExtractionMark(cn, EndMark); - if ((dn->subType() == Node::Group)) - generateAnnotatedList(dn, marker, dn->members()); - else if (dn->subType() == Node::QmlModule) - generateAnnotatedList(dn, marker, dn->members()); + if (cn->isGroup()) + generateAnnotatedList(cn, marker, cn->members()); + else if (cn->isQmlModule()) + generateAnnotatedList(cn, marker, cn->members()); - sections = marker->sections(dn, CodeMarker::Detailed, CodeMarker::Okay); + sections = marker->sections(cn, CodeMarker::Detailed, CodeMarker::Okay); s = sections.constBegin(); while (s != sections.constEnd()) { //out() << "<hr />\n"; @@ -1611,12 +1620,12 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) NodeList::ConstIterator m = (*s).members.constBegin(); while (m != (*s).members.constEnd()) { - generateDetailedMember(*m, dn, marker); + generateDetailedMember(*m, cn, marker); ++m; } ++s; } - generateFooter(dn); + generateFooter(cn); } /*! @@ -1650,7 +1659,7 @@ void HtmlGenerator::generateNavigationBar(const QString &title, << Atom(Atom::AutoLink, landingpage) << Atom(Atom::ListItemRight); - if (node->type() == Node::Class) { + if (node->isClass()) { const ClassNode *cn = static_cast<const ClassNode *>(node); QString name = node->moduleName(); @@ -1667,22 +1676,30 @@ void HtmlGenerator::generateNavigationBar(const QString &title, << Atom(Atom::String, cn->name()) << Atom(Atom::ListItemRight); } - else if (node->type() == Node::Document) { - const DocNode *dn = static_cast<const DocNode *>(node); - if (node->subType() == Node::QmlClass || node->subType() == Node::QmlBasicType) { - if (!qmltypespage.isEmpty()) - navigationbar << Atom(Atom::ListItemLeft) - << Atom(Atom::Link, qmltypespage) - << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, QLatin1String("QML Types")) - << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) - << Atom(Atom::ListItemRight); - } - else if (dn && dn->isExampleFile()) { + else if (node->isQmlType()) { + if (!qmltypespage.isEmpty()) navigationbar << Atom(Atom::ListItemLeft) - << Atom(Atom::Link, dn->parent()->name()) + << Atom(Atom::Link, qmltypespage) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, dn->parent()->title()) + << Atom(Atom::String, QLatin1String("QML Types")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) + << Atom(Atom::ListItemRight); + } + else if (node->isQmlBasicType()) { + if (!qmltypespage.isEmpty()) + navigationbar << Atom(Atom::ListItemLeft) + << Atom(Atom::Link, qmltypespage) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, QLatin1String("QML Types")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) + << Atom(Atom::ListItemRight); + } + else { + if (node->isExampleFile()) { + navigationbar << Atom(Atom::ListItemLeft) + << Atom(Atom::Link, node->parent()->name()) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, node->parent()->title()) << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(Atom::ListItemRight); @@ -1714,13 +1731,48 @@ void HtmlGenerator::generateHeader(const QString& title, QString shortVersion = qdb_->version(); if (shortVersion.count(QChar('.')) == 2) shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); - if (!project.isEmpty()) - shortVersion = QLatin1String(" | ") + project + QLatin1Char(' ') + shortVersion; + + //determine the rest of the <title> element content: "title | titleSuffix version" + QString titleSuffix; + if (!landingpage.isEmpty()) { + //for normal pages: "title | landingpage version" + titleSuffix = landingpage; + } + else if (!homepage.isEmpty()) { + //for pages that set the homepage but not landing page: "title | homepage version" + if (title != homepage) + titleSuffix = homepage; + } + else if (!project.isEmpty()) { + //for projects outside of Qt or Qt 5: "title | project version" + if (title != project) + titleSuffix = project; + } else - shortVersion = QLatin1String(" | ") + QLatin1String("Qt ") + shortVersion ; + //default: "title | Qt version" + titleSuffix = QLatin1String("Qt "); + + //for pages that duplicate the title and suffix (landing pages, home pages, + // and module landing pages, clear the duplicate + if (title == titleSuffix) + titleSuffix.clear(); + + //for pages that duplicate the version, clear the duplicate + if (title.contains(shortVersion) || titleSuffix.contains(shortVersion)) + shortVersion.clear(); + + QString divider; + if (!titleSuffix.isEmpty() && !title.isEmpty()) + divider = QLatin1String(" | "); // Generating page title - out() << " <title>" << protectEnc(title) << shortVersion << "</title>\n"; + out() << " <title>" + << protectEnc(title) + << divider + << titleSuffix + << QLatin1Char(' ') + << shortVersion + << "</title>\n"; // Include style sheet and script links. out() << headerStyles; @@ -1892,7 +1944,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) if (inner->type() == Node::Class || inner->type() == Node::Namespace) { //add the QT variable to the map if (!inner->moduleName().isEmpty()) { - DocNode * moduleNode = qdb_->findModule(inner->moduleName()); + ModuleNode* moduleNode = qdb_->findModule(inner->moduleName()); if (moduleNode && !moduleNode->qtVariable().isEmpty()) { text.clear(); text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_TELETYPE) @@ -1923,18 +1975,20 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) 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)"; + if ((*r).node_) { + text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node_)) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, (*r).signature_) + << 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()); } - text << separator(index++, classe->baseClasses().count()); ++r; } text << Atom::ParaRight; @@ -2002,9 +2056,9 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker) //add the module name and version to the map QString qmlModuleVersion; - DocNode* dn = qdb_->findQmlModule(qcn->qmlModuleName()); - if (dn) - qmlModuleVersion = dn->qmlModuleVersion(); + QmlModuleNode* qmn = qdb_->findQmlModule(qcn->qmlModuleName()); + if (qmn) + qmlModuleVersion = qmn->qmlModuleVersion(); else qmlModuleVersion = qcn->qmlModuleVersion(); text.clear(); @@ -2044,7 +2098,7 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker) } //add the inherits to the map - const QmlClassNode* base = qcn->qmlBaseNode(); + QmlClassNode* base = qcn->qmlBaseNode(); while (base && base->isInternal()) { base = base->qmlBaseNode(); } @@ -2136,7 +2190,11 @@ void HtmlGenerator::generateTableOfContents(const Node *node, QList<Atom*> toc; if (node->doc().hasTableOfContents()) toc = node->doc().tableOfContents(); - if (toc.isEmpty() && !sections && (node->subType() != Node::Module)) + if (toc.isEmpty() && !sections && !node->isModule()) + return; + + //turn off table of contents if HTML.tocdepth is set to 0 + if (tocDepth == 0) return; QStringList sectionNumber; @@ -2151,7 +2209,7 @@ void HtmlGenerator::generateTableOfContents(const Node *node, sectionNumber.append("1"); out() << "<ul>\n"; - if (node->subType() == Node::Module) { + if (node->isModule()) { if (node->hasNamespaces()) { out() << "<li class=\"level" << sectionNumber.size() @@ -2178,9 +2236,7 @@ void HtmlGenerator::generateTableOfContents(const Node *node, } } } - else if (sections && ((node->type() == Node::Class) || - (node->type() == Node::Namespace) || - (node->subType() == Node::QmlClass))) { + else if (sections && (node->isClass() || node->isNamespace() || node->isQmlType())) { QList<Section>::ConstIterator s = sections->constBegin(); while (s != sections->constEnd()) { if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) { @@ -2222,18 +2278,23 @@ void HtmlGenerator::generateTableOfContents(const Node *node, sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); } } - int numAtoms; - Text headingText = Text::sectionHeading(atom); - QString s = headingText.toString(); - out() << "<li class=\"level" - << sectionNumber.size() - << "\">"; - out() << "<a href=\"" - << '#' - << Doc::canonicalTitle(s) - << "\">"; - generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); - out() << "</a></li>\n"; + + //restrict the ToC depth to the one set by the HTML.tocdepth variable or + //print all levels if tocDepth is not set. + if (sectionNumber.size() <= tocDepth || tocDepth < 0) { + int numAtoms; + Text headingText = Text::sectionHeading(atom); + QString s = headingText.toString(); + out() << "<li class=\"level" + << sectionNumber.size() + << "\">"; + out() << "<a href=\"" + << '#' + << Doc::canonicalTitle(s) + << "\">"; + generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); + out() << "</a></li>\n"; + } } while (!sectionNumber.isEmpty()) { sectionNumber.removeLast(); @@ -2278,8 +2339,7 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, the members of QML class \a qml_cn, including the inherited members. The \a marker is used for formatting stuff. */ -QString HtmlGenerator::generateAllQmlMembersFile(const QmlClassNode* qml_cn, - CodeMarker* marker) +QString HtmlGenerator::generateAllQmlMembersFile(QmlClassNode* qml_cn, CodeMarker* marker) { QList<Section> sections; QList<Section>::ConstIterator s; @@ -2324,6 +2384,8 @@ QString HtmlGenerator::generateAllQmlMembersFile(const QmlClassNode* qml_cn, prefix = prefix.left(keys.at(j).indexOf("::")+1); } generateQmlItem(nodes[j], qcn, marker, true); + if (nodes[j]->isAttached()) + out() << " [attached]"; //generateSynopsis(nodes[j], qcn, marker, CodeMarker::Subpage, false, &prefix); out() << "</li>\n"; } @@ -2416,6 +2478,85 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner, return fileName; } +/*! + Generates a separate file where certain members of the QML + type \a qcn are listed. The \a marker is used to generate + the section lists, which are then traversed and output here. + + Note that this function currently only handles correctly the + case where \a status is \c {CodeMarker::Obsolete}. + */ +QString HtmlGenerator::generateQmlMemberFile(QmlClassNode* qcn, + CodeMarker *marker, + CodeMarker::Status status) +{ + QList<Section> sections = marker->qmlSections(qcn, CodeMarker::Summary, status); + QMutableListIterator<Section> j(sections); + while (j.hasNext()) { + if (j.next().members.size() == 0) + j.remove(); + } + if (sections.isEmpty()) + return QString(); + + QString title = "Obsolete Members for " + qcn->name(); + QString fileName = fileBase(qcn) + "-obsolete." + fileExtension(); + + if (status == CodeMarker::Obsolete) { + QString link; + if (useOutputSubdirs() && !Generator::outputSubdir().isEmpty()) + link = QString("../" + Generator::outputSubdir() + QLatin1Char('/')); + link += fileName; + qcn->setObsoleteLink(link); + } + + beginSubPage(qcn, fileName); + generateHeader(title, qcn, marker); + generateTitle(title, Text(), SmallSubTitle, qcn, marker); + + out() << "<p><b>The following members of QML type " + << "<a href=\"" << linkForNode(qcn, 0) << "\">" + << protectEnc(qcn->name()) << "</a>" + << " are obsolete.</b> " + << "They are provided to keep old source code working. " + << "We strongly advise against using them in new code.</p>\n"; + + QList<Section>::const_iterator s = sections.constBegin(); + while (s != sections.constEnd()) { + QString ref = registerRef((*s).name.toLower()); + out() << "<a name=\"" << ref + << "\"></a>" << divNavTop << '\n'; + out() << "<h2 id=\"" << ref << "\">" << protectEnc((*s).name) << "</h2>\n"; + generateQmlSummary(*s, qcn, marker); + ++s; + } + + sections = marker->qmlSections(qcn, CodeMarker::Detailed, status); + QMutableListIterator<Section> k(sections); + while (k.hasNext()) { + if (k.next().members.size() == 0) + k.remove(); + } + if (sections.isEmpty()) + return QString(); + + s = sections.constBegin(); + while (s != sections.constEnd()) { + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; + NodeList::ConstIterator m = (*s).members.constBegin(); + while (m != (*s).members.constEnd()) { + generateDetailedQmlMember(*m, qcn, marker); + out() << "<br/>\n"; + ++m; + } + ++s; + } + + generateFooter(); + endSubPage(); + return fileName; +} + void HtmlGenerator::generateClassHierarchy(const Node *relative, NodeMap& classMap) { if (classMap.isEmpty()) @@ -2448,8 +2589,8 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, NodeMap& classM NodeMap newTop; foreach (const RelatedClass &d, child->derivedClasses()) { - if (d.access != Node::Private && !d.node->doc().isEmpty()) - newTop.insert(d.node->name(), d.node); + if (d.node_ && !d.isPrivate() && !d.node_->isInternal() && d.node_->hasDoc()) + newTop.insert(d.node_->name(), d.node_); } if (!newTop.isEmpty()) { stack.push(newTop); @@ -2469,33 +2610,29 @@ void HtmlGenerator::generateAnnotatedList(const Node* relative, { if (nodeMap.isEmpty()) return; - NodeList nl; - NodeMap::const_iterator i = nodeMap.begin(); - while (i != nodeMap.end()) { - nl.append(i.value()); - ++i; - } - generateAnnotatedList(relative, marker, nl); + generateAnnotatedList(relative, marker, nodeMap.values()); } +/*! + */ void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *marker, - const NodeList& nodes) + const NodeList& unsortedNodes) { + NodeMap nm; bool allInternal = true; - foreach (const Node* node, nodes) { - if (!node->isInternal() && node->status() != Node::Obsolete) { + foreach (Node* node, unsortedNodes) { + if (!node->isInternal() && !node->isObsolete()) { allInternal = false; + nm.insert(node->fullName(relative), node); } } if (allInternal) return; out() << "<table class=\"annotated\">\n"; int row = 0; + NodeList nodes = nm.values(); foreach (const Node* node, nodes) { - if (node->isInternal() || node->status() == Node::Obsolete) - continue; - if (++row % 2 == 1) out() << "<tr class=\"odd topAlign\">"; else @@ -2504,7 +2641,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, generateFullName(node, relative); out() << "</p></td>"; - if (!(node->type() == Node::Document)) { + if (!node->isDocNode()) { Text brief = node->doc().trimmedBriefText(node->name()); if (!brief.isEmpty()) { out() << "<td class=\"tblDescr\"><p>"; @@ -2585,7 +2722,7 @@ void HtmlGenerator::generateCompactList(ListType listType, paragraphName[paragraphNr] = key[0].toUpper(); usedParagraphNames.insert(key[0].toLower().cell()); - paragraph[paragraphNr].insert(key, c.value()); + paragraph[paragraphNr].insert(c.key(), c.value()); ++c; } @@ -2680,7 +2817,7 @@ void HtmlGenerator::generateCompactList(ListType listType, } QStringList pieces; - if (it.value()->subType() == Node::QmlClass) + if (it.value()->isQmlType()) pieces << it.value()->name(); else pieces = it.value()->fullName(relative).split("::"); @@ -2786,117 +2923,105 @@ void HtmlGenerator::generateQmlItem(const Node *node, marked.remove("<@type>"); marked.remove("</@type>"); } - out() << highlightedCode(marked, relative, false, node); + out() << highlightedCode(marked, relative, false); } -void HtmlGenerator::generateOverviewList(const Node *relative) +void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const QString& selector) { - QMap<const DocNode *, QMap<QString, DocNode *> > docNodeMap; - QMap<QString, const DocNode *> groupTitlesMap; - QMap<QString, DocNode *> uncategorizedNodeMap; + NodeList nl; + CollectionList cl; QRegExp singleDigit("\\b([0-9])\\b"); - const NodeList children = qdb_->treeRoot()->childNodes(); - foreach (Node *child, children) { - if (child->type() == Node::Document && child != relative) { - DocNode *docNode = static_cast<DocNode *>(child); - - // Check whether the page is part of a group or is the group - // definition page. - QString group; - bool isGroupPage = false; - if (docNode->doc().metaCommandsUsed().contains("group")) { - group = docNode->doc().metaCommandArgs("group")[0].first; - isGroupPage = true; - } - - // there are too many examples; they would clutter the list - if (docNode->subType() == Node::Example) - continue; - - // not interested either in individual (Qt Designer etc.) manual chapters - if (docNode->links().contains(Node::ContentsLink)) - continue; - - // Discard external nodes. - if (docNode->subType() == Node::ExternalPage) - continue; - - QString sortKey = docNode->fullTitle().toLower(); - if (sortKey.startsWith("the ")) - sortKey.remove(0, 4); - sortKey.replace(singleDigit, "0\\1"); - - if (!group.isEmpty()) { - if (isGroupPage) { - // If we encounter a group definition page, we add all - // the pages in that group to the list for that group. - foreach (Node *member, docNode->members()) { - if (member->isInternal() || member->type() != Node::Document) - continue; - DocNode *page = static_cast<DocNode *>(member); - if (page) { - QString sortKey = page->fullTitle().toLower(); - if (sortKey.startsWith("the ")) - sortKey.remove(0, 4); - sortKey.replace(singleDigit, "0\\1"); - docNodeMap[const_cast<const DocNode *>(docNode)].insert(sortKey, page); - groupTitlesMap[docNode->fullTitle()] = const_cast<const DocNode *>(docNode); - } - } - } - else if (!isGroupPage) { - // If we encounter a page that belongs to a group then - // we add that page to the list for that group. - const DocNode* gn = qdb_->getGroup(group); - if (gn && !docNode->isInternal()) - docNodeMap[gn].insert(sortKey, docNode); - } - } + if (selector == "overviews") { + CNMap groups; + qdb_->mergeCollections(Node::Group, groups, relative); + cl = groups.values(); + foreach (CollectionNode* cn, cl) + nl.append(cn); + generateAnnotatedList(relative, marker, nl); + } + else if (selector == "cpp-modules") { + CNMap modules; + qdb_->mergeCollections(Node::Module, modules, relative); + cl = modules.values(); + foreach (CollectionNode* cn, cl) + nl.append(cn); + generateAnnotatedList(relative, marker, nl); + } + else if (selector == "qml-modules") { + CNMap qmlModules; + qdb_->mergeCollections(Node::QmlModule, qmlModules, relative); + cl = qmlModules.values(); + foreach (CollectionNode* cn, cl) + nl.append(cn); + generateAnnotatedList(relative, marker, nl); + } + else { + /* + \generatelist {selector} is only allowed in a + comment where the topic is \group, \module, or + \qmlmodule. + */ + if (!relative || !relative->isCollectionNode()) { + relative->doc().location().warning(tr("\\generatelist {%1} is only allowed in \\group, \\module, and \\qmlmodule comments.").arg(selector)); + return; + } + if (selector == "related") { + Node* n = const_cast<Node*>(relative); + CollectionNode* cn = static_cast<CollectionNode*>(n); + qdb_->mergeCollections(cn); + generateAnnotatedList(cn, marker, cn->members()); + } + else { + Node* n = const_cast<Node*>(relative); + CollectionNode* cn = static_cast<CollectionNode*>(n); + qdb_->mergeCollections(cn); + generateAnnotatedList(cn, marker, cn->members()); } } - // We now list all the pages found that belong to groups. - // If only certain pages were found for a group, but the definition page - // for that group wasn't listed, the list of pages will be intentionally - // incomplete. However, if the group definition page was listed, all the - // pages in that group are listed for completeness. - - if (!docNodeMap.isEmpty()) { - foreach (const QString &groupTitle, groupTitlesMap.keys()) { - const DocNode *groupNode = groupTitlesMap[groupTitle]; +#if 0 + QStringList keys = groups.uniqueKeys(); + foreach (QString key, keys) { + GroupNode* gn = static_cast<GroupNode*>(groups.value(key)); + if (gn) { out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg( - linkForNode(groupNode, relative)).arg( - protectEnc(groupNode->fullTitle())); - - if (docNodeMap[groupNode].count() == 0) + linkForNode(gn, relative)).arg( + protectEnc(gn->fullTitle())); +#if 0 + if (gn->members().isEmpty()) continue; - out() << "<ul>\n"; + NodeMap nm; + foreach (Node* member, gn->members()) { + if (member->isInternal() || member->isExample() || member->isExternalPage() || + member->isObsolete()) + continue; + // not interested either in individual (Qt Designer etc.) manual chapters + if (member->links().contains(Node::ContentsLink)) + continue; + QString sortKey = member->fullTitle().toLower(); + if (sortKey.startsWith("the ")) + sortKey.remove(0, 4); + sortKey.replace(singleDigit, "0\\1"); + nm.insert(sortKey, member); + } - foreach (const DocNode *docNode, docNodeMap[groupNode]) { - QString title = docNode->fullTitle(); + out() << "<ul>\n"; + QStringList titles = nm.keys(); + foreach (QString t, titles) { + Node* member = nm.value(t); + QString title = member->fullTitle(); if (title.startsWith("The ")) title.remove(0, 4); - out() << "<li><a href=\"" << linkForNode(docNode, relative) << "\">" + out() << "<li><a href=\"" << linkForNode(member, relative) << "\">" << protectEnc(title) << "</a></li>\n"; } out() << "</ul>\n"; +#endif } } - - if (!uncategorizedNodeMap.isEmpty()) { - out() << QString("<h3>Miscellaneous</h3>\n"); - out() << "<ul>\n"; - foreach (const DocNode *docNode, uncategorizedNodeMap) { - QString title = docNode->fullTitle(); - if (title.startsWith("The ")) - title.remove(0, 4); - out() << "<li><a href=\"" << linkForNode(docNode, relative) << "\">" - << protectEnc(title) << "</a></li>\n"; - } - out() << "</ul>\n"; - } +#endif } void HtmlGenerator::generateSection(const NodeList& nl, @@ -3099,8 +3224,7 @@ void HtmlGenerator::generateSynopsis(const Node *node, QString HtmlGenerator::highlightedCode(const QString& markedCode, const Node* relative, - bool alignNames, - const Node* self) + bool alignNames) { QString src = markedCode; QString html; @@ -3148,8 +3272,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (src.at(i) == charLangle && src.at(i + 1) == charAt) { i += 2; if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { - - const Node* n = qdb_->resolveTarget(par1.toString(), relative); + const Node* n = qdb_->findFunctionNode(par1.toString(), relative, Node::DontCare); QString link = linkForNode(n, relative); addLink(link, arg, &html); par1 = QStringRef(); @@ -3164,7 +3287,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, } } - // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags + // replace all "(<@(type|headerfile)(?: +[^>]*)?>)(.*)(</@\\2>)" tags src = html; html = QString(); @@ -3174,13 +3297,13 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, bool handled = false; if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); - const Node* n = qdb_->resolveTarget(arg.toString(), relative, self); + const Node* n = qdb_->findTypeNode(arg.toString(), relative); html += QLatin1String("<span class=\"type\">"); - if (n && n->subType() == Node::QmlBasicType) { - if (relative && relative->subType() == Node::QmlClass) + if (n && n->isQmlBasicType()) { + if (relative && relative->isQmlType()) addLink(linkForNode(n,relative), arg, &html); else - html += arg.toString(); + html += arg; } else addLink(linkForNode(n,relative), arg, &html); @@ -3189,17 +3312,17 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, } else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); - const Node* n = qdb_->resolveTarget(arg.toString(), relative); - addLink(linkForNode(n,relative), arg, &html); - handled = true; - } - else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { - par1 = QStringRef(); - const Node* n = qdb_->resolveTarget(arg.toString(), relative); - addLink(linkForNode(n,relative), arg, &html); + if (arg.at(0) == QChar('&')) + html += arg; + else { + const Node* n = qdb_->findNodeForInclude(QStringList(arg.toString())); + if (n && n != relative) + addLink(linkForNode(n,relative), arg, &html); + else + html += arg; + } handled = true; } - if (!handled) { html += charLangle; html += charAt; @@ -3491,8 +3614,13 @@ QString HtmlGenerator::refForNode(const Node *node) break; case Node::Document: break; - case Node::QmlPropertyGroup: case Node::QmlProperty: + if (node->isAttached()) + ref = node->name() + "-attached-prop"; + else + ref = node->name() + "-prop"; + break; + case Node::QmlPropertyGroup: case Node::Property: ref = node->name() + "-prop"; break; @@ -3515,7 +3643,100 @@ QString HtmlGenerator::refForNode(const Node *node) return registerRef(ref); } -#define DEBUG_ABSTRACT 0 +/*! + This function is called for links, i.e. for words that + are marked with the qdoc link command. For autolinks + that are not marked with the qdoc link command, the + getAutoLink() function is called + + It returns the string for a link found by using the data + in the \a atom to search the database. It also sets \a node + to point to the target node for that link. \a relative points + to the node holding the qdoc comment where the link command + was found. + */ +QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node) +{ + const QString& t = atom->string(); + if (t.at(0) == QChar('h')) { + if (t.startsWith("http:") || t.startsWith("https:")) + return t; + } + else if (t.at(0) == QChar('f')) { + if (t.startsWith("file:") || t.startsWith("ftp:")) + return t; + } + else if (t.at(0) == QChar('m')) { + if (t.startsWith("mailto:")) + return t; + } + + QString ref; + + *node = qdb_->findNodeForAtom(atom, relative, ref); + if (!(*node)) + return QString(); + + QString url = (*node)->url(); + if (!url.isEmpty()) { + if (ref.isEmpty()) + return url; + int hashtag = url.lastIndexOf(QChar('#')); + if (hashtag != -1) + url.truncate(hashtag); + return url + "#" + ref; + } + /* + Given that *node is not null, we now cconstruct a link + to the page that *node represents, and then if we found + a target on that page, we connect the target to the link + with '#'. + */ + QString link = linkForNode(*node, relative); + if (*node && (*node)->subType() == Node::Image) + link = "images/used-in-examples/" + link; + if (!ref.isEmpty()) + link += QLatin1Char('#') + ref; + return link; +} + +/*! + This function is called for autolinks, i.e. for words that + are not marked with the qdoc link command that qdoc has + reason to believe should be links. For links marked with + the qdoc link command, the getLink() function is called. + + It returns the string for a link found by using the data + in the \a atom to search the database. It also sets \a node + to point to the target node for that link. \a relative points + to the node holding the qdoc comment where the link command + was found. + */ +QString HtmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node** node) +{ + QString ref; + QString link; + + *node = qdb_->findNodeForAtom(atom, relative, ref); + if (!(*node)) + return QString(); + + QString url = (*node)->url(); + if (!url.isEmpty()) { + if (ref.isEmpty()) + return url; + int hashtag = url.lastIndexOf(QChar('#')); + if (hashtag != -1) + url.truncate(hashtag); + return url + "#" + ref; + } + + link = linkForNode(*node, relative); + if (!ref.isEmpty()) + link += QLatin1Char('#') + ref; + return link; +} + /*! Construct the link string for the \a node and return it. @@ -3526,7 +3747,7 @@ QString HtmlGenerator::refForNode(const Node *node) */ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative) { - if (node == 0 || node == relative) + if (node == 0) return QString(); if (!node->url().isEmpty()) return node->url(); @@ -3537,7 +3758,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative) QString fn = fileName(node); if (node && relative && node->parent() != relative) { - if (node->parent()->subType() == Node::QmlClass && relative->subType() == Node::QmlClass) { + if (node->parent()->isQmlType() && relative->isQmlType()) { if (node->parent()->isAbstract()) { /* This is a bit of a hack. What we discover with @@ -3609,13 +3830,14 @@ void HtmlGenerator::generateDetailedMember(const Node *node, generateMacRef(node, marker); #endif generateExtractionMark(node, MemberMark); + QString nodeRef = refForNode(node); if (node->type() == Node::Enum && (enume = static_cast<const EnumNode *>(node))->flagsType()) { #ifdef GENERATE_MAC_REFS generateMacRef(enume->flagsType(), marker); #endif - out() << "<h3 class=\"flags\">"; - out() << "<a name=\"" + refForNode(node) + "\"></a>"; + out() << "<h3 class=\"flags\" id=\"" << nodeRef << "\">"; + out() << "<a name=\"" + nodeRef + "\"></a>"; generateSynopsis(enume, relative, marker, CodeMarker::Detailed); out() << "<br/>"; generateSynopsis(enume->flagsType(), @@ -3625,8 +3847,8 @@ void HtmlGenerator::generateDetailedMember(const Node *node, out() << "</h3>\n"; } else { - out() << "<h3 class=\"fn\">"; - out() << "<a name=\"" + refForNode(node) + "\"></a>"; + out() << "<h3 class=\"fn\" id=\"" << nodeRef << "\">"; + out() << "<a name=\"" + nodeRef + "\"></a>"; generateSynopsis(node, relative, marker, CodeMarker::Detailed); out() << "</h3>" << divNavTop << '\n'; } @@ -3680,6 +3902,8 @@ int HtmlGenerator::hOffset(const Node *node) case Node::Namespace: case Node::Class: return 2; + case Node::QmlBasicType: + case Node::QmlType: case Node::Document: return 1; case Node::Enum: @@ -3715,131 +3939,6 @@ const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node) return anchorPair; } -QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node) -{ - QString link; - *node = 0; - inObsoleteLink = false; - - if (atom->string().contains(QLatin1Char(':')) && - (atom->string().startsWith("file:") - || atom->string().startsWith("http:") - || atom->string().startsWith("https:") - || atom->string().startsWith("ftp:") - || atom->string().startsWith("mailto:"))) { - - link = atom->string(); - } - else { - QStringList path; - if (atom->string().contains('#')) { - path = atom->string().split('#'); - } - else { - path.append(atom->string()); - } - - QString ref; - QString first = path.first().trimmed(); - if (first.isEmpty()) { - *node = relative; - } - else if (first.endsWith(".html")) { - /* - This is not a recursive search. That's ok in - this case, because we are searching for a page - node, which must be a direct child of the tree - root. - */ - *node = qdb_->treeRoot()->findChildNodeByNameAndType(first, Node::Document); - } - else { - *node = qdb_->resolveTarget(first, relative); - if (!*node) { - *node = qdb_->findDocNodeByTitle(first, relative); - } - if (!*node) { - *node = qdb_->findUnambiguousTarget(first, ref, relative); - if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) { - QString final = (*node)->url() + "#" + ref; - return final; - } - } - } - if (*node) { - if (!(*node)->url().isEmpty()) { - return (*node)->url(); - } - else { - path.removeFirst(); - } - } - else { - *node = relative; - } - - if (*node) { - if ((*node)->status() == Node::Obsolete) { - if (relative) { - if (relative->parent() != *node) { - if (relative->status() != Node::Obsolete) { - bool porting = false; - if (relative->type() == Node::Document) { - const DocNode* dn = static_cast<const DocNode*>(relative); - if (dn->title().startsWith("Porting")) - porting = true; - } - QString name = relative->plainFullName(); - if (!porting && !name.startsWith("Q3")) { - if (obsoleteLinks) { - relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") - .arg(atom->string()) - .arg(name)); - } - inObsoleteLink = true; - } - } - } - } - else { - qDebug() << "Link to Obsolete entity" - << (*node)->name() << "no relative"; - } - } - } - - /* - This loop really only makes sense if *node is not 0. - In that case, The node *node points to represents a - qdoc page, so the link will ultimately point to some - target on that page. This loop finds that target on - the page that *node represents. ref is that target. - */ - while (!path.isEmpty()) { - ref = qdb_->findTarget(path.first(), *node); - if (ref.isEmpty()) - break; - path.removeFirst(); - } - - /* - Given that *node is not null, we now cconstruct a link - to the page that *node represents, and then if there is - a target on that page, we connect the target to the link - with '#'. - */ - if (path.isEmpty()) { - link = linkForNode(*node, relative); - if (*node && (*node)->subType() == Node::Image) - link = "images/used-in-examples/" + link; - if (!ref.isEmpty()) { - link += QLatin1Char('#') + ref; - } - } - } - return link; -} - void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker) { Text text; @@ -3850,38 +3949,7 @@ void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker) Generator::generateStatus(node, marker); break; case Node::Compat: - if (node->isInnerNode()) { - text << Atom::ParaLeft - << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) - << "This " - << typeString(node) - << " is part of the Qt 3 support library." - << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) - << " It is provided to keep old source code working. " - << "We strongly advise against " - << "using it in new code. See "; - - const DocNode *docNode = qdb_->findDocNodeByTitle("Porting To Qt 4"); - QString ref; - if (docNode && node->type() == Node::Class) { - QString oldName(node->name()); - oldName.remove(QLatin1Char('3')); - ref = qdb_->findTarget(oldName, docNode); - } - - if (!ref.isEmpty()) { - text << Atom(Atom::Link, linkForNode(docNode, node) + QLatin1Char('#') + ref); - } - else - text << Atom(Atom::Link, "Porting to Qt 4"); - - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << Atom(Atom::String, "Porting to Qt 4") - << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) - << " for more information." - << Atom::ParaRight; - } - generateText(text, node, marker); + // Porting to Qt 4 no longer supported break; default: Generator::generateStatus(node, marker); @@ -3999,6 +4067,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, #endif generateExtractionMark(node, MemberMark); out() << "<div class=\"qmlitem\">"; + QString nodeRef = refForNode(node); if (node->type() == Node::QmlPropertyGroup) { const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node); NodeList::ConstIterator p = qpgn->childNodes().constBegin(); @@ -4006,19 +4075,20 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, out() << "<table class=\"qmlname\">"; QString heading = qpgn->name() + " group"; - out() << "<tr valign=\"top\" class=\"even\">"; + out() << "<tr valign=\"top\" class=\"even\" id=\"" << nodeRef << "\">"; out() << "<th class=\"centerAlign\"><p>"; - out() << "<a name=\"" + refForNode(qpgn) + "\"></a>"; + out() << "<a name=\"" + nodeRef + "\"></a>"; out() << "<b>" << heading << "</b>"; out() << "</p></th></tr>"; while (p != qpgn->childNodes().constEnd()) { if ((*p)->type() == Node::QmlProperty) { qpn = static_cast<QmlPropertyNode*>(*p); - out() << "<tr valign=\"top\" class=\"odd\">"; + nodeRef = refForNode(qpn); + out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">"; out() << "<td class=\"tblQmlPropNode\"><p>"; - out() << "<a name=\"" + refForNode(qpn) + "\"></a>"; + out() << "<a name=\"" + nodeRef + "\"></a>"; - if (!qpn->isWritable(qdb_)) + if (!qpn->isWritable()) out() << "<span class=\"qmlreadonly\">read-only</span>"; if (qpn->isDefault()) out() << "<span class=\"qmldefault\">default</span>"; @@ -4034,12 +4104,12 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, qpn = static_cast<QmlPropertyNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; - out() << "<tr valign=\"top\" class=\"odd\">"; + out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">"; out() << "<td class=\"tblQmlPropNode\"><p>"; out() << "<a name=\"" + refForNode(qpn) + "\"></a>"; if (!qpn->isReadOnlySet()) { if (qpn->declarativeCppNode()) - qpn->setReadOnly(!qpn->isWritable(qdb_)); + qpn->setReadOnly(!qpn->isWritable()); } if (qpn->isReadOnly()) out() << "<span class=\"qmlreadonly\">read-only</span>"; @@ -4054,7 +4124,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, const FunctionNode* qsn = static_cast<const FunctionNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; - out() << "<tr valign=\"top\" class=\"odd\">"; + out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">"; out() << "<td class=\"tblQmlFuncNode\"><p>"; out() << "<a name=\"" + refForNode(qsn) + "\"></a>"; generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false); @@ -4066,7 +4136,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, const FunctionNode* qshn = static_cast<const FunctionNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; - out() << "<tr valign=\"top\" class=\"odd\">"; + out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">"; out() << "<td class=\"tblQmlFuncNode\"><p>"; out() << "<a name=\"" + refForNode(qshn) + "\"></a>"; generateSynopsis(qshn,relative,marker,CodeMarker::Detailed,false); @@ -4078,7 +4148,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, const FunctionNode* qmn = static_cast<const FunctionNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; - out() << "<tr valign=\"top\" class=\"odd\">"; + out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">"; out() << "<td class=\"tblQmlFuncNode\"><p>"; out() << "<a name=\"" + refForNode(qmn) + "\"></a>"; generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false); @@ -4101,11 +4171,11 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, Output the "Inherits" line for the QML element, if there should be one. */ -void HtmlGenerator::generateQmlInherits(const QmlClassNode* qcn, CodeMarker* marker) +void HtmlGenerator::generateQmlInherits(QmlClassNode* qcn, CodeMarker* marker) { if (!qcn) return; - const QmlClassNode* base = qcn->qmlBaseNode(); + QmlClassNode* base = qcn->qmlBaseNode(); while (base && base->isInternal()) { base = base->qmlBaseNode(); } @@ -4229,7 +4299,7 @@ void HtmlGenerator::generateManifestFiles() { generateManifestFile("examples", "example"); generateManifestFile("demos", "demo"); - ExampleNode::exampleNodeMap.clear(); + qdb_->exampleNodeMap().clear(); manifestMetaContent.clear(); } @@ -4240,7 +4310,8 @@ void HtmlGenerator::generateManifestFiles() */ void HtmlGenerator::generateManifestFile(QString manifest, QString element) { - if (ExampleNode::exampleNodeMap.isEmpty()) + ExampleNodeMap& exampleNodeMap = qdb_->exampleNodeMap(); + if (exampleNodeMap.isEmpty()) return; QString fileName = manifest +"-manifest.xml"; QFile file(outputDir() + QLatin1Char('/') + fileName); @@ -4251,8 +4322,8 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element) demos = true; bool proceed = false; - ExampleNodeMap::Iterator i = ExampleNode::exampleNodeMap.begin(); - while (i != ExampleNode::exampleNodeMap.end()) { + ExampleNodeMap::Iterator i = exampleNodeMap.begin(); + while (i != exampleNodeMap.end()) { const ExampleNode* en = i.value(); if (demos) { if (en->name().startsWith("demos")) { @@ -4276,8 +4347,8 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element) writer.writeAttribute("module", project); writer.writeStartElement(manifest); - i = ExampleNode::exampleNodeMap.begin(); - while (i != ExampleNode::exampleNodeMap.end()) { + i = exampleNodeMap.begin(); + while (i != exampleNodeMap.end()) { const ExampleNode* en = i.value(); if (demos) { if (!en->name().startsWith("demos")) { @@ -4508,6 +4579,16 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent) break; case Node::Class: break; + case Node::QmlType: + break; + case Node::QmlBasicType: + break; + case Node::Group: + break; + case Node::Module: + break; + case Node::QmlModule: + break; case Node::Document: switch (child->subType()) { case Node::Example: @@ -4518,22 +4599,10 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent) break; case Node::Image: break; - case Node::Group: - break; - case Node::Module: - break; case Node::Page: break; case Node::ExternalPage: break; - case Node::QmlClass: - break; - case Node::QmlBasicType: - break; - case Node::QmlModule: - break; - case Node::Collision: - break; default: break; } |