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();