From 04770e5824cbde365e935b47bd287a9a81fff6f9 Mon Sep 17 00:00:00 2001
From: Martin Smith
Date: Wed, 20 Mar 2013 13:26:09 +0100
Subject: [PATCH] qdoc: List of all members subpage redesigned
The subpage listing all the members of a QML type,
including the inherited members, was trying to use
an old format that works ok for C++ classes but is
not optimal for QML types.
The redesigned format for QML types still lists all
the members but it lists the members for each base
type in a separate list.
The members for a QML type that has been marked as
abstract are listed with the members of the type
that inherits the abstract type.
This fix does not fix QTBUG-30111, which will be
fixed in a separate commit. This means that some
links on the subpage generated by this change
will be links to a page that doesn't actually
contain any documentation for the linked member.
But it will eventually.
Task-number: QTBUG-30114
Change-Id: I8ae4227d1eaecdbc24a4ac9b8119f0ced2cdee92
Reviewed-by: Jerome Pasion
---
src/tools/qdoc/codemarker.cpp | 64 +++++++++++++++++++++++++++-----
src/tools/qdoc/codemarker.h | 19 ++++++++--
src/tools/qdoc/cppcodemarker.cpp | 29 +++++++++++----
src/tools/qdoc/htmlgenerator.cpp | 34 ++++++++++++++++-
4 files changed, 124 insertions(+), 22 deletions(-)
diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp
index 6095d0d2fa..7a7ede0f20 100644
--- a/src/tools/qdoc/codemarker.cpp
+++ b/src/tools/qdoc/codemarker.cpp
@@ -381,8 +381,9 @@ QString CodeMarker::sortName(const Node *node, const QString* name)
if ((node->type() == Node::QmlMethod) ||
(node->type() == Node::QmlSignal) ||
(node->type() == Node::QmlSignalHandler)) {
- const FunctionNode* func = static_cast(node);
- return QLatin1Char('E') + func->name();
+ //const FunctionNode* func = static_cast(node);
+ //return QLatin1Char('E') + func->name();
+ return QLatin1Char('E') + nodeName;
}
return QLatin1Char('B') + nodeName;
@@ -518,14 +519,59 @@ bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status)
void CodeMarker::append(QList& sectionList, const FastSection& fs, bool includeKeys)
{
if (!fs.isEmpty()) {
- Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember);
- if (includeKeys) {
- section.keys = fs.memberMap.keys();
+ if (fs.classMapList_.isEmpty()) {
+ Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember);
+ if (includeKeys) {
+ section.keys = fs.memberMap.keys();
+ }
+ section.members = fs.memberMap.values();
+ section.reimpMembers = fs.reimpMemberMap.values();
+ section.inherited = fs.inherited;
+ sectionList.append(section);
+ }
+ else {
+ Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember);
+ sectionList.append(section);
+ Section* s = §ionList[sectionList.size()-1];
+ for (int i=0; ifirst = classMap->first;
+ ckn->second.second = classMap->second.values();
+ ckn->second.first = classMap->second.keys();
+ s->classKeysNodesList_.append(ckn);
+ }
+ }
+ }
+}
+
+/*!
+ The destructor must delete each member of the
+ list of QML class lists, if it is not empty;
+ */
+Section::~Section()
+{
+ if (!classKeysNodesList_.isEmpty()) {
+ for (int i=0; i MemberMap; // the string is the member signature
+typedef QPair ClassMap; // the node is the QML type
+typedef QList ClassMapList;
+
+typedef QPair KeysAndNodes;
+typedef QPair ClassKeysNodes;
+typedef QList ClassKeysNodesList;
+
struct Section
{
QString name;
@@ -66,6 +74,7 @@ struct Section
NodeList members;
NodeList reimpMembers;
QList > inherited;
+ ClassKeysNodesList classKeysNodesList_;
Section() { }
Section(const QString& name0,
@@ -76,6 +85,7 @@ struct Section
divClass(divClass0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
+ ~Section();
void appendMember(Node* node) { members.append(node); }
void appendReimpMember(Node* node) { reimpMembers.append(node); }
};
@@ -87,8 +97,9 @@ struct FastSection
QString divClass;
QString singularMember;
QString pluralMember;
- QMap memberMap;
- QMap reimpMemberMap;
+ QMultiMap memberMap;
+ QMultiMap reimpMemberMap;
+ ClassMapList classMapList_;
QList > inherited;
FastSection(const InnerNode *parent,
@@ -101,10 +112,12 @@ struct FastSection
divClass(divClass0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
+ ~FastSection();
bool isEmpty() const {
return (memberMap.isEmpty() &&
inherited.isEmpty() &&
- reimpMemberMap.isEmpty());
+ reimpMemberMap.isEmpty() &&
+ classMapList_.isEmpty());
}
};
diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp
index f0cfc18515..5af9cdf2e8 100644
--- a/src/tools/qdoc/cppcodemarker.cpp
+++ b/src/tools/qdoc/cppcodemarker.cpp
@@ -1258,9 +1258,24 @@ QList CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
append(sections,qmlattachedmethods);
}
else {
+ /*
+ This is where the list of all members including inherited
+ members is prepared.
+ */
+ ClassMap* classMap = 0;
FastSection all(qmlClassNode,QString(),QString(),"member","members");
const QmlClassNode* current = qmlClassNode;
while (current != 0) {
+ /*
+ If the QML type is abstract, do not create
+ a new entry in the list for it. Instead,
+ add its members to the current entry.
+ */
+ if (!current->isAbstract()) {
+ classMap = new ClassMap;
+ classMap->first = current;
+ all.classMapList_.append(classMap);
+ }
NodeList::ConstIterator c = current->childNodes().constBegin();
while (c != current->childNodes().constEnd()) {
if ((*c)->subType() == Node::QmlPropertyGroup) {
@@ -1268,21 +1283,19 @@ QList CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
- QString key = current->name() + "::" + (*p)->name();
+ QString key = (*p)->name();
key = sortName(*p, &key);
- if (!all.memberMap.contains(key)) {
- all.memberMap.insert(key,*p);
- }
+ all.memberMap.insert(key,*p);
+ classMap->second.insert(key,*p);
}
++p;
}
}
else {
- QString key = current->name() + "::" + (*c)->name();
+ QString key = (*c)->name();
key = sortName(*c, &key);
- if (!all.memberMap.contains(key)) {
- all.memberMap.insert(key,*c);
- }
+ all.memberMap.insert(key,*c);
+ classMap->second.insert(key,*c);
}
++c;
}
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index 69d1a69d31..7d7f9e811a 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -2067,8 +2067,38 @@ QString HtmlGenerator::generateAllQmlMembersFile(const QmlClassNode* qml_cn,
generateFullName(qml_cn, 0);
out() << ", including inherited members.
\n";
- Section section = sections.first();
- generateSectionList(section, 0, marker, CodeMarker::Subpage);
+ ClassKeysNodesList& cknl = sections.first().classKeysNodesList_;
+ if (!cknl.isEmpty()) {
+ for (int i=0; ifirst;
+ KeysAndNodes& kn = ckn->second;
+ QStringList& keys = kn.first;
+ NodeList& nodes = kn.second;
+ if (nodes.isEmpty())
+ continue;
+ if (i != 0) {
+ out() << "The following members are inherited from ";
+ generateFullName(qcn,0);
+ out() << ".
\n";
+ }
+ out() << "\n";
+ for (int j=0; jaccess() == Node::Private) {
+ continue;
+ }
+ out() << "- ";
+ QString prefix;
+ if (!keys.isEmpty()) {
+ prefix = keys.at(j).mid(1);
+ prefix = prefix.left(keys.at(j).indexOf("::")+1);
+ }
+ generateSynopsis(nodes[j], qcn, marker, CodeMarker::Summary, false, &prefix);
+ out() << "
\n";
+ }
+ out() << "
\n";
+ }
+ }
generateFooter();
endSubPage();