Beispiel #1
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    module.check4unittest = False

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addHeaderCode('#include <wxpy_api.h>')

    module.addInclude(INCLUDES)
    module.includePyCode('src/core_ex.py', order=10)

    module.addPyFunction(
        'version',
        '()',
        doc="""Returns a string containing version and port info""",
        body="""\
            if wx.Port == '__WXMSW__':
                port = 'msw'
            elif wx.Port == '__WXMAC__':
                if 'wxOSX-carbon' in wx.PlatformInfo:
                    port = 'osx-carbon'
                else:
                    port = 'osx-cocoa'
            elif wx.Port == '__WXGTK__':
                port = 'gtk'
                if 'gtk2' in wx.PlatformInfo:
                    port = 'gtk2'
                elif 'gtk3' in wx.PlatformInfo:
                    port = 'gtk3'
            else:
                port = '???'
            return "%s %s (phoenix)" % (wx.VERSION_STRING, port)
            """)

    module.addPyFunction('CallAfter',
                         '(callableObj, *args, **kw)',
                         doc="""\
            Call the specified function after the current and pending event
            handlers have been completed.  This is also good for making GUI
            method calls from non-GUI threads.  Any extra positional or
            keyword args are passed on to the callable when it is called.
            
            :param PyObject 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::
                :ref:`wx.CallLater`
            
            """,
                         body="""\
            assert callable(callableObj), "callableObj is not callable"
            app = wx.GetApp()
            assert app is not None, 'No wx.App created yet'
        
            if not hasattr(app, "_CallAfterId"):
                app._CallAfterId = wx.NewEventType()
                app.Connect(-1, -1, app._CallAfterId,
                            lambda event: event.callable(*event.args, **event.kw) )
            evt = wx.PyEvent()
            evt.SetEventType(app._CallAfterId)
            evt.callable = callableObj
            evt.args = args
            evt.kw = kw
            wx.PostEvent(app, evt)""")

    module.addPyClass(
        'CallLater', ['object'],
        doc="""\
            A convenience class for :class:`wx.Timer`, that calls the given callable
            object once after the given amount of milliseconds, passing any
            positional or keyword args.  The return value of the callable is
            available after it has been run with the :meth:`~wx.CallLater.GetResult`
            method.
            
            If you don't need to get the return value or restart the timer
            then there is no need to hold a reference to this object.  It will
            hold a reference to itself while the timer is running (the timer
            has a reference to :meth:`~wx.CallLater.Notify`) but the cycle will be
            broken when the timer completes, automatically cleaning up the
            :class:`wx.CallLater` object.
                        
            .. seealso::
                :func:`wx.CallAfter`
                
            """,
        items=[
            PyFunctionDef('__init__',
                          '(self, millis, callableObj, *args, **kwargs)',
                          doc="""\
                    Constructs a new :class:`wx.CallLater` object.

                    :param int millis: number of milliseconds to delay until calling the callable object
                    :param PyObject callableObj: the callable object
                    :param args: arguments to be passed to the callable object
                    :param kw: keywords to be passed to the callable object
                """,
                          body="""\
                    assert callable(callableObj), "callableObj is not callable"
                    self.millis = millis
                    self.callable = callableObj
                    self.SetArgs(*args, **kwargs)
                    self.runCount = 0
                    self.running = False
                    self.hasRun = False
                    self.result = None
                    self.timer = None
                    self.Start()"""),
            PyFunctionDef('__del__', '(self)', 'self.Stop()'),
            PyFunctionDef('Start',
                          '(self, millis=None, *args, **kwargs)',
                          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:
                        self.millis = millis
                    if args or kwargs:
                        self.SetArgs(*args, **kwargs)
                    self.Stop()
                    self.timer = wx.PyTimer(self.Notify)
                    self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
                    self.running = True"""),
            PyCodeDef('Restart = Start'),
            PyFunctionDef('Stop',
                          '(self)',
                          doc="Stop and destroy the timer.",
                          body="""\
                    if self.timer is not None:
                        self.timer.Stop()
                        self.timer = None"""),
            PyFunctionDef(
                'GetInterval', '(self)', """\
                if self.timer is not None:
                    return self.timer.GetInterval()
                else:
                    return 0"""),
            PyFunctionDef(
                'IsRunning', '(self)',
                """return self.timer is not None and self.timer.IsRunning()"""
            ),
            PyFunctionDef('SetArgs',
                          '(self, *args, **kwargs)',
                          doc="""\
                    (Re)set the args passed to the callable object.  This is
                    useful in conjunction with :meth:`Start` if
                    you want to schedule a new call to the same callable
                    object but with different 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',
                          doc="""\
                    Returns whether or not the callable has run.
                    
                    :rtype: bool
                    
                    """),
            PyFunctionDef('GetResult',
                          '(self)',
                          'return self.result',
                          doc="""\
                    Returns the value of the callable.
                    
                    :rtype: a Python object
                    :return: result from callable                    
                    """),
            PyFunctionDef('Notify',
                          '(self)',
                          doc="The timer has expired so call the callable.",
                          body="""\
                    if self.callable and getattr(self.callable, 'im_self', True):
                        self.runCount += 1
                        self.running = False
                        self.result = self.callable(*self.args, **self.kwargs)
                    self.hasRun = True
                    if not self.running:
                        # if it wasn't restarted, then cleanup
                        wx.CallAfter(self.Stop)"""),
            PyPropertyDef('Interval', 'GetInterval'),
            PyPropertyDef('Result', 'GetResult'),
        ])

    module.addPyCode(
        "FutureCall = deprecated(CallLater, 'Use CallLater instead.')")

    module.addPyCode("""\
        def GetDefaultPyEncoding():
            return "utf-8"
        GetDefaultPyEncoding = deprecated(GetDefaultPyEncoding, msg="wxPython now always uses utf-8")
        """)

    module.addCppFunction(
        'bool',
        'IsMainThread',
        '()',
        doc=
        "Returns ``True`` if the current thread is what wx considers the GUI thread.",
        body="return wxThread::IsMain();")

    module.addInitializerCode("""\
        wxPyPreInit(sipModuleDict);
        """)

    # This code is inserted into the module initialization function
    module.addPostInitializerCode("""\
        wxPyCoreModuleInject(sipModuleDict);
        """)
    # Here is the function it calls
    module.includeCppCode('src/core_ex.cpp')
    module.addItem(etgtools.WigCode("void _wxPyCleanup();"))

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #2
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addCppCode("""
    #if !wxUSE_HOTKEY
    #define wxEVT_HOTKEY 0
    #endif
    """)

    # Missing in 3.1.6
    module.addItem(
        etgtools.WigCode("""\
        wxEventType wxEVT_FULLSCREEN /PyName=wxEVT_FULLSCREEN/;
        """))

    module.addPyClass(
        'PyEventBinder', ['object'],
        doc="""\
            Instances of this class are used to bind specific events to event handlers.
            """,
        items=[
            PyFunctionDef('__init__',
                          '(self, evtType, expectedIDs=0)',
                          body="""\
                    if expectedIDs not in [0, 1, 2]:
                        raise ValueError("Invalid number of expectedIDs")
                    self.expectedIDs = expectedIDs

                    if isinstance(evtType, (list, tuple)):
                        self.evtType = list(evtType)
                    else:
                        self.evtType = [evtType]
                    """),
            PyFunctionDef(
                'Bind',
                '(self, target, id1, id2, function)',
                doc=
                """Bind this set of event types to target using its Connect() method.""",
                body="""\
                    for et in self.evtType:
                        target.Connect(id1, id2, et, function)
                    """),
            PyFunctionDef('Unbind',
                          '(self, target, id1, id2, handler=None)',
                          doc="""Remove an event binding.""",
                          body="""\
                    success = 0
                    for et in self.evtType:
                        success += int(target.Disconnect(id1, id2, et, handler))
                    return success != 0
                    """),
            PyFunctionDef('_getEvtType',
                          '(self)',
                          doc="""\
                    Make it easy to get to the default wxEventType typeID for this
                    event binder.
                    """,
                          body="""return self.evtType[0]"""),
            PyPropertyDef('typeId', '_getEvtType'),
            PyFunctionDef('__call__',
                          '(self, *args)',
                          deprecated="Use :meth:`EvtHandler.Bind` instead.",
                          doc="""\
                    For backwards compatibility with the old ``EVT_*`` functions.
                    Should be called with either (window, func), (window, ID,
                    func) or (window, ID1, ID2, func) parameters depending on the
                    type of the event.
                    """,
                          body="""\
                    assert len(args) == 2 + self.expectedIDs
                    id1 = ID_ANY
                    id2 = ID_ANY
                    target = args[0]
                    if self.expectedIDs == 0:
                        func = args[1]
                    elif self.expectedIDs == 1:
                        id1 = args[1]
                        func = args[2]
                    elif self.expectedIDs == 2:
                        id1 = args[1]
                        id2 = args[2]
                        func = args[3]
                    else:
                        raise ValueError("Unexpected number of IDs")

                    self.Bind(target, id1, id2, func)
                    """)
        ])

    module.includePyCode('src/event_ex.py')

    #---------------------------------------
    # wxEvtHandler
    c = module.find('wxEvtHandler')
    c.addPrivateCopyCtor()
    c.addPublic()

    c.includeCppCode('src/event_ex.cpp')

    # Ignore the Connect/Disconnect and Bind/Unbind methods (and all overloads) for now.
    for item in c.allItems():
        if item.name in ['Connect', 'Disconnect', 'Bind', 'Unbind']:
            item.ignore()

    # Connect and Disconnect methods for wxPython. Hold a reference to the
    # event handler function in the event table, so we can fetch it later when
    # it is time to handle the event.
    c.addCppMethod(
        'void',
        'Connect',
        '(int id, int lastId, wxEventType eventType, PyObject* func)',
        doc="Make an entry in the dynamic event table for an event binding.",
        body="""\
            if (PyCallable_Check(func)) {
                self->Connect(id, lastId, eventType,
                              (wxObjectEventFunction)&wxPyCallback::EventThunker,
                              new wxPyCallback(func));
            }
            else if (func == Py_None) {
                self->Disconnect(id, lastId, eventType,
                                 (wxObjectEventFunction)(wxEventFunction)
                                 &wxPyCallback::EventThunker);
            }
            else {
                PyErr_SetString(PyExc_TypeError, "Expected callable object or None.");
            }
        """)

    c.addCppMethod(
        'bool',
        'Disconnect', '(int id, int lastId=-1, '
        'wxEventType eventType=wxEVT_NULL, '
        'PyObject* func=NULL)',
        doc=
        "Remove an event binding by removing its entry in the dynamic event table.",
        body="""\
            if (func && func != Py_None) {
                // Find the current matching binder that has this function
                // pointer and disconnect that one.  Unfortunately since we
                // wrapped the PyObject function pointer in another object we
                // have to do the searching ourselves...
                size_t cookie;
                wxDynamicEventTableEntry *entry = self->GetFirstDynamicEntry(cookie);
                while (entry)
                {
                    if ((entry->m_id == id) &&
                        ((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
                        ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
                        entry->m_fn->IsMatching(wxObjectEventFunctor((wxObjectEventFunction)&wxPyCallback::EventThunker, NULL)) &&
                        (entry->m_callbackUserData != NULL))
                    {
                        wxPyThreadBlocker block;
                        wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData;
                        // NOTE: Just comparing PyObject pointers is not enough, as bound
                        // methods can result in different PyObjects each time obj.Method
                        // is evaluated. (!!!)
                        if (PyObject_RichCompareBool(cb->m_func, func, Py_EQ) == 1) {
                            delete cb;
                            // Set callback data to a known value instead of NULL to
                            // ensure Disconnect() removes the correct handler.
                            entry->m_callbackUserData = new wxObject();
                            // Now Disconnect should work
                            return self->Disconnect(id, lastId, eventType,
                                                    (wxObjectEventFunction)&wxPyCallback::EventThunker,
                                                    entry->m_callbackUserData);
                        }
                    }
                    entry = self->GetNextDynamicEntry(cookie);
                }
                return false;
            }
            else {
                return self->Disconnect(id, lastId, eventType,
                                        (wxObjectEventFunction)&wxPyCallback::EventThunker);
            }
        """)

    # Ignore the C++ version of CallAfter. We have our own.
    # TODO: If we want to support this we'll need concrete implementations of
    # the template, probably using PyObject* args.
    for m in c.find('CallAfter').all():
        m.ignore()

    c.find('QueueEvent.event').transfer = True
    module.find('wxQueueEvent.event').transfer = True

    # TODO: If we don't need to use the wxEvtHandler's client data for our own
    # tracking then enable these....
    c.find('GetClientObject').ignore()
    c.find('SetClientObject').ignore()
    c.find('GetClientData').ignore()
    c.find('SetClientData').ignore()

    # We only care about overriding a few virtuals, ignore the rest.
    tools.removeVirtuals(c)
    c.find('ProcessEvent').isVirtual = True
    c.find('TryBefore').isVirtual = True
    c.find('TryAfter').isVirtual = True
    c.find('TryBefore').ignore(False)
    c.find('TryAfter').ignore(False)

    # Release the GIL for potentially blocking or long-running functions
    c.find('ProcessEvent').releaseGIL()
    c.find('ProcessEventLocally').releaseGIL()
    c.find('SafelyProcessEvent').releaseGIL()
    c.find('ProcessPendingEvents').releaseGIL()

    c.addPyMethod(
        'Bind',
        '(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)',
        doc="""\
            Bind an event to an event handler.

            :param event: One of the ``EVT_*`` event binder objects that
                          specifies the type of event to bind.

            :param handler: A callable object to be invoked when the
                            event is delivered to self.  Pass ``None`` to
                            disconnect an event handler.

            :param source: Sometimes the event originates from a
                           different window than self, but you still
                           want to catch it in self.  (For example, a
                           button event delivered to a frame.)  By
                           passing the source of the event, the event
                           handling system is able to differentiate
                           between the same event type from different
                           controls.

            :param id: Used to spcify the event source by ID instead
                       of instance.

            :param id2: Used when it is desirable to bind a handler
                        to a range of IDs, such as with EVT_MENU_RANGE.
            """,
        body="""\
            assert isinstance(event, wx.PyEventBinder)
            assert callable(handler) or handler is None
            assert source is None or hasattr(source, 'GetId')
            if source is not None:
                id  = source.GetId()
            event.Bind(self, id, id2, handler)
            """)

    c.addPyMethod(
        'Unbind',
        '(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None)',
        doc="""\
            Disconnects the event handler binding for event from `self`.
            Returns ``True`` if successful.
            """,
        body="""\
            if source is not None:
                id  = source.GetId()
            return event.Unbind(self, id, id2, handler)
            """)

    module.addPyCode(
        'PyEvtHandler = wx.deprecated(EvtHandler, "Use :class:`EvtHandler` instead.")'
    )

    #---------------------------------------
    # wxEvent
    c = module.find('wxEvent')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    c.find('Clone').factory = True

    c.find('GetEventUserData').ignore()

    c.addProperty('EventObject GetEventObject SetEventObject')
    c.addProperty('EventType GetEventType SetEventType')
    c.addProperty('Id GetId SetId')
    c.addProperty('Skipped GetSkipped')
    c.addProperty('Timestamp GetTimestamp SetTimestamp')

    #---------------------------------------
    # wxCommandEvent
    c = module.find('wxCommandEvent')

    # The [G|S]etClientData methods deal with untyped void* values, which we
    # don't support. The [G|S]etClientObject methods use wxClientData instances
    # which we have a MappedType for, so make the ClientData methods just be
    # aliases for ClientObjects. From the Python programmer's perspective they
    # would be virtually the same anyway.
    c.find('SetClientObject.clientObject').transfer = True
    c.find('SetClientObject.clientObject').name = 'data'
    c.find('GetClientData').ignore()
    c.find('SetClientData').ignore()
    c.find('GetClientObject').pyName = 'GetClientData'
    c.find('SetClientObject').pyName = 'SetClientData'
    c.addPyMethod('GetClientObject',
                  '(self)',
                  doc="Alias for :meth:`GetClientData`",
                  body="return self.GetClientData()")
    c.addPyMethod('SetClientObject',
                  '(self, data)',
                  doc="Alias for :meth:`SetClientData`",
                  body="self.SetClientData(data)")
    c.addPyProperty('ClientData GetClientData SetClientData')

    c.addProperty('ExtraLong GetExtraLong SetExtraLong')
    c.addProperty('Int GetInt SetInt')
    c.addProperty('Selection GetSelection')
    c.addProperty('String GetString SetString')

    #---------------------------------------
    # wxPaintEvent
    c = module.find('wxPaintEvent')
    # Although the default ctor is listed as public in the interface, it is
    # magically made private for the users of the library as it can only be
    # created within wxWidgets.
    c.find('wxPaintEvent').protection = 'private'

    #---------------------------------------
    # wxKeyEvent
    c = module.find('wxKeyEvent')

    c.find('GetPosition').findOverload('wxCoord').ignore()
    c.find('GetUnicodeKey').type = 'int'

    c.addCppMethod('void',
                   'SetKeyCode',
                   '(int keyCode)',
                   body="self->m_keyCode = keyCode;")

    c.addCppMethod('void',
                   'SetRawKeyCode',
                   '(int rawKeyCode)',
                   body="self->m_rawCode = rawKeyCode;")

    c.addCppMethod('void',
                   'SetRawKeyFlags',
                   '(int rawFlags)',
                   body="self->m_rawFlags = rawFlags;")

    c.addCppMethod('void',
                   'SetUnicodeKey',
                   '(int uniChar)',
                   body="self->m_uniChar = uniChar;")

    c.addProperty('X GetX')
    c.addProperty('Y GetY')
    c.addProperty('KeyCode GetKeyCode SetKeyCode')
    c.addProperty('Position GetPosition')
    c.addProperty('RawKeyCode GetRawKeyCode SetRawKeyCode')
    c.addProperty('RawKeyFlags GetRawKeyFlags SetRawKeyFlags')
    c.addProperty('UnicodeKey GetUnicodeKey SetUnicodeKey')

    #---------------------------------------
    # wxScrollEvent
    c = module.find('wxScrollEvent')
    c.addProperty('Orientation GetOrientation SetOrientation')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxScrollWinEvent
    c = module.find('wxScrollWinEvent')
    c.addProperty('Orientation GetOrientation SetOrientation')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxMouseEvent
    c = module.find('wxMouseEvent')

    c.addCppMethod('void',
                   'SetWheelAxis',
                   '(wxMouseWheelAxis wheelAxis)',
                   body="self->m_wheelAxis = wheelAxis;")

    c.addCppMethod('void',
                   'SetWheelRotation',
                   '(int wheelRotation)',
                   body="self->m_wheelRotation = wheelRotation;")

    c.addCppMethod('void',
                   'SetWheelDelta',
                   '(int wheelDelta)',
                   body="self->m_wheelDelta = wheelDelta;")

    c.addCppMethod('void',
                   'SetLinesPerAction',
                   '(int linesPerAction)',
                   body="self->m_linesPerAction = linesPerAction;")

    c.addCppMethod('void',
                   'SetColumnsPerAction',
                   '(int columnsPerAction)',
                   body="self->m_columnsPerAction = columnsPerAction;")

    c.addProperty('WheelAxis GetWheelAxis SetWheelAxis')
    c.addProperty('WheelRotation GetWheelRotation SetWheelRotation')
    c.addProperty('WheelDelta GetWheelDelta SetWheelDelta')
    c.addProperty('LinesPerAction GetLinesPerAction SetLinesPerAction')
    c.addProperty('ColumnsPerAction GetColumnsPerAction SetColumnsPerAction')

    #---------------------------------------
    # wxSetCursorEvent
    c = module.find('wxSetCursorEvent')
    c.addProperty('Cursor GetCursor SetCursor')
    c.addProperty('X GetX')
    c.addProperty('Y GetY')

    #---------------------------------------
    # wxSizeEvent
    c = module.find('wxSizeEvent')
    c.addProperty('Rect GetRect SetRect')
    c.addProperty('Size GetSize SetSize')

    #---------------------------------------
    # wxMoveEvent
    c = module.find('wxMoveEvent')
    c.addProperty('Rect GetRect SetRect')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxEraseEvent
    c = module.find('wxEraseEvent')
    c.addProperty('DC GetDC')

    #---------------------------------------
    # wxFocusEvent
    c = module.find('wxFocusEvent')
    c.addProperty('Window GetWindow SetWindow')

    #---------------------------------------
    # wxChildFocusEvent
    c = module.find('wxChildFocusEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxActivateEvent
    c = module.find('wxActivateEvent')
    c.addProperty('Active GetActive')

    #---------------------------------------
    # wxMenuEvent
    c = module.find('wxMenuEvent')
    c.addProperty('Menu GetMenu')
    c.addProperty('MenuId GetMenuId')

    #---------------------------------------
    # wxShowEvent
    c = module.find('wxShowEvent')
    c.find('GetShow').ignore()  # deprecated
    c.addProperty('Show IsShown SetShow')

    #---------------------------------------
    # wxDropFilesEvent
    c = module.find('wxDropFilesEvent')

    # wxDropFilesEvent assumes that the C array of wxString objects will
    # continue to live as long as the event object does, and does not take
    # ownership of the array. Unfortunately the mechanism used to turn the
    # Python list into a C array will also delete it after the API call, and
    # so when wxDropFilesEvent tries to access it later the memory pointer is
    # bad. So we'll copy that array into a special holder class and give that
    # one to the API, and also assign a Python reference to it to the event
    # object, so it will get garbage collected later.
    c.find('wxDropFilesEvent.files').array = True
    c.find('wxDropFilesEvent.files').transfer = True
    c.find('wxDropFilesEvent.noFiles').arraySize = True
    c.addHeaderCode('#include "arrayholder.h"')
    c.find('wxDropFilesEvent').setCppCode_sip("""\
        if (files) {
            wxStringCArrayHolder* holder = new wxStringCArrayHolder;
            holder->m_array = files;
            // Make a PyObject for the holder, and transfer its ownership to self.
            PyObject* pyHolder = sipConvertFromNewType(
                    (void*)holder, sipType_wxStringCArrayHolder, (PyObject*)sipSelf);
            Py_DECREF(pyHolder);
            sipCpp = new sipwxDropFilesEvent(id,(int)noFiles, holder->m_array);
        }
        else
            sipCpp = new sipwxDropFilesEvent(id);
        """)

    c.find('GetFiles').type = 'PyObject*'
    c.find('GetFiles').setCppCode("""\
        int         count   = self->GetNumberOfFiles();
        wxString*   files   = self->GetFiles();
        wxPyThreadBlocker   blocker;
        PyObject*   list    = PyList_New(count);
        if (!list) {
            PyErr_SetString(PyExc_MemoryError, "Can't allocate list of files!");
            return NULL;
        }
        for (int i=0; i<count; i++) {
            PyObject* s = wx2PyString(files[i]);
            PyList_SET_ITEM(list, i, s);
        }
        return list;
        """)

    c.addProperty('Files GetFiles')
    c.addProperty('NumberOfFiles GetNumberOfFiles')
    c.addProperty('Position GetPosition')

    #---------------------------------------
    # wxUpdateUIEvent
    c = module.find('wxUpdateUIEvent')
    c.addProperty('Checked GetChecked Check')
    c.addProperty('Enabled GetEnabled Enable')
    c.addProperty('Shown GetShown Show')
    c.addProperty('Text GetText SetText')

    #---------------------------------------
    # wxMouseCaptureChangedEvent
    c = module.find('wxMouseCaptureChangedEvent')
    c.addProperty('CapturedWindow GetCapturedWindow')

    #---------------------------------------
    # wxPaletteChangedEvent
    c = module.find('wxPaletteChangedEvent')
    c.addProperty('ChangedWindow GetChangedWindow SetChangedWindow')

    #---------------------------------------
    # wxQueryNewPaletteEvent
    c = module.find('wxQueryNewPaletteEvent')
    c.addProperty('PaletteRealized GetPaletteRealized SetPaletteRealized')

    #---------------------------------------
    # wxNavigationKeyEvent
    c = module.find('wxNavigationKeyEvent')
    c.addProperty('CurrentFocus GetCurrentFocus SetCurrentFocus')
    c.addProperty('Direction GetDirection SetDirection')

    #---------------------------------------
    # wxWindowCreateEvent
    c = module.find('wxWindowCreateEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxWindowDestroyEvent
    c = module.find('wxWindowDestroyEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxContextMenuEvent
    c = module.find('wxContextMenuEvent')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxIconizeEvent
    c = module.find('wxIconizeEvent')
    # deprecated and removed
    c.find('Iconized').ignore()

    # Apply common fixups for all the event classes
    for name in [n for n in ITEMS if n.endswith('Event')]:
        c = module.find(name)
        tools.fixEventClass(c)

    #---------------------------------------
    # wxEventBlocker
    c = module.find('wxEventBlocker')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #---------------------------------------
    # wxPropagationDisabler
    c = module.find('wxPropagationDisabler')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')
    c.addPrivateCopyCtor()

    #---------------------------------------
    # wxPropagateOnce
    c = module.find('wxPropagateOnce')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')
    c.addPrivateCopyCtor()

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)