diff -r b72c6db6890b -r 5dc02b23752f tools/qdoc3/htmlgenerator.cpp --- a/tools/qdoc3/htmlgenerator.cpp Wed Jun 23 19:07:03 2010 +0300 +++ b/tools/qdoc3/htmlgenerator.cpp Tue Jul 06 15:10:48 2010 +0300 @@ -44,6 +44,7 @@ */ #include "codemarker.h" +#include "codeparser.h" #include "helpprojectwriter.h" #include "htmlgenerator.h" #include "node.h" @@ -54,10 +55,12 @@ #include #include #include +#include QT_BEGIN_NAMESPACE #define COMMAND_VERSION Doc::alias("version") +int HtmlGenerator::id = 0; QString HtmlGenerator::sinceTitles[] = { @@ -71,6 +74,7 @@ " New Typedefs", " New Properties", " New Variables", + " New QML Elements", " New Qml Properties", " New Qml Signals", " New Qml Methods", @@ -201,10 +205,18 @@ HtmlGenerator::HtmlGenerator() - : helpProjectWriter(0), inLink(false), inContents(false), - inSectionHeading(false), inTableHeader(false), numTableRows(0), - threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"), - myTree(0), slow(false), obsoleteLinks(false) + : helpProjectWriter(0), + inLink(false), + inContents(false), + inSectionHeading(false), + inTableHeader(false), + numTableRows(0), + threeColumnEnumValueTable(true), + offlineDocs(true), + funcLeftParen("\\S(\\()"), + myTree(0), + slow(false), + obsoleteLinks(false) { } @@ -248,6 +260,9 @@ postHeader = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTHEADER); + postPostHeader = config.getString(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_POSTPOSTHEADER); footer = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_FOOTER); @@ -259,13 +274,22 @@ HTMLGENERATOR_GENERATEMACREFS); project = config.getString(CONFIG_PROJECT); - + offlineDocs = !config.getBool(CONFIG_ONLINE); projectDescription = config.getString(CONFIG_DESCRIPTION); if (projectDescription.isEmpty() && !project.isEmpty()) projectDescription = project + " Reference Documentation"; projectUrl = config.getString(CONFIG_URL); + outputEncoding = config.getString(CONFIG_OUTPUTENCODING); + if (outputEncoding.isEmpty()) + outputEncoding = QLatin1String("ISO-8859-1"); + outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit()); + + naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE); + if (naturalLanguage.isEmpty()) + naturalLanguage = QLatin1String("en"); + QSet editionNames = config.subVars(CONFIG_EDITION); QSet::ConstIterator edition = editionNames.begin(); while (edition != editionNames.end()) { @@ -321,6 +345,7 @@ */ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) { +#if 0 // Copy the stylesheets from the directory containing the qdocconf file. // ### This should be changed to use a special directory in doc/src. QStringList::ConstIterator styleIter = stylesheets.begin(); @@ -330,7 +355,7 @@ Config::copyFile(Location(), filePath, filePath, outputDir()); ++styleIter; } - +#endif myTree = tree; nonCompatClasses.clear(); mainClasses.clear(); @@ -389,9 +414,9 @@ "qmake Manual", dcfQmakeRoot); - generateIndex(project.toLower().simplified().replace(" ", "-"), - projectUrl, - projectDescription); + QString fileBase = project.toLower().simplified().replace(" ", "-"); + generateIndex(fileBase, projectUrl, projectDescription); + generatePageIndex(outputDir() + "/" + fileBase + ".pageindex", marker); helpProjectWriter->generate(myTree); } @@ -431,11 +456,11 @@ endLink(); } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } break; case Atom::BaseName: @@ -483,7 +508,7 @@ case Atom::C: out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]; if (inLink) { - out() << protect(plainCode(atom->string())); + out() << protectEnc(plainCode(atom->string())); } else { out() << highlightedCode(atom->string(), marker, relative); @@ -491,14 +516,14 @@ out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE]; break; case Atom::Code: - out() << "
"
+	out() << "
"
               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
                                                  marker,relative))
               << "
\n"; break; #ifdef QDOC_QML case Atom::Qml: - out() << "
"
+	out() << "
"
               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
                                                  marker,relative))
               << "
\n"; @@ -506,7 +531,7 @@ #endif case Atom::CodeNew: out() << "

you can rewrite it as

\n" - << "
"
+              << "
"
               << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
                                                  marker,relative))
               << "
\n"; @@ -515,9 +540,9 @@ out() << "

For example, if you have code like

\n"; // fallthrough case Atom::CodeBad: - out() << "
"
-              << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
-              << "
\n"; + out() << "
"
+              << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))
+              << "
\n"; break; case Atom::FootnoteLeft: // ### For now @@ -574,7 +599,7 @@ generateAnnotatedList(relative, marker, nonCompatClasses); } else if (atom->string() == "classes") { - generateCompactList(relative, marker, nonCompatClasses); + generateCompactList(relative, marker, nonCompatClasses, true); } else if (atom->string().contains("classesbymodule")) { QString arg = atom->string().trimmed(); @@ -622,10 +647,10 @@ generateClassHierarchy(relative, marker, nonCompatClasses); } else if (atom->string() == "compatclasses") { - generateCompactList(relative, marker, compatClasses); + generateCompactList(relative, marker, compatClasses, false); } else if (atom->string() == "obsoleteclasses") { - generateCompactList(relative, marker, obsoleteClasses); + generateCompactList(relative, marker, obsoleteClasses, false); } else if (atom->string() == "functionindex") { generateFunctionIndex(relative, marker); @@ -634,10 +659,10 @@ generateLegaleseList(relative, marker); } else if (atom->string() == "mainclasses") { - generateCompactList(relative, marker, mainClasses); + generateCompactList(relative, marker, mainClasses, true); } else if (atom->string() == "services") { - generateCompactList(relative, marker, serviceClasses); + generateCompactList(relative, marker, serviceClasses, false); } else if (atom->string() == "overviews") { generateOverviewList(relative, marker); @@ -676,16 +701,23 @@ nsmap = newSinceMaps.find(atom->string()); NewClassMaps::const_iterator ncmap; ncmap = newClassMaps.find(atom->string()); + NewClassMaps::const_iterator nqcmap; + nqcmap = newQmlClassMaps.find(atom->string()); if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) { QList
sections; QList
::ConstIterator s; for (int i=0; itype()) { + case Node::Fake: + if (node->subType() == Node::QmlClass) { + sections[QmlClass].appendMember((Node*)node); + } + break; case Node::Namespace: sections[Namespace].appendMember((Node*)node); break; @@ -768,9 +800,11 @@ out() << "\n"; - out() << "

" << protect((*s).name) << "

\n"; + out() << "

" << protectEnc((*s).name) << "

\n"; if (idx == Class) - generateCompactList(0, marker, ncmap.value(), QString("Q")); + generateCompactList(0, marker, ncmap.value(), false, QString("Q")); + else if (idx == QmlClass) + generateCompactList(0, marker, nqcmap.value(), false, QString("Q")); else if (idx == MemberFunction) { ParentMaps parentmaps; ParentMaps::iterator pmap; @@ -792,11 +826,11 @@ << linkForNode(pmap.key(), 0) << "\">"; QStringList pieces = fullName(pmap.key(), 0, marker).split("::"); - out() << protect(pieces.last()); + out() << protectEnc(pieces.last()); out() << "" << ":

\n"; generateSection(nlist, 0, marker, CodeMarker::Summary); - out() << "
"; + out() << "
"; ++pmap; } } @@ -817,15 +851,15 @@ if (atom->next() != 0) text = atom->next()->string(); if (atom->type() == Atom::Image) - out() << "

"; + out() << "

"; if (fileName.isEmpty()) { out() << "[Missing image " - << protect(atom->string()) << "]"; + << protectEnc(atom->string()) << "]"; } else { - out() << "\"""; helpProjectWriter->addExtraFile(fileName); } @@ -836,13 +870,13 @@ case Atom::ImageText: break; case Atom::LegaleseLeft: - out() << "

"; + out() << "
"; break; case Atom::LegaleseRight: out() << "
"; break; case Atom::LineBreak: - out() << "
"; + out() << "
"; break; case Atom::Link: { @@ -878,24 +912,27 @@ else if (atom->string() == ATOM_LIST_VALUE) { threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom); if (threeColumnEnumValueTable) { - out() << "

\n" - << "" - << "" - << "\n"; + out() << "
ConstantValueDescription
"; + // << "" + if (++numTableRows % 2 == 1) + out() << ""; + else + out() << ""; + + out() << "" + << "" + << "\n"; } else { - out() << "

ConstantValueDescription
\n" - << "\n"; + out() << "
ConstantValue
" + << "\n"; } } else { out() << "
    string() == ATOM_LIST_LOWERALPHA) { out() << "\"a\""; } @@ -922,10 +959,10 @@ else { // (atom->string() == ATOM_LIST_VALUE) // ### Trenton - out() << "
ConstantValue
" - << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(), + out() << "
" + << protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(), relative))) - << ""; + << ""; QString itemValue; if (relative->type() == Node::Enum) { @@ -936,7 +973,7 @@ if (itemValue.isEmpty()) out() << "?"; else - out() << "" << protect(itemValue) << ""; + out() << "" << protectEnc(itemValue) << ""; skipAhead = 1; } @@ -951,7 +988,7 @@ } else if (atom->string() == ATOM_LIST_VALUE) { if (threeColumnEnumValueTable) { - out() << ""; + out() << ""; if (matchAhead(atom, Atom::ListItemRight)) out() << " "; } @@ -981,7 +1018,7 @@ out() << "\n"; } else if (atom->string() == ATOM_LIST_VALUE) { - out() << "

\n"; + out() << "\n"; } else { out() << "\n"; @@ -1052,7 +1089,7 @@ generateLink(atom, relative, marker); } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } break; case Atom::TableLeft: @@ -1062,32 +1099,28 @@ } if (!atom->string().isEmpty()) { if (atom->string().contains("%")) - out() << "

string() << "\" " - << "align=\"center\" cellpadding=\"2\" " - << "cellspacing=\"1\" border=\"0\">\n"; + out() << "
\n "; // width=\"" << atom->string() << "\">\n "; else { - out() << "

\n"; + out() << "
\n"; } } else { - out() << "

\n"; + out() << "
\n"; } numTableRows = 0; break; case Atom::TableRight: - out() << "

\n"; + out() << "\n"; break; case Atom::TableHeaderLeft: - out() << ""; + out() << ""; inTableHeader = true; break; case Atom::TableHeaderRight: out() << ""; if (matchAhead(atom, Atom::TableHeaderLeft)) { skipAhead = 1; - out() << "\n"; + out() << "\n"; } else { out() << "\n"; @@ -1096,9 +1129,9 @@ break; case Atom::TableRowLeft: if (++numTableRows % 2 == 1) - out() << ""; + out() << ""; else - out() << ""; + out() << ""; break; case Atom::TableRowRight: out() << "\n"; @@ -1116,7 +1149,10 @@ out() << " colspan=\"" << spans.at(0) << "\""; if (spans.at(1) != "1") out() << " rowspan=\"" << spans.at(1) << "\""; + if (inTableHeader) out() << ">"; + else + out() << ">

"; } if (matchAhead(atom, Atom::ParaLeft)) skipAhead = 1; @@ -1126,7 +1162,7 @@ if (inTableHeader) out() << ""; else - out() << ""; + out() << "

"; if (matchAhead(atom, Atom::ParaLeft)) skipAhead = 1; break; @@ -1163,11 +1199,11 @@ out() << "string()) << "\">"; break; case Atom::UnhandledFormat: - out() << "<Missing HTML>"; + out() << "<Missing HTML>"; break; case Atom::UnknownCommand: - out() << "\\" << protect(atom->string()) - << ""; + out() << "\\" << protectEnc(atom->string()) + << ""; break; #ifdef QDOC_QML case Atom::QmlText: @@ -1197,7 +1233,7 @@ namespasse = static_cast(inner); rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); - title = rawTitle + " Namespace Reference"; + title = rawTitle + " Namespace"; } else if (inner->type() == Node::Class) { classe = static_cast(inner); @@ -1216,6 +1252,8 @@ subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")" << Atom(Atom::LineBreak); +#if 0 + // No longer used because the modeule name is a breadcrumb. QString fixedModule = inner->moduleName(); if (fixedModule == "Qt3SupportLight") fixedModule = "Qt3Support"; @@ -1236,8 +1274,11 @@ subtitleText << "]"; } } - - generateHeader(title, inner, marker, true); +#endif + + generateHeader(title, inner, marker); + sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); + generateTableOfContents(inner,marker,§ions); generateTitle(title, subtitleText, SmallSubTitle, inner, marker); #ifdef QDOC_QML @@ -1250,7 +1291,6 @@ generateIncludes(inner, marker); generateStatus(inner, marker); if (classe) { - generateModuleWarning(classe, marker); generateInherits(classe, marker); generateInheritedBy(classe, marker); } @@ -1282,7 +1322,9 @@ bool needOtherSection = false; - sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay); + /* + sections is built above for the call to generateTableOfContents(). + */ s = sections.begin(); while (s != sections.end()) { if (s->members.isEmpty() && s->reimpMembers.isEmpty()) { @@ -1295,7 +1337,7 @@ out() << "\n"; - out() << "

" << protect((*s).name) << "

\n"; + out() << "

" << protectEnc((*s).name) << "

\n"; generateSection(s->members, inner, marker, CodeMarker::Summary); } if (!s->reimpMembers.isEmpty()) { @@ -1304,7 +1346,7 @@ out() << "\n"; - out() << "

" << protect(name) << "

\n"; + out() << "

" << protectEnc(name) << "

\n"; generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); } @@ -1334,8 +1376,10 @@ if (!inner->doc().isEmpty()) { out() << "
\n" + << "
\n" // QTBUG-9504 << "

" << "Detailed Description" << "

\n"; generateBody(inner, marker); + out() << "
\n"; // QTBUG-9504 generateAlsoList(inner, marker); } @@ -1343,7 +1387,9 @@ s = sections.begin(); while (s != sections.end()) { out() << "
\n"; - out() << "

" << protect((*s).name) << "

\n"; + if (!(*s).divClass.isEmpty()) + out() << "
\n"; // QTBUG-9504 + out() << "

" << protectEnc((*s).name) << "

\n"; NodeList::ConstIterator m = (*s).members.begin(); while (m != (*s).members.end()) { @@ -1392,6 +1438,8 @@ } ++m; } + if (!(*s).divClass.isEmpty()) + out() << "
\n"; // QTBUG-9504 ++s; } generateFooter(inner); @@ -1428,14 +1476,27 @@ QList
sections; QList
::const_iterator s; - QString htmlTitle = fake->fullTitle(); + QString fullTitle = fake->fullTitle(); + QString htmlTitle = fullTitle; if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) { subTitleSize = SmallSubTitle; htmlTitle += " (" + fake->subTitle() + ")"; } - - generateHeader(htmlTitle, fake, marker, true); - generateTitle(fake->fullTitle(), + else if (fake->subType() == Node::QmlBasicType) { + fullTitle = "QML Basic Type: " + fullTitle; + htmlTitle = fullTitle; + } + + generateHeader(htmlTitle, fake, marker); + + /* + Generate the TOC for the new doc format. + Don't generate a TOC for the home page. + */ + if (fake->name() != QString("index.html")) + generateTableOfContents(fake,marker,0); + + generateTitle(fullTitle, Text() << fake->subTitle(), subTitleSize, fake, @@ -1447,10 +1508,12 @@ generateStatus(fake, marker); if (moduleNamespaceMap.contains(fake->name())) { + out() << "\n"; out() << "

Namespaces

\n"; generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]); } if (moduleClassMap.contains(fake->name())) { + out() << "\n"; out() << "

Classes

\n"; generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]); } @@ -1509,11 +1572,12 @@ generateQmlInherits(qml_cn, marker); generateQmlInstantiates(qml_cn, marker); generateBrief(qml_cn, marker); + generateQmlInheritedBy(qml_cn, marker); sections = marker->qmlSections(qml_cn,CodeMarker::Summary); s = sections.begin(); while (s != sections.end()) { out() << "\n"; - out() << "

" << protect((*s).name) << "

\n"; + out() << "

" << protectEnc((*s).name) << "

\n"; generateQmlSummary(*s,fake,marker); ++s; } @@ -1529,11 +1593,11 @@ sections = marker->qmlSections(qml_cn,CodeMarker::Detailed); s = sections.begin(); while (s != sections.end()) { - out() << "

" << protect((*s).name) << "

\n"; + out() << "

" << protectEnc((*s).name) << "

\n"; NodeList::ConstIterator m = (*s).members.begin(); while (m != (*s).members.end()) { generateDetailedQmlMember(*m, fake, marker); - out() << "
\n"; + out() << "
\n"; fakeSection.keywords += qMakePair((*m)->name(), linkForNode(*m,0)); ++m; @@ -1549,7 +1613,7 @@ s = sections.begin(); while (s != sections.end()) { out() << "\n"; - out() << "

" << protect((*s).name) << "

\n"; + out() << "

" << protectEnc((*s).name) << "

\n"; generateSectionList(*s, fake, marker, CodeMarker::Summary); ++s; } @@ -1557,10 +1621,14 @@ Text brief = fake->doc().briefText(); if (fake->subType() == Node::Module && !brief.isEmpty()) { out() << "\n"; + out() << "
\n"; // QTBUG-9504 out() << "

" << "Detailed Description" << "

\n"; } + else + out() << "
\n"; // QTBUG-9504 generateBody(fake, marker); + out() << "
\n"; // QTBUG-9504 generateAlsoList(fake, marker); if (!fake->groupMembers().isEmpty()) { @@ -1578,7 +1646,7 @@ s = sections.begin(); while (s != sections.end()) { out() << "
\n"; - out() << "

" << protect((*s).name) << "

\n"; + out() << "

" << protectEnc((*s).name) << "

\n"; NodeList::ConstIterator m = (*s).members.begin(); while (m != (*s).members.end()) { @@ -1614,155 +1682,163 @@ } } -QString HtmlGenerator::fileExtension(const Node * /* node */) +QString HtmlGenerator::fileExtension(const Node * /* node */) const { return "html"; } +/*! + Output breadcrumb list in the html file. + */ +void HtmlGenerator::generateBreadCrumbs(const QString& title, + const Node *node, + CodeMarker *marker) +{ + Text breadcrumb; + if (node->type() == Node::Class) { + const ClassNode* cn = static_cast(node); + QString name = node->moduleName(); + out() << "
  • All Modules
  • "; + if (!name.isEmpty()) { + out() << "
  • "; + breadcrumb << Atom(Atom::AutoLink,name); + generateText(breadcrumb, node, marker); + out() << "
  • \n"; + } + breadcrumb.clear(); + if (!cn->name().isEmpty()) { + out() << "
  • "; + breadcrumb << Atom(Atom::AutoLink,cn->name()); + generateText(breadcrumb, 0, marker); + out() << "
  • \n"; + } + } + else if (node->type() == Node::Fake) { + const FakeNode* fn = static_cast(node); + if (node->subType() == Node::Module) { + out() << "
  • All Modules
  • "; + QString name = node->name(); + if (!name.isEmpty()) { + out() << "
  • "; + breadcrumb << Atom(Atom::AutoLink,name); + generateText(breadcrumb, 0, marker); + out() << "
  • \n"; + } + } + else if (node->subType() == Node::Group) { + if (fn->name() == QString("modules")) + out() << "
  • All Modules
  • "; + else { + out() << "
  • name() << "\">" << title + << "
  • "; + } + } + else if (node->subType() == Node::Page) { + if (fn->name() == QString("examples.html")) { + out() << "
  • All Examples
  • "; + } + else if (fn->name().startsWith("examples-")) { + out() << "
  • All Examples
  • "; + out() << "
  • name() << "\">" << title + << "
  • "; + } + else if (fn->name() == QString("namespaces.html")) { + out() << "
  • All Namespaces
  • "; + } + else { + out() << "
  • name() << "\">" << title + << "
  • "; + } + } + else if (node->subType() == Node::QmlClass) { + out() << "
  • QML Elements
  • "; + out() << "
  • name() << "\">" << title + << "
  • "; + } + else if (node->subType() == Node::Example) { + out() << "
  • All Examples
  • "; + QStringList sl = fn->name().split('/'); + QString name = "examples-" + sl.at(0) + ".html"; + QString t = CodeParser::titleFromName(name); + out() << "
  • " + << t << "
  • "; + out() << "
  • " + << title << "
  • "; + } + } + else if (node->type() == Node::Namespace) { + const NamespaceNode* nsn = static_cast(node); + out() << "
  • All Namespaces
  • "; + out() << "
  • " << title + << "
  • "; + } +} + void HtmlGenerator::generateHeader(const QString& title, const Node *node, - CodeMarker *marker, - bool mainPage) + CodeMarker *marker) { - out() << "\n"; - - out() << "\n" - "\n"; - + out() << QString("\n").arg(outputEncoding); + out() << "\n"; + out() << "\n"; + out() << "\n"; + out() << " \n"; QString shortVersion; - if ((project != "Qtopia") && (project != "Qt Extended")) { - shortVersion = project + " " + shortVersion + ": "; - if (node && !node->doc().location().isEmpty()) - out() << "\n"; - - shortVersion = myTree->version(); - if (shortVersion.count(QChar('.')) == 2) - shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); - if (!shortVersion.isEmpty()) { - if (project == "QSA") - shortVersion = "QSA " + shortVersion + ": "; - else - shortVersion = "Qt " + shortVersion + ": "; - } - } - - out() << "\n" - " " << shortVersion << protect(title) << "\n"; - if (!style.isEmpty()) - out() << " \n"; - - const QMap &metaMap = node->doc().metaTagMap(); - if (!metaMap.isEmpty()) { - QMapIterator i(metaMap); - while (i.hasNext()) { - i.next(); - out() << " \n"; - } + shortVersion = project + " " + shortVersion + ": "; + if (node && !node->doc().location().isEmpty()) + out() << "\n"; + + shortVersion = myTree->version(); + if (shortVersion.count(QChar('.')) == 2) + shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); + if (!shortVersion.isEmpty()) { + if (project == "QSA") + shortVersion = "QSA " + shortVersion + ": "; + else + shortVersion = "Qt " + shortVersion + ": "; } - navigationLinks.clear(); - - if (node && !node->links().empty()) { - QPair linkPair; - QPair anchorPair; - const Node *linkNode; - - if (node->links().contains(Node::PreviousLink)) { - linkPair = node->links()[Node::PreviousLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - - out() << " \n"; - - navigationLinks += "[Previous: "; - if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protect(anchorPair.second); - else - navigationLinks += protect(linkPair.second); - navigationLinks += "]\n"; - } - if (node->links().contains(Node::ContentsLink)) { - linkPair = node->links()[Node::ContentsLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - - out() << " \n"; - - navigationLinks += "["; - if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protect(anchorPair.second); - else - navigationLinks += protect(linkPair.second); - navigationLinks += "]\n"; - } - if (node->links().contains(Node::NextLink)) { - linkPair = node->links()[Node::NextLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - - out() << " \n"; - - navigationLinks += "[Next: "; - if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protect(anchorPair.second); - else - navigationLinks += protect(linkPair.second); - navigationLinks += "]\n"; - } - if (node->links().contains(Node::IndexLink)) { - linkPair = node->links()[Node::IndexLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - out() << " \n"; - } - if (node->links().contains(Node::StartLink)) { - linkPair = node->links()[Node::StartLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - out() << " \n"; - } - } - - foreach (const QString &stylesheet, stylesheets) { - out() << " \n"; - } - - foreach (const QString &customHeadElement, customHeadElements) { - out() << " " << customHeadElement << "\n"; - } - - out() << "\n" - "\n"; + out() << " " << shortVersion << protectEnc(title) << "\n"; + + out() << " "; + out() << ""; + out() << ""; + out() << ""; + + + //out() << " Qt Reference Documentation"; + out() << " \n"; + out() << " \n"; + out() << " \n"; + out() << "\n"; + + if (offlineDocs) + out() << "\n"; + else + out() << "\n"; + +#ifdef GENERATE_MAC_REFS if (mainPage) generateMacRef(node, marker); +#endif out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version()); - - + generateBreadCrumbs(title,node,marker); + out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version()); + +#if 0 // Removed for new docf format. MWS if (node && !node->links().empty()) out() << "

    \n" << navigationLinks << "

    \n"; +#endif } void HtmlGenerator::generateTitle(const QString& title, @@ -1771,17 +1847,17 @@ const Node *relative, CodeMarker *marker) { - out() << "

    " << protect(title); + if (!title.isEmpty()) + out() << "

    " << protectEnc(title) << "

    \n"; if (!subTitle.isEmpty()) { - out() << "
    "; - if (subTitleSize == SmallSubTitle) - out() << ""; + out() << ""; else - out() << ""; + out() << " class=\"subtitle\">"; generateText(subTitle, relative, marker); out() << "\n"; } - out() << "\n"; } void HtmlGenerator::generateFooter(const Node *node) @@ -1790,9 +1866,10 @@ out() << "

    \n" << navigationLinks << "

    \n"; out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version()) - << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()) - << "\n" - "\n"; + << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()); + out() << " \n"; + out() << "\n"; + out() << "\n"; } void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker, @@ -1813,7 +1890,7 @@ void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker) { if (!inner->includes().isEmpty()) { - out() << "
    "
    +        out() << "
    "
                   << trimmedTrailing(highlightedCode(indent(codeIndent,
                                                             marker->markedUpIncludes(inner->includes())),
                                                      marker,inner))
    @@ -1821,6 +1898,9 @@
         }
     }
     
    +/*!
    +  Generates a table of contents begining at \a node.
    + */
     void HtmlGenerator::generateTableOfContents(const Node *node,
                                                 CodeMarker *marker,
                                                 Doc::SectioningUnit sectioningUnit,
    @@ -1828,6 +1908,7 @@
                                                 const Node *relative)
     
     {
    +    return;
         if (!node->doc().hasTableOfContents())
             return;
         QList toc = node->doc().tableOfContents();
    @@ -1843,8 +1924,8 @@
     
         QString tdTag;
         if (numColumns > 1) {
    -        tdTag = "";
    -        out() << "

    \n" + tdTag = "
    "; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/ + out() << "\n" << tdTag << "\n"; } @@ -1896,8 +1977,123 @@ } if (numColumns > 1) - out() << "

    \n"; - + out() << "
    \n"; + + inContents = false; + inLink = false; +} + +/*! + Revised for the new doc format. + Generates a table of contents begining at \a node. + */ +void HtmlGenerator::generateTableOfContents(const Node *node, + CodeMarker *marker, + QList

    * sections) +{ + QList toc; + if (node->doc().hasTableOfContents()) + toc = node->doc().tableOfContents(); + if (toc.isEmpty() && !sections && (node->subType() != Node::Module)) + return; + + QStringList sectionNumber; + int detailsBase = 0; + + // disable nested links in table of contents + inContents = true; + inLink = true; + + out() << "
    \n"; + out() << "

    Contents

    \n"; + sectionNumber.append("1"); + out() << "
      \n"; + + if (node->subType() == Node::Module) { + if (moduleNamespaceMap.contains(node->name())) { + out() << "
    • Namespaces
    • \n"; + } + if (moduleClassMap.contains(node->name())) { + out() << "
    • Classes
    • \n"; + } + out() << "
    • Detailed Description
    • \n"; + for (int i = 0; i < toc.size(); ++i) { + if (toc.at(i)->string().toInt() == 1) { + detailsBase = 1; + break; + } + } + } + else if (sections && (node->type() == Node::Class)) { + QList
      ::ConstIterator s = sections->begin(); + while (s != sections->end()) { + if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) { + out() << "
    • " << (*s).name + << "
    • \n"; + } + ++s; + } + out() << "
    • Detailed Description
    • \n"; + for (int i = 0; i < toc.size(); ++i) { + if (toc.at(i)->string().toInt() == 1) { + detailsBase = 1; + break; + } + } + } + + for (int i = 0; i < toc.size(); ++i) { + Atom *atom = toc.at(i); + int nextLevel = atom->string().toInt() + detailsBase; + if (sectionNumber.size() < nextLevel) { + do { + sectionNumber.append("1"); + } while (sectionNumber.size() < nextLevel); + } + else { + while (sectionNumber.size() > nextLevel) { + sectionNumber.removeLast(); + } + sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); + } + int numAtoms; + Text headingText = Text::sectionHeading(atom); + QString s = headingText.toString(); + out() << "
    • "; + out() << ""; + generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); + out() << "
    • \n"; + } + while (!sectionNumber.isEmpty()) { + sectionNumber.removeLast(); + } + out() << "
    \n"; + out() << "
    \n"; inContents = false; inLink = false; } @@ -1909,7 +2105,7 @@ { if (bar.prev.begin() != 0 || bar.current.begin() != 0 || bar.next.begin() != 0) { - out() << "

    "; + out() << "

    "; if (bar.prev.begin() != 0) { #if 0 out() << "[location(), fileName); QString title = "List of All Members for " + inner->name(); - generateHeader(title, inner, marker, false); + generateHeader(title, inner, marker); generateTitle(title, Text(), SmallSubTitle, inner, marker); out() << "

    This is the complete list of members for "; generateFullName(inner, 0, marker); @@ -1992,7 +2188,7 @@ } beginSubPage(inner->location(), fileName); - generateHeader(title, inner, marker, false); + generateHeader(title, inner, marker); generateTitle(title, Text(), SmallSubTitle, inner, marker); if (status == CodeMarker::Compat) { @@ -2009,18 +2205,18 @@ out() << "

    \n"; for (i = 0; i < sections.size(); ++i) { - out() << "

    " << protect(sections.at(i).name) << "

    \n"; + out() << "

    " << protectEnc(sections.at(i).name) << "

    \n"; generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary); } sections = marker->sections(inner, CodeMarker::Detailed, status); for (i = 0; i < sections.size(); ++i) { out() << "
    \n"; - out() << "

    " << protect(sections.at(i).name) << "

    \n"; + out() << "

    " << protectEnc(sections.at(i).name) << "

    \n"; NodeList::ConstIterator m = sections.at(i).members.begin(); while (m != sections.at(i).members.end()) { @@ -2085,8 +2281,7 @@ CodeMarker *marker, const NodeMap &nodeMap) { - out() << "

    \n"; + out() << "
    \n"; int row = 0; foreach (const QString &name, nodeMap.keys()) { @@ -2096,29 +2291,29 @@ continue; if (++row % 2 == 1) - out() << ""; + out() << ""; else - out() << ""; - out() << ""; + out() << ""; if (!(node->type() == Node::Fake)) { Text brief = node->doc().trimmedBriefText(name); if (!brief.isEmpty()) { - out() << ""; + out() << "

    "; } } else { - out() << ""; + out() << ""; } out() << "\n"; } - out() << "
    "; + out() << "

    "; generateFullName(node, relative, marker); - out() << ""; + out() << "

    "; + out() << "

    "; generateText(brief, node, marker); - out() << "

    "; - out() << protect(node->doc().briefText().toString()); - out() << "

    "; + out() << protectEnc(node->doc().briefText().toString()); + out() << "

    \n"; + out() << "\n"; } /*! @@ -2133,10 +2328,11 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker, const NodeMap &classMap, + bool includeAlphabet, QString commonPrefix) { const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' - const int NumColumns = 4; // number of columns in the result + const int NumColumns = 3; // number of columns in the result if (classMap.isEmpty()) return; @@ -2205,6 +2401,7 @@ */ NodeMap paragraph[NumParagraphs+1]; QString paragraphName[NumParagraphs+1]; + QSet usedParagraphNames; NodeMap::ConstIterator c = classMap.begin(); while (c != classMap.end()) { @@ -2228,6 +2425,7 @@ } paragraphName[paragraphNo] = key[0].toUpper(); + usedParagraphNames.insert(key[0].toLower().cell()); paragraph[paragraphNo].insert(key, c.value()); ++c; } @@ -2247,15 +2445,15 @@ for (j = 0; j < NumParagraphs; j++) // j = 0..36 paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count(); - int firstOffset[NumColumns + 1]; // 4 + 1 - int currentOffset[NumColumns]; // 4 - int currentParagraphNo[NumColumns]; // 4 - int currentOffsetInParagraph[NumColumns]; // 4 + int firstOffset[NumColumns + 1]; + int currentOffset[NumColumns]; + int currentParagraphNo[NumColumns]; + int currentOffsetInParagraph[NumColumns]; int numRows = (classMap.count() + NumColumns - 1) / NumColumns; int curParagNo = 0; - for (i = 0; i < NumColumns; i++) { // i = 0..3 + for (i = 0; i < NumColumns; i++) { firstOffset[i] = qMin(i * numRows, classMap.size()); currentOffset[i] = firstOffset[i]; @@ -2271,13 +2469,29 @@ } firstOffset[NumColumns] = classMap.count(); - out() << "

    \n"; + if (includeAlphabet) { + out() << "

    "; + for (int i = 0; i < 26; i++) { + QChar ch('a' + i); + if (usedParagraphNames.contains(char('a' + i))) + out() << QString("%2 ").arg(ch).arg(ch.toUpper()); + } + out() << "

    \n"; + } + + out() << "
    \n"; for (k = 0; k < numRows; k++) { - out() << "\n"; + if (++numTableRows % 2 == 1) + out() << ""; + else + out() << ""; + //break; + +// out() << "\n"; for (i = 0; i < NumColumns; i++) { if (currentOffset[i] >= firstOffset[i + 1]) { // this column is finished - out() << "\n"; + out() << "\n"; // check why? } else { while ((currentParagraphNo[i] < NumParagraphs) && @@ -2292,16 +2506,20 @@ currentParagraphNo[i] = NumParagraphs - 1; } #endif - out() << "\n"; + out() << "

    \n"; currentOffset[i]++; currentOffsetInParagraph[i]++; @@ -2331,18 +2553,18 @@ } out() << "\n"; } - out() << "
    \n\n"; + out() << "

    "; if (currentOffsetInParagraph[i] == 0) { // start a new paragraph + if (includeAlphabet) { + QChar c = paragraphName[currentParagraphNo[i]][0].toLower(); + out() << QString("").arg(c); + } out() << "" << paragraphName[currentParagraphNo[i]] - << " "; + << ""; } - out() << "\n"; - - out() << "

    "; + out() << "

    \n"; + + out() << "

    "; if ((currentParagraphNo[i] < NumParagraphs) && !paragraphName[currentParagraphNo[i]].isEmpty()) { NodeMap::Iterator it; @@ -2314,8 +2532,12 @@ out() << ""; - QStringList pieces = fullName(it.value(), relative, marker).split("::"); - out() << protect(pieces.last()); + QStringList pieces; + if (it.value()->subType() == Node::QmlClass) + pieces << it.value()->name(); + else + pieces = fullName(it.value(), relative, marker).split("::"); + out() << protectEnc(pieces.last()); out() << ""; if (pieces.size() > 1) { out() << " ("; @@ -2323,7 +2545,7 @@ out() << ")"; } } - out() << "

    \n"; + out() << "\n"; } void HtmlGenerator::generateFunctionIndex(const Node *relative, CodeMarker *marker) { - out() << "

    "; + out() << "

    "; for (int i = 0; i < 26; i++) { QChar ch('a' + i); out() << QString("%2 ").arg(ch).arg(ch.toUpper()); } - out() << "

    \n"; + out() << "

    \n"; char nextLetter = 'a'; char currentLetter; @@ -2357,7 +2579,7 @@ #else out() << "

    "; #endif - out() << protect(f.key()) << ":"; + out() << protectEnc(f.key()) << ":"; currentLetter = f.key()[0].unicode(); while (islower(currentLetter) && currentLetter >= nextLetter) { @@ -2411,7 +2633,7 @@ QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2450,7 +2672,7 @@ QString marked = marker->markedUpQmlItem(node,summary); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2463,7 +2685,7 @@ if (summary) marked.replace("@name>", "b>"); - marked.replace("<@extra>", "  "); + marked.replace("<@extra>", ""); marked.replace("", ""); if (summary) { @@ -2556,7 +2778,7 @@ const FakeNode *groupNode = groupTitlesMap[groupTitle]; out() << QString("

    %2

    \n").arg( linkForNode(groupNode, relative)).arg( - protect(groupNode->fullTitle())); + protectEnc(groupNode->fullTitle())); if (fakeNodeMap[groupNode].count() == 0) continue; @@ -2568,7 +2790,7 @@ if (title.startsWith("The ")) title.remove(0, 4); out() << "
  • " - << protect(title) << "
  • \n"; + << protectEnc(title) << "\n"; } out() << "\n"; } @@ -2582,7 +2804,7 @@ if (title.startsWith("The ")) title.remove(0, 4); out() << "
  • " - << protect(title) << "
  • \n"; + << protectEnc(title) << "\n"; } out() << "\n"; } @@ -2606,15 +2828,12 @@ name_alignment = false; } if (name_alignment) { - out() << "\n"; + out() << "
    \n"; } else { if (twoColumn) - out() << "

    \n" - << "\n
    "; + out() << "\n" + << "\n"; else - out() << "\n"; + out() << "\n"; i++; ++m; } @@ -2649,7 +2867,7 @@ else { out() << "\n"; if (twoColumn) - out() << "\n
    "; out() << "
      \n"; } @@ -2627,20 +2846,19 @@ } if (name_alignment) { - out() << "
    "; + out() << "
    "; } else { if (twoColumn && i == (int) (nl.count() + 1) / 2) - out() << "
      \n"; - out() << "
    • "; + out() << "
      \n"; + out() << "
    • "; } generateSynopsis(*m, relative, marker, style, name_alignment); if (name_alignment) out() << "

    \n"; + out() << "
    \n"; } } } @@ -2671,15 +2889,12 @@ name_alignment = false; } if (name_alignment) { - out() << "\n"; + out() << "
    \n"; } else { if (twoColumn) - out() << "

    \n" - << "\n
    "; + out() << "\n" + << "\n"; else - out() << "\n"; + out() << "\n"; i++; ++m; } @@ -2714,7 +2928,7 @@ else { out() << "\n"; if (twoColumn) - out() << "\n
    "; out() << "
      \n"; } @@ -2692,20 +2907,19 @@ } if (name_alignment) { - out() << "
    "; + out() << "
    "; } else { if (twoColumn && i == (int) (section.members.count() + 1) / 2) - out() << "
      \n"; - out() << "
    • "; + out() << "
      \n"; + out() << "
    • "; } generateSynopsis(*m, relative, marker, style, name_alignment); if (name_alignment) out() << "

    \n"; + out() << "
    \n"; } } @@ -2733,9 +2947,9 @@ QList >::ConstIterator p = section.inherited.begin(); while (p != section.inherited.end()) { if (nameAlignment) - out() << "
  • "; + out() << "
  • "; else - out() << "
  • "; + out() << "
  • "; out() << (*p).second << " "; if ((*p).second == 1) { out() << section.singularMember; @@ -2745,7 +2959,7 @@ } out() << " inherited from " - << protect(marker->plainFullName((*p).first, relative)) + << protectEnc(marker->plainFullName((*p).first, relative)) << "
  • \n"; ++p; } @@ -2760,7 +2974,7 @@ QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2780,7 +2994,7 @@ extraRegExp.setMinimal(true); marked.replace(extraRegExp, ""); } else { - marked.replace("<@extra>", "  "); + marked.replace("<@extra>", ""); marked.replace("", ""); } @@ -2811,7 +3025,7 @@ for (int i = 0, n = src.size(); i < n;) { if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') { if (nameAlignment && !done) {// && (i != 0)) Why was this here? - html += ""; + html += ""; done = true; } i += 2; @@ -2976,9 +3190,13 @@ twoColumn = (section.members.count() >= 5); } if (twoColumn) - out() << "

    \n" - << "\n
    "; + out() << "\n"; + if (++numTableRows % 2 == 1) + out() << ""; + else + out() << ""; + +// << "\n
    "; out() << "
      \n"; int i = 0; @@ -2990,9 +3208,9 @@ } if (twoColumn && i == (int) (section.members.count() + 1) / 2) - out() << "
      \n"; - - out() << "
    • "; + out() << "
      \n"; + + out() << "
    • "; if (style == CodeMarker::Accessors) out() << ""; generateSynopsis(*m, relative, marker, style); @@ -3004,7 +3222,7 @@ } out() << "
    \n"; if (twoColumn) - out() << "

    \n"; + out() << "
    \n"; } if (style == CodeMarker::Summary && !section.inherited.isEmpty()) { @@ -3020,7 +3238,7 @@ { QList >::ConstIterator p = section.inherited.begin(); while (p != section.inherited.end()) { - out() << "

  • "; + out() << "
  • "; out() << (*p).second << " "; if ((*p).second == 1) { out() << section.singularMember; @@ -3029,7 +3247,7 @@ } out() << " inherited from " - << protect(marker->plainFullName((*p).first, relative)) + << protectEnc(marker->plainFullName((*p).first, relative)) << "
  • \n"; ++p; } @@ -3043,7 +3261,7 @@ QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -3060,7 +3278,7 @@ extraRegExp.setMinimal(true); marked.replace(extraRegExp, ""); } else { - marked.replace("<@extra>", "  "); + marked.replace("<@extra>", ""); marked.replace("", ""); } @@ -3241,7 +3459,7 @@ if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) { // hack for C++: move () outside of link int k = funcLeftParen.pos(1); - out() << protect(atom->string().left(k)); + out() << protectEnc(atom->string().left(k)); if (link.isEmpty()) { if (showBrokenLinks) out() << ""; @@ -3249,7 +3467,7 @@ out() << ""; } inLink = false; - out() << protect(atom->string().mid(k)); + out() << protectEnc(atom->string().mid(k)); } else if (marker->recognizeLanguage("Java")) { // hack for Java: remove () and use when appropriate bool func = atom->string().endsWith("()"); @@ -3257,13 +3475,13 @@ if (tt) out() << ""; if (func) { - out() << protect(atom->string().left(atom->string().length() - 2)); + out() << protectEnc(atom->string().left(atom->string().length() - 2)); } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } out() << ""; } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } } @@ -3337,7 +3555,12 @@ return clean; } -QString HtmlGenerator::protect(const QString& string) +QString HtmlGenerator::protectEnc(const QString &string) +{ + return protect(string, outputEncoding); +} + +QString HtmlGenerator::protect(const QString &string, const QString &outputEncoding) { #define APPEND(x) \ if (html.isEmpty()) { \ @@ -3360,7 +3583,7 @@ APPEND(">"); } else if (ch == QLatin1Char('"')) { APPEND("""); - } else if (ch.unicode() > 0x007F + } else if ((outputEncoding == "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 @@ -3490,7 +3713,7 @@ ref = node->name() + "-var"; break; case Node::Target: - return protect(node->name()); + return protectEnc(node->name()); } return registerRef(ref); } @@ -3564,7 +3787,7 @@ } } out() << "\">"; - out() << protect(fullName(apparentNode, relative, marker)); + out() << protectEnc(fullName(apparentNode, relative, marker)); out() << ""; } @@ -3574,14 +3797,18 @@ { const EnumNode *enume; +#ifdef GENERATE_MAC_REFS generateMacRef(node, marker); +#endif if (node->type() == Node::Enum && (enume = static_cast(node))->flagsType()) { +#ifdef GENERATE_MAC_REFS generateMacRef(enume->flagsType(), marker); +#endif out() << "

    "; out() << ""; generateSynopsis(enume, relative, marker, CodeMarker::Detailed); - out() << "
    "; + out() << "
    "; generateSynopsis(enume->flagsType(), relative, marker, @@ -3625,12 +3852,12 @@ else if (node->type() == Node::Enum) { const EnumNode *enume = static_cast(node); if (enume->flagsType()) { - out() << "

    The " << protect(enume->flagsType()->name()) + out() << "

    The " << protectEnc(enume->flagsType()->name()) << " type is a typedef for " << "QFlags<" - << protect(enume->name()) + << protectEnc(enume->name()) << ">. It stores an OR combination of " - << protect(enume->name()) + << protectEnc(enume->name()) << " values.

    \n"; } } @@ -3700,6 +3927,9 @@ NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion); if (ncmap == newClassMaps.end()) ncmap = newClassMaps.insert(sinceVersion,NodeMap()); + NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion); + if (nqcmap == newQmlClassMaps.end()) + nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap()); if ((*child)->type() == Node::Function) { FunctionNode *func = static_cast(*child); @@ -3719,6 +3949,15 @@ nsmap.value().insert(className,(*child)); ncmap.value().insert(className,(*child)); } + else if ((*child)->subType() == Node::QmlClass) { + QString className = (*child)->name(); + if ((*child)->parent() && + (*child)->parent()->type() == Node::Namespace && + !(*child)->parent()->name().isEmpty()) + className = (*child)->parent()->name()+"::"+className; + nsmap.value().insert(className,(*child)); + nqcmap.value().insert(className,(*child)); + } } else { QString name = (*child)->name(); @@ -3939,10 +4178,12 @@ } else { *node = marker->resolveTarget(first, myTree, relative); - if (!*node) + if (!*node) { *node = myTree->findFakeNodeByTitle(first); - if (!*node) + } + if (!*node) { *node = myTree->findUnambiguousTarget(first, targetAtom); + } } if (*node) { @@ -4077,6 +4318,10 @@ } } +#ifdef GENERATE_MAC_REFS +/* + No longer valid. + */ void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker) { if (!pleaseGenerateMacRef || marker == 0) @@ -4086,6 +4331,7 @@ foreach (const QString &macRef, macRefs) out() << "\n"; } +#endif void HtmlGenerator::beginLink(const QString &link, const Node *node, @@ -4137,12 +4383,10 @@ inObsoleteLink = false; } -QT_END_NAMESPACE - #ifdef QDOC_QML /*! - Generates the summary for for the \a section. Only used for + Generates the summary for the \a section. Only used for sections of QML element documentation. Currently handles only the QML property group. @@ -4159,17 +4403,20 @@ twoColumn = (count >= 5); } if (twoColumn) - out() << "

    \n" - << "\n
    "; + out() << "\n"; + if (++numTableRows % 2 == 1) + out() << ""; + else + out() << ""; + // << "\n
    "; out() << "
      \n"; int row = 0; m = section.members.begin(); while (m != section.members.end()) { if (twoColumn && row == (int) (count + 1) / 2) - out() << "
      \n"; - out() << "
    • "; + out() << "
      \n"; + out() << "
    • "; generateQmlItem(*m,relative,marker,true); out() << "
    • \n"; row++; @@ -4177,7 +4424,7 @@ } out() << "
    \n"; if (twoColumn) - out() << "

    \n"; + out() << "
    \n"; } } @@ -4190,32 +4437,34 @@ CodeMarker *marker) { const QmlPropertyNode* qpn = 0; +#ifdef GENERATE_MAC_REFS generateMacRef(node, marker); +#endif out() << "

    "; if (node->subType() == Node::QmlPropertyGroup) { const QmlPropGroupNode* qpgn = static_cast(node); NodeList::ConstIterator p = qpgn->childNodes().begin(); out() << "
    "; - out() << ""; + out() << "
    "; while (p != qpgn->childNodes().end()) { if ((*p)->type() == Node::QmlProperty) { qpn = static_cast(*p); - out() << ""; + else + out() << ""; + + out() << ""; - if (qpgn->isDefault()) { - out() << "
    "; + + if (++numTableRows % 2 == 1) + out() << "

    "; + //out() << "

    "; // old out() << ""; if (!qpn->isWritable()) out() << "read-only"; + if (qpgn->isDefault()) + out() << "default"; generateQmlItem(qpn, relative, marker, false); out() << "
    " - << "
    " - << "
    " - << "
    " - << "" - << ""; - } } ++p; } @@ -4226,11 +4475,16 @@ const FunctionNode* qsn = static_cast(node); out() << "
    "; out() << "
    " - << "default
    "; - out() << ""; + if (++numTableRows % 2 == 1) + out() << ""; + else + out() << ""; + out() << ""; + out() << "

    "; out() << "
    "; + //out() << "

    "; out() << ""; generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false); //generateQmlItem(qsn,relative,marker,false); - out() << "

    "; out() << "
    "; } @@ -4238,10 +4492,15 @@ const FunctionNode* qmn = static_cast(node); out() << "
    "; out() << ""; - out() << ""; + if (++numTableRows % 2 == 1) + out() << ""; + else + out() << ""; + out() << ""; + out() << "

    "; out() << "
    "; + //out() << "

    "; out() << ""; generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false); - out() << "

    "; out() << "
    "; } @@ -4270,7 +4529,7 @@ const Node* n = myTree->findNode(strList,Node::Fake); if (n && n->subType() == Node::QmlClass) { const QmlClassNode* qcn = static_cast(n); - out() << "

    "; + out() << "

    "; Text text; text << "[Inherits "; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); @@ -4286,6 +4545,26 @@ } /*! + Output the "Inherit by" list for the QML element, + if it is inherited by any other elements. + */ +void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn, + CodeMarker* marker) +{ + if (cn) { + NodeList subs; + QmlClassNode::subclasses(cn->name(),subs); + if (!subs.isEmpty()) { + Text text; + text << Atom::ParaLeft << "Inherited by "; + appendSortedQmlNames(text,cn,subs,marker); + text << Atom::ParaRight; + generateText(text, cn, marker); + } + } +} + +/*! Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]" line for the QML element, if there should be one. @@ -4297,7 +4576,7 @@ { const ClassNode* cn = qcn->classNode(); if (cn && (cn->status() != Node::Internal)) { - out() << "

    "; + out() << "

    "; Text text; text << "["; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); @@ -4328,7 +4607,7 @@ if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) { const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake); if (n && n->subType() == Node::QmlClass) { - out() << "

    "; + out() << "

    "; Text text; text << "["; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); @@ -4347,4 +4626,264 @@ } } +/*! + Generate the element for the given \a node using the \a writer. + Return true if a element was written; otherwise return false. + */ +bool HtmlGenerator::generatePageElement(QXmlStreamWriter& writer, + const Node* node, + CodeMarker* marker) const +{ + if (node->pageType() == Node::NoPageType) + return false; + if (node->name().isEmpty()) + return true; + if (node->access() == Node::Private) + return false; + if (!node->isInnerNode()) + return false; + + QString title; + QString rawTitle; + QString fullTitle; + const InnerNode* inner = static_cast(node); + + writer.writeStartElement("page"); + QXmlStreamAttributes attributes; + QString t; + t.setNum(id++); + switch (node->type()) { + case Node::Fake: + { + const FakeNode* fake = static_cast(node); + title = fake->fullTitle(); + break; + } + case Node::Class: + { + title = node->name() + " Class Reference"; + break; + } + case Node::Namespace: + { + rawTitle = marker->plainName(inner); + fullTitle = marker->plainFullName(inner); + title = rawTitle + " Namespace Reference"; + break; + } + default: + title = node->name(); + break; + } + writer.writeAttribute("id",t); + writer.writeStartElement("pageWords"); + writer.writeCharacters(title); + if (!inner->pageKeywords().isEmpty()) { + const QStringList& w = inner->pageKeywords(); + for (int i = 0; i < w.size(); ++i) { + writer.writeCharacters(" "); + writer.writeCharacters(w.at(i).toLocal8Bit().constData()); + } + } + writer.writeEndElement(); + writer.writeStartElement("pageTitle"); + writer.writeCharacters(title); + writer.writeEndElement(); + writer.writeStartElement("pageUrl"); + writer.writeCharacters(PageGenerator::fileName(node)); + writer.writeEndElement(); + writer.writeStartElement("pageType"); + switch (node->pageType()) { + case Node::ApiPage: + writer.writeCharacters("APIPage"); + break; + case Node::ArticlePage: + writer.writeCharacters("Article"); + break; + case Node::ExamplePage: + writer.writeCharacters("Example"); + break; + default: + break; + } + writer.writeEndElement(); + writer.writeEndElement(); + return true; +} + +/*! + Traverse the tree recursively and generate the + elements. + */ +void HtmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const +{ + if (generatePageElement(writer, node, marker)) { + + if (node->isInnerNode()) { + const InnerNode *inner = static_cast(node); + + // Recurse to write an element for this child node and all its children. + foreach (const Node *child, inner->childNodes()) + generatePageElements(writer, child, marker); + } + } +} + +/*! + Outputs the file containing the index used for searching the html docs. + */ +void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const +{ + QFile file(fileName); + if (!file.open(QFile::WriteOnly | QFile::Text)) + return ; + + QXmlStreamWriter writer(&file); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement("qtPageIndex"); + + generatePageElements(writer, myTree->root(), marker); + + writer.writeEndElement(); // qtPageIndex + writer.writeEndDocument(); + file.close(); +} + #endif + +#if 0 // fossil removed for new doc format MWS 19/04/2010 + out() << "\n"; + out() << QString("\n").arg(naturalLanguage); + + QString shortVersion; + if ((project != "Qtopia") && (project != "Qt Extended")) { + shortVersion = project + " " + shortVersion + ": "; + if (node && !node->doc().location().isEmpty()) + out() << "\n"; + + shortVersion = myTree->version(); + if (shortVersion.count(QChar('.')) == 2) + shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); + if (!shortVersion.isEmpty()) { + if (project == "QSA") + shortVersion = "QSA " + shortVersion + ": "; + else + shortVersion = "Qt " + shortVersion + ": "; + } + } + + out() << "\n" + " " << shortVersion << protectEnc(title) << "\n"; + out() << QString("").arg(outputEncoding); + + if (!style.isEmpty()) + out() << " \n"; + + const QMap &metaMap = node->doc().metaTagMap(); + if (!metaMap.isEmpty()) { + QMapIterator i(metaMap); + while (i.hasNext()) { + i.next(); + out() << " \n"; + } + } + + navigationLinks.clear(); + + if (node && !node->links().empty()) { + QPair linkPair; + QPair anchorPair; + const Node *linkNode; + + if (node->links().contains(Node::PreviousLink)) { + linkPair = node->links()[Node::PreviousLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "[Previous: "; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::ContentsLink)) { + linkPair = node->links()[Node::ContentsLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "["; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::NextLink)) { + linkPair = node->links()[Node::NextLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "[Next: "; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::IndexLink)) { + linkPair = node->links()[Node::IndexLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + out() << " \n"; + } + if (node->links().contains(Node::StartLink)) { + linkPair = node->links()[Node::StartLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + out() << " \n"; + } + } + + foreach (const QString &stylesheet, stylesheets) { + out() << " \n"; + } + + foreach (const QString &customHeadElement, customHeadElements) { + out() << " " << customHeadElement << "\n"; + } + + out() << "\n" + #endif + + QT_END_NAMESPACE