Beispiel #1
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    module.addHeaderCode('#include "wx/mediactrl.h"')

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

    c = module.find('wxMediaCtrl')
    c.addPrivateCopyCtor()

    c.find('wxMediaCtrl.id').default = '-1'
    c.find('Create.id').default = '-1'

    # the C++ class has three overloaded Load(...) methods
    # for now we ignore all than the first one for loading a filename
    for item in c.findAll("Load"):
        if not "fileName" in item.argsString:
            # ignore e.g. the Load with args '(const wxURI &uri)'
            # keep e.g. '(const wxString &fileName)'
            item.ignore()

            # Transplant the docstrings from the ignored Load methods into the
            # appropriate compatibility method
            if 'proxy' in item.argsString:
                m = c.find('LoadURIWithProxy')
            else:
                m = c.find('LoadURI')
            m.briefDoc = item.briefDoc
            m.detailedDoc = item.detailedDoc


    c = module.find('wxMediaEvent')
    tools.fixEventClass(c)

    module.addPyCode("""\
                EVT_MEDIA_LOADED = wx.PyEventBinder( wxEVT_MEDIA_LOADED )
                EVT_MEDIA_STOP = wx.PyEventBinder( wxEVT_MEDIA_STOP )
                EVT_MEDIA_FINISHED = wx.PyEventBinder( wxEVT_MEDIA_FINISHED )
                EVT_MEDIA_STATECHANGED = wx.PyEventBinder( wxEVT_MEDIA_STATECHANGED )
                EVT_MEDIA_PLAY = wx.PyEventBinder( wxEVT_MEDIA_PLAY )
                EVT_MEDIA_PAUSE = wx.PyEventBinder( wxEVT_MEDIA_PAUSE )
                """)


    # See mediactrl.h:
    module.addPyCode("""\
                MEDIABACKEND_DIRECTSHOW = "wxAMMediaBackend"
                MEDIABACKEND_MCI        = "wxMCIMediaBackend"
                MEDIABACKEND_QUICKTIME  = "wxQTMediaBackend"
                MEDIABACKEND_GSTREAMER  = "wxGStreamerMediaBackend"
                MEDIABACKEND_REALPLAYER = "wxRealPlayerMediaBackend"
                MEDIABACKEND_WMP10      = "wxWMP10MediaBackend"
                """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #2
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    
    c = module.find('wxHtmlDCRenderer')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    tools.fixHtmlSetFonts(c)
    
    c.find('Render.from').name = 'from_'
    c.find('Render.to').name = 'to_'
    
    c = module.find('wxHtmlEasyPrinting')
    c.addPrivateCopyCtor()
    
    c = module.find('wxHtmlPrintout')
    c.addPrivateCopyCtor()
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
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('wxRichTextHeaderFooterData')
    assert isinstance(c, etgtools.ClassDef)
    tools.ignoreAllOperators(c)
    
    
    c = module.find('wxRichTextPrintout')
    assert isinstance(c, etgtools.ClassDef)
    c.find('GetPageInfo.minPage').out = True
    c.find('GetPageInfo.maxPage').out = True
    c.find('GetPageInfo.selPageFrom').out = True
    c.find('GetPageInfo.selPageTo').out = True
    
    
    c = module.find('wxRichTextPrinting')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #4
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    
    module.addHeaderCode("#include <wx/textdlg.h>")
    module.find('wxGetTextFromUserPromptStr').ignore()
    module.find('wxGetPasswordFromUserPromptStr').ignore()
    
    
    c = module.find('wxTextEntryDialog')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixTopLevelWindowClass(c)
    
    # We don't wrap wxTextValidator
    for m in c.find('SetTextValidator').all():
        m.ignore()    
    
    module.addGlobalStr('wxGetTextFromUserPromptStr', c)
    module.addGlobalStr('wxGetPasswordFromUserPromptStr', c)
        
    
    c = module.find('wxPasswordEntryDialog')
    tools.fixTopLevelWindowClass(c)
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #5
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    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('wxPopupWindow')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixWindowClass(c)
    c.find('Position').isVirtual = True
    

    c = module.find('wxPopupTransientWindow')
    tools.fixWindowClass(c)
    c.find('Dismiss').isVirtual = True
    c.find('ProcessLeftDown').isVirtual = True
    c.find('OnDismiss').ignore(False)
    c.find('OnDismiss').isVirtual = True
    
            
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #6
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    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('wxCheckBox')
    assert isinstance(c, etgtools.ClassDef)
    c.find('wxCheckBox.label').default = 'wxEmptyString'
    c.find('Create.label').default = 'wxEmptyString'

    module.addGlobalStr('wxCheckBoxNameStr', c)

    # Workaround warning for the property name starting with a digit
    c.find('Get3StateValue').ignore()
    c.addAutoProperties()
    c.find('Get3StateValue').ignore(False)
    c.addProperty('ThreeStateValue Get3StateValue Set3StateValue')

    tools.fixWindowClass(c)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #7
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    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('wxMDIClientWindow')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixWindowClass(c)
    c.find('CreateClient').isVirtual = True


    c = module.find('wxMDIParentFrame')
    tools.fixTopLevelWindowClass(c)
    c.find('OnCreateClient').isVirtual = True

    m = c.find('GetClientWindow')
    assert isinstance(m, etgtools.MethodDef)
    m.type = 'wxMDIClientWindow *'
    m.setCppCode("return static_cast<wxMDIClientWindow*>(self->GetClientWindow());")
    

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

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

    module.addHeaderCode("#include <wx/datectrl.h>")

    dpc = module.find('wxDatePickerCtrl')
    assert isinstance(dpc, etgtools.ClassDef)

    # Make a copy and call it wxDatePickerCtrlGeneric so we can generate
    # wrappers for both classes
    gdpc = tools.copyClassDef(dpc, 'wxDatePickerCtrlGeneric')
    assert isinstance(gdpc, etgtools.ClassDef)
    module.insertItemAfter(dpc, gdpc)
    # and give it a new Python name to match Classic
    gdpc.pyName = 'GenericDatePickerCtrl'

    # now back to our regular tweaking
    for c in [dpc, gdpc]:
        tools.fixWindowClass(c)
        c.find('GetRange.dt1').out = True
        c.find('GetRange.dt2').out = True

    gdpc.addHeaderCode("#include <wx/generic/datectrl.h>")

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #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.
    
    c = module.find('wxHtmlHelpController')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()

    c.find('CreateHelpDialog').ignore(False)
    c.find('CreateHelpFrame').ignore(False)

    c.addItem(etgtools.WigCode("""\
        // Add implementations for the pure virtuals in the base class
        virtual bool DisplayBlock(long blockNo);
        virtual bool DisplaySection(int sectionNo);
        virtual bool LoadFile(const wxString& file = wxEmptyString);
        virtual bool Quit();
        """))
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #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.addHeaderCode('#include <wx/timectrl.h>')
    
    c = module.find('wxTimePickerCtrl')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixWindowClass(c)
    
    
    # ignore the return value and set the parameters to be outputs
    c.find('GetTime').type = 'void'
    c.find('GetTime.hour').out = True
    c.find('GetTime.min').out = True
    c.find('GetTime.sec').out = True
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #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.
    
    module.addHeaderCode("#include <wx/dcbuffer.h>")

    c = module.find('wxBufferedDC')
    c.addPrivateCopyCtor()
    for m in c.find('wxBufferedDC').all() + c.find('Init').all():
        if m.findItem('dc'):
            m.findItem('dc').keepReference = True
        if m.findItem('buffer'):
            m.findItem('buffer').keepReference = True

    
    c = module.find('wxBufferedPaintDC')
    c.addPrivateCopyCtor()
    c.find('wxBufferedPaintDC').findOverload('wxBitmap').find('buffer').keepReference = True
    
    c = module.find('wxAutoBufferedPaintDC')
    c.addPrivateCopyCtor()


    module.find('wxAutoBufferedPaintDCFactory').factory = True
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
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/ribbon/control.h>')

    # Not sure why these are showing up in this module as they are in core, so
    # let's just turn them off here...
    module.find('wxEllipsizeFlags').ignore()
    module.find('wxEllipsizeMode').ignore()


    c = module.find('wxRibbonControl')
    assert isinstance(c, etgtools.ClassDef)
    c.find('DoGetNextSmallerSize').ignore(False)
    c.find('DoGetNextLargerSize').ignore(False)
    tools.fixWindowClass(c)

    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #13
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('wxNativeFontInfo')
    assert isinstance(c, etgtools.ClassDef)
    c.addCppMethod('wxString*', '__str__', '()', """\
        return new wxString(self->ToString());
        """)

    # linker errors on all but MSW...
    c.find('GetPixelSize').ignore()
    c.find('SetPixelSize').ignore()

    c.addAutoProperties()


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #14
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('wxTimer')
    assert isinstance(c, etgtools.ClassDef)

    c = module.find('wxTimerRunner')
    c.addPrivateCopyCtor()
    
    module.addPyCode('EVT_TIMER = wx.PyEventBinder( wxEVT_TIMER )')

    module.addPyCode("""\
    class PyTimer(Timer):
        '''This timer class is passed the callable object to be called when the timer expires.'''
        def __init__(self, notify):
            Timer.__init__(self)
            self.notify = notify

        def Notify(self):
            if self.notify:
                self.notify()
    """)
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #15
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('wxFindDialogEvent')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixEventClass(c)

    module.addPyCode("""\
        EVT_FIND = wx.PyEventBinder( wxEVT_FIND, 1 )
        EVT_FIND_NEXT = wx.PyEventBinder( wxEVT_FIND_NEXT, 1 )
        EVT_FIND_REPLACE = wx.PyEventBinder( wxEVT_FIND_REPLACE, 1 )
        EVT_FIND_REPLACE_ALL = wx.PyEventBinder( wxEVT_FIND_REPLACE_ALL, 1 )
        EVT_FIND_CLOSE = wx.PyEventBinder( wxEVT_FIND_CLOSE, 1 )

        # deprecated wxEVT aliases
        wxEVT_COMMAND_FIND              = wxEVT_FIND
        wxEVT_COMMAND_FIND_NEXT         = wxEVT_FIND_NEXT
        wxEVT_COMMAND_FIND_REPLACE      = wxEVT_FIND_REPLACE
        wxEVT_COMMAND_FIND_REPLACE_ALL  = wxEVT_FIND_REPLACE_ALL
        wxEVT_COMMAND_FIND_CLOSE        = wxEVT_FIND_CLOSE
        """)

    c = module.find('wxFindReplaceDialog')
    tools.fixTopLevelWindowClass(c)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #16
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/rawbmp.h>")
    
    addPixelDataBaseClass(module)
    
    addPixelDataClass(module, 'wxNativePixelData', 'wxBitmap', bpp=24,
        doc="""\
        A class providing direct access to a :class:`wx.Bitmap`'s
        internal data without alpha channel (RGB). 
        """)
    addPixelDataClass(module, 'wxAlphaPixelData', 'wxBitmap', bpp=32,
        doc="""\
        A class providing direct access to a :class:`wx.Bitmap`'s
        internal data including the alpha channel (RGBA). 
        """)
    #addPixelDataClass(module, 'wxImagePixelData', 'wxImage', bpp=32,
    #    doc="""\
    #    ImagePixelData: A class providing direct access to a wx.Image's
    #    internal data usign the same api as the other PixelData classes. 
    #    """)
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #17
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('wxWizardPage')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixWindowClass(c, False)
    module.addPyCode("PyWizardPage = wx.deprecated(WizardPage, 'Use WizardPage instead.')")


    c = module.find('wxWizardPageSimple')
    tools.fixWindowClass(c, False)
    c.addItem(etgtools.WigCode("""\
        virtual wxWizardPage* GetNext() const;
        virtual wxWizardPage* GetPrev() const;
        """))


    c = module.find('wxWizard')
    tools.fixWindowClass(c, False)

    # ShowPage is undocumented and labeled "implementation only" but it seems
    # too useful to ignore, so add a MethodDef for it here.
    m = MethodDef(name='ShowPage', type='bool', isVirtual=True,
            briefDoc="Show the given wizard page.",
            detailedDoc=["""\
                Calls TransferDataFromWindow on the current page first, and
                returns false without changing the page if it returned false.
                Returns True/False to indicate if the page was actually
                changed."""],
            items=[ParamDef(name='page', type='wxWizardPage*'),
                   ParamDef(name='goingForward', type='bool', default='true')])
    c.addItem(m)

    # Same for IsRunning
    m = MethodDef(name='IsRunning', type='bool', isConst=True)
    c.addItem(m)


    c = module.find('wxWizardEvent')
    tools.fixEventClass(c)
    module.addPyCode("""\
        EVT_WIZARD_BEFORE_PAGE_CHANGED  = wx.PyEventBinder( wxEVT_WIZARD_BEFORE_PAGE_CHANGED, 1)
        EVT_WIZARD_PAGE_CHANGED  = wx.PyEventBinder( wxEVT_WIZARD_PAGE_CHANGED, 1)
        EVT_WIZARD_PAGE_CHANGING = wx.PyEventBinder( wxEVT_WIZARD_PAGE_CHANGING, 1)
        EVT_WIZARD_CANCEL        = wx.PyEventBinder( wxEVT_WIZARD_CANCEL, 1)
        EVT_WIZARD_HELP          = wx.PyEventBinder( wxEVT_WIZARD_HELP, 1)
        EVT_WIZARD_FINISHED      = wx.PyEventBinder( wxEVT_WIZARD_FINISHED, 1)
        EVT_WIZARD_PAGE_SHOWN    = wx.PyEventBinder( wxEVT_WIZARD_PAGE_SHOWN, 1)
        """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #18
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('wxNotificationMessage')
    assert isinstance(c, etgtools.ClassDef)

    # take care of some methods only available on MSW
    c.find('UseTaskBarIcon').setCppCode("""\
        #ifdef __WXMSW__
            return wxNotificationMessage::UseTaskBarIcon(icon);
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif
        """)

    c.find('MSWUseToasts').setCppCode("""\
        #ifdef __WXMSW__
            return wxNotificationMessage::MSWUseToasts(*shortcutPath, *appId);
        #else
            wxPyRaiseNotImplemented();
            return false;
        #endif
        """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #19
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('wxAuiMDIParentFrame')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixTopLevelWindowClass(c)
    c.find('SetMenuBar.menuBar').transfer = True
    c.find('SetArtProvider.provider').transfer = True


    c = module.find('wxAuiMDIChildFrame')
    tools.fixTopLevelWindowClass(c)
    tools.fixSetStatusWidths(c.find('SetStatusWidths'))
    c.find('SetMenuBar.menuBar').transfer = True
    c.find('Show').isVirtual = True

    c = module.find('wxAuiMDIClientWindow')
    tools.fixWindowClass(c)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #20
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('wxMessageDialog')
    assert isinstance(c, etgtools.ClassDef)

    module.addGlobalStr('wxMessageBoxCaptionStr', c)

    # Several of the wxMessageDIalog methods take a
    # wxMessageDialog::ButtonLabel parameter, which enables either a string or
    # a Stock ID to be passed. To facilitate this same ability for Python the
    # SIP types are changed to a custom type which is a MappedType which
    # handles converting from the two types for us. See msgdlg_btnlabel.sip
    c.find('ButtonLabel').ignore()
    for item in c.allItems():
        if isinstance(item, ParamDef) and item.type == 'const ButtonLabel &':
            item.type = 'const wxMessageDialogButtonLabel &'


    tools.fixTopLevelWindowClass(c)



    # Make a copy of wxMessageDialog so we can generate code for
    # wxGenericMessageDialog too.
    gmd = copy.deepcopy(c)
    assert isinstance(gmd, etgtools.ClassDef)
    gmd.name = 'wxGenericMessageDialog'
    gmd.find('wxMessageDialog').name = 'wxGenericMessageDialog'  # the ctor

    m = gmd.addItem(etgtools.MethodDef(
        protection='protected', type='void', name='AddMessageDialogCheckBox',
        briefDoc="Can be overridden to provide more contents for the dialog",
        className=gmd.name))
    m.addItem(etgtools.ParamDef(type='wxSizer*', name='sizer'))

    m = gmd.addItem(etgtools.MethodDef(
        protection='protected', type='void', name='AddMessageDialogDetails',
        briefDoc="Can be overridden to provide more contents for the dialog",
        className=gmd.name))
    m.addItem(etgtools.ParamDef(type='wxSizer*', name='sizer'))

    module.addItem(gmd)


    module.find('wxMessageBox').releaseGIL()

    c = module.find('wxMessageBox')
    c.mustHaveApp()


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #21
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('wxAppTraits')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True


    # TODO: Enable these as etg scripts for their return types are added
    for name in [ 'CreateFontMapper',
                  'CreateMessageOutput',
                  'CreateRenderer',
                  ]:
        c.find(name).ignore()

    for name in [ 'CreateConfig',
                  'CreateEventLoop',
                  'CreateLogTarget',
                  #'GetStandardPaths',
                  ]:
        c.find(name).factory = True

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #22
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/dateevt.h>")

    c = module.find('wxDateEvent')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixEventClass(c)

    c.addPyCode("""\
        EVT_DATE_CHANGED = wx.PyEventBinder( wxEVT_DATE_CHANGED, 1 )
        EVT_TIME_CHANGED = wx.PyEventBinder( wxEVT_TIME_CHANGED, 1 )
        """)

    c.addPyCode("""\
        DateEvent.PyGetDate = wx.deprecated(DateEvent.GetDate, 'Use GetDate instead.')
        DateEvent.PySetDate = wx.deprecated(DateEvent.SetDate, 'Use SetDate instead.')
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #23
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/laywin.h>')

    c = module.find('wxSashLayoutWindow')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixWindowClass(c)


    c = module.find('wxQueryLayoutInfoEvent')
    tools.fixEventClass(c)


    c = module.find('wxCalculateLayoutEvent')
    tools.fixEventClass(c)

    module.addPyCode("""\
        EVT_QUERY_LAYOUT_INFO = wx.PyEventBinder( wxEVT_QUERY_LAYOUT_INFO )
        EVT_CALCULATE_LAYOUT = wx.PyEventBinder( wxEVT_CALCULATE_LAYOUT )
        """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #24
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/unichar.h>')

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

    m = c.find('wxUniChar').findOverload('long int')
    m.find('c').type = 'long'

    m = c.find('wxUniChar').findOverload('unsigned long int')
    m.find('c').type = 'unsigned long'

    for m in c.find('wxUniChar').all():
        p = m.find('c')
        if 'long' not in p.type:
            m.ignore()


    tools.ignoreAllOperators(c)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #25
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING, 
                                check4unittest=False  # wxEventLoop is well tested in 
                                                      # myYield used by other tests...
                                )
    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('wxEventLoopBase')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True

    c.find('Yield').releaseGIL()
    c.find('YieldFor').releaseGIL()
    c.find('OnExit').ignore(False)
    
    
    c = module.find('wxEventLoopActivator')
    c.addPrivateAssignOp()
    c.addPrivateCopyCtor()
       
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


        
    c = module.find('wxGUIEventLoop')
    c.addPrivateCopyCtor()
    
    # Add declaration of the base class pure virtuals so sip knows they have
    # implementations here
    c.addItem(etgtools.WigCode("""\
        public:
        virtual int Run();
        virtual void Exit(int rc = 0);
        virtual bool Pending() const;
        virtual bool Dispatch();
        virtual int DispatchTimeout(unsigned long timeout);
        virtual void WakeUp();

        virtual bool ProcessIdle();        
        """))
    
    module.addPyCode("""\
        @wx.deprecatedMsg('Use GUIEventLoop instead.')
        class EventLoop(GUIEventLoop):
            '''Class using the old name for compatibility.'''
            def __init__(self):
                GUIEventLoop.__init__(self)
        """)
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #26
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    module.check4unittest = False

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    
    module.addHeaderCode('#include <wxpy_api.h>')
    module.addImport('_core')
    module.addPyCode("import wx", order=10)
    module.addInclude(INCLUDES)
       
    module.addCppCode("""\
        #include <wx/html/htmlwin.h>
        #include <wx/html/htmprint.h>
        #include <wx/html/helpctrl.h>
        #include <wx/html/helpwnd.h>
        #include <wx/html/helpfrm.h>
        #include <wx/html/helpdlg.h>
        """)
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #27
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING,
                                check4unittest = False)
    etgtools.parseDoxyXML(module, ITEMS)

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

    module.addHeaderCode('#include <wxPython/wxpy_api.h>')
    module.addImport('_core')
    module.addPyCode("import wx", order=10)
    module.addImport('_xml')
    module.addImport('_html')
    module.addImport('_adv')

    module.addInclude(INCLUDES)

    # Redo the initialization of wxModules in the case where this extension
    # module is not imported until *after* the wx.App has been created.
    module.addInitializerCode("""\
        wxPyReinitializeModules();
        """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #28
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('wxPlatformInfo')
    assert isinstance(c, etgtools.ClassDef)

    # to avoid conflicts with wxPython's wx.PlatformInfo
    c.renameClass('PlatformInformation')

    c.find('GetEndianness').findOverload('end').ignore()
    c.find('GetArchName').findOverload('arch').ignore()
    c.find('GetOperatingSystemId').findOverload('name').ignore()
    c.find('GetPortId').findOverload('portname').ignore()
    c.find('GetEndiannessName').findOverload('end').ignore()
    c.find('GetOperatingSystemIdName').findOverload('os').ignore()
    c.find('GetOperatingSystemFamilyName').findOverload('os').ignore()
    c.find('GetPortIdName').findOverload('port').ignore()
    c.find('GetPortIdShortName').findOverload('port').ignore()


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #29
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.find('wxPG_LABEL').ignore()
    module.find('wxPG_LABEL_STRING').ignore()
    module.find('wxPG_NULL_BITMAP').ignore()
    module.find('wxPG_COLOUR_BLACK').ignore()
    module.find('wxPG_COLOUR').ignore()
    module.find('wxPG_DEFAULT_IMAGE_SIZE').ignore()
    module.find('wxPGSortCallback').ignore()

    module.addPyCode(
        code="""\
        PG_LABEL = "@!"
        PG_LABEL_STRING = PG_LABEL
        PG_NULL_BITMAP = wx.NullBitmap
        PG_COLOUR_BLACK = wx.BLACK
        PG_DEFAULT_IMAGE_SIZE = wx.Size(-1, -1)
        """,
        order=15)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #30
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.addItem(
        tools.wxArrayWrapperTemplate('wxHtmlBookRecArray', 'wxHtmlBookRecord', module))

    module.addItem(
        tools.wxArrayWrapperTemplate('wxHtmlHelpDataItems', 'wxHtmlHelpDataItem', module))


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



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

    # Compatibility alias
    module.addPyCode("""\
        ListItemAttr = wx.deprecated(ItemAttr, 'Use ItemAttr instead')
        """)

    #-------------------------------------------------------
    c = module.find('wxListItem')
    assert isinstance(c, etgtools.ClassDef)
    c.find('SetData').findOverload('void *').ignore()
    c.find('GetData').type = 'long'

    #-------------------------------------------------------
    c = module.find('wxListCtrl')
    tools.fixWindowClass(c)

    module.addGlobalStr('wxListCtrlNameStr', before=c)

    # Unignore some protected virtual methods that we want to allow to be
    # overridden in derived classes
    for name in [
            'OnGetItemAttr',
            #'OnGetItemColumnAttr',  # MSW only?
            'OnGetItemColumnImage',
            'OnGetItemImage',
            'OnGetItemText',
            'OnGetItemIsChecked',
    ]:
        c.find(name).ignore(False)
        c.find(name).isVirtual = True

    tools.addEnableSystemTheme(c, 'wx.ListCtrl')

    # Tweaks to allow passing and using a Python callable object for the sort
    # compare function. First provide a sort callback function that can call the
    # Python function.
    c.addCppCode("""\
        static int wxCALLBACK wxPyListCtrl_SortItems(wxIntPtr item1, wxIntPtr item2, wxIntPtr funcPtr)
        {
            int retval = 0;
            PyObject* func = (PyObject*)funcPtr;
            wxPyThreadBlocker blocker;

        #if SIZEOF_LONG >= SIZEOF_VOID_P
            PyObject* args = Py_BuildValue("(ll)", item1, item2);
        #else
            PyObject* args = Py_BuildValue("(LL)", item1, item2);
        #endif

            PyObject* result = PyEval_CallObject(func, args);
            Py_DECREF(args);
            if (result) {
                retval = wxPyInt_AsLong(result);
                Py_DECREF(result);
            }
            return retval;
        }
        """)

    # Next, provide an alternate implementation of SortItems that will use that callback.
    sim = c.find('SortItems')
    assert isinstance(sim, etgtools.MethodDef)
    sim.find('fnSortCallBack').type = 'PyObject*'
    sim.find('data').ignore(
    )  # we will be using it to pass the python callback function
    sim.argsString = sim.argsString.replace('wxListCtrlCompare', 'PyObject*')
    sim.setCppCode("""\
        if (!PyCallable_Check(fnSortCallBack))
            return false;
        return self->SortItems((wxListCtrlCompare)wxPyListCtrl_SortItems,
                               (wxIntPtr)fnSortCallBack);
    """)

    # SetItemData takes a long, so lets return that type from GetItemData too,
    # instead of a wxUIntPtr.
    c.find('GetItemData').type = 'long'
    c.find('SetItemPtrData').ignore()

    # Change the semantics of GetColumn to return the item as the return
    # value instead of through a parameter.
    # bool GetColumn(int col, wxListItem& item) const;
    c.find('GetColumn').ignore()
    c.addCppMethod(
        'wxListItem*',
        'GetColumn',
        '(int col)',
        doc=
        'Gets information about this column. See SetItem() for more information.',
        factory=True,
        body="""\
        wxListItem item;
        item.SetMask( wxLIST_MASK_STATE |
                      wxLIST_MASK_TEXT  |
                      wxLIST_MASK_IMAGE |
                      wxLIST_MASK_DATA  |
                      wxLIST_SET_ITEM   |
                      wxLIST_MASK_WIDTH |
                      wxLIST_MASK_FORMAT
                      );
        if (self->GetColumn(col, item))
            return new wxListItem(item);
        else
            return NULL;
        """)

    # Do the same for GetItem
    # bool GetItem(wxListItem& info) const;
    c.find('GetItem').ignore()
    c.addCppMethod(
        'wxListItem*',
        'GetItem',
        '(int itemIdx, int col=0)',
        doc=
        'Gets information about the item. See SetItem() for more information.',
        factory=True,
        body="""\
        wxListItem* info = new wxListItem;
        info->m_itemId = itemIdx;
        info->m_col = col;
        info->m_mask = 0xFFFF;
        info->m_stateMask = 0xFFFF;
        self->GetItem(*info);
        return info;
        """)

    # bool GetItemPosition(long item, wxPoint& pos) const;
    c.find('GetItemPosition').ignore()
    c.addCppMethod(
        'wxPoint*',
        'GetItemPosition',
        '(long item)',
        doc='Returns the position of the item, in icon or small icon view.',
        factory=True,
        body="""\
        wxPoint* pos = new wxPoint;
        self->GetItemPosition(item, *pos);
        return pos;
        """)

    # bool GetItemRect(long item, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const;
    c.find('GetItemRect').ignore()
    c.addCppMethod('wxRect*',
                   'GetItemRect',
                   '(long item, int code = wxLIST_RECT_BOUNDS)',
                   doc="""\
        Returns the rectangle representing the item's size and position, in physical coordinates.
        code is one of wx.LIST_RECT_BOUNDS, wx.LIST_RECT_ICON, wx.LIST_RECT_LABEL.""",
                   factory=True,
                   body="""\
        wxRect* rect = new wxRect;
        self->GetItemRect(item, *rect, code);
        return rect;
        """)

    c.find('EditLabel.textControlClass').ignore()
    c.find('EndEditLabel').ignore()
    c.find('AssignImageList.imageList').transfer = True
    c.find('HitTest.flags').out = True
    c.find('HitTest.ptrSubItem').ignore()

    c.addCppMethod(
        'PyObject*',
        'HitTestSubItem',
        '(const wxPoint& point)',
        pyArgsString="HitTestSubItem(point) -> (item, flags, subitem)",
        doc=
        "Determines which item (if any) is at the specified point, giving details in flags.",
        body="""\
            long item, subitem;
            int flags;
            item = self->HitTest(*point, flags, &subitem);
            wxPyThreadBlocker blocker;
            PyObject* rv = PyTuple_New(3);
            PyTuple_SetItem(rv, 0, wxPyInt_FromLong(item));
            PyTuple_SetItem(rv, 1, wxPyInt_FromLong(flags));
            PyTuple_SetItem(rv, 2, wxPyInt_FromLong(subitem));
            return rv;
            """)

    # Some deprecated aliases for Classic renames
    c.addPyCode(
        'ListCtrl.FindItemData = wx.deprecated(ListCtrl.FindItem, "Use FindItem instead.")'
    )
    c.addPyCode(
        'ListCtrl.FindItemAtPos = wx.deprecated(ListCtrl.FindItem, "Use FindItem instead.")'
    )
    c.addPyCode(
        'ListCtrl.InsertStringItem = wx.deprecated(ListCtrl.InsertItem, "Use InsertItem instead.")'
    )
    c.addPyCode(
        'ListCtrl.InsertImageItem = wx.deprecated(ListCtrl.InsertItem, "Use InsertItem instead.")'
    )
    c.addPyCode(
        'ListCtrl.InsertImageStringItem = wx.deprecated(ListCtrl.InsertItem, "Use InsertItem instead.")'
    )
    c.addPyCode(
        'ListCtrl.SetStringItem = wx.deprecated(ListCtrl.SetItem, "Use SetItem instead.")'
    )

    # Provide a way to determine if column ordering is possible
    c.addCppMethod(
        'bool', 'HasColumnOrderSupport', '()', """\
        #ifdef wxHAS_LISTCTRL_COLUMN_ORDER
            return true;
        #else
            return false;
        #endif
        """)

    # And provide implementation of those methods that will work whether or
    # not wx has column ordering support
    c.find('GetColumnOrder').setCppCode("""\
        #ifdef wxHAS_LISTCTRL_COLUMN_ORDER
            return self->GetColumnOrder(col);
        #else
            wxPyRaiseNotImplemented();
            return 0;
        #endif
        """)

    c.find('GetColumnIndexFromOrder').setCppCode("""\
        #ifdef wxHAS_LISTCTRL_COLUMN_ORDER
            return self->GetColumnIndexFromOrder(pos);
        #else
            wxPyRaiseNotImplemented();
            return 0;
        #endif
        """)

    c.find('GetColumnsOrder').type = 'wxArrayInt*'
    c.find('GetColumnsOrder').factory = True
    c.find('GetColumnsOrder').setCppCode("""\
        #ifdef wxHAS_LISTCTRL_COLUMN_ORDER
            return new wxArrayInt(self->GetColumnsOrder());
        #else
            wxPyRaiseNotImplemented();
            return new wxArrayInt();
        #endif
        """)

    c.find('SetColumnsOrder').setCppCode("""\
        #ifdef wxHAS_LISTCTRL_COLUMN_ORDER
            return self->SetColumnsOrder(*orders);
        #else
            wxPyRaiseNotImplemented();
            return false;
        #endif
        """)

    # Add some Python helper methods
    c.addPyMethod('Select',
                  '(self, idx, on=1)',
                  doc='Selects/deselects an item.',
                  body="""\
        if on: state = wx.LIST_STATE_SELECTED
        else: state = 0
        self.SetItemState(idx, state, wx.LIST_STATE_SELECTED)
        """)

    c.addPyMethod('Focus',
                  '(self, idx)',
                  doc='Focus and show the given item.',
                  body="""\
        self.SetItemState(idx, wx.LIST_STATE_FOCUSED, wx.LIST_STATE_FOCUSED)
        self.EnsureVisible(idx)
        """)

    c.addPyMethod(
        'GetFocusedItem',
        '(self)',
        doc='Gets the currently focused item or -1 if none is focused.',
        body=
        'return self.GetNextItem(-1, wx.LIST_NEXT_ALL, wx.LIST_STATE_FOCUSED)')

    c.addPyMethod(
        'GetFirstSelected',
        '(self, *args)',
        doc='Returns the first selected item, or -1 when none is selected.',
        body="return self.GetNextSelected(-1)")

    c.addPyMethod(
        'GetNextSelected',
        '(self, item)',
        doc=
        'Returns subsequent selected items, or -1 when no more are selected.',
        body=
        "return self.GetNextItem(item, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)"
    )

    c.addPyMethod(
        'IsSelected',
        '(self, idx)',
        doc='Returns ``True`` if the item is selected.',
        body=
        "return (self.GetItemState(idx, wx.LIST_STATE_SELECTED) & wx.LIST_STATE_SELECTED) != 0"
    )

    c.addPyMethod('SetColumnImage',
                  '(self, col, image)',
                  body="""\
        item = self.GetColumn(col)
        # preserve all other attributes too
        item.SetMask( wx.LIST_MASK_STATE |
                      wx.LIST_MASK_TEXT  |
                      wx.LIST_MASK_IMAGE |
                      wx.LIST_MASK_DATA  |
                      wx.LIST_SET_ITEM   |
                      wx.LIST_MASK_WIDTH |
                      wx.LIST_MASK_FORMAT )
        item.SetImage(image)
        self.SetColumn(col, item)
        """)

    c.addPyMethod('ClearColumnImage',
                  '(self, col)',
                  body="self.SetColumnImage(col, -1)")

    c.addPyMethod('Append',
                  '(self, entry)',
                  doc='''\
        Append an item to the list control.  The `entry` parameter should be a
        sequence with an item for each column''',
                  body="""\
        if len(entry):
            from six import text_type
            pos = self.InsertItem(self.GetItemCount(), text_type(entry[0]))
            for i in range(1, len(entry)):
                self.SetItem(pos, i, text_type(entry[i]))
            return pos
        """)

    c.addCppMethod('wxWindow*',
                   'GetMainWindow',
                   '()',
                   body="""\
        #if defined(__WXMSW__) || defined(__WXMAC__)
            return self;
        #else
            return (wxWindow*)self->m_mainWin;
        #endif
        """)

    #-------------------------------------------------------
    c = module.find('wxListView')
    tools.fixWindowClass(c)

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

    module.addPyCode("""\
        EVT_LIST_BEGIN_DRAG        = PyEventBinder(wxEVT_LIST_BEGIN_DRAG       , 1)
        EVT_LIST_BEGIN_RDRAG       = PyEventBinder(wxEVT_LIST_BEGIN_RDRAG      , 1)
        EVT_LIST_BEGIN_LABEL_EDIT  = PyEventBinder(wxEVT_LIST_BEGIN_LABEL_EDIT , 1)
        EVT_LIST_END_LABEL_EDIT    = PyEventBinder(wxEVT_LIST_END_LABEL_EDIT   , 1)
        EVT_LIST_DELETE_ITEM       = PyEventBinder(wxEVT_LIST_DELETE_ITEM      , 1)
        EVT_LIST_DELETE_ALL_ITEMS  = PyEventBinder(wxEVT_LIST_DELETE_ALL_ITEMS , 1)
        EVT_LIST_ITEM_SELECTED     = PyEventBinder(wxEVT_LIST_ITEM_SELECTED    , 1)
        EVT_LIST_ITEM_DESELECTED   = PyEventBinder(wxEVT_LIST_ITEM_DESELECTED  , 1)
        EVT_LIST_KEY_DOWN          = PyEventBinder(wxEVT_LIST_KEY_DOWN         , 1)
        EVT_LIST_INSERT_ITEM       = PyEventBinder(wxEVT_LIST_INSERT_ITEM      , 1)
        EVT_LIST_COL_CLICK         = PyEventBinder(wxEVT_LIST_COL_CLICK        , 1)
        EVT_LIST_ITEM_RIGHT_CLICK  = PyEventBinder(wxEVT_LIST_ITEM_RIGHT_CLICK , 1)
        EVT_LIST_ITEM_MIDDLE_CLICK = PyEventBinder(wxEVT_LIST_ITEM_MIDDLE_CLICK, 1)
        EVT_LIST_ITEM_ACTIVATED    = PyEventBinder(wxEVT_LIST_ITEM_ACTIVATED   , 1)
        EVT_LIST_CACHE_HINT        = PyEventBinder(wxEVT_LIST_CACHE_HINT       , 1)
        EVT_LIST_COL_RIGHT_CLICK   = PyEventBinder(wxEVT_LIST_COL_RIGHT_CLICK  , 1)
        EVT_LIST_COL_BEGIN_DRAG    = PyEventBinder(wxEVT_LIST_COL_BEGIN_DRAG   , 1)
        EVT_LIST_COL_DRAGGING      = PyEventBinder(wxEVT_LIST_COL_DRAGGING     , 1)
        EVT_LIST_COL_END_DRAG      = PyEventBinder(wxEVT_LIST_COL_END_DRAG     , 1)
        EVT_LIST_ITEM_FOCUSED      = PyEventBinder(wxEVT_LIST_ITEM_FOCUSED     , 1)
        EVT_LIST_ITEM_CHECKED      = PyEventBinder(wxEVT_LIST_ITEM_CHECKED     , 1)
        EVT_LIST_ITEM_UNCHECKED    = PyEventBinder(wxEVT_LIST_ITEM_UNCHECKED   , 1)

        # deprecated wxEVT aliases
        wxEVT_COMMAND_LIST_BEGIN_DRAG         = wxEVT_LIST_BEGIN_DRAG
        wxEVT_COMMAND_LIST_BEGIN_RDRAG        = wxEVT_LIST_BEGIN_RDRAG
        wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT   = wxEVT_LIST_BEGIN_LABEL_EDIT
        wxEVT_COMMAND_LIST_END_LABEL_EDIT     = wxEVT_LIST_END_LABEL_EDIT
        wxEVT_COMMAND_LIST_DELETE_ITEM        = wxEVT_LIST_DELETE_ITEM
        wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS   = wxEVT_LIST_DELETE_ALL_ITEMS
        wxEVT_COMMAND_LIST_ITEM_SELECTED      = wxEVT_LIST_ITEM_SELECTED
        wxEVT_COMMAND_LIST_ITEM_DESELECTED    = wxEVT_LIST_ITEM_DESELECTED
        wxEVT_COMMAND_LIST_KEY_DOWN           = wxEVT_LIST_KEY_DOWN
        wxEVT_COMMAND_LIST_INSERT_ITEM        = wxEVT_LIST_INSERT_ITEM
        wxEVT_COMMAND_LIST_COL_CLICK          = wxEVT_LIST_COL_CLICK
        wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK   = wxEVT_LIST_ITEM_RIGHT_CLICK
        wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK  = wxEVT_LIST_ITEM_MIDDLE_CLICK
        wxEVT_COMMAND_LIST_ITEM_ACTIVATED     = wxEVT_LIST_ITEM_ACTIVATED
        wxEVT_COMMAND_LIST_CACHE_HINT         = wxEVT_LIST_CACHE_HINT
        wxEVT_COMMAND_LIST_COL_RIGHT_CLICK    = wxEVT_LIST_COL_RIGHT_CLICK
        wxEVT_COMMAND_LIST_COL_BEGIN_DRAG     = wxEVT_LIST_COL_BEGIN_DRAG
        wxEVT_COMMAND_LIST_COL_DRAGGING       = wxEVT_LIST_COL_DRAGGING
        wxEVT_COMMAND_LIST_COL_END_DRAG       = wxEVT_LIST_COL_END_DRAG
        wxEVT_COMMAND_LIST_ITEM_FOCUSED       = wxEVT_LIST_ITEM_FOCUSED
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #32
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('wxRegion')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.mustHaveApp()

    # Replace one of the constructors with one having a more python-friendly API
    c.find('wxRegion').findOverload('points').ignore()
    c.addCppCode(
        tools.ObjArrayHelperTemplate(
            'wxPoint', 'sipType_wxPoint',
            "Expected a sequence of length-2 sequences or wx.Point objects."))
    c.addCppCtor_sip(
        '(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)',
        doc="""\
        Constructs a region corresponding to the polygon made from the points
        in the provided sequence.""",
        body="""\
        size_t count;
        wxPoint* array = wxPoint_array_helper(points, &count);
        if ( array != NULL ) {
            sipCpp = new wxRegion(count, array, fillStyle);
            delete [] array;
        }
        if (PyErr_Occurred()) sipIsErr = 1;
        """)

    c.find('GetBox').findOverload('wxCoord').ignore()

    # Iterator stuff
    c.addPyMethod(
        '__iter__', '(self)', 'return PyRegionIterator(self)', """\
                  Returns a rectangle interator conforming to the Python iterator
                  protocol.""")
    c.addPyCode("""\
        class PyRegionIterator(object):
            "A Python iterator for wx.Region objects"
            def __init__(self, region):
                self._region = region
                self._iterator = wx.RegionIterator(region)
            def next(self):
                if not self._iterator:
                    raise StopIteration
                rect = self._iterator.GetRect()
                if self._iterator.HaveRects():
                    self._iterator.Next()
                return rect
            __next__ = next  # for Python 3
        """)

    c = module.find('wxRegionIterator')
    c.mustHaveApp()
    c.find('operator++').ignore()

    c.find('operator bool').ignore()
    c.addCppMethod(
        'int', '__nonzero__', '()', 'return (int)self->operator bool();',
        'Returns true while there are still rectangles available in the iteration.'
    )
    c.addCppMethod(
        'int', '__bool__', '()', 'return (int)self->operator bool();',
        'Returns true while there are still rectangles available in the iteration.'
    )

    c.addCppMethod('void', 'Next', '()', 'self->operator++();',
                   'Move the iterator to the next rectangle in the region.')

    # This is defined in the docs, but not in any of the real headers!
    module.find('wxNullRegion').ignore()

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

    scrolled = module.find('wxScrolled')
    assert isinstance(scrolled, etgtools.ClassDef)

    scrolled.find('GetViewStart').findOverload('()').ignore()
    scrolled.find('GetViewStart.x').out = True
    scrolled.find('GetViewStart.y').out = True

    m = scrolled.find('CalcScrolledPosition').findOverload('xx')
    m.find('xx').out = True
    m.find('yy').out = True

    m = scrolled.find('CalcUnscrolledPosition').findOverload('xx')
    m.find('xx').out = True
    m.find('yy').out = True

    scrolled.find('GetScrollPixelsPerUnit.xUnit').out = True
    scrolled.find('GetScrollPixelsPerUnit.yUnit').out = True

    # Just ignore this one and let the already tweaked versions be inherited from wx.Window.
    scrolled.find('GetVirtualSize').ignore()

    scrolled.addPrivateCopyCtor()
    scrolled.addPrivateAssignOp()
    tools.fixWindowClass(scrolled)

    # Add back some virtuals that were removed in fixWindowClass
    scrolled.find('OnDraw').isVirtual = True
    scrolled.find('GetSizeAvailableForScrollTarget').isVirtual = True
    scrolled.find('GetSizeAvailableForScrollTarget').ignore(False)
    scrolled.find('SendAutoScrollEvents').isVirtual = True

    # The wxScrolledCanvas typedef will be output normally and SIP will treat
    # it like a class that has a wxScrolled mix-in as one of the base classes.
    # Let's add some more info to them for the doc generators.
    docBase = """\
    The :ref:`{name}` class is a combination of the :ref:`{base}` and
    :ref:`Scrolled` classes, and manages scrolling for its client area,
    transforming the coordinates according to the scrollbar positions,
    and setting the scroll positions, thumb sizes and ranges according to
    the area in view.
    """
    item = module.find('wxScrolledCanvas')
    item.docAsClass = True
    item.bases = ['wxWindow', 'wxScrolled']
    item.briefDoc = docBase.format(name='ScrolledCanvas', base='Window')
    item.detailedDoc[0] = "This scrolled window is not intended to have children "\
                          "so it doesn't have special handling for TAB traversal "\
                          "or focus management."
    # move it ahead of wxScrolledWindow
    sw = module.find('wxScrolledWindow')
    module.items.remove(item)
    module.insertItemBefore(sw, item)

    # wxScrolledWindow is documented as a typedef but it's actually a class.
    # So we need to implement it that way here too in order to keep
    # static_casts and such happy.
    assert isinstance(sw, TypedefDef)

    # First, let's add a typedef to serve as the base class of
    # wxScrolledWindow, since SIP doesn't yet understand using template
    # instantiations as base classes.  Setting noTypeName tells SIP to not use
    # the typedef name in the actual generated code, but the typedef's type
    # instead.
    td = TypedefDef(name='_ScrolledWindowBase',
                    type='wxScrolled<wxPanel>',
                    noTypeName=True,
                    piIgnored=True)
    module.insertItemAfter(sw, td)
    module.addHeaderCode('typedef wxScrolled<wxPanel> _ScrolledWindowBase;')
    sw.ignore()

    # Now implement the class definition
    klass = ClassDef(
        name='wxScrolledWindow',
        bases=['_ScrolledWindowBase'],
        piBases=['Window', 'Scrolled'],
        briefDoc=sw.briefDoc,
        detailedDoc=sw.detailedDoc,
        items=[
            MethodDef(name='wxScrolledWindow',
                      isCtor=True,
                      items=[],
                      overloads=[
                          MethodDef(name='wxScrolledWindow',
                                    isCtor=True,
                                    items=[
                                        ParamDef(name='parent',
                                                 type='wxWindow*'),
                                        ParamDef(name='id',
                                                 type='wxWindowID',
                                                 default='wxID_ANY'),
                                        ParamDef(name='pos',
                                                 type='const wxPoint&',
                                                 default='wxDefaultPosition'),
                                        ParamDef(name='size',
                                                 type='const wxSize&',
                                                 default='wxDefaultSize'),
                                        ParamDef(
                                            name='style',
                                            type='long',
                                            default='wxScrolledWindowStyle'),
                                        ParamDef(name='name',
                                                 type='const wxString&',
                                                 default='wxPanelNameStr'),
                                    ]),
                      ]),
            MethodDef(name='SetFocusIgnoringChildren',
                      type='void',
                      items=[],
                      briefDoc="""\
                    In contrast to SetFocus() this will set the focus to the panel even if
                    there are child windows in the panel. This is only rarely needed."""
                      ),
        ],
    )
    tools.fixWindowClass(klass)
    module.insertItemAfter(td, klass)

    module.addPyCode(
        "PyScrolledWindow = wx.deprecated(ScrolledWindow, 'Use ScrolledWindow instead.')"
    )

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

    #-----------------------------------------------------------------
    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.GridSelectCells = Grid.SelectCells
        Grid.GridSelectRows = Grid.SelectRows
        Grid.GridSelectColumns = Grid.SelectColumns
        Grid.GridSelectRowsOrColumns = 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)
Beispiel #35
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('wxFileSystem')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    c.find('AddHandler.handler').transfer = True
    c.find('RemoveHandler').transferBack = True

    c = module.find('wxFileSystemHandler')
    c.find('GetAnchor').ignore(False)
    c.find('GetLeftLocation').ignore(False)
    c.find('GetProtocol').ignore(False)
    c.find('GetRightLocation').ignore(False)

    def _fixHandlerClass(klass):
        klass.addItem(
            etgtools.WigCode("""\
            virtual bool CanOpen(const wxString& location);
            virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
            virtual wxString FindFirst(const wxString& spec, int flags = 0);
            virtual wxString FindNext();
            """))

    c = module.find('wxArchiveFSHandler')
    _fixHandlerClass(c)
    c.addPrivateCopyCtor()
    module.addPyCode(
        'ZipFSHandler = wx.deprecated(ArchiveFSHandler, "Use ArchiveFSHandler instead.")'
    )

    c = module.find('wxFSFile')
    c.addPrivateCopyCtor()
    c.find('wxFSFile.stream').transfer = True
    c.find('DetachStream').transferBack = True

    c = module.find('wxFilterFSHandler')
    _fixHandlerClass(c)
    c.addPrivateCopyCtor()

    c = module.find('wxInternetFSHandler')
    _fixHandlerClass(c)
    c.addPrivateCopyCtor()

    c = module.find('wxMemoryFSHandler')
    _fixHandlerClass(c)
    c.addPrivateCopyCtor()

    # Make some more python-friendly versions of the AddFile methods accepting raw data
    c.find('AddFile').findOverload('binarydata').ignore()
    c.find('AddFileWithMimeType').findOverload('binarydata').ignore()

    c.addCppMethod(
        'void',
        'AddFile',
        '(const wxString& filename, wxPyBuffer* binarydata)',
        isStatic=True,
        doc="Add a file from raw data in a python buffer compatible object.",
        body="""\
            wxMemoryFSHandler::AddFile(*filename, binarydata->m_ptr, binarydata->m_len);
            """)

    c.addCppMethod(
        'void',
        'AddFileWithMimeType',
        '(const wxString& filename, wxPyBuffer* binarydata, const wxString& mimetype)',
        isStatic=True,
        doc="Add a file from raw data in a python buffer compatible object.",
        body="""\
            wxMemoryFSHandler::AddFileWithMimeType(
                    *filename, binarydata->m_ptr, binarydata->m_len, *mimetype);
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #36
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('wxImage')
    assert isinstance(c, etgtools.ClassDef)
    c.find('wxImage').findOverload('(const char *const *xpmData)').ignore()

    c.find('GetHandlers').ignore()  # TODO

    c.find('wxImage').findOverload('wxBitmap').mustHaveApp()

    # Ignore the ctors taking raw data buffers, so we can add in our own
    # versions that are a little smarter (accept any buffer object, check
    # the data length, etc.)
    c.find('wxImage').findOverload(
        'int width, int height, unsigned char *data, bool static_data').ignore(
        )
    c.find('wxImage').findOverload(
        'const wxSize &sz, unsigned char *data, bool static_data').ignore()
    c.find('wxImage').findOverload(
        'int width, int height, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()
    c.find('wxImage').findOverload(
        'const wxSize &sz, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()

    c.addCppCtor_sip('(int width, int height, wxPyBuffer* data)',
                     doc="Creates an image from RGB data in memory.",
                     body="""\
            if (! data->checkSize(width*height*3))
                return NULL;
            void* copy = data->copy();
            if (! copy)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(width, height, (byte*)copy);
            """)

    c.addCppCtor_sip(
        '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc="Creates an image from RGB data in memory, plus an alpha channel",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return NULL;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(width, height, (byte*)dcopy, (byte*)acopy, false);
            """)

    c.addCppCtor_sip('(const wxSize& size, wxPyBuffer* data)',
                     doc="Creates an image from RGB data in memory.",
                     body="""\
            if (! data->checkSize(size->x*size->y*3))
                return NULL;
            void* copy = data->copy();
            if (! copy)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(size->x, size->y, (byte*)copy, false);
            """)

    c.addCppCtor_sip(
        '(const wxSize& size, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc="Creates an image from RGB data in memory, plus an alpha channel",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(size->x*size->y*3) || !alpha->checkSize(size->x*size->y))
                return NULL;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(size->x, size->y, (byte*)dcopy, (byte*)acopy, false);
            """)

    # Do the same for the Create method overloads that need to deal with data buffers
    c.find('Create').findOverload(
        'int width, int height, unsigned char *data, bool static_data').ignore(
        )
    c.find('Create').findOverload(
        'const wxSize &sz, unsigned char *data, bool static_data').ignore()
    c.find('Create').findOverload(
        'int width, int height, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()
    c.find('Create').findOverload(
        'const wxSize &sz, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()

    c.addCppMethod(
        'bool',
        'Create',
        '(int width, int height, wxPyBuffer* data)',
        doc="Create a new image initialized with the given RGB data.",
        body="""\
            if (! data->checkSize(width*height*3))
                return false;
            void* copy = data->copy();
            if (! copy)
                return false;
            return self->Create(width, height, (byte*)copy);
            """)

    c.addCppMethod(
        'bool',
        'Create',
        '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc=
        "Create a new image initialized with the given RGB data and Alpha data.",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return false;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return false;
            return self->Create(width, height, (byte*)dcopy, (byte*)acopy);
            """)

    c.addCppMethod(
        'bool',
        'Create',
        '(const wxSize& size, wxPyBuffer* data)',
        doc="Create a new image initialized with the given RGB data.",
        body="""\
            if (! data->checkSize(size->x*size->y*3))
                return false;
            void* copy = data->copy();
            if (! copy)
                return false;
            return self->Create(size->x, size->y, (byte*)copy);
            """)

    c.addCppMethod(
        'bool',
        'Create',
        '(const wxSize& size, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc=
        "Create a new image initialized with the given RGB data and Alpha data.",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(size->x*size->y*3) || !alpha->checkSize(size->x*size->y))
                return false;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return false;
            return self->Create(size->x, size->y, (byte*)dcopy, (byte*)acopy);
            """)

    # And also do similar for SetData and SetAlpha
    m = c.find('SetData').findOverload('unsigned char *data')
    bd, dd = m.briefDoc, m.detailedDoc
    m.ignore()
    c.addCppMethod('void',
                   'SetData',
                   '(wxPyBuffer* data)',
                   briefDoc=bd,
                   detailedDoc=dd,
                   body="""\
        if (!data->checkSize(self->GetWidth()*self->GetHeight()*3))
            return;
        void* copy = data->copy();
        if (!copy)
            return;
        self->SetData((byte*)copy, false);
        """)

    c.find('SetData').findOverload('int new_width').ignore()
    c.addCppMethod('void',
                   'SetData',
                   '(wxPyBuffer* data, int new_width, int new_height)',
                   body="""\
        if (!data->checkSize(new_width*new_height*3))
            return;
        void* copy = data->copy();
        if (!copy)
            return;
        self->SetData((byte*)copy, new_width, new_height, false);
        """)

    m = c.find('SetAlpha').findOverload('unsigned char *alpha')
    bd, dd = m.briefDoc, m.detailedDoc
    m.ignore()
    c.addCppMethod('void',
                   'SetAlpha',
                   '(wxPyBuffer* alpha)',
                   briefDoc=bd,
                   detailedDoc=dd,
                   body="""\
        if (!alpha->checkSize(self->GetWidth()*self->GetHeight()))
            return;
        void* copy = alpha->copy();
        if (!copy)
            return;
        self->SetAlpha((byte*)copy, false);
        """)

    # GetData() and GetAlpha() return a copy of the image data/alpha bytes as
    # a bytearray object.
    c.find('GetData').ignore()
    c.addCppMethod('PyObject*',
                   'GetData',
                   '()',
                   doc="Returns a copy of the RGB bytes of the image.",
                   body="""\
            byte* data = self->GetData();
            Py_ssize_t len = self->GetWidth() * self->GetHeight() * 3;
            PyObject* rv = NULL;
            wxPyBLOCK_THREADS( rv = PyByteArray_FromStringAndSize((const char*)data, len));
            return rv;
            """)

    c.find('GetAlpha').findOverload('()').ignore()
    c.addCppMethod('PyObject*',
                   'GetAlpha',
                   '()',
                   doc="Returns a copy of the Alpha bytes of the image.",
                   body="""\
            byte* data = self->GetAlpha();
            Py_ssize_t len = self->GetWidth() * self->GetHeight();
            PyObject* rv = NULL;
            wxPyBLOCK_THREADS( rv = PyByteArray_FromStringAndSize((const char*)data, len));
            return rv;
            """)

    # GetDataBuffer, GetAlphaBuffer provide direct access to the image's
    # internal buffers as a writable buffer object.  We'll use memoryview
    # objects.
    c.addCppMethod('PyObject*',
                   'GetDataBuffer',
                   '()',
                   doc="""\
        Returns a writable Python buffer object that is pointing at the RGB
        image data buffer inside the :class:`Image`. You need to ensure that you do
        not use this buffer object after the image has been destroyed.""",
                   body="""\
            byte* data = self->GetData();
            Py_ssize_t len = self->GetWidth() * self->GetHeight() * 3;
            PyObject* rv;
            wxPyThreadBlocker blocker;
            rv = wxPyMakeBuffer(data, len);
            return rv;
            """)

    c.addCppMethod('PyObject*',
                   'GetAlphaBuffer',
                   '()',
                   doc="""\
        Returns a writable Python buffer object that is pointing at the Alpha
        data buffer inside the :class:`Image`. You need to ensure that you do
        not use this buffer object after the image has been destroyed.""",
                   body="""\
            byte* data = self->GetAlpha();
            Py_ssize_t len = self->GetWidth() * self->GetHeight();
            PyObject* rv;
            wxPyThreadBlocker blocker;
            rv = wxPyMakeBuffer(data, len);
            return rv;
            """)

    # SetDataBuffer, SetAlphaBuffer tell the image to use some other memory
    # buffer pointed to by a Python buffer object.
    c.addCppMethod('void',
                   'SetDataBuffer',
                   '(wxPyBuffer* data)',
                   doc="""\
        Sets the internal image data pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the
        :class:`Image` does.""",
                   body="""\
            if (!data->checkSize(self->GetWidth() * self->GetHeight() * 3))
                return;
            // True means don't free() the pointer
            self->SetData((byte*)data->m_ptr, true);
            """)
    c.addCppMethod('void',
                   'SetDataBuffer',
                   '(wxPyBuffer* data, int new_width, int new_height)',
                   doc="""\
        Sets the internal image data pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the
        :class:`Image` does.""",
                   body="""\
            if (!data->checkSize(new_width * new_height * 3))
                return;
            // True means don't free() the pointer
            self->SetData((byte*)data->m_ptr, new_width, new_height, true);
            """)

    c.addCppMethod('void',
                   'SetAlphaBuffer',
                   '(wxPyBuffer* alpha)',
                   doc="""\
        Sets the internal image alpha pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the
        :class:`Image` does.""",
                   body="""\
            if (!alpha->checkSize(self->GetWidth() * self->GetHeight()))
                return;
            // True means don't free() the pointer
            self->SetAlpha((byte*)alpha->m_ptr, true);
            """)

    def setParamsPyInt(name):
        """Set the pyInt flag on 'unsigned char' params"""
        method = c.find(name)
        for m in [method] + method.overloads:
            for p in m.items:
                if p.type == 'unsigned char':
                    p.pyInt = True

    setParamsPyInt('Replace')
    setParamsPyInt('ConvertAlphaToMask')
    setParamsPyInt('ConvertToMono')
    setParamsPyInt('ConvertToDisabled')
    setParamsPyInt('IsTransparent')
    setParamsPyInt('SetAlpha')
    setParamsPyInt('SetMaskColour')
    setParamsPyInt('SetMaskFromImage')
    setParamsPyInt('SetRGB')

    c.find('FindFirstUnusedColour').type = 'void'
    c.find('FindFirstUnusedColour.r').pyInt = True
    c.find('FindFirstUnusedColour.g').pyInt = True
    c.find('FindFirstUnusedColour.b').pyInt = True
    c.find('FindFirstUnusedColour.startR').pyInt = True
    c.find('FindFirstUnusedColour.startG').pyInt = True
    c.find('FindFirstUnusedColour.startB').pyInt = True
    c.find('FindFirstUnusedColour.r').out = True
    c.find('FindFirstUnusedColour.g').out = True
    c.find('FindFirstUnusedColour.b').out = True

    c.find('GetAlpha').findOverload('int x, int y').pyInt = True
    c.find('GetRed').pyInt = True
    c.find('GetGreen').pyInt = True
    c.find('GetBlue').pyInt = True
    c.find('GetMaskRed').pyInt = True
    c.find('GetMaskGreen').pyInt = True
    c.find('GetMaskBlue').pyInt = True

    c.find('GetOrFindMaskColour').type = 'void'
    c.find('GetOrFindMaskColour.r').pyInt = True
    c.find('GetOrFindMaskColour.g').pyInt = True
    c.find('GetOrFindMaskColour.b').pyInt = True
    c.find('GetOrFindMaskColour.r').out = True
    c.find('GetOrFindMaskColour.g').out = True
    c.find('GetOrFindMaskColour.b').out = True

    c.find('RGBValue.red').pyInt = True
    c.find('RGBValue.green').pyInt = True
    c.find('RGBValue.blue').pyInt = True
    c.find('RGBValue.RGBValue.r').pyInt = True
    c.find('RGBValue.RGBValue.g').pyInt = True
    c.find('RGBValue.RGBValue.b').pyInt = True

    c.addCppMethod('int', '__nonzero__', '()', 'return self->IsOk();')

    c.addPyMethod('ConvertToBitmap',
                  '(self, depth=-1)',
                  doc="""\
        ConvertToBitmap(depth=-1) -> Bitmap\n
        Convert the image to a :class:`wx.Bitmap`.""",
                  body="""\
        bmp = wx.Bitmap(self, depth)
        return bmp
        """)

    c.addPyMethod('ConvertToMonoBitmap',
                  '(self, red, green, blue)',
                  doc="""\
        ConvertToMonoBitmap(red, green, blue) -> Bitmap\n
        Creates a monochrome version of the image and returns it as a :class:`wx.Bitmap`.""",
                  body="""\
        mono = self.ConvertToMono( red, green, blue )
        bmp = wx.Bitmap( mono, 1 )
        return bmp
        """)

    c.addCppMethod(
        'wxImage*',
        'AdjustChannels',
        '(double factor_red, double factor_green, double factor_blue, double factor_alpha=1.0)',
        doc="""\
        This function muliplies all 4 channels (red, green, blue, alpha) with
        a factor (around 1.0). Useful for gamma correction, colour correction
        and to add a certain amount of transparency to a image (fade in fade
        out effects). If factor_alpha is given but the original image has no
        alpha channel then a alpha channel will be added.
        """,
        body="""\
        wxCHECK_MSG( self->Ok(), NULL, wxT("invalid image") );

        wxImage* dest = new wxImage( self->GetWidth(), self->GetHeight(), false );
        wxCHECK_MSG( dest && dest->IsOk(), NULL, wxT("unable to create image") );

        unsigned rgblen =   3 * self->GetWidth() * self->GetHeight();
        unsigned alphalen = self->GetWidth() * self->GetHeight();
        byte* src_data =  self->GetData();
        byte* src_alpha = self->GetAlpha();
        byte* dst_data =  dest->GetData();
        byte* dst_alpha = NULL;

        // adjust rgb
        if ( factor_red == 1.0 && factor_green == 1.0 && factor_blue == 1.0)
        {
            // nothing to do for RGB
            memcpy(dst_data, src_data, rgblen);
        }
        else
        {
            // rgb pixel for pixel
            for ( unsigned i = 0; i < rgblen; i= i + 3 )
            {
                dst_data[i] =     (byte) wxMin( 255, (int) (factor_red * src_data[i]) );
                dst_data[i + 1] = (byte) wxMin( 255, (int) (factor_green * src_data[i + 1]) );
                dst_data[i + 2] = (byte) wxMin( 255, (int) (factor_blue * src_data[i + 2]) );
            }
        }

        // adjust the mask colour
        if ( self->HasMask() )
        {
            dest->SetMaskColour((byte) wxMin( 255, (int) (factor_red * self->GetMaskRed() ) ),
                                (byte) wxMin( 255, (int) (factor_green * self->GetMaskGreen() ) ),
                                (byte) wxMin( 255, (int) (factor_blue * self->GetMaskBlue() ) ) );
        }

        // adjust the alpha channel
        if ( src_alpha )
        {
            // source image already has alpha information
            dest->SetAlpha(); // create an empty alpha channel (not initialized)
            dst_alpha = dest->GetAlpha();

            wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );

            if ( factor_alpha == 1.0)
            {
                // no need to adjust
                memcpy(dst_alpha, src_alpha, alphalen);
            }
            else
            {
                // alpha value for alpha value
                for ( unsigned i = 0; i < alphalen; ++i )
                {
                    dst_alpha[i] = (byte) wxMin( 255, (int) (factor_alpha * src_alpha[i]) );
                }
            }
        }
        else if ( factor_alpha != 1.0 )
        {
            // no alpha yet but we want to adjust -> create
            dest->SetAlpha(); // create an empty alpha channel (not initialized)
            dst_alpha = dest->GetAlpha();

            wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );

            for ( unsigned i = 0; i < alphalen; ++i )
            {
                dst_alpha[i] = (byte) wxMin( 255, (int) (factor_alpha * 255) );
            }
        }

        // do we have an alpha channel and a mask in the new image?
        if ( dst_alpha && dest->HasMask() )
        {
            // make the mask transparent honoring the alpha channel
            const byte mr = dest->GetMaskRed();
            const byte mg = dest->GetMaskGreen();
            const byte mb = dest->GetMaskBlue();

            for ( unsigned i = 0; i < alphalen; ++i )
            {
                int n = i * 3;
                dst_alpha[i] = ( dst_data[n] == mr && dst_data[n + 1] == mg && dst_data[n + 2] == mb )
                    ? wxIMAGE_ALPHA_TRANSPARENT
                    : dst_alpha[i];
            }

            // remove the mask now
            dest->SetMask(false);
        }

        return dest;""",
        factory=True)

    c.addProperty('Width GetWidth')
    c.addProperty('Height GetHeight')
    c.addProperty('MaskBlue GetMaskBlue')
    c.addProperty('MaskGreen GetMaskGreen')
    c.addProperty('MaskRed GetMaskRed')
    c.addProperty('Type GetType SetType')

    # For compatibility:
    module.addPyFunction(
        'EmptyImage',
        '(width=0, height=0, clear=True)',
        deprecated="Use :class:`Image` instead.",
        doc=
        'A compatibility wrapper for the wx.Image(width, height) constructor',
        body='return Image(width, height, clear)')

    module.addPyFunction(
        'ImageFromBitmap',
        '(bitmap)',
        deprecated="Use bitmap.ConvertToImage instead.",
        doc='Create a :class:`Image` from a :class:`wx.Bitmap`',
        body='return bitmap.ConvertToImage()')

    module.addPyFunction('ImageFromStream',
                         '(stream, type=BITMAP_TYPE_ANY, index=-1)',
                         deprecated="Use :class:`Image` instead.",
                         doc='Load an image from a stream (file-like object)',
                         body='return wx.Image(stream, type, index)')

    module.addPyFunction(
        'ImageFromData',
        '(width, height, data)',
        deprecated="Use :class:`Image` instead.",
        doc='Compatibility wrapper for creating an image from RGB data',
        body='return Image(width, height, data)')

    module.addPyFunction(
        'ImageFromDataWithAlpha',
        '(width, height, data, alpha)',
        deprecated="Use :class:`Image` instead.",
        doc=
        'Compatibility wrapper for creating an image from RGB and Alpha data',
        body='return Image(width, height, data, alpha)')

    module.addPyFunction('ImageFromBuffer',
                         '(width, height, dataBuffer, alphaBuffer=None)',
                         doc="""\
            Creates a :class:`Image` from the data in `dataBuffer`.  The `dataBuffer`
            parameter must be a Python object that implements the buffer interface,
            such as a string, array, etc.  The `dataBuffer` object is expected to
            contain a series of RGB bytes and be width*height*3 bytes long.  A buffer
            object can optionally be supplied for the image's alpha channel data, and
            it is expected to be width*height bytes long.

            The :class:`Image` will be created with its data and alpha pointers initialized
            to the memory address pointed to by the buffer objects, thus saving the
            time needed to copy the image data from the buffer object to the :class:`Image`.
            While this has advantages, it also has the shoot-yourself-in-the-foot
            risks associated with sharing a C pointer between two objects.

            To help alleviate the risk a reference to the data and alpha buffer
            objects are kept with the :class:`Image`, so that they won't get deleted until
            after the wx.Image is deleted.  However please be aware that it is not
            guaranteed that an object won't move its memory buffer to a new location
            when it needs to resize its contents.  If that happens then the :class:`Image`
            will end up referring to an invalid memory location and could cause the
            application to crash.  Therefore care should be taken to not manipulate
            the objects used for the data and alpha buffers in a way that would cause
            them to change size.
            """,
                         body="""\
            img = Image(width, height)
            img.SetDataBuffer(dataBuffer)
            if alphaBuffer:
                img.SetAlphaBuffer(alphaBuffer)
            img._buffer = dataBuffer
            img._alpha = alphaBuffer
            return img
            """)

    #-------------------------------------------------------
    c = module.find('wxImageHistogram')
    c.bases = []  # wxImageHistogramBase doesn't actually exist
    setParamsPyInt('MakeKey')
    c.find('FindFirstUnusedColour').type = 'void'
    c.find('FindFirstUnusedColour.r').pyInt = True
    c.find('FindFirstUnusedColour.g').pyInt = True
    c.find('FindFirstUnusedColour.b').pyInt = True
    c.find('FindFirstUnusedColour.startR').pyInt = True
    c.find('FindFirstUnusedColour.startG').pyInt = True
    c.find('FindFirstUnusedColour.startB').pyInt = True
    c.find('FindFirstUnusedColour.r').out = True
    c.find('FindFirstUnusedColour.g').out = True
    c.find('FindFirstUnusedColour.b').out = True

    #-------------------------------------------------------
    c = module.find('wxImageHandler')
    c.addPrivateCopyCtor()
    c.find('GetLibraryVersionInfo').ignore()

    c.find('DoGetImageCount').ignore(False)
    c.find('DoCanRead').ignore(False)

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

    module.find('wxIMAGE_ALPHA_TRANSPARENT').pyInt = True
    module.find('wxIMAGE_ALPHA_OPAQUE').pyInt = True
    module.find('wxIMAGE_ALPHA_THRESHOLD').pyInt = True

    # These are defines for string objects, not integers, so we can't
    # generate code for them the same way as integer values. Since they are
    # #defines we can't just tell SIP that they are global wxString objects
    # because it will then end up taking the address of temporary values when
    # it makes the getters for them. So instead we'll just make some python
    # code to insert into the .py module and hope that the interface file
    # always has the correct values of these options.
    pycode = ""
    for item in module:
        if 'IMAGE_OPTION' in item.name and isinstance(item,
                                                      etgtools.DefineDef):
            item.ignore()
            name = tools.removeWxPrefix(item.name)
            value = item.value
            for txt in ['wxString(', 'wxT(', ')']:
                value = value.replace(txt, '')

            pycode += '%s = %s\n' % (name, value)
    module.addPyCode(pycode)

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

    # These are duplicates, ignore the ones in this module
    module.find('wxPG_PROPERTYVALUES_FLAGS').ignore()
    module.find('wxPG_LABEL').ignore()
    module.find('wxPG_LABEL_STRING').ignore()
    module.find('wxPG_COLOUR_BLACK').ignore()
    module.find('wxPG_COLOUR').ignore()
    module.find('wxPG_DEFAULT_IMAGE_SIZE').ignore()

    #----------------------------------------------------------
    c = module.find('wxPGPropArgCls')
    assert isinstance(c, etgtools.ClassDef)
    c.find('wxPGPropArgCls').findOverload('wxString &').ignore()
    c.find('wxPGPropArgCls').findOverload('char *').ignore()
    c.find('wxPGPropArgCls').findOverload('wchar_t *').ignore()
    c.find('wxPGPropArgCls').findOverload('int').ignore()
    c.find('wxPGPropArgCls').findOverload('deallocPtr').ignore()

    # Make a string ctor that uses the wxPython-specific version of
    # the C++ class' ctor
    newCtor = c.addCppCtor('(const wxString& str)',
                           doc="Creates a PGPropArgCls from a string.",
                           body="""\
            wxString* name = new wxString(*str);
            return new wxPGPropArgCls(name, true);
        """)

    # Make it be the first overload instead of the last
    ctor = c.find('wxPGPropArgCls')
    overloads = list(ctor.overloads)
    del overloads[overloads.index(newCtor)]
    overloads.insert(0, newCtor)
    ctor.overloads = overloads

    c.find('GetPtr').overloads[0].ignore()

    c.convertFromPyObject = """\
        // Code to test a PyObject for compatibility with wxPGPropArgCls
        if (!sipIsErr) {
            if (sipCanConvertToType(sipPy, sipType_wxPGPropArgCls, SIP_NO_CONVERTORS))
                return TRUE;
            if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy))
                return TRUE;
            if (sipPy == Py_None)
                return TRUE;
            if (sipCanConvertToType(sipPy, sipType_wxPGProperty, SIP_NO_CONVERTORS))
                return TRUE;
            return FALSE;
        }

        // Code to convert a compatible PyObject to a wxPGPropArgCls
        if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy)) {
            wxString* name = new wxString(Py2wxString(sipPy));
            *sipCppPtr = new wxPGPropArgCls(name, true);
            return sipGetState(sipTransferObj);
        }
        else if (sipCanConvertToType(sipPy, sipType_wxPGProperty, SIP_NO_CONVERTORS)) {
            int state = 0;
            wxPGProperty* prop = reinterpret_cast<wxPGProperty*>(
                sipConvertToType(sipPy, sipType_wxPGProperty, sipTransferObj, SIP_NO_CONVERTORS, &state, sipIsErr));
            *sipCppPtr = new wxPGPropArgCls(prop);
            sipReleaseType(prop, sipType_wxPGProperty, state);
            return sipGetState(sipTransferObj);
        }
        else if (sipPy == Py_None) {
            *sipCppPtr = new wxPGPropArgCls(static_cast< wxPGProperty * >(NULL));
            return sipGetState(sipTransferObj);
        }
        else {
            // It's already a wxPGPropArgCls, just fetch the pointer and return
            *sipCppPtr = reinterpret_cast<wxPGPropArgCls*>(sipConvertToType(
                sipPy, sipType_wxPGPropArgCls, sipTransferObj,
                SIP_NO_CONVERTORS, 0, sipIsErr));
            return 0; // not a new instance
        }
        """

    #----------------------------------------------------------
    c = module.find('wxPropertyGridInterface')
    c.abstract = True
    for m in c.findAll('GetIterator'):
        if m.type == 'wxPropertyGridConstIterator':
            m.ignore()

    tools.ignoreConstOverloads(c)

    spv = c.find('SetPropertyValue')
    spv.findOverload('int value').ignore()
    spv.findOverload('wxLongLong value').ignore()
    spv.findOverload('wxLongLong_t value').ignore()
    spv.findOverload('wxULongLong value').ignore()
    spv.findOverload('wxULongLong_t value').ignore()
    spv.findOverload('wxObject *value').ignore()
    spv.findOverload('wchar_t *value').ignore()
    spv.findOverload('char *value').ignore()

    # Reorder SetPropertyValue overloads so the one taking a long int is not
    # first. Mark others that could be auto-converted from int as
    # "constrained" so they will only be used for that specific type. This
    # should result in SetPropertyValue(id, double) only used for floats and
    # not ints, or other things that can convert to int.
    spv.findOverload('bool value').find('value').constrained = True
    spv.findOverload('double value').find('value').constrained = True
    spv_long = spv.findOverload('long value')
    spv_long.ignore()
    spv.reorderOverloads()  # Ensures an ignored item is not first,
    spv_long.ignore(False)  # and then we can unignore it.

    c.find('Append.property').transfer = True
    c.find('AppendIn.newProperty').transfer = True
    for m in c.find('Insert').all():
        m.find('newProperty').transfer = True

    # Fix some syntax that sip doesn't like
    p = c.find('GetPropertiesWithFlag.iterFlags')
    if p.default.startswith('('):
        p.default = p.default[1:-1]

    # Tons of Python method implementations ported from Classic...

    module.addPyCode("""\
        _type2property = None
        _vt2getter = None
        """)

    c.addPyMethod('MapType',
                  '(self, class_, factory)',
                  doc="""\
            Registers Python type/class to property mapping.

            :param `factory`: Property builder function/class.
            """,
                  body="""\
            global _type2property
            if _type2property is None:
                raise AssertionError("call only after a propertygrid or "
                                     "manager instance constructed")
            _type2property[class_] = factory
            """)

    c.addPyMethod('DoDefaultTypeMappings',
                  '(self)',
                  doc="Add built-in properties to the map.",
                  body="""\
            import sys
            global _type2property
            if _type2property is not None:
                return
            _type2property = dict()

            _type2property[str] = StringProperty
            if sys.version_info.major < 2:
                _type2property[unicode] = StringProperty
            _type2property[int] = IntProperty
            _type2property[float] = FloatProperty
            _type2property[bool] = BoolProperty
            _type2property[list] = ArrayStringProperty
            _type2property[tuple] = ArrayStringProperty
            _type2property[wx.Font] = FontProperty
            _type2property[wx.Colour] = ColourProperty
            #_type2property[wx.Size] = SizeProperty
            #_type2property[wx.Point] = PointProperty
            #_type2property[wx.FontData] = FontDataProperty
            """)

    # TODO: is this still needed?
    c.addPyMethod('DoDefaultValueTypeMappings',
                  '(self)',
                  doc="Map pg value type ids to getter methods.",
                  body="""\
            global _vt2getter
            if _vt2getter is not None:
                return
            _vt2getter = dict()
        """)

    c.find('GetPropertyValues').ignore()
    c.addPyMethod('GetPropertyValues',
                  '(self, dict_=None, as_strings=False, inc_attributes=False)',
                  doc="""\
            Returns all property values in the grid.\n
            :param `dict_`: A to fill with the property values. If not given,
                then a new one is created. The dict_ can be an object as well,
                in which case it's __dict__ is used.
            :param `as_strings`: if True, then string representations of values
                are fetched instead of native types. Useful for config and such.
            :param `inc_attributes`: if True, then property attributes are added
                in the form of "@<propname>@<attr>".
            :returns: A dictionary with values. It is always a dictionary,
                so if dict_ was and object with __dict__ attribute, then that
                attribute is returned.
            """,
                  body="""\
            if dict_ is None:
                dict_ = {}
            elif hasattr(dict_,'__dict__'):
                dict_ = dict_.__dict__

            getter = self.GetPropertyValue if not as_strings else self.GetPropertyValueAsString

            it = self.GetVIterator(PG_ITERATE_PROPERTIES)
            while not it.AtEnd():
                p = it.GetProperty()
                name = p.GetName()
                dict_[name] = getter(p)

                if inc_attributes:
                    attrs = p.GetAttributes()
                    if attrs and len(attrs):
                        dict_['@%s@attr'%name] = attrs

                it.Next()

            return dict_
            """)

    for m in c.find('SetPropertyValues').all():
        m.ignore()
    c.addPyMethod('SetPropertyValues',
                  '(self, dict_, autofill=False)',
                  doc="""\
            Sets property values from a dictionary.\n
            :param `dict_`: the source of the property values to set, which can be
                either a dictionary or an object with a __dict__ attribute.
            :param `autofill`: If true, keys with not relevant properties are
                auto-created. For more info, see :method:`AutoFill`.

            :note:
              * Keys starting with underscore are ignored.
              * Attributes can be set with entries named like "@<propname>@<attr>".
            """,
                  body="""\
            if dict_ is None:
                dict_ = {}
            elif hasattr(dict_,'__dict__'):
                dict_ = dict_.__dict__
            attr_dicts = []

            def set_sub_obj(k0, dict_):
                for k,v in dict_.items():
                    if k[0] != '_':
                        if k.endswith('@attr'):
                            attr_dicts.append((k[1:-5],v))
                        else:
                            try:
                                self.SetPropertyValue(k,v)
                            except:
                                try:
                                    if autofill:
                                        self._AutoFillOne(k0,k,v)
                                        continue
                                except:
                                    if isinstance(v,dict):
                                        set_sub_obj(k,v)
                                    elif hasattr(v,'__dict__'):
                                        set_sub_obj(k,v.__dict__)

                for k,v in attr_dicts:
                    p = self.GetPropertyByName(k)
                    if not p:
                        raise AssertionError("No such property: '%s'"%k)
                    for an,av in v.items():
                        p.SetAttribute(an, av)


            cur_page = False
            is_manager = isinstance(self, PropertyGridManager)

            try:
                set_sub_obj(self.GetGrid().GetRoot(), dict_)
            except:
                import traceback
                traceback.print_exc()

            self.Refresh()
            """)

    # TODO: should these be marked as deprecated?
    module.addPyCode("""\
        PropertyGridInterface.GetValues = PropertyGridInterface.GetPropertyValues
        PropertyGridInterface.SetValues = PropertyGridInterface.SetPropertyValues
        """)

    c.addPyMethod('_AutoFillMany',
                  '(self,cat,dict_)',
                  body="""\
            for k,v in dict_.items():
                self._AutoFillOne(cat,k,v)
            """)

    c.addPyMethod('_AutoFillOne',
                  '(self,cat,k,v)',
                  body="""\
            global _type2property
            factory = _type2property.get(v.__class__,None)
            if factory:
                self.AppendIn(cat, factory(k,k,v))
            elif hasattr(v,'__dict__'):
                cat2 = self.AppendIn(cat, PropertyCategory(k))
                self._AutoFillMany(cat2, v.__dict__)
            elif isinstance(v, dict):
                cat2 = self.AppendIn(cat, PropertyCategory(k))
                self._AutoFillMany(cat2, v)
            elif not k.startswith('_'):
                raise AssertionError("member '%s' is of unregistered type/"
                                     "class '%s'"%(k,v.__class__))
            """)

    c.addPyMethod('AutoFill',
                  '(self, obj, parent=None)',
                  doc="""\
            "Clears properties and re-fills to match members and values of
            the given object or dictionary obj.
            """,
                  body="""\
            self.edited_objects[parent] = obj

            cur_page = False
            is_manager = isinstance(self, PropertyGridManager)

            if not parent:
                if is_manager:
                    page = self.GetCurrentPage()
                    page.Clear()
                    parent = page.GetRoot()
                else:
                    self.Clear()
                    parent = self.GetGrid().GetRoot()
            else:
                it = self.GetIterator(PG_ITERATE_PROPERTIES, parent)
                it.Next()  # Skip the parent
                while not it.AtEnd():
                    p = it.GetProperty()
                    if not p.IsSomeParent(parent):
                        break

                    self.DeleteProperty(p)

                    name = p.GetName()
                    it.Next()

            if not is_manager or page == self.GetCurrentPage():
                self.Freeze()
                cur_page = True

            try:
                self._AutoFillMany(parent,obj.__dict__)
            except:
                import traceback
                traceback.print_exc()

            if cur_page:
                self.Thaw()
            """)

    c.addPyMethod('RegisterEditor',
                  '(self, editor, editorName=None)',
                  doc="Register a new editor, either an instance or a class.",
                  body="""\
            if not isinstance(editor, PGEditor):
                editor = editor()
            if not editorName:
                editorName = editor.__class__.__name__
            try:
                self._editor_instances.append(editor)
            except:
                self._editor_instances = [editor]
            return PropertyGrid.DoRegisterEditorClass(editor, editorName)
            """)

    c.find('GetPropertyClientData').ignore()
    c.addPyMethod('GetPropertyClientData',
                  '(self, p)',
                  body="""\
            if isinstance(p, str):
                p = self.GetPropertyByName(p)
            return p.GetClientData()
            """)

    c.find('SetPropertyClientData').ignore()
    c.addPyMethod('SetPropertyClientData',
                  '(self, p, data)',
                  body="""\
            if isinstance(p, str):
                p = self.GetPropertyByName(p)
            return p.SetClientData(data)
            """)

    c.addPyMethod('GetPyIterator',
                  '(self, flags=PG_ITERATE_DEFAULT, firstProperty=None)',
                  doc="""\
            Returns a pythonic property iterator for a single :ref:`PropertyGrid`
            or page in :ref:`PropertyGridManager`. Arguments are same as for
            :ref:`GetIterator`.

            The following example demonstrates iterating absolutely all items in
            a single grid::

                iterator = propGrid.GetPyIterator(wx.propgrid.PG_ITERATE_ALL)
                for prop in iterator:
                    print(prop)

            :see: `wx.propgrid.PropertyGridInterface.Properties`
                  `wx.propgrid.PropertyGridInterface.Items`
            """,
                  body="""\
            it = self.GetIterator(flags, firstProperty)
            while not it.AtEnd():
                yield it.GetProperty()
                it.Next()
            """)

    c.addPyMethod('GetPyVIterator',
                  '(self, flags=PG_ITERATE_DEFAULT)',
                  doc="""\
            Similar to :ref:`GetVIterator` but returns a pythonic iterator.
            """,
                  body="""\
            it = self.GetVIterator(flags)
            while not it.AtEnd():
                yield it.GetProperty()
                it.Next()
            """)

    c.addPyMethod('_Properties',
                  '(self)',
                  doc="""\
            This attribute is a pythonic iterator over all properties in
            this `PropertyGrid` property container. It will only skip
            categories and private child properties. Usage is simple::

                for prop in propGrid.Properties:
                    print(prop)

            :see: `wx.propgrid.PropertyGridInterface.Items`
                  `wx.propgrid.PropertyGridInterface.GetPyIterator`
            """,
                  body="""\
            it = self.GetIterator(PG_ITERATE_NORMAL)
            while not it.AtEnd():
                yield it.GetProperty()
                it.Next()
            """)
    c.addPyProperty('Properties', '_Properties')

    c.addPyMethod('_Items',
                  '(self)',
                  doc="""\
            This attribute is a pythonic iterator over all items in this
            `PropertyGrid` property container, excluding only private child
            properties. Usage is simple::

                for prop in propGrid.Items:
                    print(prop)

            :see: `wx.propgrid.PropertyGridInterface.Properties`
                  `wx.propgrid.PropertyGridInterface.GetPyVIterator`
            """,
                  body="""\
            it = self.GetVIterator(PG_ITERATE_NORMAL | PG_ITERATE_CATEGORIES)
            while not it.AtEnd():
                yield it.GetProperty()
                it.Next()
            """)
    c.addPyProperty('Items', '_Items')

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

    module.addItem(
        tools.wxArrayPtrWrapperTemplate('wxArrayPGProperty', 'wxPGProperty',
                                        module))

    # wxPGPropArg is a typedef for "const wxPGPropArgCls&" so having the
    # wrappers treat it as a normal type can be problematic. ("new cannot be
    # applied to a reference type", etc.) Let's just ignore it and replace it
    # everywhere for the real type.
    module.find('wxPGPropArg').ignore()
    for item in module.allItems():
        if hasattr(item, 'type') and item.type == 'wxPGPropArg':
            item.type = 'const wxPGPropArgCls &'

    # Switch all wxVariant types to wxPGVariant, so the propgrid-specific
    # version of the MappedType will be used for converting to/from Python
    # objects.
    for item in module.allItems():
        if hasattr(item, 'type') and 'wxVariant' in item.type:
            item.type = item.type.replace('wxVariant', 'wxPGVariant')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #38
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('wxPickerBase')
    assert isinstance(c, etgtools.ClassDef)
    c.find('CreateBase.id').default = 'wxID_ANY'
    c.find('GetTextCtrlStyle').ignore(False)
    c.find('GetPickerStyle').ignore(False)
    c.find('PostCreation').ignore(False)

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

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

    c = module.find('wxColourPickerCtrl')
    tools.fixWindowClass(c)
    module.addGlobalStr('wxColourPickerWidgetNameStr', c)
    module.addGlobalStr('wxColourPickerCtrlNameStr', c)

    c.addItem(
        etgtools.WigCode("""\
        virtual void UpdatePickerFromTextCtrl();
        virtual void UpdateTextCtrlFromPicker();
        """))

    c = module.find('wxColourPickerEvent')
    tools.fixEventClass(c)

    c.addPyCode("""\
        EVT_COLOURPICKER_CHANGED = wx.PyEventBinder( wxEVT_COLOURPICKER_CHANGED, 1 )
        
        # deprecated wxEVT alias
        wxEVT_COMMAND_COLOURPICKER_CHANGED  = wxEVT_COLOURPICKER_CHANGED
        """)

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

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

    c = module.find('wxFilePickerCtrl')
    tools.fixWindowClass(c)
    module.addGlobalStr('wxFilePickerWidgetLabel', c)
    module.addGlobalStr('wxFilePickerWidgetNameStr', c)
    module.addGlobalStr('wxFilePickerCtrlNameStr', c)
    module.addGlobalStr('wxFileSelectorPromptStr', c)
    module.addGlobalStr('wxFileSelectorDefaultWildcardStr', c)

    c.addItem(
        etgtools.WigCode("""\
        virtual void UpdatePickerFromTextCtrl();
        virtual void UpdateTextCtrlFromPicker();
        """))

    # we'll use the [G|S]etPath methods instead so we don't have to mess with wxFileName
    c.find('GetFileName').ignore()
    c.find('SetFileName').ignore()

    c = module.find('wxDirPickerCtrl')
    tools.fixWindowClass(c)
    module.addGlobalStr('wxDirPickerWidgetLabel', c)
    module.addGlobalStr('wxDirPickerWidgetNameStr', c)
    module.addGlobalStr('wxDirPickerCtrlNameStr', c)
    module.addGlobalStr('wxDirSelectorPromptStr', c)

    c.addItem(
        etgtools.WigCode("""\
        virtual void UpdatePickerFromTextCtrl();
        virtual void UpdateTextCtrlFromPicker();
        """))

    # we'll use the [G|S]etPath methods instead so we don't have to mess with wxFileName
    c.find('GetDirName').ignore()
    c.find('SetDirName').ignore()

    c = module.find('wxFileDirPickerEvent')
    tools.fixEventClass(c)

    c.addPyCode("""\
        EVT_FILEPICKER_CHANGED = wx.PyEventBinder( wxEVT_FILEPICKER_CHANGED, 1 )
        EVT_DIRPICKER_CHANGED = wx.PyEventBinder( wxEVT_DIRPICKER_CHANGED, 1 )
        
        # deprecated wxEVT aliases
        wxEVT_COMMAND_FILEPICKER_CHANGED   = wxEVT_FILEPICKER_CHANGED
        wxEVT_COMMAND_DIRPICKER_CHANGED    = wxEVT_DIRPICKER_CHANGED
        """)

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

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

    c = module.find('wxFontPickerCtrl')
    tools.fixWindowClass(c)
    module.addGlobalStr('wxFontPickerWidgetNameStr', c)
    module.addGlobalStr('wxFontPickerCtrlNameStr', c)

    c.addItem(
        etgtools.WigCode("""\
        virtual void UpdatePickerFromTextCtrl();
        virtual void UpdateTextCtrlFromPicker();
        """))

    c = module.find('wxFontPickerEvent')
    tools.fixEventClass(c)

    c.addPyCode("""\
        EVT_FONTPICKER_CHANGED = wx.PyEventBinder( wxEVT_FONTPICKER_CHANGED, 1 )
        
        # deprecated wxEVT alias
        wxEVT_COMMAND_FONTPICKER_CHANGED  = wxEVT_FONTPICKER_CHANGED
        """)

    #-----------------------------------------------------------------
    # The C++ wxColourPickerCtrl uses a wx.Button for the implementation,
    # but that looks and works very badly on Mac because the native
    # button can't change color.  So for the Mac we'll implement our own
    # picker using a wx.BitmapButton instead.
    module.addPyCode("""\
    if 'wxMac' in wx.PlatformInfo:
        class ColourPickerCtrl(PickerBase):
            '''
            This control allows the user to select a colour. The
            implementation varies by platform but is usually a button which
            brings up a `wx.ColourDialog` when clicked.


            Window Styles
            -------------

                ======================  ============================================
                wx.CLRP_DEFAULT         Default style.
                wx.CLRP_USE_TEXTCTRL    Creates a text control to the left of the
                                        picker button which is completely managed
                                        by the `wx.ColourPickerCtrl` and which can
                                        be used by the user to specify a colour.
                                        The text control is automatically synchronized
                                        with the button's value. Use functions defined in
                                        `wx.PickerBase` to modify the text control.
                wx.CLRP_SHOW_LABEL      Shows the colour in HTML form (AABBCC) as the
                                        colour button label (instead of no label at all).
                ======================  ============================================

            Events
            ------

                ========================  ==========================================
                EVT_COLOURPICKER_CHANGED  The user changed the colour selected in the
                                          control either using the button or using the
                                          text control (see wx.CLRP_USE_TEXTCTRL; note
                                          that in this case the event is fired only if
                                          the user's input is valid, i.e. recognizable).
                ========================  ==========================================
            '''

            # ColourData object to be shared by all colour pickers, so they can
            # share the custom colours
            _colourData = None

            #--------------------------------------------------
            class ColourPickerButton(BitmapButton):
                def __init__(self, parent, id=-1, colour=wx.BLACK,
                             pos=wx.DefaultPosition, size=wx.DefaultSize,
                             style = CLRP_DEFAULT_STYLE,
                             validator = wx.DefaultValidator,
                             name = "colourpickerwidget"):

                    wx.BitmapButton.__init__(self, parent, id, wx.Bitmap(1,1),
                                             pos, size, style, validator, name)
                    self.SetColour(colour)
                    self.InvalidateBestSize()
                    self.SetInitialSize(size)
                    self.Bind(wx.EVT_BUTTON, self.OnButtonClick)

                    if ColourPickerCtrl._colourData is None:
                        ColourPickerCtrl._colourData = wx.ColourData()
                        ColourPickerCtrl._colourData.SetChooseFull(True)
                        grey = 0
                        for i in range(16):
                            c = wx.Colour(grey, grey, grey)
                            ColourPickerCtrl._colourData.SetCustomColour(i, c)
                            grey += 16

                def SetColour(self, colour):
                    # force a copy, in case the _colorData is shared
                    self.colour = wx.Colour(colour)
                    bmp = self._makeBitmap()
                    self.SetBitmapLabel(bmp)

                def GetColour(self):
                    return self.colour

                def OnButtonClick(self, evt):
                    ColourPickerCtrl._colourData.SetColour(self.colour)
                    dlg = wx.ColourDialog(self, ColourPickerCtrl._colourData)
                    if dlg.ShowModal() == wx.ID_OK:
                        ColourPickerCtrl._colourData = dlg.GetColourData()
                        self.SetColour(ColourPickerCtrl._colourData.GetColour())
                        evt = wx.ColourPickerEvent(self, self.GetId(), self.GetColour())
                        self.GetEventHandler().ProcessEvent(evt)

                def _makeBitmap(self):
                    width = height = 24
                    bg = self.GetColour()
                    if self.HasFlag(CLRP_SHOW_LABEL):
                        w, h = self.GetTextExtent(bg.GetAsString(wx.C2S_HTML_SYNTAX))
                        width += w
                    bmp = wx.Bitmap(width, height)
                    dc = wx.MemoryDC(bmp)
                    dc.SetBackground(wx.Brush(self.colour))
                    dc.Clear()
                    if self.HasFlag(CLRP_SHOW_LABEL):
                        from wx.lib.colourutils import BestLabelColour
                        fg = BestLabelColour(bg)
                        dc.SetTextForeground(fg)
                        dc.DrawText(bg.GetAsString(wx.C2S_HTML_SYNTAX),
                                    (width - w)/2, (height - h)/2)
                    return bmp

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

            def __init__(self, parent, id=-1, colour=wx.BLACK,
                         pos=wx.DefaultPosition, size=wx.DefaultSize,
                         style = CLRP_DEFAULT_STYLE,
                         validator = wx.DefaultValidator,
                         name = "colourpicker"):
                if type(colour) != wx.Colour:
                    colour = wx.Colour(colour)
                wx.PickerBase.__init__(self)
                self.CreateBase(parent, id, colour.GetAsString(),
                                pos, size, style, validator, name)
                widget = ColourPickerCtrl.ColourPickerButton(
                    self, -1, colour, style=self.GetPickerStyle(style))
                self.SetPickerCtrl(widget)
                widget.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnColourChange)
                self.PostCreation()


            def GetColour(self):
                '''Set the displayed colour.'''
                return self.GetPickerCtrl().GetColour()

            def SetColour(self, colour):
                '''Returns the currently selected colour.'''
                self.GetPickerCtrl().SetColour(colour)
                self.UpdateTextCtrlFromPicker()
            Colour = property(GetColour, SetColour)


            def UpdatePickerFromTextCtrl(self):
                col = wx.Colour(self.GetTextCtrl().GetValue())
                if not col.IsOk():
                    return
                if self.GetColour() != col:
                    self.GetPickerCtrl().SetColour(col)
                    evt = wx.ColourPickerEvent(self, self.GetId(), self.GetColour())
                    self.GetEventHandler().ProcessEvent(evt)

            def UpdateTextCtrlFromPicker(self):
                if not self.GetTextCtrl():
                    return
                self.GetTextCtrl().SetValue(self.GetColour().GetAsString())

            def GetPickerStyle(self, style):
                return style & CLRP_SHOW_LABEL

            def OnColourChange(self, evt):
                self.UpdateTextCtrlFromPicker()
                evt = wx.ColourPickerEvent(self, self.GetId(), self.GetColour())
                self.GetEventHandler().ProcessEvent(evt)
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #39
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('wxComboBox')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixWindowClass(c)

    tools.fixTextClipboardMethods(c)

    c.find('wxComboBox').findOverload('wxString choices').ignore()
    c.find('wxComboBox').findOverload('wxArrayString').find(
        'choices').default = 'wxArrayString()'
    c.find('wxComboBox').findOverload('wxArrayString').find(
        'value').default = 'wxEmptyString'

    c.find('Create').findOverload('wxString choices').ignore()
    c.find('Create').findOverload('wxArrayString').find(
        'choices').default = 'wxArrayString()'
    c.find('Create').findOverload('wxArrayString').find(
        'value').default = 'wxEmptyString'

    # When the from,to are set as output parameters the overloaded methods
    # will be ambiguous, so let's give this one a new name.
    m = c.find('GetSelection').renameOverload('long *from, long *to',
                                              'GetTextSelection')
    m.find('from').out = True
    m.find('to').out = True

    # For SetSelection we want to keep the existing method since it is
    # inherited from base classes and has no ambiguities, so just add a new
    # method for SetTextSelection instead of renaming.
    orig = c.find('SetSelection').findOverload('from')
    orig.find('from').name = 'from_'
    orig.find('to').name = 'to_'
    m = etgtools.CppMethodDef.FromMethod(orig)
    m.overloads = []
    m.name = 'SetTextSelection'
    m.argsString = '(long from_, long to_)'
    m.body = "self->SetSelection(from_, to_);"
    c.insertItemAfter(c.find('SetSelection'), m)

    # The docs say to not use this one.
    c.find('IsEmpty').ignore()

    c.addPyCode(
        "ComboBox.SetMark = wx.deprecated(ComboBox.SetTextSelection, 'Use SetTextSelection instead.')"
    )
    c.addPyCode(
        "ComboBox.GetMark = wx.deprecated(ComboBox.GetTextSelection, 'Use GetTextSelection instead.')"
    )

    module.addGlobalStr('wxComboBoxNameStr', c)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #40
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('wxHtmlWinTagHandler')
    assert isinstance(c, etgtools.ClassDef)

    c.addCppMethod('wxHtmlWinParser*', 'GetParser', '()',
        body="return (wxHtmlWinParser*)self->GetParser();")

    c.addPrivateCopyCtor()


    c = module.find('wxHtmlWinParser')
    c.find('GetEncodingConverter').ignore()
    c.find('GetInputEncoding').ignore()
    c.find('GetOutputEncoding').ignore()
    c.find('SetInputEncoding').ignore()

    tools.fixHtmlSetFonts(c)

    c.find('AddModule').ignore()

    c.addItem(etgtools.WigCode("""\
        virtual wxObject* GetProduct();
        """))


    module.addCppCode("""\
        class wxPyHtmlTagsModule : public wxHtmlTagsModule {
        public:
            wxPyHtmlTagsModule(PyObject* thc) : wxHtmlTagsModule() {
                m_tagHandlerClass = thc;
                wxPyThreadBlocker blocker;
                Py_INCREF(m_tagHandlerClass);
                RegisterModule(this);
                wxHtmlWinParser::AddModule(this);
            }

            void OnExit() {
                wxPyThreadBlocker blocker;
                Py_DECREF(m_tagHandlerClass);
                m_tagHandlerClass = NULL;
                for (size_t x=0; x < m_objArray.GetCount(); x++) {
                    PyObject* obj = (PyObject*)m_objArray.Item(x);
                    Py_DECREF(obj);
                }
            }

            void FillHandlersTable(wxHtmlWinParser *parser) {
                wxPyThreadBlocker blocker;
                wxHtmlWinTagHandler* thPtr = 0;
                // First, make a new instance of the tag handler
                PyObject* arg = PyTuple_New(0);
                PyObject* obj = PyObject_CallObject(m_tagHandlerClass, arg);
                Py_DECREF(arg);

                // Make sure it succeeded
                if (!obj) {
                    PyErr_Print();
                    return;
                }

                // now figure out where it's C++ object is...
                if (! wxPyConvertWrappedPtr(obj, (void **)&thPtr, wxT("wxHtmlWinTagHandler"))) {
                    return;
                }

                // add it,
                parser->AddTagHandler(thPtr);

                // and track it.
                m_objArray.Add(obj);
            }

        private:
            PyObject*           m_tagHandlerClass;
            wxArrayPtrVoid      m_objArray;

        };
        """)


    module.addCppFunction('void', 'HtmlWinParser_AddTagHandler', '(PyObject* tagHandlerClass)',
        body="""\
            // Dynamically create a new wxModule.  Refcounts tagHandlerClass
            // and adds itself to the wxModules list and to the wxHtmlWinParser.
            new wxPyHtmlTagsModule(tagHandlerClass);
            wxModule::InitializeModules();
            """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #41
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/treelist.h>')
    module.find('wxTreeListEventHandler').ignore()
    module.find('wxTreeListItems').ignore()

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

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

    #-----------------------------------------------------------------
    c = module.find('wxTreeListCtrl')
    tools.fixWindowClass(c)

    module.addGlobalStr('wxTreeListCtrlNameStr', c)

    # Change NO_IMAGE default arg values to just -1, as the pi code has
    # problems when using the class name before the class is fully defined.
    for item in c.allItems():
        if isinstance(item, etgtools.ParamDef) and item.default == 'NO_IMAGE':
            item.default = '-1'

    # transfer ownership of some parameters
    c.find('AssignImageList.imageList').transfer = True
    c.find('SetItemData.data').transfer = True
    c.find('AppendItem.data').transfer = True
    c.find('InsertItem.data').transfer = True
    c.find('PrependItem.data').transfer = True

    # Replace GetSelections with an implementation that returns a Python list
    c.find('GetSelections').ignore()
    c.addCppMethod('PyObject*',
                   'GetSelections',
                   '()',
                   doc="""\
            Returns a list of all selected items. This method can be used in
            both single and multi-selection case.""",
                   body="""\
            unsigned count;
            wxTreeListItems items;
            count = self->GetSelections(items);

            wxPyThreadBlocker blocker;
            PyObject* list = PyList_New(count);
            for (size_t i=0; i<count; i++) {
                wxTreeListItem* item = new wxTreeListItem(items[i]);
                PyObject* obj = wxPyConstructObject((void*)item, wxT("wxTreeListItem"), true);
                PyList_SET_ITEM(list, i, obj); // PyList_SET_ITEM steals a reference
            }
            return list;
        """)

    # Set output parameter flags
    c.find('GetSortColumn.col').out = True
    c.find('GetSortColumn.ascendingOrder').out = True

    # Replace NO_IMAGE with wxTreeListCtrl::NO_IMAGE in parameter default values
    for item in c.allItems():
        if isinstance(item, etgtools.ParamDef) and item.default == 'NO_IMAGE':
            item.default = 'wxTreeListCtrl::NO_IMAGE'

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

    c.addPyCode("""\
        EVT_TREELIST_SELECTION_CHANGED = wx.PyEventBinder( wxEVT_TREELIST_SELECTION_CHANGED )
        EVT_TREELIST_ITEM_EXPANDING =    wx.PyEventBinder( wxEVT_TREELIST_ITEM_EXPANDING )
        EVT_TREELIST_ITEM_EXPANDED =     wx.PyEventBinder( wxEVT_TREELIST_ITEM_EXPANDED )
        EVT_TREELIST_ITEM_CHECKED =      wx.PyEventBinder( wxEVT_TREELIST_ITEM_CHECKED )
        EVT_TREELIST_ITEM_ACTIVATED =    wx.PyEventBinder( wxEVT_TREELIST_ITEM_ACTIVATED )
        EVT_TREELIST_ITEM_CONTEXT_MENU = wx.PyEventBinder( wxEVT_TREELIST_ITEM_CONTEXT_MENU )
        EVT_TREELIST_COLUMN_SORTED =     wx.PyEventBinder( wxEVT_TREELIST_COLUMN_SORTED )

        # deprecated wxEVT aliases
        wxEVT_COMMAND_TREELIST_SELECTION_CHANGED  = wxEVT_TREELIST_SELECTION_CHANGED
        wxEVT_COMMAND_TREELIST_ITEM_EXPANDING     = wxEVT_TREELIST_ITEM_EXPANDING
        wxEVT_COMMAND_TREELIST_ITEM_EXPANDED      = wxEVT_TREELIST_ITEM_EXPANDED
        wxEVT_COMMAND_TREELIST_ITEM_CHECKED       = wxEVT_TREELIST_ITEM_CHECKED
        wxEVT_COMMAND_TREELIST_ITEM_ACTIVATED     = wxEVT_TREELIST_ITEM_ACTIVATED
        wxEVT_COMMAND_TREELIST_ITEM_CONTEXT_MENU  = wxEVT_TREELIST_ITEM_CONTEXT_MENU
        wxEVT_COMMAND_TREELIST_COLUMN_SORTED      = wxEVT_TREELIST_COLUMN_SORTED
        """)

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

    # Add a ctor/factory for the Mac that can use the theme brush
    module.addCppCode("""\
    #ifdef __WXMAC__
    #include <wx/osx/private.h>
    #endif
    """)
    module.addCppFunction('wxColour*',
                          'MacThemeColour',
                          '(int themeBrushID)',
                          """\
    #ifdef __WXMAC__
        return new wxColour(wxMacCreateCGColorFromHITheme(themeBrushID));
    #else
        wxPyRaiseNotImplemented();
        return NULL;
    #endif
    """,
                          factory=True)

    # Change this macro into a value so we wont have problems when SIP takes its
    # address
    module.addCppCode("""\
    #undef wxTransparentColour
    wxColour wxTransparentColour(0, 0, 0, wxALPHA_TRANSPARENT);
    """)

    module.find('wxFromString').ignore()
    module.find('wxToString').ignore()

    module.find('wxALPHA_TRANSPARENT').type = 'const int'
    module.find('wxALPHA_OPAQUE').type = 'const int'

    c = module.find('wxColour')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Just set mustHaveApp for the copy ctor as it may need to use the colour
    # database to look up color names.
    c.find('wxColour').findOverload('const wxColour &').mustHaveApp()

    # Hide the string ctor so our typemap will be invoked for the copy ctor instead.
    c.find('wxColour').findOverload('wxString').ignore()

    c.addProperty('Pixel GetPixel')
    c.addProperty('RGB GetRGB SetRGB')
    c.addProperty('RGBA GetRGBA SetRGBA')
    c.addProperty('red Red')
    c.addProperty('green Green')
    c.addProperty('blue Blue')
    c.addProperty('alpha Alpha')

    c.find('GetPixel').ignore()  # We need to add a typcast
    c.addCppMethod(
        'wxIntPtr*', 'GetPixel', '()', """\
        #ifdef __WXGTK3__
            return new wxIntPtr(0);
        #else
            return new wxIntPtr((wxIntPtr)self->GetPixel());
        #endif
        """)

    # Set a flag on the return value and parameter types that are 'unsigned char'
    # such that they will be treated as an integer instead of a string.
    for item in c.allItems():
        if hasattr(item, 'type') and item.type == 'unsigned char':
            item.pyInt = True

    c.find('ChangeLightness.r').inOut = True
    c.find('ChangeLightness.g').inOut = True
    c.find('ChangeLightness.b').inOut = True

    c.find('MakeDisabled.r').inOut = True
    c.find('MakeDisabled.g').inOut = True
    c.find('MakeDisabled.b').inOut = True

    c.find('MakeGrey.r').inOut = True
    c.find('MakeGrey.g').inOut = True
    c.find('MakeGrey.b').inOut = True
    c.find('MakeGrey').findOverload('double').find('r').inOut = True
    c.find('MakeGrey').findOverload('double').find('g').inOut = True
    c.find('MakeGrey').findOverload('double').find('b').inOut = True

    c.find('MakeMono.r').out = True
    c.find('MakeMono.g').out = True
    c.find('MakeMono.b').out = True

    # The stock Colour items are documented as simple pointers, but in
    # reality they are macros that evaluate to a function call that returns a
    # Colour pointer, and that is only valid *after* the wx.App object has
    # been created. That messes up the code that SIP generates for them. So
    # instead we will just create uninitialized colours in a block of Python
    # code, that will then be initialized later when the wx.App is created.
    c.addCppMethod('void',
                   '_copyFrom',
                   '(const wxColour* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock colours will be initialized when the wx.App object is created.\n'
    for name in [
            'wxBLACK',
            'wxBLUE',
            'wxCYAN',
            'wxGREEN',
            'wxYELLOW',
            'wxLIGHT_GREY',
            'wxRED',
            'wxWHITE',
    ]:
        item = module.find(name)
        item.ignore()
        pycode += '%s = Colour()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    c.addCppMethod('PyObject*',
                   'Get',
                   '(bool includeAlpha=true)',
                   """\
        int red = -1;
        int green = -1;
        int blue = -1;
        int alpha = wxALPHA_OPAQUE;
        if (self->IsOk()) {
            red =   self->Red();
            green = self->Green();
            blue =  self->Blue();
            alpha = self->Alpha();
        }
        if (includeAlpha)
            return sipBuildResult(0, "(iiii)", red, green, blue, alpha);
        else
            return sipBuildResult(0, "(iii)", red, green, blue);
        """,
                   pyArgsString="(includeAlpha=True) -> (r,g,b) or (r,g,b,a)",
                   briefDoc="""\
        Returns the RGB intensity values as a tuple, optionally the alpha value as well."""
                   )

    tools.addGetIMMethodTemplate(module, c, ['red', 'green', 'blue', 'alpha'])

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

    # Types that can be converted to wx.Colour:
    #     wxColour (duh)
    #     Sequence with 3 or 4 integers
    #     String with color name or #RRGGBB or #RRGGBBAA format
    #     None  (converts to wxNullColour)
    c.allowNone = True
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (sipPy == Py_None)
                return 1;
            if (sipCanConvertToType(sipPy, sipType_wxColour, SIP_NO_CONVERTORS))
                return 1;
            if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy))
                return 1;
            if (wxPyNumberSequenceCheck(sipPy, 4) || wxPyNumberSequenceCheck(sipPy, 3)) {
                return 1;
            }
            return 0;
        }

        // otherwise do the conversion
        // is it None?
        if (sipPy == Py_None) {
            *sipCppPtr = new wxColour(wxNullColour);
            return sipGetState(sipTransferObj);
        }
        // Is it a string?
        else if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy)) {
            wxString spec = Py2wxString(sipPy);
            if (!spec.empty()
                && spec.GetChar(0) == '#'
                && (spec.length() == 7 || spec.length() == 9)) {  // It's  #RRGGBB[AA]
                long red, green, blue;
                red = green = blue = 0;
                spec.Mid(1,2).ToLong(&red,   16);
                spec.Mid(3,2).ToLong(&green, 16);
                spec.Mid(5,2).ToLong(&blue,  16);

                if (spec.length() == 7)         // no alpha
                    *sipCppPtr = new wxColour(red, green, blue);
                else {                          // yes alpha
                    long alpha;
                    spec.Mid(7,2).ToLong(&alpha, 16);
                    *sipCppPtr = new wxColour(red, green, blue, alpha);
                }
                return sipGetState(sipTransferObj);
            }
            else {                                       // assume it's a colour name
                // check if alpha is there too
                int pos;
                if (((pos = spec.Find(':', true)) != wxNOT_FOUND) && (pos == spec.length()-3)) {
                    long alpha;
                    spec.Right(2).ToLong(&alpha, 16);
                    wxColour c = wxColour(spec.Left(spec.length()-3));
                    *sipCppPtr = new wxColour(c.Red(), c.Green(), c.Blue(), alpha);
                }
                else
                    *sipCppPtr = new wxColour(spec);
                return sipGetState(sipTransferObj);
            }
        }
        // Is it a sequence? (if so then length was checked above)
        else if (wxPyNumberSequenceCheck(sipPy)) {
            size_t len = PySequence_Size(sipPy);

            PyObject* o1 = PySequence_ITEM(sipPy, 0);
            PyObject* o2 = PySequence_ITEM(sipPy, 1);
            PyObject* o3 = PySequence_ITEM(sipPy, 2);
            if (len == 3)
                *sipCppPtr = new wxColour(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3));
            else {
                PyObject* o4 = PySequence_ITEM(sipPy, 3);
                *sipCppPtr = new wxColour(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3),
                                          wxPyInt_AsLong(o4));
                Py_DECREF(o4);            
            }
            Py_DECREF(o1);
            Py_DECREF(o2);
            Py_DECREF(o3);
            return sipGetState(sipTransferObj);
        }

        // if we get this far then it must already be a wxColour instance
        *sipCppPtr = reinterpret_cast<wxColour*>(sipConvertToType(
            sipPy, sipType_wxColour, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
        return 0; // not a new instance
    """

    module.addPyCode(
        'NamedColour = wx.deprecated(Colour, "Use Colour instead.")')

    # Just for TESTING, remove it later
    module.addCppCode("""\
    wxColour testColourTypeMap(const wxColour& c)
    {
        return c;
    }
    """)
    module.addItem(
        etgtools.WigCode("""\
    wxColour testColourTypeMap(const wxColour& c);
    """))

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

    # These enums are declared in files that we will not be using because
    # wxPython does not need the classes that are in those files. So just
    # inject the enums here instead.
    from etgtools import EnumDef, EnumValueDef
    e = EnumDef(name='wxStreamError')
    e.items.extend([
        EnumValueDef(name='wxSTREAM_NO_ERROR'),
        EnumValueDef(name='wxSTREAM_EOF'),
        EnumValueDef(name='wxSTREAM_WRITE_ERROR'),
        EnumValueDef(name='wxSTREAM_READ_ERROR'),
    ])
    module.insertItem(0, e)

    e = EnumDef(name='wxSeekMode')
    e.items.extend([
        EnumValueDef(name='wxFromStart'),
        EnumValueDef(name='wxFromCurrent'),
        EnumValueDef(name='wxFromEnd'),
    ])
    module.insertItem(1, e)

    #-----------------------------------------------------------------
    c = module.find('wxStreamBase')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)
    c.find('operator!').ignore()

    #-----------------------------------------------------------------
    c = module.find('wxInputStream')
    c.abstract = True
    tools.removeVirtuals(c)

    # Include a C++ class that can wrap a Python file-like object so it can
    # be used as a wxInputStream
    c.includeCppCode('src/stream_input.cpp')

    # Use that class for the convert code
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (wxPyInputStream::Check(sipPy))
                return 1;
            return 0;
        }
        // otherwise do the conversion
        *sipCppPtr = new wxPyInputStream(sipPy);
        return sipGetState(sipTransferObj);
        """

    # Add Python file-like methods so a wx.InputStream can be used as if it
    # was any other Python file object.
    c.addCppMethod(
        'void', 'seek', '(wxFileOffset offset, int whence=0)', """\
        self->SeekI(offset, (wxSeekMode)whence);
        """)
    c.addCppMethod('wxFileOffset', 'tell', '()', """\
        return self->TellI();
        """)
    c.addCppMethod('void', 'close', '()', """\
        // ignored for now
        """)
    c.addCppMethod('void', 'flush', '()', """\
        // ignored for now
        """)
    c.addCppMethod('bool', 'eof', '()', """\
        return self->Eof();
        """)

    c.addCppCode("""\
        // helper used by the read and readline methods to make a PyObject
        static PyObject* _makeReadBufObj(wxInputStream* self, wxMemoryBuffer& buf) {
            PyObject* obj = NULL;

            wxPyThreadBlocker blocker;
            wxStreamError err = self->GetLastError();  // error check
            if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) {
                PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
            }
            else {
                // Return the data as a string object.  TODO: Py3
                obj = PyBytes_FromStringAndSize(buf, buf.GetDataLen());
            }
            return obj;
        }
        """)

    c.addCppMethod(
        'PyObject*', 'read', '()', """\
        wxMemoryBuffer buf;
        const ulong BUFSIZE = 1024;

        // read while bytes are available on the stream
        while ( self->CanRead() ) {
            self->Read(buf.GetAppendBuf(BUFSIZE), BUFSIZE);
            buf.UngetAppendBuf(self->LastRead());
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod(
        'PyObject*', 'read', '(ulong size)', """\
        wxMemoryBuffer buf;

        // Read only size number of characters
        self->Read(buf.GetWriteBuf(size), size);
        buf.UngetWriteBuf(self->LastRead());
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod(
        'PyObject*', 'readline', '()', """\
        wxMemoryBuffer buf;
        char ch = 0;

        // read until \\n 
        while ((ch != '\\n') && (self->CanRead())) {
            ch = self->GetC();
            buf.AppendByte(ch);
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod(
        'PyObject*', 'readline', '(ulong size)', """\
        wxMemoryBuffer buf;
        int i;
        char ch;

        // read until \\n or byte limit reached
        for (i=ch=0; (ch != '\\n') && (self->CanRead()) && (i < size); i++) {
            ch = self->GetC();
            buf.AppendByte(ch);
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppCode("""\
        PyObject* _wxInputStream_readline(wxInputStream* self);
        
        // This does the real work of the readlines methods
        static PyObject* _readlinesHelper(wxInputStream* self, 
                                          bool useSizeHint=false, ulong sizehint=0) {
            PyObject* pylist;

            // init list
            {
                wxPyThreadBlocker blocker;
                pylist = PyList_New(0);

                if (!pylist) {
                    PyErr_NoMemory();
                    return NULL;
                }
            }
    
            // read sizehint bytes or until EOF
            ulong i;
            for (i=0; (self->CanRead()) && (useSizeHint || (i < sizehint));) {
                PyObject* s = _wxInputStream_readline(self);
                if (s == NULL) {
                    wxPyThreadBlocker blocker;
                    Py_DECREF(pylist);
                    return NULL;
                }
                wxPyThreadBlocker blocker;
                PyList_Append(pylist, s);
                i += PyBytes_Size(s);
            }
    
            // error check
            wxStreamError err = self->GetLastError();
            if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) {
                wxPyThreadBlocker blocker;
                Py_DECREF(pylist);
                PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
                return NULL;
            }    
            return pylist;        
        }
        """)

    c.addCppMethod('PyObject*', 'readlines', '()', """\
        return _readlinesHelper(self);
        """)
    c.addCppMethod(
        'PyObject*', 'readlines', '(ulong sizehint)', """\
        return _readlinesHelper(self, true, sizehint);
        """)

    #-----------------------------------------------------------------
    c = module.find('wxOutputStream')
    c.abstract = True
    tools.removeVirtuals(c)

    # Include a C++ class that can wrap a Python file-like object so it can
    # be used as a wxOutputStream
    c.includeCppCode('src/stream_output.cpp')

    # Use that class for the convert code
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (wxPyOutputStream::Check(sipPy))
                return 1;
            return 0;
        }
        // otherwise do the conversion
        *sipCppPtr = new wxPyOutputStream(sipPy);
        return sipGetState(sipTransferObj);
        """

    # Add Python file-like methods so a wx.OutputStream can be used as if it
    # was any other Python file object.
    c.addCppMethod(
        'void', 'seek', '(wxFileOffset offset, int whence=0)', """\
        self->SeekO(offset, (wxSeekMode)whence);
        """)
    c.addCppMethod('wxFileOffset', 'tell', '()', """\
        return self->TellO();
        """)
    c.addCppMethod('void', 'close', '()', """\
        self->Close();
        """)
    c.addCppMethod('void', 'flush', '()', """\
        self->Sync();
        """)
    c.addCppMethod('bool', 'eof', '()', """\
        return false; //self->Eof();
        """)

    c.addCppMethod(
        'PyObject*', 'write', '(PyObject* data)', """\
        // We use only bytes objects (strings in 2.7) for the streams, never unicode
        wxPyThreadBlocker blocker;
        if (!PyBytes_Check(data)) {
            PyErr_SetString(PyExc_TypeError, "Bytes object expected");
            return NULL;
        }
        self->Write(PyBytes_AS_STRING(data), PyBytes_GET_SIZE(data));
        RETURN_NONE();
        """)

    # TODO: Add a writelines(sequence) method

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #44
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('wxWizardPage')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixWindowClass(c, False)
    module.addPyCode(
        "PyWizardPage = wx.deprecated(WizardPage, 'Use WizardPage instead.')")

    c = module.find('wxWizardPageSimple')
    tools.fixWindowClass(c, False)
    c.addItem(
        etgtools.WigCode("""\
        virtual wxWizardPage* GetNext() const;
        virtual wxWizardPage* GetPrev() const;
        """))

    c = module.find('wxWizard')
    tools.fixWindowClass(c, False)

    # ShowPage is undocumented and labeled "implementation only" but it seems
    # too useful to ignore, so add a MethodDef for it here.
    m = MethodDef(name='ShowPage',
                  type='bool',
                  isVirtual=True,
                  briefDoc="Show the given wizard page.",
                  detailedDoc=[
                      """\
                Calls TransferDataFromWindow on the current page first, and
                returns false without changing the page if it returned false.
                Returns True/False to indicate if the page was actually
                changed."""
                  ],
                  items=[
                      ParamDef(name='page', type='wxWizardPage*'),
                      ParamDef(name='goingForward',
                               type='bool',
                               default='true')
                  ])
    c.addItem(m)

    # Same for IsRunning
    m = MethodDef(name='IsRunning', type='bool', isConst=True)
    c.addItem(m)

    c = module.find('wxWizardEvent')
    tools.fixEventClass(c)
    module.addPyCode("""\
        EVT_WIZARD_BEFORE_PAGE_CHANGED  = wx.PyEventBinder( wxEVT_WIZARD_BEFORE_PAGE_CHANGED, 1)
        EVT_WIZARD_PAGE_CHANGED  = wx.PyEventBinder( wxEVT_WIZARD_PAGE_CHANGED, 1)
        EVT_WIZARD_PAGE_CHANGING = wx.PyEventBinder( wxEVT_WIZARD_PAGE_CHANGING, 1)
        EVT_WIZARD_CANCEL        = wx.PyEventBinder( wxEVT_WIZARD_CANCEL, 1)
        EVT_WIZARD_HELP          = wx.PyEventBinder( wxEVT_WIZARD_HELP, 1)
        EVT_WIZARD_FINISHED      = wx.PyEventBinder( wxEVT_WIZARD_FINISHED, 1)
        EVT_WIZARD_PAGE_SHOWN    = wx.PyEventBinder( wxEVT_WIZARD_PAGE_SHOWN, 1)
        """)

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

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

    module.addHeaderCode('#include <wxpy_api.h>')
    module.addImport('_core')
    module.addPyCode('import wx', order=10)
    module.addInclude(INCLUDES)

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

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

    c = module.find('wxGLContext')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    c.addPrivateCopyCtor()

    c = module.find('wxGLCanvas')
    tools.fixWindowClass(c)

    # We already have a MappedType for wxArrayInt, so just tweak the
    # interfaces to use that instead of a const int pointer.
    c.find('wxGLCanvas').ignore()
    m = c.addCppCtor_sip(
        argsString="""(
             wxWindow* parent, wxWindowID id=wxID_ANY, wxArrayInt* attribList=NULL,
             const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize,
             long style=0, const wxString& name="GLCanvas",
             const wxPalette& palette=wxNullPalette)""",
        cppSignature="""(
             wxWindow* parent, wxWindowID id=wxID_ANY, const int* attribList=NULL,
             const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize,
             long style=0, const wxString& name="GLCanvas",
             const wxPalette& palette=wxNullPalette)""",
        pyArgsString=
        "(parent, id=wx.ID_ANY, attribList=None, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, name='GLCanvas', palette=wx.NullPalette)",
        body="""\
            const int* attribPtr = NULL;
            if (attribList) {
                attribList->push_back(0); // ensure it is zero-terminated
                attribPtr = &attribList->front();
            }
            sipCpp = new sipwxGLCanvas(parent, id, attribPtr, *pos, *size, style, *name, *palette);
            """,
        noDerivedCtor=False,
    )

    m = c.find('IsDisplaySupported')
    m.find('attribList').type = 'wxArrayInt*'
    m.setCppCode_sip("""\
        const int* attribPtr = NULL;
        if (attribList) {
            attribList->push_back(0); // ensure it is zero-terminated
            attribPtr = &attribList->front();
        }
        sipRes = wxGLCanvas::IsDisplaySupported(attribPtr);
        """)

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

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

    module.addHeaderCode('#include <wxpy_api.h>')
    module.addImport('_core')
    module.addPyCode('''\
    import wx
    ID_ANY = wx.ID_ANY  # Needed for some parameter defaults in this module
    ''',
                     order=10)
    module.addInclude(INCLUDES)

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

    module.addHeaderCode('#include <wx/stc/stc.h>')
    module.addHeaderCode('#include "wxpybuffer.h"')

    c = module.find('wxStyledTextCtrl')
    assert isinstance(c, etgtools.ClassDef)
    c.bases = ['wxControl']  # wxTextCtrlIface is also a base...
    c.piBases = ['wx.Control', 'wx.TextEntry']
    tools.fixWindowClass(c, False)
    module.addGlobalStr('wxSTCNameStr', c)

    c.find('GetCurLine.linePos').out = True
    c.find('GetCurLineRaw.linePos').out = True
    for name in ['Remove', 'Replace', 'SetSelection', 'GetSelection']:
        m = c.find(name)
        m.find('from').name = 'from_'
        m.find('to').name = 'to_'

    c.find('GetSelection.from_').out = True
    c.find('GetSelection.to_').out = True
    c.find('PositionToXY.x').out = True
    c.find('PositionToXY.y').out = True

    # Split the HitTest overloads into separately named methods since once
    # the output parameters are applied they will have the same function
    # signature.
    ht1 = c.find('HitTest')
    ht2 = ht1.overloads[0]
    ht1.overloads = []
    c.insertItemAfter(ht1, ht2)
    ht1.pyName = 'HitTestPos'
    ht1.find('pos').out = True
    ht2.find('row').out = True
    ht2.find('col').out = True

    # Replace the *Pointer methods with ones that return a memoryview object instead.
    c.find('GetCharacterPointer').ignore()
    c.addCppMethod('PyObject*',
                   'GetCharacterPointer',
                   '()',
                   doc="""\
            Compact the document buffer and return a read-only memoryview
            object of the characters in the document.""",
                   body="""
            const char* ptr = self->GetCharacterPointer();
            Py_ssize_t len = self->GetLength();
            PyObject* rv;
            wxPyBLOCK_THREADS( rv = wxPyMakeBuffer((void*)ptr, len, true) );
            return rv;
            """)

    c.find('GetRangePointer').ignore()
    c.addCppMethod('PyObject*',
                   'GetRangePointer',
                   '(int position, int rangeLength)',
                   doc="""\
            Return a read-only pointer to a range of characters in the
            document. May move the gap so that the range is contiguous,
            but will only move up to rangeLength bytes.""",
                   body="""
            const char* ptr = self->GetRangePointer(position, rangeLength);
            Py_ssize_t len = rangeLength;
            PyObject* rv;
            wxPyBLOCK_THREADS( rv = wxPyMakeBuffer((void*)ptr, len, true) );
            return rv;
            """)

    # Generate the code for this differently because it needs to be
    # forcibly mashed into an int in the C code
    module.find('wxSTC_MASK_FOLDERS').forcedInt = True

    # Make sure that all the methods from wxTextEntry and wxTextCtrl are
    # included. This is needed because we are pretending that this class only
    # derives from wxControl but the real C++ class also derives from
    # wxTextCtrlIface which derives from wxTextEntryBase.
    import textentry
    mod = textentry.parseAndTweakModule()
    klass = mod.find('wxTextEntry')
    items = [
        item for item in klass.items if isinstance(item, etgtools.MethodDef)
        and not item.isCtor and not item.isDtor and not c.findItem(item.name)
    ]
    c.items.extend(items)

    import textctrl
    mod = textctrl.parseAndTweakModule()
    klass = mod.find('wxTextCtrl')
    items = [
        item for item in klass.items if isinstance(item, etgtools.MethodDef)
        and not item.isCtor and not item.isDtor and not c.findItem(item.name)
    ]
    c.items.extend(items)

    c.find('EmulateKeyPress').ignore()
    c.find('IsMultiLine').ignore()
    c.find('IsSingleLine').ignore()
    c.find('MacCheckSpelling').ignore()
    c.find('ShowNativeCaret').ignore()
    c.find('HideNativeCaret').ignore()

    # Change the *RGBAImage methods to accept any buffer object
    c.find('MarkerDefineRGBAImage').ignore()
    c.addCppMethod('void',
                   'MarkerDefineRGBAImage',
                   '(int markerNumber, wxPyBuffer* pixels)',
                   doc="""\
            Define a marker from RGBA data.\n
            It has the width and height from RGBAImageSetWidth/Height. You must 
            ensure that the buffer is at least width*height*4 bytes long. 
            """,
                   body="""\
            self->MarkerDefineRGBAImage(markerNumber, (unsigned char*)pixels->m_ptr);
            """)

    c.find('RegisterRGBAImage').ignore()
    c.addCppMethod('void',
                   'RegisterRGBAImage',
                   '(int type, wxPyBuffer* pixels)',
                   doc="""\
            Register an RGBA image for use in autocompletion lists.\n
            It has the width and height from RGBAImageSetWidth/Height. You must 
            ensure that the buffer is at least width*height*4 bytes long.
            """,
                   body="""\
            self->RegisterRGBAImage(type, (unsigned char*)pixels->m_ptr);
            """)

    # TODO:  Add the UTF8 PyMethods from classic (see _stc_utf8_methods.py)

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

    module.addPyCode("""\
        EVT_STC_CHANGE = wx.PyEventBinder( wxEVT_STC_CHANGE, 1 )
        EVT_STC_STYLENEEDED = wx.PyEventBinder( wxEVT_STC_STYLENEEDED, 1 )
        EVT_STC_CHARADDED = wx.PyEventBinder( wxEVT_STC_CHARADDED, 1 )
        EVT_STC_SAVEPOINTREACHED = wx.PyEventBinder( wxEVT_STC_SAVEPOINTREACHED, 1 )
        EVT_STC_SAVEPOINTLEFT = wx.PyEventBinder( wxEVT_STC_SAVEPOINTLEFT, 1 )
        EVT_STC_ROMODIFYATTEMPT = wx.PyEventBinder( wxEVT_STC_ROMODIFYATTEMPT, 1 )
        EVT_STC_KEY = wx.PyEventBinder( wxEVT_STC_KEY, 1 )
        EVT_STC_DOUBLECLICK = wx.PyEventBinder( wxEVT_STC_DOUBLECLICK, 1 )
        EVT_STC_UPDATEUI = wx.PyEventBinder( wxEVT_STC_UPDATEUI, 1 )
        EVT_STC_MODIFIED = wx.PyEventBinder( wxEVT_STC_MODIFIED, 1 )
        EVT_STC_MACRORECORD = wx.PyEventBinder( wxEVT_STC_MACRORECORD, 1 )
        EVT_STC_MARGINCLICK = wx.PyEventBinder( wxEVT_STC_MARGINCLICK, 1 )
        EVT_STC_NEEDSHOWN = wx.PyEventBinder( wxEVT_STC_NEEDSHOWN, 1 )
        EVT_STC_PAINTED = wx.PyEventBinder( wxEVT_STC_PAINTED, 1 )
        EVT_STC_USERLISTSELECTION = wx.PyEventBinder( wxEVT_STC_USERLISTSELECTION, 1 )
        EVT_STC_URIDROPPED = wx.PyEventBinder( wxEVT_STC_URIDROPPED, 1 )
        EVT_STC_DWELLSTART = wx.PyEventBinder( wxEVT_STC_DWELLSTART, 1 )
        EVT_STC_DWELLEND = wx.PyEventBinder( wxEVT_STC_DWELLEND, 1 )
        EVT_STC_START_DRAG = wx.PyEventBinder( wxEVT_STC_START_DRAG, 1 )
        EVT_STC_DRAG_OVER = wx.PyEventBinder( wxEVT_STC_DRAG_OVER, 1 )
        EVT_STC_DO_DROP = wx.PyEventBinder( wxEVT_STC_DO_DROP, 1 )
        EVT_STC_ZOOM = wx.PyEventBinder( wxEVT_STC_ZOOM, 1 )
        EVT_STC_HOTSPOT_CLICK = wx.PyEventBinder( wxEVT_STC_HOTSPOT_CLICK, 1 )
        EVT_STC_HOTSPOT_DCLICK = wx.PyEventBinder( wxEVT_STC_HOTSPOT_DCLICK, 1 )
        EVT_STC_HOTSPOT_RELEASE_CLICK = wx.PyEventBinder( wxEVT_STC_HOTSPOT_RELEASE_CLICK, 1 )
        EVT_STC_CALLTIP_CLICK = wx.PyEventBinder( wxEVT_STC_CALLTIP_CLICK, 1 )
        EVT_STC_AUTOCOMP_SELECTION = wx.PyEventBinder( wxEVT_STC_AUTOCOMP_SELECTION, 1 )
        EVT_STC_INDICATOR_CLICK = wx.PyEventBinder( wxEVT_STC_INDICATOR_CLICK, 1 )
        EVT_STC_INDICATOR_RELEASE = wx.PyEventBinder( wxEVT_STC_INDICATOR_RELEASE, 1 )
        EVT_STC_AUTOCOMP_CANCELLED = wx.PyEventBinder( wxEVT_STC_AUTOCOMP_CANCELLED, 1 )
        EVT_STC_AUTOCOMP_CHAR_DELETED = wx.PyEventBinder( wxEVT_STC_AUTOCOMP_CHAR_DELETED, 1 )
        EVT_STC_CLIPBOARD_COPY = wx.PyEventBinder( wxEVT_STC_CLIPBOARD_COPY, 1)
        EVT_STC_CLIPBOARD_PASTE = wx.PyEventBinder( wxEVT_STC_CLIPBOARD_PASTE, 1)
        EVT_STC_AUTOCOMP_COMPLETED = wx.PyEventBinder( wxEVT_STC_AUTOCOMP_COMPLETED, 1)
        EVT_STC_MARGIN_RIGHT_CLICK = wx.PyEventBinder( wxEVT_STC_MARGIN_RIGHT_CLICK, 1)
        """)

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

    # Keep some of the old names
    module.addPyCode("""\
        # compatibility aliases
        STC_SCMOD_NORM = STC_KEYMOD_NORM
        STC_SCMOD_SHIFT = STC_KEYMOD_SHIFT
        STC_SCMOD_CTRL = STC_KEYMOD_CTRL
        STC_SCMOD_ALT = STC_KEYMOD_ALT
        STC_SCMOD_SUPER = STC_KEYMOD_SUPER
        STC_SCMOD_META = STC_KEYMOD_META
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #47
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(
        PACKAGE, MODULE, NAME, DOCSTRING,
        check4unittest=False)  # all classes abstract, no unitests needed
    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('wxItemContainerImmutable')
    c.abstract = True

    c = module.find('wxItemContainer')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True

    # Ignore the Append and Insert method overloads that we don't want to
    # support. This will keep the ones that take a wxString or an
    # wxArrayString, and wxClientData.
    def pickOverloads(m):
        assert isinstance(m, etgtools.MethodDef)
        if 'void *' in m.argsString or \
           'wxClientData **' in m.argsString or \
           'wxString *' in m.argsString or \
            'std::vector' in m.argsString:
            m.ignore()

    for m in c.findAll('Append'):
        pickOverloads(m)
    for m in c.findAll('Insert'):
        pickOverloads(m)
    for m in c.findAll('Set'):
        pickOverloads(m)

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

    # Deal with transfering ownership of wxClientData objects
    c.find('DetachClientObject').transfer = True
    c.find('SetClientObject.data').transfer = True
    c.find('Append').findOverload('clientData').find(
        'clientData').transfer = True
    c.find('Insert').findOverload('clientData').find(
        'clientData').transfer = True

    # for compatibility, should they be deprecated?
    c.addPyMethod('AppendItems', '(self, items)', 'self.Append(items)')
    c.addPyMethod('GetItems', '(self)', 'return self.GetStrings()')
    c.addPyMethod('SetItems', '(self, items)', 'self.Set(items)')

    c = module.find('wxControlWithItems')
    c.abstract = True

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    c.addPyCode("""\
        EVT_TREE_BEGIN_DRAG        = PyEventBinder(wxEVT_TREE_BEGIN_DRAG       , 1)
        EVT_TREE_BEGIN_RDRAG       = PyEventBinder(wxEVT_TREE_BEGIN_RDRAG      , 1)
        EVT_TREE_BEGIN_LABEL_EDIT  = PyEventBinder(wxEVT_TREE_BEGIN_LABEL_EDIT , 1)
        EVT_TREE_END_LABEL_EDIT    = PyEventBinder(wxEVT_TREE_END_LABEL_EDIT   , 1)
        EVT_TREE_DELETE_ITEM       = PyEventBinder(wxEVT_TREE_DELETE_ITEM      , 1)
        EVT_TREE_GET_INFO          = PyEventBinder(wxEVT_TREE_GET_INFO         , 1)
        EVT_TREE_SET_INFO          = PyEventBinder(wxEVT_TREE_SET_INFO         , 1)
        EVT_TREE_ITEM_EXPANDED     = PyEventBinder(wxEVT_TREE_ITEM_EXPANDED    , 1)
        EVT_TREE_ITEM_EXPANDING    = PyEventBinder(wxEVT_TREE_ITEM_EXPANDING   , 1)
        EVT_TREE_ITEM_COLLAPSED    = PyEventBinder(wxEVT_TREE_ITEM_COLLAPSED   , 1)
        EVT_TREE_ITEM_COLLAPSING   = PyEventBinder(wxEVT_TREE_ITEM_COLLAPSING  , 1)
        EVT_TREE_SEL_CHANGED       = PyEventBinder(wxEVT_TREE_SEL_CHANGED      , 1)
        EVT_TREE_SEL_CHANGING      = PyEventBinder(wxEVT_TREE_SEL_CHANGING     , 1)
        EVT_TREE_KEY_DOWN          = PyEventBinder(wxEVT_TREE_KEY_DOWN         , 1)
        EVT_TREE_ITEM_ACTIVATED    = PyEventBinder(wxEVT_TREE_ITEM_ACTIVATED   , 1)
        EVT_TREE_ITEM_RIGHT_CLICK  = PyEventBinder(wxEVT_TREE_ITEM_RIGHT_CLICK , 1)
        EVT_TREE_ITEM_MIDDLE_CLICK = PyEventBinder(wxEVT_TREE_ITEM_MIDDLE_CLICK, 1)
        EVT_TREE_END_DRAG          = PyEventBinder(wxEVT_TREE_END_DRAG         , 1)
        EVT_TREE_STATE_IMAGE_CLICK = PyEventBinder(wxEVT_TREE_STATE_IMAGE_CLICK, 1)
        EVT_TREE_ITEM_GETTOOLTIP   = PyEventBinder(wxEVT_TREE_ITEM_GETTOOLTIP,   1)
        EVT_TREE_ITEM_MENU         = PyEventBinder(wxEVT_TREE_ITEM_MENU,         1)
        
        # deprecated wxEVT aliases
        wxEVT_COMMAND_TREE_BEGIN_DRAG         = wxEVT_TREE_BEGIN_DRAG
        wxEVT_COMMAND_TREE_BEGIN_RDRAG        = wxEVT_TREE_BEGIN_RDRAG
        wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT   = wxEVT_TREE_BEGIN_LABEL_EDIT
        wxEVT_COMMAND_TREE_END_LABEL_EDIT     = wxEVT_TREE_END_LABEL_EDIT
        wxEVT_COMMAND_TREE_DELETE_ITEM        = wxEVT_TREE_DELETE_ITEM
        wxEVT_COMMAND_TREE_GET_INFO           = wxEVT_TREE_GET_INFO
        wxEVT_COMMAND_TREE_SET_INFO           = wxEVT_TREE_SET_INFO
        wxEVT_COMMAND_TREE_ITEM_EXPANDED      = wxEVT_TREE_ITEM_EXPANDED
        wxEVT_COMMAND_TREE_ITEM_EXPANDING     = wxEVT_TREE_ITEM_EXPANDING
        wxEVT_COMMAND_TREE_ITEM_COLLAPSED     = wxEVT_TREE_ITEM_COLLAPSED
        wxEVT_COMMAND_TREE_ITEM_COLLAPSING    = wxEVT_TREE_ITEM_COLLAPSING
        wxEVT_COMMAND_TREE_SEL_CHANGED        = wxEVT_TREE_SEL_CHANGED
        wxEVT_COMMAND_TREE_SEL_CHANGING       = wxEVT_TREE_SEL_CHANGING
        wxEVT_COMMAND_TREE_KEY_DOWN           = wxEVT_TREE_KEY_DOWN
        wxEVT_COMMAND_TREE_ITEM_ACTIVATED     = wxEVT_TREE_ITEM_ACTIVATED
        wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK   = wxEVT_TREE_ITEM_RIGHT_CLICK
        wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK  = wxEVT_TREE_ITEM_MIDDLE_CLICK
        wxEVT_COMMAND_TREE_END_DRAG           = wxEVT_TREE_END_DRAG
        wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK  = wxEVT_TREE_STATE_IMAGE_CLICK
        wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP    = wxEVT_TREE_ITEM_GETTOOLTIP
        wxEVT_COMMAND_TREE_ITEM_MENU          = wxEVT_TREE_ITEM_MENU        
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #49
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('wxSizerItem')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # ctors taking a sizer transfer ownership
    for m in c.find('wxSizerItem').all():
        if m.findItem('sizer'):
            m.find('sizer').transfer = True

    c.find('AssignSizer.sizer').transfer = True

    # userData args transfer ownership too, and we'll use wxPyUserData
    # instead of any wxObject
    for m in c.allItems():
        if isinstance(m, etgtools.MethodDef) and m.findItem('userData'):
            m.find('userData').transfer = True
            m.find('userData').type = 'wxPyUserData*'

    gud = c.find('GetUserData')
    gud.type = 'wxPyUserData*'
    gud.setCppCode('return dynamic_cast<wxPyUserData*>(self->GetUserData());')

    # these have been deprecated for a while so go ahead and get rid of them
    c.find('SetWindow').ignore()
    c.find('SetSizer').ignore()
    c.find('SetSpacer').ignore()

    c.addPrivateCopyCtor()

    #---------------------------------------------
    c = module.find('wxSizer')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixSizerClass(c)
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()

    for func in c.findAll('Add') + c.findAll('Insert') + c.findAll('Prepend'):
        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.find('GetChildren').overloads = []
    c.find('GetChildren').noCopy = True

    # Needs wxWin 2.6 compatibility
    c.find('Remove').findOverload('(wxWindow *window)').ignore()

    # deprecated and removed
    c.find('SetVirtualSizeHints').ignore()

    c.addPyMethod('AddMany',
                  '(self, items)',
                  doc="""\
        :meth:`AddMany` is a convenience method for adding several items to a sizer
        at one time. Simply pass it a list of tuples, where each tuple
        consists of the parameters that you would normally pass to the :meth:`Add`
        method.
        """,
                  body="""\
        for item in items:
            if not isinstance(item, (tuple, list)):
                item = (item, )
            self.Add(*item)
        """)

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

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

    c.addCppMethod(
        'wxSizerItem*',
        'Insert',
        '(ulong index, const wxSize& size, int proportion=0, int flag=0, '
        'int border=0, wxPyUserData* userData /Transfer/ = NULL)',
        doc="Insert a spacer using a :class:`Size` object.",
        body=
        "return self->Insert(index, size->x, size->y, proportion, flag, border, userData);"
    )

    c.addCppMethod('wxSizerItem*',
                   'Add',
                   '(const wxSize& size, const wxSizerFlags& flags)',
                   doc="Add a spacer using a :class:`Size` object.",
                   body="return self->Add(size->x, size->y, *flags);")

    c.addCppMethod('wxSizerItem*',
                   'Prepend',
                   '(const wxSize& size, const wxSizerFlags& flags)',
                   doc="Prepend a spacer using a :class:`Size` object.",
                   body="return self->Prepend(size->x, size->y, *flags);")

    c.addCppMethod(
        'wxSizerItem*',
        'Insert',
        '(ulong index, const wxSize& size, const wxSizerFlags& flags)',
        doc="Insert a spacer using a :class:`Size` object.",
        body="return self->Insert(index, size->x, size->y, *flags);")

    c.addPyMethod(
        '__nonzero__',
        '(self)',
        doc=
        "Can be used to test if the C++ part of the sizer still exists, with \n"
        "code like this::\n\n"
        "    if theSizer:\n"
        "        doSomething()",
        body="""\
        import wx.siplib
        return not wx.siplib.isdeleted(self)
        """)

    c.addPyMethod(
        '__iter__',
        '(self)',
        doc=
        "A Py convenience method that allows Sizers to act as iterables that will yield their wx.SizerItems.",
        body="for item in self.GetChildren(): yield item")

    c.addPyCode('Sizer.__bool__ = Sizer.__nonzero__')  # For Python 3

    #---------------------------------------------
    c = module.find('wxBoxSizer')
    tools.fixSizerClass(c)
    c.find('wxBoxSizer.orient').default = 'wxHORIZONTAL'

    #---------------------------------------------
    c = module.find('wxStaticBoxSizer')
    tools.fixSizerClass(c)
    c.find('wxStaticBoxSizer.orient').default = 'wxHORIZONTAL'

    #---------------------------------------------
    c = module.find('wxGridSizer')
    tools.fixSizerClass(c)

    c.addPyMethod('CalcRowsCols',
                  '(self)',
                  doc="""\
        CalcRowsCols() -> (rows, cols)

        Calculates how many rows and columns will be in the sizer based
        on the current number of items and also the rows, cols specified
        in the constructor.
        """,
                  body="""\
        nitems = len(self.GetChildren())
        rows = self.GetRows()
        cols = self.GetCols()
        assert rows != 0 or cols != 0, "Grid sizer must have either rows or columns fixed"
        if cols != 0:
            rows = (nitems + cols - 1) / cols
        elif rows != 0:
            cols = (nitems + rows - 1) / rows
        return (rows, cols)
        """)

    #---------------------------------------------
    c = module.find('wxFlexGridSizer')
    tools.fixSizerClass(c)

    #---------------------------------------------
    c = module.find('wxStdDialogButtonSizer')
    tools.fixSizerClass(c)

    module.addPyCode("PySizer = wx.deprecated(Sizer, 'Use Sizer instead.')")

    module.addItem(
        tools.wxListWrapperTemplate('wxSizerItemList', 'wxSizerItem', module))

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #50
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('wxPalette')
    tools.removeVirtuals(c)


    # Add a helper function for use with the Create method and the Ctor
    # accepting RGB data.
    c.addCppCode("""\
        // a helper function to be used in the Create method and one of the Ctors
        bool _paletteCreateHelper(wxPalette* self,
                                  PyObject* red, PyObject* green, PyObject* blue) {
            bool rval = false;
            wxPyThreadBlocker blocker;
            char* errMsg = "Expected a sequence of integer objects";

            if (!PySequence_Check(red) || !PySequence_Check(green) || !PySequence_Check(blue)) {
                PyErr_SetString(PyExc_TypeError, errMsg);
                return rval;
            }

            Py_ssize_t count = PySequence_Size(red);
            if (PySequence_Size(green) != count || PySequence_Size(blue) != count) {
                PyErr_SetString(PyExc_ValueError, "Sequence lengths must be equal");
                return rval;
            }

            unsigned char* redArray = new unsigned char[count];
            unsigned char* greenArray = new unsigned char[count];
            unsigned char* blueArray = new unsigned char[count];

            for (Py_ssize_t i = 0; i < count; i++) {
                PyObject* redItem = PySequence_ITEM(red, i);
                PyObject* greenItem = PySequence_ITEM(green, i);
                PyObject* blueItem = PySequence_ITEM(blue, i);
                if (!wxPyInt_Check(redItem) || !wxPyInt_Check(greenItem) || !wxPyInt_Check(blueItem)) {
                    PyErr_SetString(PyExc_TypeError, errMsg);
                    goto pch_exit;
                }

                long redLong = wxPyInt_AsLong(redItem);
                long greenLong = wxPyInt_AsLong(greenItem);
                long blueLong = wxPyInt_AsLong(blueItem);
                Py_DECREF(redItem);
                Py_DECREF(greenItem);
                Py_DECREF(blueItem);
                if (redLong < 0 || redLong > 255 || greenLong < 0 || greenLong > 255 || blueLong < 0 || blueLong > 255) {
                    PyErr_SetString(PyExc_ValueError, "Sequence values must be in the 0..255 range");
                    goto pch_exit;
                }
                redArray[i] = redLong;
                greenArray[i] = greenLong;
                blueArray[i] = blueLong;
            }

            rval = self->Create(count, redArray, greenArray, blueArray);

        pch_exit:
            delete[] redArray;
            delete[] greenArray;
            delete[] blueArray;
            return rval;
        }
        """)


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

    # Replace the constructor accepting the arrays of RGB values with one that
    # understands any Python sequence.
    c.find('wxPalette').findOverload('red').ignore()
    c.addCppCtor('(PyObject* red, PyObject* green, PyObject* blue)',
        doc=dedent("""\
        Creates a palette from a set of sequences of integers,
        one for each red, green and blue color components.

        :param red: A sequence of integer values in the range 0..255 inclusive.
        :param green: A sequence of integer values in the range 0..255 inclusive.
        :param blue: A sequence of integer values in the range 0..255 inclusive.

        .. note:: All sequences must be the same length.
        """),
        body="""\
            wxPalette* pal = new wxPalette;
            _paletteCreateHelper(pal, red, green, blue);
            if (PyErr_Occurred()) {
                delete pal;
                return NULL;
            }
            return pal;
            """)

    c.find('GetPixel.red').pyInt = True
    c.find('GetPixel.green').pyInt = True
    c.find('GetPixel.blue').pyInt = True

    c.find('GetRGB').ignore()
    c.addCppMethod('PyObject*', 'GetRGB', '(int pixel)',
        pyArgsString="(pixel) -> (red, green, blue)",
        doc="Returns RGB values for a given palette index.",
        body="""\
            unsigned char red;
            unsigned char green;
            unsigned char blue;
            wxPyThreadBlocker blocker;
            if (!self->GetRGB(pixel, &red, &green, &blue)) {
                PyErr_SetString(PyExc_IndexError, "Pixel out of range");
                return NULL;
            }
            PyObject* rv = PyTuple_New(3);
            PyTuple_SetItem(rv, 0, wxPyInt_FromLong(red));
            PyTuple_SetItem(rv, 1, wxPyInt_FromLong(green));
            PyTuple_SetItem(rv, 2, wxPyInt_FromLong(blue));
            return rv;
            """)

    # Replace the Create method with one that understands any kind of Python sequence
    c.find('Create').ignore()
    c.addCppMethod('PyObject*', 'Create', '(PyObject* red, PyObject* green, PyObject* blue)',
        pyArgsString="(red, green, blue) -> bool",
        doc=dedent("""\
        Creates a palette from 3 sequences of integers, one for each red, blue or green component.

        :param red: A sequence of integer values in the range 0..255 inclusive.
        :param green: A sequence of integer values in the range 0..255 inclusive.
        :param blue: A sequence of integer values in the range 0..255 inclusive.

        .. note:: All sequences must be the same length.
        """),
        body="""\
            bool rval = _paletteCreateHelper(self, red, green, blue);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred())
                return NULL;
            if (rval)
                Py_RETURN_TRUE;
            else
                Py_RETURN_FALSE;
            """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
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('wxBrush')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Set mustHaveApp on all ctors except the default ctor
    for ctor in c.find('wxBrush').all():
        if ctor.isCtor and ctor.argsString != '()':
            ctor.mustHaveApp()

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addCppCode("""\
        #ifdef __WXMAC__
        #include <wx/osx/private.h>
        #endif
        """)
    c.addCppMethod(
        'void', 'MacSetTheme', '(int macThemeBrushID)', """\
        #ifdef __WXMAC__
            self->SetColour(wxColour(wxMacCreateCGColorFromHITheme(macThemeBrushID)));
        #else
            wxPyRaiseNotImplemented();
        #endif
        """)

    c.addAutoProperties()

    # The stock Brush items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a brush
    # pointer, and that is only valid *after* the wx.App object has been
    # created. That messes up the code that SIP generates for them, so we need
    # to come up with another solution. So instead we will just create
    # uninitialized brush in a block of Python code, that will then be
    # initialized later when the wx.App is created.
    c.addCppMethod('void',
                   '_copyFrom',
                   '(const wxBrush* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock brushes will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_BRUSH' in item.name:
            item.ignore()
            pycode += '%s = Brush()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    # it is delay-initialized, see stockgdi.sip
    module.find('wxTheBrushList').ignore()

    # Some aliases that should be phased out eventually, (sooner rather than
    # later.) They are already gone (or wrapped by an #if) in the C++ code,
    # and so are not found in the documentation...
    module.addPyCode("""\
        wx.STIPPLE_MASK_OPAQUE = int(wx.BRUSHSTYLE_STIPPLE_MASK_OPAQUE)
        wx.STIPPLE_MASK        = int(wx.BRUSHSTYLE_STIPPLE_MASK)
        wx.STIPPLE             = int(wx.BRUSHSTYLE_STIPPLE)
        wx.BDIAGONAL_HATCH     = int(wx.BRUSHSTYLE_BDIAGONAL_HATCH)
        wx.CROSSDIAG_HATCH     = int(wx.BRUSHSTYLE_CROSSDIAG_HATCH)
        wx.FDIAGONAL_HATCH     = int(wx.BRUSHSTYLE_FDIAGONAL_HATCH)
        wx.CROSS_HATCH         = int(wx.BRUSHSTYLE_CROSS_HATCH)
        wx.HORIZONTAL_HATCH    = int(wx.BRUSHSTYLE_HORIZONTAL_HATCH)
        wx.VERTICAL_HATCH      = int(wx.BRUSHSTYLE_VERTICAL_HATCH)
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #52
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/wx.h>')

    #---------------------------------------
    # wxPoint2D and wxRect2D tweaks

    c = module.find('wxPoint2DDouble')
    c.renameClass('Point2D')
    c.find('wxPoint2DDouble').findOverload('wxPoint2DInt').ignore()

    c.find('m_x').pyName = 'x'
    c.find('m_y').pyName = 'y'
    c.find('GetFloor.x').out = True
    c.find('GetFloor.y').out = True
    c.find('GetRounded.x').out = True
    c.find('GetRounded.y').out = True

    # these have link errors
    c.find('operator/=').findOverload('wxDouble').ignore()
    c.find('operator*=').findOverload('wxDouble').ignore()

    c.convertFromPyObject = tools.convertTwoDoublesTemplate('wxPoint2DDouble')

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(dd)", self->m_x, self->m_y);
        """,
                   briefDoc="""\
        Get() -> (x,y)\n
        Return the x and y properties as a tuple.""")

    tools.addGetIMMethodTemplate(module, c, ['x', 'y'])

    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)', 'return "wx.Point2D"+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 (Point2D, 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('Point2D.__safe_for_unpickling__ = True')

    # ignore these operator methods, since we are not wrapping the Int version
    c.find('operator*=').findOverload('wxInt32').ignore()
    c.find('operator/=').findOverload('wxInt32').ignore()

    # ignore all the global operators too, there is no equivallent in Python
    for item in module:
        if isinstance(
                item,
                etgtools.FunctionDef) and item.name.startswith('operator'):
            for f in item.all():
                f.ignore()

    c = module.find('wxRect2DDouble')
    c.renameClass('Rect2D')
    c.find('m_x').pyName = 'x'
    c.find('m_y').pyName = 'y'
    c.find('m_width').pyName = 'width'
    c.find('m_height').pyName = 'height'

    c.convertFromPyObject = tools.convertFourDoublesTemplate('wxRect2DDouble')

    c.addCppMethod('PyObject*',
                   'Get',
                   '()',
                   """\
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(dddd)",
                    self->m_x, self->m_y, self->m_width, self->m_height);
        """,
                   briefDoc="""\
        Get() -> (x, y, width, height)\n
        Return the rectangle's properties as a tuple.""")

    tools.addGetIMMethodTemplate(module, c, ['x', 'y', 'width', 'height'])

    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)', 'return "wx.Rect2D"+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 (Rect2D, 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('Rect2D.__safe_for_unpickling__ = True')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #53
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('wxDC')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()

    c.addPrivateCopyCtor()
    c.addPublic()
    tools.removeVirtuals(c)

    # Keep only the wxSize overloads of these
    c.find('GetSize').findOverload('wxCoord').ignore()
    c.find('GetSizeMM').findOverload('wxCoord').ignore()

    # TODO: needs wxAffineMatrix2D support.
    #c.find('GetTransformMatrix').ignore()
    #c.find('SetTransformMatrix').ignore()

    # remove wxPoint* overloads, we use the wxPointList ones
    c.find('DrawLines').findOverload('wxPoint points').ignore()
    c.find('DrawPolygon').findOverload('wxPoint points').ignore()
    c.find('DrawSpline').findOverload('wxPoint points').ignore()

    # TODO: we'll need a custom method implementation for this since there
    # are multiple array parameters involved...
    c.find('DrawPolyPolygon').ignore()

    # Add output param annotations so the generated docstrings will be correct
    c.find('GetUserScale.x').out = True
    c.find('GetUserScale.y').out = True

    c.find('GetLogicalScale.x').out = True
    c.find('GetLogicalScale.y').out = True

    c.find('GetLogicalOrigin').overloads = []
    c.find('GetLogicalOrigin.x').out = True
    c.find('GetLogicalOrigin.y').out = True

    c.find('GetClippingBox.x').out = True
    c.find('GetClippingBox.y').out = True
    c.find('GetClippingBox.width').out = True
    c.find('GetClippingBox.height').out = True
    c.addPyMethod(
        'GetClippingRect',
        '(self)',
        doc="Gets the rectangle surrounding the current clipping region",
        body="return wx.Rect(*self.GetClippingBox())")

    # Deal with the text-extent methods. In Classic we renamed one overloaded
    # method with a "Full" name, and the simpler one was left with the
    # original name.  I think a simpler approach here will be to remove the
    # simple version, rename the Full version as before, and then add a
    # CppMethod to reimplement the simple version.

    for name in ['GetTextExtent', 'GetMultiLineTextExtent']:
        m = c.find(name)
        # if these fail then double-check order of parsed methods, etc.
        assert len(m.overloads) == 1
        assert 'wxCoord' not in m.overloads[0].argsString
        m.overloads = []

    c.find('GetTextExtent').pyName = 'GetFullTextExtent'
    c.find('GetMultiLineTextExtent').pyName = 'GetFullMultiLineTextExtent'

    # Set output parameters
    c.find('GetTextExtent.w').out = True
    c.find('GetTextExtent.h').out = True
    c.find('GetTextExtent.descent').out = True
    c.find('GetTextExtent.externalLeading').out = True

    c.find('GetMultiLineTextExtent.w').out = True
    c.find('GetMultiLineTextExtent.h').out = True
    c.find('GetMultiLineTextExtent.heightLine').out = True

    # Update the docs to remove references to overloading, pointer values, etc.
    m = c.find('GetTextExtent')
    m.briefDoc = "Gets the dimensions of the string as it would be drawn."
    m.detailedDoc = [
        dedent("""\
        The ``string`` parameter is the string to measure.  The return value
        is a tuple of integer values consisting of ``widget``, ``height``,
        ``decent`` and ``externalLeading``. The ``descent`` is the dimension
        from the baseline of the font to the bottom of the descender, and
        ``externalLeading`` is any extra vertical space added to the font by the
        font designer (usually is zero).

        If the optional parameter ``font`` is specified and valid, then it is
        used for the text extent calculation. Otherwise the currently selected
        font is.

        .. seealso:: :class:`wx.Font`, :meth:`~wx.DC.SetFont`,
           :meth:`~wx.DC.GetPartialTextExtents, :meth:`~wx.DC.GetMultiLineTextExtent`
        """)
    ]

    m = c.find('GetMultiLineTextExtent')
    m.briefDoc = "Gets the dimensions of the string as it would be drawn."
    m.detailedDoc = [
        dedent("""\
        The ``string`` parameter is the string to measure.  The return value
        is a tuple of integer values consisting of ``widget``, ``height`` and
        ``heightLine``.  The ``heightLine`` is the the height of a single line.

        If the optional parameter ``font`` is specified and valid, then it is
        used for the text extent calculation. Otherwise the currently selected
        font is.

        .. note:: This function works with both single-line and multi-line strings.

        .. seealso:: :class:`wx.Font`, :meth:`~wx.DC.SetFont`,
           :meth:`~wx.DC.GetPartialTextExtents, :meth:`~wx.DC.GetTextExtent`
        """)
    ]

    # Now add the simpler versions of the extent methods
    c.addCppMethod('wxSize*',
                   'GetTextExtent',
                   '(const wxString& st)',
                   isConst=True,
                   doc=dedent("""\
            Return the dimensions of the given string's text extent using the
            currently selected font.

            :param st: The string to be measured

            .. seealso:: :meth:`~wx.DC.GetFullTextExtent`
            """),
                   body="""\
            return new wxSize(self->GetTextExtent(*st));
            """,
                   overloadOkay=False,
                   factory=True)

    c.addCppMethod('wxSize*',
                   'GetMultiLineTextExtent',
                   '(const wxString& st)',
                   isConst=True,
                   doc=dedent("""\
            Return the dimensions of the given string's text extent using the
            currently selected font, taking into account multiple lines if
            present in the string.

            :param st: The string to be measured

            .. seealso:: :meth:`~wx.DC.GetFullMultiLineTextExtent`
            """),
                   body="""\
            return new wxSize(self->GetMultiLineTextExtent(*st));
            """,
                   overloadOkay=False,
                   factory=True)

    # Add some alternate implementations for other DC methods, in order to
    # avoid using parameters as return values, etc. as well as Classic
    # compatibility.
    c.find('GetPixel').ignore()
    c.addCppMethod('wxColour*',
                   'GetPixel',
                   '(wxCoord x, wxCoord y)',
                   doc="Gets the colour at the specified location on the DC.",
                   body="""\
            wxColour* col = new wxColour;
            self->GetPixel(x, y, col);
            return col;
            """,
                   factory=True)

    # Return the rect instead of using an output parameter
    m = c.find('DrawLabel').findOverload('rectBounding')
    m.type = 'wxRect*'
    m.find('rectBounding').ignore()
    m.factory = True  # a new instance of wxRect is being created
    m.setCppCode("""\
        wxRect rv;
        self->DrawLabel(*text, *bitmap, *rect, alignment, indexAccel, &rv);
        return new wxRect(rv);
        """)
    c.addPyCode(
        'DC.DrawImageLabel = wx.deprecated(DC.DrawLabel, "Use DrawLabel instead.")'
    )

    # Return the array instead of using an output parameter
    m = c.find('GetPartialTextExtents')
    m.type = 'wxArrayInt*'
    m.find('widths').ignore()
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayInt rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayInt(rval);
        """)

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)

    c.addPyMethod(
        'GetBoundingBox',
        '(self)',
        doc="""\
        GetBoundingBox() -> (x1,y1, x2,y2)\n
        Returns the min and max points used in drawing commands so far.""",
        body="return (self.MinX(), self.MinY(), self.MaxX(), self.MaxY())")

    c.addCppMethod(
        'long', 'GetHDC', '()', """\
        #ifdef __WXMSW__
            return (long)self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return 0;
        #endif""")
    c.addCppMethod(
        'void*', 'GetCGContext', '()', """\
        #ifdef __WXMAC__
            return self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")
    c.addCppMethod(
        'void*', 'GetGdkDrawable', '()', """\
        #ifdef __WXGTK__
            return self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")

    c.addPyCode(
        'DC.GetHDC = wx.deprecated(DC.GetHDC, "Use GetHandle instead.")')
    c.addPyCode(
        'DC.GetCGContext = wx.deprecated(DC.GetCGContext, "Use GetHandle instead.")'
    )
    c.addPyCode(
        'DC.GetGdkDrawable = wx.deprecated(DC.GetGdkDrawable, "Use GetHandle instead.")'
    )

    # This file contains implementations of functions for quickly drawing
    # lists of items on the DC. They are called from the CppMethods defined
    # below, which in turn are called from the PyMethods below that.
    c.includeCppCode('src/dc_ex.cpp')

    c.addCppMethod(
        'PyObject*',
        '_DrawPointList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXPoint, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawLineList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXLine, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawRectangleList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXRectangle, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawEllipseList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXEllipse, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawPolygonList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXPolygon, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawTextList',
        '(PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)',
        body=
        "return wxPyDrawTextList(*self, textList, pyPoints, foregroundList, backgroundList);"
    )

    c.addPyMethod('DrawPointList',
                  '(self, points, pens=None)',
                  doc="""\
            Draw a list of points as quickly as possible.

            :param points: A sequence of 2-element sequences representing
                           each point to draw, (x,y).
            :param pens:   If None, then the current pen is used.  If a single
                           pen then it will be used for all points.  If a list of
                           pens then there should be one for each point in points.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(points):
                raise ValueError('points and pens must have same length')
            return self._DrawPointList(points, pens, [])
            """)

    c.addPyMethod('DrawLineList',
                  '(self, lines, pens=None)',
                  doc="""\
            Draw a list of lines as quickly as possible.

            :param lines: A sequence of 4-element sequences representing
                          each line to draw, (x1,y1, x2,y2).
            :param pens:  If None, then the current pen is used.  If a
                          single pen then it will be used for all lines.  If
                          a list of pens then there should be one for each line
                          in lines.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(lines):
                raise ValueError('lines and pens must have same length')
            return self._DrawLineList(lines, pens, [])
            """)

    c.addPyMethod('DrawRectangleList',
                  '(self, rectangles, pens=None, brushes=None)',
                  doc="""\
            Draw a list of rectangles as quickly as possible.

            :param rectangles: A sequence of 4-element sequences representing
                               each rectangle to draw, (x,y, w,h).
            :param pens:       If None, then the current pen is used.  If a
                               single pen then it will be used for all rectangles.
                               If a list of pens then there should be one for each
                               rectangle in rectangles.
            :param brushes:    A brush or brushes to be used to fill the rectagles,
                               with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(rectangles):
                raise ValueError('rectangles and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(rectangles):
                raise ValueError('rectangles and brushes must have same length')
            return self._DrawRectangleList(rectangles, pens, brushes)
            """)

    c.addPyMethod('DrawEllipseList',
                  '(self, ellipses, pens=None, brushes=None)',
                  doc="""\
            Draw a list of ellipses as quickly as possible.

            :param ellipses: A sequence of 4-element sequences representing
                             each ellipse to draw, (x,y, w,h).
            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all ellipses.
                             If a list of pens then there should be one for each
                             ellipse in ellipses.
            :param brushes:  A brush or brushes to be used to fill the ellipses,
                             with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(ellipses):
                raise ValueError('ellipses and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(ellipses):
                raise ValueError('ellipses and brushes must have same length')
            return self._DrawEllipseList(ellipses, pens, brushes)
            """)

    c.addPyMethod('DrawPolygonList',
                  '(self, polygons, pens=None, brushes=None)',
                  doc="""\
            Draw a list of polygons, each of which is a list of points.

            :param polygons: A sequence of sequences of sequences.
                             [[(x1,y1),(x2,y2),(x3,y3)...], [(x1,y1),(x2,y2),(x3,y3)...]]

            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all polygons.
                             If a list of pens then there should be one for each
                             polygon.
            :param brushes:  A brush or brushes to be used to fill the polygons,
                             with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(polygons):
                raise ValueError('polygons and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(polygons):
                raise ValueError('polygons and brushes must have same length')
            return self._DrawPolygonList(polygons, pens, brushes)
            """)

    c.addPyMethod(
        'DrawTextList',
        '(self, textList, coords, foregrounds=None, backgrounds=None)',
        doc="""\
            Draw a list of strings using a list of coordinants for positioning each string.

            :param textList:    A list of strings
            :param coords:      A list of (x,y) positions
            :param foregrounds: A list of `wx.Colour` objects to use for the
                                foregrounds of the strings.
            :param backgrounds: A list of `wx.Colour` objects to use for the
                                backgrounds of the strings.

            NOTE: Make sure you set background mode to wx.Solid (DC.SetBackgroundMode)
                  If you want backgrounds to do anything.
            """,
        body="""\
            if type(textList) == type(''):
                textList = [textList]
            elif len(textList) != len(coords):
                raise ValueError('textlist and coords must have same length')
            if foregrounds is None:
                foregrounds = []
            elif isinstance(foregrounds, wx.Colour):
                foregrounds = [foregrounds]
            elif len(foregrounds) != len(coords):
                raise ValueError('foregrounds and coords must have same length')
            if backgrounds is None:
                backgrounds = []
            elif isinstance(backgrounds, wx.Colour):
                backgrounds = [backgrounds]
            elif len(backgrounds) != len(coords):
                raise ValueError('backgrounds and coords must have same length')
            return  self._DrawTextList(textList, coords, foregrounds, backgrounds)
            """)

    #-----------------------------------------------------------------
    c = module.find('wxDCClipper')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCBrushChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCPenChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCTextColourChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCFontChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #54
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/dataview.h>")

    for item in module.allItems():
        if hasattr(item, 'type') and 'wxVariant' in item.type:
            item.type = item.type.replace('wxVariant', 'wxDVCVariant')

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

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)
    c.addCppMethod('long', '__hash__', '()', """\
        return (long)self->GetID();
        """)
    c.addCppMethod('bool', '__eq__', '(wxDataViewItem* other)',
                   "return (self->GetID() == other->GetID());")
    c.addCppMethod('bool', '__ne__', '(wxDataViewItem* other)',
                   "return (self->GetID() != other->GetID());")
    c.addAutoProperties()

    module.addItem(
        tools.wxArrayWrapperTemplate('wxDataViewItemArray', 'wxDataViewItem',
                                     module))
    module.addPyCode("NullDataViewItem = DataViewItem()")

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

    c.find('~wxDataViewModel').ignore(False)

    c.find('AddNotifier.notifier').transfer = True
    c.find('RemoveNotifier.notifier').transferBack = True

    # Change the GetValue method to return the value instead of passing it
    # through a parameter for modification.
    c.find('GetValue.variant').out = True

    # The DataViewItemObjectMapper class helps map from data items to Python
    # objects, and is used as a base class of PyDataViewModel as a
    # convenience.
    module.addPyClass(
        'DataViewItemObjectMapper', ['object'],
        doc="""\
            This class provides a mechanism for mapping between Python objects and the
            :class:`DataViewItem` objects used by the :class:`DataViewModel` for tracking the items in
            the view. The ID used for the item is the id() of the Python object. Use
            :meth:`ObjectToItem` to create a :class:`DataViewItem` using a Python object as its ID,
            and use :meth:`ItemToObject` to fetch that Python object again later for a given
            :class:`DataViewItem`.

            By default a regular dictionary is used to implement the ID to object
            mapping. Optionally a WeakValueDictionary can be useful when there will be
            a high turnover of objects and mantaining an extra reference to the
            objects would be unwise.  If weak references are used then the objects
            associated with data items must be weak-referenceable.  (Things like
            stock lists and dictionaries are not.)  See :meth:`UseWeakRefs`.

            This class is used in :class:`PyDataViewModel` as a mixin for convenience.
            """,
        items=[
            PyFunctionDef('__init__',
                          '(self)',
                          body="""\
                    self.mapper = dict()
                    self.usingWeakRefs = False
                    """),
            PyFunctionDef(
                'ObjectToItem',
                '(self, obj)',
                doc=
                "Create a :class:`DataViewItem` for the object, and remember the ID-->obj mapping.",
                body="""\
                    import sys
                    oid = id(obj)
                    while oid > sys.maxsize:
                        # risk of conflict here... May need some more thought.
                        oid -= sys.maxsize
                    self.mapper[oid] = obj
                    return DataViewItem(oid)
                    """),
            PyFunctionDef(
                'ItemToObject',
                '(self, item)',
                doc="Retrieve the object that was used to create an item.",
                body="""\
                    oid = int(item.GetID())
                    return self.mapper[oid]
                    """),
            PyFunctionDef('UseWeakRefs',
                          '(self, flag)',
                          doc="""\
                    Switch to or from using a weak value dictionary for keeping the ID to
                    object map.""",
                          body="""\
                    if flag == self.usingWeakRefs:
                        return
                    if flag:
                        import weakref
                        newmap = weakref.WeakValueDictionary()
                    else:
                        newmap = dict()
                    newmap.update(self.mapper)
                    self.mapper = newmap
                    self.usingWeakRefs = flag
                    """),
        ])

    module.addPyClass(
        'PyDataViewModel', ['DataViewModel', 'DataViewItemObjectMapper'],
        doc=
        "A convenience class that is a :class:`DataViewModel` combined with an object mapper.",
        items=[
            PyFunctionDef('__init__',
                          '(self)',
                          body="""\
                    DataViewModel.__init__(self)
                    DataViewItemObjectMapper.__init__(self)
                    """)
        ])

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

    # Change the GetValueByRow method to return the value instead of passing
    # it through a parameter for modification.
    c.find('GetValueByRow.variant').out = True

    # declare implementations for base class virtuals
    c.addItem(
        etgtools.WigCode("""\
        virtual wxDataViewItem GetParent( const wxDataViewItem &item ) const;
        virtual bool IsContainer( const wxDataViewItem &item ) const;
        virtual void GetValue( wxDVCVariant &variant /Out/, const wxDataViewItem &item, unsigned int col ) const [void ( wxDVCVariant &variant, const wxDataViewItem &item, unsigned int col )];
        virtual bool SetValue( const wxDVCVariant &variant, const wxDataViewItem &item, unsigned int col );
        virtual bool GetAttr(const wxDataViewItem &item, unsigned int col, wxDataViewItemAttr &attr) const;
        virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const;
        virtual bool IsListModel() const;
        """))

    # Add some of the pure virtuals since there are undocumented
    # implementations of them in these classes. The others will need to be
    # implemented in Python classes derived from these.
    for name in ['wxDataViewIndexListModel', 'wxDataViewVirtualListModel']:
        c = module.find(name)

        c.addItem(
            etgtools.WigCode("""\
            virtual unsigned int GetRow(const wxDataViewItem& item) const;
            virtual unsigned int GetCount() const;
            virtual unsigned int GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const;
            """))

    # compatibility aliases
    module.addPyCode("""\
        PyDataViewIndexListModel = wx.deprecated(DataViewIndexListModel)
        PyDataViewVirtualListModel = wx.deprecated(DataViewVirtualListModel)
        """)

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

    def _fixupBoolGetters(method, sig):
        method.type = 'void'
        method.find('value').out = True
        method.find('value').type = 'wxDVCVariant&'
        method.cppSignature = sig

    c = module.find('wxDataViewRenderer')
    c.addPrivateCopyCtor()
    c.abstract = True
    c.addAutoProperties()
    c.find('GetView').ignore(False)

    # Change variant getters to return the value
    for name, sig in [
        ('GetValue', 'bool (wxVariant& value)'),
        ('GetValueFromEditorCtrl',
         'bool (wxWindow * editor, wxVariant& value)'),
    ]:
        _fixupBoolGetters(c.find(name), sig)

    m = c.find('SetValue')
    m.find('value').type = 'wxDVCVariant&'
    m.cppSignature = 'bool (const wxVariant& value)'

    c = module.find('wxDataViewCustomRenderer')
    m = c.find('GetValueFromEditorCtrl')
    _fixupBoolGetters(m, 'bool (wxWindow * editor, wxVariant& value)')

    # Change the virtual method handler code to follow the same pattern as the
    # tweaked public API, namely that the value is the return value instead of
    # an out parameter.
    m.virtualCatcherCode = """\
        PyObject *sipResObj = sipCallMethod(&sipIsErr, sipMethod, "D", editor, sipType_wxWindow, NULL);
        if (sipResObj == Py_None) {
            sipRes = false;
        } else {
            sipRes = true;
            sipParseResult(&sipIsErr, sipMethod, sipResObj, "H5", sipType_wxDVCVariant, &value);
        }
        """

    c.find('GetTextExtent').ignore(False)

    module.addPyCode("""\
        PyDataViewCustomRenderer = wx.deprecated(DataViewCustomRenderer,
                                                 "Use DataViewCustomRenderer instead")"""
                     )

    # Add the pure virtuals since there are undocumented implementations of
    # them in all these classes
    for name in [
            'wxDataViewTextRenderer',
            'wxDataViewIconTextRenderer',
            'wxDataViewProgressRenderer',
            'wxDataViewSpinRenderer',
            'wxDataViewToggleRenderer',
            'wxDataViewChoiceRenderer',
            #'wxDataViewChoiceByIndexRenderer',
            'wxDataViewDateRenderer',
            'wxDataViewBitmapRenderer',
    ]:
        c = module.find(name)
        c.addAutoProperties()

        c.addItem(
            etgtools.WigCode("""\
            virtual bool SetValue( const wxDVCVariant &value ) [bool (const wxVariant& value)];
            virtual void GetValue( wxDVCVariant &value /Out/ ) const [bool (wxVariant& value)];
            %Property(name=Value, get=GetValue, set=SetValue)
            """,
                             protection='public'))

    # The SpinRenderer has a few additional pure virtuals that need to be declared
    # since it derives from DataViewCustomRenderer
    c = module.find('wxDataViewSpinRenderer')
    c.addItem(
        etgtools.WigCode("""\
        virtual wxSize GetSize() const;
        virtual bool Render(wxRect cell, wxDC* dc, int state);
        """,
                         protection='public'))

    #-----------------------------------------------------------------
    c = module.find('wxDataViewColumn')
    for m in c.find('wxDataViewColumn').all():
        m.find('renderer').transfer = True

    # declare the virtuals from wxSettableHeaderColumn
    c.addItem(
        etgtools.WigCode("""\
        virtual void SetTitle(const wxString& title);
        virtual wxString GetTitle() const;
        virtual void SetBitmap(const wxBitmap& bitmap);
        virtual wxBitmap GetBitmap() const;
        virtual void SetWidth(int width);
        virtual int GetWidth() const;
        virtual void SetMinWidth(int minWidth);
        virtual int GetMinWidth() const;
        virtual void SetAlignment(wxAlignment align);
        virtual wxAlignment GetAlignment() const;
        virtual void SetFlags(int flags);
        virtual int GetFlags() const;
        virtual bool IsSortKey() const;
        virtual void SetSortOrder(bool ascending);
        virtual bool IsSortOrderAscending() const;

        virtual void SetResizeable(bool resizable);
        virtual void SetSortable(bool sortable);
        virtual void SetReorderable(bool reorderable);
        virtual void SetHidden(bool hidden);
        """))

    c.addAutoProperties()
    c.addProperty('Title', 'GetTitle', 'SetTitle')
    c.addProperty('Bitmap', 'GetBitmap', 'SetBitmap')
    c.addProperty('Width', 'GetWidth', 'SetWidth')
    c.addProperty('MinWidth', 'GetMinWidth', 'SetMinWidth')
    c.addProperty('Alignment', 'GetAlignment', 'SetAlignment')
    c.addProperty('Flags', 'GetFlags', 'SetFlags')
    c.addProperty('SortOrder', 'IsSortOrderAscending', 'SetSortOrder')

    #-----------------------------------------------------------------
    c = module.find('wxDataViewCtrl')
    tools.fixWindowClass(c)
    module.addGlobalStr('wxDataViewCtrlNameStr', c)

    c.find('AssociateModel.model').transfer = True
    c.find('AssociateModel').pyName = '_AssociateModel'
    c.addPyMethod('AssociateModel',
                  '(self, model)',
                  doc="""\
            Associates a :class:`DataViewModel` with the control.
            Ownership of the model object is passed to C++, however it
            is reference counted so it can be shared with other views.
            """,
                  body="""\
            import wx.siplib
            wasPyOwned = wx.siplib.ispyowned(model)
            self._AssociateModel(model)
            # Ownership of the python object has just been transferred to
            # C++, so DecRef the C++ instance associated with this python
            # reference.
            if wasPyOwned:
                model.DecRef()
            """)

    c.find('PrependColumn.col').transfer = True
    c.find('InsertColumn.col').transfer = True
    c.find('AppendColumn.col').transfer = True

    c.addPyMethod(
        'GetColumns',
        '(self)',
        doc="Returns a list of column objects.",
        body="return [self.GetColumn(i) for i in range(self.GetColumnCount())]"
    )

    c.find('GetSelections').ignore()
    c.addCppMethod('wxDataViewItemArray*',
                   'GetSelections',
                   '()',
                   isConst=True,
                   factory=True,
                   doc="Returns a list of the currently selected items.",
                   body="""\
            wxDataViewItemArray* selections = new wxDataViewItemArray;
            self->GetSelections(*selections);
            return selections;
            """)

    # Pythonize HitTest
    c.find('HitTest').ignore()
    c.addCppMethod('PyObject*',
                   'HitTest',
                   '(const wxPoint& point)',
                   isConst=True,
                   doc="""\
            HitTest(point) -> (item, col)\n
            Returns the item and column located at point, as a 2 element tuple.
            """,
                   body="""\
            wxDataViewItem*   item = new wxDataViewItem();;
            wxDataViewColumn* col = NULL;

            self->HitTest(*point, *item, col);

            wxPyThreadBlocker blocker;
            PyObject* value = PyTuple_New(2);
            PyObject* item_obj =
                wxPyConstructObject((void*)item, wxT("wxDataViewItem"), 1);   // owned
            PyObject* col_obj;
            if (col) {
                col_obj = wxPyConstructObject((void*)col, wxT("wxDataViewColumn"), 0);  // not owned
            } else {
                col_obj = Py_None;
                Py_INCREF(Py_None);
            }
            PyTuple_SET_ITEM(value, 0, item_obj);
            PyTuple_SET_ITEM(value, 1, col_obj);
            // PyTuple steals a reference, so we don't need to decref the items here
            return value;
            """)

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

    c.addProperty('EditCancelled', 'IsEditCancelled', 'SetEditCanceled')

    c.find('SetCache.from').name = 'from_'
    c.find('SetCache.to').name = 'to_'

    c.find('GetDataBuffer').ignore()
    c.addCppMethod('PyObject*',
                   'GetDataBuffer',
                   '()',
                   isConst=True,
                   doc="Gets the data buffer for a drop data transfer",
                   body="""\
            wxPyThreadBlocker blocker;
            return wxPyMakeBuffer(self->GetDataBuffer(), self->GetDataSize(), true);
            """)

    # TODO: SetDataBuffer

    c.find('SetDataObject.obj').transfer = True

    module.addPyCode("""\
        EVT_DATAVIEW_SELECTION_CHANGED         = wx.PyEventBinder( wxEVT_DATAVIEW_SELECTION_CHANGED, 1)
        EVT_DATAVIEW_ITEM_ACTIVATED            = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_ACTIVATED, 1)
        EVT_DATAVIEW_ITEM_COLLAPSED            = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_COLLAPSED, 1)
        EVT_DATAVIEW_ITEM_EXPANDED             = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_EXPANDED, 1)
        EVT_DATAVIEW_ITEM_COLLAPSING           = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_COLLAPSING, 1)
        EVT_DATAVIEW_ITEM_EXPANDING            = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_EXPANDING, 1)
        EVT_DATAVIEW_ITEM_START_EDITING        = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_START_EDITING, 1)
        EVT_DATAVIEW_ITEM_EDITING_STARTED      = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_EDITING_STARTED, 1)
        EVT_DATAVIEW_ITEM_EDITING_DONE         = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_EDITING_DONE, 1)
        EVT_DATAVIEW_ITEM_VALUE_CHANGED        = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, 1)
        EVT_DATAVIEW_ITEM_CONTEXT_MENU         = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, 1)
        EVT_DATAVIEW_COLUMN_HEADER_CLICK       = wx.PyEventBinder( wxEVT_DATAVIEW_COLUMN_HEADER_CLICK, 1)
        EVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK = wx.PyEventBinder( wxEVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, 1)
        EVT_DATAVIEW_COLUMN_SORTED             = wx.PyEventBinder( wxEVT_DATAVIEW_COLUMN_SORTED, 1)
        EVT_DATAVIEW_COLUMN_REORDERED          = wx.PyEventBinder( wxEVT_DATAVIEW_COLUMN_REORDERED, 1)
        EVT_DATAVIEW_ITEM_BEGIN_DRAG           = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, 1)
        EVT_DATAVIEW_ITEM_DROP_POSSIBLE        = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, 1)
        EVT_DATAVIEW_ITEM_DROP                 = wx.PyEventBinder( wxEVT_DATAVIEW_ITEM_DROP, 1)
        EVT_DATAVIEW_CACHE_HINT                = wx.PyEventBinder( wxEVT_DATAVIEW_CACHE_HINT, 1 )

        # deprecated wxEVT aliases
        wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED          = wxEVT_DATAVIEW_SELECTION_CHANGED
        wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED             = wxEVT_DATAVIEW_ITEM_ACTIVATED
        wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED             = wxEVT_DATAVIEW_ITEM_COLLAPSED
        wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED              = wxEVT_DATAVIEW_ITEM_EXPANDED
        wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING            = wxEVT_DATAVIEW_ITEM_COLLAPSING
        wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING             = wxEVT_DATAVIEW_ITEM_EXPANDING
        wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING         = wxEVT_DATAVIEW_ITEM_START_EDITING
        wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED       = wxEVT_DATAVIEW_ITEM_EDITING_STARTED
        wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE          = wxEVT_DATAVIEW_ITEM_EDITING_DONE
        wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED         = wxEVT_DATAVIEW_ITEM_VALUE_CHANGED
        wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU          = wxEVT_DATAVIEW_ITEM_CONTEXT_MENU
        wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK        = wxEVT_DATAVIEW_COLUMN_HEADER_CLICK
        wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK  = wxEVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK
        wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED              = wxEVT_DATAVIEW_COLUMN_SORTED
        wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED           = wxEVT_DATAVIEW_COLUMN_REORDERED
        wxEVT_COMMAND_DATAVIEW_CACHE_HINT                 = wxEVT_DATAVIEW_CACHE_HINT
        wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG            = wxEVT_DATAVIEW_ITEM_BEGIN_DRAG
        wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE         = wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE
        wxEVT_COMMAND_DATAVIEW_ITEM_DROP                  = wxEVT_DATAVIEW_ITEM_DROP
        """)

    #-----------------------------------------------------------------
    c = module.find('wxDataViewListCtrl')
    tools.fixWindowClass(c)

    c.find('GetStore').overloads = []

    c.find('AppendItem.values').type = 'const wxVariantVector&'
    c.find('PrependItem.values').type = 'const wxVariantVector&'
    c.find('InsertItem.values').type = 'const wxVariantVector&'

    c.find('GetValue.value').out = True

    for name in 'AppendColumn InsertColumn PrependColumn'.split():
        for m in c.find(name).all():
            m.find('column').transfer = True

    c = module.find('wxDataViewListStore')
    c.find('AppendItem.values').type = 'const wxVariantVector&'
    c.find('PrependItem.values').type = 'const wxVariantVector&'
    c.find('InsertItem.values').type = 'const wxVariantVector&'
    c.find('GetValueByRow.value').out = True
    c.addAutoProperties()

    #-----------------------------------------------------------------
    c = module.find('wxDataViewTreeCtrl')
    tools.fixWindowClass(c)
    c.find('GetStore').overloads = []

    c = module.find('wxDataViewTreeStore')
    c.addAutoProperties()
    tools.fixRefCountedClass(c)

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

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

    module.addHeaderCode('#include <wxpy_api.h>')
    module.addImport('_core')
    module.addImport('_xml')
    module.addPyCode('''\
    import wx
    ID_NONE = wx.ID_NONE  # Needed for some parameter defaults in this module
    ''',
                     order=10)
    module.addInclude(INCLUDES)

    module.addInitializerCode("""\
        wxXmlInitResourceModule();
        wxXmlResource::Get()->InitAllHandlers();
        """)

    module.addHeaderCode('#include <wx/xrc/xmlres.h>')
    module.addHeaderCode('#include <wx/fs_mem.h>')
    module.addHeaderCode('#include "wxpybuffer.h"')

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

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

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

    # Add a bit of code to the ctors to call InitAllHandlers(), for
    # compatibility with Classic
    for ctor in c.find('wxXmlResource').all():
        template = """\
        Py_BEGIN_ALLOW_THREADS
        sipCpp = new sipwxXmlResource({args});
        sipCpp->InitAllHandlers();
        Py_END_ALLOW_THREADS
        """
        if 'filemask' in ctor.argsString:
            args = '*filemask,flags,*domain'
        else:
            args = 'flags,*domain'
        ctor.setCppCode_sip(template.format(args=args))

    c.addPublic()
    c.addCppMethod(
        'bool',
        'LoadFromBuffer',
        '(wxPyBuffer* data)',
        doc=
        "Load the resource from a bytes string or other data buffer compatible object.",
        #protection='public',
        body="""\
            static int s_memFileIdx = 0;

            // Check for memory FS. If not present, load the handler:
            wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"),
                                       wxT("dummy data"));
            wxFileSystem fsys;
            wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));
            wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));
            if (f)
                delete f;
            else
                wxFileSystem::AddHandler(new wxMemoryFSHandler);

            // Now put the resource data into the memory FS
            wxString filename(wxT("XRC_resource/data_string_"));
            filename << s_memFileIdx;
            s_memFileIdx += 1;
            wxMemoryFSHandler::AddFile(filename, data->m_ptr, data->m_len);

            // Load the "file" into the resource object
            bool retval = self->Load(wxT("memory:") + filename );
            return retval;
            """)
    c.addPyCode(
        "XmlResource.LoadFromString = wx.deprecated(XmlResource.LoadFromBuffer, 'Use LoadFromBuffer instead')"
    )

    c.find('AddHandler.handler').transfer = True
    c.find('InsertHandler.handler').transfer = True
    c.find('Set.res').transfer = True
    c.find('Set').transferBack = True
    c.find('AddSubclassFactory.factory').transfer = True

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

    # un-ignore all the protected methods
    for item in c.allItems():
        if isinstance(item, etgtools.MethodDef):
            item.ignore(False)

    c.find('DoCreateResource').factory = True

    #-----------------------------------------------------------------
    module.addPyFunction(
        'EmptyXmlResource',
        '(flags=XRC_USE_LOCALE, domain="")',
        deprecated="Use :class:`xrc.XmlResource` instead",
        doc=
        'A compatibility wrapper for the XmlResource(flags, domain) constructor',
        body='return XmlResource(flags, domain)')

    module.addPyFunction(
        'XRCID',
        '(str_id, value_if_not_found=wx.ID_NONE)',
        doc=
        'Returns a numeric ID that is equivalent to the string ID used in an XML resource.',
        body='return XmlResource.GetXRCID(str_id, value_if_not_found)')

    module.addPyFunction(
        'XRCCTRL',
        '(window, str_id, *ignoreargs)',
        doc=
        'Returns the child window associated with the string ID in an XML resource.',
        body='return window.FindWindow(XRCID(str_id))')

    cls = ClassDef(name='wxXmlSubclassFactory',
                   briefDoc="",
                   items=[
                       MethodDef(name='wxXmlSubclassFactory', isCtor=True),
                       MethodDef(name='~wxXmlSubclassFactory', isDtor=True),
                       MethodDef(name='Create',
                                 type='wxObject*',
                                 isVirtual=True,
                                 isPureVirtual=True,
                                 factory=True,
                                 items=[
                                     ParamDef(type='const wxString&',
                                              name='className')
                                 ])
                   ])
    module.addItem(cls)

    module.addPyCode("""\
        # Create a factory for handling the subclass property of XRC's
        # object tag.  This factory will search for the specified
        # package.module.class and will try to instantiate it for XRC's
        # use.  The class must support instantiation with no parameters and
        # delayed creation of the UI widget (aka 2-phase create).

        def _my_import(name):
            try:
                mod = __import__(name)
            except ImportError:
                import traceback
                print(traceback.format_exc())
                raise
            components = name.split('.')
            for comp in components[1:]:
                mod = getattr(mod, comp)
            return mod

        class XmlSubclassFactory_Python(XmlSubclassFactory):
            def __init__(self):
                XmlSubclassFactory.__init__(self)

            def Create(self, className):
                assert className.find('.') != -1, "Module name must be specified!"
                mname = className[:className.rfind('.')]
                cname = className[className.rfind('.')+1:]
                module = _my_import(mname)
                klass = getattr(module, cname)
                inst = klass()
                return inst

        XmlResource.AddSubclassFactory(XmlSubclassFactory_Python())
        """)

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

    # Lots of the uses of wxDateTime_t have been changed to "unsigned short"
    # in the interface file, so lets go ahead and translate the rest of them
    # too so there will not be any "wxDateTime_t" in Phoenix confusingly
    # mixed with "unsigned short"s.
    #
    # Also add the class scope specifier to nested enum types for parameters
    # and return values.
    for item in module.allItems():
        if isinstance(
                item,
            (etgtools.FunctionDef, etgtools.ParamDef, etgtools.VariableDef)):
            typesMap = {
                'wxDateTime_t': 'unsigned short',
                'Month': 'wxDateTime::Month',
                'WeekDay': 'wxDateTime::WeekDay',
                'TZ': 'wxDateTime::TZ',
                'TimeZone': 'wxDateTime::TimeZone',
                'Tm': 'wxDateTime::Tm',
            }
            if item.type in typesMap:
                item.type = typesMap[item.type]

    # ignore the #define and add it as a Python alias instead
    module.find('wxInvalidDateTime').ignore()
    module.addPyCode('InvalidDateTime = DefaultDateTime')
    gs = module.addGlobalStr('wxDefaultDateTimeFormat',
                             module.find('wxInvalidDateTime'))
    module.addGlobalStr('wxDefaultTimeSpanFormat', gs)

    #---------------------------------------------
    # Tweaks for the wxDateTime class
    c = module.find('wxDateTime')
    assert isinstance(c, etgtools.ClassDef)
    c.allowAutoProperties = False
    tools.ignoreAllOperators(c)

    # Ignore ctors with unknown types or that have overload conflicts that
    # can't be distingished in Python
    ctor = c.find('wxDateTime')
    ctor.findOverload('time_t').ignore()
    ctor.findOverload('struct tm').ignore()
    ctor.findOverload('double jdn').ignore()
    ctor.findOverload('_SYSTEMTIME').ignore()
    ctor.findOverload('hour').ignore(
    )  # careful, the one we want to keep has an 'hour' param too

    # Add static factories for some of the ctors we ignored
    c.addCppMethod(
        'wxDateTime*',
        'FromTimeT',
        '(time_t timet)',
        factory=True,
        isStatic=True,
        doc=
        "Construct a :class:`DateTime` from a C ``time_t`` value, the number of seconds since the epoch.",
        body="return new wxDateTime(timet);")

    c.addCppMethod(
        'wxDateTime*',
        'FromJDN',
        '(double jdn)',
        factory=True,
        isStatic=True,
        doc="Construct a :class:`DateTime` from a Julian Day Number.\n\n"
        "By definition, the Julian Day Number, usually abbreviated as JDN, of a particular instant is the fractional number of days since 12 hours Universal Coordinated Time (Greenwich mean noon) on January 1 of the year -4712 in the Julian proleptic calendar.",
        body="return new wxDateTime(jdn);")

    c.addCppMethod(
        'wxDateTime*',
        'FromHMS',
        """(unsigned short hour,
            unsigned short minute=0,
            unsigned short second=0,
            unsigned short millisecond=0)""",
        factory=True,
        isStatic=True,
        doc=
        "Construct a :class:`DateTime` equal to :meth:`Today` () with the time set to the supplied parameters.",
        body="return new wxDateTime(hour, minute, second, millisecond);")

    c.addCppMethod(
        'wxDateTime*',
        'FromDMY',
        """(unsigned short day,
            wxDateTime::Month month,
            int year = Inv_Year,
            unsigned short hour=0,
            unsigned short minute=0,
            unsigned short second=0,
            unsigned short millisecond=0)""",
        factory=True,
        isStatic=True,
        doc="Construct a :class:`DateTime` using the supplied parameters.",
        body=
        "return new wxDateTime(day, month, year, hour, minute, second, millisecond);"
    )

    # and give them some simple wrappers for Classic compatibility
    module.addPyFunction(
        'DateTimeFromTimeT',
        '(timet)',
        doc="Compatibility wrapper for :meth:`DateTime.FromTimeT`",
        body="return DateTime.FromTimeT(timet)",
        deprecated='Use :meth:`DateTime.FromTimeT` instead.')
    module.addPyFunction(
        'DateTimeFromJDN',
        '(jdn)',
        doc="Compatibility wrapper for :meth:`DateTime.FromJDN`",
        body="return DateTime.FromJDN(jdn)",
        deprecated='Use :meth:`DateTime.FromJDN` instead.')
    module.addPyFunction(
        'DateTimeFromHMS',
        '(hour, minute=0, second=0, millisecond=0)',
        doc="Compatibility wrapper for :meth:`DateTime.FromHMS`",
        body="return DateTime.FromHMS(hour, minute, second, millisecond)",
        deprecated='Use :meth:`DateTime.FromHMS` instead.')
    module.addPyFunction(
        'DateTimeFromDMY',
        '(day, month, year=DateTime.Inv_Year, hour=0, minute=0, second=0, millisecond=0)',
        doc="Compatibility wrapper for :meth:`DateTime.FromDMY`",
        body=
        "return DateTime.FromDMY(day, month, year, hour, minute, second, millisecond)",
        deprecated='Use :meth:`DateTime.FromDMY` instead.')

    # Fixup similar conflicts in the Set method overloads
    c.find('Set').findOverload('struct tm').ignore()
    c.find('Set').renameOverload('Tm', 'SetTm')
    c.find('Set').renameOverload('time_t', 'SetTimeT')
    c.find('Set').renameOverload('double jdn', 'SetJDN')
    c.find('Set').renameOverload('hour', 'SetHMS')

    # Unknown parameter and return types
    c.find('SetFromMSWSysTime').ignore()
    c.find('GetAsMSWSysTime').ignore()

    # this overload is static, the other isn't.  Rename it?
    c.find('GetCentury').findOverload('year').ignore()

    c.find('GetNumberOfDays').ignore()
    c.find('GetTmNow').ignore()
    c.find('GetTmNow').ignore()

    # output the am/pm parameter values
    c.find('GetAmPmStrings.am').out = True
    c.find('GetAmPmStrings.pm').out = True

    # remove the const version of the overloaded Add's and Subtract's
    c.find('Add').findOverload('wxDateSpan', isConst=True).ignore()
    c.find('Add').findOverload('wxTimeSpan', isConst=True).ignore()
    c.find('Subtract').findOverload('wxDateSpan', isConst=True).ignore()
    c.find('Subtract').findOverload('wxTimeSpan', isConst=True).ignore()

    # Ignore the end parameter for the Parse*() methods, and provide
    # replacement implementations that don't need them. Change them to be
    # like they were in Classic, returning a -1 on failure, or the number of
    # characters parsed otherwise.
    def fixParseMethod(m, code):
        assert isinstance(m, etgtools.MethodDef)
        m.find('end').ignore()
        m.type = 'int'
        m.setCppCode(code)
        return m

    fixParseMethod(
        c.find('ParseDate'), """\
        wxString::const_iterator begin = date->begin();
        wxString::const_iterator end;
        if (! self->ParseDate(*date, &end))
            return -1;
        return end - begin;
        """)

    fixParseMethod(
        c.find('ParseDateTime'), """\
        wxString::const_iterator begin = datetime->begin();
        wxString::const_iterator end;
        if (! self->ParseDateTime(*datetime, &end))
            return -1;
        return end - begin;
        """)

    fixParseMethod(
        c.find('ParseTime'), """\
        wxString::const_iterator begin = time->begin();
        wxString::const_iterator end;
        if (! self->ParseTime(*time, &end))
            return -1;
        return end - begin;
        """)

    fixParseMethod(
        c.find('ParseRfc822Date'), """\
        wxString::const_iterator begin = date->begin();
        wxString::const_iterator end;
        if (! self->ParseRfc822Date(*date, &end))
            return -1;
        return end - begin;
        """)

    pf = c.find('ParseFormat')
    pf1 = fixParseMethod(
        pf.findOverload(
            'const wxString &date, const wxString &format, const wxDateTime &dateDef, wxString::'
        ), """\
        wxString::const_iterator begin = date->begin();
        wxString::const_iterator end;
        if (! self->ParseFormat(*date, *format, *dateDef, &end))
            return -1;
        return end - begin;
        """)

    pf2 = fixParseMethod(
        pf.findOverload(
            'const wxString &date, const wxString &format, wxString::'), """\
        wxString::const_iterator begin = date->begin();
        wxString::const_iterator end;
        if (! self->ParseFormat(*date, *format, &end))
            return -1;
        return end - begin;
        """)

    pf3 = fixParseMethod(
        pf.findOverload('const wxString &date, wxString::'), """\
        wxString::const_iterator begin = date->begin();
        wxString::const_iterator end;
        if (! self->ParseFormat(*date, &end))
            return -1;
        return end - begin;
        """)

    # Fiddle with the docstrings for ParseFormat to make them reflect the new
    # reality. The other Parse*() docs refer the reader to this one, so we
    # don't have to change all of them.

    # find the <simplesect kind="return"> node in the last paragraph
    para = pf1.detailedDoc[-1]
    elem = para.find("simplesect[@kind='return']")
    # it has a child paragraph containing the text we need to replace
    elem[
        0].text = '-1 if the parse failed, the number of characters parsed otherwise.'

    pf2.briefDoc = "This version of the :meth:`ParseFormat` method works the same, but with missing values filled in from :meth:`Today`."
    pf3.briefDoc = "This version uses \"%c\" as the format code, which is the same default used by :meth:`Format`."

    c.addPyMethod(
        '__repr__', '(self)', """\
        from six import PY2
        if self.IsValid():
            f = self.Format()
            if PY2: f = f.encode('utf-8')
            return '<wx.DateTime: "%s">' % f
        else:
            return '<wx.DateTime: \"INVALID\">'
        """)

    c.addPyMethod(
        '__str__', '(self)', """\
        from six import PY2
        if self.IsValid():
            f = self.Format()
            if PY2: f = f.encode('utf-8')
            return f
        else:
            return "INVALID DateTime"
        """)

    # use lowercase to avoid conflicts
    c.addProperty("day GetDay SetDay")
    c.addProperty("month GetMonth SetMonth")
    c.addProperty("year GetYear SetYear")
    c.addProperty("hour GetHour SetHour")
    c.addProperty("minute GetMinute SetMinute")
    c.addProperty("second GetSecond SetSecond")
    c.addProperty("millisecond GetMillisecond SetMillisecond")
    c.addProperty("JDN GetJDN SetJDN")

    c.addProperty("DayOfYear GetDayOfYear")
    c.addProperty("JulianDayNumber GetJulianDayNumber")
    c.addProperty("LastMonthDay GetLastMonthDay")
    c.addProperty("MJD GetMJD")
    c.addProperty("ModifiedJulianDayNumber GetModifiedJulianDayNumber")
    c.addProperty("RataDie GetRataDie")
    c.addProperty("Ticks GetTicks")
    c.addProperty("WeekOfMonth GetWeekOfMonth")
    c.addProperty("WeekOfYear GetWeekOfYear")

    c.addItem(
        etgtools.WigCode("""\
        bool operator<(const wxDateTime& dt) const;
        bool operator<=(const wxDateTime& dt) const;
        bool operator>(const wxDateTime& dt) const;
        bool operator>=(const wxDateTime& dt) const;
        bool operator==(const wxDateTime& dt) const;
        bool operator!=(const wxDateTime& dt) const;
        wxDateTime& operator+=(const wxTimeSpan& diff);
        wxDateTime operator+(const wxTimeSpan& ts) const;
        wxDateTime& operator-=(const wxTimeSpan& diff);
        wxDateTime operator-(const wxTimeSpan& ts) const;
        wxDateTime& operator+=(const wxDateSpan& diff);
        wxDateTime operator+(const wxDateSpan& ds) const;
        wxDateTime& operator-=(const wxDateSpan& diff);
        wxDateTime operator-(const wxDateSpan& ds) const;
        wxTimeSpan operator-(const wxDateTime& dt2) const;
        """))

    # Add some code to automatically convert from a Python datetime.date or a
    # datetime.datetime object
    c.convertFromPyObject = """\
        // Code to test a PyObject for compatibility with wxDateTime
        if (!sipIsErr) {
            if (sipCanConvertToType(sipPy, sipType_wxDateTime, SIP_NO_CONVERTORS))
                    return TRUE;
            if (wxPyDateTime_Check(sipPy) || wxPyDate_Check(sipPy))
                return TRUE;
            return FALSE;
        }

        // Code to convert a compatible PyObject to a wxDateTime
        if (wxPyDateTime_Check(sipPy)) {
            *sipCppPtr = wxPyDateTime_ToWxDateTime(sipPy);
            return sipGetState(sipTransferObj);
        }
        if (wxPyDate_Check(sipPy)) {
            *sipCppPtr = wxPyDate_ToWxDateTime(sipPy);
            return sipGetState(sipTransferObj);
        }
        // if we get this far then it must already be a wxDateTime instance
        *sipCppPtr = reinterpret_cast<wxDateTime*>(sipConvertToType(
                sipPy, sipType_wxDateTime, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));

        return 0;  // Not a new instance
        """

    #---------------------------------------------
    # Tweaks for the wxDateSpan class
    c = module.find('wxDateSpan')
    c.allowAutoProperties = False
    tools.ignoreAllOperators(c)

    c.find('Add').findOverload('', isConst=True).ignore()
    c.find('Multiply').findOverload('', isConst=True).ignore()
    c.find('Subtract').findOverload('', isConst=True).ignore()

    c.addItem(
        etgtools.WigCode("""\
        wxDateSpan& operator+=(const wxDateSpan& other);
        wxDateSpan operator+(const wxDateSpan& ds) const;
        wxDateSpan& operator-=(const wxDateSpan& other);
        wxDateSpan operator-(const wxDateSpan& ds) const;
        wxDateSpan& operator-();
        wxDateSpan& operator*=(int factor);
        wxDateSpan operator*(int n) const;
        bool operator==(const wxDateSpan& ds) const;
        bool operator!=(const wxDateSpan& ds) const;
        """))

    #---------------------------------------------
    # Tweaks for the wxTimeSpan class
    c = module.find('wxTimeSpan')
    c.allowAutoProperties = False
    tools.ignoreAllOperators(c)

    c.find('Add').findOverload('', isConst=True).ignore()
    c.find('Multiply').findOverload('', isConst=True).ignore()
    c.find('Subtract').findOverload('', isConst=True).ignore()

    c.addItem(
        etgtools.WigCode("""\
        wxTimeSpan& operator+=(const wxTimeSpan& diff);
        wxTimeSpan operator+(const wxTimeSpan& ts) const;
        wxTimeSpan& operator-=(const wxTimeSpan& diff);
        wxTimeSpan operator-(const wxTimeSpan& ts);
        wxTimeSpan& operator*=(int n);
        wxTimeSpan operator*(int n) const;
        wxTimeSpan& operator-();
        bool operator<(const wxTimeSpan &ts) const;
        bool operator<=(const wxTimeSpan &ts) const;
        bool operator>(const wxTimeSpan &ts) const;
        bool operator>=(const wxTimeSpan &ts) const;
        bool operator==(const wxTimeSpan &ts) const;
        bool operator!=(const wxTimeSpan &ts) const;
        """))

    #---------------------------------------------
    # Convert to/from Python date objects
    module.addPyFunction(
        'pydate2wxdate',
        '(date)',
        doc='Convert a Python date or datetime to a :class:`DateTime` object',
        body="""\
            import datetime
            assert isinstance(date, (datetime.datetime, datetime.date))
            return DateTime(date)  # the built-in typemap will convert it for us
        """)

    module.addPyFunction(
        'wxdate2pydate',
        '(date)',
        doc='Convert a :class:`DateTime` object to a Python datetime.',
        body="""\
            import datetime
            assert isinstance(date, DateTime)
            if date.IsValid():
                return datetime.datetime(date.year, date.month+1, date.day,
                                         date.hour, date.minute, date.second, date.millisecond*1000)
            else:
                return None
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #57
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/gdicmn.h>')

    def markCreateFactories(klass):
        """Mark all Create methods as factories"""
        for func in klass.allItems():
            if isinstance(func, etgtools.FunctionDef) \
               and func.name.startswith('Create') \
               and '*' in func.type:
                func.factory = True

    #---------------------------------------------
    c = module.find('wxGraphicsObject')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    c.addCppMethod('bool', 'IsOk', '()', 'return !self->IsNull();')
    c.addCppMethod('int', '__nonzero__', '()', "return !self->IsNull();")
    c.addCppMethod('int', '__bool__', '()', "return !self->IsNull();")

    #---------------------------------------------
    c = module.find('wxGraphicsContext')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.abstract = True
    c.mustHaveApp()

    c.addCppMethod('wxGraphicsContext*',
                   'Create',
                   '(wxAutoBufferedPaintDC* autoPaintDC /KeepReference/)',
                   pyArgsString='(autoPaintDC) -> GraphicsContext',
                   isStatic=True,
                   body="""\
            return wxGraphicsContext::Create(*autoPaintDC);
            """)

    m = c.find('Create').findOverload('wxEnhMetaFileDC')
    m.find('metaFileDC').type = 'const wxMetafileDC&'
    m.argsString = '(const wxMetafileDC& metaFileDC)'
    m.setCppCode("""\
        #ifdef __WXMSW__
        #if wxUSE_ENH_METAFILE
            return wxGraphicsContext::Create(*metaFileDC);
        #endif
        #endif
            wxPyRaiseNotImplemented();
            return NULL;
        """)

    markCreateFactories(c)

    # Ensure that the target DC or image passed to Create lives as long as the
    # GC does. NOTE: Since the Creates are static methods there is no self to
    # associate the extra reference with, but since they are factories then
    # that extra reference will be held by the return value of the factory
    # instead.
    for m in c.find('Create').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True

    c.find('GetSize.width').out = True
    c.find('GetSize.height').out = True
    c.find('GetDPI.dpiX').out = True
    c.find('GetDPI.dpiY').out = True

    m = c.find('GetPartialTextExtents')
    m.find('widths').ignore()
    m.type = 'wxArrayDouble*'
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayDouble rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayDouble(rval);
        """)

    m = c.find('GetTextExtent')
    m.pyName = 'GetFullTextExtent'
    m.find('width').out = True
    m.find('height').out = True
    m.find('descent').out = True
    m.find('externalLeading').out = True

    c.addCppMethod(
        'PyObject*',
        'GetTextExtent',
        '(const wxString& text)',
        pyArgsString="(text) -> (width, height)",
        doc=
        "Gets the dimensions of the string using the currently selected font.",
        body="""\
        wxDouble width = 0.0, height = 0.0;
        self->GetTextExtent(*text, &width, &height, NULL, NULL);
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(dd)", width, height);
        """)

    c.addPyCode(
        "GraphicsContext.DrawRotatedText = wx.deprecated(GraphicsContext.DrawText, 'Use DrawText instead.')"
    )

    c.addCppCode(
        tools.ObjArrayHelperTemplate(
            'wxPoint2D', 'sipType_wxPoint2DDouble',
            "Expected a sequence of length-2 sequences or wx.Point2D objects.")
    )

    # we'll reimplement this overload as StrokeLineSegments
    c.find('StrokeLines').findOverload('beginPoints').ignore()
    c.addCppMethod('void',
                   'StrokeLineSegments',
                   '(PyObject* beginPoints, PyObject* endPoints)',
                   pyArgsString="(beginPoint2Ds, endPoint2Ds)",
                   doc="Stroke disconnected lines from begin to end points.",
                   body="""\
        size_t c1, c2, count;
        wxPoint2D* beginP = wxPoint2D_array_helper(beginPoints, &c1);
        wxPoint2D* endP =   wxPoint2D_array_helper(endPoints, &c2);

        if ( beginP != NULL && endP != NULL ) {
            count = wxMin(c1, c2);
            self->StrokeLines(count, beginP, endP);
        }
        delete [] beginP;
        delete [] endP;
        """)

    # Also reimplement the main StrokeLines method to reuse the same helper
    # function as StrokeLineSegments
    m = c.find('StrokeLines').findOverload('points').ignore()
    c.addCppMethod('void',
                   'StrokeLines',
                   '(PyObject* points)',
                   pyArgsString="(point2Ds)",
                   doc="Stroke lines connecting all the points.",
                   body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->StrokeLines(count, ptsArray);
            delete [] ptsArray;
        }
        """)

    # and once more for DrawLines
    m = c.find('DrawLines').ignore()
    c.addCppMethod(
        'void',
        'DrawLines',
        '(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)',
        pyArgsString="(point2Ds, fillStyle=ODDEVEN_RULE)",
        doc="Draws a polygon.",
        body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->DrawLines(count, ptsArray, fillStyle);
            delete [] ptsArray;
        }
        """)

    # TODO: support this?
    c.find('CreateFromNativeHDC').ignore()

    #---------------------------------------------
    c = module.find('wxGraphicsPath')
    tools.removeVirtuals(c)
    c.find('GetBox').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.find('GetCurrentPoint').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.mustHaveApp()

    c.find('GetNativePath').setCppCode("""\
        if (self->IsNull())
            return (void*)0;
        return self->GetNativePath();
        """)

    #---------------------------------------------
    c = module.find('wxGraphicsRenderer')
    tools.removeVirtuals(c)
    markCreateFactories(c)
    c.abstract = True

    # The KeepReference annotation doesn't work for us in this case, as it will
    # hold the reference in the renderer object, but it is better to hold the
    # reference in the returned context object instead. Otherwise there is still
    # some possibility that the held DC will be destroyed before the context.
    c.addPyCode("""\
        def _ctx_hold_ref(f):
            from functools import wraps
            @wraps(f)
            def wrapper(self, obj):
                ctx = f(self, obj)
                if ctx is not None:
                    ctx._obj = obj
                return ctx
            return wrapper
        GraphicsRenderer.CreateContext = _ctx_hold_ref(GraphicsRenderer.CreateContext)
        GraphicsRenderer.CreateContextFromImage = _ctx_hold_ref(GraphicsRenderer.CreateContextFromImage)
        GraphicsRenderer.CreateContextFromUnknownDC = _ctx_hold_ref(GraphicsRenderer.CreateContextFromUnknownDC)
        """)

    # TODO: support this?
    c.find('CreateContext').findOverload('wxEnhMetaFileDC').ignore()

    # TODO: support this?
    c.find('CreateContextFromNativeHDC').ignore()

    c.addPyMethod('GetType',
                  '(self)',
                  doc="Returns the name of the GraphicsRenderer class.",
                  body="return self.GetClassInfo().GetClassName()")

    c.find('GetGDIPlusRenderer').ignore()
    c.addCppMethod('wxGraphicsRenderer*',
                   'GetGDIPlusRenderer',
                   '()',
                   isStatic=True,
                   doc="Returns GDI+ renderer (MSW only).",
                   body="""\
            #ifdef __WXMSW__
                return wxGraphicsRenderer::GetGDIPlusRenderer();
            #else
                return NULL;
            #endif
            """)

    c.find('GetDirect2DRenderer').ignore()
    c.addCppMethod('wxGraphicsRenderer*',
                   'GetDirect2DRenderer',
                   '()',
                   isStatic=True,
                   doc="Returns Direct2D renderer (MSW and Python3 only).",
                   body="""\
            #if wxUSE_GRAPHICS_DIRECT2D
                return wxGraphicsRenderer::GetDirect2DRenderer();
            #else
                return NULL;
            #endif
            """)

    #---------------------------------------------
    c = module.find('wxGraphicsMatrix')
    tools.removeVirtuals(c)
    c.mustHaveApp()

    c.find('Concat').overloads = []
    c.find('IsEqual').overloads = []

    c.find('Get.a').out = True
    c.find('Get.b').out = True
    c.find('Get.c').out = True
    c.find('Get.d').out = True
    c.find('Get.tx').out = True
    c.find('Get.ty').out = True

    c.find('TransformDistance.dx').inOut = True
    c.find('TransformDistance.dy').inOut = True

    c.find('TransformPoint.x').inOut = True
    c.find('TransformPoint.y').inOut = True

    c.find('GetNativeMatrix').setCppCode("""\
        if (self->IsNull())
            return (void*)0;
        return self->GetNativeMatrix();
        """)

    #---------------------------------------------
    c = module.find('wxGraphicsGradientStops')
    c.addCppMethod('SIP_SSIZE_T',
                   '__len__',
                   '()',
                   body="return (SIP_SSIZE_T)self->GetCount();")
    c.addCppMethod('wxGraphicsGradientStop*',
                   '__getitem__',
                   '(ulong n)',
                   pyArgsString='(n)',
                   body="return new wxGraphicsGradientStop(self->Item(n));",
                   factory=True)

    #---------------------------------------------
    c = module.find('wxGraphicsBitmap')
    c.find('GetNativeBitmap').setCppCode("""\
        if (self->IsNull())
            return (void*)0;
        return self->GetNativeBitmap();
        """)

    #---------------------------------------------
    c = module.find('wxGraphicsPenInfo')
    # Ignore Dashes for now
    # TODO: we need to do something like wx.Pen.SetDashes, but since
    # GraphicsPenInfo is transitory we can't save the reference in it to the
    # holder, and the pen will not have been created yet...
    c.find('Dashes').ignore()
    c.find('GetDashes').ignore()
    c.find('GetDashCount').ignore()
    c.find('GetDash').ignore()

    #---------------------------------------------
    # Use the pyNames we set for these classes in geometry.py so the old
    # names do not show up in the docstrings, etc.
    tools.changeTypeNames(module, 'wxPoint2DDouble', 'wxPoint2D')
    tools.changeTypeNames(module, 'wxRect2DDouble', 'wxRect2D')

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

    # do not use the va_list forms of the functions
    for func in module.allItems():
        if 'wxVLog' in func.name:
            func.ignore()

    for f in module.find('wxLogTrace').all(): # deprecated in 2.8
        f.ignore()

    # Switch the parameters to wxStrings to capitalize on the conversion code
    # we already have for them. String formatting can be done in Python if
    # needed. Drop the '...' too.
    for name in ['wxLogMessage', 'wxLogVerbose', 'wxLogWarning', 'wxLogFatalError',
                 'wxLogError', 'wxLogDebug', 'wxLogStatus', 'wxLogSysError',
                 'wxLogGeneric']:
        for f in module.find(name).all():
            p = f.find('formatString')
            p.type = 'const wxString&'
            p.name = 'message'
            f.items = f.items[:-1]

    module.find('wxSysErrorMsg').type = 'wxString'

    c = module.find('wxLogRecordInfo')
    c.find('threadId').ignore()


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

    c.find('SetActiveTarget').transferBack = True
    c.find('SetActiveTarget.logtarget').transfer = True
    c.find('SetThreadActiveTarget').transferBack = True
    c.find('SetThreadActiveTarget.logger').transfer = True

    # we need to un-ignore these protected methods as they need to be overridable
    c.find('DoLogRecord').ignore(False)
    c.find('DoLogTextAtLevel').ignore(False)
    c.find('DoLogText').ignore(False)


    c = module.find('wxLogStderr')
    c.find('wxLogStderr.fp').ignore()
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()


    c = module.find('wxLogBuffer')
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()

    c = module.find('wxLogChain')
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()

    c = module.find('wxLogGui')
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()

    c = module.find('wxLogTextCtrl')
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()



    c = module.find('wxLogFormatter')
    c.find('FormatTime').ignore(False)


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

    # Use wxPyUserData for the clientData values instead of a plain wxObject
    def _fixClientData(c):
        for item in c.allItems():
            if isinstance(item,
                          etgtools.ParamDef) and item.name == 'clientData':
                item.type = 'wxPyUserData*'
                item.transfer = True

    #---------------------------------------------
    c = module.find('wxToolBarToolBase')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)
    _fixClientData(c)

    # Switch all wxToolBarBase to wxToolBar
    for item in c.allItems():
        if isinstance(item, etgtools.ParamDef) and item.name == 'tbar':
            item.type = 'wxToolBar*'

    c.find('GetToolBar').ignore()
    c.addCppMethod('wxToolBar*',
                   'GetToolBar',
                   '()',
                   doc="Return the toolbar this tool is a member of.",
                   body="""\
            return (wxToolBar*)self->GetToolBar();
            """)

    gcd = c.find('GetClientData')
    gcd.type = 'wxPyUserData*'
    gcd.setCppCode(
        'return dynamic_cast<wxPyUserData*>(self->GetClientData());')

    #---------------------------------------------
    c = module.find('wxToolBar')
    tools.fixWindowClass(c)
    _fixClientData(c)
    c.find('SetBitmapResource').ignore()
    module.addGlobalStr('wxToolBarNameStr', c)

    gcd = c.find('GetToolClientData')
    gcd.type = 'wxPyUserData*'
    gcd.setCppCode(
        'return dynamic_cast<wxPyUserData*>(self->GetToolClientData(toolId));')

    c.find('AddTool.tool').transfer = True
    c.find('InsertTool.tool').transfer = True

    c.find('OnLeftClick').ignore()
    c.find('OnMouseEnter').ignore()
    c.find('OnRightClick').ignore()
    c.find('OnLeftClick').ignore()

    # Add some deprecated methods to aid with Classic compatibility.
    # TODO: Which others are commonly enough used that they should be here too?
    c.addPyMethod(
        'AddSimpleTool',
        '(self, toolId, bitmap, shortHelpString="", longHelpString="", isToggle=0)',
        doc='Old style method to add a tool to the toolbar.',
        deprecated='Use :meth:`AddTool` instead.',
        body="""\
            kind = wx.ITEM_NORMAL
            if isToggle: kind = wx.ITEM_CHECK
            return self.AddTool(toolId, '', bitmap, wx.NullBitmap, kind,
                                shortHelpString, longHelpString)
            """)
    c.addPyMethod(
        'AddLabelTool',
        '(self, id, label, bitmap, bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL,'
        ' shortHelp="", longHelp="", clientData=None)',
        doc='Old style method to add a tool in the toolbar.',
        deprecated='Use :meth:`AddTool` instead.',
        body="""\
            return self.AddTool(id, label, bitmap, bmpDisabled, kind,
                                shortHelp, longHelp, clientData)
            """)

    c.addPyMethod(
        'InsertSimpleTool',
        '(self, pos, toolId, bitmap, shortHelpString="", longHelpString="", isToggle=0)',
        doc='Old style method to insert a tool in the toolbar.',
        deprecated='Use :meth:`InsertTool` instead.',
        body="""\
            kind = wx.ITEM_NORMAL
            if isToggle: kind = wx.ITEM_CHECK
            return self.InsertTool(pos, toolId, '', bitmap, wx.NullBitmap, kind,
                                   shortHelpString, longHelpString)
            """)
    c.addPyMethod(
        'InsertLabelTool',
        '(self, pos, id, label, bitmap, bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL,'
        ' shortHelp="", longHelp="", clientData=None)',
        doc='Old style method to insert a tool in the toolbar.',
        deprecated='Use :meth:`InsertTool` instead.',
        body="""\
            return self.InsertTool(pos, id, label, bitmap, bmpDisabled, kind,
                                   shortHelp, longHelp, clientData)
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Beispiel #60
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('wxMask')
    c.mustHaveApp()
    for m in c.find('Create').all():
        m.ignore()

    c = module.find('wxBitmap')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    tools.removeVirtuals(c)

    # TODO: The wxCursor version of the ctor is not implemented on OSX...
    c.find('wxBitmap').findOverload('wxCursor').ignore()

    c.find('wxBitmap.bits').type = 'const char*'
    c.find('wxBitmap.type').default = 'wxBITMAP_TYPE_ANY'
    c.find('LoadFile.type').default = 'wxBITMAP_TYPE_ANY'

    c.find('wxBitmap').findOverload('(const char *const *bits)').ignore()

    c.addCppCtor('(PyObject* listOfBytes)',
        doc="Construct a Bitmap from a list of strings formatted as XPM data.",
        body="""\
            wxPyThreadBlocker blocker;
            char**    cArray = NULL;
            int       count;
            char      errMsg[] = "Expected a list of bytes objects.";

            if (!PyList_Check(listOfBytes)) {
                PyErr_SetString(PyExc_TypeError, errMsg);
                return NULL;
            }
            count = PyList_Size(listOfBytes);
            cArray = new char*[count];

            for(int x=0; x<count; x++) {
                PyObject* item = PyList_GET_ITEM(listOfBytes, x);
                if (!PyBytes_Check(item)) {
                    PyErr_SetString(PyExc_TypeError, errMsg);
                    delete [] cArray;
                    return NULL;
                }
                cArray[x] = PyBytes_AsString(item);
            }
            wxBitmap* bmp = new wxBitmap(cArray);
            delete [] cArray;
            return bmp;
            """)


    c.find('SetMask.mask').transfer = True

    c.addCppMethod('void', 'SetMaskColour', '(const wxColour& colour)',
        doc="Create a mask for this bitmap based on the pixels with the given colour.",
        body="""\
        wxMask* mask = new wxMask(*self, *colour);
        self->SetMask(mask);
        """)

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addCppMethod('long', 'GetHandle', '()',
        doc='MSW-only method to fetch the windows handle for the bitmap.',
        body="""\
            #ifdef __WXMSW__
                return (long)self->GetHandle();
            #else
                return 0;
            #endif
            """)

    c.addCppMethod('void', 'SetHandle', '(long handle)',
        doc='MSW-only method to set the windows handle for the bitmap.',
        body="""\
            #ifdef __WXMSW__
                self->SetHandle((WXHANDLE)handle);
            #endif
            """)

    c.addCppMethod('void', 'SetSize', '(const wxSize& size)',
        doc='Set the bitmap size (does not alter the existing native bitmap data or image size).',
        body="""\
            self->SetWidth(size->x);
            self->SetHeight(size->y);
            """)



    # On MSW the bitmap handler classes are different than what is
    # documented, and this causes compile errors. Nobody has needed them from
    # Python thus far, so just ignore them all for now.
    for m in c.find('FindHandler').all():
        m.ignore()
    c.find('AddHandler').ignore()
    c.find('CleanUpHandlers').ignore()
    c.find('GetHandlers').ignore()
    c.find('InsertHandler').ignore()
    c.find('RemoveHandler').ignore()

    # This one is called from the wx startup code, it's not needed in Python
    # so nuke it too since we're nuking all the others.
    c.find('InitStandardHandlers').ignore()

    module.find('wxBitmapHandler').ignore()
    #module.addItem(tools.wxListWrapperTemplate('wxList', 'wxBitmapHandler', module))


    #-----------------------------------------------------------------------
    # Declarations, helpers and methods for converting to/from buffer objects
    # with raw bitmap access.

    from etgtools import EnumDef, EnumValueDef
    e = EnumDef(name='wxBitmapBufferFormat')
    e.items.extend([ EnumValueDef(name='wxBitmapBufferFormat_RGB'),
                     EnumValueDef(name='wxBitmapBufferFormat_RGBA'),
                     EnumValueDef(name='wxBitmapBufferFormat_RGB32'),
                     EnumValueDef(name='wxBitmapBufferFormat_ARGB32'),
                     ])
    module.insertItem(0, e)

    c.includeCppCode('src/bitmap_ex.cpp')
    module.addHeaderCode('#include "bitmap_ex.h"')


    c.addCppMethod('void', 'CopyFromBuffer',
        '(wxPyBuffer* data, wxBitmapBufferFormat format=wxBitmapBufferFormat_RGB, int stride=-1)',
        doc="""\
            Copy data from a buffer object to replace the bitmap pixel data.
            Default format is plain RGB, but other formats are now supported as
            well.  The following symbols are used to specify the format of the
            bytes in the buffer:

                =============================  ================================
                wx.BitmapBufferFormat_RGB      A simple sequence of RGB bytes
                wx.BitmapBufferFormat_RGBA     A simple sequence of RGBA bytes
                wx.BitmapBufferFormat_ARGB32   A sequence of 32-bit values in native endian order, with alpha in the upper 8 bits, followed by red, green, and blue.
                wx.BitmapBufferFormat_RGB32    Same as above but the alpha byte is ignored.
                =============================  ================================""",
        body="""\
            wxPyCopyBitmapFromBuffer(self, (byte*)data->m_ptr, data->m_len, format, stride);
        """)


    c.addCppMethod('void', 'CopyToBuffer',
        '(wxPyBuffer* data, wxBitmapBufferFormat format=wxBitmapBufferFormat_RGB, int stride=-1)',
        doc="""\
            Copy pixel data to a buffer object.  See :meth:`CopyFromBuffer` for buffer
            format details.""",
        body="""\
            wxPyCopyBitmapToBuffer(self, (byte*)data->m_ptr, data->m_len, format, stride);
            """)


    # Some bitmap factories added as static methods

    c.addCppMethod('wxBitmap*', 'FromBufferAndAlpha',
        '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`wx.Bitmap` from in-memory data.  The data and alpha
            parameters must be a Python object that implements the buffer
            interface, such as a string, bytearray, etc.  The data object
            is expected to contain a series of RGB bytes and be at least
            (width * height * 3) bytes long, while the alpha object is expected
            to be width*height bytes long and represents the image's alpha
            channel.  On Windows and Mac the RGB values will be
            'premultiplied' by the alpha values.  (The other platforms do
            the multiplication themselves.)

            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.
            """,
        body="""\
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return NULL;

            byte* ddata = (byte*)data->m_ptr;
            byte* adata = (byte*)alpha->m_ptr;
            wxBitmap* bmp = new wxBitmap(width, height, 32);

            wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
            if (! pixData) {
                wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data.");
                return NULL;
            }

            wxAlphaPixelData::Iterator p(pixData);
            for (int y=0; y<height; y++) {
                wxAlphaPixelData::Iterator rowStart = p;
                for (int x=0; x<width; x++) {
                    byte a = *(adata++);
                    p.Red()   = wxPy_premultiply(*(ddata++), a);
                    p.Green() = wxPy_premultiply(*(ddata++), a);
                    p.Blue()  = wxPy_premultiply(*(ddata++), a);
                    p.Alpha() = a;
                    ++p;
                }
                p = rowStart;
                p.OffsetY(pixData, 1);
            }
            return bmp;
            """)

    c.addCppMethod('wxBitmap*', 'FromBuffer', '(int width, int height, wxPyBuffer* data)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`wx.Bitmap` from in-memory data.  The data parameter
            must be a Python object that implements the buffer interface, such
            as a string, bytearray, etc.  The data object is expected to contain
            a series of RGB bytes and be at least (width * height * 3) bytes long.

            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.
            """,
        body="""\
            wxBitmap* bmp = new wxBitmap(width, height, 24);
            wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGB);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred()) {
                delete bmp;
                bmp = NULL;
            }
            return bmp;
            """)

    module.addPyFunction('BitmapFromBuffer', '(width, height, dataBuffer, alphaBuffer=None)',
        deprecated="Use :meth:`wx.Bitmap.FromBuffer` or :meth:`wx.Bitmap.FromBufferAndAlpha` instead.",
        doc='A compatibility wrapper for :meth:`wx.Bitmap.FromBuffer` and :meth:`wx.Bitmap.FromBufferAndAlpha`',
        body="""\
            if alphaBuffer is not None:
                return Bitmap.FromBufferAndAlpha(width, height, dataBuffer, alphaBuffer)
            else:
                return Bitmap.FromBuffer(width, height, dataBuffer)
            """)




    c.addCppMethod('wxBitmap*', 'FromBufferRGBA', '(int width, int height, wxPyBuffer* data)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`wx.Bitmap` from in-memory data.  The data parameter
            must be a Python object that implements the buffer interface, such
            as a string, bytearray, etc.  The data object is expected to contain
            a series of RGBA bytes and be at least (width * height * 4) bytes long.
            On Windows and Mac the RGB values will be 'premultiplied' by the
            alpha values.  (The other platforms do the multiplication themselves.)

            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.
            """,
        body="""\
            wxBitmap* bmp = new wxBitmap(width, height, 32);
            wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGBA);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred()) {
                delete bmp;
                bmp = NULL;
            }
            return bmp;
            """)

    module.addPyFunction('BitmapFromBufferRGBA', '(width, height, dataBuffer)',
        deprecated="Use :meth:`wx.Bitmap.FromBufferRGBA` instead.",
        doc='A compatibility wrapper for :meth:`wx.Bitmap.FromBufferRGBA`',
        body='return Bitmap.FromBufferRGBA(width, height, dataBuffer)')




    c.addCppMethod('wxBitmap*', 'FromRGBA',
        '(int width, int height, byte red=0, byte green=0, byte blue=0, byte alpha=0)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a new empty 32-bit :class:`wx.Bitmap` where every pixel has been
            initialized with the given RGBA values.
            """,
        body="""\
            if ( !(width > 0 && height > 0) ) {
                wxPyErr_SetString(PyExc_ValueError, "Width and height must be greater than zero");
                return NULL;
            }

            wxBitmap* bmp = new wxBitmap(width, height, 32);
            wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
            if (! pixData) {
                wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data.");
                return NULL;
            }

            wxAlphaPixelData::Iterator p(pixData);
            for (int y=0; y<height; y++) {
                wxAlphaPixelData::Iterator rowStart = p;
                for (int x=0; x<width; x++) {
                    p.Red()   = wxPy_premultiply(red, alpha);
                    p.Green() = wxPy_premultiply(green, alpha);
                    p.Blue()  = wxPy_premultiply(blue, alpha);
                    p.Alpha() = alpha;
                    ++p;
                }
                p = rowStart;
                p.OffsetY(pixData, 1);
            }
            return bmp;
            """)

    module.addPyFunction('EmptyBitmapRGBA', '(width, height, red=0, green=0, blue=0, alpha=0)',
        deprecated="Use :meth:`wx.Bitmap.FromRGBA` instead.",
        doc='A compatibility wrapper for :meth:`wx.Bitmap.FromRGBA`',
        body='return Bitmap.FromRGBA(width, height, red, green, blue, alpha)')

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

    # For compatibility:
    module.addPyFunction('EmptyBitmap', '(width, height, depth=BITMAP_SCREEN_DEPTH)',
                         deprecated="Use :class:`wx.Bitmap` instead",
                         doc='A compatibility wrapper for the wx.Bitmap(width, height, depth) constructor',
                         body='return Bitmap(width, height, depth)')

    module.addPyFunction('BitmapFromImage', '(image)',
                         deprecated="Use :class:`wx.Bitmap` instead",
                         doc='A compatibility wrapper for the wx.Bitmap(wx.Image) constructor',
                         body='return Bitmap(image)')

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