summaryrefslogtreecommitdiffstats
path: root/tools/qdoc3
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qdoc3')
-rw-r--r--tools/qdoc3/atom.cpp2
-rw-r--r--tools/qdoc3/atom.h1
-rw-r--r--tools/qdoc3/codemarker.cpp145
-rw-r--r--tools/qdoc3/codemarker.h20
-rw-r--r--tools/qdoc3/codeparser.cpp27
-rw-r--r--tools/qdoc3/codeparser.h1
-rw-r--r--tools/qdoc3/command.cpp44
-rw-r--r--tools/qdoc3/config.cpp2
-rw-r--r--tools/qdoc3/config.h2
-rw-r--r--tools/qdoc3/cppcodemarker.cpp218
-rw-r--r--tools/qdoc3/cppcodemarker.h5
-rw-r--r--tools/qdoc3/cppcodeparser.cpp333
-rw-r--r--tools/qdoc3/cppcodeparser.h15
-rw-r--r--tools/qdoc3/doc.cpp2015
-rw-r--r--tools/qdoc3/doc.h177
-rw-r--r--tools/qdoc3/generator.cpp384
-rw-r--r--tools/qdoc3/generator.h17
-rw-r--r--tools/qdoc3/helpprojectwriter.cpp35
-rw-r--r--tools/qdoc3/htmlgenerator.cpp1762
-rw-r--r--tools/qdoc3/htmlgenerator.h63
-rw-r--r--tools/qdoc3/jambiapiparser.cpp5
-rw-r--r--tools/qdoc3/javadocgenerator.cpp3
-rw-r--r--tools/qdoc3/javadocgenerator.h2
-rw-r--r--tools/qdoc3/main.cpp76
-rw-r--r--tools/qdoc3/node.cpp118
-rw-r--r--tools/qdoc3/node.h135
-rw-r--r--tools/qdoc3/pagegenerator.cpp59
-rw-r--r--tools/qdoc3/qdoc3.pro7
-rw-r--r--tools/qdoc3/separator.cpp36
-rw-r--r--tools/qdoc3/separator.h1
-rw-r--r--tools/qdoc3/test/assistant.qdocconf6
-rw-r--r--tools/qdoc3/test/classic.css159
-rw-r--r--tools/qdoc3/test/designer.qdocconf6
-rw-r--r--tools/qdoc3/test/linguist.qdocconf6
-rw-r--r--tools/qdoc3/test/macros.qdocconf5
-rw-r--r--tools/qdoc3/test/qmake.qdocconf6
-rw-r--r--tools/qdoc3/test/qt-build-docs.qdocconf10
-rw-r--r--tools/qdoc3/test/qt-cpp-ignore.qdocconf6
-rw-r--r--tools/qdoc3/test/qt-inc.qdocconf6
-rw-r--r--tools/qdoc3/test/qt.qdocconf10
-rw-r--r--tools/qdoc3/tree.cpp134
-rw-r--r--tools/qdoc3/webxmlgenerator.cpp4
42 files changed, 2944 insertions, 3124 deletions
diff --git a/tools/qdoc3/atom.cpp b/tools/qdoc3/atom.cpp
index a82a783..da32735 100644
--- a/tools/qdoc3/atom.cpp
+++ b/tools/qdoc3/atom.cpp
@@ -93,6 +93,7 @@ QString Atom::UPPERROMAN_ ("upperroman");
\value AbstractLeft
\value AbstractRight
+ \value AnnotatedList
\value AutoLink
\value BaseName
\value BriefLeft
@@ -163,6 +164,7 @@ static const struct {
} atms[] = {
{ "AbstractLeft", Atom::AbstractLeft },
{ "AbstractRight", Atom::AbstractRight },
+ { "AnnotatedList", Atom::AnnotatedList },
{ "AutoLink", Atom::AutoLink },
{ "BaseName", Atom::BaseName },
{ "BriefLeft", Atom::BriefLeft },
diff --git a/tools/qdoc3/atom.h b/tools/qdoc3/atom.h
index 6d5af0a..941ac70 100644
--- a/tools/qdoc3/atom.h
+++ b/tools/qdoc3/atom.h
@@ -58,6 +58,7 @@ class Atom
enum Type {
AbstractLeft,
AbstractRight,
+ AnnotatedList,
AutoLink,
BaseName,
BriefLeft,
diff --git a/tools/qdoc3/codemarker.cpp b/tools/qdoc3/codemarker.cpp
index 728f9fa..4c018d1 100644
--- a/tools/qdoc3/codemarker.cpp
+++ b/tools/qdoc3/codemarker.cpp
@@ -168,7 +168,8 @@ const Node *CodeMarker::nodeForString(const QString& string)
{
if (sizeof(const Node *) == sizeof(uint)) {
return reinterpret_cast<const Node *>(string.toUInt());
- } else {
+ }
+ else {
return reinterpret_cast<const Node *>(string.toULongLong());
}
}
@@ -177,7 +178,8 @@ QString CodeMarker::stringForNode(const Node *node)
{
if (sizeof(const Node *) == sizeof(ulong)) {
return QString::number(reinterpret_cast<ulong>(node));
- } else {
+ }
+ else {
return QString::number(reinterpret_cast<qulonglong>(node));
}
}
@@ -220,7 +222,8 @@ QString CodeMarker::typified(const QString &string)
|| ch.digitValue() >= 0 || ch == QLatin1Char('_')
|| ch == QLatin1Char(':')) {
pendingWord += ch;
- } else {
+ }
+ else {
if (!pendingWord.isEmpty()) {
bool isProbablyType = (pendingWord != QLatin1String("const"));
if (isProbablyType)
@@ -251,7 +254,7 @@ QString CodeMarker::typified(const QString &string)
return result;
}
-QString CodeMarker::taggedNode(const Node *node)
+QString CodeMarker::taggedNode(const Node* node)
{
QString tag;
@@ -276,11 +279,35 @@ QString CodeMarker::taggedNode(const Node *node)
break;
default:
tag = QLatin1String("@unknown");
+ break;
}
return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
+ QLatin1String("</") + tag + QLatin1Char('>');
}
+#ifdef QDOC_QML
+QString CodeMarker::taggedQmlNode(const Node* node)
+{
+ QString tag;
+ switch (node->type()) {
+ case Node::QmlProperty:
+ tag = QLatin1String("@property");
+ break;
+ case Node::QmlSignal:
+ tag = QLatin1String("@signal");
+ break;
+ case Node::QmlMethod:
+ tag = QLatin1String("@method");
+ break;
+ default:
+ tag = QLatin1String("@unknown");
+ break;
+ }
+ return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
+ + QLatin1String("</") + tag + QLatin1Char('>');
+}
+#endif
+
QString CodeMarker::linkTag(const Node *node, const QString& body)
{
return QLatin1String("<@link node=\"") + stringForNode(node)
@@ -308,9 +335,11 @@ QString CodeMarker::sortName(const Node *node)
QString sortNo;
if (func->metaness() == FunctionNode::Ctor) {
sortNo = QLatin1String("C");
- } else if (func->metaness() == FunctionNode::Dtor) {
+ }
+ else if (func->metaness() == FunctionNode::Dtor) {
sortNo = QLatin1String("D");
- } else {
+ }
+ else {
if (nodeName.startsWith(QLatin1String("operator"))
&& nodeName.length() > 8
&& !nodeName[8].isLetterOrNumber())
@@ -331,20 +360,30 @@ QString CodeMarker::sortName(const Node *node)
return QLatin1Char('B') + nodeName;
}
-void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle style, Status status)
+void CodeMarker::insert(FastSection &fastSection,
+ Node *node,
+ SynopsisStyle style,
+ Status status)
{
- bool inheritedMember = (!node->relates() &&
- (node->parent() != (const InnerNode *)fastSection.innerNode));
bool irrelevant = false;
+ bool inheritedMember = false;
+ if (!node->relates()) {
+ if (node->parent() != (const InnerNode*)fastSection.innerNode) {
+ if (node->type() != Node::QmlProperty)
+ inheritedMember = true;
+ }
+ }
if (node->access() == Node::Private) {
irrelevant = true;
- } else if (node->type() == Node::Function) {
+ }
+ else if (node->type() == Node::Function) {
FunctionNode *func = (FunctionNode *) node;
irrelevant = (inheritedMember
&& (func->metaness() == FunctionNode::Ctor ||
func->metaness() == FunctionNode::Dtor));
- } else if (node->type() == Node::Class || node->type() == Node::Enum
+ }
+ else if (node->type() == Node::Class || node->type() == Node::Enum
|| node->type() == Node::Typedef) {
irrelevant = (inheritedMember && style != SeparateList);
if (!irrelevant && style == Detailed && node->type() == Node::Typedef) {
@@ -357,9 +396,11 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl
if (!irrelevant) {
if (status == Compat) {
irrelevant = (node->status() != Node::Compat);
- } else if (status == Obsolete) {
+ }
+ else if (status == Obsolete) {
irrelevant = (node->status() != Node::Obsolete);
- } else {
+ }
+ else {
irrelevant = (node->status() == Node::Compat ||
node->status() == Node::Obsolete);
}
@@ -370,7 +411,8 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl
QString key = sortName(node);
if (!fastSection.memberMap.contains(key))
fastSection.memberMap.insert(key, node);
- } else {
+ }
+ else {
if (node->parent()->type() == Node::Class) {
if (fastSection.inherited.isEmpty()
|| fastSection.inherited.last().first != node->parent()) {
@@ -383,16 +425,42 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl
}
}
-void CodeMarker::append(QList<Section>& sectionList,
- const FastSection& fastSection)
+/*!
+ Returns true if \a node represents a reimplemented member function.
+ If it is, then it is inserted in the reimplemented member map in the
+ section \a fs. And, the test is only performed if \a status is \e OK.
+ Otherwise, false is returned.
+ */
+bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status)
+{
+ if (node->access() == Node::Private)
+ return false;
+
+ const FunctionNode* fn = static_cast<const FunctionNode*>(node);
+ if ((fn->reimplementedFrom() != 0) && (status == Okay)) {
+ bool inherited = (!fn->relates() && (fn->parent() != (const InnerNode*)fs.innerNode));
+ if (!inherited) {
+ QString key = sortName(fn);
+ if (!fs.reimpMemberMap.contains(key)) {
+ fs.reimpMemberMap.insert(key,node);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+/*!
+ If \a fs is not empty, convert it to a Section and append
+ the new Section to \a sectionList.
+ */
+void CodeMarker::append(QList<Section>& sectionList, const FastSection& fs)
{
- if (!fastSection.memberMap.isEmpty() ||
- !fastSection.inherited.isEmpty()) {
- Section section(fastSection.name,
- fastSection.singularMember,
- fastSection.pluralMember);
- section.members = fastSection.memberMap.values();
- section.inherited = fastSection.inherited;
+ if (!fs.isEmpty()) {
+ Section section(fs.name,fs.singularMember,fs.pluralMember);
+ section.members = fs.memberMap.values();
+ section.reimpMembers = fs.reimpMemberMap.values();
+ section.inherited = fs.inherited;
sectionList.append(section);
}
}
@@ -428,7 +496,8 @@ QStringList CodeMarker::macRefsForNode(const Node *node)
#if 0
if (!classe->templateStuff().isEmpty()) {
result += QLatin1String("tmplt/");
- } else
+ }
+ else
#endif
{
result += QLatin1String("cl/");
@@ -465,14 +534,18 @@ QStringList CodeMarker::macRefsForNode(const Node *node)
result += QLatin1String("macro/");
isMacro = true;
#if 0
- } else if (!func->templateStuff().isEmpty()) {
+ }
+ else if (!func->templateStuff().isEmpty()) {
result += QLatin1String("ftmplt/");
#endif
- } else if (func->isStatic()) {
+ }
+ else if (func->isStatic()) {
result += QLatin1String("clm/");
- } else if (!func->parent()->name().isEmpty()) {
+ }
+ else if (!func->parent()->name().isEmpty()) {
result += QLatin1String("instm/");
- } else {
+ }
+ else {
result += QLatin1String("func/");
}
@@ -486,7 +559,8 @@ QStringList CodeMarker::macRefsForNode(const Node *node)
result += "/" + QLatin1String(QMetaObject::normalizedSignature(func->returnType().toLatin1().constData())) + "/(";
const QList<Parameter> &params = func->parameters();
for (int i = 0; i < params.count(); ++i) {
- QString type = params.at(i).leftType() + params.at(i).rightType();
+ QString type = params.at(i).leftType() +
+ params.at(i).rightType();
type = QLatin1String(QMetaObject::normalizedSignature(type.toLatin1().constData()));
if (i != 0)
result += ",";
@@ -529,10 +603,21 @@ QString CodeMarker::macName(const Node *node, const QString &name)
if (node->name().isEmpty()) {
return QLatin1Char('/') + myName;
- } else {
+ }
+ else {
return plainFullName(node) + QLatin1Char('/') + myName;
}
}
+#ifdef QDOC_QML
+/*!
+ Get the list of documentation sections for the children of
+ the specified QmlClassNode.
+ */
+QList<Section> CodeMarker::qmlSections(const QmlClassNode* , SynopsisStyle )
+{
+ return QList<Section>();
+}
+#endif
QT_END_NAMESPACE
diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h
index 483dc4d..91dc8b0 100644
--- a/tools/qdoc3/codemarker.h
+++ b/tools/qdoc3/codemarker.h
@@ -61,6 +61,7 @@ struct Section
QString singularMember;
QString pluralMember;
NodeList members;
+ NodeList reimpMembers;
QList<QPair<ClassNode *, int> > inherited;
Section() { }
@@ -79,6 +80,7 @@ struct FastSection
QString singularMember;
QString pluralMember;
QMap<QString, Node *> memberMap;
+ QMap<QString, Node *> reimpMemberMap;
QList<QPair<ClassNode *, int> > inherited;
FastSection(const InnerNode *innerNode0,
@@ -89,6 +91,11 @@ struct FastSection
name(name0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
+ bool isEmpty() const {
+ return (memberMap.isEmpty() && inherited.isEmpty() &&
+ reimpMemberMap.isEmpty());
+ }
+
};
class CodeMarker
@@ -114,6 +121,9 @@ class CodeMarker
virtual QString markedUpSynopsis(const Node *node,
const Node *relative,
SynopsisStyle style) = 0;
+#ifdef QDOC_QML
+ virtual QString markedUpQmlItem(const Node* , bool) { return QString(); }
+#endif
virtual QString markedUpName(const Node *node) = 0;
virtual QString markedUpFullName(const Node *node,
const Node *relative = 0) = 0;
@@ -125,6 +135,10 @@ class CodeMarker
virtual QList<Section> sections(const InnerNode *inner,
SynopsisStyle style,
Status status) = 0;
+#ifdef QDOC_QML
+ virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
+ SynopsisStyle style);
+#endif
virtual const Node *resolveTarget(const QString& target,
const Tree *tree,
const Node *relative) = 0;
@@ -144,12 +158,16 @@ class CodeMarker
virtual QString sortName(const Node *node);
QString protect(const QString &string);
QString typified(const QString &string);
- QString taggedNode(const Node *node);
+ QString taggedNode(const Node* node);
+#ifdef QDOC_QML
+ QString taggedQmlNode(const Node* node);
+#endif
QString linkTag(const Node *node, const QString& body);
void insert(FastSection &fastSection,
Node *node,
SynopsisStyle style,
Status status);
+ bool insertReimpFunc(FastSection& fs, Node* node, Status status);
void append(QList<Section>& sectionList, const FastSection& fastSection);
private:
diff --git a/tools/qdoc3/codeparser.cpp b/tools/qdoc3/codeparser.cpp
index 2fedd67..92243fa 100644
--- a/tools/qdoc3/codeparser.cpp
+++ b/tools/qdoc3/codeparser.cpp
@@ -47,6 +47,7 @@
#include "codeparser.h"
#include "node.h"
#include "tree.h"
+#include "config.h"
QT_BEGIN_NAMESPACE
@@ -67,6 +68,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_TITLE Doc::alias(QLatin1String("title"))
QList<CodeParser *> CodeParser::parsers;
+bool CodeParser::showInternal = false;
/*!
The constructor adds this code parser to the static
@@ -87,11 +89,11 @@ CodeParser::~CodeParser()
}
/*!
- Initializing a code parser is trivial.
+ Initialize the code parser base class.
*/
-void CodeParser::initializeParser(const Config & /* config */)
+void CodeParser::initializeParser(const Config& config)
{
- // nothing.
+ showInternal = config.getBool(QLatin1String(CONFIG_SHOWINTERNAL));
}
/*!
@@ -217,8 +219,10 @@ void CodeParser::processCommonMetaCommand(const Location &location,
node->setStatus(Node::Preliminary);
}
else if (command == COMMAND_INTERNAL) {
- node->setAccess(Node::Private);
- node->setStatus(Node::Internal);
+ if (!showInternal) {
+ node->setAccess(Node::Private);
+ node->setStatus(Node::Internal);
+ }
}
else if (command == COMMAND_REENTRANT) {
node->setThreadSafeness(Node::Reentrant);
@@ -241,19 +245,6 @@ void CodeParser::processCommonMetaCommand(const Location &location,
if (node->type() == Node::Fake) {
FakeNode *fake = static_cast<FakeNode *>(node);
fake->setTitle(arg);
-#ifdef QDOC2DOX
- /* qdoc -> doxygen.
- I think this must be done here, because there can be multiple
- "\externalpage" and "\title" metacommands in a single qdoc
- comment, which means, among other things, that the "\title"
- commands are not inserted into the metacommand map used by
- the Doc class. I'm sure there4 is a better way to do this in
- the DoxWriter class using the information in the FakeNode,
- but I don't have time to figure it out right now.
- */
- if (DoxWriter::isDoxPass(1))
- DoxWriter::insertTitle(fake,arg);
-#endif
}
else
location.warning(tr("Ignored '\\%1'").arg(COMMAND_TITLE));
diff --git a/tools/qdoc3/codeparser.h b/tools/qdoc3/codeparser.h
index 8f5bd87..06603a9 100644
--- a/tools/qdoc3/codeparser.h
+++ b/tools/qdoc3/codeparser.h
@@ -87,6 +87,7 @@ class CodeParser
private:
static QList<CodeParser *> parsers;
+ static bool showInternal;
};
QT_END_NAMESPACE
diff --git a/tools/qdoc3/command.cpp b/tools/qdoc3/command.cpp
index e51e235..bce262b 100644
--- a/tools/qdoc3/command.cpp
+++ b/tools/qdoc3/command.cpp
@@ -49,44 +49,46 @@
QT_BEGIN_NAMESPACE
-void executeCommand( const Location& location, const QString& format,
- const QStringList& args )
+void executeCommand(const Location& location,
+ const QString& format,
+ const QStringList& args)
{
QString actualCommand;
- for ( int i = 0; i < (int) format.length(); i++ ) {
+ for (int i = 0; i < (int) format.length(); i++) {
int ch = format[i].unicode();
- if ( ch > 0 && ch < 8 ) {
+ if (ch > 0 && ch < 8) {
actualCommand += args[ch - 1];
- } else {
+ }
+ else {
actualCommand += format[i];
}
}
QString toolName = actualCommand;
- int space = toolName.indexOf( QLatin1Char(' ') );
- if ( space != -1 )
- toolName.truncate( space );
+ int space = toolName.indexOf(QLatin1Char(' '));
+ if (space != -1)
+ toolName.truncate(space);
QProcess process;
process.start(QLatin1String("sh"),
- QStringList() << QLatin1String("-c") << actualCommand );
+ QStringList() << QLatin1String("-c") << actualCommand);
process.waitForFinished();
if (process.exitCode() == 127)
- location.fatal( tr("Couldn't launch the '%1' tool")
- .arg(toolName),
- tr("Make sure the tool is installed and in the"
- " path.") );
+ location.fatal(tr("Couldn't launch the '%1' tool")
+ .arg(toolName),
+ tr("Make sure the tool is installed and in the"
+ " path."));
QString errors = QString::fromLocal8Bit(process.readAllStandardError());
- while ( errors.endsWith(QLatin1Char('\n')) )
- errors.truncate( errors.length() - 1 );
- if ( !errors.isEmpty() )
- location.fatal( tr("The '%1' tool encountered some problems")
- .arg(toolName),
- tr("The tool was invoked like this:\n%1\n"
- "It emitted these errors:\n%2")
- .arg(actualCommand).arg(errors) );
+ while (errors.endsWith(QLatin1Char('\n')))
+ errors.truncate(errors.length() - 1);
+ if (!errors.isEmpty())
+ location.fatal(tr("The '%1' tool encountered some problems")
+ .arg(toolName),
+ tr("The tool was invoked like this:\n%1\n"
+ "It emitted these errors:\n%2")
+ .arg(actualCommand).arg(errors));
}
QT_END_NAMESPACE
diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp
index 20b0aa7..ad993d9 100644
--- a/tools/qdoc3/config.cpp
+++ b/tools/qdoc3/config.cpp
@@ -751,7 +751,7 @@ void Config::load(Location location, const QString& fileName)
word += QChar(c.digitValue());
SKIP_CHAR();
}
- else if ((metaCharPos = QString(QLatin1String("abfnrtv")).indexOf(c)) != -1) {
+ else if ((metaCharPos = QString::fromLatin1("abfnrtv").indexOf(c)) != -1) {
word += "\a\b\f\n\r\t\v"[metaCharPos];
SKIP_CHAR();
}
diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h
index 8f25340..22cb671 100644
--- a/tools/qdoc3/config.h
+++ b/tools/qdoc3/config.h
@@ -140,6 +140,7 @@ class Config
#define CONFIG_INDEXES "indexes"
#define CONFIG_LANGUAGE "language"
#define CONFIG_MACRO "macro"
+#define CONFIG_OBSOLETELINKS "obsoletelinks"
#define CONFIG_OUTPUTDIR "outputdir"
#define CONFIG_OUTPUTLANGUAGE "outputlanguage"
#define CONFIG_OUTPUTFORMATS "outputformats"
@@ -147,6 +148,7 @@ class Config
#define CONFIG_QHP "qhp"
#define CONFIG_QUOTINGINFORMATION "quotinginformation"
#define CONFIG_SLOW "slow"
+#define CONFIG_SHOWINTERNAL "showinternal"
#define CONFIG_SOURCEDIRS "sourcedirs"
#define CONFIG_SOURCES "sources"
#define CONFIG_SPURIOUS "spurious"
diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp
index 6760c65..0f8d1b7 100644
--- a/tools/qdoc3/cppcodemarker.cpp
+++ b/tools/qdoc3/cppcodemarker.cpp
@@ -43,6 +43,7 @@
cppcodemarker.cpp
*/
+#include <qdebug.h>
#include "atom.h"
#include "cppcodemarker.h"
#include "node.h"
@@ -283,7 +284,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
}
else {
for (int i = 0; i < documentedItems.size(); ++i) {
- if (i < MaxEnumValues - 2 || i == documentedItems.size() - 1) {
+ if (i < MaxEnumValues-2 || i == documentedItems.size()-1) {
if (i != 0)
synopsis += ", ";
synopsis += documentedItems.at(i);
@@ -344,6 +345,43 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
return synopsis + extra;
}
+#ifdef QDOC_QML
+/*!
+ */
+QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
+{
+ QString name = taggedQmlNode(node);
+ if (summary) {
+ name = linkTag(node,name);
+ }
+ name = "<@name>" + name + "</@name>";
+ QString synopsis = name;
+ if (node->type() == Node::QmlProperty) {
+ const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
+ synopsis += " : " + typified(pn->dataType());
+ }
+
+ QString extra;
+ if (summary) {
+ if (node->status() == Node::Preliminary) {
+ extra += " (preliminary)";
+ }
+ else if (node->status() == Node::Deprecated) {
+ extra += " (deprecated)";
+ }
+ else if (node->status() == Node::Obsolete) {
+ extra += " (obsolete)";
+ }
+ }
+
+ if (!extra.isEmpty()) {
+ extra.prepend("<@extra>");
+ extra.append("</@extra>");
+ }
+ return synopsis + extra;
+}
+#endif
+
QString CppCodeMarker::markedUpName(const Node *node)
{
QString name = linkTag(node, taggedNode(node));
@@ -411,6 +449,21 @@ QString CppCodeMarker::functionEndRegExp(const QString& /* funcName */)
return "^\\}$";
}
+#if 0
+ FastSection privateReimpFuncs(classe,
+ "Private Reimplemented Functions",
+ "private reimplemented function",
+ "private reimplemented functions");
+ FastSection protectedReimpFuncs(classe,
+ "Protected Reimplemented Functions",
+ "protected reimplemented function",
+ "protected reimplemented functions");
+ FastSection publicReimpFuncs(classe,
+ "Public Reimplemented Functions",
+ "public reimplemented function",
+ "public reimplemented functions");
+#endif
+
QList<Section> CppCodeMarker::sections(const InnerNode *inner,
SynopsisStyle style,
Status status)
@@ -421,29 +474,55 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
const ClassNode *classe = static_cast<const ClassNode *>(inner);
if (style == Summary) {
- FastSection privateFunctions(classe, "Private Functions", "private function",
+ FastSection privateFunctions(classe,
+ "Private Functions",
+ "private function",
"private functions");
FastSection privateSlots(classe, "Private Slots", "private slot", "private slots");
FastSection privateTypes(classe, "Private Types", "private type", "private types");
- FastSection protectedFunctions(classe, "Protected Functions", "protected function",
+ FastSection protectedFunctions(classe,
+ "Protected Functions",
+ "protected function",
"protected functions");
- FastSection protectedSlots(classe, "Protected Slots", "protected slot", "protected slots");
- FastSection protectedTypes(classe, "Protected Types", "protected type", "protected types");
- FastSection protectedVariables(classe, "Protected Variables", "protected type", "protected variables");
- FastSection publicFunctions(classe, "Public Functions", "public function",
- "public functions");
+ FastSection protectedSlots(classe,
+ "Protected Slots",
+ "protected slot",
+ "protected slots");
+ FastSection protectedTypes(classe,
+ "Protected Types",
+ "protected type",
+ "protected types");
+ FastSection protectedVariables(classe,
+ "Protected Variables",
+ "protected type",
+ "protected variables");
+ FastSection publicFunctions(classe,
+ "Public Functions",
+ "public function",
+ "public functions");
FastSection publicSignals(classe, "Signals", "signal", "signals");
FastSection publicSlots(classe, "Public Slots", "public slot", "public slots");
FastSection publicTypes(classe, "Public Types", "public type", "public types");
- FastSection publicVariables(classe, "Public Variables", "public type", "public variables");
+ FastSection publicVariables(classe,
+ "Public Variables",
+ "public type",
+ "public variables");
FastSection properties(classe, "Properties", "property", "properties");
- FastSection relatedNonMembers(classe, "Related Non-Members", "related non-member",
+ FastSection relatedNonMembers(classe,
+ "Related Non-Members",
+ "related non-member",
"related non-members");
- FastSection staticPrivateMembers(classe, "Static Private Members", "static private member",
+ FastSection staticPrivateMembers(classe,
+ "Static Private Members",
+ "static private member",
"static private members");
- FastSection staticProtectedMembers(classe, "Static Protected Members",
- "static protected member", "static protected members");
- FastSection staticPublicMembers(classe, "Static Public Members", "static public member",
+ FastSection staticProtectedMembers(classe,
+ "Static Protected Members",
+ "static protected member",
+ "static protected members");
+ FastSection staticPublicMembers(classe,
+ "Static Public Members",
+ "static public member",
"static public members");
FastSection macros(inner, "Macros", "macro", "macros");
@@ -495,7 +574,7 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
else if (isStatic) {
if ((*c)->type() != Node::Variable
|| !(*c)->doc().isEmpty())
- insert(staticPublicMembers, *c, style, status);
+ insert(staticPublicMembers,*c,style,status);
}
else if ((*c)->type() == Node::Property) {
insert(properties, *c, style, status);
@@ -505,7 +584,8 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
insert(publicVariables, *c, style, status);
}
else if ((*c)->type() == Node::Function) {
- insert(publicFunctions, *c, style, status);
+ if (!insertReimpFunc(publicFunctions,*c,status))
+ insert(publicFunctions, *c, style, status);
}
else {
insert(publicTypes, *c, style, status);
@@ -518,14 +598,15 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
else if (isStatic) {
if ((*c)->type() != Node::Variable
|| !(*c)->doc().isEmpty())
- insert(staticProtectedMembers, *c, style, status);
+ insert(staticProtectedMembers,*c,style,status);
}
else if ((*c)->type() == Node::Variable) {
if (!(*c)->doc().isEmpty())
- insert(protectedVariables, *c, style, status);
+ insert(protectedVariables,*c,style,status);
}
else if ((*c)->type() == Node::Function) {
- insert(protectedFunctions, *c, style, status);
+ if (!insertReimpFunc(protectedFunctions,*c,status))
+ insert(protectedFunctions, *c, style, status);
}
else {
insert(protectedTypes, *c, style, status);
@@ -538,13 +619,14 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
else if (isStatic) {
if ((*c)->type() != Node::Variable
|| !(*c)->doc().isEmpty())
- insert(staticPrivateMembers, *c, style, status);
+ insert(staticPrivateMembers,*c,style,status);
}
else if ((*c)->type() == Node::Function) {
- insert(privateFunctions, *c, style, status);
+ if (!insertReimpFunc(privateFunctions,*c,status))
+ insert(privateFunctions, *c, style, status);
}
else {
- insert(privateTypes, *c, style, status);
+ insert(privateTypes,*c,style,status);
}
}
++c;
@@ -661,17 +743,23 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
"Namespaces",
"namespace",
"namespaces");
- FastSection classes(inner, "Classes", "class", "classes");
+ FastSection classes(inner,
+ "Classes",
+ "class",
+ "classes");
FastSection types(inner,
- style == Summary ? "Types" : "Type Documentation",
+ style == Summary ?
+ "Types" : "Type Documentation",
"type",
"types");
FastSection functions(inner,
- style == Summary ? "Functions" : "Function Documentation",
+ style == Summary ?
+ "Functions" : "Function Documentation",
"function",
"functions");
FastSection macros(inner,
- style == Summary ? "Macros" : "Macro Documentation",
+ style == Summary ?
+ "Macros" : "Macro Documentation",
"macro",
"macros");
@@ -1006,4 +1094,82 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode,
return result;
}
+#ifdef QDOC_QML
+/*!
+ This function is for documenting QML properties. It returns
+ the list of documentation sections for the children of the
+ \a qmlClassNode.
+
+ Currently, it only handles QML property groups.
+ */
+QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
+ SynopsisStyle style)
+{
+ QList<Section> sections;
+ if (qmlClassNode) {
+ if (style == Summary) {
+ FastSection qmlproperties(qmlClassNode,
+ "QML Properties",
+ "property",
+ "properties");
+ FastSection qmlsignals(qmlClassNode,
+ "QML Signals",
+ "signal",
+ "signals");
+ FastSection qmlmethods(qmlClassNode,
+ "QML Methods",
+ "method",
+ "methods");
+
+ NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
+ while (c != qmlClassNode->childNodes().end()) {
+ if ((*c)->subType() == Node::QmlPropertyGroup) {
+ const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
+ NodeList::ConstIterator p = qpgn->childNodes().begin();
+ while (p != qpgn->childNodes().end()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ insert(qmlproperties,*p,style,Okay);
+ }
+ ++p;
+ }
+ }
+ else if ((*c)->type() == Node::QmlSignal) {
+ insert(qmlsignals,*c,style,Okay);
+ }
+ else if ((*c)->type() == Node::QmlMethod) {
+ insert(qmlmethods,*c,style,Okay);
+ }
+ ++c;
+ }
+ append(sections,qmlproperties);
+ append(sections,qmlsignals);
+ append(sections,qmlmethods);
+ }
+ else if (style == Detailed) {
+ FastSection qmlproperties(qmlClassNode,"QML Property Documentation");
+ FastSection qmlsignals(qmlClassNode,"QML Signal Documentation");
+ FastSection qmlmethods(qmlClassNode,"QML Method Documentation");
+ NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
+ while (c != qmlClassNode->childNodes().end()) {
+ if ((*c)->subType() == Node::QmlPropertyGroup) {
+ insert(qmlproperties,*c,style,Okay);
+ }
+ else if ((*c)->type() == Node::QmlSignal) {
+ insert(qmlsignals,*c,style,Okay);
+ }
+ else if ((*c)->type() == Node::QmlMethod) {
+ insert(qmlmethods,*c,style,Okay);
+ }
+ ++c;
+ }
+ append(sections,qmlproperties);
+ append(sections,qmlsignals);
+ append(sections,qmlmethods);
+ }
+ }
+
+ return sections;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/tools/qdoc3/cppcodemarker.h b/tools/qdoc3/cppcodemarker.h
index 2967dfe..fa3cb78 100644
--- a/tools/qdoc3/cppcodemarker.h
+++ b/tools/qdoc3/cppcodemarker.h
@@ -67,6 +67,9 @@ class CppCodeMarker : public CodeMarker
QString markedUpSynopsis(const Node *node,
const Node *relative,
SynopsisStyle style);
+#ifdef QDOC_QML
+ QString markedUpQmlItem(const Node *node, bool summary);
+#endif
QString markedUpName(const Node *node);
QString markedUpFullName(const Node *node, const Node *relative);
QString markedUpEnumValue(const QString &enumValue, const Node *relative);
@@ -76,6 +79,8 @@ class CppCodeMarker : public CodeMarker
QList<Section> sections(const InnerNode *innerNode,
SynopsisStyle style,
Status status);
+ QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
+ SynopsisStyle style);
const Node *resolveTarget(const QString& target,
const Tree *tree,
const Node *relative);
diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp
index 204c6e5..562684b 100644
--- a/tools/qdoc3/cppcodeparser.cpp
+++ b/tools/qdoc3/cppcodeparser.cpp
@@ -87,6 +87,10 @@ QT_BEGIN_NAMESPACE
#ifdef QDOC_QML
#define COMMAND_QMLCLASS Doc::alias("qmlclass")
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
+#define COMMAND_QMLINHERITS Doc::alias("inherits")
+#define COMMAND_QMLSIGNAL Doc::alias("qmlsignal")
+#define COMMAND_QMLMETHOD Doc::alias("qmlmethod")
+#define COMMAND_QMLDEFAULT Doc::alias("default")
#endif
QStringList CppCodeParser::exampleFiles;
@@ -109,7 +113,8 @@ static void extractPageLinkAndDesc(const QString &arg,
if (arg.contains(".html") && spaceAt != -1) {
*link = arg.left(spaceAt).trimmed();
*desc = arg.mid(spaceAt).trimmed();
- } else {
+ }
+ else {
*link = arg;
*desc = arg;
}
@@ -202,11 +207,6 @@ void CppCodeParser::initializeParser(const Config &config)
nodeTypeMap.insert(COMMAND_PROPERTY, Node::Property);
nodeTypeMap.insert(COMMAND_VARIABLE, Node::Variable);
-#ifdef QDOC_QML
- // nodeTypeMap.insert(COMMAND_QMLCLASS, Node::Class);
- nodeTypeMap.insert(COMMAND_QMLPROPERTY, Node::Property);
-#endif
-
exampleFiles = config.getStringList(CONFIG_EXAMPLES);
exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS);
QStringList exampleFilePatterns = config.getStringList(
@@ -477,13 +477,15 @@ QSet<QString> CppCodeParser::topicCommands()
<< COMMAND_PROPERTY
<< COMMAND_SERVICE
<< COMMAND_TYPEDEF
-#ifdef QDOC_QML
+#ifdef QDOC_QML
<< COMMAND_VARIABLE
<< COMMAND_QMLCLASS
- << COMMAND_QMLPROPERTY;
-#else
+ << COMMAND_QMLPROPERTY
+ << COMMAND_QMLSIGNAL
+ << COMMAND_QMLMETHOD;
+#else
<< COMMAND_VARIABLE;
-#endif
+#endif
}
/*!
@@ -587,24 +589,8 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc,
The command was neither "fn" nor "macro" .
*/
// ### split(" ") hack is there to support header file syntax
- QStringList paths = arg.split(" ");
+ QStringList paths = arg.split(" ");
QStringList path = paths[0].split("::");
-
-#if QDOC2DOX
- // qdoc -> doxygen.
- if (Doc::isDoxPass(1)) {
- if (command == COMMAND_PROPERTY) {
- Doc::insertProperty(path);
- }
- else if (command == COMMAND_VARIABLE) {
- Doc::insertVariable(path);
- }
- else if (command == COMMAND_ENUM) {
- // zzz
- }
- }
-#endif
-
Node *node = 0;
if (!usedNamespaces.isEmpty()) {
foreach (const QString &usedNamespace, usedNamespaces) {
@@ -643,49 +629,169 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc,
}
}
+ if (command == COMMAND_CLASS) {
+ if (paths.size() > 1) {
+ if (!paths[1].endsWith(".h")) {
+ ClassNode*cnode = static_cast<ClassNode*>(node);
+ cnode->setQmlElement(paths[1]);
+ }
+ }
+ }
return node;
}
else if (command == COMMAND_EXAMPLE) {
- FakeNode *fake = new FakeNode(tre->root(), arg, FakeNode::Example);
+ FakeNode *fake = new FakeNode(tre->root(), arg, Node::Example);
createExampleFileNodes(fake);
return fake;
}
else if (command == COMMAND_EXTERNALPAGE) {
- return new FakeNode(tre->root(), arg, FakeNode::ExternalPage);
+ return new FakeNode(tre->root(), arg, Node::ExternalPage);
}
else if (command == COMMAND_FILE) {
- return new FakeNode(tre->root(), arg, FakeNode::File);
+ return new FakeNode(tre->root(), arg, Node::File);
}
else if (command == COMMAND_GROUP) {
- return new FakeNode(tre->root(), arg, FakeNode::Group);
+ return new FakeNode(tre->root(), arg, Node::Group);
}
else if (command == COMMAND_HEADERFILE) {
- return new FakeNode(tre->root(), arg, FakeNode::HeaderFile);
+ return new FakeNode(tre->root(), arg, Node::HeaderFile);
}
else if (command == COMMAND_MODULE) {
- return new FakeNode(tre->root(), arg, FakeNode::Module);
+ return new FakeNode(tre->root(), arg, Node::Module);
}
else if (command == COMMAND_PAGE) {
- return new FakeNode(tre->root(), arg, FakeNode::Page);
+ return new FakeNode(tre->root(), arg, Node::Page);
}
-#ifdef QDOC_QML
+#ifdef QDOC_QML
else if (command == COMMAND_QMLCLASS) {
const ClassNode* classNode = 0;
- QStringList names = arg.split(" ");
- //qDebug() << "QMLCLASS" << names;
+ QStringList names = arg.split(" ");
if (names.size() > 1) {
Node* n = tre->findNode(names[1].split("::"),Node::Class);
- if (n) {
+ if (n)
classNode = static_cast<const ClassNode*>(n);
- //qDebug() << "FOUND IT!" << classNode->name();
+ }
+ return new QmlClassNode(tre->root(), names[0], classNode);
+ }
+ else if ((command == COMMAND_QMLSIGNAL) ||
+ (command == COMMAND_QMLMETHOD)) {
+ QString element;
+ QString name;
+ QmlClassNode* qmlClass = 0;
+ if (splitQmlArg(doc,arg,element,name)) {
+ Node* n = tre->findNode(QStringList(element),Node::Fake);
+ if (n && n->subType() == Node::QmlClass) {
+ qmlClass = static_cast<QmlClassNode*>(n);
+ if (command == COMMAND_QMLSIGNAL)
+ return new QmlSignalNode(qmlClass,name);
+ else
+ return new QmlMethodNode(qmlClass,name);
}
}
- return new QmlNode(tre->root(), names[0], classNode);
}
-#endif
+#endif
return 0;
}
+#ifdef QDOC_QML
+
+/*!
+ A QML property argument has the form...
+
+ <type> <element>::<name>
+
+ This function splits the argument into those three
+ parts, sets \a type, \a element, and \a property,
+ and returns true. If any of the parts isn't found,
+ a debug message is output and false is returned.
+ */
+bool CppCodeParser::splitQmlPropertyArg(const Doc& doc,
+ const QString& arg,
+ QString& type,
+ QString& element,
+ QString& property)
+{
+ QStringList blankSplit = arg.split(" ");
+ if (blankSplit.size() > 1) {
+ type = blankSplit[0];
+ QStringList colonSplit(blankSplit[1].split("::"));
+ if (colonSplit.size() > 1) {
+ element = colonSplit[0];
+ property = colonSplit[1];
+ return true;
+ }
+ else
+ doc.location().warning(tr("Missing QML element name or property name"));
+ }
+ else
+ doc.location().warning(tr("Missing QML property type or property path"));
+ return false;
+}
+
+/*!
+ A QML signal or method argument has the form...
+
+ <element>::<name>
+
+ This function splits the argument into those two
+ parts, sets \a element, and \a name, and returns
+ true. If either of the parts isn't found, a debug
+ message is output and false is returned.
+ */
+bool CppCodeParser::splitQmlArg(const Doc& doc,
+ const QString& arg,
+ QString& element,
+ QString& name)
+{
+ QStringList colonSplit(arg.split("::"));
+ if (colonSplit.size() > 1) {
+ element = colonSplit[0];
+ name = colonSplit[1];
+ return true;
+ }
+ else
+ doc.location().warning(tr("Missing QML element name or signal/method name"));
+ return false;
+}
+
+/*!
+ Process the topic \a command group with arguments \a args.
+
+ Currently, this function is called only for \e{qmlproperty}.
+ */
+Node *CppCodeParser::processTopicCommandGroup(const Doc& doc,
+ const QString& command,
+ const QStringList& args)
+{
+ QmlPropGroupNode* qmlPropGroup = 0;
+ if (command == COMMAND_QMLPROPERTY) {
+ QString type;
+ QString element;
+ QString property;
+ QStringList::ConstIterator arg = args.begin();
+ if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
+ Node* n = tre->findNode(QStringList(element),Node::Fake);
+ if (n && n->subType() == Node::QmlClass) {
+ QmlClassNode* qmlClass = static_cast<QmlClassNode*>(n);
+ if (qmlClass)
+ qmlPropGroup = new QmlPropGroupNode(qmlClass,property);
+ }
+ }
+ if (qmlPropGroup) {
+ new QmlPropertyNode(qmlPropGroup,property,type);
+ ++arg;
+ while (arg != args.end()) {
+ if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
+ new QmlPropertyNode(qmlPropGroup,property,type);
+ }
+ ++arg;
+ }
+ }
+ }
+ return qmlPropGroup;
+}
+#endif
+
/*!
Returns the set of strings representing the common metacommands
plus some other metacommands.
@@ -700,7 +806,13 @@ QSet<QString> CppCodeParser::otherMetaCommands()
<< COMMAND_NEXTPAGE
<< COMMAND_PREVIOUSPAGE
<< COMMAND_INDEXPAGE
+#ifdef QDOC_QML
+ << COMMAND_STARTPAGE
+ << COMMAND_QMLINHERITS
+ << COMMAND_QMLDEFAULT;
+#else
<< COMMAND_STARTPAGE;
+#endif
}
/*!
@@ -742,21 +854,29 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
tr("The function either doesn't exist in any base class "
"with the same signature or it exists but isn't virtual."));
}
-#if 0 // Ideally, we would enable this check to warn whenever \reimp is used
- // incorrectly, and only make the node internal if the function is a
- // reimplementation of another function in a base class.
+ /*
+ Ideally, we would enable this check to warn whenever
+ \reimp is used incorrectly, and only make the node
+ internal if the function is a reimplementation of
+ another function in a base class.
+ */
else if (from->access() == Node::Private
|| from->parent()->access() == Node::Private) {
- doc.location().warning(
- tr("Base function for '\\%1' in %2() is private or internal")
+ doc.location().warning(tr("'\\%1' in %2() should be '\\internal' because its base function is private or internal")
.arg(COMMAND_REIMP).arg(node->name()));
}
-#endif
- // Note: Setting the access to Private hides the documentation,
- // but setting the status to Internal makes the node available
- // in the XML output when the WebXMLGenerator is used.
+
+#if 0
+ // Reimplemented functions now reported in separate sections.
+ /*
+ Note: Setting the access to Private hides the documentation,
+ but setting the status to Internal makes the node available
+ in the XML output when the WebXMLGenerator is used.
+ */
func->setAccess(Node::Private);
func->setStatus(Node::Internal);
+#endif
+ func->setReimp(true);
}
else {
doc.location().warning(tr("Ignored '\\%1' in %2")
@@ -767,14 +887,19 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
else if (command == COMMAND_RELATES) {
InnerNode *pseudoParent;
if (arg.startsWith("<") || arg.startsWith("\"")) {
- pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(arg), Node::Fake));
+ pseudoParent =
+ static_cast<InnerNode *>(tre->findNode(QStringList(arg),
+ Node::Fake));
}
else {
QStringList newPath = arg.split("::");
- pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath), Node::Class));
+ pseudoParent =
+ static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
+ Node::Class));
if (!pseudoParent)
- pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath),
- Node::Namespace));
+ pseudoParent =
+ static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
+ Node::Namespace));
}
if (!pseudoParent) {
doc.location().warning(tr("Cannot find '%1' in '\\%2'")
@@ -799,6 +924,15 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
else if (command == COMMAND_STARTPAGE) {
setLink(node, Node::StartLink, arg);
}
+#ifdef QDOC_QML
+ else if (command == COMMAND_QMLINHERITS) {
+ setLink(node, Node::InheritsLink, arg);
+ }
+ else if (command == COMMAND_QMLDEFAULT) {
+ QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
+ qpgn->setDefault();
+ }
+#endif
else {
processCommonMetaCommand(doc.location(),command,arg,node,tre);
}
@@ -878,9 +1012,8 @@ bool CppCodeParser::match(int target)
readToken();
return true;
}
- else {
+ else
return false;
- }
}
/*!
@@ -915,11 +1048,14 @@ bool CppCodeParser::matchTemplateAngles(CodeChunk *dataType)
do {
if (tok == Tok_LeftAngle) {
leftAngleDepth++;
- } else if (tok == Tok_RightAngle) {
+ }
+ else if (tok == Tok_RightAngle) {
leftAngleDepth--;
- } else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
+ }
+ else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
++parenAndBraceDepth;
- } else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
+ }
+ else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
if (--parenAndBraceDepth < 0)
return false;
}
@@ -982,7 +1118,8 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var)
dataType->append(previousLexeme());
else
return false;
- } else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
+ }
+ else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
dataType->append(previousLexeme());
}
@@ -1082,8 +1219,10 @@ bool CppCodeParser::matchParameter(FunctionNode *func)
readToken();
}
}
- func->addParameter(Parameter(dataType.toString(), "", name,
- defaultValue.toString())); // ###
+ func->addParameter(Parameter(dataType.toString(),
+ "",
+ name,
+ defaultValue.toString())); // ###
return true;
}
@@ -1131,7 +1270,8 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent,
compat = true;
if (tok == Tok_operator &&
- (returnType.toString().isEmpty() || returnType.toString().endsWith("::"))) {
+ (returnType.toString().isEmpty() ||
+ returnType.toString().endsWith("::"))) {
// 'QString::operator const char *()'
parentPath = returnType.toString().split(sep);
parentPath.removeAll(QString());
@@ -1167,11 +1307,10 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent,
name = previousLexeme();
matchTemplateAngles();
- if (match(Tok_Gulbrandsen)) {
+ if (match(Tok_Gulbrandsen))
parentPath.append(name);
- } else {
+ else
break;
- }
}
if (tok == Tok_operator) {
@@ -1184,7 +1323,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent,
break;
}
}
- if (parent && (tok == Tok_Semicolon || tok == Tok_LeftBracket || tok == Tok_Colon)
+ if (parent && (tok == Tok_Semicolon ||
+ tok == Tok_LeftBracket ||
+ tok == Tok_Colon)
&& access != Node::Private) {
if (tok == Tok_LeftBracket) {
returnType.appendHotspot();
@@ -1198,7 +1339,8 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent,
}
if (tok != Tok_Semicolon)
return false;
- } else if (tok == Tok_Colon) {
+ }
+ else if (tok == Tok_Colon) {
returnType.appendHotspot();
while (tok != Tok_Semicolon && tok != Tok_Eoi) {
@@ -1390,7 +1532,7 @@ bool CppCodeParser::matchNamespaceDecl(InnerNode *parent)
QString namespaceName = previousLexeme();
NamespaceNode *namespasse = 0;
if (parent)
- namespasse = static_cast<NamespaceNode *>(parent->findNode(namespaceName, Node::Namespace));
+ namespasse = static_cast<NamespaceNode*>(parent->findNode(namespaceName, Node::Namespace));
if (!namespasse) {
namespasse = new NamespaceNode(parent, namespaceName);
namespasse->setAccess(access);
@@ -1456,7 +1598,8 @@ bool CppCodeParser::matchEnumItem(InnerNode *parent, EnumNode *enume)
if (strVal.isEmpty()) {
if (enume->items().isEmpty()) {
strVal = "0";
- } else {
+ }
+ else {
QString last = enume->items().last().value();
bool ok;
int n = last.toInt(&ok);
@@ -1466,15 +1609,16 @@ bool CppCodeParser::matchEnumItem(InnerNode *parent, EnumNode *enume)
strVal = last.left(2) + QString::number(n + 1, 16);
else
strVal = "0" + QString::number(n + 1, 8);
- } else {
- strVal = QString::number(n + 1);
}
+ else
+ strVal = QString::number(n + 1);
}
}
}
enume->addItem(EnumItem(name, strVal));
- } else {
+ }
+ else {
VariableNode *var = new VariableNode(parent, name);
var->setAccess(access);
var->setLocation(location());
@@ -1562,7 +1706,8 @@ bool CppCodeParser::matchProperty(InnerNode *parent)
if (match(Tok_Ident)) {
value = previousLexeme();
- } else if (match(Tok_LeftParen)) {
+ }
+ else if (match(Tok_LeftParen)) {
int depth = 1;
while (tok != Tok_Eoi) {
if (tok == Tok_LeftParen) {
@@ -1579,6 +1724,9 @@ bool CppCodeParser::matchProperty(InnerNode *parent)
value = "?";
}
+ /*
+ Task 259071 requires work here. See gui/widgets/qdatetime.h, for example.
+ */
if (key == "READ")
tre->addPropertyFunction(property, value, PropertyNode::Getter);
else if (key == "WRITE")
@@ -1753,12 +1901,6 @@ bool CppCodeParser::matchDocsAndStuff()
readToken();
Doc::trimCStyleComment(start_loc,comment);
- /*
- qdoc --> doxygen
- We must also remember the location of the end
- of the comment, so we can construct a diff for
- it.
- */
Location end_loc(location());
/*
@@ -1821,6 +1963,28 @@ bool CppCodeParser::matchDocsAndStuff()
/*
There is a topic command. Process it.
*/
+#ifdef QDOC_QML
+ if (topic == COMMAND_QMLPROPERTY) {
+ Doc nodeDoc = doc;
+ Node *node = processTopicCommandGroup(nodeDoc,topic,args);
+ if (node != 0) {
+ nodes.append(node);
+ docs.append(nodeDoc);
+ }
+ }
+ else {
+ QStringList::ConstIterator a = args.begin();
+ while (a != args.end()) {
+ Doc nodeDoc = doc;
+ Node *node = processTopicCommand(nodeDoc,topic,*a);
+ if (node != 0) {
+ nodes.append(node);
+ docs.append(nodeDoc);
+ }
+ ++a;
+ }
+ }
+#else
QStringList::ConstIterator a = args.begin();
while (a != args.end()) {
Doc nodeDoc = doc;
@@ -1831,6 +1995,7 @@ bool CppCodeParser::matchDocsAndStuff()
}
++a;
}
+#endif
}
NodeList::Iterator n = nodes.begin();
@@ -1838,7 +2003,8 @@ bool CppCodeParser::matchDocsAndStuff()
while (n != nodes.end()) {
processOtherMetaCommands(*d, *n);
(*n)->setDoc(*d);
- if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) {
+ if ((*n)->isInnerNode() &&
+ ((InnerNode *)*n)->includes().isEmpty()) {
InnerNode *m = static_cast<InnerNode *>(*n);
while (m->parent() != tre->root())
m = m->parent();
@@ -1926,7 +2092,8 @@ void CppCodeParser::parseQiteratorDotH(const Location &location,
mutableSequentialIteratorDefinition = lines[1];
associativeIteratorDefinition = lines[2];
mutableAssociativeIteratorDefinition = lines[3];
- } else {
+ }
+ else {
location.warning(tr("The qiterator.h hack failed"));
}
}
@@ -2008,7 +2175,7 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake)
foreach (const QString &exampleFile, exampleFiles)
(void) new FakeNode(fake,
exampleFile.mid(sizeOfBoringPartOfName),
- FakeNode::File);
+ Node::File);
}
QT_END_NAMESPACE
diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h
index 1f41318..cbb0149 100644
--- a/tools/qdoc3/cppcodeparser.h
+++ b/tools/qdoc3/cppcodeparser.h
@@ -90,6 +90,21 @@ class CppCodeParser : public CodeParser
virtual Node *processTopicCommand(const Doc& doc,
const QString& command,
const QString& arg);
+#ifdef QDOC_QML
+ // might need to implement this in QsCodeParser as well.
+ virtual Node *processTopicCommandGroup(const Doc& doc,
+ const QString& command,
+ const QStringList& args);
+ bool splitQmlPropertyArg(const Doc& doc,
+ const QString& arg,
+ QString& type,
+ QString& element,
+ QString& property);
+ bool splitQmlArg(const Doc& doc,
+ const QString& arg,
+ QString& element,
+ QString& name);
+#endif
virtual QSet<QString> otherMetaCommands();
virtual void processOtherMetaCommand(const Doc& doc,
const QString& command,
diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp
index f7007a0..e2f3525 100644
--- a/tools/qdoc3/doc.cpp
+++ b/tools/qdoc3/doc.cpp
@@ -73,20 +73,20 @@ struct Macro
};
enum {
- CMD_A, CMD_ABSTRACT, CMD_BADCODE, CMD_BASENAME, CMD_BOLD,
- CMD_BRIEF, CMD_C, CMD_CAPTION, CMD_CHAPTER, CMD_CODE,
- CMD_CODELINE, CMD_DOTS, CMD_ELSE, CMD_ENDABSTRACT,
- CMD_ENDCHAPTER, CMD_ENDCODE, CMD_ENDFOOTNOTE, CMD_ENDIF,
- CMD_ENDLEGALESE, CMD_ENDLINK, CMD_ENDLIST, CMD_ENDOMIT,
- CMD_ENDPART, CMD_ENDQUOTATION, CMD_ENDRAW, CMD_ENDSECTION1,
- CMD_ENDSECTION2, CMD_ENDSECTION3, CMD_ENDSECTION4,
- CMD_ENDSIDEBAR, CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE,
- CMD_GENERATELIST, CMD_GRANULARITY, CMD_HEADER, CMD_I,
- CMD_IF, CMD_IMAGE, CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX,
- CMD_KEYWORD, CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST,
- CMD_META, CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT,
- CMD_OMITVALUE, CMD_OVERLOAD,
- CMD_PART, CMD_PRINTLINE, CMD_PRINTTO,
+ CMD_A, CMD_ABSTRACT, CMD_ANNOTATEDLIST, CMD_BADCODE,
+ CMD_BASENAME, CMD_BOLD, CMD_BRIEF, CMD_C, CMD_CAPTION,
+ CMD_CHAPTER, CMD_CODE, CMD_CODELINE, CMD_DOTS, CMD_ELSE,
+ CMD_ENDABSTRACT, CMD_ENDCHAPTER, CMD_ENDCODE,
+ CMD_ENDFOOTNOTE, CMD_ENDIF, CMD_ENDLEGALESE, CMD_ENDLINK,
+ CMD_ENDLIST, CMD_ENDOMIT, CMD_ENDPART, CMD_ENDQUOTATION,
+ CMD_ENDRAW, CMD_ENDSECTION1, CMD_ENDSECTION2,
+ CMD_ENDSECTION3, CMD_ENDSECTION4, CMD_ENDSIDEBAR,
+ CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE, CMD_GENERATELIST,
+ CMD_GRANULARITY, CMD_HEADER, CMD_I, CMD_IF, CMD_IMAGE,
+ CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX, CMD_KEYWORD,
+ CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST, CMD_META,
+ CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT, CMD_OMITVALUE,
+ CMD_OVERLOAD, CMD_PART, CMD_PRINTLINE, CMD_PRINTTO,
CMD_PRINTUNTIL, CMD_QUOTATION, CMD_QUOTEFILE,
CMD_QUOTEFROMFILE, CMD_QUOTEFUNCTION, CMD_RAW, CMD_ROW,
CMD_SA, CMD_SECTION1, CMD_SECTION2, CMD_SECTION3,
@@ -108,6 +108,7 @@ static struct {
} cmds[] = {
{ "a", CMD_A, 0 },
{ "abstract", CMD_ABSTRACT, 0 },
+ { "annotatedlist", CMD_ANNOTATEDLIST, 0 },
{ "badcode", CMD_BADCODE, 0 },
{ "basename", CMD_BASENAME, 0 }, // ### don't document for now
{ "bold", CMD_BOLD, 0 },
@@ -515,14 +516,7 @@ void DocParser::parse(const QString& source,
break;
case CMD_BADCODE:
leavePara();
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass())
- append(Atom::CodeBad,getUnmarkedCode(CMD_BADCODE));
- else
- append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
-#else
append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
-#endif
break;
case CMD_BASENAME:
leavePara();
@@ -538,17 +532,8 @@ void DocParser::parse(const QString& source,
case CMD_C:
enterPara();
x = untabifyEtc(getArgument(true));
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass())
- append(Atom::C, x);
- else {
- marker = CodeMarker::markerForCode(x);
- append(Atom::C, marker->markedUpCode(x, 0, ""));
- }
-#else
marker = CodeMarker::markerForCode(x);
append(Atom::C, marker->markedUpCode(x, 0, ""));
-#endif
break;
case CMD_CAPTION:
leavePara();
@@ -559,14 +544,7 @@ void DocParser::parse(const QString& source,
break;
case CMD_CODE:
leavePara();
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass())
- append(Atom::Code, getUnmarkedCode(CMD_CODE));
- else
- append(Atom::Code, getCode(CMD_CODE, marker));
-#else
append(Atom::Code, getCode(CMD_CODE, marker));
-#endif
break;
#ifdef QDOC_QML
case CMD_QML:
@@ -579,17 +557,6 @@ void DocParser::parse(const QString& source,
#endif
case CMD_CODELINE:
{
-#ifdef QDOC2DOX
- if (!quoting && !DoxWriter::isDoxPass()) {
- if (priv->text.lastAtom()->type() == Atom::Code
- && priv->text.lastAtom()->string().endsWith("\n\n"))
- priv->text.lastAtom()->chopString();
- appendToCode("\n");
- } lse {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, " ");
- }
-#else
if (!quoting) {
if (priv->text.lastAtom()->type() == Atom::Code
&& priv->text.lastAtom()->string().endsWith("\n\n"))
@@ -600,37 +567,10 @@ void DocParser::parse(const QString& source,
append(Atom::CodeQuoteCommand, cmdStr);
append(Atom::CodeQuoteArgument, " ");
}
-#endif
}
break;
case CMD_DOTS:
{
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass()) {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, " ...");
- }
- else if (!quoting) {
- if (priv->text.lastAtom()->type() == Atom::Code
- && priv->text.lastAtom()->string().endsWith("\n\n"))
- priv->text.lastAtom()->chopString();
-
- QString arg = getOptionalArgument();
- int indent = 4;
- if (!arg.isEmpty())
- indent = arg.toInt();
- for (int i = 0; i < indent; ++i)
- appendToCode(" ");
- appendToCode("...\n");
- }
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- QString arg = getOptionalArgument();
- if (arg.isEmpty())
- arg = "4";
- append(Atom::CodeQuoteArgument, arg);
- }
-#else
if (!quoting) {
if (priv->text.lastAtom()->type() == Atom::Code
&& priv->text.lastAtom()->string().endsWith("\n\n"))
@@ -651,7 +591,6 @@ void DocParser::parse(const QString& source,
arg = "4";
append(Atom::CodeQuoteArgument, arg);
}
-#endif
}
break;
case CMD_ELSE:
@@ -785,6 +724,9 @@ void DocParser::parse(const QString& source,
paraState = OutsidePara; // ###
}
break;
+ case CMD_ANNOTATEDLIST:
+ append(Atom::AnnotatedList, getArgument());
+ break;
case CMD_GENERATELIST:
append(Atom::GeneratedList, getArgument());
break;
@@ -953,19 +895,8 @@ void DocParser::parse(const QString& source,
break;
case CMD_OLDCODE:
leavePara();
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass()) {
- append(Atom::CodeOld, getUnmarkedCode(CMD_OLDCODE));
- append(Atom::CodeNew, getUnmarkedCode(CMD_NEWCODE));
- }
- else {
- append(Atom::CodeOld, getCode(CMD_OLDCODE, marker));
- append(Atom::CodeNew, getCode(CMD_NEWCODE, marker));
- }
-#else
append(Atom::CodeOld, getCode(CMD_OLDCODE, marker));
append(Atom::CodeNew, getCode(CMD_NEWCODE, marker));
-#endif
break;
case CMD_OMIT:
getUntilEnd(cmd);
@@ -1147,18 +1078,6 @@ void DocParser::parse(const QString& source,
{
QString snippet = getArgument();
QString identifier = getRestOfLine();
-#ifdef QDOC2DOX
- if (quoting || DoxWriter::isDoxPass()) {
- append(Atom::SnippetCommand, cmdStr);
- append(Atom::SnippetLocation, snippet);
- append(Atom::SnippetIdentifier, identifier);
- }
- else {
- Doc::quoteFromFile(location(),quoter,snippet);
- appendToCode(quoter.quoteSnippet(location(),
- identifier));
- }
-#else
if (quoting) {
append(Atom::SnippetCommand, cmdStr);
append(Atom::SnippetLocation, snippet);
@@ -1169,7 +1088,6 @@ void DocParser::parse(const QString& source,
appendToCode(quoter.quoteSnippet(location(),
identifier));
}
-#endif
}
break;
case CMD_SUB:
@@ -1251,7 +1169,7 @@ void DocParser::parse(const QString& source,
append(Atom::FormattingRight, ATOM_FORMATTING_BOLD);
append(Atom::String, " ");
break;
- case CMD_OVERLOAD: // qdoc --> doxygen
+ case CMD_OVERLOAD:
priv->metacommandsUsed.insert(cmdStr);
x.clear();
if (!isBlankLine())
@@ -1763,10 +1681,13 @@ void DocParser::startSection(Doc::SectioningUnit unit, int cmd)
leavePara();
if (currentSectioningUnit == Doc::Book) {
+#if 0
+ // mws didn't think this was necessary.
if (unit > Doc::Section1)
location().warning(tr("Unexpected '\\%1' without '\\%2'")
.arg(cmdName(cmd))
.arg(cmdName(CMD_SECTION1)));
+#endif
currentSectioningUnit = (Doc::SectioningUnit) (unit - 1);
priv->constructExtra();
priv->extra->sectioningUnit = currentSectioningUnit;
@@ -2343,7 +2264,7 @@ QString DocParser::getCode(int cmd, CodeMarker *marker)
}
/*!
- Used only for generating doxygen output.
+ Was used only for generating doxygen output.
*/
QString DocParser::getUnmarkedCode(int cmd)
{
@@ -2579,36 +2500,6 @@ QString DocParser::slashed(const QString& str)
#define COMMAND_QMLBRIEF Doc::alias("qmlbrief")
#endif
-#ifdef QDOC2DOX
-#define DOXYGEN_INDENT 2
-#define DOXYGEN_TAB_SIZE 4
-#define DOXYGEN_INDENT_STRING " "
-#define DOXYGEN_TAB_STRING " "
-
-static QRegExp ws_rx("\\s");
-static QRegExp not_ws_rx("\\S");
-
-int DoxWriter::doxPass = 0;
-QString DoxWriter::currentClass;
-QSet<QString> DoxWriter::anchors;
-QStringMap DoxWriter::exampleTitles;
-QStringMap DoxWriter::headerFileTitles;
-QStringMap DoxWriter::fileTitles;
-QStringMap DoxWriter::groupTitles;
-QStringMap DoxWriter::moduleTitles;
-QStringMap DoxWriter::pageTitles;
-QStringMap DoxWriter::externalPageTitles;
-QStringMap DoxWriter::exampleTitlesInverse;
-QStringMap DoxWriter::headerFileTitlesInverse;
-QStringMap DoxWriter::fileTitlesInverse;
-QStringMap DoxWriter::groupTitlesInverse;
-QStringMap DoxWriter::moduleTitlesInverse;
-QStringMap DoxWriter::pageTitlesInverse;
-QStringMap DoxWriter::externalPageTitlesInverse;
-QStringMultiMap DoxWriter::variables;
-QStringMultiMap DoxWriter::properties;
-QStringMultiMap DoxWriter::enums;
-#endif
Doc::Doc(const Location& start_loc,
const Location& end_loc,
@@ -2618,15 +2509,6 @@ Doc::Doc(const Location& start_loc,
priv = new DocPrivate(start_loc,end_loc,source);
DocParser parser;
parser.parse(source,priv,metaCommandSet);
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass()) {
- DoxWriter doxWriter(source,priv);
- if (DoxWriter::isDoxPass(1))
- doxWriter.pass1();
- else
- doxWriter.pass2();
- }
-#endif
}
Doc::Doc(const Doc& doc)
@@ -3180,1855 +3062,4 @@ void Doc::detach()
priv = newPriv;
}
-#ifdef QDOC2DOX
-/*!
- Sets the doxygen writer pass to \a pass. You can use
- isDoxPass(), with or without a parameter, to test if
- you are in a doxygen writer run or in a specific pass
- of a doxygen writer run.
-
- This function is only called from main() if either the
- \e doxygen1 or \e doxygen2 flag is passed to qdoc3 on
- the command line.
- */
-void DoxWriter::setDoxPass(int pass)
-{
- qDebug() << "SETTING doxygen pass to " << pass
- << " in DoxWriter::setDoxPass()";
- doxPass = pass;
-}
-
-/*!
- Returns true if the doxygen pass is set to \a pass,
- which means we are in the specified \a pass of a doxygen
- writer run of qdoc3.
- */
-bool DoxWriter::isDoxPass(int pass) { return (doxPass == pass); }
-
-/*!
- Returns true if the doxygen pass is 1 or 2, which
- means this is a doxygen writer run to transform qdoc
- comments into doxygen comments.
- */
-bool DoxWriter::isDoxPass() { return (doxPass > 0); }
-
-bool DoxWriter::conversionRequired() const
-{
- /*
- Loop through all the topic commands searching for
- one that must be transformed to doxygen format. If
- one is found, return true.
- */
- QCommandMap::const_iterator i;
- i = priv->metaCommandMap.constBegin();
- while (i != priv->metaCommandMap.constEnd()) {
- QString s = i.key();
- if (s == "enum")
- return true;
- else if (s == "example")
- return true;
- else if (s == "externalpage")
- return true;
- else if (s == "group")
- return true;
- else if (s == "headerfile")
- return true;
- else if (s == "module")
- return true;
- else if (s == "page")
- return true;
- else if (s == "property")
- return true;
- else if (s == "typedef")
- return true;
- else if (s == "variable")
- return true;
- else if (s == "overload")
- return true;
- else if (s == "reimp")
- return true;
- else if (s == "relates")
- return true;
- else if (s == "macro")
- return true;
- else {
-#if 0
- if (s == "class")
- else if (s == "namespace")
- else if (s == "service")
- else if (s == "inheaderfile")
- else if (s == "file")
- else if (s == "fn")
- else if (s == "contentspage")
- else if (s == "nextpage")
- else if (s == "previous")
- else if (s == "indexpage")
- else if (s == "startpage")
-#endif
- }
- ++i;
- }
-
- /*
- Loop through all the qdoc atoms searching for one
- that must be transformed to doxygen format. If one
- is found, return true.
- */
- const Atom* next = priv->text.firstAtom();
- while (next != 0) {
- Atom::Type atomType = next->type();
- switch (atomType) {
- case Atom::C:
- case Atom::CaptionLeft:
- case Atom::Code:
- case Atom::CodeBad:
- case Atom::CodeNew:
- case Atom::CodeOld:
- case Atom::CodeQuoteArgument:
- case Atom::CodeQuoteCommand:
- case Atom::FootnoteLeft:
- case Atom::FormatElse:
- case Atom::FormatEndif:
- case Atom::FormatIf:
- case Atom::GeneratedList:
- case Atom::Image:
- case Atom::ImageText:
- case Atom::InlineImage:
- case Atom::LegaleseLeft:
- case Atom::LineBreak:
- case Atom::Link:
- case Atom::LinkNode:
- case Atom::ListLeft:
- case Atom::ListItemNumber:
- case Atom::ListTagLeft:
- case Atom::ListItemLeft:
- case Atom::QuotationLeft:
- case Atom::RawString:
- case Atom::SectionLeft:
- case Atom::SectionHeadingLeft:
- case Atom::SidebarLeft:
- case Atom::SnippetCommand:
- case Atom::SnippetIdentifier:
- case Atom::SnippetLocation:
- case Atom::TableLeft:
- case Atom::TableHeaderLeft:
- case Atom::TableRowLeft:
- case Atom::TableItemLeft:
- case Atom::TableOfContents:
- case Atom::Target:
- return true;
- case Atom::AbstractLeft:
- case Atom::AbstractRight:
- case Atom::AutoLink:
- case Atom::BaseName:
- case Atom::BriefLeft:
- case Atom::BriefRight:
- case Atom::CaptionRight:
- case Atom::FormattingLeft:
- case Atom::FormattingRight:
- case Atom::Nop:
- case Atom::ParaLeft:
- case Atom::ParaRight:
- case Atom::FootnoteRight:
- case Atom::LegaleseRight:
- case Atom::ListTagRight:
- case Atom::ListItemRight:
- case Atom::ListRight:
- case Atom::QuotationRight:
- case Atom::SectionRight:
- case Atom::SectionHeadingRight:
- case Atom::SidebarRight:
- case Atom::String:
- case Atom::TableRight:
- case Atom::TableHeaderRight:
- case Atom::TableRowRight:
- case Atom::TableItemRight:
- default:
- break;
- }
- next = next->next();
- }
- return false;
-}
-
-/*!
- A convenience function to write a qdoc metacommand as a
- doxygen command, without conversion. i.e., some of the
- qdoc metacommands don't require conversion for doxygen.
- */
-void DoxWriter::writeCommand(QCommandMap::const_iterator cmd)
-{
- concatenate("\\" + cmd.key() + " " + cmd.value()[0]);
- newLine();
-}
-
-/*!
- Convert the qdoc commands in the metacommand map to
- doxygen format. This function is called only in pass2().
- The metacommand map contains all the metacommands that
- were found in the qdoc comment that is being converted.
- The metacommands are the ones that begin with the '\'.
- These are not considered part of the text of the comment.
- The text is converted by convertText().
- */
-void DoxWriter::convertMetaCommands()
-{
- QCommandMap& metaCmdMap = priv->metaCommandMap;
- QCommandMap::iterator cmd;
- int c;
-
- currentPage.clear();
- currentFn.clear();
- currentTitle.clear();
- currentEnum.clear();
- currentProperty.clear();
- currentVariable.clear();
- currentClass.clear();
- currentExample.clear();
- currentGroup.clear();
- currentModule.clear();
- currentMacro.clear();
- currentService.clear();
- currentTypedef.clear();
- currentHeaderFile.clear();
- commentType = OtherComment;
-
- if ((cmd = metaCmdMap.find("class")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.indexOf(' ')) > 0)
- currentClass = currentClass.left(c);
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = ClassComment;
- }
- else if ((cmd = metaCmdMap.find("fn")) != metaCmdMap.end()) {
- currentFn = cmd.value()[0];
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = FnComment;
- }
- else if ((cmd = metaCmdMap.find("enum")) != metaCmdMap.end()) {
- currentEnum = cmd.value()[0];
- if ((c = currentEnum.lastIndexOf("::")) > 0) {
- currentClass = currentEnum.left(c);
- currentEnum = currentEnum.right(currentEnum.size()-c-2);
- qDebug() << "currentEnum =" << currentEnum;
- qDebug() << "currentClass =" << currentClass;
- }
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = EnumComment;
- }
- else if ((cmd = metaCmdMap.find("property")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentProperty = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentProperty =" << currentProperty;
- qDebug() << "currentClass =" << currentClass;
- }
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = PropertyComment;
- }
- else if ((cmd = metaCmdMap.find("variable")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentVariable = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentVariable =" << currentVariable;
- qDebug() << "currentClass =" << currentClass;
- }
- concatenate("\\var " + cmd.value()[0]);
- newLine();
- metaCmdMap.erase(cmd);
- commentType = VariableComment;
- }
-
- if ((cmd = metaCmdMap.find("page")) != metaCmdMap.end()) {
- currentPage = cmd.value()[0];
- QString htmlFile = currentPage;
- const QString* title = getPageTitle(htmlFile);
- QStringList parts = htmlFile.split('.');
- metaCmdMap.erase(cmd);
- if (title) {
- concatenate("\\page " + parts[0] + " " + *title);
- newLine();
- }
- commentType = PageComment;
- qDebug() << "currentPage =" << currentPage;
- }
-
- if ((cmd = metaCmdMap.find("example")) != metaCmdMap.end()) {
- currentExample = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = ExampleComment;
- qDebug() << "currentExample =" << currentExample;
- }
-
- if ((cmd = metaCmdMap.find("macro")) != metaCmdMap.end()) {
- currentMacro = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = MacroComment;
- qDebug() << "currentMacro =" << currentMacro;
- }
-
- if ((cmd = metaCmdMap.find("group")) != metaCmdMap.end()) {
- currentGroup = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = GroupComment;
- qDebug() << "currentGroup =" << currentGroup;
- }
-
- if ((cmd = metaCmdMap.find("module")) != metaCmdMap.end()) {
- currentModule = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = ModuleComment;
- qDebug() << "currentModule =" << currentModule;
- }
-
- if ((cmd = metaCmdMap.find("headerfile")) != metaCmdMap.end()) {
- currentHeaderFile = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = HeaderFileComment;
- qDebug() << "currentHeaderFile =" << currentHeaderFile;
- }
-
- if ((cmd = metaCmdMap.find("typedef")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentTypedef = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- }
- metaCmdMap.erase(cmd);
- commentType = TypedefComment;
- qDebug() << "currentTypedef =" << currentTypedef;
- qDebug() << "currentClass =" << currentClass;
- }
-
- cmd = priv->metaCommandMap.begin();
- while (cmd != priv->metaCommandMap.end()) {
- for (int i=0; i<cmd.value().size(); i++) {
- concatenate("\\" + cmd.key() + " " + cmd.value()[i]);
- newLine();
- }
- //qDebug() << " " << cmd.key() << ": " << cmd.value();
- ++cmd;
- }
-}
-
-/*!
- Convert the qdoc text to doxygen format. The metacommands
- are converted by convertMetaCommands(). This function is
- called in pass2().
- */
-void DoxWriter::convertText()
-{
- const Atom* prev = 0;
- const Atom* next = priv->text.firstAtom();
- while (next != 0) {
- next->dump();
- Atom::Type atomType = next->type();
- switch (atomType) {
- case Atom::AbstractLeft:
- break;
- case Atom::AbstractRight:
- break;
- case Atom::AutoLink:
- concatenate(next->string());
- break;
- case Atom::BaseName:
- break;
- case Atom::BriefLeft:
- concatenate("\\brief ");
- break;
- case Atom::BriefRight:
- newLine();
- break;
- case Atom::C:
- tt(next);
- break;
- case Atom::CaptionLeft:
- unhandled(next);
- break;
- case Atom::CaptionRight:
- unhandled(next);
- break;
- case Atom::Code:
- code(next);
- break;
- case Atom::CodeBad:
- code(next);
- break;
- case Atom::CodeNew:
- newLine();
- concatenate("you can rewrite it as");
- code(next);
- break;
- case Atom::CodeOld:
- newLine();
- concatenate("For example, if you have code like");
- code(next);
- break;
- case Atom::CodeQuoteArgument:
- unhandled(next);
- break;
- case Atom::CodeQuoteCommand:
- next = codeQuoteCommand(next);
- break;
- case Atom::FootnoteLeft:
- break;
- case Atom::FootnoteRight:
- break;
- case Atom::FormatElse:
- formatElse();
- break;
- case Atom::FormatEndif:
- formatEndif();
- break;
- case Atom::FormatIf:
- formatIf(next);
- break;
- case Atom::FormattingLeft:
- formattingLeft(next,next->next());
- break;
- case Atom::FormattingRight:
- formattingRight(next,prev);
- break;
- case Atom::GeneratedList:
- break;
- case Atom::Image:
- break;
- case Atom::ImageText:
- break;
- case Atom::InlineImage:
- break;
- case Atom::LegaleseLeft:
- break;
- case Atom::LegaleseRight:
- break;
- case Atom::LineBreak:
- break;
- case Atom::Link:
- next = link(next);
- break;
- case Atom::LinkNode:
- break;
- case Atom::ListLeft:
- {
- bool nested = false;
- if (structs.isEmpty()) {
- const Atom* i = next->next();
- while (i->type() != Atom::ListRight) {
- if ((i->type() == Atom::ListLeft) ||
- (i->type() == Atom::TableLeft)) {
- nested = true;
- break;
- }
- i = i->next();
- }
- }
- else
- nested = true;
- StructDesc d(BulletList,nested);
- if (next->string() == "numeric")
- d.structType = NumericList;
- else if (next->string() == "value") {
- d.structType = ValueList;
- }
- else if (next->string() != "bullet")
- qDebug() << "UNKNOWN LIST TYPE" << next->string();
- structs.push(d);
- if (nested || (d.structType != BulletList)) {
- if (d.structType == BulletList)
- concatenate("<ul>");
- else if (d.structType == NumericList)
- concatenate("<ol>");
- else if (d.structType == ValueList)
- concatenate("<dl>");
- newLine();
- }
- }
- break;
- case Atom::ListItemNumber:
- structs.top().count = next->string().toInt();
- break;
- case Atom::ListTagLeft:
- {
- structs.top().count++;
- concatenate("<dt>");
- const Atom* n = next->next();
- if (n->type() == Atom::String) {
- qDebug() << "ENUM VALUE" << n->string();
- }
- else
- qDebug() << "NOT EN ENUM";
- }
- break;
- case Atom::ListTagRight:
- concatenate("</dt>");
- break;
- case Atom::ListItemLeft:
- {
- newLine();
- const StructDesc& d = structs.top();
- if (d.structType == BulletList) {
- if (!d.nested)
- concatenate("\\arg ");
- else
- concatenate("<li>");
- }
- else if (d.structType == NumericList)
- concatenate("<li>");
- else if (d.structType == ValueList)
- concatenate("<dd>");
- }
- break;
- case Atom::ListItemRight:
- {
- const StructDesc& d = structs.top();
- if (d.structType == BulletList) {
- if (d.nested) {
- concatenate("</li>");
- newLine();
- }
- }
- else if (d.structType == NumericList) {
- concatenate("</li>");
- newLine();
- }
- else if (d.structType == ValueList) {
- concatenate("</dd>");
- newLine();
- }
- }
- break;
- case Atom::ListRight:
- {
- if (!structs.isEmpty()) {
- const StructDesc& d = structs.top();
- if (d.nested || (d.structType != BulletList)) {
- if (d.structType == BulletList)
- concatenate("</ul>");
- else if (d.structType == NumericList)
- concatenate("</ol>");
- else if (d.structType == ValueList)
- concatenate("</dl>");
- newLine();
- }
- structs.pop();
- }
- }
- break;
- case Atom::Nop:
- // nothing.
- break;
- case Atom::ParaLeft:
- if (structs.isEmpty())
- newLine();
- break;
- case Atom::ParaRight:
- {
- if (structs.isEmpty())
- newLine();
- else {
- const StructDesc& d = structs.top();
- if (d.nested || (d.structType != BulletList)) {
- Atom::Type t = next->next()->type();
- if ((t != Atom::ListItemRight) &&
- (t != Atom::TableItemRight))
- newLine();
- }
- else
- newLine();
- }
- }
- break;
- case Atom::QuotationLeft:
- break;
- case Atom::QuotationRight:
- break;
- case Atom::RawString:
- concatenate(next->string());
- break;
- case Atom::SectionLeft:
- // nothing.
- break;
- case Atom::SectionRight:
- // nothing.
- break;
- case Atom::SectionHeadingLeft:
- next = sectionHeading(next);
- break;
- case Atom::SectionHeadingRight:
- newLine();
- break;
- case Atom::SidebarLeft:
- break;
- case Atom::SidebarRight:
- break;
- case Atom::SnippetCommand:
- newLine();
- concatenate("\\snippet ");
- break;
- case Atom::SnippetIdentifier:
- newText += next->string();
- lineLength += next->string().size();
- newLine();
- break;
- case Atom::SnippetLocation:
- newText += next->string() + " ";
- lineLength += next->string().size() + 1;
- break;
- case Atom::String:
- wrap(next->string());
- break;
- case Atom::TableLeft:
- {
- bool nested = false;
- if (structs.isEmpty()) {
- const Atom* i = next->next();
- while (i->type() != Atom::TableRight) {
- if ((i->type() == Atom::ListLeft) ||
- (i->type() == Atom::TableLeft)) {
- nested = true;
- break;
- }
- i = i->next();
- }
- }
- else
- nested = true;
- StructDesc d(Table,nested);
- structs.push(d);
- if (next->string().isEmpty())
- concatenate("<table>");
- else {
- QString attrs = "width=\"" + next->string() + "\"";
- attrs += " align=\"center\"";
- concatenate("<table " + attrs + ">");
- }
- newLine();
- }
- break;
- case Atom::TableRight:
- concatenate("</table>");
- if (!structs.isEmpty())
- structs.pop();
- newLine();
- break;
- case Atom::TableHeaderLeft:
- concatenate("<tr>");
- if (!structs.isEmpty())
- structs.top().inTableHeader = true;
- newLine();
- break;
- case Atom::TableHeaderRight:
- concatenate("</tr>");
- if (!structs.isEmpty())
- structs.top().inTableHeader = false;
- newLine();
- break;
- case Atom::TableRowLeft:
- if (!structs.isEmpty()) {
- structs.top().inTableRow = true;
- concatenate("<tr valign=\"top\" class=\"");
- if (structs.top().odd)
- concatenate("odd\">");
- else
- concatenate("even\">");
- structs.top().odd = !structs.top().odd;
- }
- newLine();
- break;
- case Atom::TableRowRight:
- concatenate("</tr>");
- if (!structs.isEmpty())
- structs.top().inTableRow = false;
- newLine();
- break;
- case Atom::TableItemLeft:
- if (!structs.isEmpty()) {
- structs.top().inTableItem = true;
- concatenate("<td>");
- if (structs.top().inTableHeader)
- concatenate("<b> ");
- }
- break;
- case Atom::TableItemRight:
- if (!structs.isEmpty()) {
- structs.top().inTableItem = false;
- if (structs.top().inTableHeader)
- concatenate(" </b>");
- concatenate("</td>");
- }
- newLine();
- break;
- case Atom::TableOfContents:
- break;
- case Atom::Target:
- {
- QString text = next->string();
- text.remove(ws_rx);
- newLine();
- concatenate("\\anchor ");
- newText += text;
- lineLength += text.size();
- newLine();
- }
- break;
- case Atom::UnhandledFormat:
- unhandled(next);
- break;
- case Atom::UnknownCommand:
- unhandled(next);
- break;
- default:
- //next->dump();
- break;
- }
- prev = next;
- next = next->next();
- }
-}
-
-/*!
-
- Pass one looks for topic commands and target and section
- commands, and maybe other stuff. These are serialized to
- text files, which are read back in by pass2().
- */
-void DoxWriter::pass1()
-{
- QCommandMap& metaCmdMap = priv->metaCommandMap;
- if (!metaCmdMap.isEmpty()) {
- int c;
- QCommandMap::iterator cmd;
- if ((cmd = metaCmdMap.find("enum")) != metaCmdMap.end()) {
- commentType = EnumComment;
- currentEnum = cmd.value()[0];
- if ((c = currentEnum.lastIndexOf("::")) > 0) {
- currentClass = currentEnum.left(c);
- currentEnum = currentEnum.right(currentEnum.size()-c-2);
- qDebug() << "currentEnum =" << currentEnum;
- qDebug() << "currentClass =" << currentClass;
- if (enums.contains(currentEnum,currentClass)) {
- qWarning() << "DoxWriter::pass1():"
- << "Duplicate enum:"
- << currentClass << currentEnum;
- }
- else
- enums.insert(currentEnum,currentClass);
- }
- }
- else if ((cmd = metaCmdMap.find("property")) != metaCmdMap.end()) {
- commentType = PropertyComment;
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentProperty = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentProperty =" << currentProperty;
- qDebug() << "currentClass =" << currentClass;
- if (properties.contains(currentProperty,currentClass)) {
- qWarning() << "DoxWriter::pass1():"
- << "Duplicate property:"
- << currentClass << currentProperty;
- }
- else
- properties.insert(currentProperty,currentClass);
- }
- }
- else if ((cmd = metaCmdMap.find("variable")) != metaCmdMap.end()) {
- commentType = VariableComment;
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentVariable = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentVariable =" << currentVariable;
- qDebug() << "currentClass =" << currentClass;
- if (variables.contains(currentVariable,currentClass)) {
- qWarning() << "DoxWriter::pass1():"
- << "Duplicate variable:"
- << currentClass << currentVariable;
- }
- else
- variables.insert(currentVariable,currentClass);
- }
- }
- }
-
- /*
- */
- const Atom* next = priv->text.firstAtom();
- while (next != 0) {
- switch (next->type()) {
- case Atom::SectionHeadingLeft:
- {
- QString text;
- next = next->next();
- while (next) {
- if (next->type() == Atom::SectionHeadingRight)
- break;
- else
- text += next->string();
- next = next->next();
- }
- //text.remove(ws_rx);
- insertAnchor(text);
- }
- break;
- case Atom::Target:
- {
- QString text = next->string();
- //text.remove(ws_rx);
- insertAnchor(text);
- }
- default:
- break;
- }
- next = next->next();
- }
-}
-
-/*!
- Output a parsed, tokenized qdoc comment as a doxygen
- comment in diff format for input to the patch command.
- */
-void DoxWriter::pass2()
-{
- if (!conversionRequired()) {
- qDebug() << "NO CONVERSION - FILE:" << priv->start_loc.fileName()
- << "START:" << priv->start_loc.lineNo()
- << "END:" << priv->end_loc.lineNo() - 1;
- return;
- }
-
- /*
- Transformation to doxygen required...
- */
- newText = "\n/*! \n";
- convertMetaCommands();
- convertText();
- if (newText[newText.size()-1] == ' ')
- newText.remove(newText.size()-1,1);
- newText += " */\n";
- qDebug() << "CONVERTED COMMENT - FILE:" << priv->start_loc.fileName()
- << "START:" << priv->start_loc.lineNo()
- << "END:" << priv->end_loc.lineNo() - 1;
- qDebug() << newText;
-}
-
-/*!
- Unparse the second parameter of a "\l" command.
- */
-const Atom* DoxWriter::link(const Atom* atom)
-{
- QString first_text = atom->string();
- QString second_text;
- const QString* value = 0;
-
- const Atom* next = atom->next(Atom::FormattingLeft,Atom::LINK_);
- if (next) {
- next->dump();
- while (1) {
- next = next->next();
- next->dump();
- if (next->type() == Atom::FormattingRight) {
- if (next->string() == Atom::LINK_)
- break;
- else {
- // ignore it.
- }
- }
- else
- second_text += next->string();
- }
- int i = first_text.indexOf('#');
- if (i >= 0)
- first_text = first_text.right(first_text.size() - i - 1);
- //newLine();
- if ((value = getExternalPage(first_text))) {
- //qDebug() << "USED AN EXTERNAL PAGE TITLE" << first_text;
- QString href = "<a href=\""+*value+"\">"+first_text+"</a>";
- concatenate(href);
- }
- else if (first_text.startsWith("http:",Qt::CaseInsensitive)) {
- if (first_text == second_text) {
- concatenate(first_text);
- }
- else {
- QString href = "<a href=\""+first_text+"\">"+second_text+"</a>";
- concatenate(href);
- }
- }
- else if ((value = getPageFile(first_text))) {
- //qDebug() << "USED A PAGE TITLE" << first_text;
- QStringList parts = (*value).split('.');
- QString ref = "\\ref " + parts[0] + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getGroup(first_text))) {
- //qDebug() << "USED A GROUP TITLE" << first_text;
- concatenate("\\ref " + *value + " \"" + second_text + "\"");
- }
- else if ((value = getModule(first_text))) {
- //qDebug() << "USED A MODULE TITLE" << first_text;
- concatenate("\\ref " + *value + " \"" + second_text + "\"");
- }
- else if ((value = getExamplePath(first_text))) {
- //qDebug() << "USED AN EXAMPLE TITLE" << first_text;
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getFile(first_text))) {
- //qDebug() << "USED A FILE TITLE" << first_text;
- // I think this command is no longer available.
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getHeaderFile(first_text))) {
- //qDebug() << "USED A HEADER FILE TITLE" << first_text;
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if (isAnchor(first_text)) {
- //qDebug() << "USED AN ANCHOR" << first_text;
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getPageTitle(first_text))) {
- //qDebug() << "USED AN INVERSE PAGE TITLE" << first_text;
- QStringList parts = first_text.split('.');
- QString ref = "\\ref " + parts[0] + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getExampleTitle(first_text))) {
- //qDebug() << "USED AN INVERSE EXAMPLE TITLE" << first_text;
- QString title = *value;
- title.remove(ws_rx);
- QString ref = "\\ref " + title + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getGroupTitle(first_text))) {
- //qDebug() << "USED AN INVERSE GROUP TITLE" << first_text;
- concatenate("\\ref " + first_text + " \"" + second_text + "\"");
- }
- else if ((value = getModuleTitle(first_text))) {
- //qDebug() << "USED AN INVERSE MODULE TITLE" << first_text;
- concatenate("\\ref " + first_text + " \"" + second_text + "\"");
- }
- else if ((value = getFileTitle(first_text))) {
- qDebug() << "USED AN INVERSE FILE TITLE" << first_text;
- }
- else if ((value = getHeaderFileTitle(first_text))) {
- qDebug() << "USED AN INVERSE HEADER FILE TITLE" << first_text;
- }
- else if ((first_text.indexOf("::") >= 0) ||
- (first_text.indexOf("()") >= 0) ||
- (first_text[0] == 'Q')) {
- //qDebug() << "AUTO-LINKABLE" << first_text;
- if (first_text == second_text)
- concatenate(first_text);
- else {
- QString link = first_text + " " + second_text;
- concatenate("\\link " + link + "\\endlink");
- }
- }
- else {
- QString link;
- QStringList propertyClasses;
- QStringList variableClasses;
- QStringList enumClasses;
- bool p = isProperty(first_text,propertyClasses);
- bool v = isVariable(first_text,variableClasses);
- bool e = isEnum(first_text,enumClasses);
- if (e) {
- if (enumClasses.size() == 1)
- link = enumClasses[0];
- else if (enumClasses.contains(currentClass))
- link = currentClass;
- else {
- QString msg = "Unqualified enum name: " + first_text;
- QString details = "Classes: " + enumClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- if (!link.isEmpty())
- qDebug() << "FOUND ENUM" << link << first_text;
- }
- else if (p && v) {
- if (propertyClasses.size() == 1) {
- if (variableClasses.size() == 1) {
- if (propertyClasses[0] == variableClasses[0])
- link = propertyClasses[0];
- }
- }
- if (link.isEmpty()) {
- if (propertyClasses.contains(currentClass) ||
- variableClasses.contains(currentClass))
- link = currentClass;
- else {
- propertyClasses += variableClasses;
- QString msg = "Unqualified property or variable name: "
- + first_text;
- QString details = "Classes: " +
- propertyClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- }
- }
- else if (p) {
- if (propertyClasses.size() == 1)
- link = propertyClasses[0];
- else if (propertyClasses.contains(currentClass))
- link = currentClass;
- else {
- QString msg = "Unqualified property name: " + first_text;
- QString details = "Classes: " + propertyClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- }
- else if (v) {
- if (variableClasses.size() == 1)
- link = variableClasses[0];
- else if (variableClasses.contains(currentClass))
- link = currentClass;
- else {
- QString msg = "Unqualified variable name: " + first_text;
- QString details = "Classes: " + variableClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- }
- else {
- qDebug() << "NOT AUTO-LINKABLE" << first_text;
- QString s = first_text + " " + second_text;
- concatenate("\\link " + s + "\\endlink");
- }
- if (!link.isEmpty()) {
- link += "::" + first_text + " " + second_text;
- concatenate("\\link " + link + "\\endlink");
- }
- }
- }
- else
- qDebug() << "LINK with no second parameter!!!!";
- return next? next : atom;
-}
-
-/*!
- If the current line length is 0, the current line is
- indented according to the context.
- */
-void DoxWriter::indentLine()
-{
- if (lineLength == 0) {
- newText += DOXYGEN_INDENT_STRING;
- lineLength = DOXYGEN_INDENT;
- if (!structs.isEmpty()) {
- for (int i=1; i<structs.size(); ++i) {
- newText += DOXYGEN_TAB_STRING;
- lineLength += DOXYGEN_TAB_SIZE;
- }
- }
- }
-}
-
-/*!
- Concatenates a newline to the doxygen text, increments the
- line count, and resets the line length to 0.
- */
-void DoxWriter::newLine()
-{
- newText += "\n";
- ++lineCount;
- lineLength = 0;
-}
-
-static const int maxLineLength = 70;
-
-/*!
- Concatenate the \a text to the doxygen comment currently
- under construction and increment the current line length
- by the size of the \a text.
-
- If incrementing the current line length by the \a text size
- would make the current line length longer than the maximum
- line length, then call newLine() and indentLine() \e before
- concatenating the \a text.
- */
-void DoxWriter::concatenate(QString text)
-{
- if ((lineLength + text.size()) > maxLineLength)
- newLine();
- indentLine();
- newText += text;
- lineLength += text.size();
-}
-
-static bool punctuation(QChar c)
-{
- switch (c.toAscii()) {
- case '.':
- case ',':
- case ':':
- case ';':
- case '/':
- case '+':
- case '-':
- case '?':
- case '!':
- case '\"':
- return true;
- default:
- break;
- }
- return false;
-}
-
-/*!
- Concatenate the \a text string to the doxygen text, doing
- line wrapping where necessary.
- */
-void DoxWriter::wrap(QString text)
-{
- int from = 0;
- int to = -1;
-
- if ((lineLength == 0) || (lineLength >= maxLineLength)) {
- if (!text.isEmpty() && (text[0] == ' '))
- text = text.right(text.size() - 1);
- }
-
- indentLine();
- while (text.size()) {
- int avail = maxLineLength - lineLength;
- from = text.indexOf(' ',from);
- if (from >= 0) {
- if (from < avail)
- to = from++;
- else if (from == 1 && punctuation(text[0]))
- to = from++;
- else {
- if (to >= 0) {
- newText += text.left(to+1);
- lineLength += to + 1;
- text = text.right(text.size() - to - 1);
- }
- else {
- newLine();
- indentLine();
- newText += text.left(from+1);
- lineLength += from + 1;
- text = text.right(text.size() - from - 1);
- }
- from = 0;
- to = -1;
- if (text.size() && (lineLength > maxLineLength)) {
- newLine();
- indentLine();
- }
- }
- }
- else
- break;
- }
- if (text.size()) {
- if (lineLength >= maxLineLength) {
- newLine();
- indentLine();
- }
- newText += text;
- lineLength += text.size();
- }
-}
-
-/*!
- This will output something, but it depends on what the
- \a atom string and the \a next atom string are.
- */
-void DoxWriter::formattingLeft(const Atom* atom, const Atom* next)
-{
- if (atom->string() == "parameter") {
- concatenate("\\a ");
- return;
- }
- else if (atom->string() == "underline") {
- concatenate("<u>");
- return;
- }
- else if (atom->string() == "superscript") {
- concatenate("<sup>");
- return;
- }
- else if (atom->string() == "subscript") {
- concatenate("<sub>");
- return;
- }
- int ws = -1;
- if (next)
- ws = next->string().indexOf(ws_rx);
- if (atom->string() == "bold") {
- if (ws < 0)
- concatenate("\\b ");
- else
- concatenate("<b>");
- }
- else if (atom->string() == "italic") {
- if (ws < 0)
- concatenate("\\e ");
- else
- concatenate("<i>");
- }
- else if (atom->string() == "teletype") {
- if (ws < 0)
- concatenate("\\c ");
- else
- concatenate("<tt>");
- }
- else
- qDebug() << "UNHANDLED FormattingLeft: " << atom->string();
-}
-
-/*!
- This will output something, but it depends on what the
- \a atom string and the \a prev atom string are.
- */
-void DoxWriter::formattingRight(const Atom* atom, const Atom* prev)
-{
- if (atom->string() == "parameter")
- return;
- else if (atom->string() == "underline") {
- concatenate("</u>");
- return;
- }
- else if (atom->string() == "superscript") {
- concatenate("</sup>");
- return;
- }
- else if (atom->string() == "subscript") {
- concatenate("</sub>");
- return;
- }
- int ws = -1;
- if (prev)
- ws = prev->string().indexOf(ws_rx);
- if (ws < 0)
- return;
- if (atom->string() == "bold")
- concatenate("</b>");
- else if (atom->string() == "italic")
- concatenate("</i>");
- else if (atom->string() == "teletype")
- concatenate("</tt>");
- else
- qDebug() << "UNHANDLED FormattingRight: " << atom->string();
-}
-
-/*!
- Output a \c or a <tt>...</tt>.
- */
-void DoxWriter::tt(const Atom* atom)
-{
- if (atom->string().indexOf(ws_rx) < 0) {
- concatenate("\\c ");
- concatenate(atom->string());
- }
- else {
- concatenate("<tt>");
- concatenate(atom->string());
- concatenate("</tt>");
- }
-}
-
-/*!
- */
-void DoxWriter::formatIf(const Atom* atom)
-{
- if (atom->string() == "HTML") {
- newLine();
- concatenate("\\htmlonly");
- newLine();
- }
-}
-
-/*!
- */
-void DoxWriter::formatEndif()
-{
- newLine();
- concatenate("\\endhtmlonly");
- newLine();
-}
-
-/*!
- */
-void DoxWriter::formatElse()
-{
- // nothing.
-}
-
-/*!
- Pass 1: Construct a section identifier and insert it into
- the anchor set.
-
- Pass 2: Convert section1, section2, and section3 commands
- to section, subsection, and subsubsection respectively.
- Warn if a section command higher than 3 is seen.
- */
-const Atom* DoxWriter::sectionHeading(const Atom* atom)
-{
- QString heading_level = atom->string();
- QString heading_text;
- const Atom* next = atom->next();
- while (next) {
- next->dump();
- if (next->type() == Atom::SectionHeadingRight) {
- if (next->string() == heading_level)
- break;
- else {
- qDebug() << "WRONG SectionHeading number!!!!";
- }
- }
- else
- heading_text += next->string();
- next = next->next();
- }
-
- QString heading_identifier = heading_text;
- heading_identifier.remove(ws_rx);
-
- newLine();
- if (heading_level == "1")
- heading_level = "\\section ";
- else if (heading_level == "2")
- heading_level = "\\subsection ";
- else if (heading_level == "3")
- heading_level = "\\subsubsection ";
- else if (heading_level == "4") {
- heading_level = "\\subsubsection ";
- qDebug() << "WARNING section4 converted to \\subsubsection";
- }
- else {
- heading_level = "\\subsubsection ";
- qDebug() << "WARNING section5 converted to \\subsubsection";
- }
- concatenate(heading_level);
- newText += heading_identifier + " ";
- lineLength += heading_identifier.size() + 1;
- newText += heading_text;
- lineLength += heading_text.size();
- newLine();
- return next? next : atom;
-}
-
-/*!
- Report an unhandled atom.
- */
-void DoxWriter::unhandled(const Atom* atom)
-{
- qDebug() << "UNHANDLED ATOM";
- atom->dump();
-}
-
-/*!
- Output a code/endcode block.
- */
-void DoxWriter::code(const Atom* atom)
-{
- newLine();
- concatenate("\\code");
- writeCode(atom->string());
- concatenate("\\endcode");
- newLine();
-}
-
-/*!
- Output a code/endcode block depending on the
- CodeQuote Command and CodeQuoteArgument parameters.
- */
-const Atom* DoxWriter::codeQuoteCommand(const Atom* atom)
-{
- QString command = atom->string();
- atom = atom->next();
- concatenate("\\code");
- if (command == "codeline") {
- newLine();
- concatenate(atom->string());
- newLine();
- }
- else if (command == "dots") {
- newLine();
- concatenate(atom->string());
- newLine();
- }
- else {
- writeCode(atom->string());
- }
- concatenate("\\endcode");
- return atom;
-}
-
-/*!
- Appends a block of code to the comment.
- */
-void DoxWriter::writeCode(QString text)
-{
- int cr_count = text.count('\n') - 1;
- if (cr_count >= 0) {
- int last_cr = text.lastIndexOf('\n');
- newText += text.left(last_cr);
- lineCount += cr_count;
- }
- else
- newText += text;
- newLine();
-}
-
-/*!
- Inserts \a text into the anchor set. This function is called
- during doxygen pass 1.
- */
-void DoxWriter::insertAnchor(const QString& text)
-{
- anchors.insert(text);
-}
-
-/*!
- Returns true if \a text identifies an anchor, section,
- subsection, subsubsection, or page.
- */
-bool DoxWriter::isAnchor(const QString& text)
-{
- return anchors.contains(text);
-}
-
-/*!
- Write the set of anchors to a file, one per line.
- */
-void DoxWriter::writeAnchors()
-{
- QFile file("anchors.txt");
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qWarning("Unable to open anchors.txt for writing.");
- return;
- }
-
- QTextStream out(&file);
- QSet<QString>::const_iterator i = anchors.constBegin();
- while (i != anchors.constEnd()) {
- out << *i << "\n";
- ++i;
- }
- file.close();
-}
-
-/*!
- Read the set of anchors from the anchors file, one per line,
- and insert each one into the anchor set.
- */
-void DoxWriter::readAnchors()
-{
- QFile file("anchors.txt");
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning("Unable to open anchors.txt for reading.");
- return;
- }
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
- anchors.insert(line);
- }
- file.close();
-#if 0
- QSet<QString>::const_iterator i = anchors.constBegin();
- while (i != anchors.constEnd()) {
- qDebug() << *i;
- ++i;
- }
-#endif
-}
-
-/*!
- Inserts \a title into one of the title maps. \a title is
- mapped to the \a node name. This function is called during
- doxygen pass 1.
- */
-void DoxWriter::insertTitle(FakeNode* node, const QString& title)
-{
- switch (node->subType()) {
- case FakeNode::Example:
- if (exampleTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate example title:"
- << title;
- }
- else {
- exampleTitles[title] = node->name();
- exampleTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::HeaderFile:
- if (headerFileTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate header file title:"
- << title;
- }
- else {
- headerFileTitles[title] = node->name();
- headerFileTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::File:
- if (fileTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate file title:"
- << title;
- }
- else {
- fileTitles[title] = node->name();
- fileTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::Group:
- if (groupTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate group title:"
- << title;
- }
- else {
- groupTitles[title] = node->name();
- groupTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::Module:
- if (moduleTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate module title:"
- << title;
- }
- else {
- moduleTitles[title] = node->name();
- moduleTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::Page:
- if (pageTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate page title:"
- << title;
- }
- else {
- pageTitles[title] = node->name();
- pageTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::ExternalPage:
- if (externalPageTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate external page title:"
- << title;
- }
- else {
- externalPageTitles[title] = node->name();
- externalPageTitlesInverse[node->name()] = title;
- }
- break;
- default:
- break;
- }
-}
-
-/*!
- */
-const QString* DoxWriter::getPageFile(const QString& title)
-{
- QStringMapEntry entry = pageTitles.find(title);
- return (entry == pageTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExamplePath(const QString& title)
-{
- QStringMapEntry entry = exampleTitles.find(title);
- return (entry == exampleTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getFile(const QString& title)
-{
- QStringMapEntry entry = fileTitles.find(title);
- return (entry == fileTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getHeaderFile(const QString& title)
-{
- QStringMapEntry entry = headerFileTitles.find(title);
- return (entry == headerFileTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getGroup(const QString& title)
-{
- QStringMapEntry entry = groupTitles.find(title);
- return (entry == groupTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getModule(const QString& title)
-{
- QStringMapEntry entry = moduleTitles.find(title);
- return (entry == moduleTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExternalPage(const QString& title)
-{
- QStringMapEntry entry = externalPageTitles.find(title);
- return (entry == externalPageTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getPageTitle(const QString& text)
-{
- QStringMapEntry entry = pageTitlesInverse.find(text);
- return (entry == pageTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExampleTitle(const QString& text)
-{
- QStringMapEntry entry = exampleTitlesInverse.find(text);
- return (entry == exampleTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getFileTitle(const QString& text)
-{
- QStringMapEntry entry = fileTitlesInverse.find(text);
- return (entry == fileTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getHeaderFileTitle(const QString& text)
-{
- QStringMapEntry entry = headerFileTitlesInverse.find(text);
- return (entry == headerFileTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getGroupTitle(const QString& text)
-{
- QStringMapEntry entry = groupTitlesInverse.find(text);
- return (entry == groupTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getModuleTitle(const QString& text)
-{
- QStringMapEntry entry = moduleTitlesInverse.find(text);
- return (entry == moduleTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExternalPageTitle(const QString& text)
-{
- QStringMapEntry entry = externalPageTitlesInverse.find(text);
- return (entry == externalPageTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- Serialize \a map to file \a name.
- */
-void DoxWriter::writeMap(const QStringMap& map, const QString& name)
-{
-
- QFile file(name);
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for writing.";
- return;
- }
-
- QTextStream out(&file);
- QStringMap::const_iterator i = map.constBegin();
- while (i != map.constEnd()) {
- out << i.key() << "\n";
- out << i.value() << "\n";
- ++i;
- }
- file.close();
-}
-
-/*!
- Read file \a name into the \a map.
- */
-void DoxWriter::readMap(QStringMap& map, QStringMap& inverseMap, const QString& name)
-{
- QFile file(name);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for reading.";
- return;
- }
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString title = in.readLine();
- QString value = in.readLine();
- map[title] = value;
- inverseMap[value] = title;
- }
- file.close();
-}
-
-/*!
- Write the sets of titles to text files, one per line.
- */
-void DoxWriter::writeTitles()
-{
- if (!pageTitles.isEmpty())
- writeMap(pageTitles,"pagetitles.txt");
- if (!fileTitles.isEmpty())
- writeMap(fileTitles,"filetitles.txt");
- if (!headerFileTitles.isEmpty())
- writeMap(headerFileTitles,"headerfiletitles.txt");
- if (!exampleTitles.isEmpty())
- writeMap(exampleTitles,"exampletitles.txt");
- if (!moduleTitles.isEmpty())
- writeMap(moduleTitles,"moduletitles.txt");
- if (!groupTitles.isEmpty())
- writeMap(groupTitles,"grouptitles.txt");
- if (!externalPageTitles.isEmpty())
- writeMap(externalPageTitles,"externalpagetitles.txt");
-}
-
-/*!
- Read the sets of titles from the titles files, one per line,
- and insert each one into the appropriate title set.
- */
-void DoxWriter::readTitles()
-{
- readMap(pageTitles,pageTitlesInverse,"pagetitles.txt");
- readMap(fileTitles,fileTitlesInverse,"filetitles.txt");
- readMap(headerFileTitles,headerFileTitlesInverse,"headerfiletitles.txt");
- readMap(exampleTitles,exampleTitlesInverse,"exampletitles.txt");
- readMap(moduleTitles,moduleTitlesInverse,"moduletitles.txt");
- readMap(groupTitles,groupTitlesInverse,"grouptitles.txt");
- readMap(externalPageTitles,
- externalPageTitlesInverse,
- "externalpagetitles.txt");
-}
-
-/*!
- Serialize \a map to file \a name.
- */
-void DoxWriter::writeMultiMap(const QStringMultiMap& map, const QString& name)
-{
-
- QFile file(name);
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for writing.";
- return;
- }
-
- QTextStream out(&file);
- QStringMultiMap::const_iterator i = map.constBegin();
- while (i != map.constEnd()) {
- out << i.key() << "\n";
- out << i.value() << "\n";
- ++i;
- }
- file.close();
-}
-
-/*!
- Write the4 property names and variable names to text files.
- */
-void DoxWriter::writeMembers()
-{
- if (!variables.isEmpty())
- writeMultiMap(variables,"variables.txt");
- if (!properties.isEmpty())
- writeMultiMap(properties,"properties.txt");
- if (!enums.isEmpty())
- writeMultiMap(enums,"enums.txt");
-}
-
-/*!
- Read file \a name into the \a map.
- */
-void DoxWriter::readMultiMap(QStringMultiMap& map, const QString& name)
-{
- QFile file(name);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for reading.";
- return;
- }
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString member = in.readLine();
- QString className = in.readLine();
- map.insert(member,className);
- }
- file.close();
-}
-
-/*!
- Read the property names and variable names from the test files.
- */
-void DoxWriter::readMembers()
-{
- readMultiMap(variables,"variables.txt");
- readMultiMap(properties,"properties.txt");
- readMultiMap(enums,"enums.txt");
-}
-
-/*!
- Return true if \a name is a property. Loads \a classes with
- the names of all the classes in which \a name is a property.
- */
-bool DoxWriter::isProperty(const QString& name, QStringList& classes)
-{
- classes = properties.values(name);
- return !classes.isEmpty();
-}
-
-/*!
- Return true if \a name is a variable. Loads \a classes with
- the names of all the classes in which \a name is a variable.
- */
-bool DoxWriter::isVariable(const QString& name, QStringList& classes)
-{
- classes = variables.values(name);
- return !classes.isEmpty();
-}
-
-/*!
- Return true if \a name is an enum type. Loads \a classes with
- the names of all the classes in which \a name is an enum type.
- */
-bool DoxWriter::isEnum(const QString& name, QStringList& classes)
-{
- classes = enums.values(name);
- return !classes.isEmpty();
-}
-#endif
-
QT_END_NAMESPACE
diff --git a/tools/qdoc3/doc.h b/tools/qdoc3/doc.h
index dbba6e4..d58167f 100644
--- a/tools/qdoc3/doc.h
+++ b/tools/qdoc3/doc.h
@@ -133,183 +133,6 @@ class Doc
DocPrivate *priv;
};
-#ifdef QDOC2DOX
-
-class DoxWriter
-{
- public:
- DoxWriter(const QString& source, DocPrivate* docPrivate)
- : commentType(OtherComment),
- lineLength(0),
- lineCount(0),
- priv(docPrivate),
- oldText(source) {}
- ~DoxWriter() {}
-
- void pass1();
- void pass2();
-
- static void setDoxPass(int pass);
- static bool isDoxPass(int pass);
- static bool isDoxPass();
- static void insertTitle(FakeNode* node, const QString& title);
- static void writeTitles();
- static void readTitles();
- static void writeMembers();
- static void readMembers();
- static void writeAnchors();
- static void readAnchors();
-
- private:
- void indentLine();
- void newLine();
- void concatenate(QString text);
- void wrap(QString text);
- bool conversionRequired() const;
- void convertMetaCommands();
- void convertText();
- const Atom* link(const Atom* atom);
- void formattingLeft(const Atom* atom, const Atom* next);
- void formattingRight(const Atom* atom, const Atom* prev);
- void tt(const Atom* atom);
- void formatIf(const Atom* atom);
- void formatEndif();
- void formatElse();
- const Atom* sectionHeading(const Atom* atom);
- void unhandled(const Atom* atom);
- void code(const Atom* atom);
- const Atom* codeQuoteCommand(const Atom* atom);
- void writeCode(QString text);
- void writeCommand(QCommandMap::const_iterator cmd);
-
- static void insertAnchor(const QString& text);
- static bool isAnchor(const QString& text);
-
- static const QString* getPageFile(const QString& title);
- static const QString* getFile(const QString& title);
- static const QString* getExamplePath(const QString& title);
- static const QString* getHeaderFile(const QString& title);
- static const QString* getGroup(const QString& title);
- static const QString* getModule(const QString& title);
- static const QString* getExternalPage(const QString& title);
- static const QString* getPageTitle(const QString& text);
- static const QString* getFileTitle(const QString& text);
- static const QString* getExampleTitle(const QString& text);
- static const QString* getHeaderFileTitle(const QString& text);
- static const QString* getGroupTitle(const QString& text);
- static const QString* getModuleTitle(const QString& text);
- static const QString* getExternalPageTitle(const QString& text);
-
- static bool isProperty(const QString& title, QStringList& classes);
- static bool isVariable(const QString& title, QStringList& classes);
- static bool isEnum(const QString& title, QStringList& classes);
-
- private:
- static void writeMap(const QStringMap& map, const QString& name);
- static void readMap(QStringMap& map,
- QStringMap& inverseMap,
- const QString& name);
- static void writeMultiMap(const QStringMultiMap& map, const QString& name);
- static void readMultiMap(QStringMultiMap& map, const QString& name);
-
- public: // VS 6, SunCC need this to be public
- enum StructType { BulletList, NumericList, ValueList, Table };
- private:
- struct StructDesc {
- StructType structType;
- int count;
- bool nested;
- bool inTableHeader;
- bool inTableRow;
- bool inTableItem;
- bool odd;
-
- StructDesc()
- : structType(BulletList),
- count(0),
- nested(false),
- inTableHeader(false),
- inTableRow(false),
- inTableItem(false),
- odd(true) { }
-
- StructDesc(StructType t, bool n)
- : structType(t),
- count(0),
- nested(n),
- inTableHeader(false),
- inTableRow(false),
- inTableItem(false),
- odd(true) { }
- };
-
- typedef QStack<StructDesc> StructStack;
-
- enum CommentType {
- ClassComment,
- EnumComment,
- ExampleComment,
- FnComment,
- GroupComment,
- HeaderFileComment,
- MacroComment,
- ModuleComment,
- PageComment,
- PropertyComment,
- ServiceComment,
- TypedefComment,
- VariableComment,
- OtherComment
- };
-
- private:
- CommentType commentType;
- int lineLength;
- int lineCount;
- DocPrivate* priv;
- QString oldText;
- QString newText;
- StructStack structs;
-
- QString currentPage;
- QString currentFn;
- QString currentTitle;
- QString currentEnum;
- QString currentProperty;
- QString currentVariable;
- QString currentExample;
- QString currentGroup;
- QString currentModule;
- QString currentMacro;
- QString currentService;
- QString currentTypedef;
- QString currentHeaderFile;
- static QString currentClass;
-
- static int doxPass;
- static QSet<QString> anchors;
- static QStringMap exampleTitles;
- static QStringMap headerFileTitles;
- static QStringMap fileTitles;
- static QStringMap groupTitles;
- static QStringMap moduleTitles;
- static QStringMap pageTitles;
- static QStringMap externalPageTitles;
- static QStringMap exampleTitlesInverse;
- static QStringMap headerFileTitlesInverse;
- static QStringMap fileTitlesInverse;
- static QStringMap groupTitlesInverse;
- static QStringMap moduleTitlesInverse;
- static QStringMap pageTitlesInverse;
- static QStringMap externalPageTitlesInverse;
-
- static QStringMultiMap variables;
- static QStringMultiMap properties;
- static QStringMultiMap enums;
-};
-
-#endif
-
QT_END_NAMESPACE
#endif
diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp
index 3652071..e92f53b 100644
--- a/tools/qdoc3/generator.cpp
+++ b/tools/qdoc3/generator.cpp
@@ -42,9 +42,9 @@
/*
generator.cpp
*/
-
+#include <QtCore>
#include <qdir.h>
-
+#include <qdebug.h>
#include "codemarker.h"
#include "config.h"
#include "doc.h"
@@ -68,14 +68,20 @@ QStringList Generator::imageDirs;
QString Generator::outDir;
QString Generator::project;
-static Text stockLink(const QString &target)
+static void singularPlural(Text& text, const NodeList& nodes)
{
- return Text() << Atom(Atom::Link, target) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << target << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ if (nodes.count() == 1)
+ text << " is";
+ else
+ text << " are";
}
Generator::Generator()
- : amp("&amp;"), lt("&lt;"), gt("&gt;"), quot("&quot;"), tag("</?@[^>]*>")
+ : amp("&amp;"),
+ lt("&lt;"),
+ gt("&gt;"),
+ quot("&quot;"),
+ tag("</?@[^>]*>")
{
generators.prepend(this);
}
@@ -123,7 +129,8 @@ void Generator::initialize(const Config &config)
QSet<QString> formats = config.subVars(imagesDotFileExtensions);
QSet<QString>::ConstIterator f = formats.begin();
while (f != formats.end()) {
- imgFileExts[*f] = config.getStringList(imagesDotFileExtensions + Config::dot + *f);
+ imgFileExts[*f] = config.getStringList(imagesDotFileExtensions +
+ Config::dot + *f);
++f;
}
@@ -131,16 +138,22 @@ void Generator::initialize(const Config &config)
while (g != generators.end()) {
if (outputFormats.contains((*g)->format())) {
(*g)->initializeGenerator(config);
- QStringList extraImages = config.getStringList(CONFIG_EXTRAIMAGES + Config::dot
- + (*g)->format());
+ QStringList extraImages = config.getStringList(CONFIG_EXTRAIMAGES +
+ Config::dot +
+ (*g)->format());
QStringList::ConstIterator e = extraImages.begin();
while (e != extraImages.end()) {
QString userFriendlyFilePath;
- QString filePath = Config::findFile(config.lastLocation(), imageFiles, imageDirs, *e,
- imgFileExts[(*g)->format()], userFriendlyFilePath);
+ QString filePath = Config::findFile(config.lastLocation(),
+ imageFiles, imageDirs, *e,
+ imgFileExts[(*g)->format()],
+ userFriendlyFilePath);
if (!filePath.isEmpty())
- Config::copyFile(config.lastLocation(), filePath, userFriendlyFilePath,
- (*g)->outputDir() + "/images");
+ Config::copyFile(config.lastLocation(),
+ filePath,
+ userFriendlyFilePath,
+ (*g)->outputDir() +
+ "/images");
++e;
}
}
@@ -156,20 +169,23 @@ void Generator::initialize(const Config &config)
QSet<QString> formats = config.subVars(formattingDotName);
QSet<QString>::ConstIterator f = formats.begin();
while (f != formats.end()) {
- QString def = config.getString(formattingDotName + Config::dot +
- *f);
+ QString def = config.getString(formattingDotName +
+ Config::dot + *f);
if (!def.isEmpty()) {
int numParams = Config::numParams(def);
int numOccs = def.count("\1");
if (numParams != 1) {
- config.lastLocation().warning(tr("Formatting '%1' must have exactly one"
- " parameter (found %2)")
- .arg(*n).arg(numParams));
+ config.lastLocation().warning(tr("Formatting '%1' must "
+ "have exactly one "
+ "parameter (found %2)")
+ .arg(*n).arg(numParams));
}
else if (numOccs > 1) {
- config.lastLocation().fatal(tr("Formatting '%1' must contain exactly one"
- " occurrence of '\\1' (found %2)")
+ config.lastLocation().fatal(tr("Formatting '%1' must "
+ "contain exactly one "
+ "occurrence of '\\1' "
+ "(found %2)")
.arg(*n).arg(numOccs));
}
else {
@@ -241,7 +257,7 @@ void Generator::generateFakeNode(const FakeNode * /* fake */,
{
}
-void Generator::generateText(const Text& text,
+bool Generator::generateText(const Text& text,
const Node *relative,
CodeMarker *marker)
{
@@ -254,31 +270,40 @@ void Generator::generateText(const Text& text,
true,
numAtoms);
endText(relative, marker);
+ return true;
}
+ return false;
}
#ifdef QDOC_QML
-void Generator::generateQmlText(const Text& text,
+/*!
+ Extract sections of markup text surrounded by \e qmltext
+ and \e endqmltext and output them.
+ */
+bool Generator::generateQmlText(const Text& text,
const Node *relative,
- CodeMarker *marker)
+ CodeMarker *marker,
+ const QString& qmlName)
{
- if (text.firstAtom() != 0) {
- startText(relative, marker);
- const Atom *atom = text.firstAtom();
- while (atom) {
- if (atom->type() != Atom::QmlText)
- atom = atom->next();
- else {
- atom = atom->next();
- while (atom && (atom->type() != Atom::EndQmlText)) {
- int n = 1 + generateAtom(atom, relative, marker);
- while (n-- > 0)
- atom = atom->next();
- }
+ const Atom* atom = text.firstAtom();
+ if (atom == 0)
+ return false;
+
+ startText(relative, marker);
+ while (atom) {
+ if (atom->type() != Atom::QmlText)
+ atom = atom->next();
+ else {
+ atom = atom->next();
+ while (atom && (atom->type() != Atom::EndQmlText)) {
+ int n = 1 + generateAtom(atom, relative, marker);
+ while (n-- > 0)
+ atom = atom->next();
}
}
- endText(relative, marker);
}
+ endText(relative, marker);
+ return true;
}
#endif
@@ -295,19 +320,27 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
else if (node->type() == Node::Fake) {
const FakeNode *fake = static_cast<const FakeNode *>(node);
- if (fake->subType() == FakeNode::Example)
+ if (fake->subType() == Node::Example)
generateExampleFiles(fake, marker);
- else if (fake->subType() == FakeNode::File)
+ else if (fake->subType() == Node::File)
quiet = true;
}
if (node->doc().isEmpty()) {
- if (!quiet) // ### might be unnecessary
+ if (!quiet && !node->isReimp()) // ### might be unnecessary
node->location().warning(tr("No documentation for '%1'")
.arg(marker->plainFullName(node)));
}
else {
- generateText(node->doc().body(), node, marker);
+ if (node->type() == Node::Function) {
+ const FunctionNode *func = static_cast<const FunctionNode *>(node);
+ if (func->reimplementedFrom() != 0)
+ generateReimplementedFrom(func, marker);
+ }
+
+ if (!generateText(node->doc().body(), node, marker))
+ if (node->isReimp())
+ return;
if (node->type() == Node::Enum) {
const EnumNode *enume = (const EnumNode *) node;
@@ -345,7 +378,6 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
else if (node->type() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(node);
-
QSet<QString> definedParams;
QList<Parameter>::ConstIterator p = func->parameters().begin();
while (p != func->parameters().end()) {
@@ -382,7 +414,8 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
FunctionNode *primaryFunc =
func->parent()->findFunctionNode(func->name());
if (primaryFunc) {
- foreach (const Parameter &param, primaryFunc->parameters()) {
+ foreach (const Parameter &param,
+ primaryFunc->parameters()) {
if (param.name() == *a) {
needWarning = false;
break;
@@ -390,9 +423,10 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
}
- if (needWarning)
+ if (needWarning && !func->isReimp())
node->doc().location().warning(
- tr("Undocumented parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node)));
+ tr("Undocumented parameter '%1' in %2")
+ .arg(*a).arg(marker->plainFullName(node)));
}
++a;
}
@@ -404,15 +438,17 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
if (!body.contains("return", Qt::CaseInsensitive))
node->doc().location().warning(tr("Undocumented return value"));
}
-
+#if 0
+ // Now we put this at the top, before the other text.
if (func->reimplementedFrom() != 0)
generateReimplementedFrom(func, marker);
+#endif
}
}
if (node->type() == Node::Fake) {
const FakeNode *fake = static_cast<const FakeNode *>(node);
- if (fake->subType() == FakeNode::File) {
+ if (fake->subType() == Node::File) {
Text text;
Quoter quoter;
Doc::quoteFromFile(fake->doc().location(), quoter, fake->name());
@@ -459,7 +495,8 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker)
if ((*r).access == Node::Protected) {
text << " (protected)";
- } else if ((*r).access == Node::Private) {
+ }
+ else if ((*r).access == Node::Private) {
text << " (private)";
}
text << separator(index++, classe->baseClasses().count());
@@ -470,6 +507,15 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker)
}
}
+#ifdef QDOC_QML
+/*!
+ */
+void Generator::generateQmlInherits(const QmlClassNode* , CodeMarker* )
+{
+ // stub.
+}
+#endif
+
void Generator::generateInheritedBy(const ClassNode *classe,
CodeMarker *marker)
{
@@ -497,18 +543,21 @@ void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker)
QString exampleFile = child->name();
openedList.next();
text << Atom(Atom::ListItemNumber, openedList.numberString())
- << Atom(Atom::ListItemLeft, openedList.styleString()) << Atom::ParaLeft
+ << Atom(Atom::ListItemLeft, openedList.styleString())
+ << Atom::ParaLeft
<< Atom(Atom::Link, exampleFile)
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
<< exampleFile
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom::ParaRight << Atom(Atom::ListItemRight, openedList.styleString());
+ << Atom::ParaRight
+ << Atom(Atom::ListItemRight, openedList.styleString());
}
text << Atom(Atom::ListRight, openedList.styleString());
generateText(text, fake, marker);
}
-void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marker)
+void Generator::generateModuleWarning(const ClassNode *classe,
+ CodeMarker *marker)
{
QString module = classe->moduleName();
if (!module.isEmpty()) {
@@ -529,8 +578,10 @@ void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marke
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
<< Atom::ParaRight;
}
- else if (module == "Qt3Support" && Tokenizer::isTrue("defined(opensourceedition)")) {
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
+ else if (module == "Qt3Support" &&
+ Tokenizer::isTrue("defined(opensourceedition)")) {
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
<< "Note to Qt Desktop Light Edition users:"
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
<< " This class is only available in the "
@@ -558,10 +609,12 @@ QString Generator::indent(int level, const QString& markedCode)
if (markedCode.at(i - 1) == QLatin1Char('>'))
break;
}
- } else {
+ }
+ else {
if (markedCode.at(i) == QLatin1Char('\n')) {
column = 0;
- } else {
+ }
+ else {
if (column == 0) {
for (int j = 0; j < level; j++)
t += QLatin1Char(' ');
@@ -630,7 +683,7 @@ void Generator::setImageFileExtensions(const QStringList& extensions)
void Generator::unknownAtom(const Atom *atom)
{
Location::internalError(tr("unknown atom type '%1' in %2 generator")
- .arg(atom->typeString()).arg(format()));
+ .arg(atom->typeString()).arg(format()));
}
bool Generator::matchAhead(const Atom *atom, Atom::Type expectedAtomType)
@@ -659,7 +712,8 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList)
alternateFunc = func->parent()->findFunctionNode(alternateName);
}
}
- } else if (!func->name().isEmpty()) {
+ }
+ else if (!func->name().isEmpty()) {
alternateName = "set";
alternateName += func->name()[0].toUpper();
alternateName += func->name().mid(1);
@@ -715,9 +769,13 @@ void Generator::generateStatus(const Node *node, CodeMarker *marker)
case Node::Main:
break;
case Node::Preliminary:
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This "
- << typeString(node) << " is under development and is subject to change."
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << Atom::ParaRight;
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
+ << "This "
+ << typeString(node)
+ << " is under development and is subject to change."
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
+ << Atom::ParaRight;
break;
case Node::Deprecated:
text << Atom::ParaLeft;
@@ -735,16 +793,21 @@ void Generator::generateStatus(const Node *node, CodeMarker *marker)
text << "This " << typeString(node) << " is obsolete.";
if (node->isInnerNode())
text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD);
- text << " It is provided to keep old source code working. We strongly advise against "
+ text << " It is provided to keep old source code working. "
+ << "We strongly advise against "
<< "using it in new code." << Atom::ParaRight;
break;
case Node::Compat:
// reimplemented in HtmlGenerator subclass
if (node->isInnerNode()) {
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This "
- << typeString(node) << " is part of the Qt 3 compatibility layer."
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
+ << "This "
+ << typeString(node)
+ << " is part of the Qt 3 compatibility layer."
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
- << " It is provided to keep old source code working. We strongly advise against "
+ << " It is provided to keep old source code working. "
+ << "We strongly advise against "
<< "using it in new code. See "
<< Atom(Atom::AutoLink, "Porting to Qt 4")
<< " for more information."
@@ -762,71 +825,147 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker)
{
Text text;
Text theStockLink;
- Node::ThreadSafeness parent = node->parent()->inheritedThreadSafeness();
+ Node::ThreadSafeness threadSafeness = node->threadSafeness();
- switch (node->threadSafeness()) {
+ Text rlink;
+ rlink << Atom(Atom::Link,"reentrant")
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << "reentrant"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ Text tlink;
+ tlink << Atom(Atom::Link,"thread-safe")
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << "thread-safe"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ switch (threadSafeness) {
case Node::UnspecifiedSafeness:
break;
case Node::NonReentrant:
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Warning:"
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This "
- << typeString(node) << " is not " << stockLink("reentrant") << "." << Atom::ParaRight;
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Warning:"
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
+ << " This "
+ << typeString(node)
+ << " is not "
+ << rlink
+ << "."
+ << Atom::ParaRight;
break;
case Node::Reentrant:
case Node::ThreadSafe:
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD);
- if (parent == Node::ThreadSafe) {
- text << "Warning:";
- } else {
- text << "Note:";
- }
- text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " ";
-
- if (node->threadSafeness() == Node::ThreadSafe)
- theStockLink = stockLink("thread-safe");
- else
- theStockLink = stockLink("reentrant");
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Note:"
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
+ << " ";
if (node->isInnerNode()) {
- const InnerNode *innerNode = static_cast<const InnerNode *>(node);
- text << "All the functions in this " << typeString(node) << " are "
- << theStockLink;
-
- NodeList except;
+ const InnerNode* innerNode = static_cast<const InnerNode*>(node);
+ text << "All functions in this "
+ << typeString(node)
+ << " are ";
+ if (threadSafeness == Node::ThreadSafe)
+ text << tlink;
+ else
+ text << rlink;
+
+ bool exceptions = false;
+ NodeList reentrant;
+ NodeList threadsafe;
+ NodeList nonreentrant;
NodeList::ConstIterator c = innerNode->childNodes().begin();
while (c != innerNode->childNodes().end()) {
- if ((*c)->threadSafeness() != Node::UnspecifiedSafeness)
- except.append(*c);
+ switch ((*c)->threadSafeness()) {
+ case Node::Reentrant:
+ reentrant.append(*c);
+ if (threadSafeness == Node::ThreadSafe)
+ exceptions = true;
+ break;
+ case Node::ThreadSafe:
+ threadsafe.append(*c);
+ if (threadSafeness == Node::Reentrant)
+ exceptions = true;
+ break;
+ case Node::NonReentrant:
+ nonreentrant.append(*c);
+ exceptions = true;
+ break;
+ default:
+ break;
+ }
++c;
}
- if (except.isEmpty()) {
+ if (!exceptions)
text << ".";
+ else if (threadSafeness == Node::Reentrant) {
+ if (nonreentrant.isEmpty()) {
+ if (!threadsafe.isEmpty()) {
+ text << ", but ";
+ appendFullNames(text,threadsafe,innerNode,marker);
+ singularPlural(text,threadsafe);
+ text << " also " << tlink << ".";
+ }
+ else
+ text << ".";
+ }
+ else {
+ text << ", except for ";
+ appendFullNames(text,nonreentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,nonreentrant);
+ text << " nonreentrant.";
+ if (!threadsafe.isEmpty()) {
+ text << " ";
+ appendFullNames(text,threadsafe,innerNode,marker);
+ singularPlural(text,threadsafe);
+ text << " " << tlink << ".";
+ }
+ }
}
- else {
- text << ", except ";
-
- NodeList::ConstIterator e = except.begin();
- int index = 0;
- while (e != except.end()) {
- appendFullName(text, *e, innerNode, marker);
- text << separator(index++, except.count());
- ++e;
+ else { // thread-safe
+ if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) {
+ text << ", except for ";
+ if (!reentrant.isEmpty()) {
+ appendFullNames(text,reentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,reentrant);
+ text << " only " << rlink;
+ if (!nonreentrant.isEmpty())
+ text << ", and ";
+ }
+ if (!nonreentrant.isEmpty()) {
+ appendFullNames(text,nonreentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,nonreentrant);
+ text << " nonreentrant.";
+ }
+ text << ".";
}
}
}
else {
- text << "This " << typeString(node) << " is " << theStockLink << ".";
+ text << "This " << typeString(node) << " is ";
+ if (threadSafeness == Node::ThreadSafe)
+ text << tlink;
+ else
+ text << rlink;
+ text << ".";
}
text << Atom::ParaRight;
}
- generateText(text, node, marker);
+ generateText(text,node,marker);
}
void Generator::generateSince(const Node *node, CodeMarker *marker)
{
if (!node->since().isEmpty()) {
Text text;
- text << Atom::ParaLeft << "This " << typeString(node)
+ text << Atom::ParaLeft
+ << "This "
+ << typeString(node)
<< " was introduced in ";
if (project.isEmpty())
text << "version";
@@ -856,10 +995,12 @@ void Generator::generateReimplementedFrom(const FunctionNode *func,
{
if (func->reimplementedFrom() != 0) {
const FunctionNode *from = func->reimplementedFrom();
- if (from->access() != Node::Private && from->parent()->access() != Node::Private) {
+ if (from->access() != Node::Private &&
+ from->parent()->access() != Node::Private) {
Text text;
text << Atom::ParaLeft << "Reimplemented from ";
- appendFullName(text, from->parent(), func, marker, from);
+ QString fullName = from->parent()->name() + "::" + from->name() + "()";
+ appendFullName(text, from->parent(), fullName, from);
text << "." << Atom::ParaRight;
generateText(text, func, marker);
}
@@ -897,8 +1038,8 @@ const Atom *Generator::generateAtomList(const Atom *atom,
if (atom->type() == Atom::FormatEndif) {
if (generate && numAtoms0 == numAtoms) {
- relative->location().warning(tr("Output format %1 not handled").
- arg(format()));
+ relative->location().warning(tr("Output format %1 not handled")
+ .arg(format()));
Atom unhandledFormatAtom(Atom::UnhandledFormat, format());
generateAtomList(&unhandledFormatAtom,
relative,
@@ -909,7 +1050,8 @@ const Atom *Generator::generateAtomList(const Atom *atom,
atom = atom->next();
}
}
- else if (atom->type() == Atom::FormatElse || atom->type() == Atom::FormatEndif) {
+ else if (atom->type() == Atom::FormatElse ||
+ atom->type() == Atom::FormatEndif) {
return atom;
}
else {
@@ -939,6 +1081,33 @@ void Generator::appendFullName(Text& text,
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
}
+void Generator::appendFullName(Text& text,
+ const Node *apparentNode,
+ const QString& fullName,
+ const Node *actualNode)
+{
+ if (actualNode == 0)
+ actualNode = apparentNode;
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode(actualNode))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, fullName)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+}
+
+void Generator::appendFullNames(Text& text,
+ const NodeList& nodes,
+ const Node* relative,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator n = nodes.begin();
+ int index = 0;
+ while (n != nodes.end()) {
+ appendFullName(text,*n,relative,marker);
+ text << comma(index++,nodes.count());
+ ++n;
+ }
+}
+
void Generator::appendSortedNames(Text& text,
const ClassNode *classe,
const QList<RelatedClass> &classes,
@@ -950,7 +1119,8 @@ void Generator::appendSortedNames(Text& text,
r = classes.begin();
while (r != classes.end()) {
- if ((*r).node->access() == Node::Public && (*r).node->status() != Node::Internal
+ if ((*r).node->access() == Node::Public &&
+ (*r).node->status() != Node::Internal
&& !(*r).node->doc().isEmpty()) {
Text className;
appendFullName(className, (*r).node, classe, marker);
diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h
index d0909a6..8e3c57e 100644
--- a/tools/qdoc3/generator.h
+++ b/tools/qdoc3/generator.h
@@ -93,13 +93,16 @@ class Generator
virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
- virtual void generateText(const Text& text,
+ virtual bool generateText(const Text& text,
const Node *relative,
CodeMarker *marker);
#ifdef QDOC_QML
- virtual void generateQmlText(const Text& text,
+ virtual bool generateQmlText(const Text& text,
const Node *relative,
- CodeMarker *marker);
+ CodeMarker *marker,
+ const QString& qmlName);
+ virtual void generateQmlInherits(const QmlClassNode* cn,
+ CodeMarker* marker);
#endif
virtual void generateBody(const Node *node, CodeMarker *marker);
virtual void generateAlsoList(const Node *node, CodeMarker *marker);
@@ -150,6 +153,14 @@ class Generator
const Node *relative,
CodeMarker *marker,
const Node *actualNode = 0);
+ void appendFullName(Text& text,
+ const Node *apparentNode,
+ const QString& fullName,
+ const Node *actualNode);
+ void appendFullNames(Text& text,
+ const NodeList& nodes,
+ const Node* relative,
+ CodeMarker* marker);
void appendSortedNames(Text& text,
const ClassNode *classe,
const QList<RelatedClass> &classes,
diff --git a/tools/qdoc3/helpprojectwriter.cpp b/tools/qdoc3/helpprojectwriter.cpp
index cf7c618..f862e55 100644
--- a/tools/qdoc3/helpprojectwriter.cpp
+++ b/tools/qdoc3/helpprojectwriter.cpp
@@ -118,16 +118,19 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["variable"] = Node::Variable;
typeHash["target"] = Node::Target;
- QHash<QString, FakeNode::SubType> subTypeHash;
- subTypeHash["example"] = FakeNode::Example;
- subTypeHash["headerfile"] = FakeNode::HeaderFile;
- subTypeHash["file"] = FakeNode::File;
- subTypeHash["group"] = FakeNode::Group;
- subTypeHash["module"] = FakeNode::Module;
- subTypeHash["page"] = FakeNode::Page;
- subTypeHash["externalpage"] = FakeNode::ExternalPage;
-
- QSet<FakeNode::SubType> allSubTypes = QSet<FakeNode::SubType>::fromList(subTypeHash.values());
+ QHash<QString, Node::SubType> subTypeHash;
+ subTypeHash["example"] = Node::Example;
+ subTypeHash["headerfile"] = Node::HeaderFile;
+ subTypeHash["file"] = Node::File;
+ subTypeHash["group"] = Node::Group;
+ subTypeHash["module"] = Node::Module;
+ subTypeHash["page"] = Node::Page;
+ subTypeHash["externalpage"] = Node::ExternalPage;
+#ifdef QDOC_QML
+ subTypeHash["qmlclass"] = Node::QmlClass;
+#endif
+
+ QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
foreach (const QString &selector, selectors) {
QStringList pieces = selector.split(":");
@@ -139,7 +142,7 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
QString lower = pieces[0].toLower();
pieces = pieces[1].split(",");
if (typeHash.contains(lower)) {
- QSet<FakeNode::SubType> subTypes;
+ QSet<Node::SubType> subTypes;
for (int i = 0; i < pieces.size(); ++i) {
QString lower = pieces[i].toLower();
if (subTypeHash.contains(lower))
@@ -235,7 +238,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
// mask.
const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
if (subproject.selectors[node->type()].contains(fakeNode->subType()) &&
- fakeNode->subType() != FakeNode::ExternalPage &&
+ fakeNode->subType() != Node::ExternalPage &&
!fakeNode->fullTitle().isEmpty())
project.subprojects[name].nodes[objName] = node;
@@ -324,10 +327,10 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
// attributes.
case Node::Fake: {
const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
- if (fakeNode->subType() != FakeNode::ExternalPage &&
+ if (fakeNode->subType() != Node::ExternalPage &&
!fakeNode->fullTitle().isEmpty()) {
- if (fakeNode->subType() != FakeNode::File) {
+ if (fakeNode->subType() != Node::File) {
if (fakeNode->doc().hasKeywords()) {
foreach (const Atom *keyword, fakeNode->doc().keywords()) {
if (!keyword->string().isEmpty()) {
@@ -485,7 +488,7 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
writer.writeAttribute("title", fakeNode->fullTitle());
// qDebug() << "Title:" << fakeNode->fullTitle();
- if (fakeNode->subType() == FakeNode::HeaderFile) {
+ if (fakeNode->subType() == Node::HeaderFile) {
// Write subsections for all members, obsolete members and Qt 3
// members.
@@ -609,7 +612,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
while (nextPage) {
writeNode(project, writer, nextPage);
nextTitle = nextPage->links().value(Node::NextLink).first;
- if (nextTitle.isEmpty())
+ if(nextTitle.isEmpty())
break;
nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
}
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index 543975e..425c50b 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -61,11 +61,132 @@ QT_BEGIN_NAMESPACE
static bool showBrokenLinks = false;
+static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
+static QRegExp funcTag("(<@func target=\"([^\"]*)\">)(.*)(</@func>)");
+static QRegExp typeTag("(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)");
+static QRegExp spanTag("</@(?:comment|preprocessor|string|char)>");
+static QRegExp unknownTag("</?@[^>]*>");
+
+bool parseArg(const QString &src,
+ const QString &tag,
+ int *pos,
+ int n,
+ QStringRef *contents,
+ QStringRef *par1 = 0,
+ bool debug = false)
+{
+#define SKIP_CHAR(c) \
+ if (debug) \
+ qDebug() << "looking for " << c << " at " << QString(src.data() + i, n - i); \
+ if (i >= n || src[i] != c) { \
+ if (debug) \
+ qDebug() << " char '" << c << "' not found"; \
+ return false; \
+ } \
+ ++i;
+
+
+#define SKIP_SPACE \
+ while (i < n && src[i] == ' ') \
+ ++i;
+
+ int i = *pos;
+ int j = i;
+
+ // assume "<@" has been parsed outside
+ //SKIP_CHAR('<');
+ //SKIP_CHAR('@');
+
+ if (tag != QStringRef(&src, i, tag.length())) {
+ if (0 && debug)
+ qDebug() << "tag " << tag << " not found at " << i;
+ return false;
+ }
+
+ if (debug)
+ qDebug() << "haystack:" << src << "needle:" << tag << "i:" <<i;
+
+ // skip tag
+ i += tag.length();
+
+ // parse stuff like: linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
+ if (par1) {
+ SKIP_SPACE;
+ // read parameter name
+ j = i;
+ while (i < n && src[i].isLetter())
+ ++i;
+ if (src[i] == '=') {
+ if (debug)
+ qDebug() << "read parameter" << QString(src.data() + j, i - j);
+ SKIP_CHAR('=');
+ SKIP_CHAR('"');
+ // skip parameter name
+ j = i;
+ while (i < n && src[i] != '"')
+ ++i;
+ *par1 = QStringRef(&src, j, i - j);
+ SKIP_CHAR('"');
+ SKIP_SPACE;
+ } else {
+ if (debug)
+ qDebug() << "no optional parameter found";
+ }
+ }
+ SKIP_SPACE;
+ SKIP_CHAR('>');
+
+ // find contents up to closing "</@tag>
+ j = i;
+ for (; true; ++i) {
+ if (i + 4 + tag.length() > n)
+ return false;
+ if (src[i] != '<')
+ continue;
+ if (src[i + 1] != '/')
+ continue;
+ if (src[i + 2] != '@')
+ continue;
+ if (tag != QStringRef(&src, i + 3, tag.length()))
+ continue;
+ if (src[i + 3 + tag.length()] != '>')
+ continue;
+ break;
+ }
+
+ *contents = QStringRef(&src, j, i - j);
+
+ i += tag.length() + 4;
+
+ *pos = i;
+ if (debug)
+ qDebug() << " tag " << tag << " found: pos now: " << i;
+ return true;
+#undef SKIP_CHAR
+}
+
+static void addLink(const QString &linkTarget,
+ const QStringRef &nestedStuff,
+ QString *res)
+{
+ if (!linkTarget.isEmpty()) {
+ *res += "<a href=\"";
+ *res += linkTarget;
+ *res += "\">";
+ *res += nestedStuff;
+ *res += "</a>";
+ }
+ else {
+ *res += nestedStuff;
+ }
+}
+
+
HtmlGenerator::HtmlGenerator()
: helpProjectWriter(0), inLink(false), inContents(false),
inSectionHeading(false), inTableHeader(false), numTableRows(0),
threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"),
- tre(0), slow(false)
+ tre(0), slow(false), obsoleteLinks(false)
{
}
@@ -94,6 +215,7 @@ void HtmlGenerator::initializeGenerator(const Config &config)
};
Generator::initializeGenerator(config);
+ obsoleteLinks = config.getBool(QLatin1String(CONFIG_OBSOLETELINKS));
setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif");
int i = 0;
while (defaults[i].key) {
@@ -102,11 +224,21 @@ void HtmlGenerator::initializeGenerator(const Config &config)
i++;
}
- style = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_STYLE);
- postHeader = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTHEADER);
- footer = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_FOOTER);
- address = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_ADDRESS);
- pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_GENERATEMACREFS);
+ style = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_STYLE);
+ postHeader = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_POSTHEADER);
+ footer = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_FOOTER);
+ address = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_ADDRESS);
+ pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_GENERATEMACREFS);
project = config.getString(CONFIG_PROJECT);
@@ -120,10 +252,16 @@ void HtmlGenerator::initializeGenerator(const Config &config)
QSet<QString>::ConstIterator edition = editionNames.begin();
while (edition != editionNames.end()) {
QString editionName = *edition;
- QStringList editionModules = config.getStringList(
- CONFIG_EDITION + Config::dot + editionName + Config::dot + "modules");
- QStringList editionGroups = config.getStringList(
- CONFIG_EDITION + Config::dot + editionName + Config::dot + "groups");
+ QStringList editionModules = config.getStringList(CONFIG_EDITION +
+ Config::dot +
+ editionName +
+ Config::dot +
+ "modules");
+ QStringList editionGroups = config.getStringList(CONFIG_EDITION +
+ Config::dot +
+ editionName +
+ Config::dot +
+ "groups");
if (!editionModules.isEmpty())
editionModuleMap[editionName] = editionModules;
@@ -135,11 +273,17 @@ void HtmlGenerator::initializeGenerator(const Config &config)
slow = config.getBool(CONFIG_SLOW);
- stylesheets = config.getStringList(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_STYLESHEETS);
- customHeadElements = config.getStringList(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_CUSTOMHEADELEMENTS);
+ stylesheets = config.getStringList(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_STYLESHEETS);
+ customHeadElements = config.getStringList(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_CUSTOMHEADELEMENTS);
codeIndent = config.getInt(CONFIG_CODEINDENT);
- helpProjectWriter = new HelpProjectWriter(config, project.toLower() + ".qhp");
+ helpProjectWriter = new HelpProjectWriter(config,
+ project.toLower() +
+ ".qhp");
}
void HtmlGenerator::terminateGenerator()
@@ -173,6 +317,7 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
nonCompatClasses.clear();
mainClasses.clear();
compatClasses.clear();
+ obsoleteClasses.clear();
moduleClassMap.clear();
moduleNamespaceMap.clear();
funcIndex.clear();
@@ -182,9 +327,9 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
findAllFunctions(tree->root());
findAllLegaleseTexts(tree->root());
findAllNamespaces(tree->root());
-#ifdef ZZZ_QDOC_QML
+#ifdef ZZZ_QDOC_QML
findAllQmlClasses(tree->root());
-#endif
+#endif
PageGenerator::generateTree(tree, marker);
@@ -260,7 +405,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::AutoLink:
if (!inLink && !inContents && !inSectionHeading) {
const Node *node = 0;
- QString link = getLink(atom, relative, marker, node);
+ QString link = getLink(atom, relative, marker, &node);
if (!link.isEmpty()) {
beginLink(link, node, relative, marker);
generateLink(atom, relative, marker);
@@ -288,7 +433,8 @@ int HtmlGenerator::generateAtom(const Atom *atom,
QString str;
atom = atom->next();
while (atom != 0 && atom->type() != Atom::BriefRight) {
- if (atom->type() == Atom::String || atom->type() == Atom::AutoLink)
+ if (atom->type() == Atom::String ||
+ atom->type() == Atom::AutoLink)
str += atom->string();
skipAhead++;
atom = atom->next();
@@ -326,21 +472,24 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
break;
case Atom::Code:
- out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
- marker, relative))
+ out() << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
<< "</pre>\n";
break;
-#ifdef QDOC_QML
+#ifdef QDOC_QML
case Atom::Qml:
- out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
- marker, relative))
+ out() << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
<< "</pre>\n";
break;
-#endif
+#endif
case Atom::CodeNew:
out() << "<p>you can rewrite it as</p>\n"
- << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
- marker, relative))
+ << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
<< "</pre>\n";
break;
case Atom::CodeOld:
@@ -348,7 +497,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
// fallthrough
case Atom::CodeBad:
out() << "<pre><font color=\"#404040\">"
- << trimmedTrailing(protect(plainCode(indent(codeIndent, atom->string()))))
+ << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
<< "</font></pre>\n";
break;
case Atom::FootnoteLeft:
@@ -388,6 +537,20 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << formattingRightMap()[atom->string()];
}
break;
+ case Atom::AnnotatedList:
+ {
+ const FakeNode *fake = static_cast<const FakeNode *>(relative);
+ if (fake && !fake->groupMembers().isEmpty()) {
+ QList<Node*> values = tre->groups().values(atom->string());
+ QMap<QString, const Node*> nodeMap;
+ for (int i = 0; i < values.size(); ++i) {
+ const Node* n = values.at(i);
+ nodeMap.insert(n->name(),n);
+ }
+ generateAnnotatedList(fake, marker, nodeMap);
+ }
+ }
+ break;
case Atom::GeneratedList:
if (atom->string() == "annotatedclasses") {
generateAnnotatedList(relative, marker, nonCompatClasses);
@@ -443,6 +606,9 @@ int HtmlGenerator::generateAtom(const Atom *atom,
else if (atom->string() == "compatclasses") {
generateCompactList(relative, marker, compatClasses);
}
+ else if (atom->string() == "obsoleteclasses") {
+ generateCompactList(relative, marker, obsoleteClasses);
+ }
else if (atom->string() == "functionindex") {
generateFunctionIndex(relative, marker);
}
@@ -524,11 +690,12 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::Link:
{
const Node *node = 0;
- QString myLink = getLink(atom, relative, marker, node);
- if (myLink.isEmpty())
+ QString myLink = getLink(atom, relative, marker, &node);
+ if (myLink.isEmpty()) {
relative->doc().location().warning(tr("Cannot link to '%1' in %2")
.arg(atom->string())
.arg(marker->plainFullName(relative)));
+ }
beginLink(myLink, node, relative, marker);
skipAhead = 1;
}
@@ -554,13 +721,17 @@ int HtmlGenerator::generateAtom(const Atom *atom,
else if (atom->string() == ATOM_LIST_VALUE) {
threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
if (threeColumnEnumValueTable) {
- out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"100%\">\n"
- "<tr><th width=\"25%\">Constant</th><th width=\"15%\">Value</th>"
- "<th width=\"60%\">Description</th></tr>\n";
+ out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" width=\"100%\">\n"
+ << "<tr><th width=\"25%\">Constant</th>"
+ << "<th width=\"15%\">Value</th>"
+ << "<th width=\"60%\">Description</th></tr>\n";
}
else {
- out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"40%\">\n"
- << "<tr><th width=\"60%\">Constant</th><th width=\"40%\">Value</th></tr>\n";
+ out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" width=\"40%\">\n"
+ << "<tr><th width=\"60%\">Constant</th><th "
+ << "width=\"40%\">Value</th></tr>\n";
}
}
else {
@@ -734,14 +905,17 @@ int HtmlGenerator::generateAtom(const Atom *atom,
}
if (!atom->string().isEmpty()) {
if (atom->string().contains("%"))
- out() << "<p><table width=\"" << atom->string() << "\" "
+ out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" "
<< "align=\"center\" cellpadding=\"2\" "
<< "cellspacing=\"1\" border=\"0\">\n";
- else
- out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ else {
+ out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
+ }
}
else {
- out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
}
numTableRows = 0;
break;
@@ -840,7 +1014,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::EndQmlText:
// don't do anything with these. They are just tags.
break;
-#endif
+#endif
default:
unknownAtom(atom);
}
@@ -906,6 +1080,12 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
generateHeader(title, inner, marker, true);
generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
+#ifdef QDOC_QML
+ if (classe && !classe->qmlElement().isEmpty()) {
+ generateInstantiatedBy(classe,marker);
+ }
+#endif
+
generateBrief(inner, marker);
generateIncludes(inner, marker);
generateStatus(inner, marker);
@@ -924,12 +1104,16 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
out() << "<li><a href=\"" << membersLink << "\">"
<< "List of all members, including inherited members</a></li>\n";
- QString obsoleteLink = generateLowStatusMemberFile(inner, marker, CodeMarker::Obsolete);
+ QString obsoleteLink = generateLowStatusMemberFile(inner,
+ marker,
+ CodeMarker::Obsolete);
if (!obsoleteLink.isEmpty())
out() << "<li><a href=\"" << obsoleteLink << "\">"
<< "Obsolete members</a></li>\n";
- QString compatLink = generateLowStatusMemberFile(inner, marker, CodeMarker::Compat);
+ QString compatLink = generateLowStatusMemberFile(inner,
+ marker,
+ CodeMarker::Compat);
if (!compatLink.isEmpty())
out() << "<li><a href=\"" << compatLink << "\">"
<< "Qt 3 support members</a></li>\n";
@@ -941,14 +1125,34 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
s = sections.begin();
while (s != sections.end()) {
- if (s->members.isEmpty()) {
+ if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
if (!s->inherited.isEmpty())
needOtherSection = true;
- } else {
- out() << "<a name=\"" << registerRef((*s).name.toLower()) << "\"></a>\n";
- out() << "<h3>" << protect((*s).name) << "</h3>\n";
+ }
+ else {
+ if (!s->members.isEmpty()) {
+ out() << "<hr />\n";
+ out() << "<a name=\""
+ << registerRef((*s).name.toLower())
+ << "\"></a>\n";
+ out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ generateSection(s->members, inner, marker, CodeMarker::Summary);
+ }
+ if (!s->reimpMembers.isEmpty()) {
+ QString name = QString("Reimplemented ") + (*s).name;
+ out() << "<hr />\n";
+ out() << "<a name=\""
+ << registerRef(name.toLower())
+ << "\"></a>\n";
+ out() << "<h2>" << protect(name) << "</h2>\n";
+ generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
+ }
- generateSectionList(*s, inner, marker, CodeMarker::Summary);
+ if (!s->inherited.isEmpty()) {
+ out() << "<ul>\n";
+ generateSectionInheritedList(*s, inner, marker, true);
+ out() << "</ul>\n";
+ }
}
++s;
}
@@ -997,29 +1201,34 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
names << (*m)->name();
if ((*m)->type() == Node::Function) {
const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m);
- if (func->metaness() == FunctionNode::Ctor || func->metaness() == FunctionNode::Dtor
- || func->overloadNumber() != 1)
+ if (func->metaness() == FunctionNode::Ctor ||
+ func->metaness() == FunctionNode::Dtor ||
+ func->overloadNumber() != 1)
names.clear();
- } else if ((*m)->type() == Node::Property) {
+ }
+ else if ((*m)->type() == Node::Property) {
const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
- if (!prop->getters().isEmpty() && !names.contains(prop->getters().first()->name()))
+ if (!prop->getters().isEmpty() &&
+ !names.contains(prop->getters().first()->name()))
names << prop->getters().first()->name();
if (!prop->setters().isEmpty())
names << prop->setters().first()->name();
if (!prop->resetters().isEmpty())
names << prop->resetters().first()->name();
- } else if ((*m)->type() == Node::Enum) {
- const EnumNode *enume = reinterpret_cast<const EnumNode *>(*m);
+ }
+ else if ((*m)->type() == Node::Enum) {
+ const EnumNode *enume = reinterpret_cast<const EnumNode*>(*m);
if (enume->flagsType())
names << enume->flagsType()->name();
foreach (const QString &enumName,
- enume->doc().enumItemNames().toSet()
- - enume->doc().omitEnumItemNames().toSet())
- names << plainCode(marker->markedUpEnumValue(enumName, enume));
+ enume->doc().enumItemNames().toSet() -
+ enume->doc().omitEnumItemNames().toSet())
+ names << plainCode(marker->markedUpEnumValue(enumName,
+ enume));
}
foreach (const QString &name, names)
- classSection.keywords += qMakePair(name, linkForNode(*m, 0));
+ classSection.keywords += qMakePair(name,linkForNode(*m,0));
}
++m;
}
@@ -1060,16 +1269,19 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
QList<Section>::const_iterator s;
QString htmlTitle = fake->fullTitle();
- if (fake->subType() == FakeNode::File && !fake->subTitle().isEmpty()) {
+ if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
subTitleSize = SmallSubTitle;
htmlTitle += " (" + fake->subTitle() + ")";
}
generateHeader(htmlTitle, fake, marker, true);
- generateTitle(fake->fullTitle(), Text() << fake->subTitle(), subTitleSize,
- fake, marker);
+ generateTitle(fake->fullTitle(),
+ Text() << fake->subTitle(),
+ subTitleSize,
+ fake,
+ marker);
- if (fake->subType() == FakeNode::Module) {
+ if (fake->subType() == Node::Module) {
// Generate brief text and status for modules.
generateBrief(fake, marker);
generateStatus(fake, marker);
@@ -1083,7 +1295,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
}
}
- else if (fake->subType() == FakeNode::HeaderFile) {
+ else if (fake->subType() == Node::HeaderFile) {
// Generate brief text and status for modules.
generateBrief(fake, marker);
generateStatus(fake, marker);
@@ -1095,12 +1307,16 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
out() << "<li><a href=\"" << membersLink << "\">"
<< "List of all members, including inherited members</a></li>\n";
- QString obsoleteLink = generateLowStatusMemberFile(fake, marker, CodeMarker::Obsolete);
+ QString obsoleteLink = generateLowStatusMemberFile(fake,
+ marker,
+ CodeMarker::Obsolete);
if (!obsoleteLink.isEmpty())
out() << "<li><a href=\"" << obsoleteLink << "\">"
<< "Obsolete members</a></li>\n";
- QString compatLink = generateLowStatusMemberFile(fake, marker, CodeMarker::Compat);
+ QString compatLink = generateLowStatusMemberFile(fake,
+ marker,
+ CodeMarker::Compat);
if (!compatLink.isEmpty())
out() << "<li><a href=\"" << compatLink << "\">"
<< "Qt 3 support members</a></li>\n";
@@ -1126,35 +1342,65 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
appendDcfSubSection(&fakeSection, compatSection);
}
}
+#ifdef QDOC_QML
+ else if (fake->subType() == Node::QmlClass) {
+ const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
+ const ClassNode* cn = qml_cn->classNode();
+ generateQmlInherits(qml_cn, marker);
+ generateQmlInstantiates(qml_cn, marker);
+ generateBrief(qml_cn, marker);
+ sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
+ s = sections.begin();
+ while (s != sections.end()) {
+ out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
+ out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ generateQmlSummary(*s,fake,marker);
+ ++s;
+ }
+
+ out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
+ out() << "<h2>" << "Detailed Description" << "</h2>\n";
+ generateBody(fake, marker);
+ if (cn)
+ generateQmlText(cn->doc().body(), cn, marker, fake->name());
+ generateAlsoList(fake, marker);
+ out() << "<hr />\n";
+ sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
+ s = sections.begin();
+ while (s != sections.end()) {
+ out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ NodeList::ConstIterator m = (*s).members.begin();
+ while (m != (*s).members.end()) {
+ generateDetailedQmlMember(*m, fake, marker);
+ out() << "<br />\n";
+ fakeSection.keywords += qMakePair((*m)->name(),
+ linkForNode(*m,0));
+ ++m;
+ }
+ ++s;
+ }
+ generateFooter(fake);
+ return;
+ }
+#endif
+
sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
s = sections.begin();
while (s != sections.end()) {
out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
- out() << "<h3>" << protect((*s).name) << "</h3>\n";
+ out() << "<h2>" << protect((*s).name) << "</h2>\n";
generateSectionList(*s, fake, marker, CodeMarker::Summary);
++s;
}
Text brief = fake->doc().briefText();
- if (fake->subType() == FakeNode::Module && !brief.isEmpty()) {
+ if (fake->subType() == Node::Module && !brief.isEmpty()) {
out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
out() << "<h2>" << "Detailed Description" << "</h2>\n";
}
generateBody(fake, marker);
-#ifdef QDOC_QML
- if (fake->subType() == FakeNode::QmlClass) {
- //qDebug() << "generateFakeNode(): QML CLASS" << fake->name();
- const QmlNode* qmlNode = static_cast<const QmlNode*>(fake);
- const ClassNode* cn = qmlNode->classNode();
- if (cn) {
- //qDebug() << " CPP CLASS" << cn->name();
- generateQmlText(cn->doc().body(), cn, marker);
- }
- }
-#endif
-
generateAlsoList(fake, marker);
if (!fake->groupMembers().isEmpty()) {
@@ -1184,10 +1430,10 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
}
generateFooter(fake);
- if (fake->subType() == FakeNode::Example) {
+ if (fake->subType() == Node::Example) {
appendDcfSubSection(&dcfExamplesRoot, fakeSection);
}
- else if (fake->subType() != FakeNode::File) {
+ else if (fake->subType() != Node::File) {
QString contentsPage = fake->links().value(Node::ContentsLink).first;
if (contentsPage == "Qt Designer Manual") {
@@ -1407,17 +1653,19 @@ void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
{
if (!inner->includes().isEmpty()) {
- out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent,
- marker->markedUpIncludes(
- inner->includes())),
- marker, inner))
+ out() << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,
+ marker->markedUpIncludes(inner->includes())),
+ marker,inner))
<< "</pre>";
}
}
-void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker,
+void HtmlGenerator::generateTableOfContents(const Node *node,
+ CodeMarker *marker,
Doc::SectioningUnit sectioningUnit,
- int numColumns, const Node *relative)
+ int numColumns,
+ const Node *relative)
{
if (!node->doc().hasTableOfContents())
@@ -1436,7 +1684,8 @@ void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker
QString tdTag;
if (numColumns > 1) {
tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";
- out() << "<p><table width=\"100%\">\n<tr valign=\"top\">" << tdTag << "\n";
+ out() << "<p><table class=\"toc\" width=\"100%\">\n<tr valign=\"top\">"
+ << tdTag << "\n";
}
// disable nested links in table of contents
@@ -1455,7 +1704,8 @@ void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker
out() << "<ul>";
sectionNumber.append("1");
} while (sectionNumber.size() < nextLevel);
- } else {
+ }
+ else {
while (sectionNumber.size() > nextLevel) {
out() << "</ul>\n";
sectionNumber.removeLast();
@@ -1470,7 +1720,10 @@ void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker
columnSize = 0;
}
out() << "<li>";
- out() << "<a href=\"" << nodeName << "#" << Doc::canonicalTitle(headingText.toString())
+ out() << "<a href=\""
+ << nodeName
+ << "#"
+ << Doc::canonicalTitle(headingText.toString())
<< "\">";
generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
out() << "</a></li>\n";
@@ -1520,12 +1773,15 @@ void HtmlGenerator::generateNavigationBar(const NavigationBar& bar,
}
#endif
-QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, CodeMarker *marker)
+QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
+ CodeMarker *marker)
{
QList<Section> sections;
QList<Section>::ConstIterator s;
- sections = marker->sections(inner, CodeMarker::SeparateList, CodeMarker::Okay);
+ sections = marker->sections(inner,
+ CodeMarker::SeparateList,
+ CodeMarker::Okay);
if (sections.isEmpty())
return QString();
@@ -1546,10 +1802,13 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, CodeM
return fileName;
}
-QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeMarker *marker,
+QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
+ CodeMarker *marker,
CodeMarker::Status status)
{
- QList<Section> sections = marker->sections(inner, CodeMarker::Summary, status);
+ QList<Section> sections = marker->sections(inner,
+ CodeMarker::Summary,
+ status);
QMutableListIterator<Section> j(sections);
while (j.hasNext()) {
if (j.next().members.size() == 0)
@@ -1566,7 +1825,8 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeM
if (status == CodeMarker::Compat) {
title = "Qt 3 Support Members for " + inner->name();
fileName = fileBase(inner) + "-qt3." + fileExtension(inner);
- } else {
+ }
+ else {
title = "Obsolete Members for " + inner->name();
fileName = fileBase(inner) + "-obsolete." + fileExtension(inner);
}
@@ -1580,18 +1840,20 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeM
"<a href=\"qt3support.html\">Qt 3 support layer</a>.</b> "
"They are provided to help you port old code to Qt 4. We advise against "
"using them in new code.</p>\n";
- } else {
- out() << "<p><b>The following class members are obsolete.</b> They are provided to keep "
- "old source code working. We strongly advise against using them in new "
- "code.</p>\n";
+ }
+ else {
+ out() << "<p><b>The following class members are obsolete.</b> "
+ << "They are provided to keep old source code working. "
+ << "We strongly advise against using them in new code.</p>\n";
}
- out() << "<p><ul><li><a href=\"" << linkForNode(inner, 0) << "\">" << protect(inner->name())
+ out() << "<p><ul><li><a href=\""
+ << linkForNode(inner, 0) << "\">"
+ << protect(inner->name())
<< " class reference</a></li></ul></p>\n";
for (i = 0; i < sections.size(); ++i) {
- out() << "<h3>" << protect(sections.at(i).name) << "</h3>\n";
-
+ out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
}
@@ -1613,8 +1875,9 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeM
return fileName;
}
-void HtmlGenerator::generateClassHierarchy(const Node *relative, CodeMarker *marker,
- const QMap<QString, const Node *> &classMap)
+void HtmlGenerator::generateClassHierarchy(const Node *relative,
+ CodeMarker *marker,
+ const QMap<QString,const Node*> &classMap)
{
if (classMap.isEmpty())
return;
@@ -1636,8 +1899,10 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, CodeMarker *mar
if (stack.top().isEmpty()) {
stack.pop();
out() << "</ul>\n";
- } else {
- const ClassNode *child = static_cast<const ClassNode *>(*stack.top().begin());
+ }
+ else {
+ const ClassNode *child =
+ static_cast<const ClassNode *>(*stack.top().begin());
out() << "<li>";
generateFullName(child, relative, marker);
out() << "</li>\n";
@@ -1656,15 +1921,20 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, CodeMarker *mar
}
}
-void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *marker,
- const QMap<QString, const Node *> &nodeMap)
+void HtmlGenerator::generateAnnotatedList(const Node *relative,
+ CodeMarker *marker,
+ const QMap<QString, const Node *> &nodeMap)
{
- out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
int row = 0;
foreach (const QString &name, nodeMap.keys()) {
const Node *node = nodeMap[name];
+ if (node->status() == Node::Obsolete)
+ continue;
+
if (++row % 2 == 1)
out() << "<tr valign=\"top\" class=\"odd\">";
else
@@ -1680,7 +1950,8 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *mark
generateText(brief, node, marker);
out() << "</td>";
}
- } else {
+ }
+ else {
out() << "<td>";
out() << protect(node->doc().briefText().toString());
out() << "</td>";
@@ -1690,7 +1961,8 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *mark
out() << "</table></p>\n";
}
-void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker,
+void HtmlGenerator::generateCompactList(const Node *relative,
+ CodeMarker *marker,
const QMap<QString, const Node *> &classMap)
{
const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
@@ -1734,8 +2006,9 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
last = classMap.begin().key();
if (classMap.size() > 1) {
- while (commonPrefixLen < first.length() + 1 && commonPrefixLen < last.length() + 1
- && first[commonPrefixLen] == last[commonPrefixLen])
+ while (commonPrefixLen < first.length() + 1 &&
+ commonPrefixLen < last.length() + 1 &&
+ first[commonPrefixLen] == last[commonPrefixLen])
++commonPrefixLen;
}
@@ -1764,7 +2037,8 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
if (key[0].digitValue() != -1) {
paragraphNo = key[0].digitValue();
- } else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
+ }
+ else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
paragraphNo = 10 + key[0].unicode() - 'a';
}
@@ -1812,14 +2086,15 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
}
firstOffset[NumColumns] = classMap.count();
- out() << "<p><table width=\"100%\">\n";
+ out() << "<p><table class=\"generic\" width=\"100%\">\n";
for (k = 0; k < numRows; k++) {
out() << "<tr>\n";
for (i = 0; i < NumColumns; i++) {
if (currentOffset[i] >= firstOffset[i + 1]) {
// this column is finished
out() << "<td>\n</td>\n";
- } else {
+ }
+ else {
while (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count()) {
++currentParagraphNo[i];
currentOffsetInParagraph[i] = 0;
@@ -1828,29 +2103,34 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
out() << "<td align=\"right\">";
if (currentOffsetInParagraph[i] == 0) {
// start a new paragraph
- out() << "<b>" << paragraphName[currentParagraphNo[i]] << "&nbsp;</b>";
- }
- out() << "</td>\n";
-
- // bad loop
- QMap<QString, const Node *>::Iterator it;
- it = paragraph[currentParagraphNo[i]].begin();
- for (j = 0; j < currentOffsetInParagraph[i]; j++)
- ++it;
-
- out() << "<td>";
- // Previously, we used generateFullName() for this, but we
- // require some special formatting.
- out() << "<a href=\"" << linkForNode(it.value(), relative) << "\">";
- QStringList pieces = fullName(it.value(), relative, marker).split("::");
- out() << protect(pieces.last());
- out() << "</a>";
- if (pieces.size() > 1) {
- out() << " (";
- generateFullName(it.value()->parent(), relative, marker);
- out() << ")";
+ out() << "<b>"
+ << paragraphName[currentParagraphNo[i]]
+ << "&nbsp;</b>";
}
out() << "</td>\n";
+
+ if (!paragraphName[currentParagraphNo[i]].isEmpty()) {
+ QMap<QString, const Node *>::Iterator it;
+ it = paragraph[currentParagraphNo[i]].begin();
+ for (j = 0; j < currentOffsetInParagraph[i]; j++)
+ ++it;
+
+ out() << "<td>";
+ // Previously, we used generateFullName() for this, but we
+ // require some special formatting.
+ out() << "<a href=\""
+ << linkForNode(it.value(), relative)
+ << "\">";
+ QStringList pieces = fullName(it.value(), relative, marker).split("::");
+ out() << protect(pieces.last());
+ out() << "</a>";
+ if (pieces.size() > 1) {
+ out() << " (";
+ generateFullName(it.value()->parent(), relative, marker);
+ out() << ")";
+ }
+ out() << "</td>\n";
+ }
currentOffset[i]++;
currentOffsetInParagraph[i]++;
@@ -1861,7 +2141,8 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
out() << "</table></p>\n";
}
-void HtmlGenerator::generateFunctionIndex(const Node *relative, CodeMarker *marker)
+void HtmlGenerator::generateFunctionIndex(const Node *relative,
+ CodeMarker *marker)
{
out() << "<p align=\"center\"><font size=\"+1\"><b>";
for (int i = 0; i < 26; i++) {
@@ -1910,7 +2191,8 @@ void HtmlGenerator::generateFunctionIndex(const Node *relative, CodeMarker *mark
#endif
}
-void HtmlGenerator::generateLegaleseList(const Node *relative, CodeMarker *marker)
+void HtmlGenerator::generateLegaleseList(const Node *relative,
+ CodeMarker *marker)
{
QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin();
while (it != legaleseTexts.end()) {
@@ -1928,8 +2210,10 @@ void HtmlGenerator::generateLegaleseList(const Node *relative, CodeMarker *marke
}
}
-void HtmlGenerator::generateSynopsis(const Node *node, const Node *relative,
- CodeMarker *marker, CodeMarker::SynopsisStyle style)
+/*void HtmlGenerator::generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
{
QString marked = marker->markedUpSynopsis(node, relative, style);
QRegExp templateTag("(<[^@>]*>)");
@@ -1939,7 +2223,8 @@ void HtmlGenerator::generateSynopsis(const Node *node, const Node *relative,
marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
contents);
}
- marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
+ "<i>\\1<sub>\\2</sub></i>");
marked.replace("<@param>", "<i>");
marked.replace("</@param>", "</i>");
@@ -1950,7 +2235,8 @@ void HtmlGenerator::generateSynopsis(const Node *node, const Node *relative,
QRegExp extraRegExp("<@extra>.*</@extra>");
extraRegExp.setMinimal(true);
marked.replace(extraRegExp, "");
- } else {
+ }
+ else {
marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
marked.replace("</@extra>", "</tt>");
}
@@ -1960,7 +2246,40 @@ void HtmlGenerator::generateSynopsis(const Node *node, const Node *relative,
marked.replace("</@type>", "");
}
out() << highlightedCode(marked, marker, relative);
+}*/
+
+#ifdef QDOC_QML
+void HtmlGenerator::generateQmlItem(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ bool summary)
+{
+ QString marked = marker->markedUpQmlItem(node,summary);
+ QRegExp templateTag("(<[^@>]*>)");
+ if (marked.indexOf(templateTag) != -1) {
+ QString contents = protect(marked.mid(templateTag.pos(1),
+ templateTag.cap(1).length()));
+ marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
+ contents);
+ }
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
+ "<i>\\1<sub>\\2</sub></i>");
+ marked.replace("<@param>", "<i>");
+ marked.replace("</@param>", "</i>");
+
+ if (summary)
+ marked.replace("@name>", "b>");
+
+ marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
+ marked.replace("</@extra>", "</tt>");
+
+ if (summary) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
+ }
+ out() << highlightedCode(marked, marker, relative);
}
+#endif
void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
{
@@ -1984,7 +2303,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
}
// there are too many examples; they would clutter the list
- if (fakeNode->subType() == FakeNode::Example)
+ if (fakeNode->subType() == Node::Example)
continue;
// not interested either in individual (Qt Designer etc.) manual chapters
@@ -1992,7 +2311,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
continue;
// Discard external nodes.
- if (fakeNode->subType() == FakeNode::ExternalPage)
+ if (fakeNode->subType() == Node::ExternalPage)
continue;
QString sortKey = fakeNode->fullTitle().toLower();
@@ -2017,7 +2336,8 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
groupTitlesMap[fakeNode->fullTitle()] = const_cast<const FakeNode *>(fakeNode);
}
}
- } else if (!isGroupPage) {
+ }
+ else if (!isGroupPage) {
// If we encounter a page that belongs to a group then
// we add that page to the list for that group.
const FakeNode *groupNode = static_cast<const FakeNode *>(tre->root()->findNode(group, Node::Fake));
@@ -2075,21 +2395,100 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
}
}
-void HtmlGenerator::generateSectionList(const Section& section, const Node *relative,
- CodeMarker *marker, CodeMarker::SynopsisStyle style)
+#ifdef QDOC_NAME_ALIGNMENT
+void HtmlGenerator::generateSection(const NodeList& nl,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
+{
+ bool name_alignment = true;
+ if (!nl.isEmpty()) {
+ bool twoColumn = false;
+ if (style == CodeMarker::SeparateList) {
+ name_alignment = false;
+ twoColumn = (nl.count() >= 16);
+ }
+ else if (nl.first()->type() == Node::Property) {
+ twoColumn = (nl.count() >= 5);
+ name_alignment = false;
+ }
+ if (name_alignment) {
+ out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
+ << "cellspacing=\"0\" width=\"100%\">\n";
+ }
+ else {
+ if (twoColumn)
+ out() << "<p><table class=\"propsummary\" width=\"100%\" "
+ << "border=\"0\" cellpadding=\"0\""
+ << " cellspacing=\"0\">\n"
+ << "<tr><td width=\"45%\" valign=\"top\">";
+ out() << "<ul>\n";
+ }
+
+ int i = 0;
+ NodeList::ConstIterator m = nl.begin();
+ while (m != nl.end()) {
+ if ((*m)->access() == Node::Private) {
+ ++m;
+ continue;
+ }
+
+ if (name_alignment) {
+ out() << "<tr><td class=\"memItemLeft\" "
+ << "align=\"right\" valign=\"top\">";
+ }
+ else {
+ if (twoColumn && i == (int) (nl.count() + 1) / 2)
+ out() << "</ul></td><td valign=\"top\"><ul>\n";
+ out() << "<li><div class=\"fn\">";
+ }
+
+ generateSynopsis(*m, relative, marker, style, name_alignment);
+ if (name_alignment)
+ out() << "</td></tr>\n";
+ else
+ out() << "</div></li>\n";
+ i++;
+ ++m;
+ }
+ if (name_alignment)
+ out() << "</table>\n";
+ else {
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table></p>\n";
+ }
+ }
+}
+
+void HtmlGenerator::generateSectionList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
{
+ bool name_alignment = true;
if (!section.members.isEmpty()) {
bool twoColumn = false;
if (style == CodeMarker::SeparateList) {
+ name_alignment = false;
twoColumn = (section.members.count() >= 16);
- } else if (section.members.first()->type() == Node::Property) {
+ }
+ else if (section.members.first()->type() == Node::Property) {
twoColumn = (section.members.count() >= 5);
+ name_alignment = false;
+ }
+ if (name_alignment) {
+ out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
+ << "cellspacing=\"0\" width=\"100%\">\n";
+ }
+ else {
+ if (twoColumn)
+ out() << "<p><table class=\"propsummary\" width=\"100%\" "
+ << "border=\"0\" cellpadding=\"0\""
+ << " cellspacing=\"0\">\n"
+ << "<tr><td width=\"45%\" valign=\"top\">";
+ out() << "<ul>\n";
}
- if (twoColumn)
- out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""
- " cellspacing=\"0\">\n"
- << "<tr><td width=\"45%\" valign=\"top\">";
- out() << "<ul>\n";
int i = 0;
NodeList::ConstIterator m = section.members.begin();
@@ -2099,41 +2498,56 @@ void HtmlGenerator::generateSectionList(const Section& section, const Node *rela
continue;
}
- if (twoColumn && i == (int) (section.members.count() + 1) / 2)
- out() << "</ul></td><td valign=\"top\"><ul>\n";
+ if (name_alignment) {
+ out() << "<tr><td class=\"memItemLeft\" "
+ << "align=\"right\" valign=\"top\">";
+ }
+ else {
+ if (twoColumn && i == (int) (section.members.count() + 1) / 2)
+ out() << "</ul></td><td valign=\"top\"><ul>\n";
+ out() << "<li><div class=\"fn\">";
+ }
- out() << "<li><div class=\"fn\"></div>";
- if (style == CodeMarker::Accessors)
- out() << "<b>";
- generateSynopsis(*m, relative, marker, style);
- if (style == CodeMarker::Accessors)
- out() << "</b>";
- out() << "</li>\n";
+ generateSynopsis(*m, relative, marker, style, name_alignment);
+ if (name_alignment)
+ out() << "</td></tr>\n";
+ else
+ out() << "</div></li>\n";
i++;
++m;
}
- out() << "</ul>\n";
- if (twoColumn)
- out() << "</td></tr>\n</table></p>\n";
+ if (name_alignment)
+ out() << "</table>\n";
+ else {
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table></p>\n";
+ }
}
if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
out() << "<ul>\n";
- generateSectionInheritedList(section, relative, marker);
+ generateSectionInheritedList(section, relative, marker, name_alignment);
out() << "</ul>\n";
}
}
-void HtmlGenerator::generateSectionInheritedList(const Section& section, const Node *relative,
- CodeMarker *marker)
+void HtmlGenerator::generateSectionInheritedList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ bool nameAlignment)
{
QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
while (p != section.inherited.end()) {
- out() << "<li><div class=\"fn\"></div>";
+ if (nameAlignment)
+ out() << "<li><div bar=\"2\" class=\"fn\"></div>";
+ else
+ out() << "<li><div class=\"fn\"></div>";
out() << (*p).second << " ";
if ((*p).second == 1) {
out() << section.singularMember;
- } else {
+ }
+ else {
out() << section.pluralMember;
}
out() << " inherited from <a href=\"" << fileName((*p).first)
@@ -2144,270 +2558,324 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section, const N
}
}
-void HtmlGenerator::generateLink(const Atom *atom, const Node * /* relative */, CodeMarker *marker)
+void HtmlGenerator::generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style,
+ bool nameAlignment)
{
- static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
-
- if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
- // hack for C++: move () outside of link
- int k = funcLeftParen.pos(1);
- out() << protect(atom->string().left(k));
- if (link.isEmpty()) {
- if (showBrokenLinks)
- out() << "</i>";
- } else {
- out() << "</a>";
- }
- inLink = false;
- out() << protect(atom->string().mid(k));
- } else if (marker->recognizeLanguage("Java")) {
- // hack for Java: remove () and use <tt> when appropriate
- bool func = atom->string().endsWith("()");
- bool tt = (func || atom->string().contains(camelCase));
- if (tt)
- out() << "<tt>";
- if (func) {
- out() << protect(atom->string().left(atom->string().length() - 2));
- } else {
- out() << protect(atom->string());
- }
- out() << "</tt>";
- } else {
- out() << protect(atom->string());
+ QString marked = marker->markedUpSynopsis(node, relative, style);
+ QRegExp templateTag("(<[^@>]*>)");
+ if (marked.indexOf(templateTag) != -1) {
+ QString contents = protect(marked.mid(templateTag.pos(1),
+ templateTag.cap(1).length()));
+ marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
+ contents);
}
-}
-
-QString HtmlGenerator::cleanRef(const QString& ref)
-{
- QString clean;
-
- if (ref.isEmpty())
- return clean;
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
+ "<i>\\1<sub>\\2</sub></i>");
+ marked.replace("<@param>", "<i>");
+ marked.replace("</@param>", "</i>");
- clean.reserve(ref.size() + 20);
- const QChar c = ref[0];
- const uint u = c.unicode();
+ if (style == CodeMarker::Summary) {
+ marked.replace("<@name>", ""); // was "<b>"
+ marked.replace("</@name>", ""); // was "</b>"
+ }
- if ((u >= 'a' && u <= 'z') ||
- (u >= 'A' && u <= 'Z') ||
- (u >= '0' && u <= '9')) {
- clean += c;
- } else if (u == '~') {
- clean += "dtor.";
- } else if (u == '_') {
- clean += "underscore.";
+ if (style == CodeMarker::SeparateList) {
+ QRegExp extraRegExp("<@extra>.*</@extra>");
+ extraRegExp.setMinimal(true);
+ marked.replace(extraRegExp, "");
} else {
- clean += "A";
+ marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
+ marked.replace("</@extra>", "</tt>");
}
- for (int i = 1; i < (int) ref.length(); i++) {
- const QChar c = ref[i];
- const uint u = c.unicode();
- if ((u >= 'a' && u <= 'z') ||
- (u >= 'A' && u <= 'Z') ||
- (u >= '0' && u <= '9') || u == '-' ||
- u == '_' || u == ':' || u == '.') {
- clean += c;
- } else if (c.isSpace()) {
- clean += "-";
- } else if (u == '!') {
- clean += "-not";
- } else if (u == '&') {
- clean += "-and";
- } else if (u == '<') {
- clean += "-lt";
- } else if (u == '=') {
- clean += "-eq";
- } else if (u == '>') {
- clean += "-gt";
- } else if (u == '#') {
- clean += "#";
- } else {
- clean += "-";
- clean += QString::number((int)u, 16);
- }
+ if (style != CodeMarker::Detailed) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
}
- return clean;
+ out() << highlightedCode(marked, marker, relative, style, nameAlignment);
}
-QString HtmlGenerator::registerRef(const QString& ref)
+QString HtmlGenerator::highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative,
+ CodeMarker::SynopsisStyle ,
+ bool nameAlignment)
{
- QString clean = HtmlGenerator::cleanRef(ref);
+ QString src = markedCode;
+ QString html;
+ QStringRef arg;
+ QStringRef par1;
- for (;;) {
- QString& prevRef = refMap[clean.toLower()];
- if (prevRef.isEmpty()) {
- prevRef = ref;
- break;
- } else if (prevRef == ref) {
- break;
+ const QChar charLangle = '<';
+ const QChar charAt = '@';
+
+ // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
+ static const QString linkTag("link");
+ bool done = false;
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
+ if (nameAlignment && !done) {// && (i != 0)) Why was this here?
+ html += "</td><td class=\"memItemRight\" valign=\"bottom\">";
+ done = true;
+ }
+ i += 2;
+ if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
+ html += "<b>";
+ QString link = linkForNode(
+ CodeMarker::nodeForString(par1.toString()), relative);
+ addLink(link, arg, &html);
+ html += "</b>";
+ }
+ else {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.at(i++);
}
- clean += "x";
}
- return clean;
-}
-
-QString HtmlGenerator::protect(const QString& string)
-{
-#define APPEND(x) \
- if (html.isEmpty()) { \
- html = string; \
- html.truncate(i); \
- } \
- html += (x);
- QString html;
- int n = string.length();
- for (int i = 0; i < n; ++i) {
- QChar ch = string.at(i);
+ if (slow) {
+ // is this block ever used at all?
+ // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
+ src = html;
+ html = QString();
+ static const QString funcTag("func");
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
+ i += 2;
+ if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
+ QString link = linkForNode(
+ marker->resolveTarget(par1.toString(),
+ tre,
+ relative),
+ relative);
+ addLink(link, arg, &html);
+ par1 = QStringRef();
+ }
+ else {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.at(i++);
+ }
+ }
+ }
- if (ch == QLatin1Char('&')) {
- APPEND("&amp;");
- } else if (ch == QLatin1Char('<')) {
- APPEND("&lt;");
- } else if (ch == QLatin1Char('>')) {
- APPEND("&gt;");
- } else if (ch == QLatin1Char('"')) {
- APPEND("&quot;");
- } else if (ch.unicode() > 0x007F
- || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
- || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
- // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
- APPEND("&#x");
- html += QString::number(ch.unicode(), 16);
- html += QLatin1Char(';');
- } else {
- if (!html.isEmpty())
- html += ch;
+ // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
+ src = html;
+ html = QString();
+ static const QString typeTags[] = { "type", "headerfile", "func" };
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
+ i += 2;
+ bool handled = false;
+ for (int k = 0; k != 3; ++k) {
+ if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
+ par1 = QStringRef();
+ QString link = linkForNode(
+ marker->resolveTarget(arg.toString(), tre, relative),
+ relative);
+ addLink(link, arg, &html);
+ handled = true;
+ break;
+ }
+ }
+ if (!handled) {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.at(i++);
}
}
- if (!html.isEmpty())
- return html;
- return string;
+ // replace all
+ // "<@comment>" -> "<span class=\"comment\">";
+ // "<@preprocessor>" -> "<span class=\"preprocessor\">";
+ // "<@string>" -> "<span class=\"string\">";
+ // "<@char>" -> "<span class=\"char\">";
+ // "</@(?:comment|preprocessor|string|char)>" -> "</span>"
+ src = html;
+ html = QString();
+ static const QString spanTags[] = {
+ "<@comment>", "<span class=\"comment\">",
+ "<@preprocessor>", "<span class=\"preprocessor\">",
+ "<@string>", "<span class=\"string\">",
+ "<@char>", "<span class=\"char\">",
+ "</@comment>", "</span>",
+ "</@preprocessor>","</span>",
+ "</@string>", "</span>",
+ "</@char>", "</span>"
+ // "<@char>", "<font color=blue>",
+ // "</@char>", "</font>",
+ // "<@func>", "<font color=green>",
+ // "</@func>", "</font>",
+ // "<@id>", "<i>",
+ // "</@id>", "</i>",
+ // "<@keyword>", "<b>",
+ // "</@keyword>", "</b>",
+ // "<@number>", "<font color=yellow>",
+ // "</@number>", "</font>",
+ // "<@op>", "<b>",
+ // "</@op>", "</b>",
+ // "<@param>", "<i>",
+ // "</@param>", "</i>",
+ // "<@string>", "<font color=green>",
+ // "</@string>", "</font>",
+ };
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle) {
+ bool handled = false;
+ for (int k = 0; k != 8; ++k) {
+ const QString & tag = spanTags[2 * k];
+ if (tag == QStringRef(&src, i, tag.length())) {
+ html += spanTags[2 * k + 1];
+ i += tag.length();
+ handled = true;
+ break;
+ }
+ }
+ if (!handled) {
+ ++i;
+ if (src.at(i) == charAt ||
+ (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) {
+ // drop 'our' unknown tags (the ones still containing '@')
+ while (i < n && src.at(i) != QLatin1Char('>'))
+ ++i;
+ ++i;
+ }
+ else {
+ // retain all others
+ html += charLangle;
+ }
+ }
+ }
+ else {
+ html += src.at(i);
+ ++i;
+ }
+ }
-#undef APPEND
+ return html;
}
-static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
-static QRegExp funcTag("(<@func target=\"([^\"]*)\">)(.*)(</@func>)");
-static QRegExp typeTag("(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)");
-static QRegExp spanTag("</@(?:comment|preprocessor|string|char)>");
-static QRegExp unknownTag("</?@[^>]*>");
-
-bool parseArg(const QString &src,
- const QString &tag,
- int *pos,
- int n,
- QStringRef *contents,
- QStringRef *par1 = 0,
- bool debug = false)
+#else
+void HtmlGenerator::generateSectionList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
{
-#define SKIP_CHAR(c) \
- if (debug) \
- qDebug() << "looking for " << c << " at " << QString(src.data() + i, n - i); \
- if (i >= n || src[i] != c) { \
- if (debug) \
- qDebug() << " char '" << c << "' not found"; \
- return false; \
- } \
- ++i;
-
-
-#define SKIP_SPACE \
- while (i < n && src[i] == ' ') \
- ++i;
+ if (!section.members.isEmpty()) {
+ bool twoColumn = false;
+ if (style == CodeMarker::SeparateList) {
+ twoColumn = (section.members.count() >= 16);
+ }
+ else if (section.members.first()->type() == Node::Property) {
+ twoColumn = (section.members.count() >= 5);
+ }
+ if (twoColumn)
+ out() << "<p><table class=\"generic\" width=\"100%\" border=\"0\" "
+ << "cellpadding=\"0\" cellspacing=\"0\">\n"
+ << "<tr><td width=\"45%\" valign=\"top\">";
+ out() << "<ul>\n";
- int i = *pos;
- int j = i;
+ int i = 0;
+ NodeList::ConstIterator m = section.members.begin();
+ while (m != section.members.end()) {
+ if ((*m)->access() == Node::Private) {
+ ++m;
+ continue;
+ }
- // assume "<@" has been parsed outside
- //SKIP_CHAR('<');
- //SKIP_CHAR('@');
+ if (twoColumn && i == (int) (section.members.count() + 1) / 2)
+ out() << "</ul></td><td valign=\"top\"><ul>\n";
- if (tag != QStringRef(&src, i, tag.length())) {
- if (0 && debug)
- qDebug() << "tag " << tag << " not found at " << i;
- return false;
+ out() << "<li><div class=\"fn\"></div>";
+ if (style == CodeMarker::Accessors)
+ out() << "<b>";
+ generateSynopsis(*m, relative, marker, style);
+ if (style == CodeMarker::Accessors)
+ out() << "</b>";
+ out() << "</li>\n";
+ i++;
+ ++m;
+ }
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table></p>\n";
}
- if (debug)
- qDebug() << "haystack:" << src << "needle:" << tag << "i:" <<i;
-
- // skip tag
- i += tag.length();
+ if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
+ out() << "<ul>\n";
+ generateSectionInheritedList(section, relative, marker);
+ out() << "</ul>\n";
+ }
+}
- // parse stuff like: linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
- if (par1) {
- SKIP_SPACE;
- // read parameter name
- j = i;
- while (i < n && src[i].isLetter())
- ++i;
- if (src[i] == '=') {
- if (debug)
- qDebug() << "read parameter" << QString(src.data() + j, i - j);
- SKIP_CHAR('=');
- SKIP_CHAR('"');
- // skip parameter name
- j = i;
- while (i < n && src[i] != '"')
- ++i;
- *par1 = QStringRef(&src, j, i - j);
- SKIP_CHAR('"');
- SKIP_SPACE;
+void HtmlGenerator::generateSectionInheritedList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker)
+{
+ QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
+ while (p != section.inherited.end()) {
+ out() << "<li><div bar=\"2\" class=\"fn\"></div>";
+ out() << (*p).second << " ";
+ if ((*p).second == 1) {
+ out() << section.singularMember;
} else {
- if (debug)
- qDebug() << "no optional parameter found";
+ out() << section.pluralMember;
}
+ out() << " inherited from <a href=\"" << fileName((*p).first)
+ << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
+ << protect(marker->plainFullName((*p).first, relative))
+ << "</a></li>\n";
+ ++p;
}
- SKIP_SPACE;
- SKIP_CHAR('>');
+}
- // find contents up to closing "</@tag>
- j = i;
- for (; true; ++i) {
- if (i + 4 + tag.length() > n)
- return false;
- if (src[i] != '<')
- continue;
- if (src[i + 1] != '/')
- continue;
- if (src[i + 2] != '@')
- continue;
- if (tag != QStringRef(&src, i + 3, tag.length()))
- continue;
- if (src[i + 3 + tag.length()] != '>')
- continue;
- break;
+void HtmlGenerator::generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
+{
+ QString marked = marker->markedUpSynopsis(node, relative, style);
+ QRegExp templateTag("(<[^@>]*>)");
+ if (marked.indexOf(templateTag) != -1) {
+ QString contents = protect(marked.mid(templateTag.pos(1),
+ templateTag.cap(1).length()));
+ marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
+ contents);
}
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
+ marked.replace("<@param>", "<i>");
+ marked.replace("</@param>", "</i>");
- *contents = QStringRef(&src, j, i - j);
-
- i += tag.length() + 4;
-
- *pos = i;
- if (debug)
- qDebug() << " tag " << tag << " found: pos now: " << i;
- return true;
-#undef SKIP_CHAR
-}
+ if (style == CodeMarker::Summary)
+ marked.replace("@name>", "b>");
-static void addLink(const QString &linkTarget,
- const QStringRef &nestedStuff,
- QString *res)
-{
- if (!linkTarget.isEmpty()) {
- *res += "<a href=\"";
- *res += linkTarget;
- *res += "\">";
- *res += nestedStuff;
- *res += "</a>";
+ if (style == CodeMarker::SeparateList) {
+ QRegExp extraRegExp("<@extra>.*</@extra>");
+ extraRegExp.setMinimal(true);
+ marked.replace(extraRegExp, "");
+ } else {
+ marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
+ marked.replace("</@extra>", "</tt>");
}
- else {
- *res += nestedStuff;
+
+ if (style != CodeMarker::Detailed) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
}
+ out() << highlightedCode(marked, marker, relative);
}
QString HtmlGenerator::highlightedCode(const QString& markedCode,
@@ -2428,8 +2896,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
i += 2;
if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
- QString link = linkForNode(
- CodeMarker::nodeForString(par1.toString()), relative);
+ const Node* node = CodeMarker::nodeForString(par1.toString());
+ QString link = linkForNode(node, relative);
addLink(link, arg, &html);
}
else {
@@ -2442,7 +2910,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
}
}
-
if (slow) {
// is this block ever used at all?
// replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
@@ -2570,6 +3037,155 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
return html;
}
+#endif
+
+void HtmlGenerator::generateLink(const Atom* atom,
+ const Node* /* relative */,
+ CodeMarker* marker)
+{
+ static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
+
+ if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
+ // hack for C++: move () outside of link
+ int k = funcLeftParen.pos(1);
+ out() << protect(atom->string().left(k));
+ if (link.isEmpty()) {
+ if (showBrokenLinks)
+ out() << "</i>";
+ } else {
+ out() << "</a>";
+ }
+ inLink = false;
+ out() << protect(atom->string().mid(k));
+ } else if (marker->recognizeLanguage("Java")) {
+ // hack for Java: remove () and use <tt> when appropriate
+ bool func = atom->string().endsWith("()");
+ bool tt = (func || atom->string().contains(camelCase));
+ if (tt)
+ out() << "<tt>";
+ if (func) {
+ out() << protect(atom->string().left(atom->string().length() - 2));
+ } else {
+ out() << protect(atom->string());
+ }
+ out() << "</tt>";
+ } else {
+ out() << protect(atom->string());
+ }
+}
+
+QString HtmlGenerator::cleanRef(const QString& ref)
+{
+ QString clean;
+
+ if (ref.isEmpty())
+ return clean;
+
+ clean.reserve(ref.size() + 20);
+ const QChar c = ref[0];
+ const uint u = c.unicode();
+
+ if ((u >= 'a' && u <= 'z') ||
+ (u >= 'A' && u <= 'Z') ||
+ (u >= '0' && u <= '9')) {
+ clean += c;
+ } else if (u == '~') {
+ clean += "dtor.";
+ } else if (u == '_') {
+ clean += "underscore.";
+ } else {
+ clean += "A";
+ }
+
+ for (int i = 1; i < (int) ref.length(); i++) {
+ const QChar c = ref[i];
+ const uint u = c.unicode();
+ if ((u >= 'a' && u <= 'z') ||
+ (u >= 'A' && u <= 'Z') ||
+ (u >= '0' && u <= '9') || u == '-' ||
+ u == '_' || u == ':' || u == '.') {
+ clean += c;
+ } else if (c.isSpace()) {
+ clean += "-";
+ } else if (u == '!') {
+ clean += "-not";
+ } else if (u == '&') {
+ clean += "-and";
+ } else if (u == '<') {
+ clean += "-lt";
+ } else if (u == '=') {
+ clean += "-eq";
+ } else if (u == '>') {
+ clean += "-gt";
+ } else if (u == '#') {
+ clean += "#";
+ } else {
+ clean += "-";
+ clean += QString::number((int)u, 16);
+ }
+ }
+ return clean;
+}
+
+QString HtmlGenerator::registerRef(const QString& ref)
+{
+ QString clean = HtmlGenerator::cleanRef(ref);
+
+ for (;;) {
+ QString& prevRef = refMap[clean.toLower()];
+ if (prevRef.isEmpty()) {
+ prevRef = ref;
+ break;
+ } else if (prevRef == ref) {
+ break;
+ }
+ clean += "x";
+ }
+ return clean;
+}
+
+QString HtmlGenerator::protect(const QString& string)
+{
+#define APPEND(x) \
+ if (html.isEmpty()) { \
+ html = string; \
+ html.truncate(i); \
+ } \
+ html += (x);
+
+ QString html;
+ int n = string.length();
+
+ for (int i = 0; i < n; ++i) {
+ QChar ch = string.at(i);
+
+ if (ch == QLatin1Char('&')) {
+ APPEND("&amp;");
+ } else if (ch == QLatin1Char('<')) {
+ APPEND("&lt;");
+ } else if (ch == QLatin1Char('>')) {
+ APPEND("&gt;");
+ } else if (ch == QLatin1Char('"')) {
+ APPEND("&quot;");
+ } else if (ch.unicode() > 0x007F
+ || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
+ || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
+ // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
+ APPEND("&#x");
+ html += QString::number(ch.unicode(), 16);
+ html += QLatin1Char(';');
+ } else {
+ if (!html.isEmpty())
+ html += ch;
+ }
+ }
+
+ if (!html.isEmpty())
+ return html;
+ return string;
+
+#undef APPEND
+}
QString HtmlGenerator::fileBase(const Node *node)
{
@@ -2618,10 +3234,9 @@ QString HtmlGenerator::fileBase(const Node *node,
QString HtmlGenerator::fileName(const Node *node)
{
if (node->type() == Node::Fake) {
- if (static_cast<const FakeNode *>(node)->subType() == FakeNode::ExternalPage)
+ if (static_cast<const FakeNode *>(node)->subType() == Node::ExternalPage)
return node->name();
}
-
return PageGenerator::fileName(node);
}
@@ -2643,7 +3258,8 @@ QString HtmlGenerator::refForNode(const Node *node)
typedeffe = static_cast<const TypedefNode *>(node);
if (typedeffe->associatedEnum()) {
return refForNode(typedeffe->associatedEnum());
- } else {
+ }
+ else {
ref = node->name() + "-typedef";
}
break;
@@ -2651,15 +3267,27 @@ QString HtmlGenerator::refForNode(const Node *node)
func = static_cast<const FunctionNode *>(node);
if (func->associatedProperty()) {
return refForNode(func->associatedProperty());
- } else {
+ }
+ else {
ref = func->name();
if (func->overloadNumber() != 1)
ref += "-" + QString::number(func->overloadNumber());
}
break;
case Node::Property:
+#ifdef QDOC_QML
+ case Node::QmlProperty:
+#endif
ref = node->name() + "-prop";
break;
+#ifdef QDOC_QML
+ case Node::QmlSignal:
+ ref = node->name() + "-signal";
+ break;
+ case Node::QmlMethod:
+ ref = node->name() + "-method";
+ break;
+#endif
case Node::Variable:
ref = node->name() + "-var";
break;
@@ -2708,9 +3336,11 @@ QString HtmlGenerator::refForAtom(Atom *atom, const Node * /* node */)
{
if (atom->type() == Atom::SectionLeft) {
return Doc::canonicalTitle(Text::sectionHeading(atom).toString());
- } else if (atom->type() == Atom::Target) {
+ }
+ else if (atom->type() == Atom::Target) {
return Doc::canonicalTitle(atom->string());
- } else {
+ }
+ else {
return QString();
}
}
@@ -2754,7 +3384,10 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
out() << "<a name=\"" + refForNode(node) + "\"></a>";
generateSynopsis(enume, relative, marker, CodeMarker::Detailed);
out() << "<br />";
- generateSynopsis(enume->flagsType(), relative, marker, CodeMarker::Detailed);
+ generateSynopsis(enume->flagsType(),
+ relative,
+ marker,
+ CodeMarker::Detailed);
out() << "</h3>\n";
}
else {
@@ -2778,7 +3411,7 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
section.members += property->resetters();
if (!section.members.isEmpty()) {
- out() << "<p>Access functions:</p>\n";
+ out() << "<p><b>Access functions:</b></p>\n";
generateSectionList(section, node, marker, CodeMarker::Accessors);
}
}
@@ -2789,7 +3422,8 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
<< " type is a typedef for "
<< "<a href=\"qflags.html\">QFlags</a>&lt;"
<< protect(enume->name())
- << "&gt;. It stores an OR combination of " << protect(enume->name())
+ << "&gt;. It stores an OR combination of "
+ << protect(enume->name())
<< " values.</p>\n";
}
}
@@ -2803,7 +3437,8 @@ void HtmlGenerator::findAllClasses(const InnerNode *node)
if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
QString className = (*c)->name();
- if ((*c)->parent() && (*c)->parent()->type() == Node::Namespace &&
+ if ((*c)->parent() &&
+ (*c)->parent()->type() == Node::Namespace &&
!(*c)->parent()->name().isEmpty())
className = (*c)->parent()->name()+"::"+className;
@@ -2811,6 +3446,9 @@ void HtmlGenerator::findAllClasses(const InnerNode *node)
if ((*c)->status() == Node::Compat) {
compatClasses.insert(className, *c);
}
+ else if ((*c)->status() == Node::Obsolete) {
+ obsoleteClasses.insert(className, *c);
+ }
else {
nonCompatClasses.insert(className, *c);
if ((*c)->status() == Node::Main)
@@ -2851,7 +3489,7 @@ void HtmlGenerator::findAllFunctions(const InnerNode *node)
const FunctionNode *func = static_cast<const FunctionNode *>(*c);
if (func->status() > Node::Obsolete && func->metaness() != FunctionNode::Ctor
&& func->metaness() != FunctionNode::Dtor) {
- funcIndex[(*c)->name()].insert((*c)->parent()->name(), *c);
+ funcIndex[(*c)->name()].insert(tre->fullDocumentName((*c)->parent()), *c);
}
}
}
@@ -2901,7 +3539,7 @@ void HtmlGenerator::findAllNamespaces(const InnerNode *node)
}
}
-#ifdef ZZZ_QDOC_QML
+#ifdef ZZZ_QDOC_QML
/*!
This function finds all the qml element nodes and
stores them in a map for later use.
@@ -2912,24 +3550,16 @@ void HtmlGenerator::findAllQmlClasses(const InnerNode *node)
while (c != node->childNodes().constEnd()) {
if ((*c)->type() == Node::Fake) {
const FakeNode* fakeNode = static_cast<const FakeNode *>(*c);
- if (fakeNode->subType() == FakeNode::QmlClass) {
- const QmlNode* qmlNode = static_cast<const QmlNode*>(fakeNode);
- //qDebug() << "HtmlGenerator: QML CLASS" << qmlNode->name();
+ if (fakeNode->subType() == Node::QmlClass) {
+ const QmlClassNode* qmlNode =
+ static_cast<const QmlClassNode*>(fakeNode);
const Node* n = qmlNode->classNode();
- if (n)
- //qDebug() << " FOUND IT!" << n->name();
}
qmlClasses.insert(fakeNode->name(),*c);
}
++c;
}
}
-#endif
-
-#if 0
- else if ((*c)->isInnerNode()) {
- findAllClasses(static_cast<InnerNode *>(*c));
- }
#endif
int HtmlGenerator::hOffset(const Node *node)
@@ -3007,10 +3637,11 @@ const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node)
QString HtmlGenerator::getLink(const Atom *atom,
const Node *relative,
CodeMarker *marker,
- const Node *node)
+ const Node** node)
{
QString link;
- node = 0;
+ *node = 0;
+ inObsoleteLink = false;
if (atom->string().contains(":") &&
(atom->string().startsWith("file:")
@@ -3034,40 +3665,86 @@ QString HtmlGenerator::getLink(const Atom *atom,
QString first = path.first().trimmed();
if (first.isEmpty()) {
- node = relative;
+ *node = relative;
}
else if (first.endsWith(".html")) {
- node = tre->root()->findNode(first, Node::Fake);
+ *node = tre->root()->findNode(first, Node::Fake);
}
else {
- node = marker->resolveTarget(first, tre, relative);
- if (!node)
- node = tre->findFakeNodeByTitle(first);
- if (!node)
- node = tre->findUnambiguousTarget(first, targetAtom);
+ *node = marker->resolveTarget(first, tre, relative);
+ if (!*node)
+ *node = tre->findFakeNodeByTitle(first);
+ if (!*node)
+ *node = tre->findUnambiguousTarget(first, targetAtom);
}
- if (node) {
- if (!node->url().isEmpty())
- return node->url();
+ if (*node) {
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
else
path.removeFirst();
}
else {
- node = relative;
+ *node = relative;
+ }
+
+ 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::Fake) {
+ const FakeNode* fake = static_cast<const FakeNode*>(relative);
+ if (fake->title().startsWith("Porting"))
+ porting = true;
+ }
+ QString name = marker->plainFullName(relative);
+ 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;
+ }
+#if 0
+ qDebug() << "Link to Obsolete entity"
+ << (*node)->name();
+ qDebug() << " relative entity"
+ << relative->name();
+#endif
+ }
+ }
+ }
+ else {
+ qDebug() << "Link to Obsolete entity"
+ << (*node)->name() << "no relative";
+ }
+ }
+#if 0
+ else if ((*node)->status() == Node::Deprecated) {
+ qDebug() << "Link to Deprecated entity";
+ }
+ else if ((*node)->status() == Node::Internal) {
+ qDebug() << "Link to Internal entity";
+ }
+ //else
+ //qDebug() << "Node Status:" << (*node)->status();
+#endif
}
while (!path.isEmpty()) {
- targetAtom = tre->findTarget(path.first(), node);
+ targetAtom = tre->findTarget(path.first(), *node);
if (targetAtom == 0)
break;
path.removeFirst();
}
if (path.isEmpty()) {
- link = linkForNode(node, relative);
+ link = linkForNode(*node, relative);
if (targetAtom)
- link += "#" + refForAtom(targetAtom, node);
+ link += "#" + refForAtom(targetAtom, *node);
}
}
return link;
@@ -3186,10 +3863,225 @@ void HtmlGenerator::endLink()
out() << "</i>";
}
else {
+ if (inObsoleteLink) {
+ out() << "<sup>(obsolete)</sup>";
+ }
out() << "</a>";
}
}
inLink = false;
+ inObsoleteLink = false;
}
QT_END_NAMESPACE
+
+#ifdef QDOC_QML
+
+/*!
+ Generates the summary for for the \a section. Only used for
+ sections of QML element documentation.
+
+ Currently handles only the QML property group.
+ */
+void HtmlGenerator::generateQmlSummary(const Section& section,
+ const Node *relative,
+ CodeMarker *marker)
+{
+ if (!section.members.isEmpty()) {
+ NodeList::ConstIterator m;
+ int count = section.members.size();
+ bool twoColumn = false;
+ if (section.members.first()->type() == Node::QmlProperty) {
+ twoColumn = (count >= 5);
+ }
+ if (twoColumn)
+ out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""
+ " cellspacing=\"0\">\n"
+ << "<tr><td width=\"45%\" valign=\"top\">";
+ out() << "<ul>\n";
+
+ int row = 0;
+ m = section.members.begin();
+ while (m != section.members.end()) {
+ if (twoColumn && row == (int) (count + 1) / 2)
+ out() << "</ul></td><td valign=\"top\"><ul>\n";
+ out() << "<li><div class=\"fn\"></div>";
+ generateQmlItem(*m,relative,marker,true);
+ out() << "</li>\n";
+ row++;
+ ++m;
+ }
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table></p>\n";
+ }
+}
+
+/*!
+ Outputs the html detailed documentation for a section
+ on a QML element reference page.
+ */
+void HtmlGenerator::generateDetailedQmlMember(const Node *node,
+ const InnerNode *relative,
+ CodeMarker *marker)
+{
+ const QmlPropertyNode* qpn = 0;
+ generateMacRef(node, marker);
+ out() << "<div class=\"qmlitem\">";
+ if (node->subType() == Node::QmlPropertyGroup) {
+ const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ NodeList::ConstIterator p = qpgn->childNodes().begin();
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+
+ while (p != qpgn->childNodes().end()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ qpn = static_cast<const QmlPropertyNode*>(*p);
+ out() << "<tr><td>";
+ out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
+ generateQmlItem(qpn, relative, marker, false);
+ out() << "</td></tr>";
+ if (qpgn->isDefault()) {
+ out() << "</table>"
+ << "</div></div>"
+ << "<div class=\"qmlitem\">"
+ << "<div class=\"qmlproto\">"
+ << "<table class=\"qmlname\">"
+ << "<tr><td><font color=\"green\">"
+ << "default</font></td></tr>";
+ }
+ }
+ ++p;
+ }
+ out() << "</table>";
+ out() << "</div>";
+ }
+ else if (node->type() == Node::QmlSignal) {
+ const QmlSignalNode* qsn = static_cast<const QmlSignalNode*>(node);
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+ out() << "<tr><td>";
+ out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
+ generateQmlItem(qsn,relative,marker,false);
+ out() << "</td></tr>";
+ out() << "</table>";
+ out() << "</div>";
+ }
+ else if (node->type() == Node::QmlMethod) {
+ const QmlMethodNode* qmn = static_cast<const QmlMethodNode*>(node);
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+ out() << "<tr><td>";
+ out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
+ generateQmlItem(qmn,relative,marker,false);
+ out() << "</td></tr>";
+ out() << "</table>";
+ out() << "</div>";
+ }
+ out() << "<div class=\"qmldoc\">";
+ generateStatus(node, marker);
+ generateBody(node, marker);
+ generateThreadSafeness(node, marker);
+ generateSince(node, marker);
+ generateAlsoList(node, marker);
+ out() << "</div>";
+ out() << "</div>";
+}
+
+/*!
+ Output the "Inherits" line for the QML element,
+ if there should be one.
+ */
+void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn,
+ CodeMarker* marker)
+{
+ if (cn && !cn->links().empty()) {
+ if (cn->links().contains(Node::InheritsLink)) {
+ QPair<QString,QString> linkPair;
+ linkPair = cn->links()[Node::InheritsLink];
+ QStringList strList(linkPair.first);
+ const Node* n = tre->findNode(strList,Node::Fake);
+ if (n && n->subType() == Node::QmlClass) {
+ const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
+ out() << "<p style=\"text-align: center\">";
+ Text text;
+ text << "[Inherits ";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, linkPair.second);
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << "]";
+ generateText(text, cn, marker);
+ out() << "</p>";
+ }
+// else
+// qDebug() << "generateQmlInherits(): "
+// << "Inherited element not documented -->"
+// << linkPair.first;
+ }
+ }
+}
+
+/*!
+ Output the "[Xxx instantiates the C++ class QFxXxx]"
+ line for the QML element, if there should be one.
+
+ If there is no class node, or if the class node status
+ is set to Node::Internal, do nothing.
+ */
+void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
+ CodeMarker* marker)
+{
+ const ClassNode* cn = qcn->classNode();
+ if (cn && (cn->status() != Node::Internal)) {
+ out() << "<p style=\"text-align: center\">";
+ Text text;
+ text << "[";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, qcn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << " instantiates the C++ class ";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, cn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << "]";
+ generateText(text, qcn, marker);
+ out() << "</p>";
+ }
+}
+
+/*!
+ Output the "[QFxXxx is instantiated by QML element Xxx]"
+ line for the class, if there should be one.
+
+ If there is no QML element, or if the class node status
+ is set to Node::Internal, do nothing.
+ */
+void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn,
+ CodeMarker* marker)
+{
+ if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
+ const Node* n = tre->root()->findNode(cn->qmlElement(),Node::Fake);
+ if (n && n->subType() == Node::QmlClass) {
+ out() << "<p style=\"text-align: center\">";
+ Text text;
+ text << "[";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, cn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << " is instantiated by QML element ";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(n));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, n->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << "]";
+ generateText(text, cn, marker);
+ out() << "</p>";
+ }
+ }
+}
+
+#endif
diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h
index 8ff32f8..c22fe20 100644
--- a/tools/qdoc3/htmlgenerator.h
+++ b/tools/qdoc3/htmlgenerator.h
@@ -46,6 +46,8 @@
#ifndef HTMLGENERATOR_H
#define HTMLGENERATOR_H
+#define QDOC_NAME_ALIGNMENT
+
#include <qmap.h>
#include <qregexp.h>
@@ -139,27 +141,69 @@ class HtmlGenerator : public PageGenerator
void generateFunctionIndex(const Node *relative, CodeMarker *marker);
void generateLegaleseList(const Node *relative, CodeMarker *marker);
void generateOverviewList(const Node *relative, CodeMarker *marker);
- void generateSynopsis(const Node *node,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style);
void generateSectionList(const Section& section,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style);
+#ifdef QDOC_QML
+ void generateQmlSummary(const Section& section,
+ const Node *relative,
+ CodeMarker *marker);
+ void generateQmlItem(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ bool summary);
+ void generateDetailedQmlMember(const Node *node,
+ const InnerNode *relative,
+ CodeMarker *marker);
+ void generateQmlInherits(const QmlClassNode* cn, CodeMarker* marker);
+ void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker);
+ void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker);
+#endif
+#ifdef QDOC_NAME_ALIGNMENT
+ void generateSection(const NodeList& nl,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style);
+ void generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style,
+ bool nameAlignment = false);
+ void generateSectionInheritedList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ bool nameAlignment = false);
+ QString highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative,
+ CodeMarker::SynopsisStyle style = CodeMarker::Accessors,
+ bool nameAlignment = false);
+#else
+ void generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style);
void generateSectionInheritedList(const Section& section,
const Node *relative,
CodeMarker *marker);
+ QString highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative);
+#endif
void generateFullName(const Node *apparentNode,
const Node *relative,
CodeMarker *marker,
const Node *actualNode = 0);
- void generateDetailedMember(const Node *node, const InnerNode *relative, CodeMarker *marker);
- void generateLink(const Atom *atom, const Node *relative, CodeMarker *marker);
+ void generateDetailedMember(const Node *node,
+ const InnerNode *relative,
+ CodeMarker *marker);
+ void generateLink(const Atom *atom,
+ const Node *relative,
+ CodeMarker *marker);
void generateStatus(const Node *node, CodeMarker *marker);
QString registerRef(const QString& ref);
- QString highlightedCode(const QString& markedCode, CodeMarker *marker, const Node *relative);
QString fileBase(const Node *node);
#if 0
QString fileBase(const Node *node, const SectionIterator& section);
@@ -177,7 +221,7 @@ class HtmlGenerator : public PageGenerator
virtual QString getLink(const Atom *atom,
const Node *relative,
CodeMarker *marker,
- const Node *node = 0);
+ const Node** node);
virtual void generateDcf(const QString &fileBase,
const QString &startPage,
const QString &title, DcfSection &dcfRoot);
@@ -205,6 +249,7 @@ class HtmlGenerator : public PageGenerator
DcfSection dcfQmakeRoot;
HelpProjectWriter *helpProjectWriter;
bool inLink;
+ bool inObsoleteLink;
bool inContents;
bool inSectionHeading;
bool inTableHeader;
@@ -226,11 +271,13 @@ class HtmlGenerator : public PageGenerator
QStringList customHeadElements;
const Tree *tre;
bool slow;
+ bool obsoleteLinks;
QMap<QString, QMap<QString, const Node *> > moduleClassMap;
QMap<QString, QMap<QString, const Node *> > moduleNamespaceMap;
QMap<QString, const Node *> nonCompatClasses;
QMap<QString, const Node *> mainClasses;
QMap<QString, const Node *> compatClasses;
+ QMap<QString, const Node *> obsoleteClasses;
QMap<QString, const Node *> namespaceIndex;
QMap<QString, const Node *> serviceClasses;
#ifdef QDOC_QML
diff --git a/tools/qdoc3/jambiapiparser.cpp b/tools/qdoc3/jambiapiparser.cpp
index f981e6d..70e9260 100644
--- a/tools/qdoc3/jambiapiparser.cpp
+++ b/tools/qdoc3/jambiapiparser.cpp
@@ -234,8 +234,9 @@ void JambiApiParser::doneParsingSourceFiles(Tree * /* tree */)
foreach (Node *cppNode, cppTre->root()->childNodes()) {
if (cppNode->type() == Node::Fake) {
FakeNode *cppFake = static_cast<FakeNode *>(cppNode);
- if (cppFake->subType() == FakeNode::Page) {
- FakeNode *javaFake = new FakeNode(javaTre->root(), cppFake->name(),
+ if (cppFake->subType() == Node::Page) {
+ FakeNode *javaFake = new FakeNode(javaTre->root(),
+ cppFake->name(),
cppFake->subType());
javaFake->setModuleName("com.trolltech.qt"); // ### hard-coded
javaFake->setTitle(cppFake->title());
diff --git a/tools/qdoc3/javadocgenerator.cpp b/tools/qdoc3/javadocgenerator.cpp
index b32425c..294877b 100644
--- a/tools/qdoc3/javadocgenerator.cpp
+++ b/tools/qdoc3/javadocgenerator.cpp
@@ -272,9 +272,10 @@ void JavadocGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker
HtmlGenerator::generateFakeNode(fake, marker);
}
-void JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
+bool JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
{
HtmlGenerator::generateText(text, relative, marker);
+ return true;
}
void JavadocGenerator::generateBody(const Node *node, CodeMarker *marker)
diff --git a/tools/qdoc3/javadocgenerator.h b/tools/qdoc3/javadocgenerator.h
index ba9b15d..5431c38 100644
--- a/tools/qdoc3/javadocgenerator.h
+++ b/tools/qdoc3/javadocgenerator.h
@@ -68,7 +68,7 @@ protected:
void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
void generateFakeNode( const FakeNode *fake, CodeMarker *marker );
- void generateText( const Text& text, const Node *relative, CodeMarker *marker );
+ bool generateText( const Text& text, const Node *relative, CodeMarker *marker );
void generateBody( const Node *node, CodeMarker *marker );
void generateAlsoList( const Node *node, CodeMarker *marker );
diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp
index e3b2f08..9338203 100644
--- a/tools/qdoc3/main.cpp
+++ b/tools/qdoc3/main.cpp
@@ -95,11 +95,11 @@ static const struct {
};
static bool slow = false;
+static bool showInternal = false;
+static bool obsoleteLinks = false;
static QStringList defines;
static QHash<QString, Tree *> trees;
-//static int doxygen = 0;
-
/*!
Find the Tree for language \a lang and return a pointer to it.
If there is no Tree for language \a lang in the Tree table, add
@@ -122,14 +122,18 @@ static void printHelp()
{
Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
"Options:\n"
- " -help "
+ " -help "
"Display this information and exit\n"
- " -version "
+ " -version "
"Display version of qdoc and exit\n"
- " -D<name> "
+ " -D<name> "
"Define <name> as a macro while parsing sources\n"
- " -slow "
- "Turn on features that slow down qdoc") );
+ " -slow "
+ "Turn on features that slow down qdoc\n"
+ " -showinternal "
+ "Include stuff marked internal\n"
+ " -obsoletelinks "
+ "Report links from obsolete items to non-obsolete items") );
}
/*!
@@ -162,6 +166,10 @@ static void processQdocconfFile(const QString &fileName)
++i;
}
config.setStringList(CONFIG_SLOW, QStringList(slow ? "true" : "false"));
+ config.setStringList(CONFIG_SHOWINTERNAL,
+ QStringList(showInternal ? "true" : "false"));
+ config.setStringList(CONFIG_OBSOLETELINKS,
+ QStringList(obsoleteLinks ? "true" : "false"));
/*
With the default configuration values in place, load
@@ -224,18 +232,6 @@ static void processQdocconfFile(const QString &fileName)
QString lang = config.getString(CONFIG_LANGUAGE);
Location langLocation = config.lastLocation();
-#ifdef QDOC2DOX
- // qdoc -> doxygen
- if (doxygen == 2) {
- qDebug() << "READING anchors.txt";
- DoxWriter::readAnchors();
- qDebug() << "READING title maps";
- DoxWriter::readTitles();
- qDebug() << "READING member multimaps";
- DoxWriter::readMembers();
- }
-#endif
-
/*
Initialize the tree where all the parsed sources will be stored.
The tree gets built as the source files are parsed, and then the
@@ -322,17 +318,6 @@ static void processQdocconfFile(const QString &fileName)
tree->resolveGroups();
tree->resolveTargets();
-#ifdef QDOC2DOX
- // qdoc -> doxygen
- if (doxygen == 1) {
- DoxWriter::writeAnchors();
- DoxWriter::writeTitles();
- DoxWriter::writeMembers();
- }
-
- if (doxygen == 0) {
-#endif
-
/*
Now the tree has been built, and all the stuff that needed
resolving has been resolved. Now it is time to traverse
@@ -351,17 +336,13 @@ static void processQdocconfFile(const QString &fileName)
/*
Generate the XML tag file, if it was requested.
*/
+
QString tagFile = config.getString(CONFIG_TAGFILE);
if (!tagFile.isEmpty())
tree->generateTagFile(tagFile);
-
+
tree->setVersion("");
Generator::terminate();
-
-#ifdef QDOC2DOX
- }
-#endif
-
CodeParser::terminate();
CodeMarker::terminate();
CppToQsConverter::terminate();
@@ -372,7 +353,6 @@ static void processQdocconfFile(const QString &fileName)
foreach (QTranslator *translator, translators)
delete translator;
-
delete tree;
}
@@ -456,26 +436,12 @@ int main(int argc, char **argv)
else if (opt == "-slow") {
slow = true;
}
-
-#ifdef QDOC2DOX
- else if (opt == "-doxygen1") {
- // qdoc -> doxygen
- // Don't use this; it isn't ready yet.
- // Now it's a fossil.
- qDebug() << "doxygen pass 1";
- doxygen = 1;
- DoxWriter::setDoxPass(1);
+ else if (opt == "-showinternal") {
+ showInternal = true;
}
- else if (opt == "-doxygen2") {
- // qdoc -> doxygen
- // Don't use this; it isn't ready yet.
- // Now it's a fossil.
- qDebug() << "doxygen pass 2";
- doxygen = 2;
- DoxWriter::setDoxPass(2);
+ else if (opt == "-obsoletelinks") {
+ obsoleteLinks = true;
}
-#endif
-
else {
qdocFiles.append(opt);
}
diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp
index 0f9468a..610249d 100644
--- a/tools/qdoc3/node.cpp
+++ b/tools/qdoc3/node.cpp
@@ -43,6 +43,7 @@
node.cpp
*/
+#include <QtCore>
#include "node.h"
QT_BEGIN_NAMESPACE
@@ -113,6 +114,9 @@ void Node::setRelates(InnerNode *pseudoParent)
}
/*!
+ This function creates a pair that describes a link.
+ The pair is composed from \a link and \a desc. The
+ \a linkType is the map index the pair is filed under.
*/
void Node::setLink(LinkType linkType, const QString &link, const QString &desc)
{
@@ -623,7 +627,7 @@ void InnerNode::removeRelated(Node *pseudoChild)
*/
/*!
- Returns false because this is an InnerNode.
+ Returns false because this is a LeafNode.
*/
bool LeafNode::isInnerNode() const
{
@@ -713,9 +717,11 @@ void ClassNode::fixBaseClasses()
*/
/*!
+ The type of a FakeNode is Fake, and it has a \a subtype,
+ which specifies the type of FakeNode.
*/
-FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subType)
- : InnerNode(Fake, parent, name), sub(subType)
+FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
+ : InnerNode(Fake, parent, name), sub(subtype)
{
}
@@ -868,6 +874,18 @@ void FunctionNode::setOverload(bool overlode)
}
/*!
+ Sets the function node's reimplementation flag to \a r.
+ When \a r is true, it is supposed to mean that this function
+ is a reimplementation of a virtual function in a base class,
+ but it really just means the \e reimp command was seen in the
+ qdoc comment.
+ */
+void FunctionNode::setReimp(bool r)
+{
+ reimp = r;
+}
+
+/*!
*/
void FunctionNode::addParameter(const Parameter& parameter)
{
@@ -1021,4 +1039,98 @@ bool TargetNode::isInnerNode() const
return false;
}
+#ifdef QDOC_QML
+/*!
+ Constructor for the Qml class node.
+ */
+QmlClassNode::QmlClassNode(InnerNode *parent,
+ const QString& name,
+ const ClassNode* cn)
+ : FakeNode(parent, name, QmlClass), cnode(cn)
+{
+ setTitle("QML " + name + " Element Reference");
+}
+
+/*!
+ The base file name for this kind of node has "qml_"
+ prepended to it.
+
+ But not yet. Still testing.
+ */
+QString QmlClassNode::fileBase() const
+{
+#if 0
+ if (Node::fileBase() == "item")
+ qDebug() << "FILEBASE: qmlitem" << name();
+ return "qml_" + Node::fileBase();
+#endif
+ return Node::fileBase();
+}
+
+/*!
+ Constructor for the Qml property group node. \a parent is
+ always a QmlClassNode.
+ */
+QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name)
+ : FakeNode(parent, name, QmlPropertyGroup), isdefault(false)
+{
+ // nothing.
+}
+
+/*!
+ Constructor for the QML property node.
+ */
+QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
+ const QString& name,
+ const QString& type)
+ : LeafNode(QmlProperty, parent, name),
+ dt(type),
+ sto(Trool_Default),
+ des(Trool_Default)
+{
+ // nothing.
+}
+
+/*!
+ I don't know what this is.
+ */
+QmlPropertyNode::Trool QmlPropertyNode::toTrool(bool boolean)
+{
+ return boolean ? Trool_True : Trool_False;
+}
+
+/*!
+ I don't know what this is either.
+ */
+bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue)
+{
+ switch (troolean) {
+ case Trool_True:
+ return true;
+ case Trool_False:
+ return false;
+ default:
+ return defaultValue;
+ }
+}
+
+/*!
+ Constructor for the QML signal node.
+ */
+QmlSignalNode::QmlSignalNode(QmlClassNode *parent, const QString& name)
+ : LeafNode(QmlSignal, parent, name)
+{
+ // nothing.
+}
+
+/*!
+ Constructor for the QML method node.
+ */
+QmlMethodNode::QmlMethodNode(QmlClassNode *parent, const QString& name)
+ : LeafNode(QmlMethod, parent, name)
+{
+ // nothing.
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index 0a671b37d..17ec447 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -72,7 +72,31 @@ class Node
Function,
Property,
Variable,
+#ifdef QDOC_QML
+ Target,
+ QmlProperty,
+ QmlSignal,
+ QmlMethod
+#else
Target
+#endif
+ };
+
+ enum SubType {
+ NoSubType,
+ Example,
+ HeaderFile,
+ File,
+ Group,
+ Module,
+ Page,
+#ifdef QDOC_QML
+ ExternalPage,
+ QmlClass,
+ QmlPropertyGroup
+#else
+ ExternalPage
+#endif
};
enum Access { Public, Protected, Private };
@@ -99,7 +123,8 @@ class Node
NextLink,
PreviousLink,
ContentsLink,
- IndexLink /*,
+ IndexLink,
+ InheritsLink /*,
GlossaryLink,
CopyrightLink,
ChapterLink,
@@ -123,7 +148,9 @@ class Node
void setTemplateStuff(const QString &templateStuff) { tpl = templateStuff; }
virtual bool isInnerNode() const = 0;
+ virtual bool isReimp() const { return false; }
Type type() const { return typ; }
+ virtual SubType subType() const { return NoSubType; }
InnerNode *parent() const { return par; }
InnerNode *relates() const { return rel; }
const QString& name() const { return nam; }
@@ -143,7 +170,7 @@ class Node
void clearRelated() { rel = 0; }
- QString fileBase() const;
+ virtual QString fileBase() const;
protected:
Node(Type type, InnerNode *parent, const QString& name);
@@ -180,7 +207,7 @@ typedef QList<Node *> NodeList;
class InnerNode : public Node
{
public:
- ~InnerNode();
+ virtual ~InnerNode();
Node *findNode(const QString& name);
Node *findNode(const QString& name, Type type);
@@ -202,6 +229,7 @@ class InnerNode : public Node
const EnumNode *findEnumNodeForValue(const QString &enumValue) const;
const NodeList & childNodes() const { return children; }
const NodeList & relatedNodes() const { return related; }
+ int count() const { return children.size(); }
int overloadNumber(const FunctionNode *func) const;
int numOverloads(const QString& funcName) const;
NodeList overloads(const QString &funcName) const;
@@ -231,17 +259,19 @@ class LeafNode : public Node
{
public:
LeafNode();
+ virtual ~LeafNode() { }
virtual bool isInnerNode() const;
protected:
- LeafNode(Type type, InnerNode *parent, const QString& name);
+ LeafNode(Type type, InnerNode* parent, const QString& name);
};
class NamespaceNode : public InnerNode
{
public:
NamespaceNode(InnerNode *parent, const QString& name);
+ virtual ~NamespaceNode() { }
};
class ClassNode;
@@ -265,6 +295,7 @@ class ClassNode : public InnerNode
{
public:
ClassNode(InnerNode *parent, const QString& name);
+ virtual ~ClassNode() { }
void addBaseClass(Access access,
ClassNode *node,
@@ -279,29 +310,23 @@ class ClassNode : public InnerNode
QString serviceName() const { return sname; }
void setServiceName(const QString& value) { sname = value; }
+ QString qmlElement() const { return qmlelement; }
+ void setQmlElement(const QString& value) { qmlelement = value; }
private:
QList<RelatedClass> bas;
QList<RelatedClass> der;
bool hidden;
QString sname;
+ QString qmlelement;
};
class FakeNode : public InnerNode
{
public:
- enum SubType {
- Example,
- HeaderFile,
- File,
- Group,
- Module,
- Page,
- ExternalPage,
- QmlClass
- };
FakeNode(InnerNode *parent, const QString& name, SubType subType);
+ virtual ~FakeNode() { }
void setTitle(const QString &title) { tle = title; }
void setSubTitle(const QString &subTitle) { stle = subTitle; }
@@ -320,18 +345,85 @@ class FakeNode : public InnerNode
NodeList gr;
};
-class QmlNode : public FakeNode
+#ifdef QDOC_QML
+class QmlClassNode : public FakeNode
{
public:
- QmlNode(InnerNode *parent, const QString& name, const ClassNode* cn)
- : FakeNode(parent, name, QmlClass), cnode(cn) { }
+ QmlClassNode(InnerNode *parent,
+ const QString& name,
+ const ClassNode* cn);
+ virtual ~QmlClassNode() { }
const ClassNode* classNode() const { return cnode; }
+ virtual QString fileBase() const;
private:
const ClassNode* cnode;
};
+class QmlPropGroupNode : public FakeNode
+{
+ public:
+ QmlPropGroupNode(QmlClassNode* parent, const QString& name);
+ virtual ~QmlPropGroupNode() { }
+
+ const QString& element() const { return name(); }
+ void setDefault() { isdefault = true; }
+ bool isDefault() const { return isdefault; }
+
+ private:
+ bool isdefault;
+};
+
+class QmlPropertyNode : public LeafNode
+{
+ public:
+ QmlPropertyNode(QmlPropGroupNode* parent,
+ const QString& name,
+ const QString& type);
+ virtual ~QmlPropertyNode() { }
+
+ void setDataType(const QString& dataType) { dt = dataType; }
+ void setStored(bool stored) { sto = toTrool(stored); }
+ void setDesignable(bool designable) { des = toTrool(designable); }
+
+ const QString &dataType() const { return dt; }
+ QString qualifiedDataType() const { return dt; }
+ bool isStored() const { return fromTrool(sto,true); }
+ bool isDesignable() const { return fromTrool(des,false); }
+
+ const QString& element() const { return parent()->name(); }
+
+ private:
+ enum Trool { Trool_True, Trool_False, Trool_Default };
+
+ static Trool toTrool(bool boolean);
+ static bool fromTrool(Trool troolean, bool defaultValue);
+
+ QString dt;
+ Trool sto;
+ Trool des;
+};
+
+class QmlSignalNode : public LeafNode
+{
+ public:
+ QmlSignalNode(QmlClassNode* parent, const QString& name);
+ virtual ~QmlSignalNode() { }
+
+ const QString& element() const { return parent()->name(); }
+};
+
+class QmlMethodNode : public LeafNode
+{
+ public:
+ QmlMethodNode(QmlClassNode* parent, const QString& name);
+ virtual ~QmlMethodNode() { }
+
+ const QString& element() const { return parent()->name(); }
+};
+#endif
+
class EnumItem
{
public:
@@ -357,6 +449,7 @@ class EnumNode : public LeafNode
{
public:
EnumNode(InnerNode *parent, const QString& name);
+ virtual ~EnumNode() { }
void addItem(const EnumItem& item);
void setFlagsType(TypedefNode *typedeff);
@@ -377,6 +470,7 @@ class TypedefNode : public LeafNode
{
public:
TypedefNode(InnerNode *parent, const QString& name);
+ virtual ~TypedefNode() { }
const EnumNode *associatedEnum() const { return ae; }
@@ -437,6 +531,7 @@ class FunctionNode : public LeafNode
enum Virtualness { NonVirtual, ImpureVirtual, PureVirtual };
FunctionNode(InnerNode *parent, const QString &name);
+ virtual ~FunctionNode() { }
void setReturnType(const QString& returnType) { rt = returnType; }
void setMetaness(Metaness metaness) { met = metaness; }
@@ -444,6 +539,7 @@ class FunctionNode : public LeafNode
void setConst(bool conste) { con = conste; }
void setStatic(bool statique) { sta = statique; }
void setOverload(bool overlode);
+ void setReimp(bool r);
void addParameter(const Parameter& parameter);
inline void setParameters(const QList<Parameter>& parameters);
void borrowParameterNames(const FunctionNode *source);
@@ -458,6 +554,7 @@ class FunctionNode : public LeafNode
bool isConst() const { return con; }
bool isStatic() const { return sta; }
bool isOverload() const { return ove; }
+ bool isReimp() const { return reimp; }
int overloadNumber() const;
int numOverloads() const;
const QList<Parameter>& parameters() const { return params; }
@@ -483,6 +580,7 @@ class FunctionNode : public LeafNode
bool con : 1;
bool sta : 1;
bool ove : 1;
+ bool reimp: 1;
QList<Parameter> params;
const FunctionNode *rf;
const PropertyNode *ap;
@@ -496,6 +594,7 @@ class PropertyNode : public LeafNode
enum { NumFunctionRoles = Resetter + 1 };
PropertyNode(InnerNode *parent, const QString& name);
+ virtual ~PropertyNode() { }
void setDataType(const QString& dataType) { dt = dataType; }
void addFunction(FunctionNode *function, FunctionRole role);
@@ -553,6 +652,7 @@ class VariableNode : public LeafNode
{
public:
VariableNode(InnerNode *parent, const QString &name);
+ virtual ~VariableNode() { }
void setLeftType(const QString &leftType) { lt = leftType; }
void setRightType(const QString &rightType) { rt = rightType; }
@@ -578,6 +678,7 @@ class TargetNode : public LeafNode
{
public:
TargetNode(InnerNode *parent, const QString& name);
+ virtual ~TargetNode() { }
virtual bool isInnerNode() const;
};
diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp
index 06ff398..8715f4a 100644
--- a/tools/qdoc3/pagegenerator.cpp
+++ b/tools/qdoc3/pagegenerator.cpp
@@ -81,30 +81,50 @@ QString PageGenerator::fileBase(const Node *node)
{
if (node->relates())
node = node->relates();
- else if (!node->isInnerNode())
+ else if (!node->isInnerNode()) {
node = node->parent();
+#ifdef QDOC_QML
+ if (node->subType() == Node::QmlPropertyGroup) {
+ node = node->parent();
+ }
+#endif
+ }
QString base = node->doc().baseName();
if (!base.isEmpty())
return base;
- const Node *p = node;
-
- forever {
- base.prepend(p->name());
+ const Node *p = node;
+
+ forever {
+ base.prepend(p->name());
+#ifdef QDOC_QML
+ /*
+ To avoid file name conflicts in the html directory,
+ we prepend "qml-" to the file name of QML element doc
+ files.
+ */
+ if ((p->subType() == Node::QmlClass) ||
+ (p->subType() == Node::QmlPropertyGroup))
+ base.prepend("qml-");
+ else if ((p->type() == Node::QmlProperty) ||
+ (p->type() == Node::QmlSignal) ||
+ (p->type() == Node::QmlMethod))
+ base.prepend("qml-");
+#endif
const Node *pp = p->parent();
if (!pp || pp->name().isEmpty() || pp->type() == Node::Fake)
- break;
+ break;
base.prepend(QLatin1Char('-'));
p = pp;
- }
-
- if (node->type() == Node::Fake) {
+ }
+
+ if (node->type() == Node::Fake) {
#ifdef QDOC2_COMPAT
- if (base.endsWith(".html"))
- base.truncate(base.length() - 5);
+ if (base.endsWith(".html"))
+ base.truncate(base.length() - 5);
#endif
- }
+ }
// the code below is effectively equivalent to:
// base.replace(QRegExp("[^A-Za-z0-9]+"), " ");
@@ -126,7 +146,8 @@ QString PageGenerator::fileBase(const Node *node)
if ((u >= 'a' && u <= 'z') || (u >= '0' && u <= '9')) {
res += QLatin1Char(u);
begun = true;
- } else if (begun) {
+ }
+ else if (begun) {
res += QLatin1Char('-');
begun = false;
}
@@ -187,8 +208,12 @@ void PageGenerator::generateInnerNode(const InnerNode *node,
if (node->type() == Node::Fake) {
const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
- if (fakeNode->subType() == FakeNode::ExternalPage)
+ if (fakeNode->subType() == Node::ExternalPage)
+ return;
+#ifdef QDOC_QML
+ if (fakeNode->subType() == Node::QmlPropertyGroup)
return;
+#endif
}
if (node->parent() != 0) {
@@ -197,12 +222,6 @@ void PageGenerator::generateInnerNode(const InnerNode *node,
generateClassLikeNode(node, marker);
}
else if (node->type() == Node::Fake) {
- const FakeNode* fakeNode = static_cast<const FakeNode *>(node);
-#ifdef QDOC_QML
- if (fakeNode->subType() == FakeNode::QmlClass) {
- //qDebug() << "FILENAME:" << fileName(node);
- }
-#endif
generateFakeNode(static_cast<const FakeNode *>(node), marker);
}
endSubPage();
diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro
index 2bba8fb..49a16e6 100644
--- a/tools/qdoc3/qdoc3.pro
+++ b/tools/qdoc3/qdoc3.pro
@@ -1,12 +1,17 @@
DEFINES += QDOC2_COMPAT
-#DEFINES += QT_NO_CAST_TO_ASCII
+DEFINES += QT_NO_CAST_TO_ASCII
#DEFINES += QT_NO_CAST_FROM_ASCII
+#DEFINES += QT_USE_FAST_OPERATOR_PLUS
+#DEFINES += QT_USE_FAST_CONCATENATION
QT = core xml
CONFIG += console
+CONFIG -= debug_and_release_target
+#CONFIG += debug
build_all:!build_pass {
CONFIG -= build_all
CONFIG += release
+# CONFIG += debug
}
mac:CONFIG -= app_bundle
HEADERS += apigenerator.h \
diff --git a/tools/qdoc3/separator.cpp b/tools/qdoc3/separator.cpp
index 8f27f90..60674be 100644
--- a/tools/qdoc3/separator.cpp
+++ b/tools/qdoc3/separator.cpp
@@ -48,22 +48,30 @@
QT_BEGIN_NAMESPACE
-QString separator( int index, int count )
+QString separator(int index, int count)
{
- if ( index == count - 1 )
- return tr( ".", "terminator" );
+ if (index == count - 1)
+ return tr(".", "terminator");
+ if (count == 2)
+ return tr(" and ", "separator when N = 2");
+ if (index == 0)
+ return tr(", ", "first separator when N > 2");
+ if (index < count - 2)
+ return tr(", ", "general separator when N > 2");
+ return tr(", and ", "last separator when N > 2");
+}
- if ( count == 2 ) {
- return tr( " and ", "separator when N = 2" );
- } else {
- if ( index == 0 ) {
- return tr( ", ", "first separator when N > 2" );
- } else if ( index < count - 2 ) {
- return tr( ", ", "general separator when N > 2" );
- } else {
- return tr( ", and ", "last separator when N > 2" );
- }
- }
+QString comma(int index, int count)
+{
+ if (index == count - 1)
+ return QString("");
+ if (count == 2)
+ return tr(" and ", "separator when N = 2");
+ if (index == 0)
+ return tr(", ", "first separator when N > 2");
+ if (index < count - 2)
+ return tr(", ", "general separator when N > 2");
+ return tr(", and ", "last separator when N > 2");
}
QT_END_NAMESPACE
diff --git a/tools/qdoc3/separator.h b/tools/qdoc3/separator.h
index 70ba624..2336d94 100644
--- a/tools/qdoc3/separator.h
+++ b/tools/qdoc3/separator.h
@@ -51,6 +51,7 @@
QT_BEGIN_NAMESPACE
QString separator( int index, int count );
+QString comma( int index, int count );
QT_END_NAMESPACE
diff --git a/tools/qdoc3/test/assistant.qdocconf b/tools/qdoc3/test/assistant.qdocconf
index 71de998..44815ff 100644
--- a/tools/qdoc3/test/assistant.qdocconf
+++ b/tools/qdoc3/test/assistant.qdocconf
@@ -6,18 +6,18 @@ include(qt-defines.qdocconf)
project = Qt Assistant
description = Qt Assistant Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Assistant
qhp.Assistant.file = assistant.qhp
-qhp.Assistant.namespace = com.trolltech.assistant.453
+qhp.Assistant.namespace = com.trolltech.assistant.460
qhp.Assistant.virtualFolder = qdoc
qhp.Assistant.indexTitle = Qt Assistant Manual
qhp.Assistant.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.Assistant.filterAttributes = qt 4.5.3 tools assistant
+qhp.Assistant.filterAttributes = qt 4.6.0 tools assistant
qhp.Assistant.customFilters.Assistant.name = Qt Assistant Manual
qhp.Assistant.customFilters.Assistant.filterAttributes = qt tools assistant
qhp.Assistant.subprojects = manual examples
diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css
index f22a77a..4225a1b 100644
--- a/tools/qdoc3/test/classic.css
+++ b/tools/qdoc3/test/classic.css
@@ -1,12 +1,82 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+ font-family: Arial, Geneva, Helvetica, sans-serif;
+}
+H1 {
+ text-align: center;
+ font-size: 160%;
+}
+H2 {
+ font-size: 120%;
+}
+H3 {
+ font-size: 100%;
+}
+
h3.fn,span.fn
{
- margin-left: 1cm;
- text-indent: -1cm;
+ background-color: #eee;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #ddd;
+ font-weight: bold;
+ padding: 6px 0px 6px 10px;
+ margin: 42px 0px 0px 0px;
+}
+
+hr {
+ border: 0;
+ color: #a0a0a0;
+ background-color: #ccc;
+ height: 1px;
+ width: 100%;
+ text-align: left;
+ margin: 34px 0px 34px 0px;
+}
+
+table.valuelist {
+ border-width: 1px 1px 1px 1px;
+ border-style: solid;
+ border-color: #dddddd;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+}
+
+table.indextable {
+ border-width: 1px 1px 1px 1px;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+ border-color:#555;
+}
+
+
+table.valuelist th {
+ border-width: 1px 1px 1px 2px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #666;
+ color:white;
+ background-color:#666;
+}
+
+th.titleheader {
+ border-width: 1px 0px 1px 0px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #444;
+ color:white;
+ background-color:#555555;
+}
+
+p {
+
+ margin-left: 4px;
+ margin-top: 8px;
+ margin-bottom: 8px;
}
a:link
{
- color: #004faf;
+ color: #0046ad;
text-decoration: none
}
@@ -40,20 +110,38 @@ a.compat:visited
text-decoration: none
}
-td.postheader
+body
{
- font-family: sans-serif
+ background: #ffffff;
+ color: black
}
-tr.address
+table.generic, table.annotated
{
- font-family: sans-serif
+ border-width: 1px;
+ border-color:#bbb;
+ border-style:solid;
+ border-collapse:collapse;
}
-body
-{
- background: #ffffff;
- color: black
+table td.memItemLeft {
+ width: 180px;
+ padding: 2px 0px 0px 8px;
+ margin: 4px;
+ border-width: 1px;
+ border-color: #E0E0E0;
+ border-style: none;
+ font-size: 100%;
+ white-space: nowrap
+}
+
+table td.memItemRight {
+ padding: 2px 8px 0px 8px;
+ margin: 4px;
+ border-width: 1px;
+ border-color: #E0E0E0;
+ border-style: none;
+ font-size: 100%;
}
table tr.odd {
@@ -137,3 +225,52 @@ span.string,span.char
{
font-size: 0.65em
}
+
+.qmlitem {
+ padding: 0;
+}
+
+.qmlname {
+ white-space: nowrap;
+ font-weight: bold;
+ font-size: 125%;
+}
+
+.qmltype {
+ font-weight: bold;
+ font-size: 125%;
+}
+
+.qmlproto, .qmldoc {
+ // border-top: 1px solid #84b0c7;
+}
+
+.qmlproto {
+ padding: 0;
+ //background-color: #e4e4e4;//#d5e1e8;
+ //font-weight: bold;
+ //-webkit-border-top-left-radius: 8px;
+ //-webkit-border-top-right-radius: 8px;
+ //-moz-border-radius-topleft: 8px;
+ //-moz-border-radius-topright: 8px;
+}
+
+.qmldoc {
+ border-top: 1px solid #e4e4e4;
+ //padding: 2px 5px;
+ //background-color: #eef3f5;
+ //border-top-width: 0;
+ //-webkit-border-bottom-left-radius: 8px;
+ //-webkit-border-bottom-right-radius: 8px;
+ //-moz-border-radius-bottomleft: 8px;
+ //-moz-border-radius-bottomright: 8px;
+}
+
+.qmldoc p, .qmldoc dl, .qmldoc ul {
+ //margin: 6px 0;
+}
+
+*.qmlitem p {
+ //margin-top: 0px;
+ //margin-bottom: 0px;
+}
diff --git a/tools/qdoc3/test/designer.qdocconf b/tools/qdoc3/test/designer.qdocconf
index 0c39bb8..88f8dc9 100644
--- a/tools/qdoc3/test/designer.qdocconf
+++ b/tools/qdoc3/test/designer.qdocconf
@@ -6,18 +6,18 @@ include(qt-defines.qdocconf)
project = Qt Designer
description = Qt Designer Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Designer
qhp.Designer.file = designer.qhp
-qhp.Designer.namespace = com.trolltech.designer.453
+qhp.Designer.namespace = com.trolltech.designer.460
qhp.Designer.virtualFolder = qdoc
qhp.Designer.indexTitle = Qt Designer Manual
qhp.Designer.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.Designer.filterAttributes = qt 4.5.3 tools designer
+qhp.Designer.filterAttributes = qt 4.6.0 tools designer
qhp.Designer.customFilters.Designer.name = Qt Designer Manual
qhp.Designer.customFilters.Designer.filterAttributes = qt tools designer
qhp.Designer.subprojects = manual examples
diff --git a/tools/qdoc3/test/linguist.qdocconf b/tools/qdoc3/test/linguist.qdocconf
index b6bd375..1c0a585 100644
--- a/tools/qdoc3/test/linguist.qdocconf
+++ b/tools/qdoc3/test/linguist.qdocconf
@@ -6,18 +6,18 @@ include(qt-defines.qdocconf)
project = Qt Linguist
description = Qt Linguist Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Linguist
qhp.Linguist.file = linguist.qhp
-qhp.Linguist.namespace = com.trolltech.linguist.453
+qhp.Linguist.namespace = com.trolltech.linguist.460
qhp.Linguist.virtualFolder = qdoc
qhp.Linguist.indexTitle = Qt Linguist Manual
qhp.Linguist.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.Linguist.filterAttributes = qt 4.5.3 tools linguist
+qhp.Linguist.filterAttributes = qt 4.6.0 tools linguist
qhp.Linguist.customFilters.Linguist.name = Qt Linguist Manual
qhp.Linguist.customFilters.Linguist.filterAttributes = qt tools linguist
qhp.Linguist.subprojects = manual examples
diff --git a/tools/qdoc3/test/macros.qdocconf b/tools/qdoc3/test/macros.qdocconf
index 85fe1db..f7dcdc0 100644
--- a/tools/qdoc3/test/macros.qdocconf
+++ b/tools/qdoc3/test/macros.qdocconf
@@ -1,14 +1,15 @@
+macro.aacute.HTML = "&aacute;"
macro.Aring.HTML = "&Aring;"
macro.aring.HTML = "&aring;"
macro.Auml.HTML = "&Auml;"
macro.author = "\\bold{Author:}"
macro.br.HTML = "<br />"
macro.BR.HTML = "<br />"
-macro.aacute.HTML = "&aacute;"
+macro.copyright.HTML = "&copy;"
macro.eacute.HTML = "&eacute;"
-macro.iacute.HTML = "&iacute;"
macro.gui = "\\bold"
macro.hr.HTML = "<hr />"
+macro.iacute.HTML = "&iacute;"
macro.key = "\\bold"
macro.menu = "\\bold"
macro.note = "\\bold{Note:}"
diff --git a/tools/qdoc3/test/qmake.qdocconf b/tools/qdoc3/test/qmake.qdocconf
index 83220ae..0f98132 100644
--- a/tools/qdoc3/test/qmake.qdocconf
+++ b/tools/qdoc3/test/qmake.qdocconf
@@ -6,18 +6,18 @@ include(qt-defines.qdocconf)
project = QMake
description = QMake Manual
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = qmake
qhp.qmake.file = qmake.qhp
-qhp.qmake.namespace = com.trolltech.qmake.453
+qhp.qmake.namespace = com.trolltech.qmake.460
qhp.qmake.virtualFolder = qdoc
qhp.qmake.indexTitle = QMake Manual
qhp.qmake.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.qmake.filterAttributes = qt 4.5.3 tools qmake
+qhp.qmake.filterAttributes = qt 4.6.0 tools qmake
qhp.qmake.customFilters.qmake.name = qmake Manual
qhp.qmake.customFilters.qmake.filterAttributes = qt tools qmake
qhp.qmake.subprojects = manual
diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf
index 5169714..b4f0c7a 100644
--- a/tools/qdoc3/test/qt-build-docs.qdocconf
+++ b/tools/qdoc3/test/qt-build-docs.qdocconf
@@ -6,7 +6,7 @@ include(qt-defines.qdocconf)
project = Qt
description = Qt Reference Documentation
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
QtXmlPatterns QtTest
@@ -20,7 +20,7 @@ edition.DesktopLight.groups = -graphicsview-api
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.453
+qhp.Qt.namespace = com.trolltech.qt.460
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
@@ -34,9 +34,9 @@ qhp.Qt.extraFiles = classic.css \
images/dynamiclayouts-example.png \
images/stylesheet-coffee-plastique.png
-qhp.Qt.filterAttributes = qt 4.5.3 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.5.3
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.3
+qhp.Qt.filterAttributes = qt 4.6.0 qtrefdoc
+qhp.Qt.customFilters.Qt.name = Qt 4.6.0
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.0
qhp.Qt.subprojects = classes overviews examples
qhp.Qt.subprojects.classes.title = Classes
qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
index 107c692..709e336 100644
--- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf
+++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
@@ -12,6 +12,7 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
QM_EXPORT_ICONVIEW \
QM_EXPORT_NETWORK \
QM_EXPORT_OPENGL \
+ QM_EXPORT_OPENVG \
QM_EXPORT_SQL \
QM_EXPORT_TABLE \
QM_EXPORT_WORKSPACE \
@@ -50,6 +51,7 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
Q_INTERNAL_WIN_NO_THROW \
Q_NETWORK_EXPORT \
Q_OPENGL_EXPORT \
+ Q_OPENVG_EXPORT \
Q_OUTOFLINE_TEMPLATE \
Q_SQL_EXPORT \
Q_SVG_EXPORT \
@@ -65,7 +67,9 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
QT_BEGIN_INCLUDE_NAMESPACE \
QT_END_NAMESPACE \
QT_END_INCLUDE_NAMESPACE \
- PHONON_EXPORT
+ PHONON_EXPORT \
+ Q_GADGET \
+ QWEBKIT_EXPORT
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf
index d6cb0e6..379511f 100644
--- a/tools/qdoc3/test/qt-inc.qdocconf
+++ b/tools/qdoc3/test/qt-inc.qdocconf
@@ -3,7 +3,7 @@ include(macros.qdocconf)
project = Qt
description = Qt Reference Documentation
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
edition.Console = QtCore QtNetwork QtSql QtXml QtScript QtTest
edition.Desktop = QtCore QtGui QtNetwork QtOpenGL QtSql QtSvg QtXml QtScript \
@@ -99,7 +99,9 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
Q_TESTLIB_EXPORT \
Q_TYPENAME \
Q_XML_EXPORT \
- QDBUS_EXPORT
+ QDBUS_EXPORT \
+ Q_GADGET \
+ QWEBKIT_EXPORT
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf
index f1fd8a2..10e0fcd 100644
--- a/tools/qdoc3/test/qt.qdocconf
+++ b/tools/qdoc3/test/qt.qdocconf
@@ -8,7 +8,7 @@ project = Qt
versionsym =
version = %VERSION%
description = Qt Reference Documentation
-url = http://doc.qtsoftware.com/4.5
+url = http://doc.qtsoftware.com/4.6
edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
QtXmlPatterns QtTest
@@ -22,7 +22,7 @@ edition.DesktopLight.groups = -graphicsview-api
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.453
+qhp.Qt.namespace = com.trolltech.qt.460
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
@@ -36,9 +36,9 @@ qhp.Qt.extraFiles = classic.css \
images/dynamiclayouts-example.png \
images/stylesheet-coffee-plastique.png
-qhp.Qt.filterAttributes = qt 4.5.3 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.5.3
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.3
+qhp.Qt.filterAttributes = qt 4.6.0 qtrefdoc
+qhp.Qt.customFilters.Qt.name = Qt 4.6.0
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.0
qhp.Qt.subprojects = classes overviews examples
qhp.Qt.subprojects.classes.title = Classes
qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp
index c992688..d75af70 100644
--- a/tools/qdoc3/tree.cpp
+++ b/tools/qdoc3/tree.cpp
@@ -176,6 +176,8 @@ const Node *Tree::findNode(const QStringList &path,
}
/*!
+ Find the node with the specified \a path name of the
+ specified \a type.
*/
Node *Tree::findNode(const QStringList &path,
Node::Type type,
@@ -189,6 +191,8 @@ Node *Tree::findNode(const QStringList &path,
}
/*!
+ Find the node with the specified \a path name of the
+ specified \a type.
*/
const Node *Tree::findNode(const QStringList &path,
Node::Type type,
@@ -208,7 +212,9 @@ FunctionNode *Tree::findFunctionNode(const QStringList& path,
int findFlags)
{
return const_cast<FunctionNode *>(
- const_cast<const Tree *>(this)->findFunctionNode(path, relative, findFlags));
+ const_cast<const Tree *>(this)->findFunctionNode(path,
+ relative,
+ findFlags));
}
/*!
@@ -233,7 +239,8 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path,
else
next = ((InnerNode *) node)->findNode(path.at(i));
- if (!next && node->type() == Node::Class && (findFlags & SearchBaseClasses)) {
+ if (!next && node->type() == Node::Class &&
+ (findFlags & SearchBaseClasses)) {
NodeList baseClasses = allBaseClasses(static_cast<const ClassNode *>(node));
foreach (const Node *baseClass, baseClasses) {
if (i == path.size() - 1)
@@ -412,6 +419,8 @@ void Tree::addPropertyFunction(PropertyNode *property,
}
/*!
+ This function adds the \a node to the \a group. The group
+ can be listed anywhere using the \e{annotated list} command.
*/
void Tree::addToGroup(Node *node, const QString &group)
{
@@ -563,7 +572,7 @@ void Tree::resolveGroups()
FakeNode *fake =
static_cast<FakeNode*>(findNode(QStringList(i.key()),Node::Fake));
- if (fake && fake->subType() == FakeNode::Group) {
+ if (fake && fake->subType() == Node::Group) {
fake->addGroupMember(i.value());
}
else {
@@ -770,21 +779,21 @@ void Tree::readIndexSection(const QDomElement &element,
}
else if (element.nodeName() == "page") {
- FakeNode::SubType subtype;
+ Node::SubType subtype;
if (element.attribute("subtype") == "example")
- subtype = FakeNode::Example;
+ subtype = Node::Example;
else if (element.attribute("subtype") == "header")
- subtype = FakeNode::HeaderFile;
+ subtype = Node::HeaderFile;
else if (element.attribute("subtype") == "file")
- subtype = FakeNode::File;
+ subtype = Node::File;
else if (element.attribute("subtype") == "group")
- subtype = FakeNode::Group;
+ subtype = Node::Group;
else if (element.attribute("subtype") == "module")
- subtype = FakeNode::Module;
+ subtype = Node::Module;
else if (element.attribute("subtype") == "page")
- subtype = FakeNode::Page;
+ subtype = Node::Page;
else if (element.attribute("subtype") == "externalpage")
- subtype = FakeNode::ExternalPage;
+ subtype = Node::ExternalPage;
else
return;
@@ -1226,25 +1235,25 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer,
const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
switch (fakeNode->subType()) {
- case FakeNode::Example:
+ case Node::Example:
writer.writeAttribute("subtype", "example");
break;
- case FakeNode::HeaderFile:
+ case Node::HeaderFile:
writer.writeAttribute("subtype", "header");
break;
- case FakeNode::File:
+ case Node::File:
writer.writeAttribute("subtype", "file");
break;
- case FakeNode::Group:
+ case Node::Group:
writer.writeAttribute("subtype", "group");
break;
- case FakeNode::Module:
+ case Node::Module:
writer.writeAttribute("subtype", "module");
break;
- case FakeNode::Page:
+ case Node::Page:
writer.writeAttribute("subtype", "page");
break;
- case FakeNode::ExternalPage:
+ case Node::ExternalPage:
writer.writeAttribute("subtype", "externalpage");
break;
default:
@@ -1383,7 +1392,7 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer,
bool external = false;
if (inner->type() == Node::Fake) {
const FakeNode *fakeNode = static_cast<const FakeNode *>(inner);
- if (fakeNode->subType() == FakeNode::ExternalPage)
+ if (fakeNode->subType() == Node::ExternalPage)
external = true;
}
@@ -1863,7 +1872,7 @@ void Tree::generateTagFile(const QString &fileName) const
*/
void Tree::addExternalLink(const QString &url, const Node *relative)
{
- FakeNode *fakeNode = new FakeNode(root(), url, FakeNode::ExternalPage);
+ FakeNode *fakeNode = new FakeNode(root(), url, Node::ExternalPage);
fakeNode->setAccess(Node::Public);
// Create some content for the node.
@@ -1884,23 +1893,30 @@ QString Tree::fullDocumentLocation(const Node *node) const
if (!node->url().isEmpty())
return node->url();
+ QString parentName;
+ QString anchorRef;
+
if (node->type() == Node::Namespace) {
// The root namespace has no name - check for this before creating
// an attribute containing the location of any documentation.
if (!node->fileBase().isEmpty())
- return node->fileBase() + ".html";
+ parentName = node->fileBase() + ".html";
else
return "";
}
else if (node->type() == Node::Fake) {
- return node->fileBase() + ".html";
+#ifdef QDOC_QML
+ if (node->subType() == Node::QmlClass)
+ return "qml-" + node->fileBase() + ".html";
+ else
+#endif
+ parentName = node->fileBase() + ".html";
}
else if (node->fileBase().isEmpty())
return "";
- QString parentName;
Node *parentNode = 0;
if ((parentNode = node->relates()))
@@ -1912,10 +1928,11 @@ QString Tree::fullDocumentLocation(const Node *node) const
case Node::Class:
case Node::Namespace:
if (parentNode && !parentNode->name().isEmpty())
- return parentName.replace(".html", "") + "-"
- + node->fileBase().toLower() + ".html";
+ parentName = parentName.replace(".html", "") + "-"
+ + node->fileBase().toLower() + ".html";
else
- return node->fileBase() + ".html";
+ parentName = node->fileBase() + ".html";
+ break;
case Node::Function:
{
/*
@@ -1925,29 +1942,17 @@ QString Tree::fullDocumentLocation(const Node *node) const
const FunctionNode *functionNode =
static_cast<const FunctionNode *>(node);
- // Functions can be compatibility functions or be obsolete.
- switch (node->status()) {
- case Node::Compat:
- parentName.replace(".html", "-qt3.html");
- break;
- case Node::Obsolete:
- parentName.replace(".html", "-obsolete.html");
- break;
- default:
- ;
- }
-
if (functionNode->metaness() == FunctionNode::Dtor)
- return parentName + "#dtor." + functionNode->name().mid(1);
+ anchorRef = "#dtor." + functionNode->name().mid(1);
- if (functionNode->associatedProperty())
+ else if (functionNode->associatedProperty())
return fullDocumentLocation(functionNode->associatedProperty());
- if (functionNode->overloadNumber() > 1)
- return parentName + "#" + functionNode->name()
- + "-" + QString::number(functionNode->overloadNumber());
+ else if (functionNode->overloadNumber() > 1)
+ anchorRef = "#" + functionNode->name()
+ + "-" + QString::number(functionNode->overloadNumber());
else
- return parentName + "#" + functionNode->name();
+ anchorRef = "#" + functionNode->name();
}
/*
@@ -1955,27 +1960,52 @@ QString Tree::fullDocumentLocation(const Node *node) const
the latter returns the name in lower-case. For
HTML anchors, we need to preserve the case.
*/
+ break;
case Node::Enum:
- return parentName + "#" + node->name() + "-enum";
+ anchorRef = "#" + node->name() + "-enum";
+ break;
case Node::Typedef:
- return parentName + "#" + node->name() + "-typedef";
+ anchorRef = "#" + node->name() + "-typedef";
+ break;
case Node::Property:
- return parentName + "#" + node->name() + "-prop";
+ anchorRef = "#" + node->name() + "-prop";
+ break;
case Node::Variable:
- return parentName + "#" + node->name() + "-var";
+ anchorRef = "#" + node->name() + "-var";
+ break;
case Node::Target:
- return parentName + "#" + Doc::canonicalTitle(node->name());
+ anchorRef = "#" + Doc::canonicalTitle(node->name());
+ break;
case Node::Fake:
{
- QString pageName = node->name();
- return pageName.replace("/", "-").replace(".", "-") + ".html";
+ /*
+ Use node->fileBase() for fake nodes because they are represented
+ by pages whose file names are lower-case.
+ */
+ parentName = node->fileBase();
+ parentName.replace("/", "-").replace(".", "-");
+ parentName += ".html";
}
break;
default:
break;
}
- return "";
+ // Various objects can be compat (deprecated) or obsolete.
+ if (node->type() != Node::Class && node->type() != Node::Namespace) {
+ switch (node->status()) {
+ case Node::Compat:
+ parentName.replace(".html", "-qt3.html");
+ break;
+ case Node::Obsolete:
+ parentName.replace(".html", "-obsolete.html");
+ break;
+ default:
+ ;
+ }
+ }
+
+ return parentName.toLower() + anchorRef;
}
/*!
diff --git a/tools/qdoc3/webxmlgenerator.cpp b/tools/qdoc3/webxmlgenerator.cpp
index c5209b8..e87e812 100644
--- a/tools/qdoc3/webxmlgenerator.cpp
+++ b/tools/qdoc3/webxmlgenerator.cpp
@@ -191,7 +191,7 @@ void WebXMLGenerator::generateIndexSections(QXmlStreamWriter &writer,
generateRelations(writer, node, marker);
- if (fake->subType() == FakeNode::Module) {
+ if (fake->subType() == Node::Module) {
writer.writeStartElement("generatedlist");
writer.writeAttribute("contents", "classesbymodule");
@@ -264,7 +264,7 @@ void WebXMLGenerator::generateInnerNode(const InnerNode *node, CodeMarker *marke
if (node->type() == Node::Fake) {
const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
- if (fakeNode->subType() == FakeNode::ExternalPage)
+ if (fakeNode->subType() == Node::ExternalPage)
return;
}