Exemplo n.º 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)

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

    c = module.find('wxPosition')
    assert isinstance(c, etgtools.ClassDef)

    # (r,c) --> wxPosition typemap
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxPosition')

    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 "wx.Position"+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 (Position, 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('Position.__safe_for_unpickling__ = True')


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 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_TEXT =      "string"
        GRID_VALUE_LONG =      "long"
        GRID_VALUE_CHOICEINT = "choiceint"
        GRID_VALUE_DATETIME =  "datetime"
        """)

    #-----------------------------------------------------------------
    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('__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('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.')")


    #-----------------------------------------------------------------
    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 == Py_None) {
                    sipRes = false;
                }
                else {
                    sipRes = true;
                    *newval = Py2wxString(result);
                }
                Py_DECREF(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 = module.find('wxGridCellChoiceEditor')
    c.find('wxGridCellChoiceEditor').findOverload('count').ignore()

    for name in ITEMS:
        if 'Cell' in name and 'Editor' in name:
            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


    #-----------------------------------------------------------------
    # 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 == 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('wxGridTableMessage')
    c.addPrivateCopyCtor()


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

    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.SelectCells)',
        piArgsString='(self, table, takeOwnership=False, selmode=SelectCells)',
        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'))


    # Rename some nested enum values
    c.find('wxGridSelectionModes.wxGridSelectCells').pyName = 'SelectCells'
    c.find('wxGridSelectionModes.wxGridSelectRows').pyName = 'SelectRows'
    c.find('wxGridSelectionModes.wxGridSelectColumns').pyName = 'SelectColumns'
    c.find('wxGridSelectionModes.wxGridSelectRowsOrColumns').pyName = 'SelectRowsOrColumns'

    # But also keep aliases for the old names, just in case
    c.addPyCode("""\
        Grid.wxGridSelectCells = Grid.SelectCells
        Grid.wxGridSelectRows = Grid.SelectRows
        Grid.wxGridSelectColumns = Grid.SelectColumns
        Grid.wxGridSelectRowsOrColumns = Grid.SelectRowsOrColumns
        """)

    #-----------------------------------------------------------------
    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)


    c.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)
Exemplo n.º 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('wxGBPosition')
    assert isinstance(c, etgtools.ClassDef)
    
    # allow a 2 element sequence to be auto converted
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxGBPosition')
    
    c.addCppMethod('PyObject*', 'Get', '()', """\
        return sipBuildResult(0, "(ii)", self->GetRow(), self->GetCol());
        """, 
        pyArgsString="() -> (row, col)",
        briefDoc="Return the row and col properties as a tuple.")
    c.addCppMethod('void', 'Set', '(int row=0, int col=0)', """\
        self->SetRow(row);
        self->SetCol(col);
        """, 
        briefDoc="Set both the row and column properties.")
    
    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)',             'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',            'return "wx.GBPosition"+str(self.Get())')
    c.addPyMethod('__len__', '(self)',             'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)',         'return self.Get() != (0,0)')
    c.addPyMethod('__reduce__', '(self)',          'return (GBPosition, 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('GBPosition.__safe_for_unpickling__ = True')

    # In addition to the normal Row and Col properties let's also have lower
    # case versions.
    c.addProperty("Row GetRow SetRow")
    c.addProperty("Col GetCol SetCol")
    c.addProperty("row GetRow SetRow")
    c.addProperty("col GetCol SetCol")


    #-----------------------------------------------------------------
    c = module.find('wxGBSpan')
    assert isinstance(c, etgtools.ClassDef)

    # allow a 2 element sequence to be auto converted
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxGBSpan')
    
    c.addCppMethod('PyObject*', 'Get', '()', """\
        return sipBuildResult(0, "(ii)", self->GetRowspan(), self->GetColspan());
        """, 
        pyArgsString="() -> (rowspan, colspan)",
        briefDoc="Return the rowspan and colspan properties as a tuple.")
    c.addCppMethod('void', 'Set', '(int rowspan=0, int colspan=0)', """\
        self->SetRowspan(rowspan);
        self->SetColspan(colspan);
        """, 
        briefDoc="Set both the rowspan and colspan properties.")
    
    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)',             'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',            'return "wx.GBSpan"+str(self.Get())')
    c.addPyMethod('__len__', '(self)',             'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)',         'return self.Get() != (0,0)')
    c.addPyMethod('__reduce__', '(self)',          'return (GBSpan, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)',    'return self.Get()[idx]')
    c.addPyMethod('__setitem__', '(self, idx, val)',
                  """\
                  if idx == 0: self.Rowspan = val
                  elif idx == 1: self.Colspan = val
                  else: raise IndexError
                  """) 
    c.addPyCode('GBSpan.__safe_for_unpickling__ = True')

    # In addition to the normal Rowspan and Colspan properties let's also have lower
    # case versions.
    c.addProperty("Rowspan GetRowspan SetRowspan")
    c.addProperty("Colspan GetColspan SetColspan")
    c.addProperty("rowspan GetRowspan SetRowspan")
    c.addProperty("colspan GetColspan SetColspan")


    #-----------------------------------------------------------------
    c = module.find('wxGBSizerItem')
    assert isinstance(c, etgtools.ClassDef)

    # transfer ownership of a sizer if the item is managing one
    c.find('wxGBSizerItem.sizer').transfer = True
    
    # deal with userData args in the ctors
    for m in c.find('wxGBSizerItem').all():
        if isinstance(m, etgtools.MethodDef) and m.findItem('userData'):
            m.find('userData').transfer = True
            m.find('userData').type = 'wxPyUserData*'
    
    # ignore some overloads that would be ambiguous from Python
    c.find('GetPos').findOverload('row').ignore()
    c.find('GetSpan').findOverload('rowspan').ignore()
    
    c.find('GetEndPos.row').out = True
    c.find('GetEndPos.col').out = True
    
    #-----------------------------------------------------------------
    c = module.find('wxGridBagSizer')
    assert isinstance(c, etgtools.ClassDef)

    tools.fixSizerClass(c)
    
    for func in c.findAll('Add'):
        if func.findItem('sizer'):
            func.find('sizer').transfer = True
        if func.findItem('userData'):
            func.find('userData').transfer = True
            func.find('userData').type = 'wxPyUserData*'
        if func.findItem('item'):
            func.find('item').transfer = True

    c.addCppMethod('wxSizerItem*', 'Add',
                   '(const wxSize& size, const wxGBPosition& pos, '
                     'const wxGBSpan& span = wxDefaultSpan, int flag = 0, '
                     'int border = 0, wxObject* userData /Transfer/ = NULL)',
        doc="Add a spacer using a :class:`Size` object.",
        body="return self->Add(size->x, size->y, *pos, *span, flag, border, userData);")


    c.addPyCode(
        "GridBagSizer.CheckForIntersectionPos = wx.deprecated(GridBagSizer.CheckForIntersection, 'Use CheckForIntersection instead.')")
    
    # TODO: In Classic we had GetChildren return a list of wxGBSizerItems (in
    # a faked out way). Figure out how to do that here too....
    
    #module.addItem(
    #    tools.wxListWrapperTemplate('wxGBSizerItemList', 'wxGBSizerItem', module, 'wxSizerItem'))
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 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.

    module.addHeaderCode('#include <wx/richtext/richtextbuffer.h>')

    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextRangeArray', 'wxRichTextRange', module))
    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextAttrArray', 'wxRichTextAttr', module))
    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextVariantArray', 'wxVariant', module))
    module.addItem(
        tools.wxListWrapperTemplate('wxRichTextObjectList', 'wxRichTextObject', module))
    module.addItem(
        tools.wxListWrapperTemplate('wxRichTextLineList', 'wxRichTextLine', module))

    # Can this even work?  Apparently it does.
    module.addItem(
        tools.wxArrayPtrWrapperTemplate('wxRichTextObjectPtrArray', 'wxRichTextObject', module))
    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextObjectPtrArrayArray', 'wxRichTextObjectPtrArray', module))


    module.find('wxRICHTEXT_ALL').ignore()
    module.find('wxRICHTEXT_NONE').ignore()
    module.find('wxRICHTEXT_NO_SELECTION').ignore()
    code = etgtools.PyCodeDef("""\
        RICHTEXT_ALL = RichTextRange(-2, -2)
        RICHTEXT_NONE = RichTextRange(-1, -1)
        RICHTEXT_NO_SELECTION = RichTextRange(-2, -2)
        """)
    module.insertItemAfter(module.find('wxRichTextRange'), code)

    module.insertItem(0, etgtools.WigCode("""\
        // forward declarations
        class wxRichTextFloatCollector;
        """))


    #-------------------------------------------------------
    c = module.find('wxTextAttrDimension')
    assert isinstance(c, etgtools.ClassDef)
    c.find('SetValue').findOverload('units').ignore()
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextAttrDimensions')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextAttrSize')
    tools.ignoreConstOverloads(c)
    c.find('SetWidth').findOverload('units').ignore()
    c.find('SetHeight').findOverload('units').ignore()
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextAttrBorder')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")


    #-------------------------------------------------------
    c = module.find('wxTextAttrBorders')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")


    #-------------------------------------------------------
    c = module.find('wxTextBoxAttr')
    tools.ignoreConstOverloads(c)


    #-------------------------------------------------------
    c = module.find('wxRichTextAttr')
    tools.ignoreConstOverloads(c)


    #-------------------------------------------------------
    c = module.find('wxRichTextProperties')
    tools.ignoreConstOverloads(c)

    c.find('SetProperty').findOverload('bool').ignore()
    c.find('operator[]').ignore()

    #-------------------------------------------------------
    c = module.find('wxRichTextSelection')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")
    c.find('operator[]').ignore()


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

    # wxRichTextRange typemap
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxRichTextRange')

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

    tools.addGetIMMethodTemplate(module, c, ['Start', 'End'])

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


    #-------------------------------------------------------
    def _fixDrawObject(c, addMissingVirtuals=True):
        assert isinstance(c, etgtools.ClassDef)
        if c.findItem('HitTest'):
            c.find('HitTest.textPosition').out = True
            c.find('HitTest.obj').out = True
            c.find('HitTest.contextObj').out = True

        if c.findItem('FindPosition'):
            c.find('FindPosition.pt').out = True
            c.find('FindPosition.height').out = True

        if c.findItem('GetBoxRects'):
            c.find('GetBoxRects.marginRect').out = True
            c.find('GetBoxRects.borderRect').out = True
            c.find('GetBoxRects.contentRect').out = True
            c.find('GetBoxRects.paddingRect').out = True
            c.find('GetBoxRects.outlineRect').out = True

        if c.findItem('GetTotalMargin'):
            c.find('GetTotalMargin.leftMargin').out = True
            c.find('GetTotalMargin.rightMargin').out = True
            c.find('GetTotalMargin.topMargin').out = True
            c.find('GetTotalMargin.bottomMargin').out = True

        if c.findItem('CalculateRange'):
            c.find('CalculateRange.end').out = True  # TODO: should it be an inOut?

        if c.findItem('Clone'):
            c.find('Clone').factory = True
        else:
            c.addItem(etgtools.WigCode("""\
            virtual wxRichTextObject* Clone() const /Factory/;
            """))

        # These are the pure virtuals in the base class. SIP needs to see that
        # all the derived classes have an implementation, otherwise it will
        # consider them to be ABCs.
        if not c.findItem('Draw') and addMissingVirtuals:
            c.addItem(etgtools.WigCode("""\
                virtual bool Draw(wxDC& dc, wxRichTextDrawingContext& context,
                                  const wxRichTextRange& range,
                                  const wxRichTextSelection& selection,
                                  const wxRect& rect, int descent, int style);"""))
        if not c.findItem('Layout') and addMissingVirtuals:
            c.addItem(etgtools.WigCode("""\
                virtual bool Layout(wxDC& dc, wxRichTextDrawingContext& context,
                                    const wxRect& rect, const wxRect& parentRect,
                                    int style);"""))

        # TODO: Some of these args are output parameters.  How should they be dealt with?
        if not c.findItem('GetRangeSize') and addMissingVirtuals:
            c.addItem(etgtools.WigCode("""\
                virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size,
                              int& descent,
                              wxDC& dc, wxRichTextDrawingContext& context, int flags,
                              const wxPoint& position = wxPoint(0,0),
                              const wxSize& parentSize = wxDefaultSize,
                              wxArrayInt* partialExtents = NULL) const;"""))


    #-------------------------------------------------------
    c = module.find('wxRichTextObject')
    #c.find('ImportFromXML').ignore()
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)


    #-------------------------------------------------------
    c = module.find('wxRichTextCompositeObject')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c, addMissingVirtuals=False)


    #-------------------------------------------------------
    c = module.find('wxRichTextParagraphLayoutBox')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)

    c.find('MoveAnchoredObjectToParagraph.from').name = 'from_'
    c.find('MoveAnchoredObjectToParagraph.to').name = 'to_'
    c.find('DoNumberList.def').name = 'styleDef'
    c.find('SetListStyle.def').name = 'styleDef'

    #-------------------------------------------------------
    c = module.find('wxRichTextBox')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextCell')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextField')
    _fixDrawObject(c)


    #-------------------------------------------------------
    c = module.find('wxRichTextLine')
    tools.ignoreConstOverloads(c)
    c.find('SetRange.from').name = 'from_'
    c.find('SetRange.to').name = 'to_'
    c.find('Clone').factory = True

    #-------------------------------------------------------
    c = module.find('wxRichTextParagraph')
    _fixDrawObject(c)

    # These methods use an untyped wxList, but since we know what is in it
    # we'll make a fake typed list for wxPython so we can know what kinds of
    # values to get from it.
    module.addItem(
        tools.wxListWrapperTemplate('wxList', 'wxRichTextObject', module,
                                    fakeListClassName='wxRichTextObjectList_'))
    c.find('MoveToList.list').type = 'wxRichTextObjectList_&'
    c.find('MoveFromList.list').type = 'wxRichTextObjectList_&'


    #-------------------------------------------------------
    c = module.find('wxRichTextPlainText')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextImage')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextBuffer')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)

    # More untyped wxLists
    module.addItem(
        tools.wxListWrapperTemplate('wxList', 'wxRichTextFileHandler', module,
                                    fakeListClassName='wxRichTextFileHandlerList'))
    c.find('GetHandlers').type = 'wxRichTextFileHandlerList&'
    c.find('GetHandlers').noCopy = True

    module.addItem(
        tools.wxListWrapperTemplate('wxList', 'wxRichTextDrawingHandler', module,
                                    fakeListClassName='wxRichTextDrawingHandlerList'))
    c.find('GetDrawingHandlers').type = 'wxRichTextDrawingHandlerList&'
    c.find('GetDrawingHandlers').noCopy = True

    # TODO: Need a template to wrap STRING_HASH_MAP
    c.find('GetFieldTypes').ignore()

    c.find('AddHandler.handler').transfer = True
    c.find('InsertHandler.handler').transfer = True

    c.find('AddDrawingHandler.handler').transfer = True
    c.find('InsertDrawingHandler.handler').transfer = True

    c.find('AddFieldType.fieldType').transfer = True

    # TODO:  Transfer ownership with AddEventHandler?  TransferBack with Remove?


    c.find('FindHandler').renameOverload('name', 'FindHandlerByName')
    c.find('FindHandler').renameOverload('extension', 'FindHandlerByExtension')
    c.find('FindHandler').pyName = 'FindHandlerByType'

    c.find('FindHandlerFilenameOrType').pyName = 'FindHandlerByFilename'

    c.find('GetExtWildcard').ignore()
    c.addCppMethod('PyObject*', 'GetExtWildcard', '(bool combine=false, bool save=false)',
        doc="""\
            Gets a wildcard string for the file dialog based on all the currently
            loaded richtext file handlers, and a list that can be used to map
            those filter types to the file handler type.""",
        body="""\
            wxString wildcards;
            wxArrayInt types;
            wildcards = wxRichTextBuffer::GetExtWildcard(combine, save, &types);

            wxPyThreadBlocker blocker;
            PyObject* list = PyList_New(0);
            for (size_t i=0; i < types.GetCount(); i++) {
                PyObject* number = wxPyInt_FromLong(types[i]);
                PyList_Append(list, number);
                Py_DECREF(number);
            }
            PyObject* tup = PyTuple_New(2);
            PyTuple_SET_ITEM(tup, 0, wx2PyString(wildcards));
            PyTuple_SET_ITEM(tup, 1, list);
            return tup;
            """,
        isStatic=True)

    #-------------------------------------------------------
    c = module.find('wxRichTextTable')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)


    #-------------------------------------------------------
    c = module.find('wxRichTextObjectAddress')
    tools.ignoreConstOverloads(c)


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

    module.addItem(
        tools.wxListWrapperTemplate('wxList', 'wxRichTextAction', module,
                                    fakeListClassName='wxRichTextActionList'))
    c.find('GetActions').type = 'wxRichTextActionList&'
    c.find('GetActions').noCopy = True

    c.find('AddAction.action').transfer = True


    #-------------------------------------------------------
    c = module.find('wxRichTextAction')
    tools.ignoreConstOverloads(c)


    #-------------------------------------------------------
    c = module.find('wxRichTextFileHandler')
    c.find('DoLoadFile').ignore(False)
    c.find('DoSaveFile').ignore(False)

    c = module.find('wxRichTextPlainTextHandler')
    c.find('DoLoadFile').ignore(False)
    c.find('DoSaveFile').ignore(False)




    #-------------------------------------------------------
    # Ignore all Dump() methods since we don't wrap wxTextOutputStream.

    # TODO: try swithcing the parameter type to wxOutputStream and then in
    # the wrapper code create a wxTextOutputStream from that to pass on to
    # Dump.

    for m in module.findAll('Dump'):
        if m.findItem('stream'):
            m.ignore()



    # Correct the type for this define as it is a float
    module.find('wxSCRIPT_MUL_FACTOR').type = 'float'

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 5
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.
    
    
    # ignore some of these enum values
    e = module.find('wxBitmapType')
    for i in e:
        if i.name.endswith('_RESOURCE'):
            i.ignore()
    
    module.addCppCode("""\
    #if !defined(__WXMAC__)
    #define wxCURSOR_COPY_ARROW wxCURSOR_ARROW
    #endif
    """)
    
    # these are X11 only
    e = module.find('wxStockCursor')
    e.find('wxCURSOR_BASED_ARROW_DOWN').ignore()
    e.find('wxCURSOR_BASED_ARROW_UP').ignore()
    e.find('wxCURSOR_CROSS_REVERSE').ignore()
    e.find('wxCURSOR_DOUBLE_ARROW').ignore()
    
    module.find('wxClientDisplayRect.x').out = True
    module.find('wxClientDisplayRect.y').out = True
    module.find('wxClientDisplayRect.width').out = True
    module.find('wxClientDisplayRect.height').out = True
    
    module.find('wxDisplaySize.width').out = True
    module.find('wxDisplaySize.height').out = True
    module.find('wxDisplaySizeMM.width').out = True
    module.find('wxDisplaySizeMM.height').out = True
    
    #---------------------------------------
    # wxPoint tweaks
    c = module.find('wxPoint')
    tools.addAutoProperties(c)
    
    # Some operators are documented within the class that shouldn't be, so just
    # ignore them all.
    tools.ignoreAllOperators(c)
    
    # Undo a few of those ignores for legitimate items that were 
    # documented correctly
    for f in c.find('operator+=').all() + c.find('operator-=').all():
        f.ignore(False)
        
    # Add some method declarations for operators that really do exist. Note
    # that these actually use C++ global operator functions, but we treat
    # them as methods to help disambiguate implementations due to how
    # multiple classes can be converted automatically to/from 2-element
    # sequences.    
    c.addCppMethod('bool', '__eq__', '(const wxPoint& other)',
        body="return *self == *other;")
    c.addCppMethod('bool', '__neq__', '(const wxPoint& other)',
        body="return *self != *other;")
    
    c.addItem(etgtools.WigCode("""\
        wxPoint operator+(const wxPoint& other);
        wxPoint operator-();
        wxPoint operator-(const wxPoint& other);
        wxPoint operator*(int i);
        wxPoint operator/(int i);
        """))
    
    
    # wxPoint typemap
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxPoint')
    
    c.addCppMethod('PyObject*', 'Get', '()', """\
        return sipBuildResult(0, "(ii)", self->x, self->y);
        """, 
        pyArgsString="() -> (x,y)",
        briefDoc="Return the x and y properties as a tuple.")
    
    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)',             'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',            'return "wx.Point"+str(self.Get())')
    c.addPyMethod('__len__', '(self)',             'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)',         'return self.Get() != (0,0)')
    c.addPyMethod('__reduce__', '(self)',          'return (Point, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)',    'return self.Get()[idx]')
    c.addPyMethod('__setitem__', '(self, idx, val)',
                  """\
                  if idx == 0: self.x = val
                  elif idx == 1: self.y = val
                  else: raise IndexError
                  """) 
    c.addPyCode('Point.__safe_for_unpickling__ = True')
                                    
    module.addItem(
        tools.wxListWrapperTemplate('wxPointList', 'wxPoint', module, includeConvertToType=True))
    
    
    #---------------------------------------
    # wxSize tweaks
    c = module.find('wxSize')
    tools.addAutoProperties(c)

    # Used for testing releasing or holding the GIL in giltest.py
    #c.find('wxSize').findOverload('int width, int height').releaseGIL()
    #c.find('DecBy').findOverload('int dx, int dy').releaseGIL()
    #c.find('IncBy').findOverload('int dx, int dy').releaseGIL()
        
    c.addProperty("width GetWidth SetWidth")
    c.addProperty("height GetHeight SetHeight")

    # TODO:  How prevalent is the use of x,y properties on a size object?  Can we deprecate them?
    c.addProperty("x GetWidth SetWidth")
    c.addProperty("y GetHeight SetHeight")
    
    # Take care of the same issues as wxPoint
    tools.ignoreAllOperators(c)
    for f in c.find('operator+=').all() + \
             c.find('operator-=').all() + \
             c.find('operator*=').all() + \
             c.find('operator/=').all():
        f.ignore(False)
        
    c.addCppMethod('bool', '__eq__', '(const wxSize& other)',
        body="return *self == *other;")
    c.addCppMethod('bool', '__neq__', '(const wxSize& other)',
        body="return *self != *other;")
    
    c.addItem(etgtools.WigCode("""\
        wxSize operator+(const wxSize& other);
        wxSize operator-(const wxSize& other);
        wxSize operator*(int i);
        wxSize operator/(int i);

        wxPoint operator+(const wxPoint& other);
        wxPoint operator-(const wxPoint& other);
        wxRealPoint operator+(const wxRealPoint& other);
        wxRealPoint operator-(const wxRealPoint& other);
        """))
    
    
    # wxSize typemap
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxSize')
    
    c.addCppMethod('PyObject*', 'Get', '()', """\
        return sipBuildResult(0, "(ii)", self->GetWidth(), self->GetHeight());
        """,
        pyArgsString="() -> (width, height)",
        briefDoc="Return the width and height properties as a tuple.")
    
    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)',             'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',            'return "wx.Size"+str(self.Get())')
    c.addPyMethod('__len__', '(self)',             'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)',         'return self.Get() != (0,0)')
    c.addPyMethod('__reduce__', '(self)',          'return (Size, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)',    'return self.Get()[idx]')
    c.addPyMethod('__setitem__', '(self, idx, val)',
                  """\
                  if idx == 0: self.width = val
                  elif idx == 1: self.height = val
                  else: raise IndexError
                  """) 
    c.addPyCode('Size.__safe_for_unpickling__ = True')
    
    
    
    #---------------------------------------
    # wxRect tweaks
    c = module.find('wxRect')
    assert isinstance(c, etgtools.ClassDef)
    tools.addAutoProperties(c)
    
    c.addProperty("left GetLeft SetLeft")
    c.addProperty("top GetTop SetTop")
    c.addProperty("right GetRight SetRight")
    c.addProperty("bottom GetBottom SetBottom")
    
    c.addProperty("bottomLeft GetBottomLeft SetBottomLeft")
    c.addProperty("bottomRight GetBottomRight SetBottomRight")
    c.addProperty("topLeft GetTopLeft SetTopLeft")
    c.addProperty("topRight GetTopRight SetTopRight")
    
    # take care of the same issues as wxPoint
    tools.ignoreAllOperators(c)
    for f in c.find('operator+=').all() + \
             c.find('operator*=').all():
        f.ignore(False)
                
    c.addCppMethod('bool', '__eq__', '(const wxRect& other)',
        body="return *self == *other;")
    c.addCppMethod('bool', '__neq__', '(const wxRect& other)',
        body="return *self != *other;")
    
    c.addItem(etgtools.WigCode("""\
        wxRect operator+(const wxRect& other);
        wxRect operator*(const wxRect& other);
        """))

    
    # Because of our add-ons that make wx.Point and wx.Size act like 2-element
    # sequences, and also the typecheck code that allows 2-element sequences, then
    # we end up with a bit of confusion about the (Point,Point) and the
    # (Point,Size) overloads of the wx.Rect constructor. The confusion can be
    # dealt with by using keyword args, but I think that the (Point,Size) version
    # will be used more, so reorder the overloads so it is found first.
    m = module.find('wxRect.wxRect')
    mo = m.findOverload('topLeft')
    del m.overloads[m.overloads.index(mo)]
    m.overloads.append(mo)
    
    # These methods have some overloads that will end up with the same signature
    # in Python, so we have to remove one.
    module.find('wxRect.Deflate').findOverload(') const').ignore()
    module.find('wxRect.Inflate').findOverload(') const').ignore()
    module.find('wxRect.Union').findOverload(') const').ignore()
    module.find('wxRect.Intersect').findOverload(') const').ignore()
    
    # wxRect typemap
    c.convertFromPyObject = tools.convertFourIntegersTemplate('wxRect')
    
    c.addCppMethod('PyObject*', 'Get', '()', """\
        return sipBuildResult(0, "(iiii)", 
                              self->x, self->y, self->width, self->height);
        """, 
        pyArgsString="() -> (x, y, width, height)",
        briefDoc="Return the rectangle's properties as a tuple.")
    
    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)',             'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',            'return "wx.Rect"+str(self.Get())')
    c.addPyMethod('__len__', '(self)',             'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)',         'return self.Get() != (0,0,0,0)')
    c.addPyMethod('__reduce__', '(self)',          'return (Rect, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)',    'return self.Get()[idx]')
    c.addPyMethod('__setitem__', '(self, idx, val)',
                  """\
                  if idx == 0: self.x = val
                  elif idx == 1: self.y = val
                  elif idx == 2: self.width = val
                  elif idx == 3: self.height = val
                  else: raise IndexError
                  """) 
    c.addPyCode('Rect.__safe_for_unpickling__ = True')
    
    
    
    #---------------------------------------
    # wxRealPoint tweaks
    c = module.find('wxRealPoint')
    tools.addAutoProperties(c)
        
    # take care of the same issues as wxPoint
    tools.ignoreAllOperators(c)
    for f in c.find('operator+=').all() + \
             c.find('operator-=').all():
        f.ignore(False)
                
    c.addCppMethod('bool', '__eq__', '(const wxRealPoint& other)',
        body="return *self == *other;")
    c.addCppMethod('bool', '__neq__', '(const wxRealPoint& other)',
        body="return *self != *other;")
    
    c.addItem(etgtools.WigCode("""\
        wxRealPoint operator+(const wxRealPoint& other);
        wxRealPoint operator-(const wxRealPoint& other);
        wxRealPoint operator*(int i);
        wxRealPoint operator/(int i);
        """))

        
    # wxRealPoint typemap
    c.convertFromPyObject = tools.convertTwoDoublesTemplate('wxRealPoint')

    c.addCppMethod('PyObject*', 'Get', '()', """\
        return sipBuildResult(0, "(dd)", self->x, self->y);
        """, 
        pyArgsString="() -> (x, y)",
        briefDoc="Return the point's properties as a tuple.")
    
    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)',             'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',            'return "wx.RealPoint"+str(self.Get())')
    c.addPyMethod('__len__', '(self)',             'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)',         'return self.Get() != (0,0)')
    c.addPyMethod('__reduce__', '(self)',          'return (Rect, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)',    'return self.Get()[idx]')
    c.addPyMethod('__setitem__', '(self, idx, val)',
                  """\
                  if idx == 0: self.x = val
                  elif idx == 1: self.y = val
                  else: raise IndexError
                  """) 
    c.addPyCode('RealPoint.__safe_for_unpickling__ = True')

    
    
    
    c = module.find('wxColourDatabase')
    c.addPyMethod('FindColour', '(self, colour)',    'return self.Find(colour)')   

    module.find('wxTheColourDatabase').ignore()
        
                               
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 6
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
    c.find('Draw').isPureVirtual = False
    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.addPrivateAssignOp()
    c.addPrivateDefaultCtor()
    c.instanceCode = """\
        wxGridActivationResult result = wxGridActivationResult::DoNothing();
        sipCpp = &result;
        """

    c = module.find('wxGridActivationSource')
    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 = module.find('wxGridCellActivatableEditor')

    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

    c.find('GetRendererPtr').ignore()

    #-----------------------------------------------------------------
    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 so 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_COL_AUTO_SIZE = wx.PyEventBinder( wxEVT_GRID_COL_AUTO_SIZE )
        EVT_GRID_RANGE_SELECTING = wx.PyEventBinder( wxEVT_GRID_RANGE_SELECTING )
        EVT_GRID_RANGE_SELECTED = wx.PyEventBinder( wxEVT_GRID_RANGE_SELECTED )
        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_ROW_MOVE = wx.PyEventBinder( wxEVT_GRID_ROW_MOVE )
        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_COL_AUTO_SIZE =       wx.PyEventBinder( wxEVT_GRID_COL_AUTO_SIZE,      1 )
        EVT_GRID_CMD_RANGE_SELECTING =     wx.PyEventBinder( wxEVT_GRID_RANGE_SELECTING,    1 )
        EVT_GRID_CMD_RANGE_SELECTED =      wx.PyEventBinder( wxEVT_GRID_RANGE_SELECTED,     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_ROW_MOVE =            wx.PyEventBinder( wxEVT_GRID_ROW_MOVE,           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 )

        # Just for compatibility, remove them in a future release
        EVT_GRID_RANGE_SELECT =            EVT_GRID_RANGE_SELECTED
        EVT_GRID_CMD_RANGE_SELECT =        EVT_GRID_CMD_RANGE_SELECTED
        wxEVT_GRID_RANGE_SELECT =          wxEVT_GRID_RANGE_SELECTED

        """)

    #-----------------------------------------------------------------
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 7
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.addHeaderCode('#include <wx/richtext/richtextbuffer.h>')

    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextRangeArray', 'wxRichTextRange',
                                     module))
    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextAttrArray', 'wxRichTextAttr',
                                     module))
    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextVariantArray', 'wxVariant',
                                     module))
    module.addItem(
        tools.wxListWrapperTemplate('wxRichTextObjectList', 'wxRichTextObject',
                                    module))
    module.addItem(
        tools.wxListWrapperTemplate('wxRichTextLineList', 'wxRichTextLine',
                                    module))

    # Can this even work?  Apparently it does.
    module.addItem(
        tools.wxArrayPtrWrapperTemplate('wxRichTextObjectPtrArray',
                                        'wxRichTextObject', module))
    module.addItem(
        tools.wxArrayWrapperTemplate('wxRichTextObjectPtrArrayArray',
                                     'wxRichTextObjectPtrArray', module))

    module.find('wxRICHTEXT_ALL').ignore()
    module.find('wxRICHTEXT_NONE').ignore()
    module.find('wxRICHTEXT_NO_SELECTION').ignore()
    code = etgtools.PyCodeDef("""\
        RICHTEXT_ALL = RichTextRange(-2, -2)
        RICHTEXT_NONE = RichTextRange(-1, -1)
        RICHTEXT_NO_SELECTION = RichTextRange(-2, -2)
        """)
    module.insertItemAfter(module.find('wxRichTextRange'), code)

    module.insertItem(
        0,
        etgtools.WigCode("""\
        // forward declarations
        class wxRichTextFloatCollector;
        """))

    #-------------------------------------------------------
    c = module.find('wxTextAttrDimension')
    assert isinstance(c, etgtools.ClassDef)
    c.find('SetValue').findOverload('units').ignore()
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextAttrDimensions')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextAttrSize')
    tools.ignoreConstOverloads(c)
    c.find('SetWidth').findOverload('units').ignore()
    c.find('SetHeight').findOverload('units').ignore()
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextAttrBorder')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextAttrBorders')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")

    #-------------------------------------------------------
    c = module.find('wxTextBoxAttr')
    tools.ignoreConstOverloads(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextAttr')
    tools.ignoreConstOverloads(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextProperties')
    tools.ignoreConstOverloads(c)

    c.find('SetProperty').findOverload('bool').ignore()
    c.find('operator[]').ignore()

    #-------------------------------------------------------
    c = module.find('wxRichTextSelection')
    tools.ignoreConstOverloads(c)
    c.addCppMethod('int', '__nonzero__', '()', "return self->IsValid();")
    c.find('operator[]').ignore()

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

    # wxRichTextRange typemap
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxRichTextRange')

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        return sipBuildResult(0, "(ii)", self->GetStart(), self->GetEnd());
        """,
                   pyArgsString="() -> (start, end)",
                   briefDoc="Return the start and end properties as a tuple.")

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

    #-------------------------------------------------------
    def _fixDrawObject(c, addMissingVirtuals=True):
        assert isinstance(c, etgtools.ClassDef)
        if c.findItem('HitTest'):
            c.find('HitTest.textPosition').out = True
            c.find('HitTest.obj').out = True
            c.find('HitTest.contextObj').out = True

        if c.findItem('FindPosition'):
            c.find('FindPosition.pt').out = True
            c.find('FindPosition.height').out = True

        if c.findItem('GetBoxRects'):
            c.find('GetBoxRects.marginRect').out = True
            c.find('GetBoxRects.borderRect').out = True
            c.find('GetBoxRects.contentRect').out = True
            c.find('GetBoxRects.paddingRect').out = True
            c.find('GetBoxRects.outlineRect').out = True

        if c.findItem('GetTotalMargin'):
            c.find('GetTotalMargin.leftMargin').out = True
            c.find('GetTotalMargin.rightMargin').out = True
            c.find('GetTotalMargin.topMargin').out = True
            c.find('GetTotalMargin.bottomMargin').out = True

        if c.findItem('CalculateRange'):
            c.find('CalculateRange.end'
                   ).out = True  # TODO: should it be an inOut?

        if c.findItem('Clone'):
            c.find('Clone').factory = True
        else:
            c.addItem(
                etgtools.WigCode("""\
            virtual wxRichTextObject* Clone() const /Factory/;
            """))

        # These are the pure virtuals in the base class. SIP needs to see that
        # all the derived classes have an implementation, otherwise it will
        # consider them to be ABCs.
        if not c.findItem('Draw') and addMissingVirtuals:
            c.addItem(
                etgtools.WigCode("""\
                virtual bool Draw(wxDC& dc, wxRichTextDrawingContext& context,
                                  const wxRichTextRange& range,
                                  const wxRichTextSelection& selection,
                                  const wxRect& rect, int descent, int style);"""
                                 ))
        if not c.findItem('Layout') and addMissingVirtuals:
            c.addItem(
                etgtools.WigCode("""\
                virtual bool Layout(wxDC& dc, wxRichTextDrawingContext& context,
                                    const wxRect& rect, const wxRect& parentRect,
                                    int style);"""))

        # TODO: Some of these args are output parameters.  How should they be dealt with?
        if not c.findItem('GetRangeSize') and addMissingVirtuals:
            c.addItem(
                etgtools.WigCode("""\
                virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size,
                              int& descent,
                              wxDC& dc, wxRichTextDrawingContext& context, int flags,
                              const wxPoint& position = wxPoint(0,0),
                              const wxSize& parentSize = wxDefaultSize,
                              wxArrayInt* partialExtents = NULL) const;"""))

    #-------------------------------------------------------
    c = module.find('wxRichTextObject')
    #c.find('ImportFromXML').ignore()
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextCompositeObject')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c, addMissingVirtuals=False)

    #-------------------------------------------------------
    c = module.find('wxRichTextParagraphLayoutBox')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)

    c.find('MoveAnchoredObjectToParagraph.from').name = 'from_'
    c.find('MoveAnchoredObjectToParagraph.to').name = 'to_'
    c.find('DoNumberList.def').name = 'styleDef'
    c.find('SetListStyle.def').name = 'styleDef'

    #-------------------------------------------------------
    c = module.find('wxRichTextBox')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextCell')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextField')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextLine')
    tools.ignoreConstOverloads(c)
    c.find('SetRange.from').name = 'from_'
    c.find('SetRange.to').name = 'to_'
    c.find('Clone').factory = True

    #-------------------------------------------------------
    c = module.find('wxRichTextParagraph')
    _fixDrawObject(c)

    # These methods use an untyped wxList, but since we know what is in it
    # we'll make a fake typed list for wxPython so we can know what kinds of
    # values to get from it.
    module.addItem(
        tools.wxListWrapperTemplate('wxList',
                                    'wxRichTextObject',
                                    module,
                                    fakeListClassName='wxRichTextObjectList_'))
    c.find('MoveToList.list').type = 'wxRichTextObjectList_&'
    c.find('MoveFromList.list').type = 'wxRichTextObjectList_&'

    #-------------------------------------------------------
    c = module.find('wxRichTextPlainText')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextImage')
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextBuffer')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)

    # More untyped wxLists
    module.addItem(
        tools.wxListWrapperTemplate(
            'wxList',
            'wxRichTextFileHandler',
            module,
            fakeListClassName='wxRichTextFileHandlerList'))
    c.find('GetHandlers').type = 'wxRichTextFileHandlerList&'
    c.find('GetHandlers').noCopy = True

    module.addItem(
        tools.wxListWrapperTemplate(
            'wxList',
            'wxRichTextDrawingHandler',
            module,
            fakeListClassName='wxRichTextDrawingHandlerList'))
    c.find('GetDrawingHandlers').type = 'wxRichTextDrawingHandlerList&'
    c.find('GetDrawingHandlers').noCopy = True

    # TODO: Need a template to wrap STRING_HASH_MAP
    c.find('GetFieldTypes').ignore()

    c.find('AddHandler.handler').transfer = True
    c.find('InsertHandler.handler').transfer = True

    c.find('AddDrawingHandler.handler').transfer = True
    c.find('InsertDrawingHandler.handler').transfer = True

    c.find('AddFieldType.fieldType').transfer = True

    # TODO:  Transfer ownership with AddEventHandler?  TransferBack with Remove?

    c.find('FindHandler').renameOverload('name', 'FindHandlerByName')
    c.find('FindHandler').renameOverload('extension', 'FindHandlerByExtension')
    c.find('FindHandler').pyName = 'FindHandlerByType'

    c.find('FindHandlerFilenameOrType').pyName = 'FindHandlerByFilename'

    #-------------------------------------------------------
    c = module.find('wxRichTextTable')
    tools.ignoreConstOverloads(c)
    _fixDrawObject(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextObjectAddress')
    tools.ignoreConstOverloads(c)

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

    module.addItem(
        tools.wxListWrapperTemplate('wxList',
                                    'wxRichTextAction',
                                    module,
                                    fakeListClassName='wxRichTextActionList'))
    c.find('GetActions').type = 'wxRichTextActionList&'
    c.find('GetActions').noCopy = True

    c.find('AddAction.action').transfer = True

    #-------------------------------------------------------
    c = module.find('wxRichTextAction')
    tools.ignoreConstOverloads(c)

    #-------------------------------------------------------
    c = module.find('wxRichTextFileHandler')
    c.find('DoLoadFile').ignore(False)
    c.find('DoSaveFile').ignore(False)

    c = module.find('wxRichTextPlainTextHandler')
    c.find('DoLoadFile').ignore(False)
    c.find('DoSaveFile').ignore(False)

    #-------------------------------------------------------
    # Ignore all Dump() methods since we don't wrap wxTextOutputStream.

    # TODO: try swithcing the parameter type to wxOutputStream and then in
    # the wrapper code create a wxTextOutputStream from that to pass on to
    # Dump.

    for m in module.findAll('Dump'):
        if m.findItem('stream'):
            m.ignore()

    # Correct the type for this define as it is a float
    module.find('wxSCRIPT_MUL_FACTOR').type = 'float'

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 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.

    # ignore some of these enum values
    e = module.find('wxBitmapType')
    for i in e:
        if i.name.endswith('_RESOURCE'):
            i.ignore()

    module.addCppCode("""\
    #if !defined(__WXMAC__)
    #define wxCURSOR_COPY_ARROW wxCURSOR_ARROW
    #endif
    """)

    # these are X11 only
    e = module.find('wxStockCursor')
    e.find('wxCURSOR_BASED_ARROW_DOWN').ignore()
    e.find('wxCURSOR_BASED_ARROW_UP').ignore()
    e.find('wxCURSOR_CROSS_REVERSE').ignore()
    e.find('wxCURSOR_DOUBLE_ARROW').ignore()

    module.find('wxClientDisplayRect.x').out = True
    module.find('wxClientDisplayRect.y').out = True
    module.find('wxClientDisplayRect.width').out = True
    module.find('wxClientDisplayRect.height').out = True

    module.find('wxDisplaySize.width').out = True
    module.find('wxDisplaySize.height').out = True
    module.find('wxDisplaySizeMM.width').out = True
    module.find('wxDisplaySizeMM.height').out = True

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

    # Some operators are documented within the class that shouldn't be, so just
    # ignore them all.
    tools.ignoreAllOperators(c)

    # Undo a few of those ignores for legitimate items that were
    # documented correctly
    for f in c.find('operator+=').all() + c.find('operator-=').all():
        f.ignore(False)

    # Add some method declarations for operators that really do exist. Note
    # that these actually use C++ global operator functions, but we treat
    # them as methods to help disambiguate implementations due to how
    # multiple classes can be converted automatically to/from 2-element
    # sequences.
    c.addCppMethod('bool',
                   '__eq__',
                   '(const wxPoint& other)',
                   body="return *self == *other;")
    c.addCppMethod('bool',
                   '__ne__',
                   '(const wxPoint& other)',
                   body="return *self != *other;")

    c.addItem(
        etgtools.WigCode("""\
        wxPoint operator+(const wxPoint& other);
        wxPoint operator-();
        wxPoint operator-(const wxPoint& other);
        wxPoint operator*(int i);
        wxPoint operator/(int i);
        """))

    # wxPoint typemap
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxPoint')

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        return sipBuildResult(0, "(ii)", self->x, self->y);
        """,
                   pyArgsString="() -> (x,y)",
                   briefDoc="Return the x and y properties as a tuple.")

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

    module.addItem(
        tools.wxListWrapperTemplate('wxPointList',
                                    'wxPoint',
                                    module,
                                    includeConvertToType=True))

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

    # Used for testing releasing or holding the GIL in giltest.py
    #c.find('wxSize').findOverload('int width, int height').releaseGIL()
    #c.find('DecBy').findOverload('int dx, int dy').releaseGIL()
    #c.find('IncBy').findOverload('int dx, int dy').releaseGIL()

    c.addProperty("width GetWidth SetWidth")
    c.addProperty("height GetHeight SetHeight")

    # TODO:  How prevalent is the use of x,y properties on a size object?  Can we deprecate them?
    c.addProperty("x GetWidth SetWidth")
    c.addProperty("y GetHeight SetHeight")

    # Take care of the same issues as wxPoint
    tools.ignoreAllOperators(c)
    for f in c.find('operator+=').all() + \
             c.find('operator-=').all() + \
             c.find('operator*=').all() + \
             c.find('operator/=').all():
        f.ignore(False)

    c.addCppMethod('bool',
                   '__eq__',
                   '(const wxSize& other)',
                   body="return *self == *other;")
    c.addCppMethod('bool',
                   '__ne__',
                   '(const wxSize& other)',
                   body="return *self != *other;")

    c.addItem(
        etgtools.WigCode("""\
        wxSize operator+(const wxSize& other);
        wxSize operator-(const wxSize& other);
        wxSize operator*(int i);
        wxSize operator/(int i);

        wxPoint operator+(const wxPoint& other);
        wxPoint operator-(const wxPoint& other);
        wxRealPoint operator+(const wxRealPoint& other);
        wxRealPoint operator-(const wxRealPoint& other);
        """))

    # wxSize typemap
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxSize')

    c.addCppMethod(
        'PyObject*',
        'Get',
        '()',
        """\
        return sipBuildResult(0, "(ii)", self->GetWidth(), self->GetHeight());
        """,
        pyArgsString="() -> (width, height)",
        briefDoc="Return the width and height properties as a tuple.")

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

    #---------------------------------------
    # wxRect tweaks
    c = module.find('wxRect')
    assert isinstance(c, etgtools.ClassDef)
    tools.addAutoProperties(c)

    c.addProperty("left GetLeft SetLeft")
    c.addProperty("top GetTop SetTop")
    c.addProperty("right GetRight SetRight")
    c.addProperty("bottom GetBottom SetBottom")

    c.addProperty("bottomLeft GetBottomLeft SetBottomLeft")
    c.addProperty("bottomRight GetBottomRight SetBottomRight")
    c.addProperty("topLeft GetTopLeft SetTopLeft")
    c.addProperty("topRight GetTopRight SetTopRight")

    # take care of the same issues as wxPoint
    tools.ignoreAllOperators(c)
    for f in c.find('operator+=').all() + \
             c.find('operator*=').all():
        f.ignore(False)

    c.addCppMethod('bool',
                   '__eq__',
                   '(const wxRect& other)',
                   body="return *self == *other;")
    c.addCppMethod('bool',
                   '__ne__',
                   '(const wxRect& other)',
                   body="return *self != *other;")

    c.addItem(
        etgtools.WigCode("""\
        wxRect operator+(const wxRect& other);
        wxRect operator*(const wxRect& other);
        """))

    # Because of our add-ons that make wx.Point and wx.Size act like 2-element
    # sequences, and also the typecheck code that allows 2-element sequences, then
    # we end up with a bit of confusion about the (Point,Point) and the
    # (Point,Size) overloads of the wx.Rect constructor. The confusion can be
    # dealt with by using keyword args, but I think that the (Point,Size) version
    # will be used more, so reorder the overloads so it is found first.
    m = module.find('wxRect.wxRect')
    mo = m.findOverload('topLeft')
    del m.overloads[m.overloads.index(mo)]
    m.overloads.append(mo)

    # These methods have some overloads that will end up with the same signature
    # in Python, so we have to remove one.
    module.find('wxRect.Deflate').findOverload(') const').ignore()
    module.find('wxRect.Inflate').findOverload(') const').ignore()
    module.find('wxRect.Union').findOverload(') const').ignore()
    module.find('wxRect.Intersect').findOverload(') const').ignore()

    # wxRect typemap
    c.convertFromPyObject = tools.convertFourIntegersTemplate('wxRect')

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        return sipBuildResult(0, "(iiii)",
                              self->x, self->y, self->width, self->height);
        """,
                   pyArgsString="() -> (x, y, width, height)",
                   briefDoc="Return the rectangle's properties as a tuple.")

    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)', 'return "wx.Rect"+str(self.Get())')
    c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)', 'return self.Get() != (0,0,0,0)')
    c.addPyMethod('__reduce__', '(self)', 'return (Rect, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
    c.addPyMethod(
        '__setitem__', '(self, idx, val)', """\
                  if idx == 0: self.x = val
                  elif idx == 1: self.y = val
                  elif idx == 2: self.width = val
                  elif idx == 3: self.height = val
                  else: raise IndexError
                  """)
    c.addPyCode('Rect.__safe_for_unpickling__ = True')

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

    # take care of the same issues as wxPoint
    tools.ignoreAllOperators(c)
    for f in c.find('operator+=').all() + \
             c.find('operator-=').all():
        f.ignore(False)

    c.addCppMethod('bool',
                   '__eq__',
                   '(const wxRealPoint& other)',
                   body="return *self == *other;")
    c.addCppMethod('bool',
                   '__ne__',
                   '(const wxRealPoint& other)',
                   body="return *self != *other;")

    c.addItem(
        etgtools.WigCode("""\
        wxRealPoint operator+(const wxRealPoint& other);
        wxRealPoint operator-(const wxRealPoint& other);
        wxRealPoint operator*(int i);
        wxRealPoint operator/(int i);
        """))

    # wxRealPoint typemap
    c.convertFromPyObject = tools.convertTwoDoublesTemplate('wxRealPoint')

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        return sipBuildResult(0, "(dd)", self->x, self->y);
        """,
                   pyArgsString="() -> (x, y)",
                   briefDoc="Return the point's properties as a tuple.")

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

    c = module.find('wxColourDatabase')
    c.mustHaveApp()
    c.addPyMethod('FindColour', '(self, colour)', 'return self.Find(colour)')

    module.find('wxTheColourDatabase').ignore()

    #-----------------------------------------------------------------
    module.addCppFunction('PyObject*',
                          'IntersectRect',
                          '(wxRect* r1, wxRect* r2)',
                          doc="""\
            Calculate and return the intersection of r1 and r2.  Returns None if there
            is no intersection.""",
                          body="""\
            wxRegion  reg1(*r1);
            wxRegion  reg2(*r2);
            wxRect    dest(0,0,0,0);
            PyObject* obj;

            reg1.Intersect(reg2);
            dest = reg1.GetBox();

            wxPyThreadBlocker blocker;
            if (dest != wxRect(0,0,0,0)) {
                wxRect* newRect = new wxRect(dest);
                obj = wxPyConstructObject((void*)newRect, wxT("wxRect"), true);
                return obj;
            }
            Py_INCREF(Py_None);
            return Py_None;
            """)

    for funcname in [
            'wxColourDisplay',
            'wxDisplayDepth',
            'wxDisplaySize',
            'wxGetDisplaySize',
            'wxDisplaySizeMM',
            'wxGetDisplaySizeMM',
            'wxGetDisplayPPI',
            'wxClientDisplayRect',
            'wxGetClientDisplayRect',
            'wxSetCursor',
            #'wxGetXDisplay',
    ]:
        c = module.find(funcname)
        c.mustHaveApp()

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 9
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_TEXT =      "string"
        GRID_VALUE_LONG =      "long"
        GRID_VALUE_CHOICEINT = "choiceint"
        GRID_VALUE_DATETIME =  "datetime"
        """)

    #-----------------------------------------------------------------
    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',
                   '()',
                   """\
        return sipBuildResult(0, "(ii)", self->GetRow(), self->GetCol());
        """,
                   pyArgsString="() -> (row,col)",
                   briefDoc="Return the row and col properties as a tuple.")

    # 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('__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))

    #-----------------------------------------------------------------
    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.addAutoProperties(klass)

        methods = [
            ('Clone', "virtual wxGridCellRenderer* Clone() const;"),
            ('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)

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

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

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

        methods = [
            ('BeginEdit',
             "virtual void BeginEdit(int row, int col, wxGrid* grid);"),
            ('Clone', "virtual wxGridCellEditor* Clone() const;"),
            ('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++ siganture
            # 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 == Py_None) {
                    sipRes = false;
                } 
                else {
                    sipRes = true;
                    *newval = Py2wxString(result);
                }
                Py_DECREF(result);
                """ if pureVirtual else "",  # only used with the base class
        )

    c = module.find('wxGridCellEditor')
    c.addPrivateCopyCtor()
    c.find('~wxGridCellEditor').ignore(False)

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

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

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

    #-----------------------------------------------------------------
    c = module.find('wxGridCellAttr')
    c.addPrivateCopyCtor()
    c.find('~wxGridCellAttr').ignore(False)

    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('SetEditor.editor').transfer = True
    c.find('SetRenderer.renderer').transfer = True

    #-----------------------------------------------------------------
    # The insanceCode 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.')"
    )

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

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

    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)',
        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
        """)

    #-----------------------------------------------------------------
    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)

    c.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)
Exemplo n.º 10
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_TEXT =      "string"
        GRID_VALUE_LONG =      "long"
        GRID_VALUE_CHOICEINT = "choiceint"
        GRID_VALUE_DATETIME =  "datetime"
        """)
    
    #-----------------------------------------------------------------
    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', '()', """\
        return sipBuildResult(0, "(ii)", self->GetRow(), self->GetCol());
        """, 
        pyArgsString="() -> (row,col)",
        briefDoc="Return the row and col properties as a tuple.")
    
    # 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('__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))
    

    #-----------------------------------------------------------------
    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.addAutoProperties(klass)
        
        methods = [
            ('Clone',       "virtual wxGridCellRenderer* Clone() const;"),
            ('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)
    
    for name in ITEMS:
        if 'Cell' in name and 'Renderer' in name:
            fixRendererClass(name)            
            
    module.addPyCode("PyGridCellRenderer = wx.deprecated(GridCellRenderer, 'Use GridCellRenderer instead.')")
        
        
    #-----------------------------------------------------------------
    def fixEditorClass(name):
        klass = module.find(name)
        assert isinstance(klass, etgtools.ClassDef)
        tools.addAutoProperties(klass)

        methods = [
            ('BeginEdit',  "virtual void BeginEdit(int row, int col, wxGrid* grid);"),
            ('Clone',      "virtual wxGridCellEditor* Clone() const;"),
            ('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
            
        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++ siganture
            # 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);
                if (result == Py_None) {
                    sipRes = false;
                } 
                else {
                    sipRes = true;
                    *newval = Py2wxString(result);
                }
                Py_DECREF(result);
                """  if pureVirtual else "",  # only used with the base class
            )
        
        
    c = module.find('wxGridCellEditor')
    c.addPrivateCopyCtor()
    c.find('~wxGridCellEditor').ignore(False)

    c = module.find('wxGridCellChoiceEditor')
    c.find('wxGridCellChoiceEditor').findOverload('count').ignore()
    
    for name in ITEMS:
        if 'Cell' in name and 'Editor' in name:
            fixEditorClass(name)            
    
    module.addPyCode("PyGridCellEditor = wx.deprecated(GridCellEditor, 'Use GridCellEditor instead.')")
    
    #-----------------------------------------------------------------
    c = module.find('wxGridCellAttr')
    c.addPrivateCopyCtor()
    c.find('~wxGridCellAttr').ignore(False)

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


    
    #----------------------------------------------------------------- 
    # The insanceCode 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.')")


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

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

    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

    #-----------------------------------------------------------------
    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)
        

    c.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)
Exemplo n.º 11
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('wxGBPosition')
    assert isinstance(c, etgtools.ClassDef)

    # allow a 2 element sequence to be auto converted
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxGBPosition')

    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.")
    c.addCppMethod('void',
                   'Set',
                   '(int row=0, int col=0)',
                   """\
        self->SetRow(row);
        self->SetCol(col);
        """,
                   briefDoc="Set both the row and column properties.")

    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 "wx.GBPosition"+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 (GBPosition, 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('GBPosition.__safe_for_unpickling__ = True')

    # In addition to the normal Row and Col properties let's also have lower
    # case versions.
    c.addProperty("Row GetRow SetRow")
    c.addProperty("Col GetCol SetCol")
    c.addProperty("row GetRow SetRow")
    c.addProperty("col GetCol SetCol")

    #-----------------------------------------------------------------
    c = module.find('wxGBSpan')
    assert isinstance(c, etgtools.ClassDef)

    # allow a 2 element sequence to be auto converted
    c.convertFromPyObject = tools.convertTwoIntegersTemplate('wxGBSpan')

    c.addCppMethod(
        'PyObject*',
        'Get',
        '()',
        """\
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(ii)", self->GetRowspan(), self->GetColspan());
        """,
        pyArgsString="() -> (rowspan, colspan)",
        briefDoc="Return the rowspan and colspan properties as a tuple.")
    c.addCppMethod('void',
                   'Set',
                   '(int rowspan=0, int colspan=0)',
                   """\
        self->SetRowspan(rowspan);
        self->SetColspan(colspan);
        """,
                   briefDoc="Set both the rowspan and colspan properties.")

    tools.addGetIMMethodTemplate(module, c, ['rowspan', 'colspan'])

    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)', 'return "wx.GBSpan"+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 (GBSpan, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
    c.addPyMethod(
        '__setitem__', '(self, idx, val)', """\
                  if idx == 0: self.Rowspan = val
                  elif idx == 1: self.Colspan = val
                  else: raise IndexError
                  """)
    c.addPyCode('GBSpan.__safe_for_unpickling__ = True')

    # In addition to the normal Rowspan and Colspan properties let's also have lower
    # case versions.
    c.addProperty("Rowspan GetRowspan SetRowspan")
    c.addProperty("Colspan GetColspan SetColspan")
    c.addProperty("rowspan GetRowspan SetRowspan")
    c.addProperty("colspan GetColspan SetColspan")

    #-----------------------------------------------------------------
    c = module.find('wxGBSizerItem')
    assert isinstance(c, etgtools.ClassDef)

    # transfer ownership of a sizer if the item is managing one
    c.find('wxGBSizerItem.sizer').transfer = True

    # deal with userData args in the ctors
    for m in c.find('wxGBSizerItem').all():
        if isinstance(m, etgtools.MethodDef) and m.findItem('userData'):
            m.find('userData').transfer = True
            m.find('userData').type = 'wxPyUserData*'

    # ignore some overloads that would be ambiguous from Python
    c.find('GetPos').findOverload('row').ignore()
    c.find('GetSpan').findOverload('rowspan').ignore()

    c.find('GetEndPos.row').out = True
    c.find('GetEndPos.col').out = True

    #-----------------------------------------------------------------
    c = module.find('wxGridBagSizer')
    assert isinstance(c, etgtools.ClassDef)

    tools.fixSizerClass(c)

    for func in c.findAll('Add'):
        if func.findItem('sizer'):
            func.find('sizer').transfer = True
        if func.findItem('userData'):
            func.find('userData').transfer = True
            func.find('userData').type = 'wxPyUserData*'
        if func.findItem('item'):
            func.find('item').transfer = True

    c.addCppMethod(
        'wxSizerItem*',
        'Add', '(const wxSize& size, const wxGBPosition& pos, '
        'const wxGBSpan& span = wxDefaultSpan, int flag = 0, '
        'int border = 0, wxObject* userData /Transfer/ = NULL)',
        doc="Add a spacer using a :class:`Size` object.",
        body=
        "return self->Add(size->x, size->y, *pos, *span, flag, border, userData);"
    )

    c.addPyCode(
        "GridBagSizer.CheckForIntersectionPos = wx.deprecated(GridBagSizer.CheckForIntersection, 'Use CheckForIntersection instead.')"
    )

    # TODO: In Classic we had GetChildren return a list of wxGBSizerItems (in
    # a faked out way). Figure out how to do that here too....

    #module.addItem(
    #    tools.wxListWrapperTemplate('wxGBSizerItemList', 'wxGBSizerItem', module, 'wxSizerItem'))

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