qdoc: Give documenter more control of linking
This update is preparation for implementing the actual task described in the bug. To implement it required converting the QML type node and the QML basic type node to be first order tree nodes instead of subtypes of the documentation node. This cleans up a lot of messy logic in some places. It was also necessary to split the getLink() function in the html output generator into two functions, one still called getLink(), which handles the \l command, and one called qetAutoLink() which is called for generating auto links. This should make qdoc run faster. The basic infrastructure was also added for parsing the string in the square brackets for the \l command. There will be a further update to complete this task. Note that some autolinks might not be generated due to this change. I haven't seen any yet, but I believe there will be some. This can be fixed later, if it is a problem. Task-number: QTBUG-39221 Change-Id: I8135229984398408205ba901b9ef95ceac74683c Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
This commit is contained in:
parent
bb794270ec
commit
46959875cf
@ -42,31 +42,12 @@
|
||||
#include <qregexp.h>
|
||||
#include "atom.h"
|
||||
#include "location.h"
|
||||
#include "qdocdatabase.h"
|
||||
#include <stdio.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QLatin1String Atom::BOLD_ ("bold");
|
||||
QLatin1String Atom::INDEX_ ("index");
|
||||
QLatin1String Atom::ITALIC_ ("italic");
|
||||
QLatin1String Atom::LINK_ ("link");
|
||||
QLatin1String Atom::PARAMETER_ ("parameter");
|
||||
QLatin1String Atom::SPAN_ ("span");
|
||||
QLatin1String Atom::SUBSCRIPT_ ("subscript");
|
||||
QLatin1String Atom::SUPERSCRIPT_ ("superscript");
|
||||
QLatin1String Atom::TELETYPE_ ("teletype");
|
||||
QLatin1String Atom::UICONTROL_ ("uicontrol");
|
||||
QLatin1String Atom::UNDERLINE_ ("underline");
|
||||
|
||||
QLatin1String Atom::BULLET_ ("bullet");
|
||||
QLatin1String Atom::TAG_ ("tag");
|
||||
QLatin1String Atom::VALUE_ ("value");
|
||||
QLatin1String Atom::LOWERALPHA_ ("loweralpha");
|
||||
QLatin1String Atom::LOWERROMAN_ ("lowerroman");
|
||||
QLatin1String Atom::NUMERIC_ ("numeric");
|
||||
QLatin1String Atom::UPPERALPHA_ ("upperalpha");
|
||||
QLatin1String Atom::UPPERROMAN_ ("upperroman");
|
||||
|
||||
/*! \class Atom
|
||||
\brief The Atom class is the fundamental unit for representing
|
||||
documents internally.
|
||||
@ -387,4 +368,28 @@ void Atom::dump() const
|
||||
str.toLatin1().data());
|
||||
}
|
||||
|
||||
/*!
|
||||
The only constructor for LinkAtom. It only create an Atom
|
||||
of type Atom::Link with \a p1 being the link text. \a p2
|
||||
contains some search parameters.
|
||||
*/
|
||||
LinkAtom::LinkAtom(const QString& p1, const QString& p2)
|
||||
: Atom(Link, p1), qml_(false), 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -39,17 +39,16 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
atom.h
|
||||
*/
|
||||
|
||||
#ifndef ATOM_H
|
||||
#define ATOM_H
|
||||
|
||||
#include <qstringlist.h>
|
||||
#include "node.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Tree;
|
||||
|
||||
class Atom
|
||||
{
|
||||
public:
|
||||
@ -169,6 +168,8 @@ public:
|
||||
previous->next_ = this;
|
||||
}
|
||||
|
||||
virtual ~Atom() { }
|
||||
|
||||
void appendChar(QChar ch) { strs[0] += ch; }
|
||||
void appendString(const QString& string) { strs[0] += string; }
|
||||
void chopString() { strs[0].chop(1); }
|
||||
@ -186,33 +187,34 @@ public:
|
||||
int count() const { return strs.size(); }
|
||||
void dump() const;
|
||||
|
||||
static QLatin1String BOLD_;
|
||||
static QLatin1String INDEX_;
|
||||
static QLatin1String ITALIC_;
|
||||
static QLatin1String LINK_;
|
||||
static QLatin1String PARAMETER_;
|
||||
static QLatin1String SPAN_;
|
||||
static QLatin1String SUBSCRIPT_;
|
||||
static QLatin1String SUPERSCRIPT_;
|
||||
static QLatin1String TELETYPE_;
|
||||
static QLatin1String UICONTROL_;
|
||||
static QLatin1String UNDERLINE_;
|
||||
virtual bool qml() const { return false; }
|
||||
virtual bool specifiesDomain() const { return false; }
|
||||
virtual Tree* domain() const { return 0; }
|
||||
virtual Node::Type goal() const { return Node::NoType; }
|
||||
|
||||
static QLatin1String BULLET_;
|
||||
static QLatin1String TAG_;
|
||||
static QLatin1String VALUE_;
|
||||
static QLatin1String LOWERALPHA_;
|
||||
static QLatin1String LOWERROMAN_;
|
||||
static QLatin1String NUMERIC_;
|
||||
static QLatin1String UPPERALPHA_;
|
||||
static QLatin1String UPPERROMAN_;
|
||||
|
||||
private:
|
||||
protected:
|
||||
Atom* next_;
|
||||
Type type_;
|
||||
QStringList strs;
|
||||
};
|
||||
|
||||
class LinkAtom : public Atom
|
||||
{
|
||||
public:
|
||||
LinkAtom(const QString& p1, const QString& p2);
|
||||
virtual ~LinkAtom() { }
|
||||
|
||||
virtual bool qml() const { return qml_; }
|
||||
virtual bool specifiesDomain() const { return (domain_ != 0); }
|
||||
virtual Tree* domain() const { return domain_; }
|
||||
virtual Node::Type goal() const { return goal_; }
|
||||
|
||||
protected:
|
||||
bool qml_;
|
||||
Node::Type goal_;
|
||||
Tree* domain_;
|
||||
};
|
||||
|
||||
#define ATOM_FORMATTING_BOLD "bold"
|
||||
#define ATOM_FORMATTING_INDEX "index"
|
||||
#define ATOM_FORMATTING_ITALIC "italic"
|
||||
|
@ -273,7 +273,7 @@ QString CodeMarker::taggedNode(const Node* node)
|
||||
case Node::Property:
|
||||
tag = QLatin1String("@property");
|
||||
break;
|
||||
case Node::Document:
|
||||
case Node::QmlType:
|
||||
/*
|
||||
Remove the "QML:" prefix, if present.
|
||||
There shouldn't be any of these "QML:"
|
||||
@ -282,10 +282,11 @@ QString CodeMarker::taggedNode(const Node* node)
|
||||
qualifiers, but this code is kept to
|
||||
be backward compatible.
|
||||
*/
|
||||
if (node->subType() == Node::QmlClass) {
|
||||
if (node->name().startsWith(QLatin1String("QML:")))
|
||||
name = name.mid(4);
|
||||
}
|
||||
if (node->name().startsWith(QLatin1String("QML:")))
|
||||
name = name.mid(4);
|
||||
tag = QLatin1String("@property");
|
||||
break;
|
||||
case Node::Document:
|
||||
tag = QLatin1String("@property");
|
||||
break;
|
||||
case Node::QmlMethod:
|
||||
@ -400,9 +401,8 @@ void CodeMarker::insert(FastSection &fastSection,
|
||||
InnerNode* p = node->parent();
|
||||
if (p->type() == Node::QmlPropertyGroup)
|
||||
p = p->parent();
|
||||
if (p != fastSection.parent_) { // && !node->parent()->isAbstract()) {
|
||||
if (p->subType() != Node::QmlClass || !p->isAbstract()) {
|
||||
//if (node->type() != Node::QmlProperty) {
|
||||
if (p != fastSection.parent_) {
|
||||
if (!p->isQmlType() || !p->isAbstract()) {
|
||||
inheritedMember = true;
|
||||
}
|
||||
}
|
||||
@ -622,6 +622,7 @@ QStringList CodeMarker::macRefsForNode(Node *node)
|
||||
}
|
||||
case Node::Namespace:
|
||||
case Node::Document:
|
||||
case Node::QmlType:
|
||||
default:
|
||||
return QStringList();
|
||||
}
|
||||
|
@ -408,17 +408,13 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
|
||||
without including the namespace qualifier.
|
||||
*/
|
||||
Node::Type type = nodeTypeMap[command];
|
||||
Node::SubType subtype = Node::NoSubType;
|
||||
if (type == Node::Document)
|
||||
subtype = Node::QmlClass;
|
||||
|
||||
QStringList paths = arg.first.split(QLatin1Char(' '));
|
||||
QStringList path = paths[0].split("::");
|
||||
Node *node = 0;
|
||||
|
||||
node = qdb_->findNodeInOpenNamespace(path, type, subtype);
|
||||
node = qdb_->findNodeInOpenNamespace(path, type);
|
||||
if (node == 0)
|
||||
node = qdb_->findNodeByNameAndType(path, type, subtype);
|
||||
node = qdb_->findNodeByNameAndType(path, type);
|
||||
if (node == 0) {
|
||||
doc.location().warning(tr("Cannot find '%1' specified with '\\%2' in any header file")
|
||||
.arg(arg.first).arg(command));
|
||||
@ -971,14 +967,14 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
|
||||
else if (command == COMMAND_QMLINHERITS) {
|
||||
if (node->name() == arg)
|
||||
doc.location().warning(tr("%1 tries to inherit itself").arg(arg));
|
||||
else if (node->subType() == Node::QmlClass) {
|
||||
else if (node->isQmlType()) {
|
||||
QmlClassNode *qmlClass = static_cast<QmlClassNode*>(node);
|
||||
qmlClass->setQmlBaseName(arg);
|
||||
QmlClassNode::addInheritedBy(arg,node);
|
||||
}
|
||||
}
|
||||
else if (command == COMMAND_QMLINSTANTIATES) {
|
||||
if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
|
||||
if (node->isQmlType()) {
|
||||
ClassNode* classNode = qdb_->findClassNode(arg.split("::"));
|
||||
if (classNode)
|
||||
node->setClassNode(classNode);
|
||||
@ -1023,9 +1019,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
|
||||
}
|
||||
}
|
||||
else if (command == COMMAND_QMLABSTRACT) {
|
||||
if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
|
||||
if (node->isQmlType())
|
||||
node->setAbstract(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
processCommonMetaCommand(doc.location(),command,argLocPair,node);
|
||||
|
@ -819,7 +819,6 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
|
||||
}
|
||||
break;
|
||||
case Atom::BriefRight:
|
||||
// if (relative->type() != Node::Document)
|
||||
writeEndTag(); // </shortdesc> or </p>
|
||||
if (in_para)
|
||||
in_para = false;
|
||||
@ -1106,10 +1105,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
|
||||
while (n != nsmap.constEnd()) {
|
||||
const Node* node = n.value();
|
||||
switch (node->type()) {
|
||||
case Node::Document:
|
||||
if (node->subType() == Node::QmlClass) {
|
||||
sections[QmlClass].appendMember((Node*)node);
|
||||
}
|
||||
case Node::QmlType:
|
||||
sections[QmlClass].appendMember((Node*)node);
|
||||
break;
|
||||
case Node::Namespace:
|
||||
sections[Namespace].appendMember((Node*)node);
|
||||
@ -1256,8 +1253,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
|
||||
images.append(QLatin1Char('/'));
|
||||
fileName = images + atom->string();
|
||||
}
|
||||
if (relative && (relative->type() == Node::Document) &&
|
||||
(relative->subType() == Node::Example)) {
|
||||
if (relative && relative->isExample()) {
|
||||
const ExampleNode* cen = static_cast<const ExampleNode*>(relative);
|
||||
if (cen->imageFileName().isEmpty()) {
|
||||
ExampleNode* en = const_cast<ExampleNode*>(cen);
|
||||
@ -1313,8 +1309,8 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
|
||||
{
|
||||
const Node *node = 0;
|
||||
QString myLink = getLink(atom, relative, &node);
|
||||
if (myLink.isEmpty())
|
||||
myLink = getCollisionLink(atom);
|
||||
//if (myLink.isEmpty())
|
||||
//myLink = getCollisionLink(atom);
|
||||
if (myLink.isEmpty() && !noLinkErrors())
|
||||
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
|
||||
else if (!inSectionHeading_)
|
||||
@ -2052,7 +2048,7 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
|
||||
generateLowStatusMembers(inner,marker,CodeMarker::Compat);
|
||||
writeEndTag(); // </cxxClass>
|
||||
}
|
||||
else if ((inner->type() == Node::Document) && (inner->subType() == Node::HeaderFile)) {
|
||||
else if (inner->isHeaderFile()) {
|
||||
const DocNode* dn = const_cast<DocNode*>(static_cast<const DocNode*>(inner));
|
||||
rawTitle = inner->plainName();
|
||||
fullTitle = inner->plainFullName();
|
||||
@ -2168,7 +2164,7 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
|
||||
generateLowStatusMembers(inner,marker,CodeMarker::Compat);
|
||||
writeEndTag(); // </cxxClass>
|
||||
}
|
||||
else if ((inner->type() == Node::Document) && (inner->subType() == Node::QmlClass)) {
|
||||
else if (inner->isQmlType()) {
|
||||
QmlClassNode* qcn = const_cast<QmlClassNode*>(static_cast<const QmlClassNode*>(inner));
|
||||
ClassNode* cn = qcn->classNode();
|
||||
rawTitle = inner->plainName();
|
||||
@ -2216,6 +2212,36 @@ DitaXmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Generate the DITA page for a qdoc file that doesn't map
|
||||
to an underlying c++ file.
|
||||
*/
|
||||
void DitaXmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker)
|
||||
{
|
||||
QList<Section> sections;
|
||||
QList<Section>::const_iterator s;
|
||||
QString fullTitle = "QML Basic Type: " + qbtn->fullTitle();
|
||||
|
||||
generateHeader(qbtn, fullTitle);
|
||||
generateBrief(qbtn, marker); // <shortdesc>
|
||||
writeProlog(qbtn);
|
||||
|
||||
writeStartTag(DT_body);
|
||||
enterSection(QString(), QString());
|
||||
|
||||
if (!qbtn->doc().isEmpty()) {
|
||||
generateBody(qbtn, marker);
|
||||
generateAlsoList(qbtn, marker);
|
||||
}
|
||||
leaveSection(); // </section>
|
||||
if (!writeEndTag()) { // </body>
|
||||
qbtn->doc().location().warning(tr("Pop of empty XML tag stack; generating DITA for '%1'").arg(qbtn->name()));
|
||||
return;
|
||||
}
|
||||
writeRelatedLinks(qbtn);
|
||||
writeEndTag(); // </topic>
|
||||
}
|
||||
|
||||
/*!
|
||||
Write a list item for a \a link with the given \a text.
|
||||
*/
|
||||
@ -2251,10 +2277,7 @@ void DitaXmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
|
||||
QList<Section>::const_iterator s;
|
||||
QString fullTitle = dn->fullTitle();
|
||||
|
||||
if (dn->subType() == Node::QmlBasicType) {
|
||||
fullTitle = "QML Basic Type: " + fullTitle;
|
||||
}
|
||||
else if (dn->subType() == Node::Collision) {
|
||||
if (dn->subType() == Node::Collision) {
|
||||
fullTitle = "Name Collision: " + fullTitle;
|
||||
}
|
||||
|
||||
@ -2391,7 +2414,7 @@ void DitaXmlGenerator::writeRelatedLinks(const Node* node)
|
||||
linkNode = qdb_->findNodeForTarget(linkPair.first, node);
|
||||
if (!linkNode)
|
||||
node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
|
||||
if (linkNode && linkNode->type() == Node::Document) {
|
||||
if (linkNode && linkNode->isDocNode()) {
|
||||
const DocNode *docNode = static_cast<const DocNode*>(linkNode);
|
||||
linkPair.second = docNode->title();
|
||||
}
|
||||
@ -2402,7 +2425,7 @@ void DitaXmlGenerator::writeRelatedLinks(const Node* node)
|
||||
linkNode = qdb_->findNodeForTarget(linkPair.first, node);
|
||||
if (!linkNode)
|
||||
node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
|
||||
if (linkNode && linkNode->type() == Node::Document) {
|
||||
if (linkNode && linkNode->isDocNode()) {
|
||||
const DocNode *docNode = static_cast<const DocNode*>(linkNode);
|
||||
linkPair.second = docNode->title();
|
||||
}
|
||||
@ -2413,7 +2436,7 @@ void DitaXmlGenerator::writeRelatedLinks(const Node* node)
|
||||
linkNode = qdb_->findNodeForTarget(linkPair.first, node);
|
||||
if (!linkNode)
|
||||
node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
|
||||
if (linkNode && linkNode->type() == Node::Document) {
|
||||
if (linkNode && linkNode->isDocNode()) {
|
||||
const DocNode *docNode = static_cast<const DocNode*>(linkNode);
|
||||
linkPair.second = docNode->title();
|
||||
}
|
||||
@ -2804,7 +2827,7 @@ void DitaXmlGenerator::generateAnnotatedList(const Node* relative,
|
||||
writeEndTag(); // </p>
|
||||
writeEndTag(); // <entry>
|
||||
|
||||
if (!(node->type() == Node::Document)) {
|
||||
if (!node->isDocNode()) {
|
||||
Text brief = node->doc().trimmedBriefText(node->name());
|
||||
if (!brief.isEmpty()) {
|
||||
writeStartTag(DT_entry);
|
||||
@ -3026,7 +3049,7 @@ void DitaXmlGenerator::generateCompactList(ListType , // currently not needed fo
|
||||
writeHrefAttribute(linkForNode(it.value(), relative));
|
||||
|
||||
QStringList pieces;
|
||||
if (it.value()->subType() == Node::QmlClass)
|
||||
if (it.value()->isQmlType())
|
||||
pieces << it.value()->name();
|
||||
else
|
||||
pieces = it.value()->fullName(relative).split("::");
|
||||
@ -3435,8 +3458,8 @@ void DitaXmlGenerator::writeText(const QString& markedCode, const Node* relative
|
||||
}
|
||||
par1 = QStringRef();
|
||||
n = qdb_->resolveType(arg.toString(), relative);
|
||||
if (n && n->subType() == Node::QmlBasicType) {
|
||||
if (relative && relative->subType() == Node::QmlClass)
|
||||
if (n && n->isQmlBasicType()) {
|
||||
if (relative && relative->isQmlType())
|
||||
addLink(linkForNode(n, relative), arg);
|
||||
else
|
||||
writeCharacters(arg.toString());
|
||||
@ -3712,7 +3735,7 @@ QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
|
||||
|
||||
QString fn = fileName(node);
|
||||
if (node && relative && node->parent() != relative) {
|
||||
if (node->parent()->subType() == Node::QmlClass && relative->subType() == Node::QmlClass) {
|
||||
if (node->parent()->isQmlType() && relative->isQmlType()) {
|
||||
if (node->parent()->isAbstract()) {
|
||||
/*
|
||||
This is a bit of a hack. What we discover with
|
||||
@ -3775,6 +3798,7 @@ int DitaXmlGenerator::hOffset(const Node* node)
|
||||
case Node::Namespace:
|
||||
case Node::Class:
|
||||
return 2;
|
||||
case Node::QmlType:
|
||||
case Node::Document:
|
||||
return 1;
|
||||
case Node::Enum:
|
||||
@ -3836,7 +3860,7 @@ QString DitaXmlGenerator::getLink(const Atom* atom, const Node* relative, const
|
||||
if (first.isEmpty())
|
||||
*node = relative;
|
||||
else if (first.endsWith(".html"))
|
||||
*node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document, Node::NoSubType);
|
||||
*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 {
|
||||
@ -3860,7 +3884,7 @@ QString DitaXmlGenerator::getLink(const Atom* atom, const Node* relative, const
|
||||
if (relative && (relative->parent() != *node) &&
|
||||
(relative->status() != Node::Obsolete)) {
|
||||
bool porting = false;
|
||||
if (relative->type() == Node::Document) {
|
||||
if (relative->isDocNode()) {
|
||||
const DocNode* fake = static_cast<const DocNode*>(relative);
|
||||
if (fake->title().startsWith("Porting"))
|
||||
porting = true;
|
||||
@ -4607,7 +4631,7 @@ void DitaXmlGenerator::replaceTypesWithLinks(const Node* n, const InnerNode* par
|
||||
const Node* tn = qdb_->resolveType(arg.toString(), parent);
|
||||
if (tn) {
|
||||
//Do not generate a link from a C++ function to a QML Basic Type (such as int)
|
||||
if (n->type() == Node::Function && tn->subType() == Node::QmlBasicType)
|
||||
if (n->isFunction() && tn->isQmlBasicType())
|
||||
writeCharacters(arg.toString());
|
||||
else
|
||||
addLink(linkForNode(tn,parent),arg,DT_apiRelation);
|
||||
@ -4762,12 +4786,13 @@ void DitaXmlGenerator::writeEnumerations(const Section& s,
|
||||
}
|
||||
|
||||
// not included: <cxxEnumeratorAPIItemLocation>
|
||||
|
||||
#if 0
|
||||
if (!(*i).text().isEmpty()) {
|
||||
writeStartTag(DT_apiDesc);
|
||||
generateText((*i).text(), en, marker);
|
||||
writeEndTag(); // </apiDesc>
|
||||
}
|
||||
#endif
|
||||
writeEndTag(); // <cxxEnumerator>
|
||||
++i;
|
||||
}
|
||||
@ -5268,7 +5293,7 @@ DitaXmlGenerator::generateInnerNode(InnerNode* node)
|
||||
if (!node->url().isNull())
|
||||
return;
|
||||
|
||||
if (node->type() == Node::Document) {
|
||||
if (node->isDocNode()) {
|
||||
DocNode* docNode = static_cast<DocNode*>(node);
|
||||
if (docNode->subType() == Node::ExternalPage)
|
||||
return;
|
||||
@ -5279,7 +5304,7 @@ DitaXmlGenerator::generateInnerNode(InnerNode* node)
|
||||
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
|
||||
}
|
||||
}
|
||||
else if (node->type() == Node::QmlPropertyGroup)
|
||||
else if (node->isQmlPropertyGroup())
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -5292,24 +5317,19 @@ DitaXmlGenerator::generateInnerNode(InnerNode* node)
|
||||
later in generateCollisionPages(). Each one is
|
||||
appended to a list for later.
|
||||
*/
|
||||
if ((node->type() == Node::Document) && (node->subType() == Node::Collision)) {
|
||||
if (node->isCollisionNode()) {
|
||||
NameCollisionNode* ncn = static_cast<NameCollisionNode*>(node);
|
||||
collisionNodes.append(const_cast<NameCollisionNode*>(ncn));
|
||||
}
|
||||
else {
|
||||
if (!node->name().endsWith(".ditamap"))
|
||||
beginSubPage(node, fileName(node));
|
||||
if (node->type() == Node::Namespace || node->type() == Node::Class) {
|
||||
if (node->isNamespace() || node->isClass() || node->isQmlType() || node->isHeaderFile())
|
||||
generateClassLikeNode(node, marker);
|
||||
}
|
||||
else if (node->type() == Node::Document) {
|
||||
if (node->subType() == Node::HeaderFile)
|
||||
generateClassLikeNode(node, marker);
|
||||
else if (node->subType() == Node::QmlClass)
|
||||
generateClassLikeNode(node, marker);
|
||||
else
|
||||
generateDocNode(static_cast<DocNode*>(node), marker);
|
||||
}
|
||||
else if (node->isDocNode())
|
||||
generateDocNode(static_cast<DocNode*>(node), marker);
|
||||
else if (node->isQmlBasicType())
|
||||
generateQmlBasicTypePage(static_cast<QmlBasicTypeNode*>(node), marker);
|
||||
if (!node->name().endsWith(".ditamap"))
|
||||
endSubPage();
|
||||
}
|
||||
@ -5378,7 +5398,7 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
|
||||
QString message;
|
||||
for (int i=0; i<children.size(); ++i) {
|
||||
Node* child = children[i];
|
||||
if ((child->type() == Node::Document) && (child->subType() == Node::Collision)) {
|
||||
if (child->isCollisionNode()) {
|
||||
const DocNode* fake = static_cast<const DocNode*>(child);
|
||||
Node* n = collectNodesByTypeAndSubtype(fake);
|
||||
if (n)
|
||||
@ -5401,6 +5421,14 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
|
||||
if (!isDuplicate(nodeTypeMaps[Node::Class],child->name(),child))
|
||||
nodeTypeMaps[Node::Class]->insert(child->name(),child);
|
||||
break;
|
||||
case Node::QmlType:
|
||||
if (!isDuplicate(nodeTypeMaps[Node::QmlType],child->name(),child))
|
||||
nodeTypeMaps[Node::QmlType]->insert(child->name(),child);
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
if (!isDuplicate(nodeTypeMaps[Node::QmlBasicType],child->title(),child))
|
||||
nodeTypeMaps[Node::QmlBasicType]->insert(child->title(),child);
|
||||
break;
|
||||
case Node::Group:
|
||||
if (!isDuplicate(nodeTypeMaps[Node::Group],child->title(),child))
|
||||
nodeTypeMaps[Node::Group]->insert(child->title(),child);
|
||||
@ -5435,14 +5463,6 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
|
||||
if (!isDuplicate(nodeSubtypeMaps[Node::ExternalPage],child->title(),child))
|
||||
nodeSubtypeMaps[Node::ExternalPage]->insert(child->title(),child);
|
||||
break;
|
||||
case Node::QmlClass:
|
||||
if (!isDuplicate(nodeSubtypeMaps[Node::QmlClass],child->title(),child))
|
||||
nodeSubtypeMaps[Node::QmlClass]->insert(child->title(),child);
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
if (!isDuplicate(nodeSubtypeMaps[Node::QmlBasicType],child->title(),child))
|
||||
nodeSubtypeMaps[Node::QmlBasicType]->insert(child->title(),child);
|
||||
break;
|
||||
case Node::Collision:
|
||||
if (!isDuplicate(nodeSubtypeMaps[Node::Collision],child->title(),child))
|
||||
nodeSubtypeMaps[Node::Collision]->insert(child->title(),child);
|
||||
@ -5551,10 +5571,10 @@ void DitaXmlGenerator::writeDitaMap()
|
||||
writeTopicrefs(nodeTypeMaps[Node::QmlModule], "QML modules");
|
||||
|
||||
if (nodeTypeMaps[Node::QmlModule]->size() == 1)
|
||||
writeTopicrefs(nodeSubtypeMaps[Node::QmlClass], "QML types", nodeTypeMaps[Node::QmlModule]->values()[0]);
|
||||
writeTopicrefs(nodeTypeMaps[Node::QmlType], "QML types", nodeTypeMaps[Node::QmlModule]->values()[0]);
|
||||
else
|
||||
writeTopicrefs(nodeSubtypeMaps[Node::QmlClass], "QML types");
|
||||
writeTopicrefs(nodeSubtypeMaps[Node::QmlBasicType], "QML basic types");
|
||||
writeTopicrefs(nodeTypeMaps[Node::QmlType], "QML types");
|
||||
writeTopicrefs(nodeTypeMaps[Node::QmlBasicType], "QML basic types");
|
||||
|
||||
if (nodeTypeMaps[Node::Module]->size() > 1)
|
||||
writeTopicrefs(nodeTypeMaps[Node::Module], "Modules");
|
||||
@ -5910,32 +5930,32 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner)
|
||||
if (!writeMetadataElement(inner,DT_category,false)) {
|
||||
writeStartTag(DT_category);
|
||||
QString category = "Page";
|
||||
if (inner->type() == Node::Class)
|
||||
if (inner->isClass())
|
||||
category = "Class reference";
|
||||
else if (inner->type() == Node::Namespace)
|
||||
if (inner->isQmlType())
|
||||
category = "QML Reference";
|
||||
else if (inner->isQmlBasicType())
|
||||
category = "QML Basic Type";
|
||||
else if (inner->isNamespace())
|
||||
category = "Namespace";
|
||||
else if (inner->type() == Node::Module)
|
||||
else if (inner->isModule())
|
||||
category = "Module";
|
||||
else if (inner->type() == Node::QmlModule)
|
||||
else if (inner->isQmlModule())
|
||||
category = "QML Module";
|
||||
else if (inner->type() == Node::Group)
|
||||
else if (inner->isGroup())
|
||||
category = "Group";
|
||||
else if (inner->type() == Node::Document) {
|
||||
if (inner->subType() == Node::QmlClass)
|
||||
category = "QML Reference";
|
||||
else if (inner->subType() == Node::QmlBasicType)
|
||||
category = "QML Basic Type";
|
||||
else if (inner->subType() == Node::HeaderFile)
|
||||
else if (inner->isDocNode()) {
|
||||
if (inner->isHeaderFile())
|
||||
category = "Header File";
|
||||
else if (inner->subType() == Node::File)
|
||||
category = "Example Source File";
|
||||
else if (inner->subType() == Node::Example)
|
||||
else if (inner->isExample())
|
||||
category = "Example";
|
||||
else if (inner->subType() == Node::Image)
|
||||
category = "Image";
|
||||
else if (inner->subType() == Node::Page)
|
||||
category = "Page";
|
||||
else if (inner->subType() == Node::ExternalPage)
|
||||
else if (inner->isExternalPage())
|
||||
category = "External Page"; // Is this necessary?
|
||||
}
|
||||
xmlWriter().writeCharacters(category);
|
||||
@ -5977,8 +5997,7 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner)
|
||||
xmlWriter().writeAttribute("content",i.value());
|
||||
writeEndTag(); // </othermeta>
|
||||
}
|
||||
if ((tagStack.first() == DT_cxxClass && !inner->includes().isEmpty()) ||
|
||||
(inner->type() == Node::Document && inner->subType() == Node::HeaderFile)) {
|
||||
if ((tagStack.first() == DT_cxxClass && !inner->includes().isEmpty()) || inner->isHeaderFile()) {
|
||||
writeStartTag(DT_othermeta);
|
||||
xmlWriter().writeAttribute("name","includeFile");
|
||||
QString text;
|
||||
|
@ -315,6 +315,7 @@ protected:
|
||||
const Node* relative,
|
||||
CodeMarker* marker);
|
||||
virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker);
|
||||
virtual void generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker);
|
||||
virtual void generateDocNode(DocNode* dn, CodeMarker* marker);
|
||||
virtual void generateCollectionNode(CollectionNode* cn, CodeMarker* marker);
|
||||
virtual QString fileExtension() const;
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "openedlist.h"
|
||||
#include "quoter.h"
|
||||
#include "text.h"
|
||||
#include "atom.h"
|
||||
#include "tokenizer.h"
|
||||
#include <qdatetime.h>
|
||||
#include <qfile.h>
|
||||
@ -63,7 +64,6 @@ Q_GLOBAL_STATIC(QSet<QString>, null_Set_QString)
|
||||
Q_GLOBAL_STATIC(TopicList, nullTopicList)
|
||||
Q_GLOBAL_STATIC(QStringList, null_QStringList)
|
||||
Q_GLOBAL_STATIC(QList<Text>, null_QList_Text)
|
||||
//Q_GLOBAL_STATIC(QStringMap, null_QStringMap)
|
||||
Q_GLOBAL_STATIC(QStringMultiMap, null_QStringMultiMap)
|
||||
|
||||
struct Macro
|
||||
@ -477,6 +477,7 @@ private:
|
||||
void parseAlso();
|
||||
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);
|
||||
void appendChar(QChar ch);
|
||||
void appendWord(const QString &word);
|
||||
void appendToCode(const QString &code);
|
||||
@ -495,6 +496,7 @@ private:
|
||||
Doc::Sections getSectioningUnit();
|
||||
QString getArgument(bool verbatim = false);
|
||||
QString getBracedArgument(bool verbatim);
|
||||
QString getBracketedArgument();
|
||||
QString getOptionalArgument();
|
||||
QString getRestOfLine();
|
||||
QString getMetaCommandArgument(const QString &cmdStr);
|
||||
@ -504,6 +506,7 @@ private:
|
||||
|
||||
bool isBlankLine();
|
||||
bool isLeftBraceAhead();
|
||||
bool isLeftBracketAhead();
|
||||
void skipSpacesOnLine();
|
||||
void skipSpacesOrOneEndl();
|
||||
void skipAllSpaces();
|
||||
@ -965,9 +968,11 @@ void DocParser::parse(const QString& source,
|
||||
break;
|
||||
case CMD_L:
|
||||
enterPara();
|
||||
if (isLeftBracketAhead())
|
||||
p2 = getBracketedArgument();
|
||||
if (isLeftBraceAhead()) {
|
||||
p1 = getArgument();
|
||||
append(Atom::Link, p1);
|
||||
append(p1, p2);
|
||||
if (isLeftBraceAhead()) {
|
||||
currentLinkAtom = priv->text.lastAtom();
|
||||
startFormat(ATOM_FORMATTING_LINK, cmd);
|
||||
@ -980,7 +985,7 @@ void DocParser::parse(const QString& source,
|
||||
}
|
||||
else {
|
||||
p1 = getArgument();
|
||||
append(Atom::Link, p1);
|
||||
append(p1, p2);
|
||||
append(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
|
||||
append(Atom::String, cleanLink(p1));
|
||||
append(Atom::FormattingRight, ATOM_FORMATTING_LINK);
|
||||
@ -1984,6 +1989,17 @@ void DocParser::append(Atom::Type type, const QString& p1, const QString& p2)
|
||||
priv->text << Atom(type, p1, p2);
|
||||
}
|
||||
|
||||
void DocParser::append(const QString& p1, const QString& p2)
|
||||
{
|
||||
Atom::Type lastType = priv->text.lastAtom()->type();
|
||||
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);
|
||||
else
|
||||
priv->text << LinkAtom(p1, p2);
|
||||
}
|
||||
|
||||
void DocParser::appendChar(QChar ch)
|
||||
{
|
||||
if (priv->text.lastAtom()->type() != Atom::String)
|
||||
@ -2245,10 +2261,10 @@ Doc::Sections DocParser::getSectioningUnit()
|
||||
Gets an argument that is enclosed in braces and returns it
|
||||
without the enclosing braces. On entry, the current character
|
||||
is the left brace. On exit, the current character is the one
|
||||
that comes afterr the right brace.
|
||||
that comes after the right brace.
|
||||
|
||||
If \a verbatim is true, extra whitespace is retained in the
|
||||
returned string. Otherwise, extr whitespace is removed.
|
||||
returned string. Otherwise, extra whitespace is removed.
|
||||
*/
|
||||
QString DocParser::getBracedArgument(bool verbatim)
|
||||
{
|
||||
@ -2379,6 +2395,47 @@ QString DocParser::getArgument(bool verbatim)
|
||||
return arg.simplified();
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets an argument that is enclosed in brackets and returns it
|
||||
without the enclosing brackets. On entry, the current character
|
||||
is the left bracket. On exit, the current character is the one
|
||||
that comes after the right bracket.
|
||||
*/
|
||||
QString DocParser::getBracketedArgument()
|
||||
{
|
||||
QString arg;
|
||||
int delimDepth = 0;
|
||||
skipSpacesOrOneEndl();
|
||||
if (pos < in.length() && in[pos] == '[') {
|
||||
pos++;
|
||||
while (pos < in.length() && delimDepth >= 0) {
|
||||
switch (in[pos].unicode()) {
|
||||
case '[':
|
||||
delimDepth++;
|
||||
arg += QLatin1Char('[');
|
||||
pos++;
|
||||
break;
|
||||
case ']':
|
||||
delimDepth--;
|
||||
if (delimDepth >= 0)
|
||||
arg += QLatin1Char(']');
|
||||
pos++;
|
||||
break;
|
||||
case '\\':
|
||||
arg += in[pos];
|
||||
pos++;
|
||||
break;
|
||||
default:
|
||||
arg += in[pos];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (delimDepth > 0)
|
||||
location().warning(tr("Missing ']'"));
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
QString DocParser::getOptionalArgument()
|
||||
{
|
||||
skipSpacesOrOneEndl();
|
||||
@ -2527,6 +2584,20 @@ bool DocParser::isLeftBraceAhead()
|
||||
return numEndl < 2 && i < len && in[i] == '{';
|
||||
}
|
||||
|
||||
bool DocParser::isLeftBracketAhead()
|
||||
{
|
||||
int numEndl = 0;
|
||||
int i = pos;
|
||||
|
||||
while (i < len && in[i].isSpace() && numEndl < 2) {
|
||||
// ### bug with '\\'
|
||||
if (in[i] == '\n')
|
||||
numEndl++;
|
||||
i++;
|
||||
}
|
||||
return numEndl < 2 && i < len && in[i] == '[';
|
||||
}
|
||||
|
||||
/*!
|
||||
Skips to the next non-space character or EOL.
|
||||
*/
|
||||
|
@ -325,19 +325,6 @@ QString Generator::fileBase(const Node *node) const
|
||||
if (base.endsWith(".html"))
|
||||
base.truncate(base.length() - 5);
|
||||
|
||||
if (node->isQmlNode()) {
|
||||
if (!node->qmlModuleName().isEmpty()) {
|
||||
base.prepend(node->qmlModuleName() + QLatin1Char('-'));
|
||||
}
|
||||
/*
|
||||
To avoid file name conflicts in the html directory,
|
||||
we prepend a prefix (by default, "qml-") to the file name of QML
|
||||
element doc files.
|
||||
*/
|
||||
if ((node->subType() == Node::QmlClass) || (node->subType() == Node::QmlBasicType)) {
|
||||
base.prepend(outputPrefix(QLatin1String("QML")));
|
||||
}
|
||||
}
|
||||
if (node->isExample() || node->isExampleFile()) {
|
||||
QString modPrefix(node->moduleName());
|
||||
if (modPrefix.isEmpty()) {
|
||||
@ -349,6 +336,18 @@ QString Generator::fileBase(const Node *node) const
|
||||
base.append(QLatin1String("-example"));
|
||||
}
|
||||
}
|
||||
else if (node->isQmlType() || node->isQmlBasicType()) {
|
||||
base = node->name();
|
||||
if (!node->qmlModuleName().isEmpty()) {
|
||||
base.prepend(node->qmlModuleName() + QLatin1Char('-'));
|
||||
}
|
||||
/*
|
||||
To avoid file name conflicts in the html directory,
|
||||
we prepend a prefix (by default, "qml-") to the file name of QML
|
||||
element doc files.
|
||||
*/
|
||||
base.prepend(outputPrefix(QLatin1String("QML")));
|
||||
}
|
||||
else if (node->isCollectionNode()) {
|
||||
base = node->name();
|
||||
if (base.endsWith(".html"))
|
||||
@ -367,7 +366,7 @@ QString Generator::fileBase(const Node *node) const
|
||||
forever {
|
||||
const Node *pp = p->parent();
|
||||
base.prepend(p->name());
|
||||
if (!pp || pp->name().isEmpty() || pp->type() == Node::Document)
|
||||
if (!pp || pp->name().isEmpty() || pp->isDocNode())
|
||||
break;
|
||||
base.prepend(QLatin1Char('-'));
|
||||
p = pp;
|
||||
@ -467,25 +466,23 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
else if (node->isDocNode() || node->isCollectionNode()) {
|
||||
if (node->isQmlType() || node->isQmlBasicType()) {
|
||||
QString fb = fileBase(node);
|
||||
if (fb.startsWith(Generator::outputPrefix(QLatin1String("QML"))))
|
||||
return fb + QLatin1Char('.') + currentGenerator()->fileExtension();
|
||||
else {
|
||||
QString mq;
|
||||
if (!node->qmlModuleName().isEmpty()) {
|
||||
mq = node->qmlModuleName().replace(QChar('.'),QChar('-'));
|
||||
mq = mq.toLower() + QLatin1Char('-');
|
||||
}
|
||||
return fdl+ Generator::outputPrefix(QLatin1String("QML")) + mq +
|
||||
fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
|
||||
}
|
||||
}
|
||||
else if (node->isQmlType() || node->isQmlBasicType()) {
|
||||
QString fb = fileBase(node);
|
||||
if (fb.startsWith(Generator::outputPrefix(QLatin1String("QML"))))
|
||||
return fb + QLatin1Char('.') + currentGenerator()->fileExtension();
|
||||
else {
|
||||
parentName = fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
|
||||
QString mq;
|
||||
if (!node->qmlModuleName().isEmpty()) {
|
||||
mq = node->qmlModuleName().replace(QChar('.'),QChar('-'));
|
||||
mq = mq.toLower() + QLatin1Char('-');
|
||||
}
|
||||
return fdl+ Generator::outputPrefix(QLatin1String("QML")) + mq +
|
||||
fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
|
||||
}
|
||||
}
|
||||
else if (node->isDocNode() || node->isCollectionNode()) {
|
||||
parentName = fileBase(node) + QLatin1Char('.') + currentGenerator()->fileExtension();
|
||||
}
|
||||
else if (fileBase(node).isEmpty())
|
||||
return QString();
|
||||
|
||||
@ -562,6 +559,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
|
||||
case Node::Variable:
|
||||
anchorRef = QLatin1Char('#') + node->name() + "-var";
|
||||
break;
|
||||
case Node::QmlType:
|
||||
case Node::Document:
|
||||
case Node::Group:
|
||||
case Node::Module:
|
||||
@ -577,7 +575,8 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
|
||||
}
|
||||
|
||||
// Various objects can be compat (deprecated) or obsolete.
|
||||
if (node->type() != Node::Class && node->type() != Node::Namespace) {
|
||||
// Is this even correct?
|
||||
if (!node->isClass() && !node->isNamespace()) {
|
||||
switch (node->status()) {
|
||||
case Node::Compat:
|
||||
parentName.replace(QLatin1Char('.') + currentGenerator()->fileExtension(),
|
||||
@ -682,6 +681,10 @@ const Atom *Generator::generateAtomList(const Atom *atom,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Generate the body of the documentation from the qdoc comment
|
||||
found with the entity represented by the \a node.
|
||||
*/
|
||||
void Generator::generateBody(const Node *node, CodeMarker *marker)
|
||||
{
|
||||
bool quiet = false;
|
||||
@ -812,9 +815,9 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
|
||||
}
|
||||
}
|
||||
|
||||
if (node->type() == Node::Document) {
|
||||
if (node->isDocNode()) {
|
||||
const DocNode *dn = static_cast<const DocNode *>(node);
|
||||
if (dn->subType() == Node::Example) {
|
||||
if (dn->isExample()) {
|
||||
generateExampleFiles(dn, marker);
|
||||
}
|
||||
else if (dn->subType() == Node::File) {
|
||||
@ -968,6 +971,9 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker)
|
||||
/*!
|
||||
Recursive writing of HTML files from the root \a node.
|
||||
|
||||
\note DitaXmlGenerator overrides this function, but
|
||||
HtmlGenerator does not.
|
||||
|
||||
\note NameCollisionNodes are skipped here and processed
|
||||
later. See HtmlGenerator::generateCollisionPages() for
|
||||
more on this.
|
||||
@ -981,7 +987,7 @@ void Generator::generateInnerNode(InnerNode* node)
|
||||
if (node->isInternal() && !showInternal_)
|
||||
return;
|
||||
|
||||
if (node->type() == Node::Document) {
|
||||
if (node->isDocNode()) {
|
||||
DocNode* docNode = static_cast<DocNode*>(node);
|
||||
if (docNode->subType() == Node::ExternalPage)
|
||||
return;
|
||||
@ -992,7 +998,7 @@ void Generator::generateInnerNode(InnerNode* node)
|
||||
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
|
||||
}
|
||||
}
|
||||
else if (node->type() == Node::QmlPropertyGroup)
|
||||
else if (node->isQmlPropertyGroup())
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -1016,11 +1022,23 @@ void Generator::generateInnerNode(InnerNode* node)
|
||||
generateClassLikeNode(node, marker);
|
||||
endSubPage();
|
||||
}
|
||||
if (node->isQmlType()) {
|
||||
beginSubPage(node, fileName(node));
|
||||
QmlClassNode* qcn = static_cast<QmlClassNode*>(node);
|
||||
generateQmlTypePage(qcn, marker);
|
||||
endSubPage();
|
||||
}
|
||||
else if (node->isDocNode()) {
|
||||
beginSubPage(node, fileName(node));
|
||||
generateDocNode(static_cast<DocNode*>(node), marker);
|
||||
endSubPage();
|
||||
}
|
||||
else if (node->isQmlBasicType()) {
|
||||
beginSubPage(node, fileName(node));
|
||||
QmlBasicTypeNode* qbtn = static_cast<QmlBasicTypeNode*>(node);
|
||||
generateQmlBasicTypePage(qbtn, marker);
|
||||
endSubPage();
|
||||
}
|
||||
else if (node->isCollectionNode()) {
|
||||
CollectionNode* cn = static_cast<CollectionNode*>(node);
|
||||
/*
|
||||
@ -1243,6 +1261,11 @@ void Generator::generateStatus(const Node *node, CodeMarker *marker)
|
||||
generateText(text, node, marker);
|
||||
}
|
||||
|
||||
/*!
|
||||
Generate the documentation for \a relative. i.e. \a relative
|
||||
is the node that reporesentas the entity where a qdoc comment
|
||||
was found, and \a text represents the qdoc comment.
|
||||
*/
|
||||
bool Generator::generateText(const Text& text,
|
||||
const Node *relative,
|
||||
CodeMarker *marker)
|
||||
@ -1420,7 +1443,14 @@ Generator *Generator::generatorForFormat(const QString& format)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*!
|
||||
This function might be useless now with the addition of
|
||||
multiple node trees. It is called a few hundred times,
|
||||
but it never finds a collision node. The single call has
|
||||
been commented out by mws (19/05/2014). If it is no
|
||||
longer needed, it will be removed.
|
||||
|
||||
This function can be called if getLink() returns an empty
|
||||
string. It tests the \a atom string to see if it is a link
|
||||
of the form <element> :: <name>, where <element> is a QML
|
||||
@ -1452,7 +1482,7 @@ QString Generator::getCollisionLink(const Atom* atom)
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Looks up the tag \a t in the map of metadata values for the
|
||||
@ -1982,17 +2012,12 @@ QString Generator::typeString(const Node *node)
|
||||
return "namespace";
|
||||
case Node::Class:
|
||||
return "class";
|
||||
case Node::QmlType:
|
||||
return "type";
|
||||
case Node::QmlBasicType:
|
||||
return "type";
|
||||
case Node::Document:
|
||||
{
|
||||
switch (node->subType()) {
|
||||
case Node::QmlClass:
|
||||
return "type";
|
||||
case Node::QmlBasicType:
|
||||
return "type";
|
||||
default:
|
||||
return "documentation";
|
||||
}
|
||||
}
|
||||
return "documentation";
|
||||
case Node::Enum:
|
||||
return "enum";
|
||||
case Node::Typedef:
|
||||
|
@ -114,6 +114,8 @@ protected:
|
||||
virtual int generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker);
|
||||
virtual void generateBody(const Node *node, CodeMarker *marker);
|
||||
virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker);
|
||||
virtual void generateQmlTypePage(QmlClassNode* , CodeMarker* ) { }
|
||||
virtual void generateQmlBasicTypePage(QmlBasicTypeNode* , CodeMarker* ) { }
|
||||
virtual void generateDocNode(DocNode* dn, CodeMarker* marker);
|
||||
virtual void generateCollectionNode(CollectionNode* cn, CodeMarker* marker);
|
||||
virtual void generateInheritedBy(const ClassNode *classe, CodeMarker *marker);
|
||||
@ -155,7 +157,7 @@ protected:
|
||||
void generateSince(const Node *node, CodeMarker *marker);
|
||||
void generateStatus(const Node *node, CodeMarker *marker);
|
||||
void generateThreadSafeness(const Node *node, CodeMarker *marker);
|
||||
QString getCollisionLink(const Atom* atom);
|
||||
//QString getCollisionLink(const Atom* atom);
|
||||
QString getMetadataElement(const InnerNode* inner, const QString& t);
|
||||
QStringList getMetadataElements(const InnerNode* inner, const QString& t);
|
||||
QString indent(int level, const QString& markedCode);
|
||||
|
@ -139,6 +139,8 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
|
||||
typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
|
||||
typeHash["qmlmethod"] = Node::QmlMethod;
|
||||
typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
|
||||
typeHash["qmlclass"] = Node::QmlType;
|
||||
typeHash["qmlbasictype"] = Node::QmlBasicType;
|
||||
|
||||
QHash<QString, Node::SubType> subTypeHash;
|
||||
subTypeHash["example"] = Node::Example;
|
||||
@ -146,8 +148,6 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
|
||||
subTypeHash["file"] = Node::File;
|
||||
subTypeHash["page"] = Node::Page;
|
||||
subTypeHash["externalpage"] = Node::ExternalPage;
|
||||
subTypeHash["qmlclass"] = Node::QmlClass;
|
||||
subTypeHash["qmlbasictype"] = Node::QmlBasicType;
|
||||
|
||||
QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
|
||||
|
||||
@ -211,16 +211,14 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
|
||||
// "id"
|
||||
details << node->parent()->name()+"::"+node->name();
|
||||
}
|
||||
else if (node->type() == Node::Document) {
|
||||
else if (node->isQmlType() || node->isQmlBasicType()) {
|
||||
details << node->name();
|
||||
details << "QML." + node->name();
|
||||
}
|
||||
else if (node->isDocNode()) {
|
||||
const DocNode *fake = static_cast<const DocNode *>(node);
|
||||
if (fake->subType() == Node::QmlClass) {
|
||||
details << (QmlClassNode::qmlOnly ? fake->name() : fake->fullTitle());
|
||||
details << "QML." + fake->name();
|
||||
}
|
||||
else {
|
||||
details << fake->fullTitle();
|
||||
details << fake->fullTitle();
|
||||
}
|
||||
details << fake->fullTitle();
|
||||
details << fake->fullTitle();
|
||||
}
|
||||
else {
|
||||
details << node->name();
|
||||
@ -248,7 +246,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
|
||||
return false;
|
||||
|
||||
QString objName;
|
||||
if (node->type() == Node::Document) {
|
||||
if (node->isDocNode()) {
|
||||
const DocNode *fake = static_cast<const DocNode *>(node);
|
||||
objName = fake->fullTitle();
|
||||
}
|
||||
@ -288,6 +286,25 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
|
||||
project.keywords.append(keywordDetails(node));
|
||||
project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
|
||||
break;
|
||||
case Node::QmlType:
|
||||
case Node::QmlBasicType:
|
||||
if (node->doc().hasKeywords()) {
|
||||
foreach (const Atom* keyword, node->doc().keywords()) {
|
||||
if (!keyword->string().isEmpty()) {
|
||||
QStringList details;
|
||||
details << keyword->string()
|
||||
<< keyword->string()
|
||||
<< gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()) +
|
||||
QLatin1Char('#') + Doc::canonicalTitle(keyword->string());
|
||||
project.keywords.append(details);
|
||||
}
|
||||
else
|
||||
node->doc().location().warning(tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs())));
|
||||
}
|
||||
}
|
||||
project.keywords.append(keywordDetails(node));
|
||||
project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
|
||||
break;
|
||||
|
||||
case Node::Namespace:
|
||||
project.keywords.append(keywordDetails(node));
|
||||
@ -558,17 +575,14 @@ void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &write
|
||||
if (href.isEmpty())
|
||||
return;
|
||||
|
||||
Node::SubType subType = static_cast<const DocNode*>(node)->subType();
|
||||
|
||||
bool derivedClass = false;
|
||||
if (node->type() == Node::Class)
|
||||
derivedClass = !(static_cast<const ClassNode *>(node)->baseClasses().isEmpty());
|
||||
|
||||
// Do not generate a 'List of all members' for namespaces or header files,
|
||||
// but always generate it for derived classes and QML classes
|
||||
if (node->type() != Node::Namespace && subType != Node::HeaderFile &&
|
||||
(derivedClass || subType == Node::QmlClass ||
|
||||
!project.memberStatus[node].isEmpty())) {
|
||||
if (!node->isNamespace() && !node->isHeaderFile() &&
|
||||
(derivedClass || node->isQmlType() || !project.memberStatus[node].isEmpty())) {
|
||||
QString membersPath = href + QStringLiteral("-members.html");
|
||||
project.files.insert(membersPath);
|
||||
if (writeSections)
|
||||
@ -612,6 +626,14 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
|
||||
writeSection(writer, href, objName);
|
||||
break;
|
||||
|
||||
case Node::QmlType:
|
||||
writer.writeStartElement("section");
|
||||
writer.writeAttribute("ref", href);
|
||||
writer.writeAttribute("title", tr("%1 Type Reference").arg(node->fullTitle()));
|
||||
addMembers(project, writer, node);
|
||||
writer.writeEndElement(); // section
|
||||
break;
|
||||
|
||||
case Node::Document: {
|
||||
// Document nodes (such as manual pages) contain subtypes, titles and other
|
||||
// attributes.
|
||||
@ -619,12 +641,9 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
|
||||
|
||||
writer.writeStartElement("section");
|
||||
writer.writeAttribute("ref", href);
|
||||
if (docNode->subType() == Node::QmlClass)
|
||||
writer.writeAttribute("title", tr("%1 Type Reference").arg(docNode->fullTitle()));
|
||||
else
|
||||
writer.writeAttribute("title", docNode->fullTitle());
|
||||
writer.writeAttribute("title", docNode->fullTitle());
|
||||
|
||||
if ((docNode->subType() == Node::HeaderFile) || (docNode->subType() == Node::QmlClass))
|
||||
if (docNode->subType() == Node::HeaderFile)
|
||||
addMembers(project, writer, node);
|
||||
|
||||
writer.writeEndElement(); // section
|
||||
@ -695,7 +714,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
|
||||
writer.writeStartElement("section");
|
||||
const Node* node = qdb_->findDocNodeByTitle(project.indexTitle);
|
||||
if (node == 0)
|
||||
node = qdb_->findNodeByNameAndType(QStringList("index.html"), Node::Document, Node::Page);
|
||||
node = qdb_->findNodeByNameAndType(QStringList("index.html"), Node::Document);
|
||||
QString indexPath;
|
||||
// Never use a collision node as a landing page
|
||||
if (node && !node->isCollisionNode())
|
||||
|
@ -268,7 +268,7 @@ QString HtmlGenerator::format()
|
||||
*/
|
||||
void HtmlGenerator::generateDocs()
|
||||
{
|
||||
Node* qflags = qdb_->findNodeByNameAndType(QStringList("QFlags"), Node::Class, Node::NoSubType);
|
||||
Node* qflags = qdb_->findClassNode(QStringList("QFlags"));
|
||||
if (qflags)
|
||||
qflagsHref_ = linkForNode(qflags,0);
|
||||
if (!runPrepareOnly()) {
|
||||
@ -315,17 +315,22 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|
||||
case Atom::AutoLink:
|
||||
if (!inLink_ && !inContents_ && !inSectionHeading_) {
|
||||
const Node *node = 0;
|
||||
QString link = getLink(atom, relative, &node);
|
||||
if (!link.isEmpty()) {
|
||||
QString link = getAutoLink(atom, relative, &node);
|
||||
if (link.isEmpty()) {
|
||||
if (autolinkErrors())
|
||||
relative->doc().location().warning(tr("Can't autolink to '%1'").arg(atom->string()));
|
||||
}
|
||||
else if (node && node->status() == Node::Obsolete) {
|
||||
if ((relative->parent() != node) && !relative->isObsolete())
|
||||
link.clear();
|
||||
}
|
||||
if (link.isEmpty())
|
||||
out() << protectEnc(atom->string());
|
||||
else {
|
||||
beginLink(link, node, relative);
|
||||
generateLink(atom, marker);
|
||||
endLink();
|
||||
}
|
||||
else {
|
||||
out() << protectEnc(atom->string());
|
||||
if (autolinkErrors())
|
||||
relative->doc().location().warning(tr("Can't autolink to '%1'").arg(atom->string()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
out() << protectEnc(atom->string());
|
||||
@ -334,11 +339,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|
||||
case Atom::BaseName:
|
||||
break;
|
||||
case Atom::BriefLeft:
|
||||
if (relative->type() == Node::Document) {
|
||||
if (relative->subType() != Node::Example) {
|
||||
skipAhead = skipAtoms(atom, Atom::BriefRight);
|
||||
break;
|
||||
}
|
||||
if (relative->isQmlBasicType() || (relative->isDocNode() && !relative->isExample())) {
|
||||
skipAhead = skipAtoms(atom, Atom::BriefRight);
|
||||
break;
|
||||
}
|
||||
|
||||
out() << "<p>";
|
||||
@ -372,7 +375,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|
||||
}
|
||||
break;
|
||||
case Atom::BriefRight:
|
||||
if (relative->type() != Node::Document)
|
||||
if (!relative->isDocNode())
|
||||
out() << "</p>\n";
|
||||
break;
|
||||
case Atom::C:
|
||||
@ -602,10 +605,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|
||||
while (n != nsmap.constEnd()) {
|
||||
const Node* node = n.value();
|
||||
switch (node->type()) {
|
||||
case Node::Document:
|
||||
if (node->subType() == Node::QmlClass) {
|
||||
sections[QmlClass].appendMember((Node*)node);
|
||||
}
|
||||
case Node::QmlType:
|
||||
sections[QmlClass].appendMember((Node*)node);
|
||||
break;
|
||||
case Node::Namespace:
|
||||
sections[Namespace].appendMember((Node*)node);
|
||||
@ -761,8 +762,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|
||||
out() << " alt=\"\"";
|
||||
out() << " />";
|
||||
helpProjectWriter->addExtraFile(fileName);
|
||||
if ((relative->type() == Node::Document) &&
|
||||
(relative->subType() == Node::Example)) {
|
||||
if (relative->isExample()) {
|
||||
const ExampleNode* cen = static_cast<const ExampleNode*>(relative);
|
||||
if (cen->imageFileName().isEmpty()) {
|
||||
ExampleNode* en = const_cast<ExampleNode*>(cen);
|
||||
@ -805,17 +805,26 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|
||||
break;
|
||||
case Atom::Link:
|
||||
{
|
||||
inObsoleteLink = false;
|
||||
const Node *node = 0;
|
||||
QString myLink = getLink(atom, relative, &node);
|
||||
if (myLink.isEmpty()) {
|
||||
myLink = getCollisionLink(atom);
|
||||
if (myLink.isEmpty() && !noLinkErrors()) {
|
||||
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
|
||||
}
|
||||
else
|
||||
node = 0;
|
||||
QString link = getLink(atom, relative, &node);
|
||||
if (link.isEmpty() && !noLinkErrors()) {
|
||||
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
|
||||
}
|
||||
beginLink(myLink, node, relative);
|
||||
else {
|
||||
node = 0;
|
||||
if (node && node->status() == Node::Obsolete) {
|
||||
if ((relative->parent() != node) && !relative->isObsolete()) {
|
||||
inObsoleteLink = true;
|
||||
if (obsoleteLinks) {
|
||||
relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
|
||||
.arg(atom->string())
|
||||
.arg(relative->plainFullName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
beginLink(link, node, relative);
|
||||
skipAhead = 1;
|
||||
}
|
||||
break;
|
||||
@ -1128,7 +1137,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
|
||||
}
|
||||
|
||||
/*!
|
||||
Generate a reference page for a C++ class.
|
||||
Generate a reference page for a C++ class or a C++ namespace.
|
||||
*/
|
||||
void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
|
||||
{
|
||||
@ -1314,6 +1323,97 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
|
||||
generateFooter(inner);
|
||||
}
|
||||
|
||||
/*!
|
||||
Generate the HTML page for a QML type. \qcn is the QML type.
|
||||
\marker is the code markeup object.
|
||||
*/
|
||||
void HtmlGenerator::generateQmlTypePage(QmlClassNode* qcn, CodeMarker* marker)
|
||||
{
|
||||
SubTitleSize subTitleSize = LargeSubTitle;
|
||||
QList<Section>::const_iterator s;
|
||||
QString fullTitle = qcn->fullTitle();
|
||||
QString htmlTitle = fullTitle;
|
||||
|
||||
generateHeader(htmlTitle, qcn, marker);
|
||||
QList<Section> sections = marker->qmlSections(qcn, CodeMarker::Summary);
|
||||
generateTableOfContents(qcn, marker, §ions);
|
||||
marker = CodeMarker::markerForLanguage(QLatin1String("QML"));
|
||||
generateTitle(fullTitle, Text() << qcn->subTitle(), subTitleSize, qcn, marker);
|
||||
generateBrief(qcn, marker);
|
||||
generateQmlRequisites(qcn, marker);
|
||||
|
||||
QString allQmlMembersLink = generateAllQmlMembersFile(qcn, marker);
|
||||
if (!allQmlMembersLink.isEmpty()) {
|
||||
out() << "<ul>\n";
|
||||
out() << "<li><a href=\"" << allQmlMembersLink << "\">"
|
||||
<< "List of all members, including inherited members</a></li>\n";
|
||||
out() << "</ul>\n";
|
||||
}
|
||||
|
||||
s = sections.constBegin();
|
||||
while (s != sections.constEnd()) {
|
||||
out() << "<a name=\"" << registerRef((*s).name.toLower())
|
||||
<< "\"></a>" << divNavTop << '\n';
|
||||
out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
|
||||
generateQmlSummary(*s, qcn, marker);
|
||||
++s;
|
||||
}
|
||||
|
||||
generateExtractionMark(qcn, DetailedDescriptionMark);
|
||||
out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << '\n';
|
||||
out() << "<h2>" << "Detailed Description" << "</h2>\n";
|
||||
generateBody(qcn, marker);
|
||||
ClassNode* cn = qcn->classNode();
|
||||
if (cn)
|
||||
generateQmlText(cn->doc().body(), cn, marker, qcn->name());
|
||||
generateAlsoList(qcn, marker);
|
||||
generateExtractionMark(qcn, EndMark);
|
||||
//out() << "<hr />\n";
|
||||
|
||||
sections = marker->qmlSections(qcn,CodeMarker::Detailed);
|
||||
s = sections.constBegin();
|
||||
while (s != sections.constEnd()) {
|
||||
out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
|
||||
NodeList::ConstIterator m = (*s).members.constBegin();
|
||||
while (m != (*s).members.constEnd()) {
|
||||
generateDetailedQmlMember(*m, qcn, marker);
|
||||
out() << "<br/>\n";
|
||||
++m;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
generateFooter(qcn);
|
||||
}
|
||||
|
||||
/*!
|
||||
Generate the HTML page for the QML basic type represented
|
||||
by the QML basic type node \a qbtn.
|
||||
*/
|
||||
void HtmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker)
|
||||
{
|
||||
SubTitleSize subTitleSize = LargeSubTitle;
|
||||
QList<Section>::const_iterator s;
|
||||
QString htmlTitle = qbtn->fullTitle();
|
||||
QString fullTitle = "QML Basic Type: " + htmlTitle;
|
||||
|
||||
marker = CodeMarker::markerForLanguage(QLatin1String("QML"));
|
||||
|
||||
generateHeader(htmlTitle, qbtn, marker);
|
||||
generateTitle(fullTitle,
|
||||
Text() << qbtn->subTitle(),
|
||||
subTitleSize,
|
||||
qbtn,
|
||||
marker);
|
||||
generateExtractionMark(qbtn, DetailedDescriptionMark);
|
||||
out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504
|
||||
|
||||
generateBody(qbtn, marker);
|
||||
out() << "</div>\n"; // QTBUG-9504
|
||||
generateAlsoList(qbtn, marker);
|
||||
generateExtractionMark(qbtn, EndMark);
|
||||
generateFooter(qbtn);
|
||||
}
|
||||
|
||||
/*!
|
||||
We delayed generation of the disambiguation pages until now, after
|
||||
all the other pages have been generated. We do this because we might
|
||||
@ -1447,31 +1547,14 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
|
||||
QList<Section>::const_iterator s;
|
||||
QString fullTitle = dn->fullTitle();
|
||||
|
||||
if (dn->subType() == Node::QmlBasicType) {
|
||||
fullTitle = "QML Basic Type: " + fullTitle;
|
||||
|
||||
// Replace the marker with a QML code marker.
|
||||
marker = CodeMarker::markerForLanguage(QLatin1String("QML"));
|
||||
}
|
||||
else if (dn->subType() == Node::QmlClass) {
|
||||
fullTitle = fullTitle + " QML Type";
|
||||
}
|
||||
|
||||
generateHeader(fullTitle, dn, marker);
|
||||
/*
|
||||
Generate the TOC for the new doc format.
|
||||
Don't generate a TOC for the home page.
|
||||
*/
|
||||
QmlClassNode* qml_cn = 0;
|
||||
if (dn->subType() == Node::QmlClass) {
|
||||
qml_cn = static_cast<QmlClassNode*>(dn);
|
||||
sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
|
||||
generateTableOfContents(dn,marker,§ions);
|
||||
|
||||
// Replace the marker with a QML code marker.
|
||||
marker = CodeMarker::markerForLanguage(QLatin1String("QML"));
|
||||
}
|
||||
else if (dn->subType() != Node::Collision && dn->name() != QString("index.html") && dn->name() != QString("qtexamplesandtutorials.html"))
|
||||
if ((dn->subType() != Node::Collision) &&
|
||||
(dn->name() != QString("index.html")) &&
|
||||
(dn->name() != QString("qtexamplesandtutorials.html")))
|
||||
generateTableOfContents(dn,marker,0);
|
||||
|
||||
generateTitle(fullTitle,
|
||||
@ -1510,53 +1593,6 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
|
||||
|
||||
out() << "</ul>\n";
|
||||
}
|
||||
else if (dn->subType() == Node::QmlClass) {
|
||||
ClassNode* cn = qml_cn->classNode();
|
||||
generateBrief(qml_cn, marker);
|
||||
generateQmlRequisites(qml_cn, marker);
|
||||
|
||||
QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker);
|
||||
if (!allQmlMembersLink.isEmpty()) {
|
||||
out() << "<ul>\n";
|
||||
out() << "<li><a href=\"" << allQmlMembersLink << "\">"
|
||||
<< "List of all members, including inherited members</a></li>\n";
|
||||
out() << "</ul>\n";
|
||||
}
|
||||
|
||||
s = sections.constBegin();
|
||||
while (s != sections.constEnd()) {
|
||||
out() << "<a name=\"" << registerRef((*s).name.toLower())
|
||||
<< "\"></a>" << divNavTop << '\n';
|
||||
out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
|
||||
generateQmlSummary(*s,dn,marker);
|
||||
++s;
|
||||
}
|
||||
|
||||
generateExtractionMark(dn, DetailedDescriptionMark);
|
||||
out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << '\n';
|
||||
out() << "<h2>" << "Detailed Description" << "</h2>\n";
|
||||
generateBody(dn, marker);
|
||||
if (cn)
|
||||
generateQmlText(cn->doc().body(), cn, marker, dn->name());
|
||||
generateAlsoList(dn, marker);
|
||||
generateExtractionMark(dn, EndMark);
|
||||
//out() << "<hr />\n";
|
||||
|
||||
sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
|
||||
s = sections.constBegin();
|
||||
while (s != sections.constEnd()) {
|
||||
out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
|
||||
NodeList::ConstIterator m = (*s).members.constBegin();
|
||||
while (m != (*s).members.constEnd()) {
|
||||
generateDetailedQmlMember(*m, dn, marker);
|
||||
out() << "<br/>\n";
|
||||
++m;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
generateFooter(dn);
|
||||
return;
|
||||
}
|
||||
|
||||
sections = marker->sections(dn, CodeMarker::Summary, CodeMarker::Okay);
|
||||
s = sections.constBegin();
|
||||
@ -1707,7 +1743,7 @@ void HtmlGenerator::generateNavigationBar(const QString &title,
|
||||
<< Atom(Atom::AutoLink, landingpage)
|
||||
<< Atom(Atom::ListItemRight);
|
||||
|
||||
if (node->type() == Node::Class) {
|
||||
if (node->isClass()) {
|
||||
const ClassNode *cn = static_cast<const ClassNode *>(node);
|
||||
QString name = node->moduleName();
|
||||
|
||||
@ -1724,18 +1760,27 @@ void HtmlGenerator::generateNavigationBar(const QString &title,
|
||||
<< Atom(Atom::String, cn->name())
|
||||
<< Atom(Atom::ListItemRight);
|
||||
}
|
||||
else if (node->type() == Node::Document) {
|
||||
else if (node->isQmlType()) {
|
||||
if (!qmltypespage.isEmpty())
|
||||
navigationbar << Atom(Atom::ListItemLeft)
|
||||
<< Atom(Atom::Link, qmltypespage)
|
||||
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
|
||||
<< Atom(Atom::String, QLatin1String("QML Types"))
|
||||
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
|
||||
<< Atom(Atom::ListItemRight);
|
||||
}
|
||||
else if (node->isQmlBasicType()) {
|
||||
if (!qmltypespage.isEmpty())
|
||||
navigationbar << Atom(Atom::ListItemLeft)
|
||||
<< Atom(Atom::Link, qmltypespage)
|
||||
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
|
||||
<< Atom(Atom::String, QLatin1String("QML Types"))
|
||||
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
|
||||
<< Atom(Atom::ListItemRight);
|
||||
}
|
||||
else if (node->isDocNode()) {
|
||||
const DocNode *dn = static_cast<const DocNode *>(node);
|
||||
if (node->subType() == Node::QmlClass || node->subType() == Node::QmlBasicType) {
|
||||
if (!qmltypespage.isEmpty())
|
||||
navigationbar << Atom(Atom::ListItemLeft)
|
||||
<< Atom(Atom::Link, qmltypespage)
|
||||
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
|
||||
<< Atom(Atom::String, QLatin1String("QML Types"))
|
||||
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
|
||||
<< Atom(Atom::ListItemRight);
|
||||
}
|
||||
else if (dn && dn->isExampleFile()) {
|
||||
if (dn && dn->isExampleFile()) {
|
||||
navigationbar << Atom(Atom::ListItemLeft)
|
||||
<< Atom(Atom::Link, dn->parent()->name())
|
||||
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
|
||||
@ -2732,7 +2777,7 @@ void HtmlGenerator::generateCompactList(ListType listType,
|
||||
}
|
||||
|
||||
QStringList pieces;
|
||||
if (it.value()->subType() == Node::QmlClass)
|
||||
if (it.value()->isQmlType())
|
||||
pieces << it.value()->name();
|
||||
else
|
||||
pieces = it.value()->fullName(relative).split("::");
|
||||
@ -3214,8 +3259,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
|
||||
par1 = QStringRef();
|
||||
const Node* n = qdb_->resolveType(arg.toString(), relative);
|
||||
html += QLatin1String("<span class=\"type\">");
|
||||
if (n && n->subType() == Node::QmlBasicType) {
|
||||
if (relative && relative->subType() == Node::QmlClass)
|
||||
if (n && n->isQmlBasicType()) {
|
||||
if (relative && relative->isQmlType())
|
||||
addLink(linkForNode(n,relative), arg, &html);
|
||||
else
|
||||
html += arg.toString();
|
||||
@ -3576,7 +3621,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
|
||||
|
||||
QString fn = fileName(node);
|
||||
if (node && relative && node->parent() != relative) {
|
||||
if (node->parent()->subType() == Node::QmlClass && relative->subType() == Node::QmlClass) {
|
||||
if (node->parent()->isQmlType() && relative->isQmlType()) {
|
||||
if (node->parent()->isAbstract()) {
|
||||
/*
|
||||
This is a bit of a hack. What we discover with
|
||||
@ -3719,6 +3764,7 @@ int HtmlGenerator::hOffset(const Node *node)
|
||||
case Node::Namespace:
|
||||
case Node::Class:
|
||||
return 2;
|
||||
case Node::QmlType:
|
||||
case Node::Document:
|
||||
return 1;
|
||||
case Node::Enum:
|
||||
@ -3754,32 +3800,48 @@ 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)
|
||||
{
|
||||
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(); // It's some kind of protocol.
|
||||
return atom->string(); // It's some kind of protocol.
|
||||
}
|
||||
else {
|
||||
QStringList path;
|
||||
if (atom->string().contains('#'))
|
||||
path = atom->string().split('#'); // The target is in the html file.
|
||||
else
|
||||
path.append(atom->string()); // It's a general case target.
|
||||
|
||||
QString ref;
|
||||
QString first = path.first().trimmed();
|
||||
if (first.isEmpty())
|
||||
*node = relative;
|
||||
else if (first.endsWith(".html")) // The target is an html file.
|
||||
*node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document, Node::NoSubType);
|
||||
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);
|
||||
}
|
||||
@ -3795,71 +3857,77 @@ QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, const Nod
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*node) {
|
||||
if (!(*node)->url().isEmpty())
|
||||
return (*node)->url();
|
||||
else
|
||||
path.removeFirst();
|
||||
}
|
||||
else
|
||||
*node = relative;
|
||||
}
|
||||
if (!(*node))
|
||||
return link; // empty
|
||||
|
||||
if (*node) {
|
||||
if ((*node)->status() == Node::Obsolete) {
|
||||
if (relative) {
|
||||
if (relative->parent() != *node) {
|
||||
if (relative->status() != Node::Obsolete) {
|
||||
bool porting = false;
|
||||
if (relative->type() == Node::Document) {
|
||||
const DocNode* dn = static_cast<const DocNode*>(relative);
|
||||
if (dn->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug() << "Link to Obsolete entity" << (*node)->name() << "no relative";
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This loop really only makes sense if *node is not 0.
|
||||
In that case, The node *node points to represents a
|
||||
qdoc page, so the link will ultimately point to some
|
||||
target on that page. This loop finds that target on
|
||||
the page that *node represents. ref is that target.
|
||||
*/
|
||||
while (!path.isEmpty()) {
|
||||
ref = qdb_->findTarget(path.first(), *node);
|
||||
if (ref.isEmpty())
|
||||
break;
|
||||
path.removeFirst();
|
||||
}
|
||||
|
||||
/*
|
||||
Given that *node is not null, we now cconstruct a link
|
||||
to the page that *node represents, and then if there is
|
||||
a target on that page, we connect the target to the link
|
||||
with '#'.
|
||||
*/
|
||||
if (path.isEmpty()) {
|
||||
link = linkForNode(*node, relative);
|
||||
if (*node && (*node)->subType() == Node::Image)
|
||||
link = "images/used-in-examples/" + link;
|
||||
if (!ref.isEmpty())
|
||||
link += QLatin1Char('#') + ref;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*node))
|
||||
return link; // empty
|
||||
|
||||
if (!(*node)->url().isEmpty())
|
||||
return (*node)->url();
|
||||
|
||||
link = linkForNode(*node, relative);
|
||||
if (!ref.isEmpty())
|
||||
link += QLatin1Char('#') + ref;
|
||||
return link;
|
||||
}
|
||||
|
||||
@ -3884,19 +3952,7 @@ void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker)
|
||||
<< "We strongly advise against "
|
||||
<< "using it in new code. See ";
|
||||
|
||||
const DocNode *docNode = qdb_->findDocNodeByTitle("Porting To Qt 4");
|
||||
QString ref;
|
||||
if (docNode && node->type() == Node::Class) {
|
||||
QString oldName(node->name());
|
||||
oldName.remove(QLatin1Char('3'));
|
||||
ref = qdb_->findTarget(oldName, docNode);
|
||||
}
|
||||
|
||||
if (!ref.isEmpty()) {
|
||||
text << Atom(Atom::Link, linkForNode(docNode, node) + QLatin1Char('#') + ref);
|
||||
}
|
||||
else
|
||||
text << Atom(Atom::Link, "Porting to Qt 4");
|
||||
text << Atom(Atom::Link, "Porting to Qt 4");
|
||||
|
||||
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
|
||||
<< Atom(Atom::String, "Porting to Qt 4")
|
||||
@ -4525,6 +4581,10 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
|
||||
break;
|
||||
case Node::Class:
|
||||
break;
|
||||
case Node::QmlType:
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
break;
|
||||
case Node::Group:
|
||||
break;
|
||||
case Node::Module:
|
||||
@ -4545,10 +4605,6 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
|
||||
break;
|
||||
case Node::ExternalPage:
|
||||
break;
|
||||
case Node::QmlClass:
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
break;
|
||||
case Node::Collision:
|
||||
break;
|
||||
default:
|
||||
|
@ -102,6 +102,8 @@ protected:
|
||||
const Node *relative,
|
||||
CodeMarker *marker);
|
||||
virtual void generateClassLikeNode(InnerNode* inner, CodeMarker* marker);
|
||||
virtual void generateQmlTypePage(QmlClassNode* qcn, CodeMarker* marker);
|
||||
virtual void generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* marker);
|
||||
virtual void generateDocNode(DocNode* dn, CodeMarker* marker);
|
||||
virtual void generateCollectionNode(CollectionNode* cn, CodeMarker* marker);
|
||||
virtual QString fileExtension() const;
|
||||
@ -215,6 +217,7 @@ private:
|
||||
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
|
||||
|
@ -298,7 +298,8 @@ static void processQdocconfFile(const QString &fileName)
|
||||
currentDir = QFileInfo(fileName).path();
|
||||
Location::initialize(config);
|
||||
config.load(fileName);
|
||||
//qDebug() << "\nSTART PROJECT:" << config.getString(CONFIG_PROJECT).toLower();
|
||||
QString project = config.getString(CONFIG_PROJECT).toLower();
|
||||
//qDebug() << "\nSTART PROJECT:" << project;
|
||||
/*
|
||||
Add the defines to the configuration variables.
|
||||
*/
|
||||
@ -372,9 +373,11 @@ static void processQdocconfFile(const QString &fileName)
|
||||
Location outputFormatsLocation = config.lastLocation();
|
||||
|
||||
//if (!Generator::runPrepareOnly())
|
||||
Generator::debug(" loading index files");
|
||||
loadIndexFiles(config);
|
||||
qdb->newPrimaryTree(config.getString(CONFIG_PROJECT));
|
||||
qdb->setSearchOrder();
|
||||
Generator::debug(" done loading index files");
|
||||
|
||||
QSet<QString> excludedDirs;
|
||||
QSet<QString> excludedFiles;
|
||||
@ -458,7 +461,6 @@ static void processQdocconfFile(const QString &fileName)
|
||||
to the big tree.
|
||||
*/
|
||||
QSet<CodeParser *> usedParsers;
|
||||
//Config::debug_ = true;
|
||||
|
||||
Generator::debug("Parsing header files");
|
||||
int parsed = 0;
|
||||
@ -528,6 +530,8 @@ static void processQdocconfFile(const QString &fileName)
|
||||
|
||||
//Generator::writeOutFileNames();
|
||||
Generator::debug("Shutting down qdoc");
|
||||
if (Generator::debugging())
|
||||
Generator::stopDebugging(project);
|
||||
|
||||
QDocDatabase::qdocDB()->setVersion(QString());
|
||||
Generator::terminate();
|
||||
|
@ -51,6 +51,38 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
int Node::propertyGroupCount_ = 0;
|
||||
QStringMap Node::operators_;
|
||||
QMap<QString,Node::Type> Node::goals_;
|
||||
|
||||
/*!
|
||||
Initialize the map of search goals. This is called once
|
||||
by QDocDatabase::initializeDB(). The map key is a string
|
||||
representing a value in the enum Node::Type. The map value
|
||||
is the enum value.
|
||||
|
||||
There should be an entry in the map for each value in the
|
||||
Type enum.
|
||||
*/
|
||||
void Node::initialize()
|
||||
{
|
||||
goals_.insert("class", Node::Class);
|
||||
goals_.insert("qmltype", Node::QmlType);
|
||||
goals_.insert("page", Node::Document);
|
||||
goals_.insert("function", Node::Function);
|
||||
goals_.insert("property", Node::Property);
|
||||
goals_.insert("variable", Node::Variable);
|
||||
goals_.insert("group", Node::Group);
|
||||
goals_.insert("module", Node::Module);
|
||||
goals_.insert("qmlmodule", Node::QmlModule);
|
||||
goals_.insert("qmppropertygroup", Node::QmlPropertyGroup);
|
||||
goals_.insert("qmlproperty", Node::QmlProperty);
|
||||
goals_.insert("qmlsignal", Node::QmlSignal);
|
||||
goals_.insert("qmlsignalhandler", Node::QmlSignalHandler);
|
||||
goals_.insert("qmlmethod", Node::QmlMethod);
|
||||
goals_.insert("qmlbasictype", Node::QmlBasicType);
|
||||
goals_.insert("enum", Node::Enum);
|
||||
goals_.insert("typedef", Node::Typedef);
|
||||
goals_.insert("namespace", Node::Namespace);
|
||||
}
|
||||
|
||||
/*!
|
||||
Increment the number of property groups seen in the current
|
||||
@ -328,6 +360,10 @@ QString Node::nodeTypeString(unsigned t)
|
||||
return "group";
|
||||
case Module:
|
||||
return "module";
|
||||
case QmlType:
|
||||
return "QML type";
|
||||
case QmlBasicType:
|
||||
return "QML basic type";
|
||||
case QmlModule:
|
||||
return "QML module";
|
||||
case QmlProperty:
|
||||
@ -376,10 +412,6 @@ QString Node::nodeSubtypeString(unsigned t)
|
||||
return "page";
|
||||
case ExternalPage:
|
||||
return "external page";
|
||||
case QmlClass:
|
||||
return "QML type";
|
||||
case QmlBasicType:
|
||||
return "QML basic type";
|
||||
case DitaMap:
|
||||
return "ditamap";
|
||||
case Collision:
|
||||
@ -616,9 +648,9 @@ QmlClassNode* Node::qmlClassNode()
|
||||
{
|
||||
if (isQmlNode()) {
|
||||
Node* n = this;
|
||||
while (n && n->subType() != Node::QmlClass)
|
||||
while (n && !n->isQmlType())
|
||||
n = n->parent();
|
||||
if (n && n->subType() == Node::QmlClass)
|
||||
if (n && n->isQmlType())
|
||||
return static_cast<QmlClassNode*>(n);
|
||||
}
|
||||
return 0;
|
||||
@ -654,6 +686,14 @@ bool Node::isInternal() const
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a pointer to the root of the Tree this node is in.
|
||||
*/
|
||||
const Node* Node::root() const
|
||||
{
|
||||
return (parent() ? parent()->root() : this);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class InnerNode
|
||||
*/
|
||||
@ -1072,6 +1112,7 @@ InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name)
|
||||
{
|
||||
switch (type) {
|
||||
case Class:
|
||||
case QmlType:
|
||||
case Namespace:
|
||||
setPageType(ApiPage);
|
||||
break;
|
||||
@ -1313,6 +1354,7 @@ LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
|
||||
case QmlSignal:
|
||||
case QmlSignalHandler:
|
||||
case QmlMethod:
|
||||
case QmlBasicType:
|
||||
setPageType(ApiPage);
|
||||
break;
|
||||
default:
|
||||
@ -1356,7 +1398,7 @@ LeafNode::LeafNode(InnerNode* parent, Type type, const QString& name)
|
||||
Constructs a namespace node.
|
||||
*/
|
||||
NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
|
||||
: InnerNode(Namespace, parent, name)
|
||||
: InnerNode(Namespace, parent, name), tree_(0)
|
||||
{
|
||||
setPageType(ApiPage);
|
||||
}
|
||||
@ -1562,10 +1604,6 @@ DocNode::DocNode(InnerNode* parent, const QString& name, SubType subtype, Node::
|
||||
case DitaMap:
|
||||
setPageType(ptype);
|
||||
break;
|
||||
case QmlClass:
|
||||
case QmlBasicType:
|
||||
setPageType(ApiPage);
|
||||
break;
|
||||
case Example:
|
||||
setPageType(ExamplePage);
|
||||
break;
|
||||
@ -2051,12 +2089,11 @@ bool QmlClassNode::qmlOnly = false;
|
||||
QMultiMap<QString,Node*> QmlClassNode::inheritedBy;
|
||||
|
||||
/*!
|
||||
Constructs a Qml class node (i.e. a Document node with the
|
||||
subtype QmlClass. The new node has the given \a parent
|
||||
and \a name.
|
||||
Constructs a Qml class node. The new node has the given
|
||||
\a parent and \a name.
|
||||
*/
|
||||
QmlClassNode::QmlClassNode(InnerNode *parent, const QString& name)
|
||||
: DocNode(parent, name, QmlClass, Node::ApiPage),
|
||||
: InnerNode(QmlType, parent, name),
|
||||
abstract_(false),
|
||||
cnodeRequired_(false),
|
||||
wrapper_(false),
|
||||
@ -2070,6 +2107,7 @@ QmlClassNode::QmlClassNode(InnerNode *parent, const QString& name)
|
||||
i = 4;
|
||||
}
|
||||
setTitle(name.mid(i));
|
||||
setPageType(Node::ApiPage);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2187,13 +2225,12 @@ QString QmlClassNode::qmlModuleIdentifier() const
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a Qml basic type node (i.e. a Document node with
|
||||
the subtype QmlBasicType. The new node has the given
|
||||
Constructs a Qml basic type node. The new node has the given
|
||||
\a parent and \a name.
|
||||
*/
|
||||
QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent,
|
||||
const QString& name)
|
||||
: DocNode(parent, name, QmlBasicType, Node::ApiPage)
|
||||
: InnerNode(QmlBasicType, parent, name)
|
||||
{
|
||||
setTitle(name);
|
||||
}
|
||||
@ -2293,7 +2330,7 @@ PropertyNode* QmlPropertyNode::findCorrespondingCppProperty()
|
||||
{
|
||||
PropertyNode* pn;
|
||||
Node* n = parent();
|
||||
while (n && n->subType() != Node::QmlClass)
|
||||
while (n && !n->isQmlType())
|
||||
n = n->parent();
|
||||
if (n) {
|
||||
QmlClassNode* qcn = static_cast<QmlClassNode*>(n);
|
||||
@ -2489,12 +2526,14 @@ QString Node::fullDocumentName() const
|
||||
if (!n->name().isEmpty() && !n->isQmlPropertyGroup())
|
||||
pieces.insert(0, n->name());
|
||||
|
||||
if (n->type() == Node::Document) {
|
||||
if ((n->subType() == Node::QmlClass) && !n->qmlModuleName().isEmpty())
|
||||
pieces.insert(0, n->qmlModuleName());
|
||||
if (n->isQmlType() && !n->qmlModuleName().isEmpty()) {
|
||||
pieces.insert(0, n->qmlModuleName());
|
||||
break;
|
||||
}
|
||||
|
||||
if (n->isDocNode())
|
||||
break;
|
||||
|
||||
// Examine the parent node if one exists.
|
||||
if (n->parent())
|
||||
n = n->parent();
|
||||
@ -2504,7 +2543,7 @@ QString Node::fullDocumentName() const
|
||||
|
||||
// Create a name based on the type of the ancestor node.
|
||||
QString concatenator = "::";
|
||||
if ((n->type() == Node::Document) && (n->subType() != Node::QmlClass))
|
||||
if (n->isDocNode())
|
||||
concatenator = QLatin1Char('#');
|
||||
|
||||
return pieces.join(concatenator);
|
||||
@ -2679,16 +2718,15 @@ QString Node::idForNode() const
|
||||
}
|
||||
}
|
||||
else if (parent_) {
|
||||
if (parent_->type() == Class)
|
||||
if (parent_->isClass())
|
||||
str = "class-member-" + func->name();
|
||||
else if (parent_->type() == Namespace)
|
||||
else if (parent_->isNamespace())
|
||||
str = "namespace-member-" + func->name();
|
||||
else if (parent_->isQmlType())
|
||||
str = "qml-method-" + parent_->name().toLower() + "-" + func->name();
|
||||
else if (parent_->type() == Document) {
|
||||
if (parent_->subType() == QmlClass)
|
||||
str = "qml-method-" + parent_->name().toLower() + "-" + func->name();
|
||||
else
|
||||
qDebug() << "qdoc internal error: Node subtype not handled:"
|
||||
<< parent_->subType() << func->name();
|
||||
qDebug() << "qdoc internal error: Node subtype not handled:"
|
||||
<< parent_->subType() << func->name();
|
||||
}
|
||||
else
|
||||
qDebug() << "qdoc internal error: Node type not handled:"
|
||||
@ -2699,12 +2737,15 @@ QString Node::idForNode() const
|
||||
str += QLatin1Char('-') + QString::number(func->overloadNumber());
|
||||
}
|
||||
break;
|
||||
case Node::QmlType:
|
||||
str = "qml-class-" + name();
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
str = "qml-basic-type-" + name();
|
||||
break;
|
||||
case Node::Document:
|
||||
{
|
||||
switch (subType()) {
|
||||
case Node::QmlClass:
|
||||
str = "qml-class-" + name();
|
||||
break;
|
||||
case Node::Page:
|
||||
case Node::HeaderFile:
|
||||
str = title();
|
||||
@ -2723,9 +2764,6 @@ QString Node::idForNode() const
|
||||
str = name();
|
||||
str.replace(QLatin1Char('/'), QLatin1Char('-'));
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
str = "qml-basic-type-" + name();
|
||||
break;
|
||||
case Node::Collision:
|
||||
str = title();
|
||||
str.replace(": ","-");
|
||||
|
@ -49,12 +49,11 @@
|
||||
|
||||
#include "codechunk.h"
|
||||
#include "doc.h"
|
||||
#include "location.h"
|
||||
#include "text.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Node;
|
||||
class Tree;
|
||||
class EnumNode;
|
||||
class ClassNode;
|
||||
class InnerNode;
|
||||
@ -83,6 +82,7 @@ class Node
|
||||
|
||||
public:
|
||||
enum Type {
|
||||
NoType,
|
||||
Namespace,
|
||||
Class,
|
||||
Document,
|
||||
@ -93,12 +93,14 @@ public:
|
||||
Variable,
|
||||
Group,
|
||||
Module,
|
||||
QmlType,
|
||||
QmlModule,
|
||||
QmlPropertyGroup,
|
||||
QmlProperty,
|
||||
QmlSignal,
|
||||
QmlSignalHandler,
|
||||
QmlMethod,
|
||||
QmlBasicType,
|
||||
LastType
|
||||
};
|
||||
|
||||
@ -110,8 +112,6 @@ public:
|
||||
Image,
|
||||
Page,
|
||||
ExternalPage,
|
||||
QmlClass,
|
||||
QmlBasicType,
|
||||
DitaMap,
|
||||
Collision,
|
||||
LastSubtype
|
||||
@ -248,11 +248,13 @@ public:
|
||||
virtual bool wasSeen() const { return false; }
|
||||
virtual void appendGroupName(const QString& ) { }
|
||||
virtual QString element() const { return QString(); }
|
||||
virtual Tree* tree() const { return 0; }
|
||||
bool isIndexNode() const { return indexNodeFlag_; }
|
||||
Type type() const { return nodeType_; }
|
||||
virtual SubType subType() const { return NoSubType; }
|
||||
bool match(const NodeTypeList& types) const;
|
||||
InnerNode* parent() const { return parent_; }
|
||||
const Node* root() const;
|
||||
InnerNode* relates() const { return relatesTo_; }
|
||||
const QString& name() const { return name_; }
|
||||
QString moduleName() const;
|
||||
@ -318,6 +320,8 @@ public:
|
||||
static QString nodeSubtypeString(unsigned t);
|
||||
static int incPropertyGroupCount();
|
||||
static void clearPropertyGroupCount();
|
||||
static void initialize();
|
||||
static Type goal(const QString& t) { return goals_.value(t); }
|
||||
|
||||
protected:
|
||||
Node(Type type, InnerNode* parent, const QString& name);
|
||||
@ -347,6 +351,7 @@ private:
|
||||
QString outSubDir_;
|
||||
static QStringMap operators_;
|
||||
static int propertyGroupCount_;
|
||||
static QMap<QString,Node::Type> goals_;
|
||||
};
|
||||
|
||||
class InnerNode : public Node
|
||||
@ -435,6 +440,11 @@ public:
|
||||
NamespaceNode(InnerNode* parent, const QString& name);
|
||||
virtual ~NamespaceNode() { }
|
||||
virtual bool isNamespace() const { return true; }
|
||||
virtual Tree* tree() const { return tree_; }
|
||||
void setTree(Tree* t) { tree_ = t; }
|
||||
|
||||
private:
|
||||
Tree* tree_;
|
||||
};
|
||||
|
||||
struct RelatedClass
|
||||
@ -583,7 +593,7 @@ struct ImportRec {
|
||||
|
||||
typedef QList<ImportRec> ImportList;
|
||||
|
||||
class QmlClassNode : public DocNode
|
||||
class QmlClassNode : public InnerNode
|
||||
{
|
||||
public:
|
||||
QmlClassNode(InnerNode* parent, const QString& name);
|
||||
@ -635,7 +645,7 @@ private:
|
||||
ImportList importList_;
|
||||
};
|
||||
|
||||
class QmlBasicTypeNode : public DocNode
|
||||
class QmlBasicTypeNode : public InnerNode
|
||||
{
|
||||
public:
|
||||
QmlBasicTypeNode(InnerNode* parent,
|
||||
@ -719,17 +729,13 @@ public:
|
||||
EnumItem() { }
|
||||
EnumItem(const QString& name, const QString& value)
|
||||
: nam(name), val(value) { }
|
||||
EnumItem(const QString& name, const QString& value, const Text &txt)
|
||||
: nam(name), val(value), txt(txt) { }
|
||||
|
||||
const QString& name() const { return nam; }
|
||||
const QString& value() const { return val; }
|
||||
const Text &text() const { return txt; }
|
||||
|
||||
private:
|
||||
QString nam;
|
||||
QString val;
|
||||
Text txt;
|
||||
};
|
||||
|
||||
class EnumNode : public LeafNode
|
||||
|
@ -286,6 +286,16 @@ void QDocForest::setSearchOrder()
|
||||
}
|
||||
forest_.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
Rebuild the forest after constructing the search order.
|
||||
It was destroyed during construction of the search order,
|
||||
but it is needed for module-specific searches.
|
||||
*/
|
||||
for (int i=0; i<searchOrder_.size(); ++i) {
|
||||
forest_.insert(moduleNames_.at(i).toLower(), searchOrder_.at(i));
|
||||
}
|
||||
|
||||
#if 0
|
||||
qDebug() << " SEARCH ORDER:";
|
||||
for (int i=0; i<moduleNames_.size(); ++i)
|
||||
@ -498,9 +508,12 @@ void QDocDatabase::destroyQdocDB()
|
||||
include \c array and \c data, which are just generic names
|
||||
used as place holders in function signatures that appear in
|
||||
the documentation.
|
||||
|
||||
Also calls Node::initialize() to initialize the search goal map.
|
||||
*/
|
||||
void QDocDatabase::initializeDB()
|
||||
{
|
||||
Node::initialize();
|
||||
typeNodeMap_.insert( "accepted", 0);
|
||||
typeNodeMap_.insert( "actionPerformed", 0);
|
||||
typeNodeMap_.insert( "activated", 0);
|
||||
@ -776,14 +789,14 @@ QmlClassNode* QDocDatabase::findQmlType(const QString& qmid, const QString& name
|
||||
}
|
||||
|
||||
QStringList path(name);
|
||||
Node* n = forest_.findNodeByNameAndType(path, Node::Document, Node::QmlClass, true);
|
||||
Node* n = forest_.findNodeByNameAndType(path, Node::QmlType);
|
||||
if (n) {
|
||||
if (n->subType() == Node::QmlClass)
|
||||
if (n->isQmlType())
|
||||
return static_cast<QmlClassNode*>(n);
|
||||
else if (n->subType() == Node::Collision) {
|
||||
else if (n->isCollisionNode()) {
|
||||
NameCollisionNode* ncn;
|
||||
ncn = static_cast<NameCollisionNode*>(n);
|
||||
return static_cast<QmlClassNode*>(ncn->findAny(Node::Document,Node::QmlClass));
|
||||
return static_cast<QmlClassNode*>(ncn->findAny(Node::QmlType, Node::NoSubType));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -992,9 +1005,7 @@ void QDocDatabase::findAllClasses(InnerNode* node)
|
||||
serviceClasses_.insert(serviceName, *c);
|
||||
}
|
||||
}
|
||||
else if ((*c)->type() == Node::Document &&
|
||||
(*c)->subType() == Node::QmlClass &&
|
||||
!(*c)->doc().isEmpty()) {
|
||||
else if ((*c)->isQmlType() && !(*c)->doc().isEmpty()) {
|
||||
QString qmlTypeName = (*c)->name();
|
||||
if (qmlTypeName.startsWith(QLatin1String("QML:")))
|
||||
qmlClasses_.insert(qmlTypeName.mid(4),*c);
|
||||
@ -1103,7 +1114,7 @@ void QDocDatabase::findAllObsoleteThings(InnerNode* node)
|
||||
name = (*c)->parent()->name() + "::" + name;
|
||||
obsoleteClasses_.insert(name, *c);
|
||||
}
|
||||
else if ((*c)->type() == Node::Document && (*c)->subType() == Node::QmlClass) {
|
||||
else if ((*c)->isQmlType()) {
|
||||
if (name.startsWith(QLatin1String("QML:")))
|
||||
name = name.mid(4);
|
||||
name = (*c)->qmlModuleName() + "::" + name;
|
||||
@ -1139,7 +1150,7 @@ void QDocDatabase::findAllObsoleteThings(InnerNode* node)
|
||||
++p;
|
||||
}
|
||||
}
|
||||
else if ((*c)->type() == Node::Document && (*c)->subType() == Node::QmlClass) {
|
||||
else if ((*c)->isQmlType()) {
|
||||
InnerNode* n = static_cast<InnerNode*>(*c);
|
||||
bool inserted = false;
|
||||
NodeList::const_iterator p = n->childNodes().constBegin();
|
||||
@ -1154,7 +1165,7 @@ void QDocDatabase::findAllObsoleteThings(InnerNode* node)
|
||||
Node* parent = (*c)->parent();
|
||||
if (parent->type() == Node::QmlPropertyGroup && parent->parent())
|
||||
parent = parent->parent();
|
||||
if (parent && parent->subType() == Node::QmlClass && !parent->name().isEmpty())
|
||||
if (parent && parent->isQmlType() && !parent->name().isEmpty())
|
||||
name = parent->name() + "::" + name;
|
||||
}
|
||||
qmlTypesWithObsoleteMembers_.insert(name,*c);
|
||||
@ -1223,7 +1234,7 @@ void QDocDatabase::findAllSince(InnerNode* node)
|
||||
nsmap.value().insert(className,(*child));
|
||||
ncmap.value().insert(className,(*child));
|
||||
}
|
||||
else if ((*child)->subType() == Node::QmlClass) {
|
||||
else if ((*child)->isQmlType()) {
|
||||
// Insert QML elements into the since and element maps.
|
||||
QString className = (*child)->name();
|
||||
if ((*child)->parent() && !(*child)->parent()->name().isEmpty()) {
|
||||
@ -1344,7 +1355,7 @@ const Node* QDocDatabase::findNodeForTarget(const QString& target, const Node* r
|
||||
if (target.isEmpty())
|
||||
node = relative;
|
||||
else if (target.endsWith(".html")) {
|
||||
node = findNodeByNameAndType(QStringList(target), Node::Document, Node::NoSubType);
|
||||
node = findNodeByNameAndType(QStringList(target), Node::Document);
|
||||
}
|
||||
else {
|
||||
node = resolveTarget(target, relative);
|
||||
@ -1366,7 +1377,7 @@ void QDocDatabase::resolveQmlInheritance(InnerNode* root)
|
||||
NodeMap previousSearches;
|
||||
// Do we need recursion?
|
||||
foreach (Node* child, root->childNodes()) {
|
||||
if (child->type() == Node::Document && child->subType() == Node::QmlClass) {
|
||||
if (child->isQmlType()) {
|
||||
QmlClassNode* qcn = static_cast<QmlClassNode*>(child);
|
||||
if (qcn->qmlBaseNodeNotSet() && !qcn->qmlBaseName().isEmpty()) {
|
||||
QmlClassNode* bqcn = static_cast<QmlClassNode*>(previousSearches.value(qcn->qmlBaseName()));
|
||||
@ -1463,18 +1474,16 @@ FunctionNode* QDocDatabase::findNodeInOpenNamespace(const QStringList& parentPat
|
||||
}
|
||||
|
||||
/*!
|
||||
Find a node of the specified \a type and \a subtype that is
|
||||
reached with the specified \a path qualified with the name
|
||||
of one of the open namespaces (might not be any open ones).
|
||||
If the node is found in an open namespace, prefix \a path
|
||||
with the name of the open namespace and "::" and return a
|
||||
pointer to the node. Othewrwise return 0.
|
||||
Find a node of the specified \a type that is reached with
|
||||
the specified \a path qualified with the name of one of the
|
||||
open namespaces (might not be any open ones). If the node
|
||||
is found in an open namespace, prefix \a path with the name
|
||||
of the open namespace and "::" and return a pointer to the
|
||||
node. Othewrwise return 0.
|
||||
|
||||
This function only searches in the current primary tree.
|
||||
*/
|
||||
Node* QDocDatabase::findNodeInOpenNamespace(QStringList& path,
|
||||
Node::Type type,
|
||||
Node::SubType subtype)
|
||||
Node* QDocDatabase::findNodeInOpenNamespace(QStringList& path, Node::Type type)
|
||||
{
|
||||
if (path.isEmpty())
|
||||
return 0;
|
||||
@ -1486,7 +1495,7 @@ Node* QDocDatabase::findNodeInOpenNamespace(QStringList& path,
|
||||
p = t.split("::") + path;
|
||||
else
|
||||
p = path;
|
||||
n = primaryTree()->findNodeByNameAndType(p, type, subtype);
|
||||
n = primaryTree()->findNodeByNameAndType(p, type);
|
||||
if (n) {
|
||||
path = p;
|
||||
break;
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <qmap.h>
|
||||
#include "tree.h"
|
||||
#include "config.h"
|
||||
#include "text.h"
|
||||
#include <qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -79,6 +80,7 @@ class QDocForest
|
||||
Tree* firstTree();
|
||||
Tree* nextTree();
|
||||
Tree* primaryTree() { return primaryTree_; }
|
||||
Tree* findTree(const QString& t) { return forest_.value(t); }
|
||||
NamespaceNode* primaryTreeRoot() { return (primaryTree_ ? primaryTree_->root() : 0); }
|
||||
bool isEmpty() { return searchOrder().isEmpty(); }
|
||||
bool done() { return (currentIndex_ >= searchOrder().size()); }
|
||||
@ -93,20 +95,15 @@ class QDocForest
|
||||
return n;
|
||||
relative = 0;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 1" << path;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Node* findNodeByNameAndType(const QStringList& path,
|
||||
Node::Type type,
|
||||
Node::SubType subtype,
|
||||
bool acceptCollision = false) {
|
||||
Node* findNodeByNameAndType(const QStringList& path, Node::Type type) {
|
||||
foreach (Tree* t, searchOrder()) {
|
||||
Node* n = t->findNodeByNameAndType(path, type, subtype, acceptCollision);
|
||||
Node* n = t->findNodeByNameAndType(path, type);
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 2" << path << type << subtype;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -116,7 +113,6 @@ class QDocForest
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 3" << path;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -126,7 +122,6 @@ class QDocForest
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 4" << path;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -149,21 +144,9 @@ class QDocForest
|
||||
return n;
|
||||
relative = 0;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 5" << path;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString findTarget(const QString& target, const Node* node)
|
||||
{
|
||||
foreach (Tree* t, searchOrder()) {
|
||||
QString ref = t->findTarget(target, node);
|
||||
if (!ref.isEmpty())
|
||||
return ref;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 7" << target;
|
||||
return QString();
|
||||
}
|
||||
|
||||
const Node* findUnambiguousTarget(const QString& target, QString& ref)
|
||||
{
|
||||
foreach (Tree* t, searchOrder()) {
|
||||
@ -171,7 +154,6 @@ class QDocForest
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 8" << target;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -182,7 +164,6 @@ class QDocForest
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
//qDebug() << "FAILED SEARCH 9" << title;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -229,6 +210,7 @@ class QDocDatabase
|
||||
static void destroyQdocDB();
|
||||
~QDocDatabase();
|
||||
|
||||
Tree* findTree(const QString& t) { return forest_.findTree(t); }
|
||||
const CNMap& groups() { return primaryTree()->groups(); }
|
||||
const CNMap& modules() { return primaryTree()->modules(); }
|
||||
const CNMap& qmlModules() { return primaryTree()->qmlModules(); }
|
||||
@ -307,7 +289,7 @@ class QDocDatabase
|
||||
return primaryTree()->findFunctionNode(parentPath, clone);
|
||||
}
|
||||
FunctionNode* findNodeInOpenNamespace(const QStringList& parentPath, const FunctionNode* clone);
|
||||
Node* findNodeInOpenNamespace(QStringList& path, Node::Type type, Node::SubType subtype);
|
||||
Node* findNodeInOpenNamespace(QStringList& path, Node::Type type);
|
||||
NameCollisionNode* findCollisionNode(const QString& name) {
|
||||
return primaryTree()->findCollisionNode(name);
|
||||
}
|
||||
@ -321,9 +303,6 @@ class QDocDatabase
|
||||
********************************************************************/
|
||||
ClassNode* findClassNode(const QStringList& path) { return forest_.findClassNode(path); }
|
||||
InnerNode* findRelatesNode(const QStringList& path) { return forest_.findRelatesNode(path); }
|
||||
QString findTarget(const QString& target, const Node* node) {
|
||||
return forest_.findTarget(target, node);
|
||||
}
|
||||
const Node* resolveTarget(const QString& target, const Node* relative) {
|
||||
return forest_.resolveTarget(target, relative);
|
||||
}
|
||||
@ -338,11 +317,14 @@ class QDocDatabase
|
||||
const Node* findUnambiguousTarget(const QString& target, QString& ref) {
|
||||
return forest_.findUnambiguousTarget(target, ref);
|
||||
}
|
||||
Node* findNodeByNameAndType(const QStringList& path, Node::Type type, Node::SubType subtype){
|
||||
return forest_.findNodeByNameAndType(path, type, subtype, false);
|
||||
Node* findNodeByNameAndType(const QStringList& path, Node::Type type) {
|
||||
return forest_.findNodeByNameAndType(path, type);
|
||||
}
|
||||
/*******************************************************************/
|
||||
|
||||
QString findTarget(const QString& target, const Node* node) {
|
||||
return node->root()->tree()->findTarget(target, node);
|
||||
}
|
||||
void addPropertyFunction(PropertyNode* property,
|
||||
const QString& funcName,
|
||||
PropertyNode::FunctionRole funcRole) {
|
||||
|
@ -206,8 +206,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
|
||||
abstract = true;
|
||||
node->setAbstract(abstract);
|
||||
}
|
||||
else if ((element.nodeName() == "qmlclass") ||
|
||||
((element.nodeName() == "page") && (element.attribute("subtype") == "qmlclass"))) {
|
||||
else if (element.nodeName() == "qmlclass") {
|
||||
QmlClassNode* qcn = new QmlClassNode(parent, name);
|
||||
qcn->setTitle(element.attribute("title"));
|
||||
QString qmlModuleName = element.attribute("qml-module-name");
|
||||
@ -260,11 +259,11 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
|
||||
if (element.attribute("writable") == "false")
|
||||
readonly = true;
|
||||
QmlPropertyNode* qpn = 0;
|
||||
if (parent->type() == Node::Document) {
|
||||
if (parent->isQmlType()) {
|
||||
QmlClassNode* qcn = static_cast<QmlClassNode*>(parent);
|
||||
qpn = new QmlPropertyNode(qcn, name, type, attached);
|
||||
}
|
||||
else if (parent->type() == Node::QmlPropertyGroup) {
|
||||
else if (parent->isQmlPropertyGroup()) {
|
||||
QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(parent);
|
||||
qpn = new QmlPropertyNode(qpgn, name, type, attached);
|
||||
}
|
||||
@ -332,14 +331,6 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
|
||||
subtype = Node::ExternalPage;
|
||||
ptype = Node::ArticlePage;
|
||||
}
|
||||
else if (attr == "qmlclass") {
|
||||
subtype = Node::QmlClass;
|
||||
ptype = Node::ApiPage;
|
||||
}
|
||||
else if (attr == "qmlbasictype") {
|
||||
subtype = Node::QmlBasicType;
|
||||
ptype = Node::ApiPage;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
@ -614,7 +605,7 @@ void QDocIndexFiles::resolveIndex()
|
||||
foreach (pair, basesList_) {
|
||||
foreach (const QString& base, pair.second.split(QLatin1Char(','))) {
|
||||
QStringList basePath = base.split(QString("::"));
|
||||
Node* n = qdb_->findNodeByNameAndType(basePath, Node::Class, Node::NoSubType);
|
||||
Node* n = qdb_->findClassNode(basePath);
|
||||
if (n)
|
||||
pair.first->addResolvedBaseClass(Node::Public, static_cast<ClassNode*>(n));
|
||||
else
|
||||
@ -661,17 +652,20 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
case Node::Class:
|
||||
nodeName = "class";
|
||||
break;
|
||||
case Node::Document:
|
||||
nodeName = "page";
|
||||
if (node->subType() == Node::QmlClass) {
|
||||
case Node::QmlType:
|
||||
{
|
||||
nodeName = "qmlclass";
|
||||
QmlModuleNode* qmn = node->qmlModule();
|
||||
if (qmn)
|
||||
qmlModuleName = qmn->qmlModuleName();
|
||||
qmlFullBaseName = node->qmlFullBaseName();
|
||||
}
|
||||
else if (node->subType() == Node::QmlBasicType)
|
||||
nodeName = "qmlbasictype";
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
nodeName = "qmlbasictype";
|
||||
break;
|
||||
case Node::Document:
|
||||
nodeName = "page";
|
||||
break;
|
||||
case Node::Group:
|
||||
nodeName = "group";
|
||||
@ -755,10 +749,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
|
||||
QXmlStreamAttributes attributes;
|
||||
|
||||
if ((node->type() != Node::Document) &&
|
||||
(node->type() != Node::Group) &&
|
||||
(node->type() != Node::Module) &&
|
||||
(node->type() != Node::QmlModule)) {
|
||||
if (!node->isDocNode() && !node->isGroup() && !node->isModule() && !node->isQmlModule()) {
|
||||
QString threadSafety;
|
||||
switch (node->threadSafeness()) {
|
||||
case Node::NonReentrant:
|
||||
@ -843,10 +834,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
writer.writeAttribute("href", href);
|
||||
|
||||
writer.writeAttribute("status", status);
|
||||
if ((node->type() != Node::Document) &&
|
||||
(node->type() != Node::Group) &&
|
||||
(node->type() != Node::Module) &&
|
||||
(node->type() != Node::QmlModule)) {
|
||||
if (!node->isDocNode() && !node->isGroup() && !node->isModule() && !node->isQmlModule()) {
|
||||
writer.writeAttribute("access", access);
|
||||
if (node->isAbstract())
|
||||
writer.writeAttribute("abstract", "true");
|
||||
@ -896,6 +884,18 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
writer.writeAttribute("brief", brief);
|
||||
}
|
||||
break;
|
||||
case Node::QmlType:
|
||||
{
|
||||
const QmlClassNode* qcn = static_cast<const QmlClassNode*>(node);
|
||||
writer.writeAttribute("title", qcn->title());
|
||||
writer.writeAttribute("fulltitle", qcn->fullTitle());
|
||||
writer.writeAttribute("subtitle", qcn->subTitle());
|
||||
if (!qcn->groupNames().isEmpty())
|
||||
writer.writeAttribute("groups", qcn->groupNames().join(","));
|
||||
if (!brief.isEmpty())
|
||||
writer.writeAttribute("brief", brief);
|
||||
}
|
||||
break;
|
||||
case Node::Document:
|
||||
{
|
||||
/*
|
||||
@ -923,12 +923,6 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
|
||||
case Node::ExternalPage:
|
||||
writer.writeAttribute("subtype", "externalpage");
|
||||
break;
|
||||
case Node::QmlClass:
|
||||
//writer.writeAttribute("subtype", "qmlclass");
|
||||
break;
|
||||
case Node::QmlBasicType:
|
||||
//writer.writeAttribute("subtype", "qmlbasictype");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1289,7 +1283,7 @@ bool compareNodes(const Node* n1, const Node* n2)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n1->type() == Node::Document && n2->type() == Node::Document) {
|
||||
if (n1->isDocNode() && n2->isDocNode()) {
|
||||
const DocNode* f1 = static_cast<const DocNode*>(n1);
|
||||
const DocNode* f2 = static_cast<const DocNode*>(n2);
|
||||
if (f1->fullTitle() < f2->fullTitle())
|
||||
|
@ -365,7 +365,7 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
|
||||
QString command = *i;
|
||||
ArgList args = doc.metaCommandArgs(command);
|
||||
if (command == COMMAND_QMLABSTRACT) {
|
||||
if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
|
||||
if (node->isQmlType()) {
|
||||
node->setAbstract(true);
|
||||
}
|
||||
}
|
||||
@ -378,7 +378,7 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
|
||||
else if (command == COMMAND_QMLINHERITS) {
|
||||
if (node->name() == args[0].first)
|
||||
doc.location().warning(tr("%1 tries to inherit itself").arg(args[0].first));
|
||||
else if (node->subType() == Node::QmlClass) {
|
||||
else if (node->isQmlType()) {
|
||||
QmlClassNode *qmlClass = static_cast<QmlClassNode*>(node);
|
||||
qmlClass->setQmlBaseName(args[0].first);
|
||||
QmlClassNode::addInheritedBy(args[0].first,node);
|
||||
@ -541,7 +541,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
|
||||
switch (member->type) {
|
||||
case QQmlJS::AST::UiPublicMember::Signal:
|
||||
{
|
||||
if (current->type() == Node::Document) {
|
||||
if (current->isQmlType()) {
|
||||
QmlClassNode *qmlClass = static_cast<QmlClassNode *>(current);
|
||||
if (qmlClass) {
|
||||
|
||||
@ -564,7 +564,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
|
||||
{
|
||||
QString type = member->memberType.toString();
|
||||
QString name = member->name.toString();
|
||||
if (current->type() == Node::Document) {
|
||||
if (current->isQmlType()) {
|
||||
QmlClassNode *qmlClass = static_cast<QmlClassNode *>(current);
|
||||
if (qmlClass) {
|
||||
QString name = member->name.toString();
|
||||
@ -608,7 +608,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd)
|
||||
if (nestingLevel > 1) {
|
||||
return true;
|
||||
}
|
||||
if (current->type() == Node::Document) {
|
||||
if (current->isQmlType()) {
|
||||
QmlClassNode* qmlClass = static_cast<QmlClassNode*>(current);
|
||||
if (qmlClass) {
|
||||
QString name = fd->name.toString();
|
||||
@ -661,7 +661,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiScriptBinding* )
|
||||
if (nestingLevel > 1) {
|
||||
return true;
|
||||
}
|
||||
if (current->type() == Node::Document) {
|
||||
if (current->isQmlType()) {
|
||||
QString handler = sb->qualifiedId->name.toString();
|
||||
if (handler.length() > 2 && handler.startsWith("on") && handler.at(2).isUpper()) {
|
||||
QmlClassNode* qmlClass = static_cast<QmlClassNode*>(current);
|
||||
|
@ -77,6 +77,7 @@ Tree::Tree(const QString& module, QDocDatabase* qdb)
|
||||
: module_(module), qdb_(qdb), root_(0, QString())
|
||||
{
|
||||
root_.setModuleName(module_);
|
||||
root_.setTree(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -103,7 +104,7 @@ ClassNode* Tree::findClassNode(const QStringList& path, Node* start) const
|
||||
{
|
||||
if (!start)
|
||||
start = const_cast<NamespaceNode*>(root());
|
||||
return static_cast<ClassNode*>(findNodeRecursive(path, 0, start, Node::Class, Node::NoSubType));
|
||||
return static_cast<ClassNode*>(findNodeRecursive(path, 0, start, Node::Class));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -114,7 +115,7 @@ ClassNode* Tree::findClassNode(const QStringList& path, Node* start) const
|
||||
NamespaceNode* Tree::findNamespaceNode(const QStringList& path) const
|
||||
{
|
||||
Node* start = const_cast<NamespaceNode*>(root());
|
||||
return static_cast<NamespaceNode*>(findNodeRecursive(path, 0, start, Node::Namespace, Node::NoSubType));
|
||||
return static_cast<NamespaceNode*>(findNodeRecursive(path, 0, start, Node::Namespace));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -161,7 +162,7 @@ QmlClassNode* Tree::findQmlTypeNode(const QStringList& path)
|
||||
if (qcn)
|
||||
return qcn;
|
||||
}
|
||||
return static_cast<QmlClassNode*>(findNodeRecursive(path, 0, root(), Node::Document, Node::QmlClass));
|
||||
return static_cast<QmlClassNode*>(findNodeRecursive(path, 0, root(), Node::QmlType));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -224,14 +225,14 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
|
||||
QmlClassNode* qcn = lookupQmlType(QString(path[0] + "::" + path[1]));
|
||||
if (!qcn) {
|
||||
QStringList p(path[1]);
|
||||
Node* n = findNodeByNameAndType(p, Node::Document, Node::QmlClass, true);
|
||||
Node* n = findNodeByNameAndType(p, Node::QmlType);
|
||||
if (n) {
|
||||
if (n->subType() == Node::QmlClass)
|
||||
if (n->isQmlType())
|
||||
qcn = static_cast<QmlClassNode*>(n);
|
||||
else if (n->subType() == Node::Collision) {
|
||||
NameCollisionNode* ncn;
|
||||
ncn = static_cast<NameCollisionNode*>(n);
|
||||
qcn = static_cast<QmlClassNode*>(ncn->findAny(Node::Document, Node::QmlClass));
|
||||
qcn = static_cast<QmlClassNode*>(ncn->findAny(Node::QmlType, Node::NoSubType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,7 +490,7 @@ void Tree::resolveCppToQmlLinks()
|
||||
{
|
||||
|
||||
foreach (Node* child, root_.childNodes()) {
|
||||
if (child->type() == Node::Document && child->subType() == Node::QmlClass) {
|
||||
if (child->isQmlType()) {
|
||||
QmlClassNode* qcn = static_cast<QmlClassNode*>(child);
|
||||
ClassNode* cn = const_cast<ClassNode*>(qcn->classNode());
|
||||
if (cn)
|
||||
@ -558,15 +559,23 @@ NodeList Tree::allBaseClasses(const ClassNode* classNode) const
|
||||
search at the tree root. \a subtype is not used unless
|
||||
\a type is \c{Document}.
|
||||
*/
|
||||
Node* Tree::findNodeByNameAndType(const QStringList& path,
|
||||
Node::Type type,
|
||||
Node::SubType subtype,
|
||||
bool acceptCollision) const
|
||||
Node* Tree::findNodeByNameAndType(const QStringList& path, Node::Type type) const
|
||||
{
|
||||
Node* result = findNodeRecursive(path, 0, root(), type, subtype, acceptCollision);
|
||||
return result;
|
||||
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 */
|
||||
|
||||
/*!
|
||||
@ -588,9 +597,7 @@ Node* Tree::findNodeByNameAndType(const QStringList& path,
|
||||
Node* Tree::findNodeRecursive(const QStringList& path,
|
||||
int pathIndex,
|
||||
const Node* start,
|
||||
Node::Type type,
|
||||
Node::SubType subtype,
|
||||
bool acceptCollision) const
|
||||
Node::Type type) const
|
||||
{
|
||||
if (!start || path.isEmpty())
|
||||
return 0; // no place to start, or nothing to search for.
|
||||
@ -600,8 +607,6 @@ Node* Tree::findNodeRecursive(const QStringList& path,
|
||||
return node; // found a match.
|
||||
return 0; // premature leaf
|
||||
}
|
||||
if (pathIndex >= path.size())
|
||||
return 0; // end of search path.
|
||||
|
||||
InnerNode* current = static_cast<InnerNode*>(node);
|
||||
const NodeList& children = current->childNodes();
|
||||
@ -612,39 +617,19 @@ Node* Tree::findNodeRecursive(const QStringList& path,
|
||||
continue;
|
||||
if (n->isQmlPropertyGroup()) {
|
||||
if (type == Node::QmlProperty) {
|
||||
n = findNodeRecursive(path, pathIndex, n, type, subtype);
|
||||
n = findNodeRecursive(path, pathIndex, n, type);
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (n->name() == name) {
|
||||
if (pathIndex+1 >= path.size()) {
|
||||
if (n->type() == type) {
|
||||
if (type == Node::Document) {
|
||||
if (n->subType() == subtype)
|
||||
return n;
|
||||
else if (n->subType() == Node::Collision) {
|
||||
if (acceptCollision)
|
||||
return n;
|
||||
return n->disambiguate(type, subtype);
|
||||
}
|
||||
else if (subtype == Node::NoSubType)
|
||||
return n;
|
||||
continue;
|
||||
}
|
||||
if (n->type() == type)
|
||||
return n;
|
||||
}
|
||||
else if (n->isCollisionNode()) {
|
||||
if (acceptCollision)
|
||||
return n;
|
||||
return findNodeRecursive(path, pathIndex, n, type, subtype);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else { // Search the children of n for the next name in the path.
|
||||
n = findNodeRecursive(path, pathIndex+1, n, type, subtype);
|
||||
n = findNodeRecursive(path, pathIndex+1, n, type);
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
@ -672,9 +657,6 @@ Node* Tree::findNodeRecursive(const QStringList& path,
|
||||
Node* start,
|
||||
const NodeTypeList& types) const
|
||||
{
|
||||
/*
|
||||
Safety checks
|
||||
*/
|
||||
if (!start || path.isEmpty())
|
||||
return 0;
|
||||
if (start->isLeaf())
|
||||
@ -1233,7 +1215,7 @@ QmlModuleNode* Tree::addToQmlModule(const QString& name, Node* node)
|
||||
QmlModuleNode* qmn = findQmlModule(blankSplit[0]);
|
||||
qmn->addMember(node);
|
||||
node->setQmlModule(qmn);
|
||||
if (node->subType() == Node::QmlClass) {
|
||||
if (node->isQmlType()) {
|
||||
QmlClassNode* n = static_cast<QmlClassNode*>(node);
|
||||
for (int i=0; i<qmid.size(); ++i) {
|
||||
QString key = qmid[i] + "::" + node->name();
|
||||
|
@ -91,9 +91,7 @@ class Tree
|
||||
Node* findNodeRecursive(const QStringList& path,
|
||||
int pathIndex,
|
||||
const Node* start,
|
||||
Node::Type type,
|
||||
Node::SubType subtype,
|
||||
bool acceptCollision = false) const;
|
||||
Node::Type type) const;
|
||||
Node* findNodeRecursive(const QStringList& path,
|
||||
int pathIndex,
|
||||
Node* start,
|
||||
@ -110,12 +108,7 @@ class Tree
|
||||
|
||||
QmlClassNode* findQmlTypeNode(const QStringList& path);
|
||||
|
||||
Node* findNodeByNameAndType(const QStringList& path,
|
||||
Node::Type type,
|
||||
Node::SubType subtype,
|
||||
bool acceptCollision = false) const;
|
||||
|
||||
|
||||
Node* findNodeByNameAndType(const QStringList& path, Node::Type type) const;
|
||||
InnerNode* findRelatesNode(const QStringList& path);
|
||||
NameCollisionNode* checkForCollision(const QString& name);
|
||||
NameCollisionNode* findCollisionNode(const QString& name) const;
|
||||
|
Loading…
Reference in New Issue
Block a user