diff --git a/docs/sphinx/_static/images/sphinxdocs/user.png b/docs/sphinx/_static/images/sphinxdocs/user.png
new file mode 100644
index 00000000..749c825e
Binary files /dev/null and b/docs/sphinx/_static/images/sphinxdocs/user.png differ
diff --git a/docs/sphinx/_static/images/widgets/fullsize/wxgtk/genericdirctrl.png b/docs/sphinx/_static/images/widgets/fullsize/wxgtk/genericdirctrl.png
new file mode 100644
index 00000000..0ddd0329
Binary files /dev/null and b/docs/sphinx/_static/images/widgets/fullsize/wxgtk/genericdirctrl.png differ
diff --git a/docs/sphinx/_static/images/widgets/fullsize/wxgtk/treectrl.png b/docs/sphinx/_static/images/widgets/fullsize/wxgtk/treectrl.png
new file mode 100644
index 00000000..797381d2
Binary files /dev/null and b/docs/sphinx/_static/images/widgets/fullsize/wxgtk/treectrl.png differ
diff --git a/docs/sphinx/_static/images/widgets/fullsize/wxmac/genericdirctrl.png b/docs/sphinx/_static/images/widgets/fullsize/wxmac/genericdirctrl.png
new file mode 100644
index 00000000..0c65af47
Binary files /dev/null and b/docs/sphinx/_static/images/widgets/fullsize/wxmac/genericdirctrl.png differ
diff --git a/docs/sphinx/_static/images/widgets/fullsize/wxmac/treectrl.png b/docs/sphinx/_static/images/widgets/fullsize/wxmac/treectrl.png
new file mode 100644
index 00000000..190c6234
Binary files /dev/null and b/docs/sphinx/_static/images/widgets/fullsize/wxmac/treectrl.png differ
diff --git a/docs/sphinx/_static/images/widgets/fullsize/wxmsw/genericdirctrl.png b/docs/sphinx/_static/images/widgets/fullsize/wxmsw/genericdirctrl.png
new file mode 100644
index 00000000..0dd9a21e
Binary files /dev/null and b/docs/sphinx/_static/images/widgets/fullsize/wxmsw/genericdirctrl.png differ
diff --git a/docs/sphinx/_static/images/widgets/fullsize/wxmsw/treectrl.png b/docs/sphinx/_static/images/widgets/fullsize/wxmsw/treectrl.png
new file mode 100644
index 00000000..db1b7ed5
Binary files /dev/null and b/docs/sphinx/_static/images/widgets/fullsize/wxmsw/treectrl.png differ
diff --git a/docs/sphinx/_templates/main.html b/docs/sphinx/_templates/main.html
index 073961c5..c0f76ff0 100644
--- a/docs/sphinx/_templates/main.html
+++ b/docs/sphinx/_templates/main.html
@@ -49,6 +49,17 @@
shows the main thoughts behind the project Phoenix implementation
+
+
+
+
Note
+
+ If you wish to help in the documentation effort, the main docstrings guidelines are outlined in
+
this document.
+
+
+
+
The Phoenix documentation has been built automatically starting from XML files representing the
wxWidgets C++ documentation (generated using Doxygen).
diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py
index d3309f1b..5af9a344 100644
--- a/docs/sphinx/conf.py
+++ b/docs/sphinx/conf.py
@@ -56,7 +56,7 @@ copyright = u'2012, Andrea Gavana'
# The short X.Y version.
version = '2.9'
# The full version, including alpha/beta/rc tags.
-release = '2.9.3.74 (Phoenix)'
+release = '2.9.4.80 (Phoenix)'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -158,7 +158,7 @@ html_use_index = True
html_split_index = True
# If true, links to the reST sources are added to the pages.
-html_show_sourcelink = False
+html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
diff --git a/docs/sphinx/rest_substitutions/overviews/DocstringsGuidelines.rst b/docs/sphinx/rest_substitutions/overviews/DocstringsGuidelines.rst
new file mode 100644
index 00000000..4001985d
--- /dev/null
+++ b/docs/sphinx/rest_substitutions/overviews/DocstringsGuidelines.rst
@@ -0,0 +1,271 @@
+.. include:: headings.inc
+
+.. highlight:: rst
+
+
+.. _docstrings guidelines:
+
+==================================================
+|phoenix_title| **Phoenix Docstrings Guidelines**
+==================================================
+
+This document gives a brief introduction about the current docstrings standards
+in the Phoenix project. Most of the documentation in the Phoenix core is automatically
+generated by parsing the wxWidgets XML docs; however, Phoenix has its own pure-Python
+functions and classes in at least two places:
+
+* **Core Library**: examples include :ref:`CallLater` and :func:`date2pydate`, which require
+ manual input od the documentation strings. This is achieved by editing the source Python files
+ located in the ``etg`` folder in the Phoenix directory tree;
+* **wx.lib**: the whole of ``wx.lib`` (and its sub-folders) is made up of pure-Python modules,
+ ofter representing owner-drawn widgets which are not available as wrapped modules. Again,
+ this requires manual editing of the source Python files.
+
+This document is a starting point in setting some reasonable standards on how the pure-Python
+docstrings may be edited and improved to make the overall appearance of the Phoenix documentation
+consistent and pleasant.
+
+
+.. _info field lists:
+
+Info Field Lists
+----------------
+
+`Info Field Lists` refer to the various options available while documenting a method or a function,
+and in particular its parameters, keywords, return type and possibly raised Python `Exceptions`.
+
+Inside Python object description directives, reST field lists with these fields
+are recognized and formatted nicely:
+
+* ``param``, ``parameter``, ``arg``, ``argument``, ``key``, ``keyword``:
+ Description of a parameter.
+* ``type``: Type of a parameter.
+* ``raises``, ``raise``, ``except``, ``exception``: That (and when) a specific
+ exception is raised.
+* ``var``, ``ivar``, ``cvar``: Description of a variable.
+* ``returns``, ``return``: Description of the return value.
+* ``rtype``: Return type.
+
+
+The field names must consist of one of these keywords and an argument (except
+for ``returns`` and ``rtype``, which do not need an argument). This is best
+explained by an example::
+
+ .. method:: Set3StateValue(self, state):
+
+ Sets the checkbox item to the given `state`.
+
+ :param `state`: can be one of: ``wx.CHK_UNCHECKED`` (check is off), ``wx.CHK_CHECKED``
+ (check is on) or ``wx.CHK_UNDETERMINED`` (check is mixed).
+ :type `state`: integer
+
+ :returns: ``True`` if the value was successfully set, ``False`` otherwise.
+ :rtype: bool
+
+ :raise: `Exception` when the item is not a 3-state checkbox item.
+
+|
+
+This will render like this:
+
+ .. method:: Set3StateValue(self, state):
+ :noindex:
+
+ Sets the checkbox item to the given `state`.
+
+ :param `state`: can be one of: ``wx.CHK_UNCHECKED`` (check is off), ``wx.CHK_CHECKED``
+ (check is on) or ``wx.CHK_UNDETERMINED`` (check is mixed).
+ :type `state`: integer
+
+ :returns: ``True`` if the value was successfully set, ``False`` otherwise.
+ :rtype: bool
+
+ :raise: `Exception` when the item is not a 3-state checkbox item.
+
+
+|
+
+It is also possible to combine parameter type and description, if the type is a
+single word, like this::
+
+ :param integer `state`: can be one of: ``wx.CHK_UNCHECKED`` (check is off), ``wx.CHK_CHECKED``
+ (check is on) or ``wx.CHK_UNDETERMINED`` (check is mixed).
+
+
+In general, the standards for the ``:param`` field are the following:
+
+1. Do not use the ``@param`` construct, as I am not sure Sphinx and docutils understand it;
+2. Always try and define the parameter type: if the parameter is another Phoenix class, you can simply
+ write this::
+
+ :param Point `pt`: the mouse pointer location.
+
+ Or, alternatively::
+
+ :param `pt`: the mouse pointer location.
+ :type `pt`: `Point`
+
+
+Similarly, for the ``:return:`` and ``:rtype:`` field, you may consider doing the following:
+
+1. Try and put double-backticks on words like ``True``, ``False``, ``None`` and the various
+ Phoenix constants (i.e., ``wx.TR_DEFAULT_STYLE``);
+2. If you can't guess what a method function returns, just leave the ``:returns:`` and ``:rtype:``
+ fields blank.
+
+
+.. seealso:: `Sphinx Info Field List `_
+
+
+.. _admonitions:
+
+Admonitions
+-----------
+
+Admonitions are specially marked "topics" that can appear anywhere an ordinary body element can.
+They contain arbitrary body elements. Typically, an admonition is rendered as an offset block
+in a document, sometimes outlined or shaded, with a title matching the admonition type. For example::
+
+ .. warning:: I am a warning.
+
+
+Will render as:
+
+.. warning:: I am a warning.
+
+|
+
+Currently, the `sphinx_generator` tool recognizes the following admonitions:
+
+1. ``.. note::`` : simple annotations to make a particular comment/sentence
+ stand out against the rest of the documentation strings for a particular class, method or function;
+2. ``.. warning::`` : this admonition normally indicates a problem or a severe limitation of a method,
+ class or function. In the Phoenix world, this may also indicate that a particular widget is not
+ supported under one or more platforms;
+3. ``.. deprecated::`` : used to mark deprecated methods, classes or functions;
+4. ``.. availability::`` : normally employed to make the user understand on which platform(s) a particular
+ functionality is supported/available;
+5. ``.. seealso::`` : added primarily to facilitate the browsing of the docs, this admonition
+ should be employed every time you think a user may be interested in seeing a related/similar method
+ or a function providing an alternative implementation;
+6. ``.. todo::`` : used to mark incomplete methods/functions, or simply as a remainder for the user and
+ the developer that some more functionality needs to be added.
+
+You can put pretty much anything inside an admonition section, as long as it is properly indented. The
+recommendation is to implement it like this::
+
+ .. note::
+
+ The class :ref:`TreeCtrl` can be used to display a tree, with these notes:
+
+ - The note contains all indented body elements
+ following.
+ - It includes this bullet list.
+
+
+|
+
+Which will render as follows:
+
+.. note::
+
+ The class :ref:`TreeCtrl` can be used to display a tree, with these notes:
+
+ - The note contains all indented body elements
+ following.
+ - It includes this bullet list.
+
+
+
+In addition to the aforementioned admonitions, you can also use the default Sphinx directives
+like ``.. versionadded::`` and ``.. versionchanged::``, to highlight the fact that some method,
+function or class has been added/modified starting with a particular Phoenix version.
+
+
+.. seealso:: `Sphinx Paragraph-level markup `_
+
+
+.. _contributing samples:
+
+Contributing Samples
+--------------------
+
+.. highlight:: python
+
+If you wish to contribute a (short) sample to be included in the documentation, please follow
+these conventions:
+
+1. Name the snippet of code like ``classname.methodname.INTEGER.py``, i.e. if you wish to contribute 2
+ snippets about the :meth:`CheckBox.SetValue` method, please name your snippet files like this:
+
+ * `CheckBox.SetValue.1.py`
+ * `CheckBox.SetValue.2.py`
+
+
+2. At the very top of the snippet file (on the first line), put your name, or your alias, or anything
+ you use as internet name preceeded by a double-hash, i.e.:
+
+ ``##Andrea Gavana``
+
+
+ So that your source code looks more or less like this::
+
+ ##Chris Barker
+ #!/usr/bin/env python
+
+ """
+ A simple test of the GridBagSizer
+ http://wiki.wxpython.org/index.cgi/WriteItYourself
+ """
+
+ # Whatever code here...
+ def SendSizeEvent(self):
+
+ self.AdjustMySize()
+
+
+
+.. highlight:: rst
+
+This snippet will end up in the snippets `contrib` folder, to differentiate it from the snippets
+automatically generated when parsing the wxWidgets C++ XML documentation.
+
+Please keep the snippets as short as possible: they don't need to be fully-runnable and self contained
+applications, they are simply meant to show a particular/clever/unusual way of using a method, a class
+or a function.
+
+Please do send your sample snippets to me at `this `_ e-mail address or, if
+you have commit rights in the current Phoenix SVN area, feel free to upload them yourself under the
+following folder:
+
+``/trunk/docs/sphinx/rest_substitutions/snippets/python/contrib``
+
+
+.. _contributing screenshots:
+
+Contributing Screenshots
+------------------------
+
+Currently Phoenix is relatively short of widgets screenshots, especially on Linux/Mac platforms.
+
+If you wish to contribute a screenshot of a widget to be included in the documentation, please follow
+these conventions:
+
+- If the widget is a class belonging to the main `wx` namespace, just use the
+ class name in lower case (i.e., `wx.Frame` ==> `frame.png`);
+- If it belongs to a sub-namespace (i.e., `wx.dataview`, `wx.aui`, `wx.html`
+ and so on), it should be named this way (examples):
+
+ 1) `wx.dataview.DataViewCtrl` ==> `dataview.dataviewctrl.png`
+ 2) `wx.aui.AuiManager` ==> `aui.auimanager.png`
+
+
+Please do send your screenshots to me at `this `_ e-mail address or, if
+you have commit rights in the current Phoenix SVN area, feel free to upload them yourself under the
+following folder:
+
+``/trunk/docs/sphinx/_static/images/widgets/fullsize``
+
+Please make sure to upload your images in the appropriate sub-folder, depending on the platform you
+chose to take the screenshots on.
+
diff --git a/docs/sphinx/rest_substitutions/overviews/index.rst b/docs/sphinx/rest_substitutions/overviews/index.rst
index ca412d72..767da949 100644
--- a/docs/sphinx/rest_substitutions/overviews/index.rst
+++ b/docs/sphinx/rest_substitutions/overviews/index.rst
@@ -126,7 +126,7 @@ project in the `wxWidgets SVN `_.
wxPython Documentation
----------------------
-The new wxPython API documentation is available `in this page `_.
+The new wxPython API documentation is available `in this page `_.
.. toctree::
diff --git a/docs/sphinx/rest_substitutions/overviews/treectrl_overview.rst b/docs/sphinx/rest_substitutions/overviews/treectrl_overview.rst
new file mode 100644
index 00000000..9da7656f
--- /dev/null
+++ b/docs/sphinx/rest_substitutions/overviews/treectrl_overview.rst
@@ -0,0 +1,69 @@
+.. include:: headings.inc
+
+
+.. _treectrl overview:
+
+===============================================
+|phoenix_title| **TreeCtrl Overview**
+===============================================
+
+The tree control displays its items in a tree like structure. Each item has its own (optional) icon
+and a label. An item may be either collapsed (meaning that its children are not visible) or expanded
+(meaning that its children are shown). Each item in the tree is identified by its itemId which is of
+opaque data type :ref:`TreeItemId`. You can test whether an item is valid by calling :meth:`TreeItemId.IsOk`.
+
+The items text and image may be retrieved and changed with `(Get|Set)ItemText` and `(Get|Set)ItemImage`.
+In fact, an item may even have two images associated with it: the normal one and another one for selected
+state which is set/retrieved with `(Get|Set)ItemSelectedImage` functions, but this functionality might
+be unavailable on some platforms.
+
+Tree items have several attributes: an item may be selected or not, visible or not, bold or not. It may
+also be expanded or collapsed. All these attributes may be retrieved with the corresponding functions:
+:meth:`TreeCtrl.IsSelected`, :meth:`TreeCtrl.IsVisible`, :meth:`TreeCtrl.IsBold` and :meth:`TreeCtrl.IsExpanded`.
+Only one item at a time may be selected, selecting another one (with :meth:`TreeCtrl.SelectItem`) automatically
+unselects the previously selected one.
+
+In addition to its icon and label, a user-specific data structure may be associated with all tree items.
+If you wish to do it, you should derive a class from :ref:`TreeItemData` which is a very simple class
+having only one function `GetId()` which returns the id of the item this data is associated with. This data
+will be freed by the control itself when the associated item is deleted (all items are deleted when the
+control is destroyed), so you shouldn't delete it yourself (if you do it, you should call `SetItemData(None)`
+to prevent the tree from deleting the pointer second time). The associated data may be retrieved with
+:meth:`TreeCtrl.GetItemData` function.
+
+Working with trees is relatively straightforward if all the items are added to the tree at the moment of
+its creation. However, for large trees it may be very inefficient. To improve the performance you may want
+to delay adding the items to the tree until the branch containing the items is expanded: so, in the
+beginning, only the root item is created (with :meth:`TreeCtrl.AddRoot`). Other items are added when
+``EVT_TREE_ITEM_EXPANDING`` event is received: then all items lying immediately under the item being expanded
+should be added, but, of course, only when this event is received for the first time for this item - otherwise,
+the items would be added twice if the user expands/collapses/re-expands the branch.
+
+The tree control provides functions for enumerating its items. There are 3 groups of enumeration functions: for
+the children of a given item, for the sibling of the given item and for the visible items (those which are
+currently shown to the user: an item may be invisible either because its branch is collapsed or because it
+is scrolled out of view). Child enumeration functions require the caller to give them a `cookie` parameter: it
+is a number which is opaque to the caller but is used by the tree control itself to allow multiple enumerations
+to run simultaneously (this is explicitly allowed). The only thing to remember is that the `cookie` passed
+to :meth:`TreeCtrl.GetFirstChild` and to :meth:`TreeCtrl.GetNextChild` should be the same variable (and that
+nothing should be done with it by the user code).
+
+Among other features of the tree control are:
+
+* Item Sorting with :meth:`TreeCtrl.SortChildren` which uses the user-defined comparison function `OnCompareItems`
+ (by default the comparison is the alphabetic comparison of tree labels);
+* Hit Testing (determining to which portion of the control the given point belongs, useful for implementing
+ drag-and-drop in the tree) with :meth:`TreeCtrl.HitTest`;
+* Editing of the tree item labels in place (see :meth:`TreeCtrl.EditLabel`).
+
+Finally, the tree control has a keyboard interface: the cursor navigation (arrow) keys may be used to change
+the current selection. ``HOME`` and ``END`` are used to go to the first/last sibling of the current item. ``+``,
+``-`` and ``*`` expand, collapse and toggle the current branch. Note, however, that ``DEL`` and ``INS`` keys
+do nothing by default, but it is common to associate them with deleting an item from a tree and inserting
+a new one into it.
+
+
+.. seealso:: :ref:`TreeCtrl`, :ref:`ImageList`
+
+
+
diff --git a/docs/sphinx/rest_substitutions/snippets/python/contrib/GridBagSizer.1.py b/docs/sphinx/rest_substitutions/snippets/python/contrib/GridBagSizer.1.py
new file mode 100644
index 00000000..3fb4e7ae
--- /dev/null
+++ b/docs/sphinx/rest_substitutions/snippets/python/contrib/GridBagSizer.1.py
@@ -0,0 +1,46 @@
+##Chris Barker
+#!/usr/bin/env python
+
+"""
+A simple test of the GridBagSizer
+
+http://wiki.wxpython.org/index.cgi/WriteItYourself
+
+"""
+
+import wx
+
+class MyFrame(wx.Frame):
+ def __init__(self, parent, ID, title):
+ wx.Frame.__init__(self, parent, ID, title, wx.DefaultPosition)
+
+ Buttons = []
+ for i in range(6):
+ Buttons.append(wx.Button(self,-1, "Button %i"%(i)))
+
+ sizer = wx.GridBagSizer(9, 9)
+ sizer.Add(Buttons[0], (0, 0), wx.DefaultSpan, wx.ALL, 5)
+ sizer.Add(Buttons[1], (1, 1), (1,7), wx.EXPAND)
+ sizer.Add(Buttons[2], (6, 6), (3,3), wx.EXPAND)
+ sizer.Add(Buttons[3], (3, 0), (1,1), wx.ALIGN_CENTER)
+ sizer.Add(Buttons[4], (4, 0), (1,1), wx.ALIGN_LEFT)
+ sizer.Add(Buttons[5], (5, 0), (1,1), wx.ALIGN_RIGHT)
+
+ sizer.AddGrowableRow(6)
+ sizer.AddGrowableCol(6)
+
+ self.SetSizerAndFit(sizer)
+ self.Centre()
+
+
+class MyApp(wx.App):
+ def OnInit(self):
+ frame = MyFrame(None, -1, "wx.gridbagsizer.py")
+ frame.Show(True)
+ self.SetTopWindow(frame)
+ return True
+
+if __name__ == "__main__":
+ app = MyApp(0)
+ app.MainLoop()
+
diff --git a/docs/sphinx/rest_substitutions/snippets/python/contrib/GridBagSizer.2.py b/docs/sphinx/rest_substitutions/snippets/python/contrib/GridBagSizer.2.py
new file mode 100644
index 00000000..6442a0cc
--- /dev/null
+++ b/docs/sphinx/rest_substitutions/snippets/python/contrib/GridBagSizer.2.py
@@ -0,0 +1,43 @@
+##Chris Barker
+#!/usr/bin/env python
+
+import wx
+
+class TestFrame(wx.Frame):
+ def __init__(self, *args, **kwargs):
+ wx.Frame.__init__(self, *args, **kwargs)
+
+ t = wx.TextCtrl(self)
+
+ b1 = wx.Button(self, label="Button1")
+ b2 = wx.Button(self, label="Button2")
+
+ exitBut = wx.Button(self, label="Exit")
+ exitBut.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
+
+ sizer = wx.GridBagSizer(10, 10)
+ sizer.Add(t, (0,0), span=(2,1), flag=wx.ALIGN_CENTER_VERTICAL )
+ sizer.Add(b1, (0,1), span=(2,1), flag=wx.ALIGN_CENTER)
+ sizer.Add(b2, (0,2), flag=wx.ALIGN_CENTER)
+
+ sizer.Add(exitBut, (1,3))
+
+ self.SetSizerAndFit(sizer)
+
+ wx.EVT_CLOSE(self, self.OnCloseWindow)
+
+ def OnCloseWindow(self, event):
+ self.Destroy()
+
+class App(wx.App):
+ def OnInit(self):
+ frame = TestFrame(None, title="GridBagSizer Test")
+ self.SetTopWindow(frame)
+ frame.Show(True)
+ return True
+
+if __name__ == "__main__":
+ app = App(0)
+ app.MainLoop()
+
+
diff --git a/etg/_core.py b/etg/_core.py
index e7a766e2..0648f15b 100644
--- a/etg/_core.py
+++ b/etg/_core.py
@@ -19,7 +19,8 @@ DOCSTRING = ""
# The classes and/or the basename of the Doxygen XML files to be processed by
# this script.
ITEMS = [ ]
-
+
+
# The list of other ETG scripts and back-end generator modules that are
# included as part of this module. These items are in their own etg scripts
@@ -228,7 +229,14 @@ def run():
method calls from non-GUI threads. Any extra positional or
keyword args are passed on to the callable when it is called.
- :see: `CallLater`""",
+ :param callableObj: the callable object
+ :param args: arguments to be passed to the callable object
+ :param kw: keywords to be passed to the callable object
+
+ .. seealso::
+ :class:`CallLater`
+
+ """,
body="""\
assert callable(callableObj), "callableObj is not callable"
app = wx.GetApp()
@@ -260,7 +268,15 @@ def run():
the timer completes, automatically cleaning up the wx.CallLater
object.
- :see: `CallAfter`""",
+ :param int millis: number of milli seconds
+ :param callableObj: the callable object
+ :param args: arguments to be passed to the callable object
+ :param kw: keywords to be passed to the callable object
+
+ ::seealso:
+ :func:`CallAfter`
+
+ """,
items = [
PyFunctionDef('__init__', '(self, millis, callableObj, *args, **kwargs)',
body="""\
@@ -278,7 +294,14 @@ def run():
PyFunctionDef('__del__', '(self)', 'self.Stop()'),
PyFunctionDef('Start', '(self, millis=None, *args, **kwargs)',
- doc="(Re)start the timer",
+ doc="""\
+ (Re)start the timer
+
+ :param int millis: number of milli seconds
+ :param args: arguments to be passed to the callable object
+ :param kw: keywords to be passed to the callable object
+
+ """,
body="""\
self.hasRun = False
if millis is not None:
@@ -312,14 +335,28 @@ def run():
(Re)set the args passed to the callable object. This is
useful in conjunction with Restart if you want to schedule a
new call to the same callable object but with different
- parameters.""",
+ parameters.
+
+ :param args: arguments to be passed to the callable object
+ :param kw: keywords to be passed to the callable object
+
+ """,
body="""\
self.args = args
self.kwargs = kwargs"""),
- PyFunctionDef('HasRun', '(self)', 'return self.hasRun'),
- PyFunctionDef('GetResult', '(self)', 'return self.result'),
-
+ PyFunctionDef('HasRun', '(self)', 'return self.hasRun',
+ doc="""\
+ :rtype: boolean
+
+ """),
+
+ PyFunctionDef('GetResult', '(self)', 'return self.result',
+ doc="""\
+ :rtype: result from callable
+
+ """),
+
PyFunctionDef('Notify', '(self)',
doc="The timer has expired so call the callable.",
body="""\
diff --git a/etg/app.py b/etg/app.py
index 7bb86000..1e052c2a 100644
--- a/etg/app.py
+++ b/etg/app.py
@@ -343,7 +343,7 @@ def run():
app to terminate upon a Ctrl-C in the console like other
GUI apps will.
- :note: You should override OnInit to do applicaition
+ :note: You should override OnInit to do application
initialization to ensure that the system, toolkit and
wxWidgets are fully initialized.
""",
diff --git a/etgtools/sphinx_generator.py b/etgtools/sphinx_generator.py
index 3efba2a8..aba62d87 100644
--- a/etgtools/sphinx_generator.py
+++ b/etgtools/sphinx_generator.py
@@ -20,6 +20,7 @@ import os
import operator
import shutil
import textwrap
+import glob
from StringIO import StringIO
@@ -41,6 +42,7 @@ from sphinxtools.utilities import FindControlImages, MakeSummary, PickleItem
from sphinxtools.utilities import ChopDescription, PythonizeType, Wx2Sphinx
from sphinxtools.utilities import PickleClassInfo, IsNumeric
from sphinxtools.utilities import Underscore2Capitals, CountSpaces
+from sphinxtools.utilities import FormatContributedSnippets
from sphinxtools.constants import VERSION, REMOVED_LINKS, SECTIONS
from sphinxtools.constants import MAGIC_METHODS, MODULENAME_REPLACE
@@ -1512,9 +1514,9 @@ class XRef(Node):
else:
text = ':ref:`%s`'%Wx2Sphinx(stripped)[1]
-
- return space_before + text + space_after + ConvertToPython(tail)
+ return space_before + text + space_after + ConvertToPython(tail)
+
# ----------------------------------------------------------------------- #
@@ -1578,6 +1580,8 @@ class ComputerOutput(Node):
text += ConvertToPython(self.element.tail)
space_before, space_after = CountSpaces(text)
+ if space_before == '':
+ space_before = ' '
return space_before + text + space_after
@@ -1626,15 +1630,43 @@ class Emphasis(Node):
if self.element.tag == 'emphasis':
format = '`%s`'
+ emphasys = '`'
elif self.element.tag == 'bold':
format = '**%s**'
+ emphasys = '**'
spacing = ('ParameterList' in self.GetHierarchy() and [' '] or [''])[0]
text = Node.Join(self, with_tail=False)
- if text.strip():
- text = spacing + format % text.strip()
+ if self.children:
+
+ startPos = 0
+ newText = spacing
+
+ for child in self.children:
+ childText = child.Join()
+
+ tail = child.element.tail
+ tail = (tail is not None and [tail] or [''])[0]
+
+ childText = childText.replace(ConvertToPython(tail), '')
+ fullChildText = child.Join()
+ endPos = text.index(childText)
+
+ newText += ' ' + emphasys + text[startPos:endPos].strip() + emphasys + ' '
+ newText += childText + ' '
+ remaining = fullChildText.replace(childText, '')
+ newText += emphasys + remaining.strip() + emphasys + ' '
+
+ startPos = endPos
+
+ text = newText
+
+ else:
+
+ if text.strip():
+ text = spacing + format % text.strip()
if self.element.tail:
text += ConvertToPython(self.element.tail)
@@ -1776,6 +1808,8 @@ class XMLDocString(object):
self.class_name = ''
self.snippet_count = 0
+ self.contrib_snippets = []
+
self.table_count = 0
self.list_level = 1
@@ -1787,7 +1821,7 @@ class XMLDocString(object):
self.appearance = []
self.overloads = []
-
+
if isinstance(xml_item, extractors.MethodDef):
self.kind = 'method'
elif isinstance(xml_item, (extractors.FunctionDef, extractors.PyFunctionDef)):
@@ -2050,13 +2084,29 @@ class XMLDocString(object):
dummy, fullname = Wx2Sphinx(name)
elif self.kind == 'method':
method = self.xml_item
- if method.isCtor:
+ if hasattr(method, 'isCtor') and method.isCtor:
method_name = '__init__'
+
+ if hasattr(method, 'className') and method.className is not None:
+ klass = RemoveWxPrefix(method.className)
+ else:
+ klass = RemoveWxPrefix(method.klass.name)
+
+ method_name = '%s.%s'%(klass, method_name)
else:
method_name = method.name or method.pyName
- method_name = RemoveWxPrefix(method_name)
- dummy, fullname = Wx2Sphinx(method.className)
- fullname = fullname + '.' + method_name
+ if hasattr(method, 'className') and method.className is not None:
+ klass = RemoveWxPrefix(method.className)
+ method_name = '%s.%s'%(klass, method_name)
+ elif hasattr(method, 'klass'):
+ klass = RemoveWxPrefix(method.klass.name)
+ method_name = '%s.%s'%(klass, method_name)
+ else:
+ method_name = RemoveWxPrefix(method_name)
+ method_name = '%s'%method_name
+ klass = None
+
+ dummy, fullname = Wx2Sphinx(method_name)
elif self.kind == 'function':
function = self.xml_item
name = function.pyName or function.name
@@ -2090,7 +2140,17 @@ class XMLDocString(object):
converted_py = os.path.join(SNIPPETROOT, 'python', 'converted', fullname + '.%d.py'%self.snippet_count)
return cpp_file, python_file, converted_py
-
+
+
+ def HuntContributedSnippets(self):
+
+ fullname = self.GetFullName()
+ contrib_folder = os.path.join(SNIPPETROOT, 'python', 'contrib')
+
+ possible_py = glob.glob(os.path.normpath(contrib_folder + '/' + fullname + '*.py'))
+
+ return possible_py
+
# -----------------------------------------------------------------------
@@ -2159,6 +2219,13 @@ class XMLDocString(object):
subs_desc = templates.TEMPLATE_SUBCLASSES % subs
stream.write(subs_desc)
+ possible_py = self.HuntContributedSnippets()
+
+ if possible_py:
+ possible_py.sort()
+ snippets = FormatContributedSnippets(self.kind, possible_py)
+ stream.write(snippets)
+
if klass.method_list:
summary = MakeSummary(name, klass.method_list, templates.TEMPLATE_METHOD_SUMMARY, 'meth')
stream.write(summary)
@@ -2381,6 +2448,14 @@ class XMLDocString(object):
stream.write('\n\n')
self.Reformat(stream)
+
+ possible_py = self.HuntContributedSnippets()
+
+ if possible_py:
+ possible_py.sort()
+ snippets = FormatContributedSnippets(self.kind, possible_py)
+ stream.write(snippets)
+
stream.write("\n\n")
if not self.is_overload and write:
@@ -2418,6 +2493,13 @@ class XMLDocString(object):
self.Reformat(stream)
+ possible_py = self.HuntContributedSnippets()
+
+ if possible_py:
+ possible_py.sort()
+ snippets = FormatContributedSnippets(self.kind, possible_py)
+ stream.write(snippets)
+
if not self.is_overload and write:
PickleItem(stream.getvalue(), self.current_module, name, 'function')
@@ -2494,8 +2576,11 @@ class XMLDocString(object):
newline = line
if 'supports the following styles:' in line:
- docstrings += templates.TEMPLATE_WINDOW_STYLES % class_name
-
+ if class_name is not None:
+ # Crappy wxWidgets docs!!! They put the Window Styles inside the
+ # constructor!!!
+ docstrings += templates.TEMPLATE_WINDOW_STYLES % class_name
+
elif 'The following event handler macros' in line:
last = line.index(':')
line = line[last+1:].strip()
@@ -2935,12 +3020,18 @@ class SphinxGenerator(generators.DocsGeneratorBase):
stream = StringIO()
stream.write('\n .. method:: %s%s\n\n' % (pm.name, pm.argsString))
- docstrings = ConvertToPython(pm.pyDocstring).replace('\n', ' ')
+## docstrings = ConvertToPython(pm.pyDocstring).replace('\n', ' ')
+ docstrings = ConvertToPython(pm.pyDocstring)
newdocs = ''
+ spacer = ' '*6
+
for line in docstrings.splitlines():
- newdocs += ' '*6 + line + "\n"
-
+ if not line.startswith(spacer):
+ newdocs += spacer + line + "\n"
+ else:
+ newdocs += line + "\n"
+
stream.write(newdocs + '\n\n')
name = RemoveWxPrefix(self.current_class.name) or self.current_class.pyName
diff --git a/sphinxtools/constants.py b/sphinxtools/constants.py
index 9adea49e..015b37ff 100644
--- a/sphinxtools/constants.py
+++ b/sphinxtools/constants.py
@@ -144,7 +144,7 @@ HTML_REPLACE = ['module', 'function', 'method', 'class', 'classmethod', 'staticm
# The SVN revision of wxWidgets/Phoenix used to build the Sphinx docs.
# There must be a more intelligent way to get this information automatically.
-SVN_REVISION = '71022'
+SVN_REVISION = '71066'
# Today's date representation for the Sphinx HTML docs
TODAY = datetime.date.today().strftime('%d %B %Y')
diff --git a/sphinxtools/postprocess.py b/sphinxtools/postprocess.py
index ed1442c5..f481ecc4 100644
--- a/sphinxtools/postprocess.py
+++ b/sphinxtools/postprocess.py
@@ -145,7 +145,10 @@ def BuildEnumsAndMethods(sphinxDir):
text = text.replace(':note:', '.. note::')
text = text.replace(':see:', '.. seealso::')
text = text.replace('`String`&', 'string')
-
+ text = text.replace('See also\n', '.. seealso:: ')
+ # Avoid Sphinx warnings on wx.TreeCtrl
+ text = text.replace('**( `', '** ( `')
+
if text != orig_text:
fid = open(input, 'wt')
fid.write(text)
@@ -184,8 +187,14 @@ def BuildEnumsAndMethods(sphinxDir):
# ----------------------------------------------------------------------- #
def FindInherited(input, class_summary, enum_base, text):
-
- regex = re.findall(':meth:\S+', text)
+
+ # Malformed inter-links
+ regex = re.findall(r'\S:meth:\S+', text)
+ for regs in regex:
+ newreg = regs[0] + ' ' + regs[1:]
+ text = text.replace(regs, newreg)
+
+ regex = re.findall(r':meth:\S+', text)
for regs in regex:
@@ -304,20 +313,25 @@ def ReformatFunctions(file):
label = local_file.split('.')[0:-2][0]
names = functions.keys()
+ names = [name.lower() for name in names]
names.sort()
text = templates.TEMPLATE_FUNCTION_SUMMARY % (label, label)
letters = []
for fun in names:
- if fun[0] not in letters:
- letters.append(fun[0].upper())
+ upper = fun[0].upper()
+ if upper not in letters:
+ letters.append(upper)
- text += ' | '.join(['`%s`_'%letter for letter in letters])
+ text += ' | '.join([':ref:`%s <%s %s>`'%(letter, label, letter) for letter in letters])
text += '\n\n\n'
+ names = functions.keys()
+ names = sorted(names, key=str.lower)
+
for letter in letters:
- text += '%s\n^\n\n'%letter
+ text += '.. _%s %s:\n\n%s\n^\n\n'%(label, letter, letter)
for fun in names:
if fun[0].upper() != letter:
continue
diff --git a/sphinxtools/templates.py b/sphinxtools/templates.py
index 30aabc1f..f34b0de7 100644
--- a/sphinxtools/templates.py
+++ b/sphinxtools/templates.py
@@ -198,6 +198,12 @@ TEMPLATE_EVENTS = '''
'''
+TEMPLATE_CONTRIB = '''
+
+|user| Contributed Examples
+===========================
+
+'''
# Template used to generate the widgets gallery (this needs some work)
TEMPLATE_GALLERY = '''
diff --git a/sphinxtools/utilities.py b/sphinxtools/utilities.py
index 7d6baf7f..89772810 100644
--- a/sphinxtools/utilities.py
+++ b/sphinxtools/utilities.py
@@ -19,6 +19,8 @@ import cPickle
from UserDict import UserDict
# Phoenix-specific imports
+from templates import TEMPLATE_CONTRIB
+
from constants import IGNORE, PUNCTUATION
from constants import CPP_ITEMS, VERSION, VALUE_MAP
from constants import RE_KEEP_SPACES
@@ -587,3 +589,31 @@ def Wx2Sphinx(name):
# ----------------------------------------------------------------------- #
+
+def FormatContributedSnippets(kind, contrib_snippets):
+
+ spacer = ''
+ if kind == 'function':
+ spacer = 3*' '
+ elif kind == 'method':
+ spacer = 6*' '
+
+ if kind == 'class':
+ text = TEMPLATE_CONTRIB
+ else:
+ text = spacer + '\n**Contributed Examples:**\n\n'
+
+ for indx, snippet in enumerate(contrib_snippets):
+ fid = open(snippet, 'rt')
+ lines = fid.readlines()
+ fid.close()
+ user = lines[0].replace('##', '').strip()
+
+ text += '\n' + spacer + 'Example %d (%s)::\n\n'%(indx+1, user)
+
+ for line in lines[1:]:
+ text += 4*' '+ spacer + line
+
+ text += '\n'
+
+ return text