summaryrefslogtreecommitdiffstats
path: root/src/tools/qdoc/htmlgenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/qdoc/htmlgenerator.cpp')
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp588
1 files changed, 391 insertions, 197 deletions
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index 7cb56974d5..f17e3adde8 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -166,9 +166,9 @@ void HtmlGenerator::initializeGenerator(const Config &config)
pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() +
Config::dot +
HTMLGENERATOR_GENERATEMACREFS);
- noBreadCrumbs = config.getBool(HtmlGenerator::format() +
+ noNavigationBar = config.getBool(HtmlGenerator::format() +
Config::dot +
- HTMLGENERATOR_NOBREADCRUMBS);
+ HTMLGENERATOR_NONAVIGATIONBAR);
project = config.getString(CONFIG_PROJECT);
@@ -229,6 +229,25 @@ void HtmlGenerator::initializeGenerator(const Config &config)
examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH);
if (!examplesPath.isEmpty())
examplesPath += QLatin1Char('/');
+
+ //retrieve the config for the navigation bar
+ homepage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_HOMEPAGE);
+
+ landingpage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_LANDINGPAGE);
+
+ cppclassespage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_CPPCLASSESPAGE);
+
+ qmltypespage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_QMLTYPESPAGE);
+
+ buildversion = config.getString(CONFIG_BUILDVERSION);
}
/*!
@@ -1095,8 +1114,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
QList<Section> sections;
QList<Section>::ConstIterator s;
- ClassNode* classe = 0;
-
QString title;
QString rawTitle;
QString fullTitle;
@@ -1106,7 +1123,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
title = rawTitle + " Namespace";
}
else if (inner->type() == Node::Class) {
- classe = static_cast<ClassNode*>(inner);
rawTitle = inner->plainName();
fullTitle = inner->plainFullName();
title = rawTitle + " Class";
@@ -1121,16 +1137,9 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
generateTableOfContents(inner,marker,&sections);
generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
generateBrief(inner, marker);
- generateIncludes(inner, marker);
+ generateRequisites(inner, marker);
generateStatus(inner, marker);
- if (classe) {
- generateInherits(classe, marker);
- generateInheritedBy(classe, marker);
- if (classe->qmlElement() != 0)
- generateInstantiatedBy(classe,marker);
- }
generateThreadSafeness(inner, marker);
- generateSince(inner, marker);
out() << "<ul>\n";
@@ -1511,10 +1520,7 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
const_cast<DocNode*>(dn)->setCurrentChild();
ClassNode* cn = qml_cn->classNode();
generateBrief(qml_cn, marker);
- generateQmlInherits(qml_cn, marker);
- generateQmlInheritedBy(qml_cn, marker);
- generateQmlInstantiates(qml_cn, marker);
- generateSince(qml_cn, marker);
+ generateQmlRequisites(qml_cn, marker);
QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker);
if (!allQmlMembersLink.isEmpty()) {
@@ -1616,129 +1622,67 @@ QString HtmlGenerator::fileExtension() const
}
/*!
- Output breadcrumb list in the html file.
+ Output navigation list in the html file.
*/
-void HtmlGenerator::generateBreadCrumbs(const QString &title,
+void HtmlGenerator::generateNavigationBar(const QString &title,
const Node *node,
CodeMarker *marker)
{
- if (noBreadCrumbs)
+ if (noNavigationBar)
return;
- Text breadcrumbs;
+ Text navigationbar;
+
+ if (homepage == title)
+ return;
+ if (!homepage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::AutoLink, homepage)
+ << Atom(Atom::ListItemRight);
+ if (!landingpage.isEmpty() && landingpage != title)
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::AutoLink, landingpage)
+ << Atom(Atom::ListItemRight);
+
if (node->type() == Node::Class) {
const ClassNode *cn = static_cast<const ClassNode *>(node);
QString name = node->moduleName();
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Modules"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Modules"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- if (!name.isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, name)
+
+ if (!cppclassespage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::Link, cppclassespage)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, QLatin1String("C++ Classes"))
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
<< Atom(Atom::ListItemRight);
+
if (!cn->name().isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
+ navigationbar << Atom(Atom::ListItemLeft)
<< Atom(Atom::String, protectEnc(cn->name()))
<< Atom(Atom::ListItemRight);
}
else if (node->type() == Node::Document) {
- const DocNode* fn = static_cast<const DocNode*>(node);
- if (node->subType() == Node::Module) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Modules"))
+ 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("Modules"))
+ << Atom(Atom::String, QLatin1String("QML Types"))
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
<< Atom(Atom::ListItemRight);
- QString name = node->name();
- if (!name.isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(name))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::Group) {
- if (fn->name() == QString("modules"))
- breadcrumbs << Atom(Atom::String, QLatin1String("Modules"));
- else
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::Page) {
- if (fn->name() == QString("qdeclarativeexamples.html")) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("QML Examples & Demos"))
- << Atom(Atom::ListItemRight);
- }
- else if (fn->name().startsWith("examples-")) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (fn->name() == QString("namespaces.html"))
- breadcrumbs << Atom(Atom::String, QLatin1String("Namespaces"));
- else
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::QmlClass) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("Basic QML Types"))
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
+
+ navigationbar << Atom(Atom::ListItemLeft)
<< Atom(Atom::String, protectEnc(title))
<< Atom(Atom::ListItemRight);
}
- else if (node->subType() == Node::Example) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- QStringList sl = fn->name().split('/');
- if (sl.contains("declarative"))
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("QML Examples & Demos"))
- << Atom(Atom::ListItemRight);
- else {
- QString name = protectEnc("examples-" + sl.at(0) + ".html"); // this generates an empty link
- QString t = CodeParser::titleFromName(name);
- }
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
+ else {
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::String, protectEnc(title))
+ << Atom(Atom::ListItemRight);
}
}
- else if (node->type() == Node::Namespace) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Namespaces"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Namespaces"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- generateText(breadcrumbs, node, marker);
+ generateText(navigationbar, node, marker);
}
void HtmlGenerator::generateHeader(const QString& title,
@@ -1782,7 +1726,8 @@ void HtmlGenerator::generateHeader(const QString& title,
#endif
out() << QString(postHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
- generateBreadCrumbs(title,node,marker);
+ generateNavigationBar(title,node,marker);
+ out() << "<li id=\"buildversion\">\n" << buildversion << "</li>\n";
out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
navigationLinks.clear();
@@ -1881,6 +1826,271 @@ void HtmlGenerator::generateFooter(const Node *node)
out() << "</html>\n";
}
+/*!
+Lists the required imports and includes in a table.
+The number of rows is known, so this path is simpler than the generateSection() path.
+*/
+void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
+{
+ QMap<QString, Text> requisites;
+ Text text;
+
+ const QString headerText = "Header";
+ const QString sinceText = "Since";
+ const QString inheritedBytext = "Inherited By";
+ const QString inheritsText = "Inherits";
+ const QString instantiatedByText = "Instantiated By";
+ const QString qtVariableText = "qmake";
+
+ //add the includes to the map
+ if (!inner->includes().isEmpty()) {
+ text.clear();
+ text << formattingRightMap()[ATOM_FORMATTING_BOLD]
+ << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
+ << highlightedCode(indent(codeIndent,
+ marker->markedUpIncludes(inner->includes())),
+ inner)
+ << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ requisites.insert(headerText, text);
+ }
+
+ //The order of the requisites matter
+ QStringList requisiteorder;
+ requisiteorder << headerText
+ << qtVariableText
+ << sinceText
+ << instantiatedByText
+ << inheritsText
+ << inheritedBytext;
+
+ //add the since and project into the map
+ if (!inner->since().isEmpty()) {
+ text.clear();
+ QStringList since = inner->since().split(QLatin1Char(' '));
+ if (since.count() == 1) {
+ // Handle legacy use of \since <version>.
+ if (project.isEmpty())
+ text << "version";
+ else
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << " " << since[0];
+ }
+ else {
+ // Reconstruct the <project> <version> string.
+ text << " " << since.join(' ');
+ }
+ text << Atom::ParaRight;
+ requisites.insert(sinceText, text);
+ }
+
+ //add the instantiated-by to the map if the class node is not internal
+ if (inner->type() == Node::Class) {
+ ClassNode* classe = static_cast<ClassNode*>(inner);
+ if (classe->qmlElement() != 0 && classe->status() != Node::Internal) {
+ text.clear();
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode(classe->qmlElement()))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, classe->qmlElement()->name())
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ requisites.insert(instantiatedByText, text);
+
+ }
+
+ //add the inherits to the map
+ QList<RelatedClass>::ConstIterator r;
+ int index;
+ if (!classe->baseClasses().isEmpty()) {
+ text.clear();
+ r = classe->baseClasses().constBegin();
+ index = 0;
+ while (r != classe->baseClasses().constEnd()) {
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, (*r).dataTypeWithTemplateArgs)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ if ((*r).access == Node::Protected) {
+ text << " (protected)";
+ }
+ else if ((*r).access == Node::Private) {
+ text << " (private)";
+ }
+ text << separator(index++, classe->baseClasses().count());
+ ++r;
+ }
+ text << Atom::ParaRight;
+ requisites.insert(inheritsText, text);
+ }
+
+ //add the inherited-by to the map
+ if (!classe->derivedClasses().isEmpty()) {
+ text.clear();
+ text << Atom::ParaLeft;
+ appendSortedNames(text, classe, classe->derivedClasses());
+ text << Atom::ParaRight;
+ requisites.insert(inheritedBytext, text);
+ }
+
+ //add the QT variable to the map
+ DocNode * moduleNode = qdb_->findModule(classe->moduleName());
+ if (moduleNode && !moduleNode->qtVariable().isEmpty()) {
+ text.clear();
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_TELETYPE)
+ << "QT += " + moduleNode->qtVariable()
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_TELETYPE);
+ requisites.insert(qtVariableText, text);
+ }
+
+ }
+
+ if (!requisites.isEmpty()) {
+ //generate the table
+ out() << "<table class=\"alignedsummary\">\n";
+
+ QStringList::ConstIterator i;
+ for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
+
+ if (requisites.contains(*i)) {
+ out() << "<tr>"
+ << "<td class=\"memItemLeft rightAlign topAlign\"> "
+ << *i << ":"
+ << "</td><td class=\"memItemRight bottomAlign\"> ";
+
+ if (*i == headerText)
+ out() << requisites.value(*i).toString();
+ else
+ generateText(requisites.value(*i), inner, marker);
+ out() << "</td></tr>";
+ }
+ }
+ out() << "</table>";
+ }
+}
+
+/*!
+Lists the required imports and includes in a table.
+The number of rows is known, so this path is simpler than the generateSection() path.
+*/
+void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker)
+{
+ if (!qcn)
+ return;
+ QMap<QString, Text> requisites;
+ Text text;
+
+ const QString importText = "Import Statement:";
+ const QString sinceText = "Since:";
+ const QString inheritedBytext = "Inherited By:";
+ const QString inheritsText = "Inherits:";
+ const QString instantiatesText = "Instantiates:";
+
+ //The order of the requisites matter
+ QStringList requisiteorder;
+ requisiteorder << importText
+ << sinceText
+ << instantiatesText
+ << inheritsText
+ << inheritedBytext;
+
+ //add the module name and version to the map
+ text.clear();
+ text << formattingRightMap()[ATOM_FORMATTING_BOLD]
+ << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
+ << "import " + qcn->qmlModuleName() + " " + qcn->qmlModuleVersion()
+ << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ requisites.insert(importText, text);
+
+ //add the since and project into the map
+ if (!qcn->since().isEmpty()) {
+ text.clear();
+ QStringList since = qcn->since().split(QLatin1Char(' '));
+ if (since.count() == 1) {
+ // Handle legacy use of \since <version>.
+ if (project.isEmpty())
+ text << "version";
+ else
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ text << " " << since[0];
+ }
+ else {
+ // Reconstruct the <project> <version> string.
+ text << " " << since.join(' ');
+ }
+ text << Atom::ParaRight;
+ requisites.insert(sinceText, text);
+ }
+
+ //add the instantiates to the map
+ ClassNode* cn = qcn->classNode();
+ if (cn && (cn->status() != Node::Internal)) {
+ text.clear();
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, cn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ requisites.insert(instantiatesText, text);
+ }
+
+ //add the inherits to the map
+ const QmlClassNode* base = qcn->qmlBaseNode();
+ while (base && base->isInternal()) {
+ base = base->qmlBaseNode();
+ }
+ if (base) {
+ text.clear();
+ text << Atom::ParaLeft
+ << Atom(Atom::LinkNode,CodeMarker::stringForNode(base))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, base->name())
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
+ << Atom::ParaRight;
+ requisites.insert(inheritsText, text);
+ }
+
+ //add the inherited-by to the map
+ NodeList subs;
+ QmlClassNode::subclasses(qcn->name(), subs);
+ if (!subs.isEmpty()) {
+ text.clear();
+ text << Atom::ParaLeft;
+ appendSortedQmlNames(text, qcn, subs);
+ text << Atom::ParaRight;
+ requisites.insert(inheritedBytext, text);
+ }
+
+ if (!requisites.isEmpty()) {
+ //generate the table
+ out() << "<table class=\"alignedsummary\">\n";
+
+ QStringList::ConstIterator i;
+ for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
+
+ if (requisites.contains(*i)) {
+ out() << "<tr>"
+ << "<td class=\"memItemLeft rightAlign topAlign\"> "
+ << *i
+ << "</td><td class=\"memItemRight bottomAlign\"> ";
+
+ if (*i == importText)
+ out()<<requisites.value(*i).toString();
+ else
+ generateText(requisites.value(*i), qcn, marker);
+ out() << "</td></tr>";
+ }
+ }
+ out() << "</table>";
+ }
+}
+
void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
const Node *relative)
{
@@ -2151,7 +2361,10 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner,
fileName = fileBase(inner) + "-obsolete." + fileExtension();
}
if (status == CodeMarker::Obsolete) {
- QString link = QString("../" + Generator::outputSubdir() + QLatin1Char('/')) + fileName;
+ QString link;
+ if (useOutputSubdirs() && !Generator::outputSubdir().isEmpty())
+ link = QString("../" + Generator::outputSubdir() + QLatin1Char('/'));
+ link += fileName;
inner->setObsoleteLink(link);
}
@@ -2160,21 +2373,22 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner,
generateTitle(title, Text(), SmallSubTitle, inner, marker);
if (status == CodeMarker::Compat) {
- out() << "<p><b>The following class members are part of the "
+ out() << "<p><b>The following members of class "
+ << "<a href=\"" << linkForNode(inner, 0) << "\">"
+ << protectEnc(inner->name()) << "</a>"
+ << "are part of the "
"Qt compatibility layer.</b> We advise against "
"using them in new code.</p>\n";
}
else {
- out() << "<p><b>The following class members are obsolete.</b> "
+ out() << "<p><b>The following members of class "
+ << "<a href=\"" << linkForNode(inner, 0) << "\">"
+ << protectEnc(inner->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";
}
- out() << "<p><ul><li><a href=\""
- << linkForNode(inner, 0) << "\">"
- << protectEnc(inner->name())
- << " class reference</a></li></ul></p>\n";
-
for (i = 0; i < sections.size(); ++i) {
out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
@@ -2492,8 +2706,10 @@ void HtmlGenerator::generateCompactList(ListType listType,
}
else if (listType == Obsolete) {
QString fileName = fileBase(it.value()) + "-obsolete." + fileExtension();
- QString link = QString("../" + it.value()->outputSubdirectory() +
- QLatin1Char('/')) + fileName;
+ QString link;
+ if (useOutputSubdirs())
+ link = QString("../" + it.value()->outputSubdirectory() + QLatin1Char('/'));
+ link += fileName;
out() << "<a href=\"" << link << "\">";
}
@@ -3308,8 +3524,8 @@ QString HtmlGenerator::refForNode(const Node *node)
}
break;
case Node::Document:
- if (node->subType() != Node::QmlPropertyGroup)
- break;
+ break;
+ case Node::QmlPropertyGroup:
case Node::QmlProperty:
case Node::Property:
ref = node->name() + "-prop";
@@ -3372,7 +3588,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
}
QString link = fn;
- if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
+ if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
QString ref = refForNode(node);
if (relative && fn == fileName(relative) && ref == refForNode(relative))
return QString();
@@ -3387,7 +3603,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
back down into the other subdirectory.
*/
if (node && relative && (node != relative)) {
- if (node->outputSubdirectory() != relative->outputSubdirectory())
+ if (useOutputSubdirs() && node->outputSubdirectory() != relative->outputSubdirectory())
link.prepend(QString("../" + node->outputSubdirectory() + QLatin1Char('/')));
}
return link;
@@ -3778,6 +3994,22 @@ void HtmlGenerator::generateQmlSummary(const Section& section,
while (m != section.members.constEnd()) {
out() << "<li class=\"fn\">";
generateQmlItem(*m,relative,marker,true);
+ if ((*m)->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*m);
+ if (!qpgn->childNodes().isEmpty()) {
+ NodeList::ConstIterator p = qpgn->childNodes().constBegin();
+ out() << "<ul>\n";
+ while (p != qpgn->childNodes().constEnd()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ out() << "<li class=\"fn\">";
+ generateQmlItem(*p, relative, marker, true);
+ out() << "</li>\n";
+ }
+ ++p;
+ }
+ out() << "</ul>\n";
+ }
+ }
out() << "</li>\n";
++m;
}
@@ -3799,11 +4031,18 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
#endif
generateExtractionMark(node, MemberMark);
out() << "<div class=\"qmlitem\">";
- if (node->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ if (node->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
out() << "<div class=\"qmlproto\">";
out() << "<table class=\"qmlname\">";
+
+ QString heading = qpgn->name() + " group";
+ out() << "<tr valign=\"top\" class=\"even\">";
+ out() << "<th class=\"centerAlign\"><p>";
+ out() << "<a name=\"" + refForNode(qpgn) + "\"></a>";
+ out() << "<b>" << heading << "</b>";
+ out() << "</p></th></tr>";
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(*p);
@@ -3825,68 +4064,23 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
}
else if (node->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(node);
- /*
- If the QML property node has a single subproperty,
- override, replace qpn with that override node and
- proceed as normal.
- */
- if (qpn->qmlPropNodes().size() == 1) {
- Node* n = qpn->qmlPropNodes().at(0);
- if (n->type() == Node::QmlProperty)
- qpn = static_cast<QmlPropertyNode*>(n);
- }
- /*
- Now qpn either has no overrides, or it has more
- than 1. If it has none, proceed to output as nortmal.
- */
- if (qpn->qmlPropNodes().isEmpty()) {
- out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
- out() << "<tr valign=\"top\" class=\"odd\">";
- out() << "<td class=\"tblQmlPropNode\"><p>";
- out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
- if (!qpn->isReadOnlySet()) {
- if (qpn->declarativeCppNode())
- qpn->setReadOnly(!qpn->isWritable(qdb_));
- }
- if (qpn->isReadOnly())
- out() << "<span class=\"qmlreadonly\">read-only</span>";
- if (qpn->isDefault())
- out() << "<span class=\"qmldefault\">default</span>";
- generateQmlItem(qpn, relative, marker, false);
- out() << "</p></td></tr>";
- out() << "</table>";
- out() << "</div>";
- }
- else {
- /*
- The QML property node has multiple override nodes.
- Process the whole list as we would for a QML property
- group.
- */
- NodeList::ConstIterator p = qpn->qmlPropNodes().constBegin();
- out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
- while (p != qpn->qmlPropNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p);
- out() << "<tr valign=\"top\" class=\"odd\">";
- out() << "<td class=\"tblQmlPropNode\"><p>";
- out() << "<a name=\"" + refForNode(q) + "\"></a>";
- if (!qpn->isReadOnlySet())
- qpn->setReadOnly(!qpn->isWritable(qdb_));
- if (qpn->isReadOnly())
- out() << "<span class=\"qmlreadonly\">read-only</span>";
- if (qpn->isDefault())
- out() << "<span class=\"qmldefault\">default</span>";
- generateQmlItem(q, relative, marker, false);
- out() << "</p></td></tr>";
- }
- ++p;
- }
- out() << "</table>";
- out() << "</div>";
- }
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+ out() << "<tr valign=\"top\" class=\"odd\">";
+ out() << "<td class=\"tblQmlPropNode\"><p>";
+ out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
+ if (!qpn->isReadOnlySet()) {
+ if (qpn->declarativeCppNode())
+ qpn->setReadOnly(!qpn->isWritable(qdb_));
+ }
+ if (qpn->isReadOnly())
+ out() << "<span class=\"qmlreadonly\">read-only</span>";
+ if (qpn->isDefault())
+ out() << "<span class=\"qmldefault\">default</span>";
+ generateQmlItem(qpn, relative, marker, false);
+ out() << "</p></td></tr>";
+ out() << "</table>";
+ out() << "</div>";
}
else if (node->type() == Node::QmlSignal) {
const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
@@ -4359,8 +4553,6 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
break;
case Node::QmlClass:
break;
- case Node::QmlPropertyGroup:
- break;
case Node::QmlBasicType:
break;
case Node::QmlModule:
@@ -4394,6 +4586,8 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
if (!related)
child->location().warning(tr("Global variable, %1, %2").arg(child->name()).arg(message));
break;
+ case Node::QmlPropertyGroup:
+ break;
case Node::QmlProperty:
if (!related)
child->location().warning(tr("Global QML property, %1, %2").arg(child->name()).arg(message));