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 <jerome.pasion@digia.com>
This commit is contained in:
parent
bf3a5ccef1
commit
04770e5824
@ -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<const FunctionNode *>(node);
|
||||
return QLatin1Char('E') + func->name();
|
||||
//const FunctionNode* func = static_cast<const FunctionNode *>(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<Section>& 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; i<fs.classMapList_.size(); i++) {
|
||||
ClassMap* classMap = fs.classMapList_[i];
|
||||
ClassKeysNodes* ckn = new ClassKeysNodes;
|
||||
ckn->first = 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<classKeysNodesList_.size(); i++) {
|
||||
ClassKeysNodes* classKeysNodes = classKeysNodesList_[i];
|
||||
classKeysNodesList_[i] = 0;
|
||||
delete classKeysNodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The destructor must delete the QML class maps in the class
|
||||
map list, if the class map list is not empty.
|
||||
*/
|
||||
FastSection::~FastSection()
|
||||
{
|
||||
if (!classMapList_.isEmpty()) {
|
||||
for (int i=0; i<classMapList_.size(); i++) {
|
||||
ClassMap* classMap = classMapList_[i];
|
||||
classMapList_[i] = 0;
|
||||
delete classMap;
|
||||
}
|
||||
section.members = fs.memberMap.values();
|
||||
section.reimpMembers = fs.reimpMemberMap.values();
|
||||
section.inherited = fs.inherited;
|
||||
sectionList.append(section);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,14 @@ QT_BEGIN_NAMESPACE
|
||||
class Config;
|
||||
class Tree;
|
||||
|
||||
typedef QMultiMap<QString, Node*> MemberMap; // the string is the member signature
|
||||
typedef QPair<const QmlClassNode*, MemberMap> ClassMap; // the node is the QML type
|
||||
typedef QList<ClassMap*> ClassMapList;
|
||||
|
||||
typedef QPair<QStringList, NodeList> KeysAndNodes;
|
||||
typedef QPair<const QmlClassNode*, KeysAndNodes> ClassKeysNodes;
|
||||
typedef QList<ClassKeysNodes*> ClassKeysNodesList;
|
||||
|
||||
struct Section
|
||||
{
|
||||
QString name;
|
||||
@ -66,6 +74,7 @@ struct Section
|
||||
NodeList members;
|
||||
NodeList reimpMembers;
|
||||
QList<QPair<InnerNode *, int> > 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<QString, Node *> memberMap;
|
||||
QMap<QString, Node *> reimpMemberMap;
|
||||
QMultiMap<QString, Node *> memberMap;
|
||||
QMultiMap<QString, Node *> reimpMemberMap;
|
||||
ClassMapList classMapList_;
|
||||
QList<QPair<InnerNode *, int> > 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());
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -1258,9 +1258,24 @@ QList<Section> 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<Section> 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;
|
||||
}
|
||||
|
@ -2067,8 +2067,38 @@ QString HtmlGenerator::generateAllQmlMembersFile(const QmlClassNode* qml_cn,
|
||||
generateFullName(qml_cn, 0);
|
||||
out() << ", including inherited members.</p>\n";
|
||||
|
||||
Section section = sections.first();
|
||||
generateSectionList(section, 0, marker, CodeMarker::Subpage);
|
||||
ClassKeysNodesList& cknl = sections.first().classKeysNodesList_;
|
||||
if (!cknl.isEmpty()) {
|
||||
for (int i=0; i<cknl.size(); i++) {
|
||||
ClassKeysNodes* ckn = cknl[i];
|
||||
const QmlClassNode* qcn = ckn->first;
|
||||
KeysAndNodes& kn = ckn->second;
|
||||
QStringList& keys = kn.first;
|
||||
NodeList& nodes = kn.second;
|
||||
if (nodes.isEmpty())
|
||||
continue;
|
||||
if (i != 0) {
|
||||
out() << "<p>The following members are inherited from ";
|
||||
generateFullName(qcn,0);
|
||||
out() << ".</p>\n";
|
||||
}
|
||||
out() << "<ul>\n";
|
||||
for (int j=0; j<keys.size(); j++) {
|
||||
if (nodes[j]->access() == Node::Private) {
|
||||
continue;
|
||||
}
|
||||
out() << "<li class=\"fn\">";
|
||||
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() << "</li>\n";
|
||||
}
|
||||
out() << "</ul>\n";
|
||||
}
|
||||
}
|
||||
|
||||
generateFooter();
|
||||
endSubPage();
|
||||
|
Loading…
Reference in New Issue
Block a user