diff options
Diffstat (limited to 'src/tools/qdoc/ditaxmlgenerator.cpp')
-rw-r--r-- | src/tools/qdoc/ditaxmlgenerator.cpp | 505 |
1 files changed, 312 insertions, 193 deletions
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp index 1f986e35ff..0c88cbc529 100644 --- a/src/tools/qdoc/ditaxmlgenerator.cpp +++ b/src/tools/qdoc/ditaxmlgenerator.cpp @@ -70,9 +70,15 @@ QString DitaXmlGenerator::ditaTags[] = { "", "alt", + "apiData", + "apiDef", + "apiDefItem", "apiDesc", + "apiDetail", + "apiItemName", "APIMap", "apiName", + "apiRef", "apiRelation", "audience", "author", @@ -215,6 +221,34 @@ QString DitaXmlGenerator::ditaTags[] = "prodname", "prolog", "publisher", + "qmlAttached", + "qmlDetail", + "qmlImportModule", + "qmlInheritedBy", + "qmlInherits", + "qmlInstantiates", + "qmlMethod", + "qmlMethodDef", + "qmlMethodDetail", + "qmlName", + "qmlProperty", + "qmlPropertyDef", + "qmlPropertyDetail", + "qmlPropertyGroup", + "qmlPropertyGroupDef", + "qmlPropertyGroupDetail", + "qmlQualifier", + "qmlSignal", + "qmlSignalDef", + "qmlSignalDetail", + "qmlSignalHandler", + "qmlSignalHandlerDef", + "qmlSignalHandlerDetail", + "qmlSignature", + "qmlSince", + "qmlType", + "qmlTypeDef", + "qmlTypeDetail", "related-links", "resourceid", "revised", @@ -335,18 +369,18 @@ DitaXmlGenerator::DitaTag DitaXmlGenerator::currentTag() } /*! - Write the start tag \c{<apiDesc>}. if \a title is not - empty, generate a GUID from it and write the GUID as the - value of the \e{id} attribute. + Write the start \a tag. if \a title is not empty, generate + a GUID from it and write the GUID as the value of the \e{id} + attribute. Then if \a outputclass is not empty, write it as the value of the \a outputclass attribute. Fiunally, set the section nesting level to 1 and return 1. */ -int DitaXmlGenerator::enterApiDesc(const QString& outputclass, const QString& title) +int DitaXmlGenerator::enterDesc(DitaTag tag, const QString& outputclass, const QString& title) { - writeStartTag(DT_apiDesc); + writeStartTag(tag); if (!title.isEmpty()) { writeGuidAttribute(title); //Are there cases where the spectitle is required? @@ -646,6 +680,10 @@ void DitaXmlGenerator::generateTree(Tree *tree) Generator::generateTree(tree); generateCollisionPages(); + + QString fileBase = project.toLower().simplified().replace(" ", "-"); + generateIndex(fileBase, projectUrl, projectDescription); + writeDitaMap(tree); } @@ -1797,7 +1835,7 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) writeLocation(nsn); writeEndTag(); // <cxxClassDefinition> - enterApiDesc(QString(),title); + enterDesc(DT_apiDesc,QString(),title); #if 0 // To be removed, if really not needed. Text brief = nsn->doc().briefText(); // zzz @@ -1933,7 +1971,7 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) writeLocation(cn); writeEndTag(); // <cxxClassDefinition> - enterApiDesc(QString(),title); + enterDesc(DT_apiDesc,QString(),title); #if 0 // To be removed, if really not needed. Text brief = cn->doc().briefText(); // zzz @@ -2059,7 +2097,7 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) writeProlog(inner); writeStartTag(DT_cxxClassDetail); - enterApiDesc(QString(),title); + enterDesc(DT_apiDesc,QString(),title); #if 0 // To be removed, if really not needed. Text brief = fn->doc().briefText(); // zzz @@ -2173,15 +2211,20 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); title = rawTitle + " Element"; - //QString fullTitle = fake->fullTitle(); - //QString htmlTitle = fullTitle; + Node::clearPropertyGroupCount(); generateHeader(inner, fullTitle); generateBrief(inner, marker); // <shortdesc> writeProlog(inner); - writeStartTag(DT_cxxClassDetail); - enterApiDesc(QString(),title); + writeStartTag(DT_qmlTypeDetail); + generateQmlModuleDef(qcn); + generateQmlInherits(qcn,marker); + generateQmlInstantiates(qcn,marker); + generateQmlInheritedBy(qcn, marker); + generateQmlSince(qcn); + + enterDesc(DT_apiDesc,QString(),title); #if 0 // To be removed, if really not needed. Text brief = qcn->doc().briefText(); // zzz @@ -2191,10 +2234,6 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) writeEndTag(); // </p> } #endif - generateQmlInstantiates(qcn, marker); - generateQmlInherits(qcn, marker); - generateQmlInheritedBy(qcn, marker); - generateSince(qcn, marker); enterSection("",""); generateBody(qcn, marker); if (cn) { @@ -2203,42 +2242,13 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) } leaveSection(); leaveSection(); // </apiDesc> + writeEndTag(); // </qmlTypeDetail> - QList<Section> summarySections; - summarySections = marker->qmlSections(qcn,CodeMarker::Summary); - if (!summarySections.isEmpty()) { - enterSection("redundant",QString()); - s = summarySections.begin(); - while (s != summarySections.end()) { - QString attr; - if (!s->members.isEmpty()) { - writeStartTag(DT_p); - attr = cleanRef((*s).name).toLower() + " h2"; - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc((*s).name)); - writeEndTag(); // </p> - generateQmlSummary(*s,qcn,marker); - //generateSection(s->members, inner, marker, CodeMarker::Summary); - //generateSectionInheritedList(*s, inner, marker); - } - ++s; - } - leaveSection(); - } - - QList<Section> detailSections; - detailSections = marker->qmlSections(qcn,CodeMarker::Detailed); - if (!detailSections.isEmpty()) { - enterSection("details",QString()); - s = detailSections.begin(); - while (s != detailSections.end()) { + QList<Section> members = marker->qmlSections(qcn,CodeMarker::Detailed); + if (!members.isEmpty()) { + s = members.begin(); + while (s != members.end()) { if (!s->members.isEmpty()) { - QString attr; - writeStartTag(DT_p); - attr = cleanRef((*s).name).toLower() + " h2"; - xmlWriter().writeAttribute("outputclass",attr); - writeCharacters(protectEnc((*s).name)); - writeEndTag(); // </p> NodeList::ConstIterator m = (*s).members.begin(); while (m != (*s).members.end()) { generateDetailedQmlMember(*m, qcn, marker); @@ -2247,14 +2257,11 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker) } ++s; } - leaveSection(); } - writeEndTag(); // </cxxClassDetail> - writeEndTag(); // </cxxClass> + writeEndTag(); // </apiRef> } } - /*! Write a list item for a \a link with the given \a text. */ @@ -2429,7 +2436,7 @@ void DitaXmlGenerator::writeRelatedLinks(const FakeNode* node, CodeMarker* marke /*! Returns "dita" for this subclass of class Generator. */ -QString DitaXmlGenerator::fileExtension(const Node * /* node */) const +QString DitaXmlGenerator::fileExtension() const { return "dita"; } @@ -2487,14 +2494,14 @@ void DitaXmlGenerator::generateHeader(const Node* node, outputclass = "headerfile"; } else if (node->subType() == Node::QmlClass) { - mainTag = DT_cxxClass; + mainTag = DT_qmlType; nameTag = DT_apiName; - dtd = "dtd/cxxClass.dtd"; - version = "0.7.0"; + dtd = "dtd/qmlType.dtd"; + version = "0.1.0"; doctype = "<!DOCTYPE " + ditaTags[mainTag] + - " PUBLIC \"-//NOKIA//DTD DITA C++ API Class Reference Type v" + - version + "//EN\" \"" + dtd + "\">"; - outputclass = "QML-class"; + " PUBLIC \"-//NOKIA//DTD DITA QML Type" + + "//EN\" \"" + dtd + "\">"; + outputclass = "QML-type"; } else { mainTag = DT_topic; @@ -4426,6 +4433,50 @@ void DitaXmlGenerator::generateQmlSummary(const Section& section, } /*! + Writes the QML property \a qpn to the current DITA XML file. + Assumes that the correct start tag has already been written, + but nothing has been written inside that tag. This function + begins by writing the GUID id attribute for the property. + */ +void DitaXmlGenerator::startQmlProperty(QmlPropertyNode* qpn, + const InnerNode* relative, + CodeMarker* marker) +{ + writeStartTag(DT_qmlProperty); + writeGuidAttribute((Node*)qpn); + writeStartTag(DT_apiName); + writeCharacters(qpn->name()); + writeEndTag(); // </apiName> + generateBrief(qpn, marker); // <shortdesc> + writeStartTag(DT_qmlPropertyDetail); + writeStartTag(DT_qmlPropertyDef); + if (!qpn->isReadOnlySet()) + qpn->setReadOnly(!qpn->isWritable(tree_)); + if (qpn->isReadOnly()) { + writeStartTag(DT_qmlQualifier); + xmlWriter().writeAttribute("name","read-only"); + xmlWriter().writeAttribute("value","read-only"); + writeEndTag(); // </qmlQualifier> + } + if (qpn->isDefault()) { + writeStartTag(DT_qmlQualifier); + xmlWriter().writeAttribute("name","default"); + xmlWriter().writeAttribute("value","default"); + writeEndTag(); // </qmlQualifier> + } + if (qpn->isAttached()) { + writeStartTag(DT_qmlAttached); + xmlWriter().writeAttribute("name","attached"); + xmlWriter().writeAttribute("value","yes"); + writeEndTag(); // </qmlAttached> + } + writeStartTag(DT_apiData); + generateQmlItem(qpn, relative, marker, false); + writeEndTag(); // </apiData> + writeEndTag(); // </qmlPropertyDef> +} + +/*! Outputs the DITA detailed documentation for a section on a QML element reference page. */ @@ -4435,71 +4486,57 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node, { QString marked; QmlPropertyNode* qpn = 0; + if (node->subType() == Node::QmlPropertyGroup) { const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node); NodeList::ConstIterator p = qpgn->childNodes().begin(); - writeStartTag(DT_ul); - while (p != qpgn->childNodes().end()) { - if ((*p)->type() == Node::QmlProperty) { - qpn = static_cast<QmlPropertyNode*>(*p); - writeStartTag(DT_li); - writeGuidAttribute((Node*)qpn); - QString attr; - if (!qpn->isReadOnlySet()) - qpn->setReadOnly(!qpn->isWritable(tree_)); - if (qpn->isReadOnly()) - attr = "read-only"; - if (qpn->isDefault()) { - if (!attr.isEmpty()) - attr += QLatin1Char(' '); - attr += "default"; + if (qpgn->childNodes().size() == 1) { + qpn = static_cast<QmlPropertyNode*>(*p); + startQmlProperty(qpn,relative,marker); + writeQmlDesc(node, marker); + writeEndTag(); // </qmlPropertyDetail> + writeEndTag(); // </qmlProperty> + } + else { + writeStartTag(DT_qmlPropertyGroup); + QString id = "id-qml-propertygroup-" + node->name(); + id.replace('.','-'); + xmlWriter().writeAttribute("id",id); + writeStartTag(DT_apiName); + //writeCharacters("..."); + writeEndTag(); // </apiName> + writeStartTag(DT_qmlPropertyGroupDetail); + writeQmlDesc(node, marker); + writeEndTag(); // </qmlPropertyGroupDetail> + while (p != qpgn->childNodes().end()) { + if ((*p)->type() == Node::QmlProperty) { + qpn = static_cast<QmlPropertyNode*>(*p); + startQmlProperty(qpn,relative,marker); + writeEndTag(); // </qmlPropertyDetail> + writeEndTag(); // </qmlProperty> } - if (!attr.isEmpty()) - xmlWriter().writeAttribute("outputclass",attr); - generateQmlItem(qpn, relative, marker, false); - writeEndTag(); // </li> + ++p; } - ++p; + writeEndTag(); // </qmlPropertyGroup } - writeEndTag(); // </ul> } 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) { + if (qpn->qmlPropNodes().isEmpty()) { + startQmlProperty(qpn,relative,marker); + writeQmlDesc(node, marker); + writeEndTag(); // </qmlPropertyDetail> + writeEndTag(); // </qmlProperty> + } + else if (qpn->qmlPropNodes().size() == 1) { Node* n = qpn->qmlPropNodes().at(0); - if (n->type() == Node::QmlProperty) + 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()) { - writeStartTag(DT_ul); - writeStartTag(DT_li); - writeGuidAttribute((Node*)qpn); - QString attr; - if (!qpn->isReadOnlySet()) { - if (qpn->declarativeCppNode()) - qpn->setReadOnly(!qpn->isWritable(tree_)); - } - if (qpn->isReadOnly()) - attr = "read-only"; - if (qpn->isDefault()) { - if (!attr.isEmpty()) - attr += QLatin1Char(' '); - attr += "default"; - } - if (!attr.isEmpty()) - xmlWriter().writeAttribute("outputclass",attr); - generateQmlItem(qpn, relative, marker, false); - writeEndTag(); // </li> - writeEndTag(); // </ul> + startQmlProperty(qpn,relative,marker); + writeQmlDesc(node, marker); + writeEndTag(); // </qmlPropertyDetail> + writeEndTag(); // </qmlProperty> + } } else { /* @@ -4507,68 +4544,99 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node, Process the whole list as we would for a QML property group. */ + writeStartTag(DT_qmlPropertyGroup); + QString id = "id-qml-propertygroup-" + node->name(); + id.replace('.','-'); + xmlWriter().writeAttribute("id",id); + writeStartTag(DT_apiName); + //writeCharacters("..."); + writeEndTag(); // </apiName> + writeStartTag(DT_qmlPropertyGroupDetail); + writeQmlDesc(node, marker); + writeEndTag(); // </qmlPropertyGroupDetail> NodeList::ConstIterator p = qpn->qmlPropNodes().begin(); - writeStartTag(DT_ul); while (p != qpn->qmlPropNodes().end()) { if ((*p)->type() == Node::QmlProperty) { QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p); - writeStartTag(DT_li); - writeGuidAttribute((Node*)q); - QString attr; - if (!qpn->isReadOnlySet()) - qpn->setReadOnly(!qpn->isWritable(tree_)); - if (qpn->isReadOnly()) - attr = "read-only"; - if (qpn->isDefault()) { - if (!attr.isEmpty()) - attr += QLatin1Char(' '); - attr += "default"; - } - if (!attr.isEmpty()) - xmlWriter().writeAttribute("outputclass",attr); - generateQmlItem(q, relative, marker, false); - writeEndTag(); // </li> + startQmlProperty(q,relative,marker); + writeEndTag(); // </qmlPropertyDetail> + writeEndTag(); // </qmlProperty> } ++p; } - writeEndTag(); // </ul> + writeEndTag(); // </qmlPropertyGroup } } - else if (node->type() == Node::QmlSignal) { - Node* n = const_cast<Node*>(node); - writeStartTag(DT_ul); - writeStartTag(DT_li); - writeGuidAttribute(n); - marked = getMarkedUpSynopsis(n, relative, marker, CodeMarker::Detailed); - writeText(marked, marker, relative); - writeEndTag(); // </li> - writeEndTag(); // </ul> - } - else if (node->type() == Node::QmlSignalHandler) { - Node* n = const_cast<Node*>(node); - writeStartTag(DT_ul); - writeStartTag(DT_li); - writeGuidAttribute(n); - marked = getMarkedUpSynopsis(n, relative, marker, CodeMarker::Detailed); - writeText(marked, marker, relative); - writeEndTag(); // </li> - writeEndTag(); // </ul> - } - else if (node->type() == Node::QmlMethod) { - Node* n = const_cast<Node*>(node); - writeStartTag(DT_ul); - writeStartTag(DT_li); - writeGuidAttribute(n); - marked = getMarkedUpSynopsis(n, relative, marker, CodeMarker::Detailed); - writeText(marked, marker, relative); - writeEndTag(); // </li> - writeEndTag(); // </ul> - } + else if (node->type() == Node::QmlSignal) + writeQmlRef(DT_qmlSignal,node,relative,marker); + else if (node->type() == Node::QmlSignalHandler) + writeQmlRef(DT_qmlSignalHandler,node,relative,marker); + else if (node->type() == Node::QmlMethod) + writeQmlRef(DT_qmlMethod,node,relative,marker); +} + +/*! + Outputs the DITA detailed documentation for a section + on a QML element reference page. + */ +void DitaXmlGenerator::writeQmlRef(DitaTag tag, + Node* node, + const InnerNode* relative, + CodeMarker* marker) +{ + writeStartTag(tag); + Node* n = const_cast<Node*>(node); + writeGuidAttribute(n); + writeStartTag(DT_apiName); + writeCharacters(n->name()); + writeEndTag(); // </apiName> + writeStartTag((DitaTag)((int)tag+2)); + writeStartTag((DitaTag)((int)tag+1)); + writeStartTag(DT_apiData); + QString marked = getMarkedUpSynopsis(n, relative, marker, CodeMarker::Detailed); + writeText(marked, marker, relative); + writeEndTag(); // </apiData> + if (node->isAttached()) { + writeStartTag(DT_qmlAttached); + xmlWriter().writeAttribute("name","attached"); + xmlWriter().writeAttribute("value","yes"); + writeEndTag(); // </qmlAttached> + } + writeEndTag(); // </qmlXxxDef> + writeQmlDesc(node, marker); + writeEndTag(); // </qmlXxxDetail> + writeEndTag(); // tag +} + +/*! + Writes the <apiDesc> tag and its contents for the \a node. + The \a marker is used for markeing up the text body. + */ +void DitaXmlGenerator::writeQmlDesc(Node* node, CodeMarker* marker) +{ + writeStartTag(DT_apiDesc); generateStatus(node, marker); generateBody(node, marker); generateThreadSafeness(node, marker); generateSince(node, marker); generateAlsoList(node, marker); + writeEndTag(); // </apiDesc> +} + +/*! + This generates a <qmlTypeDef> in which the + QML module name and version number are specified. + */ +void DitaXmlGenerator::generateQmlModuleDef(QmlClassNode* qcn) +{ + writeStartTag(DT_qmlImportModule); + writeStartTag(DT_apiItemName); + writeCharacters(qcn->qmlModuleName()); + writeEndTag(); // </apiItemName> + writeStartTag(DT_apiData); + writeCharacters(qcn->qmlModuleVersion()); + writeEndTag(); // </apiData> + writeEndTag(); // </qmlImportModule> } /*! @@ -4581,17 +4649,42 @@ void DitaXmlGenerator::generateQmlInherits(const QmlClassNode* qcn, CodeMarker* return; const FakeNode* base = qcn->qmlBase(); if (base) { - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","inherits"); + writeStartTag(DT_qmlInherits); + //writeStartTag(DT_qmlTypeDef); + //xmlWriter().writeAttribute("outputclass","inherits"); + writeStartTag(DT_apiData); Text text; - text << "[Inherits "; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(base)); text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); text << Atom(Atom::String, base->name()); text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - text << "]"; generateText(text, qcn, marker); - writeEndTag(); // </p> + writeEndTag(); // </apiData> + writeEndTag(); // </qmlInherits> + } +} + +/*! + Output the "Inherit by" list for the QML element, + if it is inherited by any other elements. + */ +void DitaXmlGenerator::generateQmlInheritedBy(const QmlClassNode* qcn, CodeMarker* marker) +{ + if (qcn) { + NodeList subs; + QmlClassNode::subclasses(qcn->name(),subs); + if (!subs.isEmpty()) { + writeStartTag(DT_qmlInheritedBy); + //writeStartTag(DT_qmlTypeDef); + //xmlWriter().writeAttribute("outputclass","inherited-by"); + writeStartTag(DT_apiData); + Text text; + appendSortedQmlNames(text,qcn,subs,marker); + text << Atom::ParaRight; + generateText(text, qcn, marker); + writeEndTag(); // </apiData> + writeEndTag(); // </qmlIneritedBy> + } } } @@ -4606,22 +4699,39 @@ void DitaXmlGenerator::generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* ma { ClassNode* cn = qcn->classNode(); if (cn && (cn->status() != Node::Internal)) { - writeStartTag(DT_p); - xmlWriter().writeAttribute("outputclass","instantiates"); + writeStartTag(DT_qmlInstantiates); + //writeStartTag(DT_qmlTypeDef); + //xmlWriter().writeAttribute("outputclass","instantiates"); + writeStartTag(DT_apiData); Text text; - text << "["; - text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); - text << Atom(Atom::String, qcn->name()); - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - text << " instantiates the C++ class "; 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); - text << "]"; generateText(text, qcn, marker); - writeEndTag(); // </p> + writeEndTag(); // </apiData> + writeEndTag(); // </qmlInstantiates> + } +} + +/*! + Generate a <qmlXxxDef> for the "since" version string, if there is one. + */ +void DitaXmlGenerator::generateQmlSince(const Node* node) +{ + if (!node->since().isEmpty()) { + writeStartTag(DT_qmlSince); + //writeStartTag(DT_qmlTypeDef); + //xmlWriter().writeAttribute("outputclass","since"); + writeStartTag(DT_apiItemName); + QStringList pieces = node->since().split(QLatin1Char(' ')); + writeCharacters(pieces[0]); + writeEndTag(); // </apiItemName> + writeStartTag(DT_apiData); + if (pieces.size() > 1) + writeCharacters(pieces[1]); + writeEndTag(); // </apiData> + writeEndTag(); // </qmlSince> } } @@ -5589,7 +5699,7 @@ void DitaXmlGenerator::writeApiDesc(const Node* node, { if (!node->doc().isEmpty()) { inDetailedDescription = true; - enterApiDesc(QString(),title); + enterDesc(DT_apiDesc,QString(),title); generateBody(node, marker); generateAlsoList(node, marker); leaveSection(); @@ -5690,7 +5800,7 @@ DitaXmlGenerator::generateInnerNode(InnerNode* node) } /*! - Returns true if \a format is "XML" or "HTML" . + Returns true if \a format is "DITAXML" or "HTML" . */ bool DitaXmlGenerator::canHandleFormat(const QString& format) { @@ -6048,23 +6158,32 @@ void DitaXmlGenerator::writeTopicrefs(NodeMultiMap* nmm, const QString& navtitle xmlWriter().writeAttribute("navtitle",i.key()); xmlWriter().writeAttribute("href",fileName(i.value())); switch (i.value()->type()) { - case Node::Class: { - const NamespaceNode* nn = static_cast<const NamespaceNode*>(i.value()); - const NodeList& c = nn->childNodes(); - for (int j=0; j<c.size(); ++j) { - if (c[j]->isInternal() || c[j]->access() == Node::Private || c[j]->doc().isEmpty()) - continue; - if (c[j]->type() == Node::Class) { + case Node::Class: + case Node::Namespace: { + const NamespaceNode* nn = static_cast<const NamespaceNode*>(i.value()); + const NodeList& c = nn->childNodes(); + QMap<QString, const Node*> tempMap; + for (int j=0; j<c.size(); ++j) { + if (c[j]->isInternal() || c[j]->access() == Node::Private || c[j]->doc().isEmpty()) + continue; + if (c[j]->type() == Node::Class) { + tempMap.insert(c[j]->name(), c[j]); + } + } + QMap<QString, const Node*>::iterator classIterator = tempMap.begin(); + while (classIterator != tempMap.end()) { + const Node* currentNode = static_cast<const Node*>(classIterator.value()); writeStartTag(DT_topicref); - xmlWriter().writeAttribute("navtitle",c[j]->name()); - xmlWriter().writeAttribute("href",fileName(c[j])); + xmlWriter().writeAttribute("navtitle",currentNode->name()); + xmlWriter().writeAttribute("href",fileName(currentNode)); writeEndTag(); // </topicref> + ++classIterator; } + + break; } - break; - } - default: - break; + default: + break; } writeEndTag(); // </topicref> ++i; |