chiark / gitweb /
doxygen: support Qt signals and slots.
authorVladimír Vondruš <mosra@centrum.cz>
Thu, 13 Sep 2018 16:47:34 +0000 (18:47 +0200)
committerVladimír Vondruš <mosra@centrum.cz>
Thu, 13 Sep 2018 16:47:34 +0000 (18:47 +0200)
doc/doxygen.rst
doxygen/dox2html5.py
doxygen/templates/base-class-reference.html
doxygen/templates/details-func.html
doxygen/templates/entry-func.html
doxygen/test/cpp_signals_slots/Doxyfile [new file with mode: 0644]
doxygen/test/cpp_signals_slots/File.h [new file with mode: 0644]
doxygen/test/cpp_signals_slots/classClass.html [new file with mode: 0644]
doxygen/test/test_cpp.py

index da428dcf4375ed517b631faf8f8012bbb220d1b6..c0c3db5ebf783ae305d164801674697a8dd4bfec 100644 (file)
@@ -1248,6 +1248,12 @@ Property                                Description
 :py:`compound.public_funcs`             List of public functions. Set only for
                                         classes. See `Function properties`_ for
                                         details.
+:py:`compound.signals`                  List of Qt signals. Set only for
+                                        classes. See `Function properties`_ for
+                                        details.
+:py:`compound.public_slots`             List of public Qt slots. Set only for
+                                        classes. See `Function properties`_ for
+                                        details.
 :py:`compound.public_static_vars`       List of public static variables. Set
                                         only for classes. See
                                         `Variable properties`_ for details.
@@ -1263,6 +1269,9 @@ Property                                Description
 :py:`compound.protected_funcs`          List of protected functions. Set only
                                         for classes. See `Function properties`_
                                         for details.
+:py:`compound.protected_slots`          List of protected Qt slots. Set only
+                                        for classes. See `Function properties`_
+                                        for details.
 :py:`compound.protected_static_vars`    List of protected static variables. Set
                                         only for classes. See
                                         `Variable properties`_ for details.
@@ -1272,6 +1281,9 @@ Property                                Description
 :py:`compound.private_funcs`            List of documented private virtual
                                         functions. Set only for classes. See
                                         `Function properties`_ for details.
+:py:`compound.private_slots`            List of documented private virtual Qt
+                                        slots. Set only for classes. See
+                                        `Function properties`_ for details.
 :py:`compound.friend_funcs`             List of documented friend functions.
                                         Set only for classes. See
                                         `Function properties`_ for details.
@@ -1499,8 +1511,10 @@ Property                    Description
 ``````````````````````
 
 The :py:`commpound.funcs`, :py:`compound.public_static_funcs`,
-:py:`compound.public_funcs`, :py:`compound.protected_static_funcs`,
-:py:`compound.protected_funcs`, :py:`compound.private_funcs`,
+:py:`compound.public_funcs`, :py:`compound.signals`,
+:py:`compound.public_slots`, :py:`compound.protected_static_funcs`,
+:py:`compound.protected_funcs`, :py:`compound.protected_slots`,
+:py:`compound.private_funcs`, :py:`compound.private_slots`,
 :py:`compound.friend_funcs` and :py:`compound.related_funcs` properties contain
 a list of functions, where every item has the following properties:
 
@@ -1555,6 +1569,10 @@ Property                        Description
 :py:`func.is_constexpr`         If the function is :cpp:`constexpr`
 :py:`func.is_defaulted`         If the function is :cpp:`default`\ ed
 :py:`func.is_deleted`           If the function is :cpp:`delete`\ d
+:py:`func.is_signal`            If the function is a Qt signal. Set only for
+                                member functions.
+:py:`func.is_slot`              If the function is a Qt slot. Set only for
+                                member functions.
 =============================== ===============================================
 
 The :py:`func.params` is a list of function parameters and their description.
index 0fac50f17d9ad1f15607b52252217613556e110c..056648abd80ebeac67a74a951f7bd6fcc036cab8 100755 (executable)
@@ -1570,7 +1570,7 @@ def parse_typedef(state: State, element: ET.Element):
     return None
 
 def parse_func(state: State, element: ET.Element):
-    assert element.tag == 'memberdef' and element.attrib['kind'] in ['function', 'friend']
+    assert element.tag == 'memberdef' and element.attrib['kind'] in ['function', 'friend', 'signal', 'slot']
 
     func = Empty()
     state.current_definition_url_base, func.base_url, func.id = parse_id(element)
@@ -1627,6 +1627,8 @@ def parse_func(state: State, element: ET.Element):
     if element.attrib['kind'] != 'friend':
         func.is_protected = element.attrib['prot'] == 'protected'
         func.is_private = element.attrib['prot'] == 'private'
+    func.is_signal = element.attrib['kind'] == 'signal'
+    func.is_slot = element.attrib['kind'] == 'slot'
 
     func.has_template_details, func.templates = parse_template_params(state, element.find('templateparamlist'), templates)
 
@@ -2082,14 +2084,18 @@ def parse_xml(state: State, xml: str):
     compound.public_static_funcs = []
     compound.typeless_funcs = []
     compound.public_funcs = []
+    compound.signals = []
+    compound.public_slots = []
     compound.public_static_vars = []
     compound.public_vars = []
     compound.protected_types = []
     compound.protected_static_funcs = []
     compound.protected_funcs = []
+    compound.protected_slots = []
     compound.protected_static_vars = []
     compound.protected_vars = []
     compound.private_funcs = []
+    compound.private_slots = []
     compound.related = []
     compound.friend_funcs = []
     compound.groups = []
@@ -2341,6 +2347,20 @@ def parse_xml(state: State, xml: str):
                             compound.typeless_funcs += [func]
                         if func.has_details: compound.has_func_details = True
 
+            elif compounddef_child.attrib['kind'] == 'signal':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        compound.signals += [func]
+                        if func.has_details: compound.has_func_details = True
+
+            elif compounddef_child.attrib['kind'] == 'public-slot':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        compound.public_slots += [func]
+                        if func.has_details: compound.has_func_details = True
+
             elif compounddef_child.attrib['kind'] == 'public-static-attrib':
                 for memberdef in compounddef_child:
                     var = parse_var(state, memberdef)
@@ -2384,6 +2404,13 @@ def parse_xml(state: State, xml: str):
                             compound.typeless_funcs += [func]
                         if func.has_details: compound.has_func_details = True
 
+            elif compounddef_child.attrib['kind'] == 'protected-slot':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        compound.protected_slots += [func]
+                        if func.has_details: compound.has_func_details = True
+
             elif compounddef_child.attrib['kind'] == 'protected-static-attrib':
                 for memberdef in compounddef_child:
                     var = parse_var(state, memberdef)
@@ -2398,17 +2425,19 @@ def parse_xml(state: State, xml: str):
                         compound.protected_vars += [var]
                         if var.has_details: compound.has_var_details = True
 
-            elif compounddef_child.attrib['kind'] == 'private-func':
+            elif compounddef_child.attrib['kind'] in ['private-func', 'private-slot']:
                 # Gather only private functions that are virtual and
                 # documented
                 for memberdef in compounddef_child:
                     if memberdef.attrib['virt'] == 'non-virtual' or (not memberdef.find('briefdescription').text and not memberdef.find('detaileddescription').text):
-                        assert True # only because coverage.py can't handle continue :/
-                        continue # pragma: no cover
+                        continue
 
                     func = parse_func(state, memberdef)
                     if func:
-                        compound.private_funcs += [func]
+                        if compounddef_child.attrib['kind'] == 'private-slot':
+                            compound.private_slots += [func]
+                        else:
+                            compound.private_funcs += [func]
                         if func.has_details: compound.has_func_details = True
 
             elif compounddef_child.attrib['kind'] == 'related':
@@ -2472,7 +2501,7 @@ def parse_xml(state: State, xml: str):
                         if typedef:
                             list += [('typedef', typedef)]
                             if typedef.has_details: compound.has_typedef_details = True
-                    elif memberdef.attrib['kind'] == 'function':
+                    elif memberdef.attrib['kind'] in ['function', 'signal', 'slot']:
                         # Gather only private functions that are virtual and
                         # documented
                         if memberdef.attrib['prot'] == 'private' and (memberdef.attrib['virt'] == 'non-virtual' or (not memberdef.find('briefdescription').text and not memberdef.find('detaileddescription').text)):
index f80af0cba68681c6d53e45f4cbdd09125dbaf0f6..71cf5424b779f27f54b2a4e8b1fbdf530fd9ce47 100644 (file)
@@ -41,7 +41,7 @@
           </tbody>
         </table>
         {% endif %}
-        {% if compound.sections or compound.public_types or compound.public_static_funcs or compound.typeless_funcs or compound.public_funcs or compound.public_static_vars or compound.public_vars or compound.protected_types or compound.protected_static_funcs or compound.protected_funcs or compound.protected_static_vars or compound.protected_vars or compound.private_funcs or compound.groups or compound.friend_funcs or compound.related %}
+        {% if compound.sections or compound.public_types or compound.public_static_funcs or compound.typeless_funcs or compound.public_funcs or compound.signals or compound.public_slots or compound.public_static_vars or compound.public_vars or compound.protected_types or compound.protected_static_funcs or compound.protected_funcs or compound.protected_signals or compound.protected_static_vars or compound.protected_vars or compound.private_funcs or compound.private_slots or compound.groups or compound.friend_funcs or compound.related %}
         <div class="m-block m-default">
           <h3>Contents</h3>
           <ul>
                 {% if compound.public_funcs %}
                 <li><a href="#pub-methods">Public functions</a></li>
                 {% endif %}
+                {% if compound.signals %}
+                <li><a href="#signals">Signals</a></li>
+                {% endif %}
+                {% if compound.public_slots %}
+                <li><a href="#pub-slots">Public slots</a></li>
+                {% endif %}
                 {% if compound.public_vars %}
                 <li><a href="#pub-attribs">Public variables</a></li>
                 {% endif %}
@@ -93,6 +99,9 @@
                 {% if compound.protected_funcs %}
                 <li><a href="#pro-methods">Protected functions</a></li>
                 {% endif %}
+                {% if compound.protected_slots %}
+                <li><a href="#pro-slots">Protected slots</a></li>
+                {% endif %}
                 {% if compound.protected_static_vars %}
                 <li><a href="#pro-static-attribs">Protected static variables</a></li>
                 {% endif %}
                 {% if compound.private_funcs %}
                 <li><a href="#pri-methods">Private functions</a></li>
                 {% endif %}
+                {% if compound.private_slots %}
+                <li><a href="#pri-slots">Private slots</a></li>
+                {% endif %}
                 {% for group in compound.groups %}
                 <li><a href="#{{ group.id }}">{{ group.name }}</a></li>
                 {% endfor %}
           <h2><a href="#pub-methods">Public functions</a></h2>
           <dl class="m-dox">
             {% for func in compound.public_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.signals %}
+        <section id="signals">
+          <h2><a href="#signals">Signals</a></h2>
+          <dl class="m-dox">
+            {% for func in compound.signals %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.public_slots %}
+        <section id="pub-slots">
+          <h2><a href="#pub-slots">Public slots</a></h2>
+          <dl class="m-dox">
+            {% for func in compound.public_slots %}
 {{ entry_func(func) }}
             {% endfor %}
           </dl>
           <h2><a href="#pro-methods">Protected functions</a></h2>
           <dl class="m-dox">
             {% for func in compound.protected_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.protected_slots %}
+        <section id="pro-slots">
+          <h2><a href="#pro-slots">Protected slots</a></h2>
+          <dl class="m-dox">
+            {% for func in compound.protected_slots %}
 {{ entry_func(func) }}
             {% endfor %}
           </dl>
           <h2><a href="#pri-methods">Private functions</a></h2>
           <dl class="m-dox">
             {% for func in compound.private_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.private_slots %}
+        <section id="pri-slots">
+          <h2><a href="#pri-slots">Private slots</a></h2>
+          <dl class="m-dox">
+            {% for func in compound.private_slots %}
 {{ entry_func(func) }}
             {% endfor %}
           </dl>
           {% endfor %}
           {% for func in compound.public_funcs %}
           {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.signals %}
+          {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.public_slots %}
+          {% if func.has_details %}
 {{ details_func(func, compound.prefix_wbr) }}
           {% endif %}
           {% endfor %}
           {% endfor %}
           {% for func in compound.protected_funcs %}
           {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.protected_slots %}
+          {% if func.has_details %}
 {{ details_func(func, compound.prefix_wbr) }}
           {% endif %}
           {% endfor %}
           {% for func in compound.private_funcs %}
           {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.private_slots %}
+          {% if func.has_details %}
 {{ details_func(func, compound.prefix_wbr) }}
           {% endif %}
           {% endfor %}
index 14666c79ea1f89d15215f6b1f60cda285945e0df..2c394c7b92ab873e9b23934d5b32ad12255664c0 100644 (file)
@@ -13,7 +13,7 @@
               </div>
               {% endif %}
               {% set j = joiner(',\n              ') %}
-              <span class="m-dox-wrap-bumper">{{ func.prefix }}{{ func.type }} {{ prefix }}</span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#{{ func.id }}" class="m-dox-self">{{ func.name }}</a>(</span><span class="m-dox-wrap">{% for param in func.params %}{{ j() }}{{ param.type_name }}{% if param.default %} = {{ param.default }}{% endif %}{% endfor %}){{ func.suffix }}{% if func.is_explicit %} <span class="m-label m-info">explicit</span> {% endif %}{% if func.is_pure_virtual %} <span class="m-label m-warning">pure virtual</span>{% elif func.is_virtual %} <span class="m-label m-warning">virtual</span>{% endif %}{% if func.is_protected %} <span class="m-label m-warning">protected</span>{% elif func.is_private %} <span class="m-label m-danger">private</span>{% endif %}{% if func.is_defaulted %} <span class="m-label m-info">defaulted</span>{% endif %}{% if func.is_deleted %} <span class="m-label m-danger">deleted</span>{% endif %}{% if func.is_constexpr %} <span class="m-label m-primary">constexpr</span>{% endif %}{% if func.is_noexcept %} <span class="m-label m-success">noexcept</span>{% endif %}</span></span>
+              <span class="m-dox-wrap-bumper">{{ func.prefix }}{{ func.type }} {{ prefix }}</span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#{{ func.id }}" class="m-dox-self">{{ func.name }}</a>(</span><span class="m-dox-wrap">{% for param in func.params %}{{ j() }}{{ param.type_name }}{% if param.default %} = {{ param.default }}{% endif %}{% endfor %}){{ func.suffix }}{% if func.is_explicit %} <span class="m-label m-info">explicit</span> {% endif %}{% if func.is_pure_virtual %} <span class="m-label m-warning">pure virtual</span>{% elif func.is_virtual %} <span class="m-label m-warning">virtual</span>{% endif %}{% if func.is_protected %} <span class="m-label m-warning">protected{% if func.is_slot %} slot{% endif %}</span>{% elif func.is_private %} <span class="m-label m-danger">private{% if func.is_slot %} slot{% endif %}</span>{% elif func.is_signal %} <span class="m-label m-success">signal</span>{% elif func.is_slot %} <span class="m-label m-success">public slot</span>{% endif %}{% if func.is_defaulted %} <span class="m-label m-info">defaulted</span>{% endif %}{% if func.is_deleted %} <span class="m-label m-danger">deleted</span>{% endif %}{% if func.is_constexpr %} <span class="m-label m-primary">constexpr</span>{% endif %}{% if func.is_noexcept %} <span class="m-label m-success">noexcept</span>{% endif %}</span></span>
             </h3>
             {% if func.brief %}
             <p>{{ func.brief }}</p>
index d2060aca7547d661c6da1b5bd7866042cc928bcf..66e03b7f1c31300d1049f716956d03c2be13570b 100644 (file)
@@ -4,6 +4,6 @@
               <div class="m-dox-template">template&lt;{% for t in func.templates %}{{ j() }}{{ t.type }}{% if t.name %} {{ t.name }}{% endif %}{% if t.default %} = {{ t.default }}{% endif %}{% endfor %}&gt;</div>
               {% endif %}
               {% set j = joiner(',\n              ') %}
-              <span class="m-dox-wrap-bumper">{{ func.prefix }}{% if func.type == 'void' %}void {% elif func.type %}auto {% endif %}<a href="{% if func.base_url != compound.url %}{{ func.base_url }}{% endif %}#{{ func.id }}" {% if func.has_details or func.base_url != compound.url %}class="m-dox"{% else %}class="m-dox-self" name="{{ func.id }}"{% endif %}>{{ func.name }}</a>(</span><span class="m-dox-wrap">{% for param in func.params %}{{ j() }}{{ param.type_name }}{% if param.default %} = {{ param.default }}{% endif %}{% endfor %}){{ func.suffix }}{% if func.type and func.type != 'void' %} -&gt; {{ func.type }}{% endif %}{% if func.is_deprecated %} <span class="m-label m-danger">deprecated</span>{% endif %}{% if not func.type or mark_nonpublic %}{% if func.is_protected %} <span class="m-label m-flat m-warning">protected</span>{% elif func.is_private %} <span class="m-label m-flat m-danger">private</span>{% endif %}{% endif %}{% if func.is_defaulted %} <span class="m-label m-flat m-info">defaulted</span>{% endif %}{% if func.is_deleted %} <span class="m-label m-flat m-danger">deleted</span>{% endif %}{% if func.is_explicit %} <span class="m-label m-flat m-info">explicit</span> {% endif %}{% if func.is_pure_virtual %} <span class="m-label m-flat m-warning">pure virtual</span>{% elif func.is_virtual %} <span class="m-label m-flat m-warning">virtual</span>{% endif %}{% if func.is_constexpr %} <span class="m-label m-flat m-primary">constexpr</span>{% endif %}{% if func.is_noexcept %} <span class="m-label m-flat m-success">noexcept</span>{% endif %}</span>
+              <span class="m-dox-wrap-bumper">{{ func.prefix }}{% if func.type == 'void' %}void {% elif func.type %}auto {% endif %}<a href="{% if func.base_url != compound.url %}{{ func.base_url }}{% endif %}#{{ func.id }}" {% if func.has_details or func.base_url != compound.url %}class="m-dox"{% else %}class="m-dox-self" name="{{ func.id }}"{% endif %}>{{ func.name }}</a>(</span><span class="m-dox-wrap">{% for param in func.params %}{{ j() }}{{ param.type_name }}{% if param.default %} = {{ param.default }}{% endif %}{% endfor %}){{ func.suffix }}{% if func.type and func.type != 'void' %} -&gt; {{ func.type }}{% endif %}{% if func.is_deprecated %} <span class="m-label m-danger">deprecated</span>{% endif %}{% if not func.type or mark_nonpublic %}{% if func.is_protected %} <span class="m-label m-flat m-warning">protected{% if func.is_slot %} slot{% endif %}</span>{% elif func.is_private %} <span class="m-label m-flat m-danger">private{% if func.is_slot %} slot{% endif %}</span>{% elif func.is_signal %} <span class="m-label m-flat m-success">signal</span>{% elif func.is_slot %} <span class="m-label m-flat m-success">public slot</span>{% endif %}{% endif %}{% if func.is_defaulted %} <span class="m-label m-flat m-info">defaulted</span>{% endif %}{% if func.is_deleted %} <span class="m-label m-flat m-danger">deleted</span>{% endif %}{% if func.is_explicit %} <span class="m-label m-flat m-info">explicit</span> {% endif %}{% if func.is_pure_virtual %} <span class="m-label m-flat m-warning">pure virtual</span>{% elif func.is_virtual %} <span class="m-label m-flat m-warning">virtual</span>{% endif %}{% if func.is_constexpr %} <span class="m-label m-flat m-primary">constexpr</span>{% endif %}{% if func.is_noexcept %} <span class="m-label m-flat m-success">noexcept</span>{% endif %}</span>
             </dt>
             <dd>{{ func.brief }}</dd>
diff --git a/doxygen/test/cpp_signals_slots/Doxyfile b/doxygen/test/cpp_signals_slots/Doxyfile
new file mode 100644 (file)
index 0000000..0451f2a
--- /dev/null
@@ -0,0 +1,15 @@
+INPUT                   = File.h
+AUTOLINK_SUPPORT        = NO
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
+XML_PROGRAMLISTING      = NO
+
+##! M_PAGE_FINE_PRINT   =
+##! M_THEME_COLOR       =
+##! M_FAVICON           =
+##! M_LINKS_NAVBAR1     =
+##! M_LINKS_NAVBAR2     =
+##! M_SEARCH_DISABLED   = YES
+
diff --git a/doxygen/test/cpp_signals_slots/File.h b/doxygen/test/cpp_signals_slots/File.h
new file mode 100644 (file)
index 0000000..c8d7b37
--- /dev/null
@@ -0,0 +1,88 @@
+/** @file
+ * @brief Uh
+ */
+
+/** @brief A class */
+class Class {
+    signals:
+        /**
+         * @brief A signal
+         *
+         * Details.
+         */
+        void signal();
+
+    public slots:
+        /**
+         * @brief A public slot
+         *
+         * Details.
+         */
+        void publicSlot();
+
+    protected slots:
+        /**
+         * @brief A protected slot
+         *
+         * Details.
+         */
+        void protectedSlot();
+
+    private slots:
+        /**
+         * @brief A private virtual slot
+         *
+         * Shown because it's virtual.
+         */
+        virtual void privateVirtualSlot();
+
+        /**
+         * @brief A private slot
+         *
+         * Non-virtual, so hidden.
+         */
+        void privateSlot();
+
+    /** @{ @name A user-defined group */
+
+    signals:
+        /**
+         * @brief A grouped signal
+         *
+         * Details.
+         */
+        void groupedSignal();
+
+    public slots:
+        /**
+         * @brief A public grouped slot
+         *
+         * Details.
+         */
+        void publicGroupedSlot();
+
+    protected slots:
+        /**
+         * @brief A protected grouped slot
+         *
+         * Details.
+         */
+        void protectedGroupedSlot();
+
+    private slots:
+        /**
+         * @brief A private virtual grouped slot
+         *
+         * Shown because it's virtual.
+         */
+        virtual void privateVirtualGroupedSlot();
+
+        /**
+         * @brief A private grouped slot
+         *
+         * Non-virtual, so hidden.
+         */
+        void privateGroupedSlot();
+
+    /*@}*/
+};
diff --git a/doxygen/test/cpp_signals_slots/classClass.html b/doxygen/test/cpp_signals_slots/classClass.html
new file mode 100644 (file)
index 0000000..08cb0ee
--- /dev/null
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Class class | My Project</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+  <link rel="stylesheet" href="m-dark+doxygen.compiled.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Project</a>
+    </div>
+  </div>
+</nav></header>
+<main><article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>
+          Class <span class="m-thin">class</span>
+        </h1>
+        <p>A class.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#signals">Signals</a></li>
+                <li><a href="#pub-slots">Public slots</a></li>
+                <li><a href="#pro-slots">Protected slots</a></li>
+                <li><a href="#pri-slots">Private slots</a></li>
+                <li><a href="#a-user-defined-group">A user-defined group</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="signals">
+          <h2><a href="#signals">Signals</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a448480eaac813fcfd70bfe2025ad930a" class="m-dox">signal</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A signal.</dd>
+          </dl>
+        </section>
+        <section id="pub-slots">
+          <h2><a href="#pub-slots">Public slots</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#ad5d015b3ec21448231db0bf2f7c67d0f" class="m-dox">publicSlot</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A public slot.</dd>
+          </dl>
+        </section>
+        <section id="pro-slots">
+          <h2><a href="#pro-slots">Protected slots</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a3181cba4338292307ee59e22a823776a" class="m-dox">protectedSlot</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A protected slot.</dd>
+          </dl>
+        </section>
+        <section id="pri-slots">
+          <h2><a href="#pri-slots">Private slots</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#ac75473d5b861e743dde9c3e3b754cbd6" class="m-dox">privateVirtualSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-flat m-warning">virtual</span></span>
+            </dt>
+            <dd>A private virtual slot.</dd>
+          </dl>
+        </section>
+        <section id="a-user-defined-group">
+          <h2><a href="#a-user-defined-group">A user-defined group</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a041a72366d11da9502768014f4c37b49" class="m-dox">groupedSignal</a>(</span><span class="m-dox-wrap">) <span class="m-label m-flat m-success">signal</span></span>
+            </dt>
+            <dd>A grouped signal.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a6f2d90e1d6895a7f56d5526ebf352608" class="m-dox">publicGroupedSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-flat m-success">public slot</span></span>
+            </dt>
+            <dd>A public grouped slot.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a95badba7d96ec504b4fce9ae796cc5c9" class="m-dox">protectedGroupedSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-flat m-warning">protected slot</span></span>
+            </dt>
+            <dd>A protected grouped slot.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a028a4f04109d41c84b1c7a44997b1135" class="m-dox">privateVirtualGroupedSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-flat m-danger">private slot</span> <span class="m-label m-flat m-warning">virtual</span></span>
+            </dt>
+            <dd>A private virtual grouped slot.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Function documentation</h2>
+          <section class="m-dox-details" id="a448480eaac813fcfd70bfe2025ad930a"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a448480eaac813fcfd70bfe2025ad930a" class="m-dox-self">signal</a>(</span><span class="m-dox-wrap">) <span class="m-label m-success">signal</span></span></span>
+            </h3>
+            <p>A signal.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="ad5d015b3ec21448231db0bf2f7c67d0f"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#ad5d015b3ec21448231db0bf2f7c67d0f" class="m-dox-self">publicSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-success">public slot</span></span></span>
+            </h3>
+            <p>A public slot.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="a3181cba4338292307ee59e22a823776a"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a3181cba4338292307ee59e22a823776a" class="m-dox-self">protectedSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-warning">protected slot</span></span></span>
+            </h3>
+            <p>A protected slot.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="ac75473d5b861e743dde9c3e3b754cbd6"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#ac75473d5b861e743dde9c3e3b754cbd6" class="m-dox-self">privateVirtualSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-warning">virtual</span> <span class="m-label m-danger">private slot</span></span></span>
+            </h3>
+            <p>A private virtual slot.</p>
+<p>Shown because it&#x27;s virtual.</p>
+          </div></section>
+          <section class="m-dox-details" id="a041a72366d11da9502768014f4c37b49"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a041a72366d11da9502768014f4c37b49" class="m-dox-self">groupedSignal</a>(</span><span class="m-dox-wrap">) <span class="m-label m-success">signal</span></span></span>
+            </h3>
+            <p>A grouped signal.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="a6f2d90e1d6895a7f56d5526ebf352608"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a6f2d90e1d6895a7f56d5526ebf352608" class="m-dox-self">publicGroupedSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-success">public slot</span></span></span>
+            </h3>
+            <p>A public grouped slot.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="a95badba7d96ec504b4fce9ae796cc5c9"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a95badba7d96ec504b4fce9ae796cc5c9" class="m-dox-self">protectedGroupedSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-warning">protected slot</span></span></span>
+            </h3>
+            <p>A protected grouped slot.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="a028a4f04109d41c84b1c7a44997b1135"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Class::<wbr /></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a028a4f04109d41c84b1c7a44997b1135" class="m-dox-self">privateVirtualGroupedSlot</a>(</span><span class="m-dox-wrap">) <span class="m-label m-warning">virtual</span> <span class="m-label m-danger">private slot</span></span></span>
+            </h3>
+            <p>A private virtual grouped slot.</p>
+<p>Shown because it&#x27;s virtual.</p>
+          </div></section>
+        </section>
+      </div>
+    </div>
+  </div>
+</article></main>
+</body>
+</html>
index 44aca62d6a620444a9935fe1c0fef5f13fb2c6f5..5bab4020d4d9b986aee40dee4e39b65e900dfecc 100644 (file)
@@ -72,3 +72,11 @@ class Friends(IntegrationTestCase):
         self.run_dox2html5(wildcard='class*.xml')
         self.assertEqual(*self.actual_expected_contents('classClass.html'))
         self.assertEqual(*self.actual_expected_contents('classTemplate.html'))
+
+class SignalsSlots(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'signals_slots', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='classClass.xml')
+        self.assertEqual(*self.actual_expected_contents('classClass.html'))