1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the tools applications of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include "generator.h"
45 #include "qdocdatabase.h"
46 #include "qdoctagfiles.h"
47 #include "qdocindexfiles.h"
52 static NodeMap emptyNodeMap_;
53 static NodeMultiMap emptyNodeMultiMap_;
55 /*! \class QDocDatabase
58 QDocDatabase* QDocDatabase::qdocDB_ = NULL;
61 Constructs the singleton qdoc database object.
62 It constructs a singleton Tree object with this
63 qdoc database pointer.
65 QDocDatabase::QDocDatabase()
67 tree_ = new Tree(this);
71 Destroys the qdoc database object. This requires deleting
72 the tree of nodes, which deletes each node.
74 QDocDatabase::~QDocDatabase()
80 /*! \fn Tree* QDocDatabase::tree()
81 Returns the pointer to the tree. This function is for compatibility
82 with the current qdoc. It will be removed when the QDocDatabase class
83 replaces the current structures.
87 Creates the singleton. Allows only one instance of the class
88 to be created. Returns a pointer to the singleton.
90 QDocDatabase* QDocDatabase::qdocDB()
93 qdocDB_ = new QDocDatabase;
98 Destroys the singleton.
100 void QDocDatabase::destroyQdocDB()
109 \fn const DocNodeMap& QDocDatabase::modules() const
110 Returns a const reference to the collection of all
115 \fn const DocNodeMap& QDocDatabase::qmlModules() const
116 Returns a const reference to the collection of all
121 Looks up the module node named \a name in the collection
122 of all module nodes. If a match is found, a pointer to the
123 node is returned. Otherwise, a new module node named \a name
124 is created and inserted into the collection, and the pointer
125 to that node is returned.
127 DocNode* QDocDatabase::addModule(const QString& name)
129 return findModule(name,true);
133 Looks up the QML module node named \a name in the collection
134 of all QML module nodes. If a match is found, a pointer to the
135 node is returned. Otherwise, a new QML module node named \a name
136 is created and inserted into the collection, and the pointer
137 to that node is returned.
139 DocNode* QDocDatabase::addQmlModule(const QString& name)
141 return findQmlModule(name,true);
145 Looks up the C++ module named \a moduleName. If it isn't
146 there, create it. Then append \a node to the module's child
147 list. The parent of \a node is not changed by this function.
148 Returns the module node.
150 DocNode* QDocDatabase::addToModule(const QString& moduleName, Node* node)
152 DocNode* dn = findModule(moduleName,true);
154 node->setModuleName(moduleName);
159 Looks up the QML module named \a qmlModuleName. If it isn't
160 there, create it. Then append \a node to the module's child
161 list. The parent of \a node is not changed by this function.
162 Returns a pointer to the QML module node.
164 DocNode* QDocDatabase::addToQmlModule(const QString& qmlModuleName, Node* node)
166 DocNode* dn = findQmlModule(qmlModuleName,true);
168 node->setQmlModuleInfo(qmlModuleName);
169 if (node->subType() == Node::QmlClass) {
170 QString t = node->qmlModuleIdentifier() + "::" + node->name();
171 QmlClassNode* n = static_cast<QmlClassNode*>(node);
172 if (!qmlTypeMap_.contains(t))
173 qmlTypeMap_.insert(t,n);
174 if (!masterMap_.contains(t))
175 masterMap_.insert(t,node);
176 if (!masterMap_.contains(node->name(),node))
177 masterMap_.insert(node->name(),node);
183 Find the module node named \a name and return a pointer
184 to it. If a matching node is not found and \a addIfNotFound
185 is true, add a new module node named \a name and return
186 a pointer to that one. Otherwise, return 0.
188 If a new module node is added, its parent is the tree root,
189 but the new module node is not added to the child list of the
192 DocNode* QDocDatabase::findModule(const QString& name, bool addIfNotFound)
194 DocNodeMap::const_iterator i = modules_.find(name);
195 if (i != modules_.end()) {
199 DocNode* dn = new DocNode(tree_->root(), name, Node::Module, Node::OverviewPage);
200 modules_.insert(name,dn);
201 if (!masterMap_.contains(name,dn))
202 masterMap_.insert(name,dn);
209 Find the QML module node named \a name and return a pointer
210 to it. If a matching node is not found and \a addIfNotFound
211 is true, add a new QML module node named \a name and return
212 a pointer to that one. Otherwise, return 0.
214 If a new QML module node is added, its parent is the tree root,
215 but the new QML module node is not added to the child list of
218 DocNode* QDocDatabase::findQmlModule(const QString& name, bool addIfNotFound)
220 QStringList dotSplit;
221 QStringList blankSplit = name.split(QLatin1Char(' '));
222 QString qmid = blankSplit[0];
223 if (blankSplit.size() > 1) {
224 dotSplit = blankSplit[1].split(QLatin1Char('.'));
228 if (qmlModules_.contains(qmid))
229 dn = qmlModules_.value(qmid);
230 else if (addIfNotFound) {
231 dn = new DocNode(tree_->root(), name, Node::QmlModule, Node::OverviewPage);
232 dn->setQmlModuleInfo(name);
233 qmlModules_.insert(qmid,dn);
234 masterMap_.insert(qmid,dn);
235 masterMap_.insert(dn->name(),dn);
241 Looks up the QML type node identified by the Qml module id
242 \a qmid and QML type \a name and returns a pointer to the
243 QML type node. The key is \a qmid + "::" + \a name.
245 If the QML module id is empty, it looks up the QML type by
248 QmlClassNode* QDocDatabase::findQmlType(const QString& qmid, const QString& name) const
251 return qmlTypeMap_.value(qmid + "::" + name);
253 QStringList path(name);
254 Node* n = tree_->findNodeByNameAndType(path, Node::Document, Node::QmlClass, 0, true);
256 if (n->subType() == Node::QmlClass)
257 return static_cast<QmlClassNode*>(n);
258 else if (n->subType() == Node::Collision) {
259 NameCollisionNode* ncn;
260 ncn = static_cast<NameCollisionNode*>(n);
261 return static_cast<QmlClassNode*>(ncn->findAny(Node::Document,Node::QmlClass));
271 void QDocDatabase::printModules() const
273 DocNodeMap::const_iterator i = modules_.begin();
274 while (i != modules_.end()) {
275 qDebug() << " " << i.key();
283 void QDocDatabase::printQmlModules() const
285 DocNodeMap::const_iterator i = qmlModules_.begin();
286 while (i != qmlModules_.end()) {
287 qDebug() << " " << i.key();
293 Traverses the database to construct useful data structures
294 for use when outputting certain significant collections of
295 things, C++ classes, QML types, "since" lists, and other
298 void QDocDatabase::buildCollections()
300 nonCompatClasses_.clear();
301 mainClasses_.clear();
302 compatClasses_.clear();
303 obsoleteClasses_.clear();
305 legaleseTexts_.clear();
306 serviceClasses_.clear();
309 findAllClasses(treeRoot());
310 findAllFunctions(treeRoot());
311 findAllLegaleseTexts(treeRoot());
312 findAllNamespaces(treeRoot());
313 findAllSince(treeRoot());
317 Finds all the C++ class nodes and QML type nodes and
318 sorts them into maps.
320 void QDocDatabase::findAllClasses(const InnerNode* node)
322 NodeList::const_iterator c = node->childNodes().constBegin();
323 while (c != node->childNodes().constEnd()) {
324 if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
325 if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
326 QString className = (*c)->name();
327 if ((*c)->parent() &&
328 (*c)->parent()->type() == Node::Namespace &&
329 !(*c)->parent()->name().isEmpty())
330 className = (*c)->parent()->name()+"::"+className;
332 if (!(static_cast<const ClassNode *>(*c))->hideFromMainList()) {
333 if ((*c)->status() == Node::Compat) {
334 compatClasses_.insert(className, *c);
336 else if ((*c)->status() == Node::Obsolete) {
337 obsoleteClasses_.insert(className, *c);
340 nonCompatClasses_.insert(className, *c);
341 if ((*c)->status() == Node::Main)
342 mainClasses_.insert(className, *c);
346 QString serviceName = (static_cast<const ClassNode *>(*c))->serviceName();
347 if (!serviceName.isEmpty())
348 serviceClasses_.insert(serviceName, *c);
350 else if ((*c)->type() == Node::Document &&
351 (*c)->subType() == Node::QmlClass &&
352 !(*c)->doc().isEmpty()) {
353 QString qmlTypeName = (*c)->name();
354 if (qmlTypeName.startsWith(QLatin1String("QML:")))
355 qmlClasses_.insert(qmlTypeName.mid(4),*c);
357 qmlClasses_.insert(qmlTypeName,*c);
359 else if ((*c)->isInnerNode()) {
360 findAllClasses(static_cast<InnerNode*>(*c));
368 Finds all the function nodes
370 void QDocDatabase::findAllFunctions(const InnerNode* node)
372 NodeList::ConstIterator c = node->childNodes().constBegin();
373 while (c != node->childNodes().constEnd()) {
374 if ((*c)->access() != Node::Private) {
375 if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
376 findAllFunctions(static_cast<const InnerNode*>(*c));
378 else if ((*c)->type() == Node::Function) {
379 const FunctionNode* func = static_cast<const FunctionNode*>(*c);
380 if ((func->status() > Node::Obsolete) &&
381 !func->isInternal() &&
382 (func->metaness() != FunctionNode::Ctor) &&
383 (func->metaness() != FunctionNode::Dtor)) {
384 funcIndex_[(*c)->name()].insert((*c)->parent()->fullDocumentName(), *c);
393 Finds all the nodes containing legalese text and puts them
396 void QDocDatabase::findAllLegaleseTexts(const InnerNode* node)
398 NodeList::ConstIterator c = node->childNodes().constBegin();
399 while (c != node->childNodes().constEnd()) {
400 if ((*c)->access() != Node::Private) {
401 if (!(*c)->doc().legaleseText().isEmpty())
402 legaleseTexts_.insertMulti((*c)->doc().legaleseText(), *c);
403 if ((*c)->isInnerNode())
404 findAllLegaleseTexts(static_cast<const InnerNode *>(*c));
411 Finds all the namespace nodes and puts them in an index.
413 void QDocDatabase::findAllNamespaces(const InnerNode* node)
415 NodeList::ConstIterator c = node->childNodes().constBegin();
416 while (c != node->childNodes().constEnd()) {
417 if ((*c)->access() != Node::Private) {
418 if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
419 findAllNamespaces(static_cast<const InnerNode *>(*c));
420 if ((*c)->type() == Node::Namespace) {
421 const NamespaceNode* nspace = static_cast<const NamespaceNode *>(*c);
422 // Ensure that the namespace's name is not empty (the root
423 // namespace has no name).
424 if (!nspace->name().isEmpty()) {
425 namespaceIndex_.insert(nspace->name(), *c);
435 Finds all the nodes where a \e{since} command appeared in the
436 qdoc comment and sorts them into maps according to the kind of
439 This function is used for generating the "New Classes... in x.y"
440 section on the \e{What's New in Qt x.y} page.
442 void QDocDatabase::findAllSince(const InnerNode* node)
444 NodeList::const_iterator child = node->childNodes().constBegin();
445 while (child != node->childNodes().constEnd()) {
446 QString sinceString = (*child)->since();
447 // Insert a new entry into each map for each new since string found.
448 if (((*child)->access() != Node::Private) && !sinceString.isEmpty()) {
449 NodeMultiMapMap::iterator nsmap = newSinceMaps_.find(sinceString);
450 if (nsmap == newSinceMaps_.end())
451 nsmap = newSinceMaps_.insert(sinceString,NodeMultiMap());
453 NodeMapMap::iterator ncmap = newClassMaps_.find(sinceString);
454 if (ncmap == newClassMaps_.end())
455 ncmap = newClassMaps_.insert(sinceString,NodeMap());
457 NodeMapMap::iterator nqcmap = newQmlTypeMaps_.find(sinceString);
458 if (nqcmap == newQmlTypeMaps_.end())
459 nqcmap = newQmlTypeMaps_.insert(sinceString,NodeMap());
461 if ((*child)->type() == Node::Function) {
462 // Insert functions into the general since map.
463 FunctionNode *func = static_cast<FunctionNode *>(*child);
464 if ((func->status() > Node::Obsolete) &&
465 (func->metaness() != FunctionNode::Ctor) &&
466 (func->metaness() != FunctionNode::Dtor)) {
467 nsmap.value().insert(func->name(),(*child));
470 else if ((*child)->url().isEmpty()) {
471 if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) {
472 // Insert classes into the since and class maps.
473 QString className = (*child)->name();
474 if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
475 !(*child)->parent()->name().isEmpty()) {
476 className = (*child)->parent()->name()+"::"+className;
478 nsmap.value().insert(className,(*child));
479 ncmap.value().insert(className,(*child));
481 else if ((*child)->subType() == Node::QmlClass) {
482 // Insert QML elements into the since and element maps.
483 QString className = (*child)->name();
484 if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
485 !(*child)->parent()->name().isEmpty()) {
486 className = (*child)->parent()->name()+"::"+className;
488 nsmap.value().insert(className,(*child));
489 nqcmap.value().insert(className,(*child));
491 else if ((*child)->type() == Node::QmlProperty) {
492 // Insert QML properties into the since map.
493 QString propertyName = (*child)->name();
494 nsmap.value().insert(propertyName,(*child));
498 // Insert external documents into the general since map.
499 QString name = (*child)->name();
500 if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
501 !(*child)->parent()->name().isEmpty()) {
502 name = (*child)->parent()->name()+"::"+name;
504 nsmap.value().insert(name,(*child));
507 // Recursively find child nodes with since commands.
508 if ((*child)->isInnerNode()) {
509 findAllSince(static_cast<InnerNode *>(*child));
517 Find the \a key in the map of new class maps, and return a
518 reference to the value, which is a NodeMap. If \a key is not
519 found, return a reference to an empty NodeMap.
521 const NodeMap& QDocDatabase::getClassMap(const QString& key) const
523 NodeMapMap::const_iterator i = newClassMaps_.constFind(key);
524 if (i != newClassMaps_.constEnd())
526 return emptyNodeMap_;
530 Find the \a key in the map of new QML type maps, and return a
531 reference to the value, which is a NodeMap. If the \a key is not
532 found, return a reference to an empty NodeMap.
534 const NodeMap& QDocDatabase::getQmlTypeMap(const QString& key) const
536 NodeMapMap::const_iterator i = newQmlTypeMaps_.constFind(key);
537 if (i != newQmlTypeMaps_.constEnd())
539 return emptyNodeMap_;
543 Find the \a key in the map of new \e {since} maps, and return
544 a reference to the value, which is a NodeMultiMap. If \a key
545 is not found, return a reference to an empty NodeMultiMap.
547 const NodeMultiMap& QDocDatabase::getSinceMap(const QString& key) const
549 NodeMultiMapMap::const_iterator i = newSinceMaps_.constFind(key);
550 if (i != newSinceMaps_.constEnd())
552 return emptyNodeMultiMap_;
556 Performs several housekeeping algorithms that create
557 certain data structures and resolve lots of links, prior
558 to generating documentation.
560 void QDocDatabase::resolveIssues() {
561 tree_->resolveGroups();
562 resolveTargets(treeRoot());
563 tree_->resolveCppToQmlLinks();
567 Look up group \a name in the map of groups. If found, populate
568 the node map \a group with the classes in the group that are
569 not marked internal or private.
571 void QDocDatabase::getGroup(const QString& name, NodeMap& group) const
574 NodeList values = tree_->groups().values(name);
575 for (int i=0; i<values.size(); ++i) {
576 const Node* n = values.at(i);
577 if ((n->status() != Node::Internal) && (n->access() != Node::Private)) {
578 group.insert(n->nameForLists(),n);
584 Searches the \a database for a node named \a target and returns
585 a pointer to it if found.
587 const Node* QDocDatabase::resolveTarget(const QString& target,
588 const Node* relative,
591 const Node* node = 0;
592 if (target.endsWith("()")) {
593 QString funcName = target;
595 QStringList path = funcName.split("::");
596 const FunctionNode* fn = tree_->findFunctionNode(path, relative, SearchBaseClasses);
599 Why is this case not accepted?
601 if (fn->metaness() != FunctionNode::MacroWithoutParams)
605 else if (target.contains(QLatin1Char('#'))) {
606 // This error message is never printed; I think we can remove the case.
607 qDebug() << "qdoc: target case not handled:" << target;
610 QStringList path = target.split("::");
611 int flags = SearchBaseClasses | SearchEnumValues | NonFunction;
612 node = tree_->findNode(path, relative, flags, self);
618 Finds the node that will generate the documentation that
619 contains the \a target and returns a pointer to it.
621 const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* relative)
623 const Node* node = 0;
624 if (target.isEmpty())
626 else if (target.endsWith(".html"))
627 node = tree_->root()->findChildNodeByNameAndType(target, Node::Document);
629 node = resolveTarget(target, relative);
631 node = findDocNodeByTitle(target, relative);
637 Inserts a new target into the target table with the specified
638 \a name, \a node, and \a priority.
640 void QDocDatabase::insertTarget(const QString& name, Node* node, int priority)
644 target.priority_ = priority;
645 Atom a = Atom(Atom::Target, name);
646 target.ref_ = refForAtom(&a);
647 targetMultiMap_.insert(name, target);
651 This function searches for a \a target anchor node. If it
652 finds one, it sets \a ref and returns the found node.
655 QDocDatabase::findUnambiguousTarget(const QString& target, QString& ref, const Node* relative)
658 int numBestTargets = 0;
659 QList<Target> bestTargetList;
661 QString key = Doc::canonicalTitle(target);
662 TargetMultiMap::iterator i = targetMultiMap_.find(key);
663 while (i != targetMultiMap_.end()) {
666 const Target& candidate = i.value();
667 if (candidate.priority_ < bestTarget.priority_) {
668 bestTarget = candidate;
669 bestTargetList.clear();
670 bestTargetList.append(candidate);
672 } else if (candidate.priority_ == bestTarget.priority_) {
673 bestTargetList.append(candidate);
678 if (numBestTargets > 0) {
679 if (numBestTargets == 1) {
680 ref = bestTarget.ref_;
681 return bestTarget.node_;
683 else if (bestTargetList.size() > 1) {
684 if (relative && !relative->qmlModuleIdentifier().isEmpty()) {
685 for (int i=0; i<bestTargetList.size(); ++i) {
686 const Node* n = bestTargetList.at(i).node_;
687 if (n && relative->qmlModuleIdentifier() == n->qmlModuleIdentifier()) {
688 ref = bestTargetList.at(i).ref_;
700 This function searches for a node with the specified \a title.
701 If \a relative node is provided, it is used to disambiguate if
702 it has a QML module identifier.
704 const DocNode* QDocDatabase::findDocNodeByTitle(const QString& title, const Node* relative) const
706 QString key = Doc::canonicalTitle(title);
707 DocNodeMultiMap::const_iterator i = docNodesByTitle_.constFind(key);
708 if (i != docNodesByTitle_.constEnd()) {
709 if (relative && !relative->qmlModuleIdentifier().isEmpty()) {
710 const DocNode* dn = i.value();
711 InnerNode* parent = dn->parent();
712 if (parent && parent->type() == Node::Document && parent->subType() == Node::Collision) {
713 const NodeList& nl = parent->childNodes();
714 NodeList::ConstIterator it = nl.constBegin();
715 while (it != nl.constEnd()) {
716 if ((*it)->qmlModuleIdentifier() == relative->qmlModuleIdentifier()) {
718 By returning here, we avoid printing all the duplicate
719 header warnings, which are not really duplicates now,
720 because of the QML module identifier being used as a
723 dn = static_cast<const DocNode*>(*it);
731 Reporting all these duplicate section titles is probably
732 overkill. We should report the duplicate file and let
735 DocNodeMultiMap::const_iterator j = i;
737 if (j != docNodesByTitle_.constEnd() && j.key() == i.key()) {
738 QList<Location> internalLocations;
739 while (j != docNodesByTitle_.constEnd()) {
740 if (j.key() == i.key() && j.value()->url().isEmpty())
741 internalLocations.append(j.value()->location());
744 if (internalLocations.size() > 0) {
745 i.value()->location().warning(tr("This page exists in more than one file: \"%1\"").arg(title));
746 foreach (const Location &location, internalLocations)
747 location.warning(tr("[It also exists here]"));
756 This function searches for a node with a canonical title
757 constructed from \a target. If the node it finds is \a node,
758 it returns the ref from that node. Otherwise it returns an
761 QString QDocDatabase::findTarget(const QString& target, const Node* node) const
763 QString key = Doc::canonicalTitle(target);
764 TargetMultiMap::const_iterator i = targetMultiMap_.constFind(key);
766 if (i != targetMultiMap_.constEnd()) {
768 if (i.value().node_ == node)
769 return i.value().ref_;
771 } while (i != targetMultiMap_.constEnd() && i.key() == key);
778 void QDocDatabase::resolveTargets(InnerNode* root)
782 foreach (Node* child, root->childNodes()) {
783 if (child->type() == Node::Document) {
784 DocNode* node = static_cast<DocNode*>(child);
785 if (!node->title().isEmpty()) {
786 QString key = Doc::canonicalTitle(node->title());
787 docNodesByTitle_.insert(key, node);
789 if (node->subType() == Node::Collision) {
790 resolveTargets(node);
794 if (child->doc().hasTableOfContents()) {
795 const QList<Atom*>& toc = child->doc().tableOfContents();
797 target.node_ = child;
798 target.priority_ = 3;
800 for (int i = 0; i < toc.size(); ++i) {
801 target.ref_ = refForAtom(toc.at(i));
802 QString title = Text::sectionHeading(toc.at(i)).toString();
803 if (!title.isEmpty()) {
804 QString key = Doc::canonicalTitle(title);
805 targetMultiMap_.insert(key, target);
809 if (child->doc().hasKeywords()) {
810 const QList<Atom*>& keywords = child->doc().keywords();
812 target.node_ = child;
813 target.priority_ = 1;
815 for (int i = 0; i < keywords.size(); ++i) {
816 target.ref_ = refForAtom(keywords.at(i));
817 QString key = Doc::canonicalTitle(keywords.at(i)->string());
818 targetMultiMap_.insert(key, target);
821 if (child->doc().hasTargets()) {
822 const QList<Atom*>& toc = child->doc().targets();
824 target.node_ = child;
825 target.priority_ = 2;
827 for (int i = 0; i < toc.size(); ++i) {
828 target.ref_ = refForAtom(toc.at(i));
829 QString key = Doc::canonicalTitle(toc.at(i)->string());
830 targetMultiMap_.insert(key, target);
837 Generates a tag file and writes it to \a name.
839 void QDocDatabase::generateTagFile(const QString& name, Generator* g)
841 if (!name.isEmpty()) {
842 QDocTagFiles::qdocTagFiles()->generateTagFile(name, g);
843 QDocTagFiles::destroyQDocTagFiles();
848 Reads and parses the qdoc index files listed in \a indexFiles.
850 void QDocDatabase::readIndexes(const QStringList& indexFiles)
852 QDocIndexFiles::qdocIndexFiles()->readIndexes(indexFiles);
853 QDocIndexFiles::destroyQDocIndexFiles();
857 Generates a qdoc index file and write it to \a fileName. The
858 index file is generated with the parameters \a url, \a title,
859 \a g, and \a generateInternalNodes.
861 void QDocDatabase::generateIndex(const QString& fileName,
863 const QString& title,
865 bool generateInternalNodes)
867 QDocIndexFiles::qdocIndexFiles()->generateIndex(fileName, url, title, g, generateInternalNodes);
868 QDocIndexFiles::destroyQDocIndexFiles();
871 QString QDocDatabase::refForAtom(const Atom* atom)
874 if (atom->type() == Atom::SectionLeft)
875 return Doc::canonicalTitle(Text::sectionHeading(atom).toString());
876 if (atom->type() == Atom::Target)
877 return Doc::canonicalTitle(atom->string());