summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/tools/qdoc/atom.cpp51
-rw-r--r--src/tools/qdoc/atom.h39
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.cpp230
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.h4
-rw-r--r--src/tools/qdoc/doc.cpp17
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp237
-rw-r--r--src/tools/qdoc/htmlgenerator.h5
-rw-r--r--src/tools/qdoc/main.cpp2
-rw-r--r--src/tools/qdoc/node.cpp8
-rw-r--r--src/tools/qdoc/node.h4
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp124
-rw-r--r--src/tools/qdoc/qdocdatabase.h18
-rw-r--r--src/tools/qdoc/qdocindexfiles.cpp190
-rw-r--r--src/tools/qdoc/qdocindexfiles.h2
-rw-r--r--src/tools/qdoc/text.cpp16
-rw-r--r--src/tools/qdoc/text.h1
-rw-r--r--src/tools/qdoc/tree.cpp33
-rw-r--r--src/tools/qdoc/tree.h1
18 files changed, 551 insertions, 431 deletions
diff --git a/src/tools/qdoc/atom.cpp b/src/tools/qdoc/atom.cpp
index 8816ea5d6f..5c699b0546 100644
--- a/src/tools/qdoc/atom.cpp
+++ b/src/tools/qdoc/atom.cpp
@@ -374,22 +374,51 @@ void Atom::dump() const
contains some search parameters.
*/
LinkAtom::LinkAtom(const QString& p1, const QString& p2)
- : Atom(Link, p1), qml_(false), goal_(Node::NoType), domain_(0)
+ : Atom(p1), genus_(DontCare), goal_(Node::NoType), domain_(0)
{
QStringList params = p2.toLower().split(QLatin1Char(' '));
foreach (const QString& p, params) {
- if (p == "qml")
- qml_ = true;
- else {
- if (!domain_) {
- domain_ = QDocDatabase::qdocDB()->findTree(p);
- if (domain_)
- continue;
- }
- if (goal_ == Node::NoType)
- goal_ = Node::goal(p);
+ if (!domain_) {
+ domain_ = QDocDatabase::qdocDB()->findTree(p);
+ if (domain_)
+ continue;
+ }
+ if (goal_ == Node::NoType) {
+ goal_ = Node::goal(p);
+ if (goal_ != Node::NoType)
+ continue;
}
+ if (p == "qml")
+ genus_ = QML;
+ else if (p == "cpp")
+ genus_ = CPP;
}
}
+/*!
+ Standard copy constructor of LinkAtom \a t.
+ */
+LinkAtom::LinkAtom(const LinkAtom& t)
+ : Atom(Link, t.string()),
+ genus_(t.genus_),
+ goal_(t.goal_),
+ domain_(t.domain_)
+{
+ // nothing
+}
+
+/*!
+ Special copy constructor of LinkAtom \a t, where
+ where the new LinkAtom will not be the first one
+ in the list.
+ */
+LinkAtom::LinkAtom(Atom* previous, const LinkAtom& t)
+ : Atom(previous, Link, t.string()),
+ genus_(t.genus_),
+ goal_(t.goal_),
+ domain_(t.domain_)
+{
+ previous->next_ = this;
+}
+
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/atom.h b/src/tools/qdoc/atom.h
index 999919482b..36a7390ae2 100644
--- a/src/tools/qdoc/atom.h
+++ b/src/tools/qdoc/atom.h
@@ -44,10 +44,12 @@
#include <qstringlist.h>
#include "node.h"
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
class Tree;
+class LinkAtom;
class Atom
{
@@ -63,7 +65,7 @@ public:
BriefRight,
C,
CaptionLeft,
- CaptionRight,
+ CaptionRight, // 10
Code,
CodeBad,
CodeNew,
@@ -73,7 +75,7 @@ public:
DivLeft,
DivRight,
EndQmlText,
- FootnoteLeft,
+ FootnoteLeft, // 20
FootnoteRight,
FormatElse,
FormatEndif,
@@ -83,7 +85,7 @@ public:
GeneratedList,
GuidLink,
HR,
- Image,
+ Image, // 30
ImageText,
ImportantLeft,
ImportantRight,
@@ -93,7 +95,7 @@ public:
LegaleseLeft,
LegaleseRight,
LineBreak,
- Link,
+ Link, // 40
LinkNode,
ListLeft,
ListItemNumber,
@@ -103,7 +105,7 @@ public:
ListItemRight,
ListRight,
Nop,
- NoteLeft,
+ NoteLeft, // 50
NoteRight,
ParaLeft,
ParaRight,
@@ -113,7 +115,7 @@ public:
QuotationRight,
RawString,
SectionLeft,
- SectionRight,
+ SectionRight, // 60
SectionHeadingLeft,
SectionHeadingRight,
SidebarLeft,
@@ -123,7 +125,7 @@ public:
SnippetIdentifier,
SnippetLocation,
String,
- TableLeft,
+ TableLeft, // 70
TableRight,
TableHeaderLeft,
TableHeaderRight,
@@ -133,11 +135,21 @@ public:
TableItemRight,
TableOfContents,
Target,
- UnhandledFormat,
+ UnhandledFormat, // 80
UnknownCommand,
Last = UnknownCommand
};
+ enum NodeGenus { DontCare, CPP, QML };
+
+ friend class LinkAtom;
+
+ Atom(const QString& string)
+ : next_(0), type_(Link)
+ {
+ strs << string;
+ }
+
Atom(Type type, const QString& string = "")
: next_(0), type_(type)
{
@@ -186,8 +198,10 @@ public:
const QString& string(int i) const { return strs[i]; }
int count() const { return strs.size(); }
void dump() const;
+ const QStringList& strings() const { return strs; }
- virtual bool qml() const { return false; }
+ virtual bool isLinkAtom() const { return false; }
+ virtual NodeGenus genus() const { return DontCare; }
virtual bool specifiesDomain() const { return false; }
virtual Tree* domain() const { return 0; }
virtual Node::Type goal() const { return Node::NoType; }
@@ -202,15 +216,18 @@ class LinkAtom : public Atom
{
public:
LinkAtom(const QString& p1, const QString& p2);
+ LinkAtom(const LinkAtom& t);
+ LinkAtom(Atom* previous, const LinkAtom& t);
virtual ~LinkAtom() { }
- virtual bool qml() const { return qml_; }
+ virtual bool isLinkAtom() const { return true; }
+ virtual NodeGenus genus() const { return genus_; }
virtual bool specifiesDomain() const { return (domain_ != 0); }
virtual Tree* domain() const { return domain_; }
virtual Node::Type goal() const { return goal_; }
protected:
- bool qml_;
+ NodeGenus genus_;
Node::Type goal_;
Tree* domain_;
};
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index bbd32204ce..c2a5cdb8b8 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -765,7 +765,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
case Atom::AutoLink:
if (!noLinks && !inLink_ && !inContents_ && !inSectionHeading_) {
const Node* node = 0;
- QString link = getLink(atom, relative, &node);
+ QString link = getAutoLink(atom, relative, &node);
if (!link.isEmpty()) {
beginLink(link);
generateLink(atom, marker);
@@ -1308,13 +1308,11 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
case Atom::Link:
{
const Node *node = 0;
- QString myLink = getLink(atom, relative, &node);
- //if (myLink.isEmpty())
- //myLink = getCollisionLink(atom);
- if (myLink.isEmpty() && !noLinkErrors())
+ QString link = getLink(atom, relative, &node);
+ if (link.isEmpty() && !noLinkErrors())
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
else if (!inSectionHeading_)
- beginLink(myLink);
+ beginLink(link);
skipAhead = 1;
}
break;
@@ -3722,6 +3720,129 @@ QString DitaXmlGenerator::fileName(const Node* node)
return Generator::fileName(node);
}
+/*!
+ This function is called for links, i.e. for words that
+ are marked with the qdoc link command. For autolinks
+ that are not marked with the qdoc link command, qdoc
+ calls getAutoLink().
+
+ Return the link represented by the \a atom, and set \a node
+ to point to the target node for that link. \a relative points
+ to the node holding the qdoc comment where the link command
+ was found.
+ */
+QString DitaXmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node)
+{
+ if (atom->string().contains(QLatin1Char(':')) && (atom->string().startsWith("file:") ||
+ atom->string().startsWith("http:") ||
+ atom->string().startsWith("https:") ||
+ atom->string().startsWith("ftp:") ||
+ atom->string().startsWith("mailto:"))) {
+ return atom->string(); // It's some kind of protocol.
+ }
+
+ QString ref;
+ QString link;
+ QStringList path = atom->string().split("#");
+ QString first = path.first().trimmed();
+
+ *node = 0;
+ if (first.isEmpty())
+ *node = relative; // search for a target on the current page.
+ else {
+ if (first.endsWith(".html")) { // The target is an html file.
+ *node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document);
+ }
+ else if (first.endsWith("()")) { // The target is a C++ function or QML method.
+ *node = qdb_->resolveFunctionTarget(first, relative);
+ }
+ else {
+ *node = qdb_->resolveTarget(first, relative);
+ if (!(*node))
+ *node = qdb_->findDocNodeByTitle(first);
+ if (!(*node)) {
+ *node = qdb_->findUnambiguousTarget(first, ref);
+ if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
+ QString final = (*node)->url() + "#" + ref;
+ return final;
+ }
+ }
+ }
+ }
+ if (!(*node))
+ return link; // empty
+
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
+
+ if (!path.isEmpty()) {
+ ref = qdb_->findTarget(path.first(), *node);
+ if (ref.isEmpty())
+ return link; // empty
+ }
+
+ /*
+ Given that *node is not null, we now cconstruct a link
+ to the page that *node represents, and then if we found
+ a target on that page, we connect the target to the link
+ with '#'.
+ */
+ link = linkForNode(*node, relative);
+ if (*node && (*node)->subType() == Node::Image)
+ link = "images/used-in-examples/" + link;
+ if (!ref.isEmpty())
+ link += QLatin1Char('#') + ref;
+ return link;
+}
+
+/*!
+ This function is called for autolinks, i.e. for words that
+ are not marked with the qdoc link command that qdoc has
+ reason to believe should be links. For links marked with
+ the qdoc link command, qdoc calls getLink().
+
+ Return the link represented by the \a atom, and set \a node
+ to point to the target node for that link. \a relative points
+ to the node holding the qdoc comment where the link command
+ was found.
+ */
+QString DitaXmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node** node)
+{
+ QString ref;
+ QString link;
+ QString target = atom->string().trimmed();
+ *node = 0;
+
+ if (target.endsWith("()")) { // The target is a C++ function or QML method.
+ *node = qdb_->resolveFunctionTarget(target, relative);
+ }
+ else {
+ *node = qdb_->resolveTarget(target, relative);
+ if (!(*node)) {
+ *node = qdb_->findDocNodeByTitle(target);
+ }
+ if (!(*node)) {
+ *node = qdb_->findUnambiguousTarget(target, ref);
+ if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
+ QString final = (*node)->url() + "#" + ref;
+ return final;
+ }
+ }
+ }
+
+ if (!(*node))
+ return link; // empty
+
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
+
+ link = linkForNode(*node, relative);
+ if (!ref.isEmpty())
+ link += QLatin1Char('#') + ref;
+ return link;
+}
+
+
QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
{
if (node == 0 || node == relative)
@@ -3832,103 +3953,6 @@ const QPair<QString,QString> DitaXmlGenerator::anchorForNode(const Node* node)
return anchorPair;
}
-QString DitaXmlGenerator::getLink(const Atom* atom, const Node* relative, const Node** node)
-{
- QString link;
- *node = 0;
- inObsoleteLink = false;
-
- if (atom->string().contains(QLatin1Char(':')) &&
- (atom->string().startsWith("file:")
- || atom->string().startsWith("http:")
- || atom->string().startsWith("https:")
- || atom->string().startsWith("ftp:")
- || atom->string().startsWith("mailto:"))) {
-
- link = atom->string();
- }
- else {
- QStringList path;
- if (atom->string().contains('#'))
- path = atom->string().split('#');
- else
- path.append(atom->string());
-
- QString ref;
- QString first = path.first().trimmed();
-
- if (first.isEmpty())
- *node = relative;
- else if (first.endsWith(".html"))
- *node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document);
- else if (first.endsWith("()")) // The target is a C++ function or QML method.
- *node = qdb_->resolveFunctionTarget(first, relative);
- else {
- *node = qdb_->resolveTarget(first, relative);
- if (!(*node))
- *node = qdb_->findDocNodeByTitle(first);
- if (!*node)
- *node = qdb_->findUnambiguousTarget(first, ref);
- }
-
- if (*node) {
- if (!(*node)->url().isEmpty())
- return (*node)->url();
- else
- path.removeFirst();
- }
- else
- *node = relative;
-
- if (*node && (*node)->status() == Node::Obsolete) {
- if (relative && (relative->parent() != *node) &&
- (relative->status() != Node::Obsolete)) {
- bool porting = false;
- if (relative->isDocNode()) {
- const DocNode* fake = static_cast<const DocNode*>(relative);
- if (fake->title().startsWith("Porting"))
- porting = true;
- }
- QString name = relative->plainFullName();
- if (!porting && !name.startsWith("Q3")) {
- if (obsoleteLinks) {
- relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
- .arg(atom->string())
- .arg(name));
- }
- inObsoleteLink = true;
- }
- }
- }
-
- while (!path.isEmpty()) {
- ref = qdb_->findTarget(path.first(), *node);
- if (ref.isEmpty())
- break;
- path.removeFirst();
- }
-
- if (path.isEmpty()) {
- link = linkForNode(*node, relative);
- if (*node && (*node)->subType() == Node::Image)
- link = "images/used-in-examples/" + link;
- if (!ref.isEmpty()) {
- if (link.isEmpty())
- link = outFileName();
- QString guid = lookupGuid(link, ref);
- link += QLatin1Char('#') + guid;
- }
- else if (!link.isEmpty() && *node && (link.endsWith(".xml") || link.endsWith(".dita"))) {
- link += QLatin1Char('#') + (*node)->guid();
- }
- }
- }
- if (!link.isEmpty() && link[0] == '#') {
- link.prepend(outFileName());
- }
- return link;
-}
-
void DitaXmlGenerator::generateStatus(const Node* node, CodeMarker* marker)
{
Text text;
diff --git a/src/tools/qdoc/ditaxmlgenerator.h b/src/tools/qdoc/ditaxmlgenerator.h
index 0239151402..d4264d948c 100644
--- a/src/tools/qdoc/ditaxmlgenerator.h
+++ b/src/tools/qdoc/ditaxmlgenerator.h
@@ -425,12 +425,14 @@ private:
void generateLink(const Atom* atom, CodeMarker* marker);
void generateStatus(const Node* node, CodeMarker* marker);
+ QString getLink(const Atom *atom, const Node *relative, const Node** node);
+ QString getAutoLink(const Atom *atom, const Node *relative, const Node** node);
+
QString registerRef(const QString& ref);
virtual QString fileBase(const Node *node) const;
QString fileName(const Node *node);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
- QString getLink(const Atom *atom, const Node *relative, const Node **node);
#ifdef GENERATE_MAC_REFS
void generateMacRef(const Node* node, CodeMarker* marker);
#endif
diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp
index 4fe0972d72..5745b094d5 100644
--- a/src/tools/qdoc/doc.cpp
+++ b/src/tools/qdoc/doc.cpp
@@ -475,6 +475,7 @@ private:
void startSection(Doc::Sections unit, int cmd);
void endSection(int unit, int endCmd);
void parseAlso();
+ void append(const QString &string);
void append(Atom::Type type, const QString& string = QString());
void append(Atom::Type type, const QString& p1, const QString& p2);
void append(const QString& p1, const QString& p2);
@@ -968,8 +969,9 @@ void DocParser::parse(const QString& source,
break;
case CMD_L:
enterPara();
- if (isLeftBracketAhead())
+ if (isLeftBracketAhead()) {
p2 = getBracketedArgument();
+ }
if (isLeftBraceAhead()) {
p1 = getArgument();
append(p1, p2);
@@ -990,6 +992,7 @@ void DocParser::parse(const QString& source,
append(Atom::String, cleanLink(p1));
append(Atom::FormattingRight, ATOM_FORMATTING_LINK);
}
+ p2.clear();
break;
case CMD_LEGALESE:
leavePara();
@@ -1001,7 +1004,7 @@ void DocParser::parse(const QString& source,
if (openCommand(cmd)) {
enterPara();
p1 = getArgument();
- append(Atom::Link, p1);
+ append(p1);
append(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
skipSpacesOrOneEndl();
}
@@ -1981,6 +1984,14 @@ void DocParser::append(Atom::Type type, const QString &string)
priv->text << Atom(type, string);
}
+void DocParser::append(const QString &string)
+{
+ Atom::Type lastType = priv->text.lastAtom()->type();
+ if ((lastType == Atom::Code) && priv->text.lastAtom()->string().endsWith(QLatin1String("\n\n")))
+ priv->text.lastAtom()->chopString();
+ priv->text << Atom(string);
+}
+
void DocParser::append(Atom::Type type, const QString& p1, const QString& p2)
{
Atom::Type lastType = priv->text.lastAtom()->type();
@@ -1995,7 +2006,7 @@ void DocParser::append(const QString& p1, const QString& p2)
if ((lastType == Atom::Code) && priv->text.lastAtom()->string().endsWith(QLatin1String("\n\n")))
priv->text.lastAtom()->chopString();
if (p2.isEmpty())
- priv->text << Atom(Atom::Link, p1, p2);
+ priv->text << Atom(p1);
else
priv->text << LinkAtom(p1, p2);
}
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index b27968982a..f5e2e6309e 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -3649,6 +3649,112 @@ QString HtmlGenerator::refForNode(const Node *node)
#define DEBUG_ABSTRACT 0
/*!
+ This function is called for links, i.e. for words that
+ are marked with the qdoc link command. For autolinks
+ that are not marked with the qdoc link command, the
+ getAutoLink() function is called
+
+ It returns the string for a link found by using the data
+ in the \a atom to search the database. It also sets \a node
+ to point to the target node for that link. \a relative points
+ to the node holding the qdoc comment where the link command
+ was found.
+ */
+QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node)
+{
+ const QString& t = atom->string();
+ if (t.at(0) == QChar('h')) {
+ if (t.startsWith("http:") || t.startsWith("https:"))
+ return t;
+ }
+ else if (t.at(0) == QChar('f')) {
+ if (t.startsWith("file:") || t.startsWith("ftp:"))
+ return t;
+ }
+ else if (t.at(0) == QChar('m')) {
+ if (t.startsWith("mailto:"))
+ return t;
+ }
+
+ QString ref;
+
+ *node = qdb_->findNode(atom, relative, ref);
+ if (!(*node))
+ return QString();
+
+ QString url = (*node)->url();
+ if (!url.isEmpty()) {
+ if (ref.isEmpty())
+ return url;
+ int hashtag = url.lastIndexOf(QChar('#'));
+ if (hashtag != -1)
+ url.truncate(hashtag);
+ return url + "#" + ref;
+ }
+ /*
+ Given that *node is not null, we now cconstruct a link
+ to the page that *node represents, and then if we found
+ a target on that page, we connect the target to the link
+ with '#'.
+ */
+ QString link = linkForNode(*node, relative);
+ if (*node && (*node)->subType() == Node::Image)
+ link = "images/used-in-examples/" + link;
+ if (!ref.isEmpty())
+ link += QLatin1Char('#') + ref;
+ return link;
+}
+
+/*!
+ This function is called for autolinks, i.e. for words that
+ are not marked with the qdoc link command that qdoc has
+ reason to believe should be links. For links marked with
+ the qdoc link command, the getLink() function is called.
+
+ It returns the string for a link found by using the data
+ in the \a atom to search the database. It also sets \a node
+ to point to the target node for that link. \a relative points
+ to the node holding the qdoc comment where the link command
+ was found.
+ */
+QString HtmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node** node)
+{
+ QString ref;
+ QString link;
+ QString target = atom->string().trimmed();
+ *node = 0;
+
+ if (target.endsWith("()")) { // The target is a C++ function or QML method.
+ *node = qdb_->resolveFunctionTarget(target, relative);
+ }
+ else {
+ *node = qdb_->resolveTarget(target, relative);
+ if (!(*node)) {
+ *node = qdb_->findDocNodeByTitle(target);
+ }
+ if (!(*node)) {
+ *node = qdb_->findUnambiguousTarget(target, ref);
+ if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
+ QString final = (*node)->url() + "#" + ref;
+ return final;
+ }
+ }
+ }
+
+ if (!(*node))
+ return link; // empty
+
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
+
+ link = linkForNode(*node, relative);
+ if (!ref.isEmpty())
+ link += QLatin1Char('#') + ref;
+ return link;
+}
+
+
+/*!
Construct the link string for the \a node and return it.
The \a relative node is use to decide the link we are
generating is in the same file as the target. Note the
@@ -3847,137 +3953,6 @@ const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node)
return anchorPair;
}
-/*!
- This function is called for links, i.e. for words that
- are marked with the qdoc link command. For autolinks
- that are not marked with the qdoc link command, qdoc
- calls getAutoLink().
-
- Return the link represented by the \a atom, and set \a node
- to point to the target node for that link. \a relative points
- to the node holding the qdoc comment where the link command
- was found.
- */
-QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node)
-{
- if (atom->string().contains(QLatin1Char(':')) && (atom->string().startsWith("file:") ||
- atom->string().startsWith("http:") ||
- atom->string().startsWith("https:") ||
- atom->string().startsWith("ftp:") ||
- atom->string().startsWith("mailto:"))) {
- return atom->string(); // It's some kind of protocol.
- }
-
- QString ref;
- QString link;
- QString first;
- QStringList path;
-
- *node = 0;
- if (atom->string().contains('#')) {
- path = atom->string().split('#');
- first = path.first().trimmed();
- path.removeFirst();
- }
- else
- first = atom->string();
-
- if (first.isEmpty())
- *node = relative; // search for a target on the current page.
- else {
- if (first.endsWith(".html")) { // The target is an html file.
- *node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document);
- //Node* n = qdb_->findHtmlFileNode(atom);
- }
- else if (first.endsWith("()")) { // The target is a C++ function or QML method.
- *node = qdb_->resolveFunctionTarget(first, relative);
- }
- else {
- *node = qdb_->resolveTarget(first, relative);
- if (!(*node))
- *node = qdb_->findDocNodeByTitle(first);
- if (!(*node)) {
- *node = qdb_->findUnambiguousTarget(first, ref);
- if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
- QString final = (*node)->url() + "#" + ref;
- return final;
- }
- }
- }
- }
- if (!(*node))
- return link; // empty
-
- if (!(*node)->url().isEmpty())
- return (*node)->url();
-
- if (!path.isEmpty()) {
- ref = qdb_->findTarget(path.first(), *node);
- if (ref.isEmpty())
- return link; // empty
- }
-
- /*
- Given that *node is not null, we now cconstruct a link
- to the page that *node represents, and then if we found
- a target on that page, we connect the target to the link
- with '#'.
- */
- link = linkForNode(*node, relative);
- if (*node && (*node)->subType() == Node::Image)
- link = "images/used-in-examples/" + link;
- if (!ref.isEmpty())
- link += QLatin1Char('#') + ref;
- return link;
-}
-
-/*!
- This function is called for autolinks, i.e. for words that
- are not marked with the qdoc link command that qdoc has
- reason to believe should be links. For links marked with
- the qdoc link command, qdoc calls getLink().
-
- Return the link represented by the \a atom, and set \a node
- to point to the target node for that link. \a relative points
- to the node holding the qdoc comment where the link command
- was found.
- */
-QString HtmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node** node)
-{
- QString ref;
- QString link;
- QString path = atom->string().trimmed();
- *node = 0;
-
- if (path.endsWith("()")) { // The target is a C++ function or QML method.
- *node = qdb_->resolveFunctionTarget(path, relative);
- }
- else {
- *node = qdb_->resolveTarget(path, relative);
- if (!(*node)) {
- *node = qdb_->findDocNodeByTitle(path);
- }
- if (!(*node)) {
- *node = qdb_->findUnambiguousTarget(path, ref);
- if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
- QString final = (*node)->url() + "#" + ref;
- return final;
- }
- }
- }
-
- if (!(*node))
- return link; // empty
-
- if (!(*node)->url().isEmpty())
- return (*node)->url();
-
- link = linkForNode(*node, relative);
- if (!ref.isEmpty())
- link += QLatin1Char('#') + ref;
- return link;
-}
-
void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker)
{
Text text;
diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h
index 787b34daf2..ef569b38ce 100644
--- a/src/tools/qdoc/htmlgenerator.h
+++ b/src/tools/qdoc/htmlgenerator.h
@@ -211,13 +211,14 @@ private:
void generateLink(const Atom *atom, CodeMarker *marker);
void generateStatus(const Node *node, CodeMarker *marker);
+ QString getLink(const Atom *atom, const Node *relative, const Node** node);
+ QString getAutoLink(const Atom *atom, const Node *relative, const Node** node);
+
QString registerRef(const QString& ref);
virtual QString fileBase(const Node *node) const;
QString fileName(const Node *node);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
- QString getLink(const Atom *atom, const Node *relative, const Node** node);
- QString getAutoLink(const Atom *atom, const Node *relative, const Node** node);
#ifdef GENERATE_MAC_REFS
void generateMacRef(const Node *node, CodeMarker *marker);
#endif
diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp
index 21ca2c4820..aba9956604 100644
--- a/src/tools/qdoc/main.cpp
+++ b/src/tools/qdoc/main.cpp
@@ -292,7 +292,7 @@ static void processQdocconfFile(const QString &fileName)
Location::initialize(config);
config.load(fileName);
QString project = config.getString(CONFIG_PROJECT).toLower();
- //qDebug() << "\nSTART PROJECT:" << project;
+ //qDebug() << "\nStart project:" << project;
/*
Add the defines to the configuration variables.
*/
diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp
index fd610dedb6..03b798cbb3 100644
--- a/src/tools/qdoc/node.cpp
+++ b/src/tools/qdoc/node.cpp
@@ -687,6 +687,14 @@ bool Node::isInternal() const
}
/*!
+ Returns a pointer to the Tree this node is in.
+ */
+Tree* Node::tree() const
+{
+ return (parent() ? parent()->tree() : 0);
+}
+
+/*!
Returns a pointer to the root of the Tree this node is in.
*/
const Node* Node::root() const
diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h
index ebdaad9010..4f9097d774 100644
--- a/src/tools/qdoc/node.h
+++ b/src/tools/qdoc/node.h
@@ -248,7 +248,7 @@ public:
virtual bool wasSeen() const { return false; }
virtual void appendGroupName(const QString& ) { }
virtual QString element() const { return QString(); }
- virtual Tree* tree() const { return 0; }
+ virtual Tree* tree() const;
bool isIndexNode() const { return indexNodeFlag_; }
Type type() const { return nodeType_; }
virtual SubType subType() const { return NoSubType; }
@@ -440,7 +440,7 @@ public:
NamespaceNode(InnerNode* parent, const QString& name);
virtual ~NamespaceNode() { }
virtual bool isNamespace() const { return true; }
- virtual Tree* tree() const { return tree_; }
+ virtual Tree* tree() const { return (parent() ? parent()->tree() : tree_); }
void setTree(Tree* t) { tree_ = t; }
private:
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp
index 8bf83ca796..8f28e38431 100644
--- a/src/tools/qdoc/qdocdatabase.cpp
+++ b/src/tools/qdoc/qdocdatabase.cpp
@@ -384,7 +384,7 @@ void QDocForest::newPrimaryTree(const QString& module)
point, but it only makes sense in the primary tree, which is
searched first. After the primary tree is searched, \a relative
is set to 0 for searching the index trees. When relative is 0,
- the root node of the index tree is the starting point.
+ the root nodes of the index trees are the starting points.
*/
const Node* QDocForest::resolveTarget(const QString& target, const Node* relative)
{
@@ -395,11 +395,6 @@ const Node* QDocForest::resolveTarget(const QString& target, const Node* relativ
const Node* n = t->findNode(path, relative, flags);
if (n)
return n;
-#if 0
- n = t->findDocNodeByTitle(target);
- if (n)
- return n;
-#endif
relative = 0;
}
return 0;
@@ -1567,67 +1562,86 @@ void QDocDatabase::mergeCollections(CollectionNode* cn)
}
}
-QT_END_NAMESPACE
-
-#if 0
- void getAllGroups(CNMM& t);
- void getAllModules(CNMM& t);
- void getAllQmlModules(CNMM& t);
/*!
- For each tree in the forest, get the group map from the tree.
- Insert each pair from the group map into the collection node
- multimap \a t.
+ This function is called when the \a{atom} might be a link
+ atom. It handles the optional, square bracket parameters
+ for the link command.
*/
-void QDocForest::getAllGroups(CNMM& t)
+Node* QDocDatabase::findNode(const Atom* atom)
{
- foreach (Tree* t, searchOrder()) {
- const GroupMap& gm = t->groups();
- if (!gm.isEmpty()) {
- GroupMap::const_iterator i = gm.begin();
- while (i != gm.end()) {
- t.insert(i.key(), i.value());
- ++i;
- }
- }
+ QStringList path(atom->string());
+ if (atom->specifiesDomain()) {
+ return atom->domain()->findNodeByNameAndType(path, atom->goal());
}
+ qDebug() << "FINDNODE:" << path << atom->goal();
+ return forest_.findNodeByNameAndType(path, atom->goal());
}
-/*!
- For each tree in the forest, get the module map from the tree.
- Insert each pair from the module map into the collection node
- multimap \a t.
- */
-void QDocForest::getAllModules(CNMM& t)
+const DocNode* QDocDatabase::findDocNodeByTitle(const Atom* atom)
{
- foreach (Tree* t, searchOrder()) {
- const ModuleMap& mm = t->modules();
- if (!mm.isEmpty()) {
- ModuleMap::const_iterator i = mm.begin();
- while (i != mm.end()) {
- t.insert(i.key(), i.value());
- ++i;
- }
- }
- }
+ return forest_.findDocNodeByTitle(atom->string());
}
/*!
- For each tree in the forest, get the QML module map from the
- tree. Insert each pair from the QML module map into the
- collection node multimap \a t.
- */
-void QDocForest::getAllQmlModules(CNMM& t)
+ Searches for the node that matches the path in \a atom. The
+ \a relative node is used if the first leg of the path is
+ empty, i.e. if the path begins with a hashtag. The function
+ also sets \a ref if there remains an unused leg in the path
+ after the node is found. The node is returned as well as the
+ \a ref. If the returned node pointer is null, \a ref is not
+ valid.
+ */
+const Node* QDocDatabase::findNode(const Atom* atom, const Node* relative, QString& ref)
{
- foreach (Tree* t, searchOrder()) {
- const QmlModuleMap& qmm = t->groups();
- if (!qmm.isEmpty()) {
- QmlModuleMap::const_iterator i = qmm.begin();
- while (i != qmm.end()) {
- t.insert(i.key(), i.value());
- ++i;
- }
+ const Node* node = 0;
+ QStringList path = atom->string().split("#");
+ QString first = path.first().trimmed();
+ path.removeFirst();
+
+ if (first.isEmpty())
+ node = relative; // search for a target on the current page.
+ else if (atom->specifiesDomain()) {
+ qDebug() << "Processing LinkAtom";
+ if (first.endsWith(".html")) { // The target is an html file.
+ node = atom->domain()->findNodeByNameAndType(QStringList(first), Node::Document);
+ }
+ else if (first.endsWith("()")) { // The target is a C++ function or QML method.
+ node = atom->domain()->resolveFunctionTarget(first, 0); //relative);
+ }
+ else {
+ node = atom->domain()->resolveTarget(first, 0); // relative);
+ if (!node)
+ node = atom->domain()->findUnambiguousTarget(first, ref); // ref
+ if (!node && path.isEmpty())
+ node = atom->domain()->findDocNodeByTitle(first);
+ }
+ }
+ else {
+ if (first.endsWith(".html")) { // The target is an html file.
+ node = findNodeByNameAndType(QStringList(first), Node::Document); // ref
+ }
+ else if (first.endsWith("()")) { // The target is a C++ function or QML method.
+ node = resolveFunctionTarget(first, relative);
+ }
+ else {
+ node = resolveTarget(first, relative); // ref
+ if (!node)
+ node = findUnambiguousTarget(first, ref); // ref
+ if (!node && path.isEmpty())
+ node = findDocNodeByTitle(first);
+ }
+ }
+ if (node && ref.isEmpty()) {
+ if (!node->url().isEmpty())
+ return node;
+ if (!path.isEmpty()) {
+ ref = findTarget(path.first(), node);
+ if (ref.isEmpty())
+ node = 0;
}
}
+ return node;
}
-#endif
+
+QT_END_NAMESPACE
diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h
index 8741443a7c..7c398a9d51 100644
--- a/src/tools/qdoc/qdocdatabase.h
+++ b/src/tools/qdoc/qdocdatabase.h
@@ -249,7 +249,9 @@ class QDocDatabase
void findAllSince(InnerNode *node);
public:
- // special collection access functions
+ /*******************************************************************
+ special collection access functions
+ ********************************************************************/
NodeMap& getCppClasses();
NodeMap& getMainClasses();
NodeMap& getCompatibilityClasses();
@@ -266,9 +268,9 @@ class QDocDatabase
const NodeMap& getQmlTypeMap(const QString& key);
const NodeMultiMap& getSinceMap(const QString& key);
- /* convenience functions
- Many of these will be either eliminated or replaced.
- */
+ /*******************************************************************
+ Many of these will be either eliminated or replaced.
+ ********************************************************************/
void resolveInheritance() { primaryTree()->resolveInheritance(); }
void resolveQmlInheritance(InnerNode* root);
void resolveIssues();
@@ -299,6 +301,14 @@ class QDocDatabase
/*******************************************************************/
/*******************************************************************
+ The functions declared below handle the parameters in '[' ']'.
+ ********************************************************************/
+ Node* findNode(const Atom* atom);
+ const Node* findNode(const Atom* atom, const Node* relative, QString& ref);
+ const DocNode* findDocNodeByTitle(const Atom* atom);
+ /*******************************************************************/
+
+ /*******************************************************************
The functions declared below are called for all trees.
********************************************************************/
ClassNode* findClassNode(const QStringList& path) { return forest_.findClassNode(path); }
diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp
index 25f6b8eec9..317209dd64 100644
--- a/src/tools/qdoc/qdocindexfiles.cpp
+++ b/src/tools/qdoc/qdocindexfiles.cpp
@@ -54,6 +54,8 @@
QT_BEGIN_NAMESPACE
+static Node* top = 0;
+
/*!
\class QDocIndexFiles
@@ -110,11 +112,13 @@ void QDocIndexFiles::readIndexes(const QStringList& indexFiles)
foreach (const QString& indexFile, indexFiles) {
QString msg = "Loading index file: " + indexFile;
Location::logToStdErr(msg);
- //qDebug() << " LOAD INDEX FILE:" << indexFile;
+ //qDebug() << msg;
readIndexFile(indexFile);
}
}
+static bool readingRoot = true;
+
/*!
Reads and parses the index file at \a path.
*/
@@ -146,6 +150,7 @@ void QDocIndexFiles::readIndexFile(const QString& path)
basesList_.clear();
relatedList_.clear();
+ readingRoot = true;
NamespaceNode* root = qdb_->newIndexTree(project_);
// Scan all elements in the XML file, constructing a map that contains
@@ -154,6 +159,7 @@ void QDocIndexFiles::readIndexFile(const QString& path)
while (!child.isNull()) {
readIndexSection(child, root, indexUrl);
child = child.nextSiblingElement();
+ readingRoot = true;
}
// Now that all the base classes have been found for this index,
@@ -167,13 +173,16 @@ void QDocIndexFiles::readIndexFile(const QString& path)
appropriate node(s).
*/
void QDocIndexFiles::readIndexSection(const QDomElement& element,
- InnerNode* parent,
+ Node* current,
const QString& indexUrl)
{
QString name = element.attribute("name");
QString href = element.attribute("href");
Node* node;
Location location;
+ InnerNode* parent = 0;
+ if (current->isInnerNode())
+ parent = static_cast<InnerNode*>(current);
QString filePath;
int lineNo = 0;
@@ -462,15 +471,15 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
location = Location(parent->name().toLower() + ".html");
}
else if (element.nodeName() == "keyword") {
- qdb_->insertTarget(name, TargetRec::Keyword, parent, 1);
+ qdb_->insertTarget(name, TargetRec::Keyword, current, 1);
return;
}
else if (element.nodeName() == "target") {
- qdb_->insertTarget(name, TargetRec::Target, parent, 2);
+ qdb_->insertTarget(name, TargetRec::Target, current, 2);
return;
}
else if (element.nodeName() == "contents") {
- qdb_->insertTarget(name, TargetRec::Contents, parent, 3);
+ qdb_->insertTarget(name, TargetRec::Contents, current, 3);
return;
}
else
@@ -560,26 +569,15 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
node->setReconstitutedBrief(briefAttr);
}
- if (node->isInnerNode()) {
- InnerNode* inner = static_cast<InnerNode*>(node);
+ // zzz
+ bool useParent = (element.nodeName() == "namespace" && name.isEmpty());
+ if (element.hasChildNodes()) {
QDomElement child = element.firstChildElement();
while (!child.isNull()) {
- if (element.nodeName() == "class") {
- readIndexSection(child, inner, indexUrl);
- }
- else if (element.nodeName() == "qmlclass") {
- readIndexSection(child, inner, indexUrl);
- }
- else if (element.nodeName() == "page") {
- readIndexSection(child, inner, indexUrl);
- }
- else if (element.nodeName() == "namespace" && !name.isEmpty()) {
- // The root node in the index is a namespace with an empty name.
- readIndexSection(child, inner, indexUrl);
- }
- else {
+ if (useParent)
readIndexSection(child, parent, indexUrl);
- }
+ else
+ readIndexSection(child, node, indexUrl);
child = child.nextSiblingElement();
}
}
@@ -1143,6 +1141,42 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
break;
}
+ /*
+ For our pages, we canonicalize the target, keyword and content
+ item names so that they can be used by qdoc for other sets of
+ documentation.
+
+ The reason we do this here is that we don't want to ruin
+ externally composed indexes, containing non-qdoc-style target names
+ when reading in indexes.
+
+ targets and keywords are now allowed in any node, not just inner nodes.
+ */
+
+ if (node->doc().hasTargets()) {
+ bool external = false;
+ if (node->type() == Node::Document) {
+ const DocNode* docNode = static_cast<const DocNode*>(node);
+ if (docNode->subType() == Node::ExternalPage)
+ external = true;
+ }
+ foreach (const Atom* target, node->doc().targets()) {
+ QString targetName = target->string();
+ if (!external)
+ targetName = Doc::canonicalTitle(targetName);
+ writer.writeStartElement("target");
+ writer.writeAttribute("name", targetName);
+ writer.writeEndElement(); // target
+ }
+ }
+ if (node->doc().hasKeywords()) {
+ foreach (const Atom* keyword, node->doc().keywords()) {
+ writer.writeStartElement("keyword");
+ writer.writeAttribute("name", Doc::canonicalTitle(keyword->string()));
+ writer.writeEndElement(); // keyword
+ }
+ }
+
// Inner nodes and function nodes contain child nodes of some sort, either
// actual child nodes or function parameters. For these, we close the
// opening tag, create child elements, then add a closing tag for the
@@ -1151,36 +1185,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
if (node->isInnerNode()) {
const InnerNode* inner = static_cast<const InnerNode*>(node);
- // For internal pages, we canonicalize the target, keyword and content
- // item names so that they can be used by qdoc for other sets of
- // documentation.
- // The reason we do this here is that we don't want to ruin
- // externally composed indexes, containing non-qdoc-style target names
- // when reading in indexes.
-
- if (inner->doc().hasTargets()) {
- bool external = false;
- if (inner->type() == Node::Document) {
- const DocNode* docNode = static_cast<const DocNode*>(inner);
- if (docNode->subType() == Node::ExternalPage)
- external = true;
- }
- foreach (const Atom* target, inner->doc().targets()) {
- QString targetName = target->string();
- if (!external)
- targetName = Doc::canonicalTitle(targetName);
- writer.writeStartElement("target");
- writer.writeAttribute("name", targetName);
- writer.writeEndElement(); // target
- }
- }
- if (inner->doc().hasKeywords()) {
- foreach (const Atom* keyword, inner->doc().keywords()) {
- writer.writeStartElement("keyword");
- writer.writeAttribute("name", Doc::canonicalTitle(keyword->string()));
- writer.writeEndElement(); // keyword
- }
- }
if (inner->doc().hasTableOfContents()) {
for (int i = 0; i < inner->doc().tableOfContents().size(); ++i) {
Atom* item = inner->doc().tableOfContents()[i];
@@ -1336,6 +1340,47 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
generateIndexSections(writer, child, generateInternalNodes);
}
}
+
+ if (node == top) {
+ /*
+ We wait until the end of the index file to output the group, module,
+ and QML module elements. By outputting them at the end, when we read
+ the index file back in, all the group, module, and QML module member
+ elements will have already been created. It is then only necessary to
+ create the group, module, or QML module element and add each member to
+ its member list.
+ */
+ const CNMap& groups = qdb_->groups();
+ if (!groups.isEmpty()) {
+ CNMap::ConstIterator g = groups.constBegin();
+ while (g != groups.constEnd()) {
+ if (generateIndexSection(writer, g.value(), generateInternalNodes))
+ writer.writeEndElement();
+ ++g;
+ }
+ }
+
+ const CNMap& modules = qdb_->modules();
+ if (!modules.isEmpty()) {
+ CNMap::ConstIterator g = modules.constBegin();
+ while (g != modules.constEnd()) {
+ if (generateIndexSection(writer, g.value(), generateInternalNodes))
+ writer.writeEndElement();
+ ++g;
+ }
+ }
+
+ const CNMap& qmlModules = qdb_->qmlModules();
+ if (!qmlModules.isEmpty()) {
+ CNMap::ConstIterator g = qmlModules.constBegin();
+ while (g != qmlModules.constEnd()) {
+ if (generateIndexSection(writer, g.value(), generateInternalNodes))
+ writer.writeEndElement();
+ ++g;
+ }
+ }
+ }
+
writer.writeEndElement();
}
}
@@ -1368,45 +1413,8 @@ void QDocIndexFiles::generateIndex(const QString& fileName,
writer.writeAttribute("version", qdb_->version());
writer.writeAttribute("project", g->config()->getString(CONFIG_PROJECT));
- generateIndexSections(writer, qdb_->primaryTreeRoot(), generateInternalNodes);
-
- /*
- We wait until the end of the index file to output the group, module,
- and QML module elements. By outputting them at the end, when we read
- the index file back in, all the group, module, and QML module member
- elements will have already been created. It is then only necessary to
- create the group, module, or QML module element and add each member to
- its member list.
- */
- const CNMap& groups = qdb_->groups();
- if (!groups.isEmpty()) {
- CNMap::ConstIterator g = groups.constBegin();
- while (g != groups.constEnd()) {
- if (generateIndexSection(writer, g.value(), generateInternalNodes))
- writer.writeEndElement();
- ++g;
- }
- }
-
- const CNMap& modules = qdb_->modules();
- if (!modules.isEmpty()) {
- CNMap::ConstIterator g = modules.constBegin();
- while (g != modules.constEnd()) {
- if (generateIndexSection(writer, g.value(), generateInternalNodes))
- writer.writeEndElement();
- ++g;
- }
- }
-
- const CNMap& qmlModules = qdb_->qmlModules();
- if (!qmlModules.isEmpty()) {
- CNMap::ConstIterator g = qmlModules.constBegin();
- while (g != qmlModules.constEnd()) {
- if (generateIndexSection(writer, g.value(), generateInternalNodes))
- writer.writeEndElement();
- ++g;
- }
- }
+ top = qdb_->primaryTreeRoot();
+ generateIndexSections(writer, top, generateInternalNodes);
writer.writeEndElement(); // INDEX
writer.writeEndElement(); // QDOCINDEX
diff --git a/src/tools/qdoc/qdocindexfiles.h b/src/tools/qdoc/qdocindexfiles.h
index bd94fdb215..27ee96ea8d 100644
--- a/src/tools/qdoc/qdocindexfiles.h
+++ b/src/tools/qdoc/qdocindexfiles.h
@@ -72,7 +72,7 @@ class QDocIndexFiles
bool generateInternalNodes = false);
void readIndexFile(const QString& path);
- void readIndexSection(const QDomElement& element, InnerNode* parent, const QString& indexUrl);
+ void readIndexSection(const QDomElement& element, Node* current, const QString& indexUrl);
void resolveIndex();
bool generateIndexSection(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false);
void generateIndexSections(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false);
diff --git a/src/tools/qdoc/text.cpp b/src/tools/qdoc/text.cpp
index e2f682726d..ae716a0e50 100644
--- a/src/tools/qdoc/text.cpp
+++ b/src/tools/qdoc/text.cpp
@@ -111,6 +111,22 @@ Text& Text::operator<<(const Atom& atom)
return *this;
}
+/*!
+ Special output operator for LinkAtom. It makes a copy of
+ the LinkAtom \a atom and connects the cop;y to the list
+ in this Text.
+ */
+Text& Text::operator<<(const LinkAtom& atom)
+{
+ if (first == 0) {
+ first = new LinkAtom(atom);
+ last = first;
+ }
+ else
+ last = new LinkAtom(last, atom);
+ return *this;
+}
+
Text& Text::operator<<(const Text& text)
{
const Atom* atom = text.firstAtom();
diff --git a/src/tools/qdoc/text.h b/src/tools/qdoc/text.h
index 9274140caa..ca079e3b35 100644
--- a/src/tools/qdoc/text.h
+++ b/src/tools/qdoc/text.h
@@ -65,6 +65,7 @@ public:
Text& operator<<(Atom::Type atomType);
Text& operator<<(const QString& string);
Text& operator<<(const Atom& atom);
+ Text& operator<<(const LinkAtom& atom);
Text& operator<<(const Text& text);
void stripFirstAtom();
void stripLastAtom();
diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp
index 147abe21af..e689227bf1 100644
--- a/src/tools/qdoc/tree.cpp
+++ b/src/tools/qdoc/tree.cpp
@@ -563,20 +563,6 @@ Node* Tree::findNodeByNameAndType(const QStringList& path, Node::Type type) cons
{
return findNodeRecursive(path, 0, root(), type);
}
-#if 0
-/*!
- Find the node with the specified \a path name that is of
- the specified \a type and \a subtype. Begin the search at
- the \a start node. If the \a start node is 0, begin the
- search at the tree root. \a subtype is not used unless
- \a type is \c{Document}.
- */
-Node* Tree::findHtmlFileNode(const QStringList& path) const
-{
- return findNodeRecursive(path, 0, root());
-}
-#endif
-/* internal members */
/*!
Recursive search for a node identified by \a path. Each
@@ -624,7 +610,7 @@ Node* Tree::findNodeRecursive(const QStringList& path,
}
else if (n->name() == name) {
if (pathIndex+1 >= path.size()) {
- if (n->type() == type)
+ if ((n->type() == type) || (type == Node::NoType))
return n;
continue;
}
@@ -816,6 +802,23 @@ void Tree::insertTarget(const QString& name, TargetRec::Type type, Node* node, i
}
/*!
+ Searches this tree for a node named \a target and returns
+ a pointer to it if found. The \a start node is the starting
+ point, but it only makes sense if \a start is in this tree.
+ If \a start is not in this tree, \a start is set to 0 before
+ beginning the search to ensure that the search starts at the
+ root.
+ */
+const Node* Tree::resolveTarget(const QString& target, const Node* start)
+{
+ QStringList path = target.split("::");
+ int flags = SearchBaseClasses | SearchEnumValues | NonFunction;
+ if (start && start->tree() != this)
+ start = 0;
+ return findNode(path, start, flags);
+}
+
+/*!
*/
void Tree::resolveTargets(InnerNode* root)
{
diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h
index 7160e321db..a953751968 100644
--- a/src/tools/qdoc/tree.h
+++ b/src/tools/qdoc/tree.h
@@ -114,6 +114,7 @@ class Tree
NameCollisionNode* findCollisionNode(const QString& name) const;
QString findTarget(const QString& target, const Node* node) const;
void insertTarget(const QString& name, TargetRec::Type type, Node* node, int priority);
+ const Node* resolveTarget(const QString& target, const Node* start);
void resolveTargets(InnerNode* root);
const Node* findUnambiguousTarget(const QString& target, QString& ref);
const DocNode* findDocNodeByTitle(const QString& title) const;