From 911d90273c0036e581b835db7d8a869a29b70e5a Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Thu, 25 Aug 2011 23:45:50 +0000 Subject: [PATCH] Lots of little changes made to Phoenix code over the past few months, plus some tweaks to get it running with the current wx. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@68905 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- build.py | 98 ++++++++++++++++++++++++++++++----- buildtools/config.py | 4 +- buildtools/distutils_hacks.py | 17 ++++-- etg/app.py | 2 +- etg/font.py | 5 +- etg/frame.py | 2 +- etg/region.py | 7 +++ etg/toplevel.py | 2 +- etg/window.py | 5 +- etgtools/sip_generator.py | 7 ++- etgtools/tweaker_tools.py | 44 ++++++++++++---- sip/gen/_core.sip | 5 +- sip/gen/app.sip | 5 -- sip/gen/event.sip | 4 +- sip/gen/font.sip | 25 ++++++++- sip/gen/frame.sip | 8 +-- sip/gen/object.sip | 2 +- sip/gen/toplevel.sip | 8 +-- sip/gen/window.sip | 34 +++++++++--- src/event_ex.py | 2 +- unittests/test_pyevent.py | 2 - unittests/test_windowlist.py | 47 +++++++++++++++++ 22 files changed, 271 insertions(+), 64 deletions(-) create mode 100644 unittests/test_windowlist.py diff --git a/build.py b/build.py index 32003215..663fb852 100755 --- a/build.py +++ b/build.py @@ -53,12 +53,14 @@ Usage: ./build.py [command(s)] [options] build_wx Do the wxWidgets part of the build build_py Build wxPython only - build Build both wxWidgets and wxPython. + build Build both wxWidgets and wxPython clean_wx Clean the wx parts of the build clean_py Clean the wxPython parts of the build - cleanall Clean both wx and wxPython, and a little extra scrubbing + clean Clean both wx and wxPython """ +# cleanall Clean both wx and wxPython, and a little extra scrubbing + parser = makeOptionParser() parser.print_help() @@ -84,8 +86,8 @@ def main(args): if cmd.startswith('test_'): testOne(cmd, options, args) elif cmd in ['dox', 'doxhtml', 'etg', 'sip', 'touch', 'test', - 'build_wx', 'build_py', 'build', - 'clean_wx', 'clean_py', 'cleanall']: + 'build_wx', 'build_py', 'build', + 'clean', 'clean_wx', 'clean_py', 'cleanall']: function = globals()[cmd] function(options, args) else: @@ -161,6 +163,7 @@ def setPythonVersion(args): else: findPython = runcmd("which %s" % PYTHON, True, False) msg('Found %s at %s' % (PYTHON, findPython)) + PYTHON = findPython msg(runcmd('%s -c "import sys; print sys.version"' % PYTHON, True, False)) @@ -210,7 +213,6 @@ def wxDir(): def getMSWSettings(options): class MSWsettings(object): pass - msw = MSWsettings() msw.CPU = os.environ.get('CPU') if msw.CPU == 'AMD64': @@ -219,9 +221,9 @@ def getMSWSettings(options): msw.dllDir = posixjoin(wxDir(), "lib", "vc_dll") msw.buildDir = posixjoin(wxDir(), "build", "msw") - #msw.build_type_ext = "u" - #if options.debug: - # msw.build_type_ext = "ud" + msw.dll_type = "u" + if options.debug: + msw.dll_type = "ud" return msw @@ -289,6 +291,19 @@ def getBuildDir(options): return BUILD_DIR +def deleteIfExists(deldir, verbose=True): + if os.path.exists(deldir) and os.path.isdir(deldir): + if verbose: + print "Removing folder: %s" % deldir + shutil.rmtree(deldir) + + +def delFiles(fileList, verbose=True): + for afile in fileList: + if verbose: + print "Removing file: %s" % afile + os.remove(afile) + def macFixDependencyInstallName(destdir, prefix, extension, buildDir): print "**** macFixDependencyInstallName(%s, %s, %s, %s)" % (destdir, prefix, extension, buildDir) @@ -305,7 +320,6 @@ def macFixDependencyInstallName(destdir, prefix, extension, buildDir): os.chdir(pwd) - #--------------------------------------------------------------------------- # Command functions #--------------------------------------------------------------------------- @@ -329,7 +343,8 @@ def dox(options, args): def doxhtml(options, args): msg('Running command: doxhtml') - _doDox('html chm') + _doDox('html') + _doDox('chm') @@ -587,18 +602,77 @@ def build_py(options, args): def clean_wx(options, args): msg('Running command: clean_wx') + if isWindows: + if options.both: + options.debug = True + msw = getMSWSettings(options) + cfg = Config() + deleteIfExists(opj(msw.dllDir, 'msw'+msw.dll_type)) + delFiles(glob.glob(opj(msw.dllDir, 'wx*%s%s*' % (version2_nodot, msw.dll_type)))) + delFiles(glob.glob(opj(msw.dllDir, 'wx*%s%s*' % (version3_nodot, msw.dll_type)))) + deleteIfExists(opj(msw.buildDir, 'vc_msw'+msw.dll_type+'dll')) + + if options.both: + options.debug = False + options.both = False + clean_wx(options, args) + options.both = True + else: + BUILD_DIR = getBuildDir(options) + deleteIfExists(BUILD_DIR) def clean_py(options, args): msg('Running command: clean_py') + assert os.getcwd() == phoenixDir() + if isWindows and options.both: + options.debug = True + cfg = Config() + build_base = 'build' + if isDarwin: + if options.osx_cocoa: + build_base += '/cocoa' + else: + build_base += '/carbon' + deleteIfExists(build_base) + files = list() + for wc in ['*.py', '*.pyc', '*.so', '*.pyd', '*.pdb', + ]: + files += glob.glob(opj(cfg.PKGDIR, wc)) + if isWindows: + msw = getMSWSettings(options) + for wc in [ 'wx*' + version2_nodot + msw.dll_type + '*.dll', + 'wx*' + version3_nodot + msw.dll_type + '*.dll']: + files += glob.glob(opj(cfg.PKGDIR, wc)) + delFiles(files) + + if options.both: + options.debug = False + options.both = False + clean_py(options, args) + options.both = True +def clean(options, args): + clean_wx(options, args) + clean_py(options, args) + + def cleanall(options, args): - msg('Running command: cleanall') - + # These take care of all the object, lib, shared lib files created by the + # compilation part of build clean_wx(options, args) clean_py(options, args) + # Now also scrub out all of the SIP and C++ source files that are + # generated by the Phoenix ETG system. + msg('Running command: cleanall') + assert os.getcwd() == phoenixDir() + files = list() + for wc in ['sip/cpp/*.h', 'sip/cpp/*.cpp', 'sip/cpp/*.sbf', 'sip/gen/*.sip']: + files += glob.glob(wc) + delFiles(files) + #--------------------------------------------------------------------------- diff --git a/buildtools/config.py b/buildtools/config.py index eb9a807e..89aff38a 100644 --- a/buildtools/config.py +++ b/buildtools/config.py @@ -47,7 +47,7 @@ class Configuration(object): SIPFILES = 'sip' # where to find other sip files for %Include or %Import SIPOUT = 'sip/cpp' # where to put the generated C++ code - SIPOPTS = ' '.join(['-k', # turn on keyword args support + SIPOPTS = ' '.join(['-w', # enable warnings '-o', # turn on auto-docstrings #'-e', # turn on exceptions support '-T', # turn off writing the timestamp to the generated files @@ -557,4 +557,4 @@ def etg2sip(etgfile): sipfile = os.path.splitext(os.path.basename(etgfile))[0] + '.sip' sipfile = posixjoin(cfg.SIPGEN, sipfile) return sipfile - \ No newline at end of file + diff --git a/buildtools/distutils_hacks.py b/buildtools/distutils_hacks.py index 66a7a53a..c3909385 100644 --- a/buildtools/distutils_hacks.py +++ b/buildtools/distutils_hacks.py @@ -151,12 +151,20 @@ from distutils.errors import DistutilsExecError, CompileError def _darwin_compiler_fixup(compiler_so, cc_args): """ This function will strip '-isysroot PATH' and '-arch ARCH' from the - compile flags if the user has specified one them in extra_compile_flags. + compile flags if the user has specified one of them in extra_compile_flags. This is needed because '-arch ARCH' adds another architecture to the build, without a way to remove an architecture. Furthermore GCC will barf if multiple '-isysroot' arguments are present. + + I've further modified our copy of this function to check if there + is a -isysroot flag in the CC/CXX values in the environment. If so then we + want to make sure that we keep that one and strip the others, instead of + stripping it and leaving Python's. """ + ccHasSysroot = '-isysroot' in os.environ.get('CC', '') \ + or '-isysroot' in os.environ.get('CXX', '') + stripArch = stripSysroot = 0 compiler_so = list(compiler_so) @@ -169,7 +177,7 @@ def _darwin_compiler_fixup(compiler_so, cc_args): stripArch = stripSysroot = True else: stripArch = '-arch' in cc_args - stripSysroot = '-isysroot' in cc_args or stripArch # <== This line changed + stripSysroot = '-isysroot' in cc_args or stripArch if stripArch: while 1: @@ -182,7 +190,10 @@ def _darwin_compiler_fixup(compiler_so, cc_args): if stripSysroot: try: - index = compiler_so.index('-isysroot') + index = 0 + if ccHasSysroot: + index = compiler_so.index('-isysroot') + 1 + index = compiler_so.index('-isysroot', index) # Strip this argument and the next one: del compiler_so[index:index+2] except ValueError: diff --git a/etg/app.py b/etg/app.py index 89dc9e96..6baf9961 100644 --- a/etg/app.py +++ b/etg/app.py @@ -103,7 +103,7 @@ def run(): # Remove the virtualness from these methods for m in [ 'GetDisplayMode', 'GetLayoutDirection', 'GetTopWindow', 'IsActive', - 'SafeYield', 'SafeYieldFor', 'SendIdleEvents', 'SetDisplayMode', + 'SafeYield', 'SafeYieldFor', 'SetDisplayMode', 'SetNativeTheme', ]: c.find(m).isVirtual = False diff --git a/etg/font.py b/etg/font.py index ad2b6a05..bea7716a 100644 --- a/etg/font.py +++ b/etg/font.py @@ -87,9 +87,12 @@ def run(): c.addProperty('PointSize GetPointSize SetPointSize') c.addProperty('PixelSize GetPixelSize SetPixelSize') c.addProperty('Style GetStyle SetStyle') - c.addProperty('Underlined GetUnderlined SetUnderlined') c.addProperty('Weight GetWeight SetWeight') + # TODO, there is now a Underlined method so we can't have a + # property of the same name. + #c.addProperty('Underlined GetUnderlined SetUnderlined') + #----------------------------------------------------------------- diff --git a/etg/frame.py b/etg/frame.py index f0caf51f..e9701c90 100644 --- a/etg/frame.py +++ b/etg/frame.py @@ -32,7 +32,7 @@ def run(): c = module.find('wxFrame') assert isinstance(c, etgtools.ClassDef) - tools.fixWindowClass(c) + tools.fixTopLevelWindowClass(c) c.find('wxFrame.title').default = 'wxEmptyString' c.find('Create.title').default = 'wxEmptyString' diff --git a/etg/region.py b/etg/region.py index 2d5898dc..893aaf5e 100644 --- a/etg/region.py +++ b/etg/region.py @@ -39,6 +39,13 @@ def run(): c.find('GetBox').findOverload('wxCoord').ignore() c.addProperty('Box GetBox') + + # TODO: Make wxRegion and/or wxRegionIterator compatible with Python + # Iterator protocol. Perhaps it could be as simple as creating a generator + # object that uses a wxRegionIterator and which is returned from a + # wxRegion.__iter__ method. + + c = module.find('wxRegionIterator') c.find('operator++').ignore() diff --git a/etg/toplevel.py b/etg/toplevel.py index bc17f7f9..c3ca29ac 100644 --- a/etg/toplevel.py +++ b/etg/toplevel.py @@ -32,7 +32,7 @@ def run(): c = module.find('wxTopLevelWindow') assert isinstance(c, etgtools.ClassDef) - tools.fixWindowClass(c) + tools.fixTopLevelWindowClass(c) c.find('wxTopLevelWindow.title').default = 'wxEmptyString' c.find('Create.title').default = 'wxEmptyString' diff --git a/etg/window.py b/etg/window.py index 4194d213..a16590a5 100644 --- a/etg/window.py +++ b/etg/window.py @@ -250,8 +250,11 @@ def run(): # Add a wrapper for wxWindowList and a new iterator class for it that # makes wxWindowList quack like a read-only Python sequence. module.addItem(tools.wxListWrapperTemplate('wxWindowList', 'wxWindow')) + - + module.addCppFunction('wxWindowList*', 'GetTopLevelWindows', '()', + briefDoc="Returns a list-like object of the the application's top-level windows, (frames,dialogs, etc.)", + body="return &wxTopLevelWindows;") #----------------------------------------------------------------- tools.doCommonTweaks(module) diff --git a/etgtools/sip_generator.py b/etgtools/sip_generator.py index caf09a9f..84c22006 100644 --- a/etgtools/sip_generator.py +++ b/etgtools/sip_generator.py @@ -50,7 +50,10 @@ class SipWrapperGenerator(generators.WrapperGeneratorBase): """) if module.name == module.module: stream.write(""" -%%Module(name=%s.%s, use_argument_names=True, language="C++") +%%Module( name=%s.%s, + keyword_arguments="All", + use_argument_names=True, + language="C++") { %%AutoPyName(remove_leading="wx") }; @@ -539,7 +542,7 @@ from %s import * if item.transferBack: annotations.append('TransferBack') if item.transferThis: - annotations.append('TranserThis') + annotations.append('TransferThis') if item.pyInt: annotations.append('PyInt') diff --git a/etgtools/tweaker_tools.py b/etgtools/tweaker_tools.py index 8b6298bd..615287d7 100644 --- a/etgtools/tweaker_tools.py +++ b/etgtools/tweaker_tools.py @@ -99,7 +99,20 @@ def fixWindowClass(klass): klass.find('%s.id' % klass.name).default = 'wxID_ANY' klass.find('Create.id').default = 'wxID_ANY' + +def fixTopLevelWindowClass(klass): + """ + Tweaks for TLWs + """ + # TLW tweaks are a little different. We use the function annotation for + # TransferThis instead of the argument anotation. + klass.find(klass.name).findOverload('parent').transfer = True + klass.find('Create').transferThis = True + # give the id param a default value + klass.find('%s.id' % klass.name).default = 'wxID_ANY' + klass.find('Create.id').default = 'wxID_ANY' + def removeVirtuals(klass): """ Sometimes methods are marked as virtual but probably don't ever need to be @@ -429,10 +442,12 @@ def convertFourDoublesTemplate(CLASS): def wxListWrapperTemplate(ListClass, ItemClass, RealItemClass=None): if RealItemClass is None: RealItemClass = ItemClass - ListClass_noPrefix = removeWxPrefix(ListClass) + + ListClass_pyName = removeWxPrefix(ListClass) - # *** TODO: This can probably be done in a way that is not SIP-specfic. Try - # creating extractor objects from scratch and attach cppMethods to them. + # *** TODO: This can probably be done in a way that is not SIP-specfic. + # Try creating extractor objects from scratch and attach cppMethods to + # them as needed, etc.. return extractors.WigCode('''\ class {ListClass}_iterator /Abstract/ @@ -444,13 +459,15 @@ class {ListClass}_iterator /Abstract/ {ListClass}_iterator({ListClass}::compatibility_iterator start) : m_node(start) {{}} - {ItemClass}* next() {{ + {ItemClass}* __next__() {{ {RealItemClass}* obj = NULL; if (m_node) {{ obj = m_node->GetData(); m_node = m_node->GetNext(); }} - else PyErr_SetString(PyExc_StopIteration, ""); + else {{ + PyErr_SetString(PyExc_StopIteration, ""); + }} return ({ItemClass}*)obj; }} private: @@ -458,13 +475,18 @@ class {ListClass}_iterator /Abstract/ }}; %End public: - {ItemClass}* next(); + {ItemClass}* __next__(); + %MethodCode + sipRes = sipCpp->__next__(); + if (PyErr_Occurred()) + return NULL; + %End }}; class {ListClass} {{ public: - int __len__(); + SIP_SSIZE_T __len__(); %MethodCode sipRes = sipCpp->size(); %End @@ -506,10 +528,10 @@ public: }}; %Extract(id=pycode) -def _{ListClass_noPrefix}___repr__(self): - return "{ListClass}: " + repr(list(self)) -{ListClass_noPrefix}.__repr__ = _{ListClass_noPrefix}___repr__ -del _{ListClass_noPrefix}___repr__ +def _{ListClass_pyName}___repr__(self): + return "{ListClass_pyName}: " + repr(list(self)) +{ListClass_pyName}.__repr__ = _{ListClass_pyName}___repr__ +del _{ListClass_pyName}___repr__ %End '''.format(**locals())) diff --git a/sip/gen/_core.sip b/sip/gen/_core.sip index 769034dd..6d993616 100644 --- a/sip/gen/_core.sip +++ b/sip/gen/_core.sip @@ -4,7 +4,10 @@ // Copyright: (c) 2010 by Total Control Software // License: wxWindows License -%Module(name=wxPhoenix._core, use_argument_names=True, language="C++") +%Module( name=wxPhoenix._core, + keyword_arguments="All", + use_argument_names=True, + language="C++") { %AutoPyName(remove_leading="wx") }; diff --git a/sip/gen/app.sip b/sip/gen/app.sip index 607a0428..78549bd4 100644 --- a/sip/gen/app.sip +++ b/sip/gen/app.sip @@ -477,11 +477,6 @@ public: long eventsToProcess ); - bool SendIdleEvents( - wxWindow * win, - wxIdleEvent & event - ); - bool SetDisplayMode( const wxVideoMode & info ); diff --git a/sip/gen/event.sip b/sip/gen/event.sip index ecba3402..f3aca079 100644 --- a/sip/gen/event.sip +++ b/sip/gen/event.sip @@ -1800,7 +1800,7 @@ wxEventType wxEVT_COMMAND_COMBOBOX_DROPDOWN /PyName=wxEVT_COMMAND_COMBOBOX_DRO wxEventType wxEVT_COMMAND_COMBOBOX_CLOSEUP /PyName=wxEVT_COMMAND_COMBOBOX_CLOSEUP/; -wxEventType wxEVT_COMMAND_THREAD /PyName=wxEVT_COMMAND_THREAD/; +wxEventType wxEVT_THREAD /PyName=wxEVT_THREAD/; wxEventType wxEVT_LEFT_DOWN /PyName=wxEVT_LEFT_DOWN/; @@ -2306,7 +2306,7 @@ EVT_TEXT_CUT = wx.PyEventBinder( wxEVT_COMMAND_TEXT_CUT ) EVT_TEXT_COPY = wx.PyEventBinder( wxEVT_COMMAND_TEXT_COPY ) EVT_TEXT_PASTE = wx.PyEventBinder( wxEVT_COMMAND_TEXT_PASTE ) -EVT_THREAD = wx.PyEventBinder( wxEVT_COMMAND_THREAD ) +EVT_THREAD = wx.PyEventBinder( wxEVT_THREAD ) # End of included code block #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= diff --git a/sip/gen/font.sip b/sip/gen/font.sip index a78bd560..8cc3fbed 100644 --- a/sip/gen/font.sip +++ b/sip/gen/font.sip @@ -94,6 +94,8 @@ public: wxFont Smaller(); + wxFont Underlined(); + wxFont & MakeBold(); wxFont & MakeItalic(); @@ -102,6 +104,8 @@ public: wxFont & MakeSmaller(); + wxFont & MakeUnderlined(); + wxFont & Scale( float x ); @@ -142,6 +146,15 @@ public: wxFontStyle style ); + void SetSymbolicSize( + wxFontSymbolicSize size + ); + + void SetSymbolicSizeRelativeTo( + wxFontSymbolicSize size, + int base + ); + void SetUnderlined( bool underlined ); @@ -214,7 +227,6 @@ public: %Property(name=PointSize, get=GetPointSize, set=SetPointSize) %Property(name=PixelSize, get=GetPixelSize, set=SetPixelSize) %Property(name=Style, get=GetStyle, set=SetStyle) - %Property(name=Underlined, get=GetUnderlined, set=SetUnderlined) %Property(name=Weight, get=GetWeight, set=SetWeight) }; // end of class wxFont @@ -247,6 +259,17 @@ enum wxFontWeight wxFONTWEIGHT_MAX }; +enum wxFontSymbolicSize +{ + wxFONTSIZE_XX_SMALL, + wxFONTSIZE_X_SMALL, + wxFONTSIZE_SMALL, + wxFONTSIZE_MEDIUM, + wxFONTSIZE_LARGE, + wxFONTSIZE_X_LARGE, + wxFONTSIZE_XX_LARGE +}; + enum wxFontFlag { wxFONTFLAG_DEFAULT, diff --git a/sip/gen/frame.sip b/sip/gen/frame.sip index 88fedc61..69ce0bc5 100644 --- a/sip/gen/frame.sip +++ b/sip/gen/frame.sip @@ -21,14 +21,14 @@ public: wxFrame(); wxFrame( - wxWindow * parent /TranserThis/, + wxWindow * parent, wxWindowID id = wxID_ANY, const wxString & title = wxEmptyString, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString & name = wxFrameNameStr - ); + ) /Transfer/; ~wxFrame(); @@ -37,14 +37,14 @@ public: ); bool Create( - wxWindow * parent /TranserThis/, + wxWindow * parent, wxWindowID id = wxID_ANY, const wxString & title = wxEmptyString, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString & name = wxFrameNameStr - ); + ) /TransferThis/; wxStatusBar * CreateStatusBar( int number = 1, diff --git a/sip/gen/object.sip b/sip/gen/object.sip index 2b9ddc50..8c93b95e 100644 --- a/sip/gen/object.sip +++ b/sip/gen/object.sip @@ -90,7 +90,7 @@ public: delete self; } %End - void Destroy() /TranserThis/; + void Destroy() /TransferThis/; %MethodCode _wxObject_Destroy(sipCpp, sipIsErr); %End diff --git a/sip/gen/toplevel.sip b/sip/gen/toplevel.sip index 9bb52e58..7a1a8902 100644 --- a/sip/gen/toplevel.sip +++ b/sip/gen/toplevel.sip @@ -21,26 +21,26 @@ public: wxTopLevelWindow(); wxTopLevelWindow( - wxWindow * parent /TranserThis/, + wxWindow * parent, wxWindowID id = wxID_ANY, const wxString & title = wxEmptyString, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString & name = wxFrameNameStr - ); + ) /Transfer/; ~wxTopLevelWindow(); bool Create( - wxWindow * parent /TranserThis/, + wxWindow * parent, wxWindowID id = wxID_ANY, const wxString & title = wxEmptyString, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString & name = wxFrameNameStr - ); + ) /TransferThis/; bool CanSetTransparent(); diff --git a/sip/gen/window.sip b/sip/gen/window.sip index 1bb60b00..3a99579f 100644 --- a/sip/gen/window.sip +++ b/sip/gen/window.sip @@ -76,7 +76,7 @@ public: wxWindow(); wxWindow( - wxWindow * parent /TranserThis/, + wxWindow * parent /TransferThis/, wxWindowID id = wxID_ANY, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, @@ -763,7 +763,7 @@ public: bool force = false ); - bool Destroy() /TranserThis/; + bool Destroy() /TransferThis/; bool IsBeingDeleted(); @@ -953,7 +953,7 @@ public: ); bool Create( - wxWindow * parent /TranserThis/, + wxWindow * parent /TransferThis/, wxWindowID id = wxID_ANY, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, @@ -1165,13 +1165,15 @@ class wxWindowList_iterator /Abstract/ wxWindowList_iterator(wxWindowList::compatibility_iterator start) : m_node(start) {} - wxWindow* next() { + wxWindow* __next__() { wxWindow* obj = NULL; if (m_node) { obj = m_node->GetData(); m_node = m_node->GetNext(); } - else PyErr_SetString(PyExc_StopIteration, ""); + else { + PyErr_SetString(PyExc_StopIteration, ""); + } return (wxWindow*)obj; } private: @@ -1179,13 +1181,18 @@ class wxWindowList_iterator /Abstract/ }; %End public: - wxWindow* next(); + wxWindow* __next__(); + %MethodCode + sipRes = sipCpp->__next__(); + if (PyErr_Occurred()) + return NULL; + %End }; class wxWindowList { public: - int __len__(); + SIP_SSIZE_T __len__(); %MethodCode sipRes = sipCpp->size(); %End @@ -1228,12 +1235,23 @@ public: %Extract(id=pycode) def _WindowList___repr__(self): - return "wxWindowList: " + repr(list(self)) + return "WindowList: " + repr(list(self)) WindowList.__repr__ = _WindowList___repr__ del _WindowList___repr__ %End +%ModuleCode +wxWindowList* _GetTopLevelWindows_function(int& _isErr) +{ + return &wxTopLevelWindows; +} +%End +wxWindowList* GetTopLevelWindows(); +%MethodCode + sipRes = _GetTopLevelWindows_function(sipIsErr); +%End + //--------------------------------------------------------------------------- diff --git a/src/event_ex.py b/src/event_ex.py index f50e4063..5b9a3a5b 100644 --- a/src/event_ex.py +++ b/src/event_ex.py @@ -285,4 +285,4 @@ EVT_TEXT_CUT = wx.PyEventBinder( wxEVT_COMMAND_TEXT_CUT ) EVT_TEXT_COPY = wx.PyEventBinder( wxEVT_COMMAND_TEXT_COPY ) EVT_TEXT_PASTE = wx.PyEventBinder( wxEVT_COMMAND_TEXT_PASTE ) -EVT_THREAD = wx.PyEventBinder( wxEVT_COMMAND_THREAD ) +EVT_THREAD = wx.PyEventBinder( wxEVT_THREAD ) diff --git a/unittests/test_pyevent.py b/unittests/test_pyevent.py index a7944662..cf4b13d7 100644 --- a/unittests/test_pyevent.py +++ b/unittests/test_pyevent.py @@ -3,8 +3,6 @@ import unittest2 import wxPhoenix as wx ##import os; print 'PID:', os.getpid(); raw_input('Ready to start, press enter...') -from wxPhoenix import siplib - #--------------------------------------------------------------------------- class PyEvents(unittest2.TestCase): diff --git a/unittests/test_windowlist.py b/unittests/test_windowlist.py new file mode 100644 index 00000000..1b3d80a6 --- /dev/null +++ b/unittests/test_windowlist.py @@ -0,0 +1,47 @@ +import sys +import unittest2 +import wxPhoenix as wx +##import os; print 'PID:', os.getpid(); raw_input('Ready to start, press enter...') + +#--------------------------------------------------------------------------- + +class WindowList(unittest2.TestCase): + def setUp(self): + self.app = wx.App() + self.frames = list() + for i in range(5): + frm = wx.Frame(None, title='frm%d' % i) + self.frames.append( frm ) + for i in range(5): + w = wx.Window(self.frames[4]) + + def tearDown(self): + def _closeAll(): + for frm in self.frames: + frm.Close() + wx.CallAfter(_closeAll) + self.app.MainLoop() + del self.app + + + def test_WindowList_GetTLW1(self): + TLWs = wx.GetTopLevelWindows() + self.assertTrue(len(TLWs) == 5) + + def test_WindowList_GetTLW2(self): + TLWs = wx.GetTopLevelWindows() + for tlw in TLWs: + self.assertTrue(type(tlw) == wx.Frame) + self.assertTrue(tlw.Title.startswith('frm')) + + def test_WindowList_GetChildren(self): + children = self.frames[0].GetChildren() + self.assertTrue(len(children) == 0) + children = self.frames[4].GetChildren() + self.assertTrue(len(children) == 5) + +#--------------------------------------------------------------------------- + + +if __name__ == '__main__': + unittest2.main()