X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d14a1e28567de23c586bc80017073d0c39f8d18f..a0ef52c0383af9624f257cf2d999c1995146ab5f:/wxPython/src/_core_ex.py diff --git a/wxPython/src/_core_ex.py b/wxPython/src/_core_ex.py index b26ed2113f..3856de4f6f 100644 --- a/wxPython/src/_core_ex.py +++ b/wxPython/src/_core_ex.py @@ -1,15 +1,14 @@ #---------------------------------------------------------------------------- -# Use Python's bool constants if available, make aliases if not +# Use Python's bool constants if available, make some if not try: True except NameError: - True = 1==1 - False = 1==0 + __builtins__.True = 1==1 + __builtins__.False = 1==0 + def bool(value): return not not value + __builtins__.bool = bool -# Backwards compaatibility -TRUE = true = True -FALSE = false = False # workarounds for bad wxRTTI names @@ -20,23 +19,51 @@ __wxPyPtrTypeMap['wxStatusBar95'] = 'wxStatusBar' #---------------------------------------------------------------------------- # Load version numbers from __version__... Ensure that major and minor -# versions are the same for both wxPython and wxWindows. +# versions are the same for both wxPython and wxWidgets. from __version__ import * __version__ = VERSION_STRING -assert MAJOR_VERSION == _core.MAJOR_VERSION, "wxPython/wxWindows version mismatch" -assert MINOR_VERSION == _core.MINOR_VERSION, "wxPython/wxWindows version mismatch" -if RELEASE_VERSION != _core.RELEASE_VERSION: +assert MAJOR_VERSION == _core_.MAJOR_VERSION, "wxPython/wxWidgets version mismatch" +assert MINOR_VERSION == _core_.MINOR_VERSION, "wxPython/wxWidgets version mismatch" +if RELEASE_VERSION != _core_.RELEASE_VERSION: import warnings - warnings.warn("wxPython/wxWindows release number mismatch") + warnings.warn("wxPython/wxWidgets release number mismatch") + +#---------------------------------------------------------------------------- + +# Set wxPython's default string<-->unicode conversion encoding from +# the locale, but only if Python's default hasn't been changed. (We +# assume that if the user has customized it already then that is the +# encoding we need to use as well.) +# +# The encoding selected here is used when string or unicode objects +# need to be converted in order to pass them to wxWidgets. Please be +# aware that the default encoding within the same locale may be +# slightly different on different platforms. For example, please see +# http://www.alanwood.net/demos/charsetdiffs.html for differences +# between the common latin/roman encodings. + +default = _sys.getdefaultencoding() +if default == 'ascii': + import locale + import codecs + try: + default = locale.getdefaultlocale()[1] + codecs.lookup(default) + except (ValueError, LookupError, TypeError): + default = _sys.getdefaultencoding() + del locale + del codecs +if default: + wx.SetDefaultPyEncoding(default) +del default #---------------------------------------------------------------------------- class PyDeadObjectError(AttributeError): pass - class _wxPyDeadObject(object): """ Instances of wx objects that are OOR capable will have their __class__ @@ -46,54 +73,85 @@ class _wxPyDeadObject(object): reprStr = "wxPython wrapper for DELETED %s object! (The C++ object no longer exists.)" attrStr = "The C++ part of the %s object has been deleted, attribute access no longer allowed." - def __repr__( self ): + def __repr__(self): if not hasattr(self, "_name"): self._name = "[unknown]" return self.reprStr % self._name - def __getattr__( self, *args ): + def __getattr__(self, *args): if not hasattr(self, "_name"): self._name = "[unknown]" - raise PyDeadObjectError( self.attrStr % self._name ) + raise PyDeadObjectError(self.attrStr % self._name) + + def __nonzero__(self): + return 0 + + + +class PyUnbornObjectError(AttributeError): + pass + +class _wxPyUnbornObject(object): + """ + Some stock objects are created when the wx._core module is + imported, but their C++ instance is not created until the wx.App + object is created and initialized. These object instances will + temporarily have their __class__ changed to this class so an + exception will be raised if they are used before the C++ instance + is ready. + """ + + reprStr = "wxPython wrapper for UNBORN object! (The C++ object is not initialized yet.)" + attrStr = "The C++ part of this object has not been initialized, attribute access not allowed." + + def __repr__(self): + #if not hasattr(self, "_name"): + # self._name = "[unknown]" + return self.reprStr #% self._name + + def __getattr__(self, *args): + #if not hasattr(self, "_name"): + # self._name = "[unknown]" + raise PyUnbornObjectError(self.attrStr) # % self._name ) def __nonzero__(self): return 0 #---------------------------------------------------------------------------- -_wxPyCallAfterId = None def CallAfter(callable, *args, **kw): """ Call the specified function after the current and pending event handlers have been completed. This is also good for making GUI - method calls from non-GUI threads. + method calls from non-GUI threads. Any extra positional or + keyword args are passed on to the callable when it is called. + + :see: `wx.FutureCall` """ app = wx.GetApp() - assert app, 'No wxApp created yet' + assert app is not None, 'No wx.App created yet' - global _wxPyCallAfterId - if _wxPyCallAfterId is None: - _wxPyCallAfterId = wx.NewEventType() - app.Connect(-1, -1, _wxPyCallAfterId, - lambda event: event.callable(*event.args, **event.kw) ) + if not hasattr(app, "_CallAfterId"): + app._CallAfterId = wx.NewEventType() + app.Connect(-1, -1, app._CallAfterId, + lambda event: event.callable(*event.args, **event.kw) ) evt = wx.PyEvent() - evt.SetEventType(_wxPyCallAfterId) + evt.SetEventType(app._CallAfterId) evt.callable = callable evt.args = args evt.kw = kw wx.PostEvent(app, evt) - #---------------------------------------------------------------------------- class FutureCall: """ - A convenience class for wxTimer, that calls the given callable + A convenience class for `wx.Timer`, that calls the given callable object once after the given amount of milliseconds, passing any positional or keyword args. The return value of the callable is - availbale after it has been run with the GetResult method. + availbale after it has been run with the `GetResult` method. If you don't need to get the return value or restart the timer then there is no need to hold a reference to this object. It will @@ -101,12 +159,15 @@ class FutureCall: has a reference to self.Notify) but the cycle will be broken when the timer completes, automatically cleaning up the wx.FutureCall object. + + :see: `wx.CallAfter` """ def __init__(self, millis, callable, *args, **kwargs): self.millis = millis self.callable = callable self.SetArgs(*args, **kwargs) self.runCount = 0 + self.running = False self.hasRun = False self.result = None self.timer = None @@ -128,6 +189,7 @@ class FutureCall: self.Stop() self.timer = wx.PyTimer(self.Notify) self.timer.Start(self.millis, wx.TIMER_ONE_SHOT) + self.running = True Restart = Start @@ -174,20 +236,61 @@ class FutureCall: """ if self.callable and getattr(self.callable, 'im_self', True): self.runCount += 1 + self.running = False self.result = self.callable(*self.args, **self.kwargs) self.hasRun = True - wx.CallAfter(self.Stop) + if not self.running: + # if it wasn't restarted, then cleanup + wx.CallAfter(self.Stop) + + +#---------------------------------------------------------------------------- +# Control which items in this module should be documented by epydoc. +# We allow only classes and functions, which will help reduce the size +# of the docs by filtering out the zillions of constants, EVT objects, +# and etc that don't make much sense by themselves, but are instead +# documented (or will be) as part of the classes/functions/methods +# where they should be used. + +class __DocFilter: + """ + A filter for epydoc that only allows non-Ptr classes and + functions, in order to reduce the clutter in the API docs. + """ + def __init__(self, globals): + self._globals = globals + + def __call__(self, name): + import types + obj = self._globals.get(name, None) + + # only document classes and function + if type(obj) not in [type, types.ClassType, types.FunctionType, types.BuiltinFunctionType]: + return False + + # skip other things that are private or will be documented as part of somethign else + if name.startswith('_') or name.startswith('EVT') or name.endswith('_swigregister') or name.endswith('Ptr') : + return False + + # skip functions that are duplicates of static functions in a class + if name.find('_') != -1: + cls = self._globals.get(name.split('_')[0], None) + methname = name.split('_')[1] + if hasattr(cls, methname) and type(getattr(cls, methname)) is types.FunctionType: + return False + + return True #---------------------------------------------------------------------------- #---------------------------------------------------------------------------- # Import other modules in this package that should show up in the # "core" wx namespace -from gdi import * -from windows import * -from controls import * -from misc import * +from _gdi import * +from _windows import * +from _controls import * +from _misc import * #---------------------------------------------------------------------------- #----------------------------------------------------------------------------