summaryrefslogtreecommitdiffstats
path: root/src/tools/qdoc/helpprojectwriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/qdoc/helpprojectwriter.cpp')
-rw-r--r--src/tools/qdoc/helpprojectwriter.cpp174
1 files changed, 110 insertions, 64 deletions
diff --git a/src/tools/qdoc/helpprojectwriter.cpp b/src/tools/qdoc/helpprojectwriter.cpp
index d46f887518..81ad038f91 100644
--- a/src/tools/qdoc/helpprojectwriter.cpp
+++ b/src/tools/qdoc/helpprojectwriter.cpp
@@ -131,22 +131,23 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["function"] = Node::Function;
typeHash["property"] = Node::Property;
typeHash["variable"] = Node::Variable;
+ typeHash["group"] = Node::Group;
+ typeHash["module"] = Node::Module;
+ typeHash["qmlmodule"] = Node::QmlModule;
typeHash["qmlproperty"] = Node::QmlProperty;
typeHash["qmlsignal"] = Node::QmlSignal;
typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
typeHash["qmlmethod"] = Node::QmlMethod;
typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
+ typeHash["qmlclass"] = Node::QmlType;
+ typeHash["qmlbasictype"] = Node::QmlBasicType;
QHash<QString, Node::SubType> subTypeHash;
subTypeHash["example"] = Node::Example;
subTypeHash["headerfile"] = Node::HeaderFile;
subTypeHash["file"] = Node::File;
- subTypeHash["group"] = Node::Group;
- subTypeHash["module"] = Node::Module;
subTypeHash["page"] = Node::Page;
subTypeHash["externalpage"] = Node::ExternalPage;
- subTypeHash["qmlclass"] = Node::QmlClass;
- subTypeHash["qmlbasictype"] = Node::QmlBasicType;
QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
@@ -210,16 +211,14 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
// "id"
details << node->parent()->name()+"::"+node->name();
}
- else if (node->type() == Node::Document) {
+ else if (node->isQmlType() || node->isQmlBasicType()) {
+ details << node->name();
+ details << "QML." + node->name();
+ }
+ else if (node->isDocNode()) {
const DocNode *fake = static_cast<const DocNode *>(node);
- if (fake->subType() == Node::QmlClass) {
- details << (QmlClassNode::qmlOnly ? fake->name() : fake->fullTitle());
- details << "QML." + fake->name();
- }
- else {
- details << fake->fullTitle();
- details << fake->fullTitle();
- }
+ details << fake->fullTitle();
+ details << fake->fullTitle();
}
else {
details << node->name();
@@ -247,7 +246,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
return false;
QString objName;
- if (node->type() == Node::Document) {
+ if (node->isDocNode()) {
const DocNode *fake = static_cast<const DocNode *>(node);
objName = fake->fullTitle();
}
@@ -285,12 +284,28 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Class:
project.keywords.append(keywordDetails(node));
- project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
+ break;
+ case Node::QmlType:
+ case Node::QmlBasicType:
+ if (node->doc().hasKeywords()) {
+ foreach (const Atom* keyword, node->doc().keywords()) {
+ if (!keyword->string().isEmpty()) {
+ QStringList details;
+ details << keyword->string()
+ << keyword->string()
+ << gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()) +
+ QLatin1Char('#') + Doc::canonicalTitle(keyword->string());
+ project.keywords.append(details);
+ }
+ else
+ node->doc().location().warning(tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs())));
+ }
+ }
+ project.keywords.append(keywordDetails(node));
break;
case Node::Namespace:
project.keywords.append(keywordDetails(node));
- project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
break;
case Node::Enum:
@@ -316,6 +331,33 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
}
break;
+ case Node::Group:
+ case Node::Module:
+ case Node::QmlModule:
+ {
+ const CollectionNode* cn = static_cast<const CollectionNode*>(node);
+ if (!cn->fullTitle().isEmpty()) {
+ if (cn->doc().hasKeywords()) {
+ foreach (const Atom* keyword, cn->doc().keywords()) {
+ if (!keyword->string().isEmpty()) {
+ QStringList details;
+ details << keyword->string()
+ << keyword->string()
+ << gen_->fullDocumentLocation(node, Generator::useOutputSubdirs()) +
+ QLatin1Char('#') + Doc::canonicalTitle(keyword->string());
+ project.keywords.append(details);
+ }
+ else
+ cn->doc().location().warning(
+ tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()))
+ );
+ }
+ }
+ project.keywords.append(keywordDetails(node));
+ }
+ }
+ break;
+
case Node::Property:
case Node::QmlProperty:
case Node::QmlSignal:
@@ -342,7 +384,6 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
if (node->relates()) {
project.memberStatus[node->relates()].insert(node->status());
- project.files.insert(gen_->fullDocumentLocation(node->relates(),Generator::useOutputSubdirs()));
} else if (node->parent())
project.memberStatus[node->parent()].insert(node->status());
}
@@ -364,8 +405,6 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Variable:
{
- QString location = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
- project.files.insert(location.left(location.lastIndexOf(QLatin1Char('#'))));
project.keywords.append(keywordDetails(node));
}
break;
@@ -396,7 +435,6 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
}
project.keywords.append(keywordDetails(node));
}
- project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
}
break;
}
@@ -467,8 +505,6 @@ void HelpProjectWriter::generateSections(HelpProject &project,
project.memberStatus[node].insert(childNode->status());
if (childNode->relates()) {
project.memberStatus[childNode->relates()].insert(childNode->status());
- project.files.insert(gen_->fullDocumentLocation(childNode->relates(),
- Generator::useOutputSubdirs()));
}
if (childNode->type() == Node::Function) {
@@ -479,11 +515,6 @@ void HelpProjectWriter::generateSections(HelpProject &project,
childMap[childNode->fullDocumentName()] = childNode;
}
}
- // Insert files for all/compatibility/obsolete members
- addMembers(project, writer, node, false);
- if (node->relates())
- addMembers(project, writer, node->relates(), false);
-
foreach (const Node *child, childMap)
generateSections(project, writer, child);
}
@@ -518,44 +549,34 @@ void HelpProjectWriter::writeSection(QXmlStreamWriter &writer, const QString &pa
}
/*
- Add files for all members, compatibility members and obsolete members
- Also write subsections for these depending on 'writeSections' (default=true).
+ Write subsections for all members, compatibility members and obsolete members.
*/
void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &writer,
- const Node *node, bool writeSections)
+ const Node *node)
{
QString href = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
href = href.left(href.size()-5);
if (href.isEmpty())
return;
- Node::SubType subType = static_cast<const DocNode*>(node)->subType();
-
bool derivedClass = false;
if (node->type() == Node::Class)
derivedClass = !(static_cast<const ClassNode *>(node)->baseClasses().isEmpty());
// Do not generate a 'List of all members' for namespaces or header files,
// but always generate it for derived classes and QML classes
- if (node->type() != Node::Namespace && subType != Node::HeaderFile &&
- (derivedClass || subType == Node::QmlClass ||
- !project.memberStatus[node].isEmpty())) {
+ if (!node->isNamespace() && !node->isHeaderFile() &&
+ (derivedClass || node->isQmlType() || !project.memberStatus[node].isEmpty())) {
QString membersPath = href + QStringLiteral("-members.html");
- project.files.insert(membersPath);
- if (writeSections)
- writeSection(writer, membersPath, tr("List of all members"));
+ writeSection(writer, membersPath, tr("List of all members"));
}
if (project.memberStatus[node].contains(Node::Compat)) {
QString compatPath = href + QStringLiteral("-compat.html");
- project.files.insert(compatPath);
- if (writeSections)
- writeSection(writer, compatPath, tr("Compatibility members"));
+ writeSection(writer, compatPath, tr("Compatibility members"));
}
if (project.memberStatus[node].contains(Node::Obsolete)) {
QString obsoletePath = href + QStringLiteral("-obsolete.html");
- project.files.insert(obsoletePath);
- if (writeSections)
- writeSection(writer, obsoletePath, tr("Obsolete members"));
+ writeSection(writer, obsoletePath, tr("Obsolete members"));
}
}
@@ -583,6 +604,14 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
writeSection(writer, href, objName);
break;
+ case Node::QmlType:
+ writer.writeStartElement("section");
+ writer.writeAttribute("ref", href);
+ writer.writeAttribute("title", tr("%1 Type Reference").arg(node->fullTitle()));
+ addMembers(project, writer, node);
+ writer.writeEndElement(); // section
+ break;
+
case Node::Document: {
// Document nodes (such as manual pages) contain subtypes, titles and other
// attributes.
@@ -590,17 +619,25 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
- if (docNode->subType() == Node::QmlClass)
- writer.writeAttribute("title", tr("%1 Type Reference").arg(docNode->fullTitle()));
- else
- writer.writeAttribute("title", docNode->fullTitle());
+ writer.writeAttribute("title", docNode->fullTitle());
- if ((docNode->subType() == Node::HeaderFile) || (docNode->subType() == Node::QmlClass))
+ if (docNode->subType() == Node::HeaderFile)
addMembers(project, writer, node);
writer.writeEndElement(); // section
}
break;
+ case Node::Group:
+ case Node::Module:
+ case Node::QmlModule:
+ {
+ const CollectionNode* cn = static_cast<const CollectionNode*>(node);
+ writer.writeStartElement("section");
+ writer.writeAttribute("ref", href);
+ writer.writeAttribute("title", cn->fullTitle());
+ writer.writeEndElement(); // section
+ }
+ break;
default:
;
}
@@ -609,10 +646,15 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
void HelpProjectWriter::generateProject(HelpProject &project)
{
const Node *rootNode;
+
+ // Restrict searching only to the local (primary) tree
+ QVector<Tree*> searchOrder = qdb_->searchOrder();
+ qdb_->setLocalSearch();
+
if (!project.indexRoot.isEmpty())
rootNode = qdb_->findDocNodeByTitle(project.indexRoot);
else
- rootNode = qdb_->treeRoot();
+ rootNode = qdb_->primaryTreeRoot();
if (!rootNode)
return;
@@ -655,16 +697,14 @@ void HelpProjectWriter::generateProject(HelpProject &project)
writer.writeStartElement("section");
const Node* node = qdb_->findDocNodeByTitle(project.indexTitle);
if (node == 0)
- node = qdb_->findNode(QStringList("index.html"));
+ node = qdb_->findNodeByNameAndType(QStringList("index.html"), Node::Document);
QString indexPath;
- // Never use a collision node as a landing page
- if (node && !node->isCollisionNode())
+ if (node)
indexPath = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
else
indexPath = "index.html";
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", project.indexTitle);
- project.files.insert(gen_->fullDocumentLocation(rootNode));
generateSections(project, writer, rootNode);
@@ -673,7 +713,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
if (subproject.type == QLatin1String("manual")) {
- const DocNode *indexPage = qdb_->findDocNodeByTitle(subproject.indexTitle);
+ const Node *indexPage = qdb_->findNodeForTarget(subproject.indexTitle, 0);
if (indexPage) {
Text indexBody = indexPage->doc().body();
const Atom *atom = indexBody.firstAtom();
@@ -700,13 +740,12 @@ void HelpProjectWriter::generateProject(HelpProject &project)
if (sectionStack.top() > 0)
writer.writeEndElement(); // section
- const DocNode *page = qdb_->findDocNodeByTitle(atom->string());
+ const Node *page = qdb_->findNodeForTarget(atom->string(), 0);
writer.writeStartElement("section");
QString indexPath = gen_->fullDocumentLocation(page,
Generator::useOutputSubdirs());
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", atom->string());
- project.files.insert(indexPath);
sectionStack.top() += 1;
}
@@ -728,10 +767,10 @@ void HelpProjectWriter::generateProject(HelpProject &project)
if (!name.isEmpty()) {
writer.writeStartElement("section");
- QString indexPath = gen_->fullDocumentLocation(qdb_->findDocNodeByTitle(subproject.indexTitle),Generator::useOutputSubdirs());
+ QString indexPath = gen_->fullDocumentLocation(qdb_->findNodeForTarget(subproject.indexTitle, 0),
+ Generator::useOutputSubdirs());
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", subproject.title);
- project.files.insert(indexPath);
}
if (subproject.sortPages) {
QStringList titles = subproject.nodes.keys();
@@ -748,7 +787,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
if (!nextTitle.isEmpty() &&
node->links().value(Node::ContentsLink).first.isEmpty()) {
- DocNode *nextPage = const_cast<DocNode *>(qdb_->findDocNodeByTitle(nextTitle));
+ const Node *nextPage = qdb_->findNodeForTarget(nextTitle, 0);
// Write the contents node.
writeNode(project, writer, node);
@@ -758,7 +797,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
nextTitle = nextPage->links().value(Node::NextLink).first;
if (nextTitle.isEmpty() || visited.contains(nextTitle))
break;
- nextPage = const_cast<DocNode *>(qdb_->findDocNodeByTitle(nextTitle));
+ nextPage = qdb_->findNodeForTarget(nextTitle, 0);
visited.insert(nextTitle);
}
break;
@@ -771,6 +810,9 @@ void HelpProjectWriter::generateProject(HelpProject &project)
}
}
+ // Restore original search order
+ qdb_->setSearchOrder(searchOrder);
+
writer.writeEndElement(); // section
writer.writeEndElement(); // toc
@@ -785,12 +827,16 @@ void HelpProjectWriter::generateProject(HelpProject &project)
writer.writeEndElement(); // keywords
writer.writeStartElement("files");
- foreach (const QString &usedFile, project.files) {
+
+ // The list of files to write is the union of generated files and
+ // other files (images and extras) included in the project
+ QSet<QString> files = QSet<QString>::fromList(gen_->outputFileNames());
+ files.unite(project.files);
+ files.unite(project.extraFiles);
+ foreach (const QString &usedFile, files) {
if (!usedFile.isEmpty())
writer.writeTextElement("file", usedFile);
}
- foreach (const QString &usedFile, project.extraFiles)
- writer.writeTextElement("file", usedFile);
writer.writeEndElement(); // files
writer.writeEndElement(); // filterSection