From aa1ef7bd75412191e7912855abdfdc1af1c70335 Mon Sep 17 00:00:00 2001 From: Scott Talbert Date: Thu, 14 Apr 2022 19:51:57 -0400 Subject: [PATCH] Update ETG scripts to support wxWidgets 3.1.6 functionality Fixes #2136. --- docs/sphinx/itemToModuleMap.json | 3 +- etg/_core.py | 2 + etg/_stc.py | 1 + etg/app.py | 3 + etg/bmpbndl.py | 58 +++++++++++++++++ etg/cursor.py | 1 + etg/dataview.py | 2 +- etg/defs.py | 3 + etg/event.py | 5 ++ etg/gdicmn.py | 3 + etg/htmlwin.py | 2 +- etg/icon.py | 3 + etg/listctrl.py | 4 ++ etg/menuitem.py | 9 ++- etg/richtextbuffer.py | 17 ++++- etg/textctrl.py | 11 ++++ etg/treectrl.py | 1 - etg/webview.py | 12 ++++ etgtools/tweaker_tools.py | 1 - src/wxvector.sip | 106 +++++++++++++++++++++++++++++++ 20 files changed, 238 insertions(+), 9 deletions(-) create mode 100644 etg/bmpbndl.py create mode 100644 src/wxvector.sip diff --git a/docs/sphinx/itemToModuleMap.json b/docs/sphinx/itemToModuleMap.json index 7cbd105e..80caca1c 100644 --- a/docs/sphinx/itemToModuleMap.json +++ b/docs/sphinx/itemToModuleMap.json @@ -2630,7 +2630,7 @@ "ObjectRefData":"wx.", "OperatingSystemId":"wx.", "Orientation":"wx.", -"Origin":"wx.grid.GridActivationSource.", +"Origin":"wx.HelpEvent.", "OutBottom":"wx.", "OutCode":"wx.", "OutLeft":"wx.", @@ -3582,6 +3582,7 @@ "RichTextImageBlock":"wx.richtext.", "RichTextLine":"wx.richtext.", "RichTextLineBreakChar":"wx.richtext.", +"RichTextLineVector":"wx.richtext.", "RichTextListStyleDefinition":"wx.richtext.", "RichTextModuleInit":"wx.richtext.", "RichTextObject":"wx.richtext.", diff --git a/etg/_core.py b/etg/_core.py index 9bf82d21..220c1371 100644 --- a/etg/_core.py +++ b/etg/_core.py @@ -49,6 +49,7 @@ INCLUDES = [ # base and core stuff 'userdata', 'wxpybuffer', 'msgdlg_btnlabel', + 'wxvector', 'stockgdi', 'longlong', @@ -76,6 +77,7 @@ INCLUDES = [ # base and core stuff 'image', 'gdiobj', 'bitmap', + 'bmpbndl', 'icon', 'iconloc', 'iconbndl', 'font', 'fontutil', diff --git a/etg/_stc.py b/etg/_stc.py index 50d38433..bcf8b55f 100644 --- a/etg/_stc.py +++ b/etg/_stc.py @@ -152,6 +152,7 @@ def run(): tc_excludes = ['OSXEnableAutomaticQuoteSubstitution', 'OSXEnableAutomaticDashSubstitution', 'OSXDisableAllSmartSubstitutions', + 'OSXEnableNewLineReplacement', ] import textctrl mod = textctrl.parseAndTweakModule() diff --git a/etg/app.py b/etg/app.py index ccb4cb6c..bd2ef2ae 100644 --- a/etg/app.py +++ b/etg/app.py @@ -10,6 +10,7 @@ import etgtools import etgtools.tweaker_tools as tools from etgtools import PyFunctionDef, PyCodeDef, PyPropertyDef +import sys PACKAGE = "wx" MODULE = "_core" @@ -206,6 +207,8 @@ def run(): c.addProperty('UseBestVisual GetUseBestVisual SetUseBestVisual') c.addProperty('TopWindow GetTopWindow SetTopWindow') + if sys.platform != 'linux': + c.find('GTKSuppressDiagnostics').ignore() #------------------------------------------------------- diff --git a/etg/bmpbndl.py b/etg/bmpbndl.py new file mode 100644 index 00000000..a166b576 --- /dev/null +++ b/etg/bmpbndl.py @@ -0,0 +1,58 @@ +#--------------------------------------------------------------------------- +# Name: etg/bmpbndl.py +# Author: Scott Talbert +# +# Created: 13-Apr-2022 +# Copyright: (c) 2022 by Scott Talbert +# License: wxWindows License +#--------------------------------------------------------------------------- + +import etgtools +import etgtools.tweaker_tools as tools +from etgtools import MethodDef + +PACKAGE = "wx" +MODULE = "_core" +NAME = "bmpbndl" # Base name of the file to generate to for this script +DOCSTRING = "" + +# The classes and/or the basename of the Doxygen XML files to be processed by +# this script. +ITEMS = [ 'wxBitmapBundle', + 'wxBitmapBundleImpl', + ] + +#--------------------------------------------------------------------------- + +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 ') + + c = module.find('wxBitmapBundle') + assert isinstance(c, etgtools.ClassDef) + + c.find('FromSVG').findOverload('char *data, const wxSize &sizeDef').ignore() + + + c = module.find('wxBitmapBundleImpl') + assert isinstance(c, etgtools.ClassDef) + + m = MethodDef(name='~wxBitmapBundleImpl', isDtor=True, isVirtual=True, protection='protected') + c.addItem(m) + + #----------------------------------------------------------------- + tools.doCommonTweaks(module) + tools.runGenerators(module) + + +#--------------------------------------------------------------------------- +if __name__ == '__main__': + run() + diff --git a/etg/cursor.py b/etg/cursor.py index 5e221fe9..f957358b 100644 --- a/etg/cursor.py +++ b/etg/cursor.py @@ -45,6 +45,7 @@ def run(): c.find('wxCursor').findOverload('cursorName').find('type').default='wxBITMAP_TYPE_ANY' # TODO: This ctor ^^ in Classic has a custom implementation for wxGTK that # sets the hotspot. Is that still needed? + c.find('wxCursor').findOverload('(const char *const *xpmData)').ignore() c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();") c.addCppMethod('int', '__bool__', '()', "return self->IsOk();") diff --git a/etg/dataview.py b/etg/dataview.py index 80eade26..fdfb4e1a 100644 --- a/etg/dataview.py +++ b/etg/dataview.py @@ -344,7 +344,7 @@ def run(): c.addItem(etgtools.WigCode("""\ virtual void SetTitle(const wxString& title); virtual wxString GetTitle() const; - virtual void SetBitmap(const wxBitmap& bitmap); + virtual void SetBitmap(const wxBitmapBundle& bitmap); virtual wxBitmap GetBitmap() const; virtual void SetWidth(int width); virtual int GetWidth() const; diff --git a/etg/defs.py b/etg/defs.py index 167e0726..4445cf93 100644 --- a/etg/defs.py +++ b/etg/defs.py @@ -110,6 +110,9 @@ def run(): module.addPyCode("ADJUST_MINSIZE = 0") module.addPyCode("WS_EX_VALIDATE_RECURSIVELY = 0") + # This is only supported with C++14, so ignore it for now + module.find('wxDEPRECATED_ATTR').ignore() + #----------------------------------------------------------------- tools.doCommonTweaks(module) diff --git a/etg/event.py b/etg/event.py index 4a5c30e1..5f79d888 100644 --- a/etg/event.py +++ b/etg/event.py @@ -100,6 +100,11 @@ def run(): #endif """) + # Missing in 3.1.6 + module.addItem(etgtools.WigCode("""\ + wxEventType wxEVT_FULLSCREEN /PyName=wxEVT_FULLSCREEN/; + """)) + module.addPyClass('PyEventBinder', ['object'], doc="""\ diff --git a/etg/gdicmn.py b/etg/gdicmn.py index 04ca3693..f182266a 100644 --- a/etg/gdicmn.py +++ b/etg/gdicmn.py @@ -155,6 +155,9 @@ def run(): c.find('operator*=').all() + \ c.find('operator/=').all(): f.ignore(False) + # Ignore these because they conflict with __imul__() and __itruediv__() + c.find('operator*=').findOverload('double').ignore() + c.find('operator/=').findOverload('double').ignore() c.addCppMethod('bool', '__eq__', '(const wxSize& other)', body="return *self == *other;") diff --git a/etg/htmlwin.py b/etg/htmlwin.py index 1023e751..fd902921 100644 --- a/etg/htmlwin.py +++ b/etg/htmlwin.py @@ -73,7 +73,7 @@ def run(): virtual wxWindow* GetHTMLWindow(); virtual wxColour GetHTMLBackgroundColour() const; virtual void SetHTMLBackgroundColour(const wxColour& clr); - virtual void SetHTMLBackgroundImage(const wxBitmap& bmpBg); + virtual void SetHTMLBackgroundImage(const wxBitmapBundle& bmpBg); virtual void SetHTMLStatusText(const wxString& text); virtual wxCursor GetHTMLCursor(wxHtmlWindowInterface::HTMLCursor type) const; """)) diff --git a/etg/icon.py b/etg/icon.py index 2733ddd6..6b1faf23 100644 --- a/etg/icon.py +++ b/etg/icon.py @@ -79,6 +79,9 @@ def run(): #endif """) + # Documented wrongly in 3.1.6 + c.find('GetLogicalSize').type = 'wxSize' + # For compatibility: module.addPyFunction('EmptyIcon', '()', diff --git a/etg/listctrl.py b/etg/listctrl.py index d25171da..6362b866 100644 --- a/etg/listctrl.py +++ b/etg/listctrl.py @@ -333,6 +333,10 @@ def run(): #endif """) + # Documented wrongly in 3.1.6 + c.find('RemoveSortIndicator').type = 'void' + c.find('RemoveSortIndicator').isConst = False + #------------------------------------------------------- c = module.find('wxListView') diff --git a/etg/menuitem.py b/etg/menuitem.py index b2f620b4..ac6cdb38 100644 --- a/etg/menuitem.py +++ b/etg/menuitem.py @@ -109,11 +109,12 @@ def run(): c.find('GetBitmap').type = 'const wxBitmap*' + c.find('GetBitmap').transferBack = True c.find('GetBitmap').setCppCode("""\ #ifdef __WXMSW__ - return &self->GetBitmap(checked); + return new wxBitmap(self->GetBitmap(checked)); #else - return &self->GetBitmap(); + return new wxBitmap(self->GetBitmap()); #endif """) @@ -157,6 +158,10 @@ def run(): module.addItem(tools.wxListWrapperTemplate('wxMenuItemList', 'wxMenuItem', module)) + # Documented wrongly in 3.1.6 + c.find('AddExtraAccel.accel').isConst = True + c.find('AddExtraAccel.accel').type = 'wxAcceleratorEntry&' + #----------------------------------------------------------------- diff --git a/etg/richtextbuffer.py b/etg/richtextbuffer.py index aaaba858..dad166b1 100644 --- a/etg/richtextbuffer.py +++ b/etg/richtextbuffer.py @@ -79,8 +79,6 @@ def run(): tools.wxArrayWrapperTemplate('wxRichTextVariantArray', 'wxVariant', module)) module.addItem( tools.wxListWrapperTemplate('wxRichTextObjectList', 'wxRichTextObject', module)) - module.addItem( - tools.wxListWrapperTemplate('wxRichTextLineList', 'wxRichTextLine', module)) # Can this even work? Apparently it does. module.addItem( @@ -319,6 +317,21 @@ def run(): fakeListClassName='wxRichTextObjectList_')) c.find('MoveToList.list').type = 'wxRichTextObjectList_&' c.find('MoveFromList.list').type = 'wxRichTextObjectList_&' + # TODO: figure out why wxvector.sip doesn't work for this + c.find('GetLines').type = 'PyObject*' + c.find('GetLines').setCppCode("""\ + wxPyThreadBlocker blocker; + PyObject* result = PyList_New(0); + const wxRichTextLineVector& vector = self->GetLines(); + for (size_t idx=0; idx < vector.size(); idx++) {{ + PyObject* obj; + wxRichTextLine* item = new wxRichTextLine(*vector.at(idx)); + obj = wxPyConstructObject((void*)item, "wxRichTextLine", true); + PyList_Append(result, obj); + Py_DECREF(obj); + }} + return result; + """) #------------------------------------------------------- diff --git a/etg/textctrl.py b/etg/textctrl.py index 7f1c1fba..a590512e 100644 --- a/etg/textctrl.py +++ b/etg/textctrl.py @@ -9,6 +9,8 @@ # License: wxWindows License #--------------------------------------------------------------------------- +import sys + import etgtools import etgtools.tweaker_tools as tools @@ -144,6 +146,15 @@ def parseAndTweakModule(): #endif """) + # TODO: add support for wxTextProofOptions (only supported on MSW/GTK3) + # so will need stubs on other platforms. + c.find('EnableProofCheck').ignore() + c.find('GetProofCheckOptions').ignore() + + # This function only exists on OSX + if sys.platform != 'darwin': + c.find('OSXEnableNewLineReplacement').ignore() + c = module.find('wxTextUrlEvent') diff --git a/etg/treectrl.py b/etg/treectrl.py index 4b1d0a22..23945b60 100644 --- a/etg/treectrl.py +++ b/etg/treectrl.py @@ -150,7 +150,6 @@ def run(): # transfer imagelist ownership - c.find('AssignImageList.imageList').transfer = True c.find('AssignStateImageList.imageList').transfer = True c.find('AssignButtonsImageList.imageList').transfer = True diff --git a/etg/webview.py b/etg/webview.py index b4abb35c..6fec5045 100644 --- a/etg/webview.py +++ b/etg/webview.py @@ -91,6 +91,11 @@ def run(): # This tweak is needed only for the stub code module.find('wxWebViewHandler.wxWebViewHandler').argsString = '(const wxString& scheme="")' + # Documented wrongly in 3.1.6 (needs to be fixed in stubs too) + c = module.find('wxWebViewFactory') + c.find('GetVersionInfo').argsString = '()' + c.find('GetVersionInfo').items = [] + tools.generateStubs('wxUSE_WEBVIEW', module, typeValMap={ 'wxWebViewNavigationActionFlags': 'wxWEBVIEW_NAV_ACTION_NONE', @@ -98,6 +103,13 @@ def run(): 'wxVersionInfo': 'wxVersionInfo()', }) + # Missing in 3.1.6 + module.addItem(etgtools.WigCode("""\ + wxEventType wxEVT_WEBVIEW_FULLSCREEN_CHANGED /PyName=wxEVT_WEBVIEW_FULLSCREEN_CHANGED/; + wxEventType wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED /PyName=wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED/; + wxEventType wxEVT_WEBVIEW_SCRIPT_RESULT /PyName=wxEVT_WEBVIEW_SCRIPT_RESULT/; + """)) + c = module.find('wxWebView') assert isinstance(c, etgtools.ClassDef) tools.fixWindowClass(c) diff --git a/etgtools/tweaker_tools.py b/etgtools/tweaker_tools.py index e67975db..5b76888e 100644 --- a/etgtools/tweaker_tools.py +++ b/etgtools/tweaker_tools.py @@ -497,7 +497,6 @@ def addWindowVirtuals(klass): ('DoSetSize', 'void DoSetSize(int x, int y, int width, int height, int sizeFlags)'), ('DoSetClientSize', 'void DoSetClientSize(int width, int height)'), ('DoSetSizeHints', 'void DoSetSizeHints( int minW, int minH, int maxW, int maxH, int incW, int incH )'), - ('DoGetBorderSize', 'wxSize DoGetBorderSize() const'), ('DoMoveWindow', 'void DoMoveWindow(int x, int y, int width, int height)'), ('DoSetWindowVariant', 'void DoSetWindowVariant( wxWindowVariant variant)'), ('GetDefaultBorder', 'wxBorder GetDefaultBorder() const'), diff --git a/src/wxvector.sip b/src/wxvector.sip new file mode 100644 index 00000000..16c0a943 --- /dev/null +++ b/src/wxvector.sip @@ -0,0 +1,106 @@ +//-------------------------------------------------------------------------- +// Name: wxvector.sip +// Purpose: MappedType for wxVector +// +// Author: Scott Talbert +// +// Created: 14-Apr-2022 +// Copyright: (c) 2022 by Scott Talbert +// Licence: wxWindows license +//-------------------------------------------------------------------------- + +template<_TYPE_> +%MappedType wxVector<_TYPE_> +{ + %ConvertFromTypeCode + PyObject *l = PyList_New(sipCpp->size()); + + if (!l) + return 0; + + for (int i = 0; i < sipCpp->size(); ++i) { + _TYPE_ *t = new _TYPE_(sipCpp->at(i)); + PyObject *tobj = sipConvertFromNewType(t, sipType__TYPE_, + sipTransferObj); + + if (!tobj) { + delete t; + Py_DECREF(l); + + return 0; + } + + PyList_SetItem(l, i, tobj); + } + + return l; + %End + + %ConvertToTypeCode + PyObject *iter = PyObject_GetIter(sipPy); + + if (!sipIsErr) { + PyErr_Clear(); + Py_XDECREF(iter); + + return (iter +#if PY_MAJOR_VERSION < 3 + && !PyString_Check(sipPy) +#endif + && !PyUnicode_Check(sipPy)); + } + + if (!iter) { + *sipIsErr = 1; + + return 0; + } + + wxVector<_TYPE_> *wv = new wxVector<_TYPE_>; + + for (Py_ssize_t i = 0; ; ++i) { + PyErr_Clear(); + PyObject *itm = PyIter_Next(iter); + + if (!itm) { + if (PyErr_Occurred()) { + delete wv; + Py_DECREF(iter); + *sipIsErr = 1; + + return 0; + } + + break; + } + + int state; + _TYPE_ *t = reinterpret_cast<_TYPE_ *>( + sipForceConvertToType(itm, sipType__TYPE_, sipTransferObj, + SIP_NOT_NONE, &state, sipIsErr)); + + if (*sipIsErr) { + PyErr_Format(PyExc_TypeError, + "index %zd has type '%s' but '_TYPE_' is expected", i, + sipPyTypeName(Py_TYPE(itm))); + + Py_DECREF(itm); + delete wv; + Py_DECREF(iter); + + return 0; + } + + wv->push_back(*t); + + sipReleaseType(t, sipType__TYPE_, state); + Py_DECREF(itm); + } + + Py_DECREF(iter); + + *sipCppPtr = wv; + + return sipGetState(sipTransferObj); + %End +}; \ No newline at end of file