qdoc: Allow using group name as a QHP subproject selector

QDoc already recognized "group" as a document type selector, but provided no
way of defining which group the members should be selected from.

This commit adds that feature, by allowing 'group:groupname' as a selector.
All members (from the local tree) of the specified group are added to the
subproject.

Introduce up-to-date selector names for QML types and documentation pages,
but keep the old legacy names for compatibility.

Add documentation for the selectors.

Change-Id: Ic3f60a028d15f5f8e0035d28fbc503630af8f1d1
Task-number: QTBUG-32985
Reviewed-by: Martin Smith <martin.smith@digia.com>
This commit is contained in:
Topi Reinio 2015-07-23 14:52:28 +02:00 committed by Topi Reiniö
parent 71545f8df8
commit 3714c9b3fe
3 changed files with 123 additions and 48 deletions

View File

@ -1083,43 +1083,107 @@
\section1 Overview \section1 Overview
Starting with Qt 4.4, Qt Assistant uses a different system for managing Qt Assistant uses a system for managing Qt documentation that requires
Qt documentation that requires QDoc to generate inventories of files in a QDoc to generate inventories of files in a format that is similar to the
format that is similar to the old style DCF format, but with additional old style DCF format, but with additional features.
features.
Instead of hard-coding information about the documentation sets for Qt,
QDoc allows configuration variables to be used to specify which pages are QDoc allows configuration variables to be used to specify which pages are
to be used in each documentation set it generates. These are specified as to be used in each documentation set it generates. These are specified as
subvariables of the \c qch variable with each set declared using a unique subvariables of the \c qhp variable with each set declared using a unique
identifier as a subvariable. identifier as a subvariable.
For example, the configuration file for the Qt documentation defines a For example, the configuration file for the Qt Quick documentation set
\c Qt documentation set by specifying information about the set as specifies information about the set as subvariables with the
subvariables with the \c{qhp.Qt} prefix: \c{qhp.QtQuick} prefix:
\code \badcode
qhp.Qt.file = qt.qhp qhp.projects = QtQuick
qhp.Qt.namespace = org.qt-project.qtcore.$QT_VERSION_TAG
qhp.Qt.virtualFolder = qdoc qhp.QtQuick.file = qtquick.qhp
qhp.Qt.indexTitle = Qt Reference Documentation qhp.QtQuick.namespace = org.qt-project.qtquick.$QT_VERSION_TAG
qhp.Qt.indexRoot = qhp.QtQuick.virtualFolder = qtquick
qhp.Qt.extraFiles = classic.css images/qt-logo.png qhp.QtQuick.indexTitle = Qt Quick
qhp.Qt.filterAttributes = qt 4.4.0 qtrefdoc qhp.QtQuick.indexRoot =
qhp.Qt.customFilters.Qt.name = Qt 4.4.0
qhp.Qt.customFilters.Qt.filterAttributes = qt 4.4.0 qhp.QtQuick.filterAttributes = qtquick $QT_VERSION qtrefdoc
qhp.Qt.subprojects = classes overviews examples qhp.QtQuick.customFilters.Qt.name = QtQuick $QT_VERSION
qhp.Qt.subprojects.classes.title = Classes qhp.QtQuick.customFilters.Qt.filterAttributes = qtquick $QT_VERSION
qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
qhp.Qt.subprojects.classes.selectors = class qhp.QtQuick.subprojects = qmltypes classes examples
qhp.Qt.subprojects.overviews.title = Overviews
qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs qhp.QtQuick.subprojects.qmltypes.title = QML Types
qhp.Qt.subprojects.overviews.selectors = fake:page,group,module qhp.QtQuick.subprojects.qmltypes.indexTitle = Qt Quick QML Types
qhp.Qt.subprojects.examples.title = Tutorials and Examples qhp.QtQuick.subprojects.qmltypes.selectors = qmlclass
qhp.Qt.subprojects.examples.indexTitle = Qt Examples qhp.QtQuick.subprojects.qmltypes.sortPages = true
qhp.Qt.subprojects.examples.selectors = fake:example
qhp.QtQuick.subprojects.classes.title = Classes
qhp.QtQuick.subprojects.classes.title = C++ Classes
qhp.QtQuick.subprojects.classes.indexTitle = Qt Quick C++ Classes
qhp.QtQuick.subprojects.classes.selectors = class fake:headerfile
qhp.QtQuick.subprojects.classes.sortPages = true
qhp.QtQuick.subprojects.examples.title = Examples
qhp.QtQuick.subprojects.examples.indexTitle = Qt Quick Examples and Tutorials
qhp.QtQuick.subprojects.examples.selectors = fake:example
\endcode \endcode
The documentation set may include one or more subprojects, which are added
to the table of contents under the name specified by \c title. The page
in the documentation referred to by the \c indexTitle acts as the index page
for the subproject. The page types to list under the subproject are specified
by \c selectors. The entries are alphabetically sorted if \c sortPages is set
to \c true.
\section2 Using Selectors
The \c selectors property specifies which page types are listed under the
table of contents entry for a subproject. Multiple selectors can be listed,
separated by whitespace.
\table
\header \li Selector \li Description
\row \li \c namespace \li Namespaces
\row \li \c class \li Classes
\row \li \c qmltype \li QML Types
\row \li \c qmlclass \li Alias for \c qmltype.
\row \li \c module \li C++ Modules
\row \li \c qmlmodule \li QML Modules
\row \li \c doc[:subtype] \li Documentation pages with a specified
\c subtype. Multiple subtypes can be
listed as a comma-separated list.
\row \li \c fake \li Alias for \c doc.
\row \li \c group[:groupname] \li Documentation pages for members of a
specified group, as added using the
\l {ingroup-command}
{\\ingroup} groupname command.
Multiple group names can be listed as
a comma-separated list.
(Introduced in QDoc 5.6).
\endtable
Available subtypes for the \c doc selector:
\table
\header \li Subtype \li Description
\row \li \c example \li Examples
\row \li \c headerfile \li Header files
\row \li \c page \li Documentation pages defined with the
\l {page-command} {\\page} command.
\endtable
For example, the following configuration would select example pages and
pages that include the \c {\ingroup tutorials} command:
\badcode
qhp.QtQuickControls.subprojects = examples
qhp.QtQuickControls.subprojects.examples.title = Examples and Tutorials
qhp.QtQuickControls.subprojects.examples.indexTitle = Qt Quick Controls Examples
qhp.QtQuickControls.subprojects.examples.selectors = doc:example group:tutorials
qhp.QtQuickControls.subprojects.examples.sortPages = true
\endcode
\section2 Adding Table of Contents
To create a table of contents for a manual, create a subproject with To create a table of contents for a manual, create a subproject with
a \c{type} property and set it to \c{manual}. The page in the documentation a \c{type} property and set it to \c{manual}. The page in the documentation
referred to by the \c{indexTitle} property must contain a list of links referred to by the \c{indexTitle} property must contain a list of links
@ -1130,7 +1194,7 @@
subproject for its documentation, including all the documentation in a subproject for its documentation, including all the documentation in a
single manual: single manual:
\code \badcode
qhp.QtCreator.subprojects = manual qhp.QtCreator.subprojects = manual
qhp.QtCreator.subprojects.manual.title = Qt Creator Manual qhp.QtCreator.subprojects.manual.title = Qt Creator Manual
qhp.QtCreator.subprojects.manual.indexTitle = Qt Creator Manual qhp.QtCreator.subprojects.manual.indexTitle = Qt Creator Manual

View File

@ -125,7 +125,8 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
QHash<QString, Node::NodeType> typeHash; QHash<QString, Node::NodeType> typeHash;
typeHash["namespace"] = Node::Namespace; typeHash["namespace"] = Node::Namespace;
typeHash["class"] = Node::Class; typeHash["class"] = Node::Class;
typeHash["fake"] = Node::Document; typeHash["doc"] = Node::Document;
typeHash["fake"] = Node::Document; // Legacy alias for 'doc'
typeHash["enum"] = Node::Enum; typeHash["enum"] = Node::Enum;
typeHash["typedef"] = Node::Typedef; typeHash["typedef"] = Node::Typedef;
typeHash["function"] = Node::Function; typeHash["function"] = Node::Function;
@ -139,7 +140,8 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["qmlsignalhandler"] = Node::QmlSignalHandler; typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
typeHash["qmlmethod"] = Node::QmlMethod; typeHash["qmlmethod"] = Node::QmlMethod;
typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup; typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
typeHash["qmlclass"] = Node::QmlType; typeHash["qmlclass"] = Node::QmlType; // Legacy alias for 'qmltype'
typeHash["qmltype"] = Node::QmlType;
typeHash["qmlbasictype"] = Node::QmlBasicType; typeHash["qmlbasictype"] = Node::QmlBasicType;
QHash<QString, Node::DocSubtype> docSubtypeHash; QHash<QString, Node::DocSubtype> docSubtypeHash;
@ -158,16 +160,20 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
if (typeHash.contains(lower)) if (typeHash.contains(lower))
subproject.selectors[typeHash[lower]] = allSubTypes; subproject.selectors[typeHash[lower]] = allSubTypes;
} else if (pieces.size() >= 2) { } else if (pieces.size() >= 2) {
QString lower = pieces[0].toLower(); QString docType = pieces[0].toLower();
pieces = pieces[1].split(QLatin1Char(',')); pieces = pieces[1].split(QLatin1Char(','));
if (typeHash.contains(lower)) { if (typeHash.contains(docType)) {
QSet<Node::DocSubtype> docSubtypes; QSet<Node::DocSubtype> docSubtypes;
for (int i = 0; i < pieces.size(); ++i) { for (int i = 0; i < pieces.size(); ++i) {
QString lower = pieces[i].toLower(); QString piece = pieces[i].toLower();
if (docSubtypeHash.contains(lower)) if (typeHash[docType] == Node::Group) {
docSubtypes.insert(docSubtypeHash[lower]); subproject.groups << piece;
continue;
} }
subproject.selectors[typeHash[lower]] = docSubtypes; if (docSubtypeHash.contains(piece))
docSubtypes.insert(docSubtypeHash[piece]);
}
subproject.selectors[typeHash[docType]] = docSubtypes;
} }
} }
} }
@ -249,14 +255,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
if (!docPath.isEmpty() && project.excluded.contains(docPath)) if (!docPath.isEmpty() && project.excluded.contains(docPath))
return false; return false;
QString objName; QString objName = node->isDocumentNode() ? node->fullTitle() : node->fullDocumentName();
if (node->isDocumentNode()) {
const DocumentNode *fake = static_cast<const DocumentNode *>(node);
objName = fake->fullTitle();
}
else
objName = node->fullDocumentName();
// Only add nodes to the set for each subproject if they match a selector. // Only add nodes to the set for each subproject if they match a selector.
// Those that match will be listed in the table of contents. // Those that match will be listed in the table of contents.
@ -267,11 +266,22 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
project.subprojects[i].nodes[objName] = node; project.subprojects[i].nodes[objName] = node;
} }
else if (subproject.selectors.contains(node->type())) { else if (subproject.selectors.contains(node->type())) {
// Add all group members for 'group:name' selector
if (node->isGroup()) {
if (project.subprojects[i].groups.contains(node->name())) {
const CollectionNode* cn = static_cast<const CollectionNode*>(node);
foreach (const Node* m, cn->members()) {
QString memberName = m->isDocumentNode()
? m->fullTitle() : m->fullDocumentName();
project.subprojects[i].nodes[memberName] = m;
}
}
}
// Accept only the node types in the selectors hash. // Accept only the node types in the selectors hash.
if (node->type() != Node::Document) else if (node->type() != Node::Document)
project.subprojects[i].nodes[objName] = node; project.subprojects[i].nodes[objName] = node;
else { else {
// Accept only fake nodes with subtypes contained in the selector's // Accept only doc nodes with subtypes contained in the selector's
// mask. // mask.
const DocumentNode *docNode = static_cast<const DocumentNode *>(node); const DocumentNode *docNode = static_cast<const DocumentNode *>(node);
if (subproject.selectors[node->type()].contains(docNode->docSubtype()) && if (subproject.selectors[node->type()].contains(docNode->docSubtype()) &&

View File

@ -54,6 +54,7 @@ struct SubProject
bool sortPages; bool sortPages;
QString type; QString type;
QHash<QString, const Node *> nodes; QHash<QString, const Node *> nodes;
QStringList groups;
}; };
struct HelpProject struct HelpProject