From 00e3c4d7dcb5f14e9d13200a1e5d041d266f6610 Mon Sep 17 00:00:00 2001
From: Martin Smith 
Date: Wed, 16 Jun 2010 14:49:07 +0200
Subject: doc: Added more DITA output to the XML generator
Some of the cxxFunction stuff for member functions.
Task-number:  	 QTBUG-11391
---
 tools/qdoc3/ditaxmlgenerator.cpp | 135 +++++++++++++++++++++++++++++++++++----
 tools/qdoc3/ditaxmlgenerator.h   |  20 +++++-
 tools/qdoc3/node.cpp             |  14 ++++
 tools/qdoc3/node.h               |   7 +-
 4 files changed, 160 insertions(+), 16 deletions(-)
diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp
index 197bc13..ebca881 100644
--- a/tools/qdoc3/ditaxmlgenerator.cpp
+++ b/tools/qdoc3/ditaxmlgenerator.cpp
@@ -501,19 +501,18 @@ QString DitaXmlGenerator::format()
 }
 
 /*!
-  Create a new GUID, write it to the XML stream
-  as an "id" attribute, and return it.
+  Calls lookupGuid() to get a GUID for \a text, then writes
+  it to the XML stream as an "id" attribute, and returns it.
  */
 QString DitaXmlGenerator::writeGuidAttribute(QString text)
 {
-    QString guid = QUuid::createUuid().toString();
-    name2guidMap.insert(text,guid);
+    QString guid = lookupGuid(text);
     writer.writeAttribute("id",guid);
     return guid;
 }
 
 /*!
-  Looks up \a text in the GUID map. It it finds \a text,
+  Looks up \a text in the GUID map. If it finds \a text,
   it returns the associated GUID. Otherwise it inserts
   \a text into the map with a new GUID, and it returns
   the new GUID.
@@ -1436,6 +1435,12 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
         writer.writeStartElement(CXXCLASSACCESSSPECIFIER);
         writer.writeAttribute("value",inner->accessString());
         writer.writeEndElement(); // 
+        if (cn->isAbstract()) {
+            writer.writeStartElement(CXXCLASSABSTRACT);
+            writer.writeAttribute("name","abstract");
+            writer.writeAttribute("value","abstract");
+            writer.writeEndElement(); // 
+        }
         writeDerivations(cn, marker);
         writeLocation(cn, marker);
         writer.writeEndElement(); // 
@@ -1452,6 +1457,26 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
     
         writer.writeEndElement(); // 
         writer.writeEndElement(); // 
+
+        sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
+        s = sections.begin();
+        while (s != sections.end()) {
+            if ((*s).name == "Member Function Documentation") {
+                writeFunctions((*s),cn,marker);
+            }
+            else if ((*s).name == "Member Type Documentation") {
+                writeNestedClasses((*s),cn,marker);
+                writeEnumerations((*s),cn,marker);
+                writeTypedefs((*s),cn,marker);
+            }
+            else if ((*s).name == "Member Variable Documentation") {
+                writeDataMembers((*s),cn,marker);
+            }
+            else if ((*s).name == "Property Documentation") {
+                writeProperties((*s),cn,marker);
+            }
+            ++s;
+        }
         writer.writeEndElement(); // 
     }
 
@@ -4502,19 +4527,101 @@ void DitaXmlGenerator::writeDerivations(const ClassNode* cn, CodeMarker* marker)
      }
 }
 
-void DitaXmlGenerator::writeLocation(const ClassNode* cn, CodeMarker* marker)
+void DitaXmlGenerator::writeLocation(const Node* n, CodeMarker* marker)
 {
-    writer.writeStartElement(CXXCLASSAPIITEMLOCATION);
-    writer.writeStartElement(CXXCLASSDECLARATIONFILE);
+    QString s1, s2, s3;
+    if (n->type() == Node::Class) {
+        s1 = CXXCLASSAPIITEMLOCATION;
+        s2 = CXXCLASSDECLARATIONFILE;
+        s3 = CXXCLASSDECLARATIONFILELINE;
+    }
+    else if (n->type() == Node::Function) {
+        s1 = CXXFUNCTIONAPIITEMLOCATION;
+        s2 = CXXFUNCTIONDECLARATIONFILE;
+        s3 = CXXFUNCTIONDECLARATIONFILELINE;
+    }
+    writer.writeStartElement(s1);
+    writer.writeStartElement(s2);
     writer.writeAttribute("name","filePath");
-    writer.writeAttribute("value",cn->location().filePath());
-    writer.writeEndElement(); // 
-    writer.writeStartElement(CXXCLASSDECLARATIONFILELINE);
+    writer.writeAttribute("value",n->location().filePath());
+    writer.writeEndElement(); // DeclarationFile>
+    writer.writeStartElement(s3);
     writer.writeAttribute("name","lineNumber");
     QString lineNr;
-    writer.writeAttribute("value",lineNr.setNum(cn->location().lineNo()));
-    writer.writeEndElement(); // 
-    writer.writeEndElement(); // 
+    writer.writeAttribute("value",lineNr.setNum(n->location().lineNo()));
+    writer.writeEndElement(); // DeclarationFileLine>
+    writer.writeEndElement(); // ApiItemLocation>
+}
+
+void DitaXmlGenerator::writeFunctions(const Section& s, 
+                                      const ClassNode* cn, 
+                                      CodeMarker* marker) {
+    NodeList::ConstIterator m = s.members.begin();
+    while (m != s.members.end()) {
+        if ((*m)->type() == Node::Function) {
+            const FunctionNode* fn = reinterpret_cast(*m);
+            QString name = fn->name();
+            writer.writeStartElement(CXXFUNCTION);
+            writeGuidAttribute(name);
+            writer.writeStartElement(APINAME);
+            writer.writeCharacters(name);
+            writer.writeEndElement(); // 
+            generateBrief(fn,marker);
+            writer.writeStartElement(CXXFUNCTIONDETAIL);
+            writer.writeStartElement(CXXFUNCTIONDEFINITION);
+            writer.writeStartElement(CXXFUNCTIONACCESSSPECIFIER);
+            writer.writeAttribute("value",fn->accessString());
+            writer.writeEndElement(); // 
+
+            writeLocation(fn, marker);
+            writer.writeEndElement(); // 
+            writer.writeStartElement(APIDESC);
+
+            if (!fn->doc().isEmpty()) {
+                writer.writeStartElement("p");
+                writer.writeAttribute("outputclass","h2");
+                writer.writeCharacters("Function Description");
+                writer.writeEndElement(); // 
+                generateBody(fn, marker);
+                //        generateAlsoList(inner, marker);
+            }
+    
+            writer.writeEndElement(); // 
+            writer.writeEndElement(); // 
+            writer.writeEndElement(); // 
+
+            if (fn->metaness() == FunctionNode::Ctor ||
+                fn->metaness() == FunctionNode::Dtor ||
+                fn->overloadNumber() != 1) {
+            }
+        }
+        ++m;
+    }
+}
+
+void DitaXmlGenerator::writeNestedClasses(const Section& s, 
+                                          const ClassNode* cn, 
+                                          CodeMarker* marker) {
+}
+
+void DitaXmlGenerator::writeEnumerations(const Section& s, 
+                                         const ClassNode* cn, 
+                                         CodeMarker* marker) {
+}
+
+void DitaXmlGenerator::writeTypedefs(const Section& s, 
+                                     const ClassNode* cn, 
+                                     CodeMarker* marker) {
+}
+
+void DitaXmlGenerator::writeDataMembers(const Section& s, 
+                                        const ClassNode* cn, 
+                                        CodeMarker* marker) {
+}
+
+void DitaXmlGenerator::writeProperties(const Section& s, 
+                                       const ClassNode* cn, 
+                                       CodeMarker* marker) {
 }
 
 QT_END_NAMESPACE
diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h
index 070329b..5afd82a 100644
--- a/tools/qdoc3/ditaxmlgenerator.h
+++ b/tools/qdoc3/ditaxmlgenerator.h
@@ -111,7 +111,25 @@ class DitaXmlGenerator : public PageGenerator
     virtual QString refForAtom(Atom *atom, const Node *node);
     
     void writeDerivations(const ClassNode* cn, CodeMarker* marker);
-    void writeLocation(const ClassNode* cn, CodeMarker* marker);
+    void writeLocation(const Node* n, CodeMarker* marker);
+    void writeFunctions(const Section& s, 
+                        const ClassNode* cn, 
+                        CodeMarker* marker);
+    void writeNestedClasses(const Section& s, 
+                            const ClassNode* cn, 
+                            CodeMarker* marker);
+    void writeEnumerations(const Section& s, 
+                           const ClassNode* cn, 
+                           CodeMarker* marker);
+    void writeTypedefs(const Section& s, 
+                       const ClassNode* cn, 
+                       CodeMarker* marker);
+    void writeDataMembers(const Section& s, 
+                          const ClassNode* cn, 
+                          CodeMarker* marker);
+    void writeProperties(const Section& s, 
+                         const ClassNode* cn, 
+                         CodeMarker* marker);
 
  private:
     enum SubTitleSize { SmallSubTitle, LargeSubTitle };
diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp
index 4664e9d..b71a43e 100644
--- a/tools/qdoc3/node.cpp
+++ b/tools/qdoc3/node.cpp
@@ -789,6 +789,7 @@ ClassNode::ClassNode(InnerNode *parent, const QString& name)
     : InnerNode(Class, parent, name)
 {
     hidden = false;
+    abstract = false;
     setPageType(ApiPage);
 }
 
@@ -1078,6 +1079,19 @@ FunctionNode::FunctionNode(Type type, InnerNode *parent, const QString& name, bo
 }
 
 /*!
+  Sets the \a virtualness of this function. If the \a virtualness
+  is PureVirtual, and if the parent() is a ClassNode, set the parent's
+  \e abstract flag to true.
+ */
+void FunctionNode::setVirtualness(Virtualness virtualness)
+{
+    vir = virtualness;
+    if ((virtualness == PureVirtual) && parent() &&
+        (parent()->type() == Node::Class))
+        parent()->setAbstract(true);
+}
+
+/*!
  */
 void FunctionNode::setOverload(bool overlode)
 {
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index 523394d..ccfd9b6 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -261,6 +261,8 @@ class InnerNode : public Node
     QStringList secondaryKeys();
     const QStringList& pageKeywords() const { return pageKeywds; }
     virtual void addPageKeywords(const QString& t) { pageKeywds << t; }
+    virtual bool isAbstract() const { return false; }
+    virtual void setAbstract(bool ) { }
 
  protected:
     InnerNode(Type type, InnerNode *parent, const QString& name);
@@ -341,11 +343,14 @@ class ClassNode : public InnerNode
     void setServiceName(const QString& value) { sname = value; }
     QString qmlElement() const { return qmlelement; }
     void setQmlElement(const QString& value) { qmlelement = value; }
+    virtual bool isAbstract() const { return abstract; }
+    virtual void setAbstract(bool b) { abstract = b; }
 
  private:
     QList bas;
     QList der;
     bool hidden;
+    bool abstract;
     QString sname;
     QString qmlelement;
 };
@@ -582,7 +587,7 @@ class FunctionNode : public LeafNode
     void setReturnType(const QString& returnType) { rt = returnType; }
     void setParentPath(const QStringList& parentPath) { pp = parentPath; }
     void setMetaness(Metaness metaness) { met = metaness; }
-    void setVirtualness(Virtualness virtualness) { vir = virtualness; }
+    void setVirtualness(Virtualness virtualness);
     void setConst(bool conste) { con = conste; }
     void setStatic(bool statique) { sta = statique; }
     void setOverload(bool overlode);
-- 
cgit v0.12