diff options
Diffstat (limited to 'src/tools/qdoc/htmlgenerator.cpp')
-rw-r--r-- | src/tools/qdoc/htmlgenerator.cpp | 412 |
1 files changed, 212 insertions, 200 deletions
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 4aed6085cd..18d2af5810 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -49,6 +49,7 @@ #include <qiterator.h> #include <qtextcodec.h> #include <quuid.h> +#include <qmap.h> QT_BEGIN_NAMESPACE @@ -71,11 +72,11 @@ static void addLink(const QString &linkTarget, QString *res) { if (!linkTarget.isEmpty()) { - *res += "<a href=\""; + *res += QLatin1String("<a href=\""); *res += linkTarget; - *res += "\">"; + *res += QLatin1String("\">"); *res += nestedStuff; - *res += "</a>"; + *res += QLatin1String("</a>"); } else { *res += nestedStuff; @@ -139,8 +140,8 @@ void HtmlGenerator::initializeGenerator(const Config &config) */ int i = 0; while (defaults[i].key) { - formattingLeftMap().insert(defaults[i].key, defaults[i].left); - formattingRightMap().insert(defaults[i].key, defaults[i].right); + formattingLeftMap().insert(QLatin1String(defaults[i].key), QLatin1String(defaults[i].left)); + formattingRightMap().insert(QLatin1String(defaults[i].key), QLatin1String(defaults[i].right)); i++; } @@ -180,7 +181,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) projectDescription = config.getString(CONFIG_DESCRIPTION); if (projectDescription.isEmpty() && !project.isEmpty()) - projectDescription = project + " Reference Documentation"; + projectDescription = project + QLatin1String(" Reference Documentation"); projectUrl = config.getString(CONFIG_URL); tagFile_ = config.getString(CONFIG_TAGFILE); @@ -236,8 +237,8 @@ void HtmlGenerator::initializeGenerator(const Config &config) headerStyles = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSTYLES); QString prefix = CONFIG_QHP + Config::dot + project + Config::dot; - manifestDir = "qthelp://" + config.getString(prefix + "namespace"); - manifestDir += QLatin1Char('/') + config.getString(prefix + "virtualFolder") + QLatin1Char('/'); + manifestDir = QLatin1String("qthelp://") + config.getString(prefix + QLatin1String("namespace")); + manifestDir += QLatin1Char('/') + config.getString(prefix + QLatin1String("virtualFolder")) + QLatin1Char('/'); readManifestMetaContent(config); examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH); if (!examplesPath.isEmpty()) @@ -282,12 +283,17 @@ QString HtmlGenerator::format() */ void HtmlGenerator::generateKeywordAnchors(const Node* node) { + Q_UNUSED(node); + // Disabled: keywords always link to the top of the QDoc + // comment they appear in, and do not use a dedicated anchor. +#if 0 if (!node->doc().isEmpty()) { const QList<Atom*>& keywords = node->doc().keywords(); foreach (Atom* a, keywords) { - out() << "<a name=\"" << Doc::canonicalTitle(a->string()) << "\"></a>"; + out() << QLatin1String("<a name=\"") << Doc::canonicalTitle(a->string()) << QLatin1String("\"></a>"); } } +#endif } /*! @@ -470,18 +476,10 @@ QString HtmlGenerator::generateLinksToBrokenLinksPage(CodeMarker* marker, int& c */ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker) { - int skipAhead = 0; + int idx, skipAhead = 0; static bool in_para = false; switch (atom->type()) { - case Atom::AbstractLeft: - if (relative) - relative->doc().location().warning(tr("\abstract is not implemented.")); - else - Location::information(tr("\abstract is not implemented.")); - break; - case Atom::AbstractRight: - break; case Atom::AutoLink: case Atom::NavAutoLink: if (!inLink_ && !inContents_ && !inSectionHeading_) { @@ -547,9 +545,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark else out() << "variable"; QStringList words = str.split(QLatin1Char(' ')); - if (!(words.first() == "contains" || words.first() == "specifies" - || words.first() == "describes" || words.first() == "defines" - || words.first() == "holds" || words.first() == "determines")) + if (!(words.first() == QLatin1String("contains") || words.first() == QLatin1String("specifies") + || words.first() == QLatin1String("describes") || words.first() == QLatin1String("defines") + || words.first() == QLatin1String("holds") || words.first() == QLatin1String("determines"))) out() << " holds "; else out() << ' '; @@ -668,74 +666,83 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark break; case Atom::AnnotatedList: { - CollectionNode* cn = qdb_->getCollection(atom->string(), Node::DOC); + const CollectionNode* cn = qdb_->getCollectionNode(atom->string(), Node::DOC); if (cn) generateList(cn, marker, atom->string()); } break; case Atom::GeneratedList: - if (atom->string() == "annotatedclasses") { + if (atom->string() == QLatin1String("annotatedclasses")) { generateAnnotatedList(relative, marker, qdb_->getCppClasses()); } - else if (atom->string() == "classes") { + else if (atom->string() == QLatin1String("classes")) { 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") { + else if (atom->string() == QLatin1String("qmlbasictypes")) { generateCompactList(Generic, relative, qdb_->getQmlBasicTypes(), true, QStringLiteral("")); } - else if (atom->string() == "qmltypes") { + else if (atom->string() == QLatin1String("qmltypes")) { generateCompactList(Generic, relative, qdb_->getQmlTypes(), true, QStringLiteral("")); } - else if (atom->string().contains("classesbymodule")) { - QString physicalModuleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed(); + else if ((idx = atom->string().indexOf(QStringLiteral("bymodule"))) != -1) { + QString moduleName = atom->string().mid(idx + 8).trimmed(); + Node::Genus genus = Node::CPP; + if (atom->string().startsWith(QLatin1String("qml"))) + genus = Node::QML; + else if (atom->string().startsWith(QLatin1String("js"))) + genus = Node::JS; QDocDatabase* qdb = QDocDatabase::qdocDB(); - CollectionNode* cn = qdb->findModule(physicalModuleName); + const CollectionNode* cn = qdb->getCollectionNode(moduleName, genus); if (cn) { - NodeMap m; - cn->getMemberClasses(m); - if (!m.isEmpty()) { - generateAnnotatedList(relative, marker, m); + if (genus == Node::CPP) { + NodeMap m; + cn->getMemberClasses(m); + if (!m.isEmpty()) { + generateAnnotatedList(relative, marker, m); + } } + else + generateAnnotatedList(relative, marker, cn->members()); } } - else if (atom->string() == "classhierarchy") { + else if (atom->string() == QLatin1String("classhierarchy")) { generateClassHierarchy(relative, qdb_->getCppClasses()); } - else if (atom->string() == "obsoleteclasses") { + else if (atom->string() == QLatin1String("obsoleteclasses")) { generateCompactList(Generic, relative, qdb_->getObsoleteClasses(), false, QStringLiteral("Q")); } - else if (atom->string() == "obsoleteqmltypes") { + else if (atom->string() == QLatin1String("obsoleteqmltypes")) { generateCompactList(Generic, relative, qdb_->getObsoleteQmlTypes(), false, QStringLiteral("")); } - else if (atom->string() == "obsoletecppmembers") { + else if (atom->string() == QLatin1String("obsoletecppmembers")) { generateCompactList(Obsolete, relative, qdb_->getClassesWithObsoleteMembers(), false, QStringLiteral("Q")); } - else if (atom->string() == "obsoleteqmlmembers") { + else if (atom->string() == QLatin1String("obsoleteqmlmembers")) { generateCompactList(Obsolete, relative, qdb_->getQmlTypesWithObsoleteMembers(), false, QStringLiteral("")); } - else if (atom->string() == "functionindex") { + else if (atom->string() == QLatin1String("functionindex")) { generateFunctionIndex(relative); } - else if (atom->string() == "legalese") { + else if (atom->string() == QLatin1String("legalese")) { generateLegaleseList(relative, marker); } - else if (atom->string() == "overviews") { + else if (atom->string() == QLatin1String("overviews")) { generateList(relative, marker, "overviews"); } - else if (atom->string() == "cpp-modules") { + else if (atom->string() == QLatin1String("cpp-modules")) { generateList(relative, marker, "cpp-modules"); } - else if (atom->string() == "qml-modules") { + else if (atom->string() == QLatin1String("qml-modules")) { generateList(relative, marker, "qml-modules"); } - else if (atom->string() == "namespaces") { + else if (atom->string() == QLatin1String("namespaces")) { generateAnnotatedList(relative, marker, qdb_->getNamespaces()); } - else if (atom->string() == "related") { + else if (atom->string() == QLatin1String("related")) { generateList(relative, marker, "related"); } #if 0 @@ -743,7 +750,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark This is not used in Qt5, as of 10/02/2014 Remove permanently if it is not missed. */ - else if (atom->string() == "relatedinline") { + else if (atom->string() == QLatin1String("relatedinline")) { const DocumentNode *dn = static_cast<const DocumentNode *>(relative); if (dn && !dn->members().isEmpty()) { // Reverse the list into the original scan order. @@ -1218,13 +1225,13 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark p2 = atom->string(1); } if (!p1.isEmpty()) { - if (p1 == "borderless") + if (p1 == QLatin1String("borderless")) attr = p1; else if (p1.contains("%")) width = p1; } if (!p2.isEmpty()) { - if (p2 == "borderless") + if (p2 == QLatin1String("borderless")) attr = p2; else if (p2.contains("%")) width = p2; @@ -1336,7 +1343,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark /*! Generate a reference page for a C++ class or a C++ namespace. */ -void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) +void HtmlGenerator::generateClassLikeNode(Aggregate* inner, CodeMarker* marker) { QList<Section> sections; QList<Section>::ConstIterator s; @@ -1485,7 +1492,7 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m); if (func->metaness() == FunctionNode::Ctor || func->metaness() == FunctionNode::Dtor || - func->overloadNumber() != 1) + func->overloadNumber() != 0) names.clear(); } else if ((*m)->type() == Node::Property) { @@ -1644,7 +1651,7 @@ void HtmlGenerator::generateDocumentNode(DocumentNode* dn, CodeMarker* marker) is DITA map page, write the node's contents as a dita map and return without doing anything else. */ - if (dn->subType() == Node::Page && dn->pageType() == Node::DitaMapPage) { + if (dn->docSubtype() == Node::Page && dn->pageType() == Node::DitaMapPage) { const DitaMapNode* dmn = static_cast<const DitaMapNode*>(dn); writeDitaMap(dmn); return; @@ -1660,7 +1667,7 @@ void HtmlGenerator::generateDocumentNode(DocumentNode* dn, CodeMarker* marker) Generate the TOC for the new doc format. Don't generate a TOC for the home page. */ - if ((dn->name() != QStringLiteral("index.html"))) + if ((dn->name() != QLatin1String("index.html"))) generateTableOfContents(dn,marker,0); generateKeywordAnchors(dn); @@ -1670,7 +1677,7 @@ void HtmlGenerator::generateDocumentNode(DocumentNode* dn, CodeMarker* marker) dn, marker); - if (dn->subType() == Node::HeaderFile) { + if (dn->docSubtype() == Node::HeaderFile) { // Generate brief text and status for modules. generateBrief(dn, marker); generateStatus(dn, marker); @@ -1804,10 +1811,12 @@ void HtmlGenerator::generateCollectionNode(CollectionNode* cn, CodeMarker* marke generateAlsoList(cn, marker); generateExtractionMark(cn, EndMark); - if (cn->isGroup()) - generateAnnotatedList(cn, marker, cn->members()); - else if (cn->isQmlModule() || cn->isJsModule()) - generateAnnotatedList(cn, marker, cn->members()); + if (!cn->noAutoList()) { + if (cn->isGroup()) + generateAnnotatedList(cn, marker, cn->members()); + else if (cn->isQmlModule() || cn->isJsModule()) + generateAnnotatedList(cn, marker, cn->members()); + } sections = marker->sections(cn, CodeMarker::Detailed, CodeMarker::Okay); s = sections.constBegin(); @@ -2087,7 +2096,7 @@ void HtmlGenerator::generateFooter(const Node *node) 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) +void HtmlGenerator::generateRequisites(Aggregate *inner, CodeMarker *marker) { QMap<QString, Text> requisites; Text text; @@ -2136,7 +2145,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->physicalModuleName().isEmpty()) { - CollectionNode* cn = qdb_->findModule(inner->physicalModuleName()); + const CollectionNode* cn = qdb_->getCollectionNode(inner->physicalModuleName(), Node::CPP); if (cn && !cn->qtVariable().isEmpty()) { text.clear(); text << "QT += " + cn->qtVariable(); @@ -2246,11 +2255,7 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker) //add the module name and version to the map QString logicalModuleVersion; - CollectionNode* collection = 0; - if (qcn->isJsNode()) - collection = qdb_->findJsModule(qcn->logicalModuleName()); - else - collection = qdb_->findQmlModule(qcn->logicalModuleName()); + const CollectionNode* collection = qdb_->getCollectionNode(qcn->logicalModuleName(), qcn->genus()); if (collection) logicalModuleVersion = collection->logicalModuleVersion(); else @@ -2359,7 +2364,7 @@ void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker, } } -void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker) +void HtmlGenerator::generateIncludes(const Aggregate *inner, CodeMarker *marker) { if (!inner->includes().isEmpty()) { out() << "<pre class=\"cpp\">" @@ -2518,7 +2523,7 @@ void HtmlGenerator::generateSidebar() { out() << "</div>\n"; } -QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, +QString HtmlGenerator::generateListOfAllMemberFile(const Aggregate *inner, CodeMarker *marker) { QList<Section> sections; @@ -2613,7 +2618,7 @@ QString HtmlGenerator::generateAllQmlMembersFile(QmlTypeNode* qml_cn, CodeMarker return fileName; } -QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner, +QString HtmlGenerator::generateLowStatusMemberFile(Aggregate *inner, CodeMarker *marker, CodeMarker::Status status) { @@ -3164,13 +3169,13 @@ void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const { CNMap cnm; Node::Genus genus = Node::DontCare; - if (selector == "overviews") + if (selector == QLatin1String("overviews")) genus = Node::DOC; - else if (selector == "cpp-modules") + else if (selector == QLatin1String("cpp-modules")) genus = Node::CPP; - else if (selector == "qml-modules") + else if (selector == QLatin1String("qml-modules")) genus = Node::QML; - else if (selector == "js-modules") + else if (selector == QLatin1String("js-modules")) genus = Node::JS; if (genus != Node::DontCare) { NodeList nl; @@ -3345,7 +3350,7 @@ void HtmlGenerator::generateSectionList(const Section& section, void HtmlGenerator::generateSectionInheritedList(const Section& section, const Node *relative) { - QList<QPair<InnerNode *, int> >::ConstIterator p = section.inherited.constBegin(); + QList<QPair<Aggregate *, int> >::ConstIterator p = section.inherited.constBegin(); while (p != section.inherited.constEnd()) { out() << "<li class=\"fn\">"; out() << (*p).second << ' '; @@ -3415,6 +3420,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, { QString src = markedCode; QString html; + html.reserve(src.size()); QStringRef arg; QStringRef par1; @@ -3427,62 +3433,30 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, static const QString linkTag("link"); // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)" + // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" + // replace all "(<@(type|headerfile)(?: +[^>]*)?>)(.*)(</@\\2>)" tags bool done = false; for (int i = 0, srcSize = src.size(); i < srcSize;) { if (src.at(i) == charLangle && src.at(i + 1) == charAt) { if (alignNames && !done) { - html += "</td><td class=\"memItemRight bottomAlign\">"; + html += QLatin1String("</td><td class=\"memItemRight bottomAlign\">"); done = true; } i += 2; if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) { - html += "<b>"; + html += QLatin1String("<b>"); const Node* n = CodeMarker::nodeForString(par1.toString()); QString link = linkForNode(n, relative); addLink(link, arg, &html); - html += "</b>"; - } - else { - html += charLangle; - html += charAt; + html += QLatin1String("</b>"); } - } - else { - html += src.at(i++); - } - } - - // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" - src = html; - html = QString(); - for (int i = 0, srcSize = src.size(); i < srcSize;) { - if (src.at(i) == charLangle && src.at(i + 1) == charAt) { - i += 2; - if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { + else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { const Node* n = qdb_->findFunctionNode(par1.toString(), relative, Node::DontCare); QString link = linkForNode(n, relative); addLink(link, arg, &html); par1 = QStringRef(); } - else { - html += charLangle; - html += charAt; - } - } - else { - html += src.at(i++); - } - } - - // replace all "(<@(type|headerfile)(?: +[^>]*)?>)(.*)(</@\\2>)" tags - src = html; - html = QString(); - - for (int i=0, srcSize=src.size(); i<srcSize;) { - if (src.at(i) == charLangle && src.at(i+1) == charAt) { - i += 2; - bool handled = false; - if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { + else if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); const Node* n = qdb_->findTypeNode(arg.toString(), relative); html += QLatin1String("<span class=\"type\">"); @@ -3495,7 +3469,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, else addLink(linkForNode(n,relative), arg, &html); html += QLatin1String("</span>"); - handled = true; } else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) { par1 = QStringRef(); @@ -3508,9 +3481,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, else html += arg; } - handled = true; } - if (!handled) { + else { html += charLangle; html += charAt; } @@ -3533,59 +3505,68 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, // "</@(?:comment|preprocessor|string|char|number|op|type|name|keyword)>" -> "</span>" src = html; html = QString(); - static const QString spanTags[] = { - "<@comment>", "<span class=\"comment\">", - "<@preprocessor>", "<span class=\"preprocessor\">", - "<@string>", "<span class=\"string\">", - "<@char>", "<span class=\"char\">", - "<@number>", "<span class=\"number\">", - "<@op>", "<span class=\"operator\">", - "<@type>", "<span class=\"type\">", - "<@name>", "<span class=\"name\">", - "<@keyword>", "<span class=\"keyword\">", - "</@comment>", "</span>", - "</@preprocessor>", "</span>", - "</@string>", "</span>", - "</@char>", "</span>", - "</@number>", "</span>", - "</@op>", "</span>", - "</@type>", "</span>", - "</@name>", "</span>", - "</@keyword>", "</span>", + html.reserve(src.size()); + static const QLatin1String spanTags[] = { + QLatin1String("comment>"), QLatin1String("<span class=\"comment\">"), + QLatin1String("preprocessor>"), QLatin1String("<span class=\"preprocessor\">"), + QLatin1String("string>"), QLatin1String("<span class=\"string\">"), + QLatin1String("char>"), QLatin1String("<span class=\"char\">"), + QLatin1String("number>"), QLatin1String("<span class=\"number\">"), + QLatin1String("op>"), QLatin1String("<span class=\"operator\">"), + QLatin1String("type>"), QLatin1String("<span class=\"type\">"), + QLatin1String("name>"), QLatin1String("<span class=\"name\">"), + QLatin1String("keyword>"), QLatin1String("<span class=\"keyword\">") }; + int nTags = 9; // Update the upper bound of k in the following code to match the length // of the above array. for (int i = 0, n = src.size(); i < n;) { - if (src.at(i) == charLangle) { - bool handled = false; - for (int k = 0; k != 18; ++k) { - const QString & tag = spanTags[2 * k]; - if (tag == QStringRef(&src, i, tag.length())) { - html += spanTags[2 * k + 1]; - i += tag.length(); - handled = true; - break; + if (src.at(i) == QLatin1Char('<')) { + if (src.at(i + 1) == QLatin1Char('@')) { + i += 2; + bool handled = false; + for (int k = 0; k != nTags; ++k) { + const QLatin1String& tag = spanTags[2 * k]; + if (i + tag.size() <= src.length() && + tag == QStringRef(&src, i, tag.size())) { + html += spanTags[2 * k + 1]; + i += tag.size(); + handled = true; + break; + } } - } - if (!handled) { - ++i; - if (src.at(i) == charAt || - (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) { + if (!handled) { // drop 'our' unknown tags (the ones still containing '@') while (i < n && src.at(i) != QLatin1Char('>')) ++i; ++i; } - else { - // retain all others - html += charLangle; + continue; + } + else if (src.at(i + 1) == QLatin1Char('/') && src.at(i + 2) == QLatin1Char('@')) { + i += 3; + bool handled = false; + for (int k = 0; k != nTags; ++k) { + const QLatin1String& tag = spanTags[2 * k]; + if (i + tag.size() <= src.length() && + tag == QStringRef(&src, i, tag.size())) { + html += QLatin1String("</span>"); + i += tag.size(); + handled = true; + break; + } + } + if (!handled) { + // drop 'our' unknown tags (the ones still containing '@') + while (i < n && src.at(i) != QLatin1Char('>')) + ++i; + ++i; } + continue; } } - else { - html += src.at(i); - ++i; - } + html += src.at(i); + ++i; } return html; } @@ -3660,7 +3641,7 @@ QString HtmlGenerator::protect(const QString &string, const QString &outputEncod APPEND(">"); } else if (ch == QLatin1Char('"')) { APPEND("""); - } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F) + } else if ((outputEncoding == QLatin1String("ISO-8859-1") && ch.unicode() > 0x007F) || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/')) || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) { // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator @@ -3686,13 +3667,13 @@ QString HtmlGenerator::fileBase(const Node *node) const result = Generator::fileBase(node); - if (!node->isInnerNode()) { + if (!node->isAggregate()) { switch (node->status()) { case Node::Compat: - result += "-compat"; + result += QLatin1String("-compat"); break; case Node::Obsolete: - result += "-obsolete"; + result += QLatin1String("-obsolete"); break; default: ; @@ -3704,9 +3685,9 @@ QString HtmlGenerator::fileBase(const Node *node) const QString HtmlGenerator::fileName(const Node *node) { if (node->type() == Node::Document) { - if (static_cast<const DocumentNode *>(node)->subType() == Node::ExternalPage) + if (static_cast<const DocumentNode *>(node)->docSubtype() == Node::ExternalPage) return node->name(); - if (static_cast<const DocumentNode *>(node)->subType() == Node::Image) + if (static_cast<const DocumentNode *>(node)->docSubtype() == Node::Image) return node->name(); } return Generator::fileName(node); @@ -3737,12 +3718,12 @@ QString HtmlGenerator::refForNode(const Node *node) break; case Node::Function: func = static_cast<const FunctionNode *>(node); - if (func->associatedProperty()) { - return refForNode(func->associatedProperty()); + if (func->hasOneAssociatedProperty() && func->doc().isEmpty()) { + return refForNode(func->firstAssociatedProperty()); } else { ref = func->name(); - if (func->overloadNumber() != 1) + if (func->overloadNumber() != 0) ref += QLatin1Char('-') + QString::number(func->overloadNumber()); } break; @@ -3767,7 +3748,7 @@ QString HtmlGenerator::refForNode(const Node *node) case Node::QmlMethod: func = static_cast<const FunctionNode *>(node); ref = func->name() + "-method"; - if (func->overloadNumber() != 1) + if (func->overloadNumber() != 0) ref += QLatin1Char('-') + QString::number(func->overloadNumber()); break; case Node::Variable: @@ -3831,12 +3812,10 @@ QString HtmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const QString link = (*node)->url(); if (link.isEmpty()) { link = linkForNode(*node, relative); - if ((*node)->subType() == Node::Image) + if ((*node)->docSubtype() == Node::Image) link = "images/used-in-examples/" + link; - if (!ref.isEmpty()) - link += QLatin1Char('#') + ref; } - else if (!ref.isEmpty()) { + if (!ref.isEmpty()) { int hashtag = link.lastIndexOf(QChar('#')); if (hashtag != -1) link.truncate(hashtag); @@ -3872,7 +3851,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative) } QString link = fn; - if (!node->isInnerNode() || node->isQmlPropertyGroup() || node->isJsPropertyGroup()) { + if (!node->isAggregate() || node->isQmlPropertyGroup() || node->isJsPropertyGroup()) { QString ref = refForNode(node); if (relative && fn == fileName(relative) && ref == refForNode(relative)) return QString(); @@ -3923,27 +3902,25 @@ void HtmlGenerator::generateFullName(const Node *apparentNode, const Node *relat } void HtmlGenerator::generateDetailedMember(const Node *node, - const InnerNode *relative, + const Aggregate *relative, CodeMarker *marker) { - const EnumNode *enume; - + const EnumNode *etn; #ifdef GENERATE_MAC_REFS generateMacRef(node, marker); #endif generateExtractionMark(node, MemberMark); generateKeywordAnchors(node); QString nodeRef = refForNode(node); - if (node->type() == Node::Enum - && (enume = static_cast<const EnumNode *>(node))->flagsType()) { + if (node->isEnumType() && (etn = static_cast<const EnumNode *>(node))->flagsType()) { #ifdef GENERATE_MAC_REFS - generateMacRef(enume->flagsType(), marker); + generateMacRef(etn->flagsType(), marker); #endif out() << "<h3 class=\"flags\" id=\"" << nodeRef << "\">"; out() << "<a name=\"" + nodeRef + "\"></a>"; - generateSynopsis(enume, relative, marker, CodeMarker::Detailed); + generateSynopsis(etn, relative, marker, CodeMarker::Detailed); out() << "<br/>"; - generateSynopsis(enume->flagsType(), + generateSynopsis(etn->flagsType(), relative, marker, CodeMarker::Detailed); @@ -3958,10 +3935,11 @@ void HtmlGenerator::generateDetailedMember(const Node *node, generateStatus(node, marker); generateBody(node, marker); + generateOverloadedSignal(node, marker); generateThreadSafeness(node, marker); generateSince(node, marker); - if (node->type() == Node::Property) { + if (node->isProperty()) { const PropertyNode *property = static_cast<const PropertyNode *>(node); Section section; @@ -3987,16 +3965,17 @@ void HtmlGenerator::generateDetailedMember(const Node *node, const FunctionNode* fn = static_cast<const FunctionNode*>(node); if (fn->isPrivateSignal()) generatePrivateSignalNote(node, marker); + generateAssociatedPropertyNotes(fn); } - else if (node->type() == Node::Enum) { - const EnumNode *enume = static_cast<const EnumNode *>(node); - if (enume->flagsType()) { - out() << "<p>The " << protectEnc(enume->flagsType()->name()) + else if (node->isEnumType()) { + const EnumNode *etn = static_cast<const EnumNode *>(node); + if (etn->flagsType()) { + out() << "<p>The " << protectEnc(etn->flagsType()->name()) << " type is a typedef for " << "<a href=\"" << qflagsHref_ << "\">QFlags</a><" - << protectEnc(enume->name()) + << protectEnc(etn->name()) << ">. It stores an OR combination of " - << protectEnc(enume->name()) + << protectEnc(etn->name()) << " values.</p>\n"; } } @@ -4053,7 +4032,7 @@ void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker) switch (node->status()) { case Node::Obsolete: - if (node->isInnerNode()) + if (node->isAggregate()) Generator::generateStatus(node, marker); break; case Node::Compat: @@ -4166,7 +4145,7 @@ void HtmlGenerator::generateQmlSummary(const Section& section, on a QML element reference page. */ void HtmlGenerator::generateDetailedQmlMember(Node *node, - const InnerNode *relative, + const Aggregate *relative, CodeMarker *marker) { QmlPropertyNode* qpn = 0; @@ -4371,8 +4350,8 @@ void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType if (markType == MemberMark) { if (node->type() == Node::Function) { const FunctionNode *func = static_cast<const FunctionNode *>(node); - if (!func->associatedProperty()) { - if (func->overloadNumber() == 1) + if (!func->hasAssociatedProperties()) { + if (func->overloadNumber() == 0) out() << "[overload1]"; out() << "$$$" + func->name() + func->rawParameters().remove(' '); } @@ -4428,7 +4407,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString QString fileName = manifest +"-manifest.xml"; QFile file(outputDir() + QLatin1Char('/') + fileName); bool demos = false; - if (manifest == "demos") + if (manifest == QLatin1String("demos")) demos = true; bool proceed = false; @@ -4481,7 +4460,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString writer.writeAttribute("docUrl", docUrl); QStringList proFiles; foreach (const Node* child, en->childNodes()) { - if (child->subType() == Node::File) { + if (child->docSubtype() == Node::File) { QString file = child->name(); if (file.endsWith(".pro") || file.endsWith(".qmlproject")) { proFiles << file; @@ -4578,11 +4557,11 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString if (s.length() < 2 || s.at(0).isDigit() || s.at(0) == '-' - || s == QStringLiteral("qt") - || s == QStringLiteral("the") - || s == QStringLiteral("and") - || s.startsWith(QStringLiteral("example")) - || s.startsWith(QStringLiteral("chapter"))) + || s == QLatin1String("qt") + || s == QLatin1String("the") + || s == QLatin1String("and") + || s.startsWith(QLatin1String("example")) + || s.startsWith(QLatin1String("chapter"))) tag_it = tags.erase(tag_it); else if (s != *tag_it) { modified << s; @@ -4596,7 +4575,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString if (!tags.isEmpty()) { writer.writeStartElement("tags"); bool wrote_one = false; - foreach (QString tag, tags) { + foreach (const QString &tag, tags) { if (wrote_one) writer.writeCharacters(","); writer.writeCharacters(tag); @@ -4608,7 +4587,7 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString QString ename = en->name().mid(en->name().lastIndexOf('/')+1); QMap<int, const Node*> filesToOpen; foreach (const Node* child, en->childNodes()) { - if (child->subType() == Node::File) { + if (child->docSubtype() == Node::File) { QFileInfo fileInfo(child->name()); QString fileName = fileInfo.fileName().toLower(); // open .qml, .cpp and .h files with a @@ -4693,7 +4672,7 @@ void HtmlGenerator::readManifestMetaContent(const Config &config) subtype: QML class subtype: QML module */ -void HtmlGenerator::reportOrphans(const InnerNode* parent) +void HtmlGenerator::reportOrphans(const Aggregate* parent) { const NodeList& children = parent->childNodes(); if (children.size() == 0) @@ -4729,7 +4708,7 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent) case Node::QmlModule: break; case Node::Document: - switch (child->subType()) { + switch (child->docSubtype()) { case Node::Example: break; case Node::HeaderFile: @@ -4819,7 +4798,7 @@ QXmlStreamWriter& HtmlGenerator::xmlWriter() It also ensures that a GUID map is created for the output file. */ -void HtmlGenerator::beginDitamapPage(const InnerNode* node, const QString& fileName) +void HtmlGenerator::beginDitamapPage(const Aggregate* node, const QString& fileName) { Generator::beginSubPage(node,fileName); QXmlStreamWriter* writer = new QXmlStreamWriter(out().device()); @@ -4891,4 +4870,37 @@ void HtmlGenerator::writeDitaRefs(const DitaRefList& ditarefs) } } +/*! + Generates bold Note lines that explain how function \a fn + is associated with each of its associated properties. + */ +void HtmlGenerator::generateAssociatedPropertyNotes(const FunctionNode* fn) +{ + if (fn->hasAssociatedProperties()) { + out() << "<p><b>Note:</b> "; + foreach (const PropertyNode* pn, fn->associatedProperties()) { + QString msg; + switch (pn->role(fn)) { + case PropertyNode::Getter: + msg = QStringLiteral("Getter function "); + break; + case PropertyNode::Setter: + msg = QStringLiteral("Setter function "); + break; + case PropertyNode::Resetter: + msg = QStringLiteral("Resetter function "); + break; + case PropertyNode::Notifier: + msg = QStringLiteral("Notifier signal "); + break; + default: + break; + } + QString link = linkForNode(pn, 0); + out() << msg << "for property <a href=\"" << link << "\">" << pn->name() << "</a>. "; + } + out() << "</p>"; + } +} + QT_END_NAMESPACE |