Beispiel #1
0
def changeTypeNames(module, oldName, newName, skipTypedef=False):
    """
    Changes the matching type names for functions and parameters to a new
    name, and optionally adds typedefs for the new name as well.
    """
    if not skipTypedef:
        module.addHeaderCode("typedef {old} {new};".format(old=oldName, new=newName))
        module.addItem(extractors.TypedefDef(type=oldName, name=newName))
    for item in module.allItems():
        if isinstance(item, (extractors.FunctionDef, extractors.ParamDef)) and \
                 hasattr(item, 'type') and oldName in item.type:
            item.type = item.type.replace(oldName, newName)
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.addGlobalStr('wxGridNameStr', module.items[0])
    module.addPyCode("""\
        GRID_VALUE_STRING =    "string"
        GRID_VALUE_BOOL =      "bool"
        GRID_VALUE_NUMBER =    "long"
        GRID_VALUE_FLOAT =     "double"
        GRID_VALUE_CHOICE =    "choice"
        GRID_VALUE_DATE =      "date"
        GRID_VALUE_TEXT =      "string"
        GRID_VALUE_LONG =      "long"
        GRID_VALUE_CHOICEINT = "choiceint"
        GRID_VALUE_DATETIME =  "datetime"
        """)

    # Add compatibility constants for these since they've been removed from wxWidgets
    # TODO: Remove these in a future release.
    module.addPyCode("""\
        GRIDTABLE_REQUEST_VIEW_GET_VALUES = 2000
        GRIDTABLE_REQUEST_VIEW_SEND_VALUES = 2001
        """)

    module.insertItem(
        0, etgtools.TypedefDef(type='wxWindow', name='wxGridWindow'))

    #-----------------------------------------------------------------
    c = module.find('wxGridCellCoords')
    assert isinstance(c, etgtools.ClassDef)
    tools.addAutoProperties(c)
    c.find('operator!').ignore()
    c.find('operator=').ignore()

    # Add a typemap for 2 element sequences
    c.convertFromPyObject = tools.convertTwoIntegersTemplate(
        'wxGridCellCoords')

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(ii)", self->GetRow(), self->GetCol());
        """,
                   pyArgsString="() -> (row,col)",
                   briefDoc="Return the row and col properties as a tuple.")

    tools.addGetIMMethodTemplate(module, c, ['Row', 'Col'])

    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',
                  'return "GridCellCoords"+str(self.Get())')
    c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0)')
    c.addPyMethod('__bool__', '(self)', 'return self.Get() != (0,0)')
    c.addPyMethod('__reduce__', '(self)',
                  'return (GridCellCoords, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
    c.addPyMethod(
        '__setitem__', '(self, idx, val)', """\
                  if idx == 0: self.Row = val
                  elif idx == 1: self.Col = val
                  else: raise IndexError
                  """)
    c.addPyCode('GridCellCoords.__safe_for_unpickling__ = True')

    module.addItem(
        tools.wxArrayWrapperTemplate('wxGridCellCoordsArray',
                                     'wxGridCellCoords',
                                     module,
                                     getItemCopy=True))

    #-----------------------------------------------------------------
    c = module.find('wxGridBlockCoords')
    tools.addAutoProperties(c)

    c.find('operator!').ignore()
    c.addCppMethod('int', '__bool__', '()', "return self->operator!();")

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(iiii)", self->GetTopRow(), self->GetLeftCol(), self->GetBottomRow(), self->GetRightCol());
        """,
                   pyArgsString="() -> (topRow, leftCol, bottomRow, rightCol)",
                   briefDoc="Return the block coordinants as a tuple.")

    c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',
                  'return "GridBlockCoords"+str(self.Get())')

    #-----------------------------------------------------------------
    c = module.find('wxGridBlockDiffResult')
    c.find('m_parts').ignore()

    c.addCppMethod(
        'PyObject*', '_getParts', '()', """\
        wxPyThreadBlocker blocker;
        PyObject* ret = PyTuple_New(4);
        if (ret) {
            PyTuple_SET_ITEM(ret, 0, wxPyConstructObject(&self->m_parts[0], "wxGridBlockCoords", false));
            PyTuple_SET_ITEM(ret, 1, wxPyConstructObject(&self->m_parts[1], "wxGridBlockCoords", false));
            PyTuple_SET_ITEM(ret, 2, wxPyConstructObject(&self->m_parts[2], "wxGridBlockCoords", false));
            PyTuple_SET_ITEM(ret, 3, wxPyConstructObject(&self->m_parts[3], "wxGridBlockCoords", false));
        }
        return ret;
        """)
    c.addProperty('m_parts', '_getParts')

    #-----------------------------------------------------------------
    c = module.find('wxGridBlocks')
    c.addPrivateDefaultCtor()
    c.addPrivateAssignOp()

    c.addPyMethod(
        '__iter__', '(self)', 'return PyGridBlocksIterator(self)',
        "Returns a Python iterator for accessing the collection of grid blocks."
    )

    # This class is the Python iterator that knows how to fetch blocks from the
    # wxGridBlocks object
    c.addPyCode("""\
        class PyGridBlocksIterator(object):
            "A Python iterator for GridBlocks objects"
            def __init__(self, blocks):
                self._blocks = blocks
                self._iterator = self._blocks.begin()

            def __next__(self):
                if self._iterator == self._blocks.end():
                    raise StopIteration
                obj = self._iterator._get()
                self._iterator = self._iterator._next()
                return obj
        """)

    # c.find('iterator').addCppMethod('wxGridBlocks::iterator', '_next', '()',
    #                                 "return self->operator++();")
    # c.find('iterator').addCppMethod('const wxGridBlockCoords&', '_get', '()',
    #                                 "return self->operator*();")

    # TODO: Doing these the normal way (above) breaks because it tries to use just
    # "iterator" for the self param type, instead of wxGridBlocks::iterator.
    # That should be fixable, but until then just add these methods the manual
    # sip way.
    c.find('iterator').addItem(
        etgtools.WigCode("""\
        iterator& _next();
        %MethodCode
            PyErr_Clear();
            Py_BEGIN_ALLOW_THREADS
            sipRes = &sipCpp->operator++();
            Py_END_ALLOW_THREADS
            if (PyErr_Occurred()) return 0;
        %End

        const wxGridBlockCoords& _get() const;
        %MethodCode
            PyErr_Clear();
            Py_BEGIN_ALLOW_THREADS
            sipRes =  new ::wxGridBlockCoords(sipCpp->operator*());
            Py_END_ALLOW_THREADS
            if (PyErr_Occurred()) return 0;
        %End

        bool __eq__(const iterator& it) const;
        bool __ne__(const iterator& it) const;
        """))

    #-----------------------------------------------------------------
    c = module.find('wxGridSizesInfo')
    c.find('m_customSizes').ignore(
    )  # TODO: Add support for wxUnsignedToIntHashMap??

    #-----------------------------------------------------------------
    def fixRendererClass(name):
        klass = module.find(name)
        assert isinstance(klass, etgtools.ClassDef)
        tools.fixRefCountedClass(klass)
        tools.addAutoProperties(klass)

        methods = [
            ('Clone', "virtual wxGridCellRenderer* Clone() const /Factory/;"),
            ('Draw',
             "virtual void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, "
             "    const wxRect& rect, int row, int col, bool isSelected);"),
            ('GetBestSize',
             "virtual wxSize GetBestSize(wxGrid& grid, wxGridCellAttr& attr, "
             "    wxDC& dc, int row, int col);"),
        ]
        for method, code in methods:
            if not klass.findItem(method):
                klass.addItem(etgtools.WigCode(code))

    c = module.find('wxGridCellRenderer')
    c.addPrivateCopyCtor()
    c.find('~wxGridCellRenderer').ignore(False)
    c.find('Clone').factory = True
    tools.fixRefCountedClass(c)

    for name in ITEMS:
        if 'Cell' in name and 'Renderer' in name:
            fixRendererClass(name)

    module.addPyCode(
        "PyGridCellRenderer = wx.deprecated(GridCellRenderer, 'Use GridCellRenderer instead.')"
    )

    #-----------------------------------------------------------------

    c = module.find('wxGridActivationResult')
    c.ignore()  # FIXME
    c.addPrivateAssignOp()
    c.instanceCode = 'sipCpp = new wxGridActivationResult::DoNothing();'

    c = module.find('wxGridActivationSource')
    c.ignore()  # FIXME
    c.noDefCtor = True
    c.addPrivateAssignOp()

    #-----------------------------------------------------------------
    def fixEditorClass(name):
        klass = module.find(name)
        assert isinstance(klass, etgtools.ClassDef)
        tools.fixRefCountedClass(klass)
        tools.addAutoProperties(klass)

        methods = [
            ('BeginEdit',
             "virtual void BeginEdit(int row, int col, wxGrid* grid);"),
            ('Clone', "virtual wxGridCellEditor* Clone() const /Factory/;"),
            ('Create',
             "virtual void Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler);"
             ),
            #('EndEdit',    "virtual bool EndEdit(int row, int col, const wxGrid* grid, const wxString& oldval, wxString* newval);"),
            ('ApplyEdit',
             "virtual void ApplyEdit(int row, int col, wxGrid* grid);"),
            ('Reset', "virtual void Reset();"),
            ('GetValue', "virtual wxString GetValue() const;"),
        ]
        for method, code in methods:
            if not klass.findItem(method):
                klass.addItem(etgtools.WigCode(code))

        # Fix up EndEdit so it returns newval on success or None on failure
        pureVirtual = False
        if klass.findItem('EndEdit'):
            klass.find('EndEdit').ignore()
            pureVirtual = True

        # The Python version of EndEdit has a different signature than the
        # C++ version, so we need to take care of mapping between them so the
        # C++ compiler still recognizes this as a match for the virtual
        # method in the base class.
        klass.addCppMethod(
            'PyObject*',
            'EndEdit',
            '(int row, int col, const wxGrid* grid, const wxString& oldval)',
            cppSignature=
            'bool (int row, int col, const wxGrid* grid, const wxString& oldval, wxString* newval)',
            pyArgsString='(row, col, grid, oldval)',
            isVirtual=True,
            isPureVirtual=pureVirtual,
            doc="""\
                End editing the cell.

                This function must check if the current value of the editing cell
                is valid and different from the original value in its string
                form. If not then simply return None.  If it has changed then
                this method should save the new value so that ApplyEdit can
                apply it later and the string representation of the new value
                should be returned.

                Notice that this method shoiuld not modify the grid as the
                change could still be vetoed.
                """,

            # Code for Python --> C++ calls.  Make it return newval or None.
            body="""\
                bool rv;
                wxString newval;
                rv = self->EndEdit(row, col, grid, *oldval, &newval);
                if (rv) {
                    return wx2PyString(newval);
                }
                else {
                    Py_INCREF(Py_None);
                    return Py_None;
                }
                """,

            # Code for C++ --> Python calls. This is used when a C++ method
            # call needs to be reflected to a call to the overridden Python
            # method, so we need to translate between the real C++ signature
            # and the Python signature.
            virtualCatcherCode="""\
                // VirtualCatcherCode for wx.grid.GridCellEditor.EndEdit
                PyObject *result;
                result = sipCallMethod(0, sipMethod, "iiDN", row, col,
                                       const_cast<wxGrid *>(grid),sipType_wxGrid,NULL,
                                       new wxString(oldval),sipType_wxString,NULL);
                if (result == NULL) {
                    if (PyErr_Occurred())
                        PyErr_Print();
                    sipRes = false;
                }
                else if (result == Py_None) {
                    sipRes = false;
                }
                else {
                    sipRes = true;
                    *newval = Py2wxString(result);
                }
                Py_XDECREF(result);
                """ if pureVirtual else "",  # only used with the base class
        )

    c = module.find('wxGridCellEditor')
    c.addPrivateCopyCtor()
    c.find('~wxGridCellEditor').ignore(False)
    c.find('Clone').factory = True
    tools.fixRefCountedClass(c)
    c.find('TryActivate').ignore(
    )  # FIXME: remove this when the compilation issues with wxGridActivationResult is fixed

    c = module.find('wxGridCellActivatableEditor')
    c.ignore()  # FIXME: see above

    c = module.find('wxGridCellChoiceEditor')
    c.find('wxGridCellChoiceEditor').findOverload('count').ignore()

    for name in ITEMS:
        if 'Cell' in name and 'Editor' in name and name != 'wxGridCellActivatableEditor':
            fixEditorClass(name)

    module.addPyCode(
        "PyGridCellEditor = wx.deprecated(GridCellEditor, 'Use GridCellEditor instead.')"
    )

    #-----------------------------------------------------------------
    c = module.find('wxGridCellAttr')
    c.addPrivateCopyCtor()
    c.find('~wxGridCellAttr').ignore(False)
    c.find('Clone').factory = True
    tools.fixRefCountedClass(c)

    c.find('GetAlignment.hAlign').out = True
    c.find('GetAlignment.vAlign').out = True
    c.find('GetNonDefaultAlignment.hAlign').out = True
    c.find('GetNonDefaultAlignment.vAlign').out = True
    c.find('GetSize.num_rows').out = True
    c.find('GetSize.num_cols').out = True

    c.find('SetEditor.editor'
           ).transfer = True  # these are probably redundant now...
    c.find('SetRenderer.renderer').transfer = True

    #-----------------------------------------------------------------
    module.find('wxGridCellRendererPtr').piIgnored = True
    module.find('wxGridCellEditorPtr').piIgnored = True
    module.find('wxGridCellAttrPtr').piIgnored = True

    #-----------------------------------------------------------------
    # The instanceCode attribute is code that is used to make a default
    # instance of the class. We can't create them using the same class in
    # this case because they are abstract.

    c = module.find('wxGridCornerHeaderRenderer')
    c.instanceCode = 'sipCpp = new wxGridCornerHeaderRendererDefault;'

    c = module.find('wxGridRowHeaderRenderer')
    c.instanceCode = 'sipCpp = new wxGridRowHeaderRendererDefault;'

    c = module.find('wxGridColumnHeaderRenderer')
    c.instanceCode = 'sipCpp = new wxGridColumnHeaderRendererDefault;'

    #-----------------------------------------------------------------
    c = module.find('wxGridCellAttrProvider')
    c.addPrivateCopyCtor()

    c.find('SetAttr.attr').transfer = True
    c.find('SetRowAttr.attr').transfer = True
    c.find('SetColAttr.attr').transfer = True

    module.addPyCode(
        "PyGridCellAttrProvider = wx.deprecated(GridCellAttrProvider, 'Use GridCellAttrProvider instead.')"
    )

    #-----------------------------------------------------------------
    c = module.find('wxGridTableBase')
    c.addPrivateCopyCtor()

    c.find('SetAttr.attr').transfer = True
    c.find('SetRowAttr.attr').transfer = True
    c.find('SetColAttr.attr').transfer = True

    module.addPyCode(
        "PyGridTableBase = wx.deprecated(GridTableBase, 'Use GridTableBase instead.')"
    )

    # Make the GetValue methods easier to use from Python.  For example,
    # instead of needing to always return a string, the GetValue in the derived
    # class can return any type (as long as the renderer and editor knows how
    # to deal with it, and the value can be converted to a string for display).
    m = c.find('GetValue')
    m.type = 'PyObject*'
    m.cppSignature = 'wxString (int row, int col)'
    m.setCppCode("return wx2PyString(self->GetValue(row, col));")
    m.virtualCatcherCode = """\
        // virtualCatcherCode for GridTableBase.GetValue
        PyObject *result = sipCallMethod(&sipIsErr, sipMethod, "ii", row, col);
        if (result == NULL) {
            if (PyErr_Occurred())
                PyErr_Print();
            sipRes = "";
        }
        else if (result == Py_None) {
            sipRes = "";
        }
        else {
            if (!PyBytes_Check(result) && !PyUnicode_Check(result)) {
                PyObject* old = result;
                result = PyObject_Str(result);
                Py_DECREF(old);
            }
            sipRes = Py2wxString(result);
        }
        Py_XDECREF(result);
        """

    # SetValue is okay as-is...

    # Replace these virtuals in the base class with Python methods, they just
    # need to call GetValue or SetValue directly since they must already be
    # implemented in the derived Python class because they are pure virtual.
    c.addPyMethod('GetValueAsLong',
                  '(self, row, col)',
                  body="""\
            val = self.GetValue(row, col)
            try:
                return int(val)
            except ValueError:
                return 0
            """,
                  docsIgnored=True)

    c.addPyMethod('GetValueAsDouble',
                  '(self, row, col)',
                  body="""\
            val = self.GetValue(row, col)
            try:
                return float(val)
            except ValueError:
                return 0.0
            """,
                  docsIgnored=True)

    c.addPyMethod('GetValueAsBool',
                  '(self, row, col)',
                  body="""\
            val = self.GetValue(row, col)
            try:
                return bool(val)
            except ValueError:
                return False
            """,
                  docsIgnored=True)

    c.addPyMethod('SetValueAsLong',
                  '(self, row, col, value)',
                  body="self.SetValue(row, col, int(value))",
                  docsIgnored=True)

    c.addPyMethod('SetValueAsDouble',
                  '(self, row, col, value)',
                  body="self.SetValue(row, col, float(value))",
                  docsIgnored=True)

    c.addPyMethod('SetValueAsBool',
                  '(self, row, col, value)',
                  body="self.SetValue(row, col, bool(value))",
                  docsIgnored=True)

    # Should we add support for using generic PyObjects in the *AsCustom
    # methods? I don't think it is necessary due to the GetValue
    # modifications above, so for now, at least, let.s just ignore them.
    c.find('GetValueAsCustom').ignore()
    c.find('SetValueAsCustom').ignore()

    #-----------------------------------------------------------------
    c = module.find('wxGridStringTable')
    c.addPrivateCopyCtor()

    #-----------------------------------------------------------------
    c = module.find('wxGridTableMessage')
    c.addPrivateCopyCtor()

    #-----------------------------------------------------------------
    c = module.find('wxGrid')
    tools.fixWindowClass(c, ignoreProtected=False)
    c.bases = ['wxScrolledCanvas']

    c.find('GetColLabelAlignment.horiz').out = True
    c.find('GetColLabelAlignment.vert').out = True
    c.find('GetRowLabelAlignment.horiz').out = True
    c.find('GetRowLabelAlignment.vert').out = True

    c.find('GetCellAlignment.horiz').out = True
    c.find('GetCellAlignment.vert').out = True
    c.find('GetDefaultCellAlignment.horiz').out = True
    c.find('GetDefaultCellAlignment.vert').out = True

    c.find('RegisterDataType.renderer').transfer = True
    c.find('RegisterDataType.editor').transfer = True

    c.find('SetRowAttr.attr').transfer = True
    c.find('SetColAttr.attr').transfer = True
    c.find('SetCellEditor.editor').transfer = True
    c.find('SetCellRenderer.renderer').transfer = True

    # This overload is deprecated, so don't generate code for it.
    c.find('SetCellValue').findOverload('wxString &val').ignore()

    c.find('SetDefaultEditor.editor').transfer = True
    c.find('SetDefaultRenderer.renderer').transfer = True

    for n in [
            'GetColGridLinePen', 'GetDefaultGridLinePen', 'GetRowGridLinePen'
    ]:
        c.find(n).isVirtual = True

    # The SetTable method can optionally pass ownership of the table
    # object to the grid, so we need to optionally update the
    # ownership of the Python proxy object to match.
    c.find('SetTable').pyName = '_SetTable'
    c.addPyMethod(
        'SetTable',
        '(self, table, takeOwnership=False, selmode=Grid.GridSelectCells)',
        piArgsString=
        '(self, table, takeOwnership=False, selmode=GridSelectCells)',
        doc="Set the Grid Table to be used by this grid.",
        body="""\
            val = self._SetTable(table, takeOwnership, selmode)
            if takeOwnership:
                import wx.siplib
                wx.siplib.transferto(table, self)
            return val
        """)

    # SIP will normally try to add support for overriding this method since
    # it is inherited from super classes, but in this case we want it to be
    # ignored (because IRL it is private in one of the intermediate classes)
    # so we'll tell SIP that it is private here instead.
    c.addItem(
        etgtools.WigCode("""\
        wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
        """,
                         protection='private'))

    # Add a simpler set of names for the wxGridSelectionModes enum
    c.addPyCode("""\
        Grid.SelectCells = Grid.GridSelectCells
        Grid.SelectRows = Grid.GridSelectRows
        Grid.SelectColumns = Grid.GridSelectColumns
        Grid.SelectRowsOrColumns = Grid.GridSelectRowsOrColumns
        """)

    c.find('SetCellAlignment').findOverload('align').ignore()
    c.find('SetCellTextColour').overloads = []

    c.find('GetGridWindowOffset').findOverload('int &x').ignore()

    # Custom code to deal with the wxGridBlockCoordsVector return type of these
    # methods. It's a wxVector, which we'll just convert to a list.

    # TODO: There are a few of these now to we ought to either wrap wxVector, or add
    #       something in tweaker_tools to make adding code like this easier and more
    #       automated.
    code = """\
        wxPyThreadBlocker blocker;
        PyObject* result = PyList_New(0);
        wxGridBlockCoordsVector vector = self->{method}();
        for (size_t idx=0; idx < vector.size(); idx++) {{
            PyObject* obj;
            wxGridBlockCoords* item = new wxGridBlockCoords(vector[idx]);
            obj = wxPyConstructObject((void*)item, "wxGridBlockCoords", true);
            PyList_Append(result, obj);
            Py_DECREF(obj);
        }}
        return result;
        """
    c.find('GetSelectedRowBlocks').type = 'PyObject*'
    c.find('GetSelectedRowBlocks').setCppCode(
        code.format(method='GetSelectedRowBlocks'))
    c.find('GetSelectedColBlocks').type = 'PyObject*'
    c.find('GetSelectedColBlocks').setCppCode(
        code.format(method='GetSelectedColBlocks'))

    #-----------------------------------------------------------------
    c = module.find('wxGridUpdateLocker')
    c.addPrivateCopyCtor()

    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------

    for name in [
            'wxGridSizeEvent', 'wxGridRangeSelectEvent',
            'wxGridEditorCreatedEvent', 'wxGridEvent'
    ]:
        c = module.find(name)
        tools.fixEventClass(c)

    module.addPyCode("""\
        EVT_GRID_CELL_LEFT_CLICK = wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_CLICK )
        EVT_GRID_CELL_RIGHT_CLICK = wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_CLICK )
        EVT_GRID_CELL_LEFT_DCLICK = wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_DCLICK )
        EVT_GRID_CELL_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_DCLICK )
        EVT_GRID_LABEL_LEFT_CLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_CLICK )
        EVT_GRID_LABEL_RIGHT_CLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_CLICK )
        EVT_GRID_LABEL_LEFT_DCLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_DCLICK )
        EVT_GRID_LABEL_RIGHT_DCLICK = wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_DCLICK )
        EVT_GRID_ROW_SIZE = wx.PyEventBinder( wxEVT_GRID_ROW_SIZE )
        EVT_GRID_COL_SIZE = wx.PyEventBinder( wxEVT_GRID_COL_SIZE )
        EVT_GRID_RANGE_SELECT = wx.PyEventBinder( wxEVT_GRID_RANGE_SELECT )
        EVT_GRID_CELL_CHANGING = wx.PyEventBinder( wxEVT_GRID_CELL_CHANGING )
        EVT_GRID_CELL_CHANGED = wx.PyEventBinder( wxEVT_GRID_CELL_CHANGED )
        EVT_GRID_SELECT_CELL = wx.PyEventBinder( wxEVT_GRID_SELECT_CELL )
        EVT_GRID_EDITOR_SHOWN = wx.PyEventBinder( wxEVT_GRID_EDITOR_SHOWN )
        EVT_GRID_EDITOR_HIDDEN = wx.PyEventBinder( wxEVT_GRID_EDITOR_HIDDEN )
        EVT_GRID_EDITOR_CREATED = wx.PyEventBinder( wxEVT_GRID_EDITOR_CREATED )
        EVT_GRID_CELL_BEGIN_DRAG = wx.PyEventBinder( wxEVT_GRID_CELL_BEGIN_DRAG )
        EVT_GRID_COL_MOVE = wx.PyEventBinder( wxEVT_GRID_COL_MOVE )
        EVT_GRID_COL_SORT = wx.PyEventBinder( wxEVT_GRID_COL_SORT )
        EVT_GRID_TABBING = wx.PyEventBinder( wxEVT_GRID_TABBING )

        # The same as above but with the ability to specify an identifier
        EVT_GRID_CMD_CELL_LEFT_CLICK =     wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_CLICK,    1 )
        EVT_GRID_CMD_CELL_RIGHT_CLICK =    wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_CLICK,   1 )
        EVT_GRID_CMD_CELL_LEFT_DCLICK =    wx.PyEventBinder( wxEVT_GRID_CELL_LEFT_DCLICK,   1 )
        EVT_GRID_CMD_CELL_RIGHT_DCLICK =   wx.PyEventBinder( wxEVT_GRID_CELL_RIGHT_DCLICK,  1 )
        EVT_GRID_CMD_LABEL_LEFT_CLICK =    wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_CLICK,   1 )
        EVT_GRID_CMD_LABEL_RIGHT_CLICK =   wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_CLICK,  1 )
        EVT_GRID_CMD_LABEL_LEFT_DCLICK =   wx.PyEventBinder( wxEVT_GRID_LABEL_LEFT_DCLICK,  1 )
        EVT_GRID_CMD_LABEL_RIGHT_DCLICK =  wx.PyEventBinder( wxEVT_GRID_LABEL_RIGHT_DCLICK, 1 )
        EVT_GRID_CMD_ROW_SIZE =            wx.PyEventBinder( wxEVT_GRID_ROW_SIZE,           1 )
        EVT_GRID_CMD_COL_SIZE =            wx.PyEventBinder( wxEVT_GRID_COL_SIZE,           1 )
        EVT_GRID_CMD_RANGE_SELECT =        wx.PyEventBinder( wxEVT_GRID_RANGE_SELECT,       1 )
        EVT_GRID_CMD_CELL_CHANGING =       wx.PyEventBinder( wxEVT_GRID_CELL_CHANGING,      1 )
        EVT_GRID_CMD_CELL_CHANGED =        wx.PyEventBinder( wxEVT_GRID_CELL_CHANGED,       1 )
        EVT_GRID_CMD_SELECT_CELL =         wx.PyEventBinder( wxEVT_GRID_SELECT_CELL,        1 )
        EVT_GRID_CMD_EDITOR_SHOWN =        wx.PyEventBinder( wxEVT_GRID_EDITOR_SHOWN,       1 )
        EVT_GRID_CMD_EDITOR_HIDDEN =       wx.PyEventBinder( wxEVT_GRID_EDITOR_HIDDEN,      1 )
        EVT_GRID_CMD_EDITOR_CREATED =      wx.PyEventBinder( wxEVT_GRID_EDITOR_CREATED,     1 )
        EVT_GRID_CMD_CELL_BEGIN_DRAG =     wx.PyEventBinder( wxEVT_GRID_CELL_BEGIN_DRAG,    1 )
        EVT_GRID_CMD_COL_MOVE =            wx.PyEventBinder( wxEVT_GRID_COL_MOVE,           1 )
        EVT_GRID_CMD_COL_SORT =            wx.PyEventBinder( wxEVT_GRID_COL_SORT,           1 )
        EVT_GRID_CMD_TABBING =             wx.PyEventBinder( wxEVT_GRID_TABBING,            1 )
        """)

    #-----------------------------------------------------------------
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #3
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.

    #-------------------------------------------------------
    c = module.find('wxTreeItemId')
    assert isinstance(c, etgtools.ClassDef)
    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)

    c.addCppMethod('bool', '__eq__', '(const wxTreeItemId* other)', """\
        return *self == *other;
        """)
    c.addCppMethod('bool', '__neq__', '(const wxTreeItemId* other)', """\
        return *self != *other;
        """)

    c.addPyMethod('__hash__', '(self)', """\
        return hash(int(self.GetID()))
        """)

    td = etgtools.TypedefDef(name='wxTreeItemIdValue', type='void*')
    module.insertItemBefore(c, td)

    #-------------------------------------------------------
    module.addPyCode("""\
        def TreeItemData(data):
            return data
        TreeItemData = deprecated(TreeItemData, "The TreeItemData class no longer exists, just pass your object directly to the tree instead.")
        """)

    #-------------------------------------------------------
    c = module.find('wxTreeCtrl')
    tools.fixWindowClass(c)
    module.addGlobalStr('wxTreeCtrlNameStr', before=c)

    # Set all wxTreeItemData parameters to transfer ownership.  Is this still needed with MappedTypes?
    for item in c.allItems():
        if hasattr(item, 'type') and item.type == 'wxTreeItemData *' and \
           isinstance(item, etgtools.ParamDef):
            item.transfer = True

    c.addPyCode("""\
        TreeCtrl.GetItemPyData = wx.deprecated(TreeCtrl.GetItemData, 'Use GetItemData instead.')
        TreeCtrl.SetItemPyData = wx.deprecated(TreeCtrl.SetItemData, 'Use SetItemData instead.')
        TreeCtrl.GetPyData = wx.deprecated(TreeCtrl.GetItemData, 'Use GetItemData instead.')
        TreeCtrl.SetPyData = wx.deprecated(TreeCtrl.SetItemData, 'Use SetItemData instead.')
        """)

    # We can't use wxClassInfo
    c.find('EditLabel.textCtrlClass').ignore()

    # Replace GetSelections with a method that returns a Python list
    # size_t GetSelections(wxArrayTreeItemIds& selection) const;
    c.find('GetSelections').ignore()
    c.addCppMethod(
        'PyObject*',
        'GetSelections',
        '()',
        doc=
        'Returns a list of currently selected items in the tree.  This function '
        'can be called only if the control has the wx.TR_MULTIPLE style.',
        body="""\
        wxPyThreadBlocker blocker;
        PyObject*           rval = PyList_New(0);
        wxArrayTreeItemIds  array;
        size_t              num, x;
        num = self->GetSelections(array);
        for (x=0; x < num; x++) {
            wxTreeItemId *tii = new wxTreeItemId(array.Item(x));
            PyObject* item = wxPyConstructObject((void*)tii, wxT("wxTreeItemId"), true);
            PyList_Append(rval, item);
            Py_DECREF(item);
        }
        return rval;
        """)

    # Change GetBoundingRect to return the rectangle instead of modifying the parameter.
    #bool GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly = false) const;
    c.find('GetBoundingRect').ignore()
    c.addCppMethod('PyObject*',
                   'GetBoundingRect',
                   '(const wxTreeItemId& item, bool textOnly=false)',
                   doc="""\
        Returns the rectangle bounding the item. If textOnly is true,
        only the rectangle around the item's label will be returned, otherwise
        the item's image is also taken into account. The return value may be None
        if the rectangle was not successfully retrieved, such as if the item is
        currently not visible.
        """,
                   isFactory=True,
                   body="""\
        wxRect rect;
        if (self->GetBoundingRect(*item, rect, textOnly)) {
            wxPyThreadBlocker blocker;
            wxRect* r = new wxRect(rect);
            PyObject* val = wxPyConstructObject((void*)r, wxT("wxRect"), true);
            return val;
        }
        else
            RETURN_NONE();
        """)

    # switch the virtualness back on for those methods that need to have it.
    c.find('OnCompareItems').isVirtual = True

    # transfer imagelist ownership
    c.find('AssignImageList.imageList').transfer = True
    c.find('AssignStateImageList.imageList').transfer = True
    c.find('AssignButtonsImageList.imageList').transfer = True

    # Make the cookie values be returned, instead of setting it through the parameter
    c.find('GetFirstChild.cookie').out = True
    c.find('GetNextChild.cookie').inOut = True

    # TODO: These don't exist on MSW, Are they important enough that we
    # should provide them for the other platforms anyway?
    c.find('AssignButtonsImageList').ignore()
    c.find('GetButtonsImageList').ignore()
    c.find('SetButtonsImageList').ignore()

    #-------------------------------------------------------
    c = module.find('wxTreeEvent')
    tools.fixEventClass(c)

    c.addPyCode("""\
        EVT_TREE_BEGIN_DRAG        = PyEventBinder(wxEVT_TREE_BEGIN_DRAG       , 1)
        EVT_TREE_BEGIN_RDRAG       = PyEventBinder(wxEVT_TREE_BEGIN_RDRAG      , 1)
        EVT_TREE_BEGIN_LABEL_EDIT  = PyEventBinder(wxEVT_TREE_BEGIN_LABEL_EDIT , 1)
        EVT_TREE_END_LABEL_EDIT    = PyEventBinder(wxEVT_TREE_END_LABEL_EDIT   , 1)
        EVT_TREE_DELETE_ITEM       = PyEventBinder(wxEVT_TREE_DELETE_ITEM      , 1)
        EVT_TREE_GET_INFO          = PyEventBinder(wxEVT_TREE_GET_INFO         , 1)
        EVT_TREE_SET_INFO          = PyEventBinder(wxEVT_TREE_SET_INFO         , 1)
        EVT_TREE_ITEM_EXPANDED     = PyEventBinder(wxEVT_TREE_ITEM_EXPANDED    , 1)
        EVT_TREE_ITEM_EXPANDING    = PyEventBinder(wxEVT_TREE_ITEM_EXPANDING   , 1)
        EVT_TREE_ITEM_COLLAPSED    = PyEventBinder(wxEVT_TREE_ITEM_COLLAPSED   , 1)
        EVT_TREE_ITEM_COLLAPSING   = PyEventBinder(wxEVT_TREE_ITEM_COLLAPSING  , 1)
        EVT_TREE_SEL_CHANGED       = PyEventBinder(wxEVT_TREE_SEL_CHANGED      , 1)
        EVT_TREE_SEL_CHANGING      = PyEventBinder(wxEVT_TREE_SEL_CHANGING     , 1)
        EVT_TREE_KEY_DOWN          = PyEventBinder(wxEVT_TREE_KEY_DOWN         , 1)
        EVT_TREE_ITEM_ACTIVATED    = PyEventBinder(wxEVT_TREE_ITEM_ACTIVATED   , 1)
        EVT_TREE_ITEM_RIGHT_CLICK  = PyEventBinder(wxEVT_TREE_ITEM_RIGHT_CLICK , 1)
        EVT_TREE_ITEM_MIDDLE_CLICK = PyEventBinder(wxEVT_TREE_ITEM_MIDDLE_CLICK, 1)
        EVT_TREE_END_DRAG          = PyEventBinder(wxEVT_TREE_END_DRAG         , 1)
        EVT_TREE_STATE_IMAGE_CLICK = PyEventBinder(wxEVT_TREE_STATE_IMAGE_CLICK, 1)
        EVT_TREE_ITEM_GETTOOLTIP   = PyEventBinder(wxEVT_TREE_ITEM_GETTOOLTIP,   1)
        EVT_TREE_ITEM_MENU         = PyEventBinder(wxEVT_TREE_ITEM_MENU,         1)

        # deprecated wxEVT aliases
        wxEVT_COMMAND_TREE_BEGIN_DRAG         = wxEVT_TREE_BEGIN_DRAG
        wxEVT_COMMAND_TREE_BEGIN_RDRAG        = wxEVT_TREE_BEGIN_RDRAG
        wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT   = wxEVT_TREE_BEGIN_LABEL_EDIT
        wxEVT_COMMAND_TREE_END_LABEL_EDIT     = wxEVT_TREE_END_LABEL_EDIT
        wxEVT_COMMAND_TREE_DELETE_ITEM        = wxEVT_TREE_DELETE_ITEM
        wxEVT_COMMAND_TREE_GET_INFO           = wxEVT_TREE_GET_INFO
        wxEVT_COMMAND_TREE_SET_INFO           = wxEVT_TREE_SET_INFO
        wxEVT_COMMAND_TREE_ITEM_EXPANDED      = wxEVT_TREE_ITEM_EXPANDED
        wxEVT_COMMAND_TREE_ITEM_EXPANDING     = wxEVT_TREE_ITEM_EXPANDING
        wxEVT_COMMAND_TREE_ITEM_COLLAPSED     = wxEVT_TREE_ITEM_COLLAPSED
        wxEVT_COMMAND_TREE_ITEM_COLLAPSING    = wxEVT_TREE_ITEM_COLLAPSING
        wxEVT_COMMAND_TREE_SEL_CHANGED        = wxEVT_TREE_SEL_CHANGED
        wxEVT_COMMAND_TREE_SEL_CHANGING       = wxEVT_TREE_SEL_CHANGING
        wxEVT_COMMAND_TREE_KEY_DOWN           = wxEVT_TREE_KEY_DOWN
        wxEVT_COMMAND_TREE_ITEM_ACTIVATED     = wxEVT_TREE_ITEM_ACTIVATED
        wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK   = wxEVT_TREE_ITEM_RIGHT_CLICK
        wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK  = wxEVT_TREE_ITEM_MIDDLE_CLICK
        wxEVT_COMMAND_TREE_END_DRAG           = wxEVT_TREE_END_DRAG
        wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK  = wxEVT_TREE_STATE_IMAGE_CLICK
        wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP    = wxEVT_TREE_ITEM_GETTOOLTIP
        wxEVT_COMMAND_TREE_ITEM_MENU          = wxEVT_TREE_ITEM_MENU
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #4
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.

    c = module.find('wxVisualAttributes')
    assert isinstance(c, etgtools.ClassDef)
    # Mark the stucture memebers as read-only, and make copies of the values
    # when fetching them. This is to protect against cases where the
    # VisualAttributes object is transient and may be GC'd while we still are
    # using a reference to a C++ member value.
    c.find('colBg').noSetter = True
    c.find('colBg').getCode = """\
        wxColour* clr = new wxColour(sipCpp->colBg);
        sipPy = wxPyConstructObject((void*)clr, "wxColour", true);
    """
    c.find('colFg').noSetter = True
    c.find('colFg').getCode = """\
        wxColour* clr = new wxColour(sipCpp->colFg);
        sipPy = wxPyConstructObject((void*)clr, "wxColour", true);
    """
    c.find('font').noSetter = True
    c.find('font').getCode = """\
        wxFont* font = new wxFont(sipCpp->font);
        sipPy = wxPyConstructObject((void*)font, "wxFont", true);
    """

    c = module.find('wxWindow')
    assert isinstance(c, etgtools.ClassDef)
    module.addGlobalStr('wxPanelNameStr', c)

    c.find('FindFocus').mustHaveApp()
    c.find('GetCapture').mustHaveApp()

    # First we need to let the wrapper generator know about wxWindowBase since
    # AddChild and RemoveChild need to use that type in order to be virtualized.
    winbase = ClassDef(
        name='wxWindowBase',
        bases=['wxEvtHandler'],
        abstract=True,
        items=[
            MethodDef(name='AddChild',
                      isVirtual=True,
                      type='void',
                      protection='public',
                      items=[ParamDef(name='child', type='wxWindowBase*')]),
            MethodDef(name='RemoveChild',
                      isVirtual=True,
                      type='void',
                      protection='public',
                      items=[ParamDef(name='child', type='wxWindowBase*')])
        ])
    module.insertItemBefore(c, winbase)

    # Now change the base class of wxWindow
    c.bases = ['wxWindowBase']

    # And fix the arg types we get from Doxy
    c.find('AddChild.child').type = 'wxWindowBase*'
    c.find('RemoveChild.child').type = 'wxWindowBase*'

    # We now return you to our regularly scheduled programming...
    c.includeCppCode('src/window_ex.cpp')

    # ignore some overloads that will be ambiguous after wrapping
    c.find('GetChildren').overloads = []
    c.find('GetChildren').noCopy = True
    for name in ['GetVirtualSize', 'GetPosition', 'GetScreenPosition']:
        c.find(name).findOverload('int *').ignore()

    # Fix ClientToScreen/ScreenToClient int * overloads
    for name in ['ClientToScreen', 'ScreenToClient']:
        c.find(name).findOverload('int *').find('x').inOut = True
        c.find(name).findOverload('int *').find('y').inOut = True

    # Like the above, but these also need to transplant the docs from the
    # ignored item to the non-ignored overload.
    for name in ['GetClientSize', 'GetSize']:
        c.find(name).findOverload('int *').ignore()
        item = c.find(name)
        ov = item.overloads[0]
        item.briefDoc = ov.briefDoc
        item.detailedDoc = ov.detailedDoc

    # Release the GIL for potentially blocking or long-running functions
    c.find('PopupMenu').releaseGIL()
    c.find('ProcessEvent').releaseGIL()
    c.find('ProcessWindowEvent').releaseGIL()
    c.find('ProcessWindowEventLocally').releaseGIL()

    # Add a couple wrapper functions for symmetry with the getters of the same name
    c.addPyMethod('SetRect', '(self, rect)', 'return self.SetSize(rect)')
    c.addPyProperty('Rect GetRect SetRect')
    c.addPyMethod('SetClientRect', '(self, rect)',
                  'return self.SetClientSize(rect)')
    c.addPyProperty('ClientRect GetClientRect SetClientRect')

    # Split the overloaded GetTextExtent into two distinct methods, because the
    # resulting method signatures are not different enough from the Python
    # perspective.
    m1 = c.find('GetTextExtent')  #.findOverload('int *')
    assert len(m1.overloads) == 1
    m2 = m1.overloads.pop()
    c.insertItemAfter(m1, m2)

    # Now do the needed tweaks for the full GetFullTextExtent
    m1.pyName = 'GetFullTextExtent'
    m1.find('w').out = True
    m1.find('h').out = True
    m1.find('descent').out = True
    m1.find('externalLeading').out = True

    c.find('GetHandle').type = 'wxUIntPtr*'
    c.find('GetHandle').setCppCode(
        "return new wxUIntPtr(wxPyGetWinHandle(self));")

    c.addCppMethod(
        'void*', 'GetGtkWidget', '()', """\
    #ifdef __WXGTK__
        return (void*)self->GetHandle();
    #else
        return NULL;
    #endif
    """)

    c.addCppMethod('void',
                   'AssociateHandle',
                   '(long handle)',
                   doc="Associate the window with a new native handle",
                   body="self->AssociateHandle((WXWidget)handle);")
    c.addCppMethod('void',
                   'DissociateHandle',
                   '()',
                   doc="Dissociate the current native handle from the window",
                   body="self->DissociateHandle();")

    # Add some new methods
    c.addCppMethod(
        'wxWindow*',
        'GetTopLevelParent',
        '()',
        'return wxGetTopLevelParent(self);',
        briefDoc=
        "Returns the first ancestor of this window which is a top-level window."
    )

    c.addCppMethod(
        'bool',
        'MacIsWindowScrollbar',
        '(const wxWindow* sb)',
        """\
    #ifdef __WXMAC__
        return self->MacIsWindowScrollbar(sb);
    #else
        return false;
    #endif
    """,
        pyArgsString="(sb)",
        briefDoc=
        "Is the given widget one of this window's built-in scrollbars?  Only applicable on Mac."
    )

    c.addCppMethod(
        'void',
        'SetDimensions',
        '(int x, int y, int width, int height, int sizeFlags=wxSIZE_AUTO)',
        pyArgsString="(x, y, width, height, sizeFlags=SIZE_AUTO)",
        body="""\
        self->SetSize(x, y, width, height, sizeFlags);
        """)
    c.addPyCode(
        "Window.SetDimensions = wx.deprecated(Window.SetDimensions, 'Use SetSize instead.')"
    )

    # Make the Register/UnregisterHotKey functions be available on Windows,
    # and empty stubs otherwise
    c.find('RegisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->RegisterHotKey(hotkeyId, modifiers, virtualKeyCode);
    #else
        return false;
    #endif
    """)
    c.find('UnregisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->UnregisterHotKey(hotkeyId);
    #else
        return false;
    #endif
    """)
    c.find('RegisterHotKey').isVirtual = False
    c.find('UnregisterHotKey').isVirtual = False

    c.find('SetDoubleBuffered').setCppCode("""\
    #if defined(__WXGTK20__) || defined(__WXGTK3__) || defined(__WXMSW__)
        self->SetDoubleBuffered(on);
    #endif
    """)

    c.addPyMethod(
        '__nonzero__',
        '(self)',
        doc=
        "Can be used to test if the C++ part of the window still exists, with \n"
        "code like this::\n\n"
        "    if theWindow:\n"
        "        doSomething()",
        body="""\
        import wx.siplib
        return not wx.siplib.isdeleted(self)
        """)
    c.addPyCode('Window.__bool__ = Window.__nonzero__')  # For Python 3

    c.addPyMethod('DestroyLater',
                  '(self)',
                  doc="""\
           Schedules the window to be destroyed in the near future.

           This should be used whenever Destroy could happen too soon, such
           as when there may still be events for this window or its children
           waiting in the event queue.
           """,
                  body="""\
            self.Hide()
            wx.GetApp().ScheduleForDestruction(self)
            """)

    c.addPyMethod('DLG_UNIT',
                  '(self, dlg_unit)',
                  doc="""\
            A convenience wrapper for :meth:`ConvertDialogToPixels`.
            """,
                  body="""\
            is_wxType = isinstance(dlg_unit, (wx.Size, wx.Point))
            pix = self.ConvertDialogToPixels(dlg_unit)
            if not is_wxType:
                pix = tuple(pix)
            return pix
            """)

    # wxAccessbile is MSW only. Provide a NotImplemented fallback for the
    # other platforms.
    c.find('GetAccessible').setCppCode("""\
        #if wxUSE_ACCESSIBILITY
            return self->GetAccessible();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif
        """)
    c.find('SetAccessible.accessible').transfer = True
    c.find('SetAccessible').setCppCode("""\
        #if wxUSE_ACCESSIBILITY
            self->SetAccessible(accessible);
        #else
            wxPyRaiseNotImplemented();
        #endif
        """)

    # Make some of the protected methods visible and overridable from Python
    c.find('SendDestroyEvent').ignore(False)

    c.find('Destroy').transferThis = True
    c.addPyMethod('PostCreate',
                  '(self, pre)',
                  'pass',
                  deprecated='PostCreate is no longer necessary.')

    # transfer ownership of these parameters to the C++ object
    c.find('SetCaret.caret').transfer = True
    c.find('SetToolTip.tip').transfer = True
    c.find('SetDropTarget.target').transfer = True
    c.find('SetConstraints.constraints').transfer = True
    c.find('SetSizer.sizer').transfer = True
    c.find('SetSizerAndFit.sizer').transfer = True

    # Change some =0 default values to =NULL so the docs will make more sense
    c.find('FindWindowById.parent').default = 'NULL'
    c.find('FindWindowByLabel.parent').default = 'NULL'
    c.find('FindWindowByName.parent').default = 'NULL'

    # Transfer ownership of the wx.EvtHandler when pushing/popping them...
    c.find('PushEventHandler.handler').transfer = True
    c.find('PopEventHandler').transferBack = True

    # ...and for Set/RemoveEventHandler too
    c.find('SetEventHandler.handler').transfer = True
    c.find('RemoveEventHandler.handler').transferBack = True

    # Define some properties using the getter and setter methods
    c.addProperty('AcceleratorTable GetAcceleratorTable SetAcceleratorTable')
    c.addProperty('AutoLayout GetAutoLayout SetAutoLayout')
    c.addProperty('BackgroundColour GetBackgroundColour SetBackgroundColour')
    c.addProperty('BackgroundStyle GetBackgroundStyle SetBackgroundStyle')
    c.addProperty('EffectiveMinSize GetEffectiveMinSize')
    c.addProperty('BestSize GetBestSize')
    c.addProperty('BestVirtualSize GetBestVirtualSize')
    c.addProperty('Border GetBorder')
    c.addProperty('Caret GetCaret SetCaret')
    c.addProperty('CharHeight GetCharHeight')
    c.addProperty('CharWidth GetCharWidth')
    c.addProperty('Children GetChildren')
    c.addProperty('ClientAreaOrigin GetClientAreaOrigin')
    c.addProperty('ClientSize GetClientSize SetClientSize')
    c.addProperty('Constraints GetConstraints SetConstraints')
    c.addProperty('ContainingSizer GetContainingSizer SetContainingSizer')
    c.addProperty('Cursor GetCursor SetCursor')
    c.addProperty('DefaultAttributes GetDefaultAttributes')
    c.addProperty('DropTarget GetDropTarget SetDropTarget')
    c.addProperty('EventHandler GetEventHandler SetEventHandler')
    c.addProperty('ExtraStyle GetExtraStyle SetExtraStyle')
    c.addProperty('Font GetFont SetFont')
    c.addProperty('ForegroundColour GetForegroundColour SetForegroundColour')
    c.addProperty('GrandParent GetGrandParent')
    c.addProperty('TopLevelParent GetTopLevelParent')
    c.addProperty('Handle GetHandle')
    c.addProperty('HelpText GetHelpText SetHelpText')
    c.addProperty('Id GetId SetId')
    c.addProperty('Label GetLabel SetLabel')
    c.addProperty('LayoutDirection GetLayoutDirection SetLayoutDirection')
    c.addProperty('MaxHeight GetMaxHeight')
    c.addProperty('MaxSize GetMaxSize SetMaxSize')
    c.addProperty('MaxWidth GetMaxWidth')
    c.addProperty('MinHeight GetMinHeight')
    c.addProperty('MinSize GetMinSize SetMinSize')
    c.addProperty('MinWidth GetMinWidth')
    c.addProperty('Name GetName SetName')
    c.addProperty('Parent GetParent')
    c.addProperty('Position GetPosition SetPosition')
    c.addProperty('ScreenPosition GetScreenPosition')
    c.addProperty('ScreenRect GetScreenRect')
    c.addProperty('Size GetSize SetSize')
    c.addProperty('Sizer GetSizer SetSizer')
    c.addProperty('ThemeEnabled GetThemeEnabled SetThemeEnabled')
    c.addProperty('ToolTip GetToolTip SetToolTip')
    c.addProperty('UpdateClientRect GetUpdateClientRect')
    c.addProperty('UpdateRegion GetUpdateRegion')
    c.addProperty('Validator GetValidator SetValidator')
    c.addProperty('VirtualSize GetVirtualSize SetVirtualSize')
    c.addProperty('WindowStyle GetWindowStyle SetWindowStyle')
    c.addProperty('WindowStyleFlag GetWindowStyleFlag SetWindowStyleFlag')
    c.addProperty('WindowVariant GetWindowVariant SetWindowVariant')
    c.addProperty('Shown IsShown Show')
    c.addProperty('Enabled IsEnabled Enable')
    c.addProperty('TopLevel IsTopLevel')
    c.addProperty('MinClientSize GetMinClientSize SetMinClientSize')
    c.addProperty('MaxClientSize GetMaxClientSize SetMaxClientSize')
    ##c.addProperty('GtkWidget GetGtkWidget')

    tools.fixWindowClass(c)
    tools.addSipConvertToSubClassCode(c)

    # for compatibility with Classic
    c.addPyMethod('GetPositionTuple',
                  '(self)',
                  'return self.GetPosition()',
                  deprecated='Use GetPosition instead')
    c.addPyMethod('GetSizeTuple',
                  '(self)',
                  'return self.GetSize()',
                  deprecated='Use GetSize instead')
    c.addPyMethod('MoveXY',
                  '(self, x, y)',
                  'return self.Move(x, y)',
                  deprecated='Use Move instead.')
    c.addPyMethod('SetSizeWH',
                  '(self, w, h)',
                  'return self.SetSize(w,h)',
                  deprecated='Use SetSize instead.')
    c.addPyMethod('SetVirtualSizeWH',
                  '(self, w, h)',
                  'return self.SetVirtualSize(w,h)',
                  deprecated='Use SetVirtualSize instead.')
    c.addPyMethod('GetVirtualSizeTuple',
                  '(self)',
                  'return self.GetVirtualSize()',
                  deprecated='Use GetVirtualSize instead.')
    c.addPyMethod('SetToolTipString',
                  '(self, string)',
                  'return self.SetToolTip(string)',
                  deprecated='Use SetToolTip instead.')
    c.addPyMethod('ConvertDialogPointToPixels',
                  '(self, point)',
                  'return self.ConvertDialogToPixels(point)',
                  deprecated='Use ConvertDialogToPixels instead.')
    c.addPyMethod('ConvertDialogSizeToPixels',
                  '(self, size)',
                  'return self.ConvertDialogToPixels(point)',
                  deprecated='Use ConvertDialogToPixels instead.')

    c.addPyMethod(
        'SetSizeHintsSz',
        '(self, minSize, maxSize=wx.DefaultSize, incSize=wx.DefaultSize)',
        'return self.SetSizeHints(minSize, maxSize, incSize)',
        deprecated='Use SetSizeHints instead.')

    # TODO: the C++ DoEraseBackground is protected in wxMSW. We need a way to
    # unprotect it, like adding a shim in the sip class...
    #c.addHeaderCode("""\
    #    #ifdef __WXMSW__
    #    #include <wx/msw/dc.h>
    #    #endif
    #    """)
    #c.addCppMethod('bool', 'DoEraseBackground', '(wxDC* dc)',
    #    doc="Default erase background implementation.",
    #    body="""\
    #    #ifdef __WXMSW__
    #        return self->DoEraseBackground(((wxMSWDCImpl*)dc->GetImpl())->GetHDC());
    #    #else
    #        dc->SetBackground(wxBrush(self->GetBackgroundColour()));
    #        dc->Clear();
    #        return true;
    #    #endif
    #    """)

    # this is a nested class
    c.find('ChildrenRepositioningGuard').addPrivateCopyCtor()
    module.insertItem(
        0,
        etgtools.TypedefDef(type='wxWindow::ChildrenRepositioningGuard',
                            name='ChildrenRepositioningGuard'))

    #-----------------------------------------------------------------------
    # Other stuff

    module.addPyCode('''\
    class FrozenWindow(object):
        """
        A context manager to be used with Python 'with' statements
        that will freeze the given window for the duration of the
        with block.
        """
        def __init__(self, window):
            self._win = window
        def __enter__(self):
            self._win.Freeze()
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            self._win.Thaw()
    ''')

    module.addPyCode('''\
        def DLG_UNIT(win, dlg_unit, val2=None):
            """
            Convenience function for converting a wx.Point, wx.Size or
            (x,y) in dialog units to pixels, using the given window as a
            reference.
            """
            if val2 is not None:
                dlg_unit = (dlg_unit, val2)
            is_wxType = isinstance(dlg_unit, (wx.Size, wx.Point))
            pix = win.ConvertDialogToPixels(dlg_unit)
            if not is_wxType:
                pix = tuple(pix)
            return pix

        DLG_PNT = wx.deprecated(DLG_UNIT, "Use DLG_UNIT instead.")
        DLG_SZE = wx.deprecated(DLG_UNIT, "Use DLG_UNIT instead.")
        ''')

    # Add a wrapper for wxWindowList and a new iterator class for it that
    # makes wxWindowList quack like a read-only Python sequence.
    module.addItem(
        tools.wxListWrapperTemplate('wxWindowList', 'wxWindow', module))

    module.addCppFunction(
        'wxWindowList*',
        'GetTopLevelWindows',
        '()',
        noCopy=True,
        briefDoc=
        "Returns a list-like object of the the application's top-level windows, (frames,dialogs, etc.)",
        body="return &wxTopLevelWindows;")

    module.addPyCode("PyWindow = wx.deprecated(Window, 'Use Window instead.')")

    module.find('wxFindWindowAtPointer.pt').out = True

    module.find('wxFindWindowAtPointer').mustHaveApp()
    module.find('wxGetActiveWindow').mustHaveApp()
    module.find('wxGetTopLevelParent').mustHaveApp()

    module.addCppFunction('wxWindow*',
                          'FindWindowById',
                          '(long id, const wxWindow* parent=NULL)',
                          doc="""\
            FindWindowById(id, parent=None) -> Window

            Find the first window in the application with the given id. If parent
            is None, the search will start from all top-level frames and dialog
            boxes; if non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.
            """,
                          body="return wxWindow::FindWindowById(id, parent);",
                          mustHaveAppFlag=True)

    module.addCppFunction(
        'wxWindow*',
        'FindWindowByName',
        '(const wxString& name, const wxWindow* parent=NULL)',
        doc="""\
            FindWindowByName(name, parent=None) -> Window

            Find a window by its name (as given in a window constructor or Create
            function call). If parent is None, the search will start from all
            top-level frames and dialog boxes; if non-None, the search will be
            limited to the given window hierarchy. The search is recursive in both
            cases.

            If no window with the name is found, wx.FindWindowByLabel is called.""",
        body="return wxWindow::FindWindowByName(*name, parent);",
        mustHaveAppFlag=True)

    module.addCppFunction(
        'wxWindow*',
        'FindWindowByLabel',
        '(const wxString& label, const wxWindow* parent=NULL)',
        doc="""\
            FindWindowByLabel(label, parent=None) -> Window

            Find a window by its label. Depending on the type of window, the label
            may be a window title or panel item label. If parent is None, the
            search will start from all top-level frames and dialog boxes; if
            non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.""",
        body="return wxWindow::FindWindowByLabel(*label, parent);",
        mustHaveAppFlag=True)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #5
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE,
                                MODULE,
                                NAME,
                                DOCSTRING,
                                check4unittest=False)
    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 <wx/textfile.h>")

    # tweaks for defs.h to help SIP understand the types better
    module.find('wxInt16').type = 'short'
    module.find('wxInt64').type = 'long long'
    module.find('wxUint64').type = 'unsigned long long'

    # See src/wacky_ints.sip
    module.find('wxIntPtr').ignore()
    module.find('wxUIntPtr').ignore()

    # Correct the types for these as their values are outside the range of int
    module.find('wxUINT32_MAX').type = 'unsigned long'
    module.find('wxINT64_MIN').type = 'long long'
    module.find('wxINT64_MAX').type = 'long long'
    module.find('wxUINT64_MAX').type = 'unsigned long long'

    # Generate the code for these differently because they need to be
    # forcibly mashed into an int in the C code
    module.find('wxCANCEL_DEFAULT').forcedInt = True
    module.find('wxVSCROLL').forcedInt = True
    module.find('wxWINDOW_STYLE_MASK').forcedInt = True

    module.find('wxInt8').pyInt = True
    module.find('wxUint8').pyInt = True
    module.find('wxByte').pyInt = True

    module.find('wxDELETE').ignore()
    module.find('wxDELETEA').ignore()
    module.find('wxSwap').ignore()
    module.find('wxVaCopy').ignore()

    # Add some typedefs for basic wx types and others so the backend
    # generator knows what they are
    td = module.find('wxUIntPtr')
    module.insertItemAfter(td,
                           etgtools.TypedefDef(type='wchar_t', name='wxUChar'))
    module.insertItemAfter(td,
                           etgtools.TypedefDef(type='wchar_t', name='wxChar'))
    module.insertItemAfter(td, etgtools.TypedefDef(type='long', name='time_t'))
    module.insertItemAfter(
        td, etgtools.TypedefDef(type='long long', name='wxFileOffset'))
    module.insertItemAfter(
        td, etgtools.TypedefDef(type='SIP_SSIZE_T', name='ssize_t'))
    module.insertItemAfter(
        td, etgtools.TypedefDef(type='unsigned char', name='byte', pyInt=True))
    module.insertItemAfter(
        td, etgtools.TypedefDef(type='unsigned long', name='ulong'))

    # Forward declarations for classes that are referenced but not defined
    # yet.
    #
    # TODO: Remove these when the classes are added for real.
    # TODO: Add these classes for real :-)
    module.insertItem(
        0,
        etgtools.WigCode("""\
        // forward declarations
        class wxExecuteEnv;
        """))

    # Add some code for getting the version numbers
    module.addCppCode("""
        #include <wx/version.h>
        const int MAJOR_VERSION = wxMAJOR_VERSION;
        const int MINOR_VERSION = wxMINOR_VERSION;
        const int RELEASE_NUMBER = wxRELEASE_NUMBER;
        """)
    module.addItem(
        etgtools.WigCode("""
        const int MAJOR_VERSION;
        const int MINOR_VERSION;
        const int RELEASE_NUMBER;
        """))

    # TODO: these should be removed someday
    module.addPyCode("BG_STYLE_CUSTOM = BG_STYLE_PAINT")
    module.addPyCode("ADJUST_MINSIZE = 0")
    module.addPyCode("WS_EX_VALIDATE_RECURSIVELY = 0")

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

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

    module.find('wxCreateDynamicObject').ignore()

    #--------------------------------------------------
    c = module.find('wxClassInfo')
    assert isinstance(c, etgtools.ClassDef)
    module.insertItemBefore(
        c, etgtools.TypedefDef(type='void*', name='wxObjectConstructorFn'))
    module.find('wxClassInfo').abstract = True
    module.find('wxClassInfo.wxClassInfo').ignore()

    #--------------------------------------------------
    c = module.find('wxRefCounter')
    assert isinstance(c, etgtools.ClassDef)
    c.find('~wxRefCounter').ignore(False)
    c.addPrivateCopyCtor()
    tools.fixRefCountedClass(c)

    #--------------------------------------------------
    c = module.find('wxObject')
    c.find('operator delete').ignore()
    c.find('operator new').ignore()
    c.find('IsKindOf').ignore()

    # EXPERIMENTAL: By turning off the virtualness of the wxObject dtor, and
    # since there are no other virtuals that we are exposing here, then all
    # classes that derive from wxObject that do not have any virtuals of
    # their own (or have the virtual flags turned off by the tweaker code)
    # can have simpler wrappers generated for them with no extra derived
    # class whose only purpose is to reflect calls to the virtual methods to
    # Python implementations. (And since the only virtual is the dtor then
    # that is of no real benefit to Python code since we're not overriding
    # the dtor anyhow.) In addition it appears so far that none of these
    # classes would ever need to have Python derived classes anyway. This
    # also makes it easier and less SIP-specific to add or replace ctors in
    # those classes with custom C++ code. (See wxFont and wxAcceleratorTable
    # for examples.)
    c.find('~wxObject').isVirtual = False
    c.find('GetClassInfo').isVirtual = False

    c.addCppMethod('const wxChar*',
                   'GetClassName',
                   '()',
                   body='return self->GetClassInfo()->GetClassName();',
                   doc='Returns the class name of the C++ class using wxRTTI.')

    c.addCppMethod(
        'void',
        'Destroy',
        '()',
        body='delete self;',
        doc='Deletes the C++ object this Python object is a proxy for.',
        transferThis=True)  # TODO: Check this

    tools.addSipConvertToSubClassCode(c)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #7
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING,
                                check4unittest=False)
    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.
        
    # tweaks for defs.h to help SIP understand the types better
    module.find('wxInt16').type = 'short'
    module.find('wxInt64').type = 'long long'
    module.find('wxUint64').type = 'unsigned long long'
    
    # NOTE: this is better, but probably still not totally correct...
    if sys.maxsize > 2**32:
        module.find('wxIntPtr').type =  'long long'           #'ssize_t'
        module.find('wxUIntPtr').type = 'unsigned long long'  #'size_t'
    else:
        module.find('wxIntPtr').type =  'long'                #'ssize_t'
        module.find('wxUIntPtr').type = 'unsigned long'       #'size_t'
        
    module.find('wxInt8').pyInt = True
    module.find('wxUint8').pyInt = True
    module.find('wxByte').pyInt = True
    
    module.find('wxDELETE').ignore()
    module.find('wxDELETEA').ignore()
    module.find('wxSwap').ignore()
    module.find('wxVaCopy').ignore()
    
    # Add some typedefs for basic wx types and others so the backend
    # generator knows what they are
    td = module.find('wxUIntPtr')
    module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxUChar'))
    module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxChar'))
    module.insertItemAfter(td, etgtools.TypedefDef(type='unsigned long', name='size_t'))
    module.insertItemAfter(td, etgtools.TypedefDef(type='long', name='time_t'))
    module.insertItemAfter(td, etgtools.TypedefDef(type='long long', name='wxFileOffset'))
    module.insertItemAfter(td, etgtools.TypedefDef(type='SIP_SSIZE_T', name='ssize_t'))
    module.insertItemAfter(td, etgtools.TypedefDef(type='unsigned char', name='byte', pyInt=True))
    

    
    # Forward declarations for classes that are referenced but not defined
    # yet. 
    # 
    # TODO: Remove these when the classes are added for real.
    # TODO: Add these classes for real :-)
    module.insertItem(0, etgtools.WigCode("""\
        // forward declarations
        class wxPalette;
        class wxExecuteEnv;
        """))
    
   
    # Add some code for getting the version numbers
    module.addCppCode("""
        #include <wx/version.h>
        const int MAJOR_VERSION = wxMAJOR_VERSION;
        const int MINOR_VERSION = wxMINOR_VERSION;           
        const int RELEASE_NUMBER = wxRELEASE_NUMBER;     
        """)
    module.addItem(etgtools.WigCode("""
        const int MAJOR_VERSION;
        const int MINOR_VERSION;
        const int RELEASE_NUMBER;
        """))

    module.addPyCode("BG_STYLE_CUSTOM = BG_STYLE_PAINT")
    

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #8
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.    

    c = module.find('wxWindow')
    assert isinstance(c, etgtools.ClassDef)
    module.addGlobalStr('wxPanelNameStr', c)
        
    
    # First we need to let the wrapper generator know about wxWindowBase since
    # AddChild and RemoveChild need to use that type in order to be virtualized.
    winbase = ClassDef(name='wxWindowBase', bases=['wxEvtHandler'], abstract=True,
            items=[MethodDef(name='AddChild', isVirtual=True, type='void', protection='public',
                        items=[ParamDef(name='child', type='wxWindowBase*')]),
                   MethodDef(name='RemoveChild', isVirtual=True, type='void', protection='public',
                        items=[ParamDef(name='child', type='wxWindowBase*')])
                   ])
    module.insertItemBefore(c, winbase)
    
    # Now change the base class of wxWindow
    c.bases = ['wxWindowBase']
    
    # And fix the arg types we get from Doxy
    c.find('AddChild.child').type = 'wxWindowBase*'
    c.find('RemoveChild.child').type = 'wxWindowBase*'
    
    
    # We now return you to our regularly scheduled programming...
    c.includeCppCode('src/window_ex.cpp')

    # ignore some overloads that will be ambiguous afer wrapping
    c.find('GetChildren').overloads = []
    c.find('GetChildren').noCopy = True
    c.find('GetClientSize').findOverload('int *').ignore()
    c.find('GetSize').findOverload('int *').ignore()
    c.find('GetVirtualSize').findOverload('int *').ignore()
    c.find('GetPosition').findOverload('int *').ignore()
    c.find('GetScreenPosition').findOverload('int *').ignore()
    c.find('ClientToScreen').findOverload('int *').ignore()
    c.find('ScreenToClient').findOverload('int *').ignore()

    # Release the GIL for potentially blocking or long-running functions
    c.find('PopupMenu').releaseGIL()
    c.find('ProcessEvent').releaseGIL()
    c.find('ProcessWindowEvent').releaseGIL()
    c.find('ProcessWindowEventLocally').releaseGIL()
    
    # Add a couple wrapper functions for symmetry with the getters of the same name
    c.addPyMethod('SetRect', '(self, rect)', 'return self.SetSize(rect)')
    c.addPyProperty('Rect GetRect SetRect')
    c.addPyMethod('SetClientRect', '(self, rect)', 'return self.SetClientSize(rect)')
    c.addPyProperty('ClientRect GetClientRect SetClientRect')
                    
    m = c.find('GetTextExtent').findOverload('int *')
    m.pyName = 'GetFullTextExtent'
    m.find('w').out = True
    m.find('h').out = True
    m.find('descent').out = True
    m.find('externalLeading').out = True
    
    c.find('GetHandle').type = 'unsigned long'
    c.find('GetHandle').setCppCode("return wxPyGetWinHandle(self);")
    
    c.addCppMethod('void*', 'GetGtkWidget', '()', """\
    #ifdef __WXGTK__
        return (void*)self->GetHandle();
    #else
        return NULL;
    #endif
    """)
    
    c.addCppMethod('void', 'AssociateHandle', '(long handle)',
        doc="Associate the window with a new native handle",
        body="self->AssociateHandle((WXWidget)handle);")
    c.addCppMethod('void', 'DissociateHandle', '()',
        doc="Dissociate the current native handle from the window",
        body="self->DissociateHandle();")
        
    
    # Add some new methods
    c.addCppMethod('wxWindow*', 'GetTopLevelParent', '()',
                   'return wxGetTopLevelParent(self);',
                   briefDoc="Returns the first ancestor of this window which is a top-level window.")

    c.addCppMethod('bool', 'MacIsWindowScrollbar', '(const wxWindow* sb)', """\
    #ifdef __WXMAC__
        return self->MacIsWindowScrollbar(sb); 
    #else
        return false;
    #endif
    """,
    pyArgsString="(sb)",
    briefDoc="Is the given widget one of this window's built-in scrollbars?  Only applicable on Mac.")

    
    c.addCppMethod('void', 'SetDimensions', '(int x, int y, int width, int height, int sizeFlags=wxSIZE_AUTO)', 
        pyArgsString="(x, y, width, height, sizeFlags=SIZE_AUTO)",
        body="""\
        self->SetSize(x, y, width, height, sizeFlags);
        """)
    c.addPyCode("Window.SetDimensions = wx.deprecated(Window.SetDimensions, 'Use SetSize instead.')")
    
    # Make the Register/UnregisterHotKey functions be available on Windows,
    # and empty stubs otherwise
    c.find('RegisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->RegisterHotKey(hotkeyId, modifiers, virtualKeyCode);
    #else
        return false;
    #endif
    """)
    c.find('UnregisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->UnregisterHotKey(hotkeyId);
    #else
        return false;
    #endif
    """)    
    c.find('RegisterHotKey').isVirtual = False
    c.find('UnregisterHotKey').isVirtual = False

    
    c.find('SetDoubleBuffered').setCppCode("""\
    #if defined(__WXGTK20__) || defined(__WXMSW__)
        self->SetDoubleBuffered(on);
    #endif
    """)

    c.addPyMethod('__nonzero__', '(self)',
        doc="Can be used to test if the C++ part of the window still exists, with \n"
            "code like this::\n\n"
            "    if theWindow:\n"
            "        doSomething()",
        body="""\
        import wx.siplib
        return not wx.siplib.isdeleted(self)
        """)
    c.addPyCode('Window.__bool__ = Window.__nonzero__') # For Python 3


    c.addPyMethod('DestroyLater', '(self)',
        doc="""\
           Schedules the window to be destroyed in the near future.
           
           This should be used whenever Destroy could happen too soon, such
           as when there may still be events for this window or its children
           waiting in the event queue. 
           """,
        body="""\
            self.Hide()
            wx.GetApp().ScheduleForDestruction(self)
            """)
    
    
    # MSW only.  Do we want them wrapped?
    c.find('GetAccessible').ignore()
    c.find('SetAccessible').ignore()
    
    # Make some of the protected methods visible and overridable from Python
    c.find('SendDestroyEvent').ignore(False)

    c.find('Destroy').transferThis=True
    c.addPyMethod('PostCreate', '(self, pre)', 'pass', deprecated='PostCreate is no longer necessary.')
    
    # transfer ownership of these parameters to the C++ object
    c.find('SetCaret.caret').transfer = True
    c.find('SetToolTip.tip').transfer = True
    c.find('SetDropTarget.target').transfer = True
    c.find('SetConstraints.constraints').transfer = True
    c.find('SetSizer.sizer').transfer = True
    c.find('SetSizerAndFit.sizer').transfer = True
    
    # Define some properties using the getter and setter methods
    c.addProperty('AcceleratorTable GetAcceleratorTable SetAcceleratorTable')
    c.addProperty('AutoLayout GetAutoLayout SetAutoLayout')
    c.addProperty('BackgroundColour GetBackgroundColour SetBackgroundColour')
    c.addProperty('BackgroundStyle GetBackgroundStyle SetBackgroundStyle')
    c.addProperty('EffectiveMinSize GetEffectiveMinSize')
    c.addProperty('BestSize GetBestSize')
    c.addProperty('BestVirtualSize GetBestVirtualSize')
    c.addProperty('Border GetBorder')
    c.addProperty('Caret GetCaret SetCaret')
    c.addProperty('CharHeight GetCharHeight')
    c.addProperty('CharWidth GetCharWidth')
    c.addProperty('Children GetChildren')
    c.addProperty('ClientAreaOrigin GetClientAreaOrigin')
    c.addProperty('ClientSize GetClientSize SetClientSize')
    c.addProperty('Constraints GetConstraints SetConstraints')
    c.addProperty('ContainingSizer GetContainingSizer SetContainingSizer')
    c.addProperty('Cursor GetCursor SetCursor')
    c.addProperty('DefaultAttributes GetDefaultAttributes')
    c.addProperty('DropTarget GetDropTarget SetDropTarget')
    c.addProperty('EventHandler GetEventHandler SetEventHandler')
    c.addProperty('ExtraStyle GetExtraStyle SetExtraStyle')
    c.addProperty('Font GetFont SetFont')
    c.addProperty('ForegroundColour GetForegroundColour SetForegroundColour')
    c.addProperty('GrandParent GetGrandParent')
    c.addProperty('TopLevelParent GetTopLevelParent')
    c.addProperty('Handle GetHandle')
    c.addProperty('HelpText GetHelpText SetHelpText')
    c.addProperty('Id GetId SetId')
    c.addProperty('Label GetLabel SetLabel')
    c.addProperty('LayoutDirection GetLayoutDirection SetLayoutDirection')
    c.addProperty('MaxHeight GetMaxHeight')
    c.addProperty('MaxSize GetMaxSize SetMaxSize')
    c.addProperty('MaxWidth GetMaxWidth')
    c.addProperty('MinHeight GetMinHeight')
    c.addProperty('MinSize GetMinSize SetMinSize')
    c.addProperty('MinWidth GetMinWidth')
    c.addProperty('Name GetName SetName')
    c.addProperty('Parent GetParent')
    c.addProperty('Position GetPosition SetPosition')
    c.addProperty('ScreenPosition GetScreenPosition')
    c.addProperty('ScreenRect GetScreenRect')
    c.addProperty('Size GetSize SetSize')
    c.addProperty('Sizer GetSizer SetSizer')
    c.addProperty('ThemeEnabled GetThemeEnabled SetThemeEnabled')
    c.addProperty('ToolTip GetToolTip SetToolTip')
    c.addProperty('UpdateClientRect GetUpdateClientRect')
    c.addProperty('UpdateRegion GetUpdateRegion')
    c.addProperty('Validator GetValidator SetValidator')
    c.addProperty('VirtualSize GetVirtualSize SetVirtualSize')
    c.addProperty('WindowStyle GetWindowStyle SetWindowStyle')
    c.addProperty('WindowStyleFlag GetWindowStyleFlag SetWindowStyleFlag')
    c.addProperty('WindowVariant GetWindowVariant SetWindowVariant')
    c.addProperty('Shown IsShown Show')
    c.addProperty('Enabled IsEnabled Enable')
    c.addProperty('TopLevel IsTopLevel')
    c.addProperty('MinClientSize GetMinClientSize SetMinClientSize')
    c.addProperty('MaxClientSize GetMaxClientSize SetMaxClientSize')
    ##c.addProperty('GtkWidget GetGtkWidget')

    tools.fixWindowClass(c)
    tools.addSipConvertToSubClassCode(c)

    # for compatibility with Classic
    c.addPyMethod('GetPositionTuple', '(self)', 'return self.GetPosition()', deprecated='Use GetPosition instead')
    c.addPyMethod('MoveXY',  '(self, x, y)', 'return self.Move(x, y)', deprecated='Use Move instead.')
    c.addPyMethod('SetSizeWH', '(self, w, h)', 'return self.SetSize(w,h)', deprecated='Use SetSize instead.')
    c.addPyMethod('SetVirtualSizeWH', '(self, w, h)', 'return self.SetVirtualSize(w,h)', deprecated='Use SetVirtualSize instead.')
    c.addPyMethod('GetVirtualSizeTuple', '(self)', 'return self.GetVirtualSize()', deprecated='Use GetVirtualSize instead.')
    c.addPyMethod('SetToolTipString',  '(self, string)', 'return self.SetToolTip(string)', deprecated='Use SetToolTip instead.')
    c.addPyMethod('ConvertDialogPointToPixels', '(self, point)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.')
    c.addPyMethod('ConvertDialogSizeToPixels', '(self, size)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.')


    # this is a nested class
    c.find('ChildrenRepositioningGuard').addPrivateCopyCtor()
    module.insertItem(0, 
            etgtools.TypedefDef(type='wxWindow::ChildrenRepositioningGuard',
                                name='ChildrenRepositioningGuard'))

        
    #-----------------------------------------------------------------------
    # Other stuff
    
    module.addPyCode('''\
    class FrozenWindow(object):
        """
        A context manager to be used with Python 'with' statements
        that will freeze the given window for the duration of the
        with block.
        """
        def __init__(self, window):
            self._win = window
        def __enter__(self):
            self._win.Freeze()
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            self._win.Thaw()
    ''')
    
    
    # Add a wrapper for wxWindowList and a new iterator class for it that
    # makes wxWindowList quack like a read-only Python sequence.
    module.addItem(tools.wxListWrapperTemplate('wxWindowList', 'wxWindow', module))
    
    module.addCppFunction('wxWindowList*', 'GetTopLevelWindows', '()', 
        noCopy=True,
        briefDoc="Returns a list-like object of the the application's top-level windows, (frames,dialogs, etc.)",
        body="return &wxTopLevelWindows;")
    
    module.addPyCode("PyWindow = wx.deprecated(Window, 'Use Window instead.')")


    module.find('wxFindWindowAtPointer.pt').out = True
    
   
    module.addCppFunction('wxWindow*', 'FindWindowById', '(long id, const wxWindow* parent=NULL)', 
        doc="""\
            FindWindowById(id, parent=None) -> Window
        
            Find the first window in the application with the given id. If parent
            is None, the search will start from all top-level frames and dialog
            boxes; if non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.
            """,
        body="return wxWindow::FindWindowById(id, parent);")
    
    module.addCppFunction('wxWindow*', 'FindWindowByName', '(const wxString& name, const wxWindow* parent=NULL)', 
        doc="""\
            FindWindowByName(name, parent=None) -> Window
            
            Find a window by its name (as given in a window constructor or Create
            function call). If parent is None, the search will start from all
            top-level frames and dialog boxes; if non-None, the search will be
            limited to the given window hierarchy. The search is recursive in both
            cases.

            If no window with the name is found, wx.FindWindowByLabel is called.""",
        body="return wxWindow::FindWindowByName(*name, parent);")
    
    module.addCppFunction('wxWindow*', 'FindWindowByLabel', '(const wxString& label, const wxWindow* parent=NULL)', 
        doc="""\
            FindWindowByLabel(label, parent=None) -> Window
            
            Find a window by its label. Depending on the type of window, the label
            may be a window title or panel item label. If parent is None, the
            search will start from all top-level frames and dialog boxes; if
            non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.""",
        body="return wxWindow::FindWindowByLabel(*label, parent);")
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)