]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/_core_ex.py
bug fixes for using wxTransientPopupWindow and wxDP_ALLOWNONE support from Andreas...
[wxWidgets.git] / wxPython / src / _core_ex.py
CommitLineData
d14a1e28
RD
1#----------------------------------------------------------------------------
2
322913ce 3# Use Python's bool constants if available, make some if not
d14a1e28
RD
4try:
5 True
6except NameError:
322913ce
RD
7 __builtins__.True = 1==1
8 __builtins__.False = 1==0
c19bd0a3
RD
9 def bool(value): return not not value
10 __builtins__.bool = bool
d14a1e28 11
d14a1e28
RD
12
13
14# workarounds for bad wxRTTI names
15__wxPyPtrTypeMap['wxGauge95'] = 'wxGauge'
16__wxPyPtrTypeMap['wxSlider95'] = 'wxSlider'
17__wxPyPtrTypeMap['wxStatusBar95'] = 'wxStatusBar'
18
19
20#----------------------------------------------------------------------------
21# Load version numbers from __version__... Ensure that major and minor
611190df 22# versions are the same for both wxPython and wxWidgets.
d14a1e28
RD
23
24from __version__ import *
25__version__ = VERSION_STRING
26
611190df
RD
27assert MAJOR_VERSION == _core_.MAJOR_VERSION, "wxPython/wxWidgets version mismatch"
28assert MINOR_VERSION == _core_.MINOR_VERSION, "wxPython/wxWidgets version mismatch"
54f9ee45 29if RELEASE_VERSION != _core_.RELEASE_VERSION:
d14a1e28 30 import warnings
611190df 31 warnings.warn("wxPython/wxWidgets release number mismatch")
d14a1e28
RD
32
33#----------------------------------------------------------------------------
34
669e06d7
RD
35# Set the default string<-->unicode conversion encoding from the
36# locale. This encoding is used when string or unicode objects need
37# to be converted in order to pass them to wxWidgets. Please be aware
38# that the default encoding within the same locale may be slightly
39# different on different platforms. For example, please see
40# http://www.alanwood.net/demos/charsetdiffs.html for differences
41# between the common latin/roman encodings.
4293f847
RD
42import locale
43default = locale.getdefaultlocale()[1]
44if default:
45 wx.SetDefaultPyEncoding(default)
46del default
47del locale
48
49#----------------------------------------------------------------------------
50
d14a1e28
RD
51class PyDeadObjectError(AttributeError):
52 pass
53
d14a1e28
RD
54class _wxPyDeadObject(object):
55 """
56 Instances of wx objects that are OOR capable will have their __class__
57 changed to this class when the C++ object is deleted. This should help
58 prevent crashes due to referencing a bogus C++ pointer.
59 """
60 reprStr = "wxPython wrapper for DELETED %s object! (The C++ object no longer exists.)"
61 attrStr = "The C++ part of the %s object has been deleted, attribute access no longer allowed."
62
9e58eb56 63 def __repr__(self):
d14a1e28
RD
64 if not hasattr(self, "_name"):
65 self._name = "[unknown]"
66 return self.reprStr % self._name
67
9e58eb56 68 def __getattr__(self, *args):
d14a1e28
RD
69 if not hasattr(self, "_name"):
70 self._name = "[unknown]"
9e58eb56
RD
71 raise PyDeadObjectError(self.attrStr % self._name)
72
73 def __nonzero__(self):
74 return 0
75
76
77
78class PyUnbornObjectError(AttributeError):
79 pass
80
81class _wxPyUnbornObject(object):
82 """
54f9ee45 83 Some stock objects are created when the wx._core module is
9e58eb56
RD
84 imported, but their C++ instance is not created until the wx.App
85 object is created and initialized. These object instances will
86 temporarily have their __class__ changed to this class so an
87 exception will be raised if they are used before the C++ instance
88 is ready.
89 """
90
91 reprStr = "wxPython wrapper for UNBORN object! (The C++ object is not initialized yet.)"
92 attrStr = "The C++ part of this object has not been initialized, attribute access not allowed."
93
94 def __repr__(self):
95 #if not hasattr(self, "_name"):
96 # self._name = "[unknown]"
97 return self.reprStr #% self._name
98
99 def __getattr__(self, *args):
100 #if not hasattr(self, "_name"):
101 # self._name = "[unknown]"
102 raise PyUnbornObjectError(self.attrStr) # % self._name )
d14a1e28
RD
103
104 def __nonzero__(self):
105 return 0
106
107
108#----------------------------------------------------------------------------
d14a1e28
RD
109
110def CallAfter(callable, *args, **kw):
111 """
112 Call the specified function after the current and pending event
113 handlers have been completed. This is also good for making GUI
61863841
RD
114 method calls from non-GUI threads. Any extra positional or
115 keyword args are passed on to the callable when it is called.
116
117 :see: `wx.FutureCall`
d14a1e28
RD
118 """
119 app = wx.GetApp()
2148e701 120 assert app is not None, 'No wx.App created yet'
d14a1e28 121
b0cafb91
RD
122 if not hasattr(app, "_CallAfterId"):
123 app._CallAfterId = wx.NewEventType()
124 app.Connect(-1, -1, app._CallAfterId,
125 lambda event: event.callable(*event.args, **event.kw) )
d14a1e28 126 evt = wx.PyEvent()
b0cafb91 127 evt.SetEventType(app._CallAfterId)
d14a1e28
RD
128 evt.callable = callable
129 evt.args = args
130 evt.kw = kw
131 wx.PostEvent(app, evt)
132
d14a1e28
RD
133#----------------------------------------------------------------------------
134
135
136class FutureCall:
137 """
a3c9f064 138 A convenience class for `wx.Timer`, that calls the given callable
d14a1e28
RD
139 object once after the given amount of milliseconds, passing any
140 positional or keyword args. The return value of the callable is
61863841 141 availbale after it has been run with the `GetResult` method.
d14a1e28
RD
142
143 If you don't need to get the return value or restart the timer
144 then there is no need to hold a reference to this object. It will
145 hold a reference to itself while the timer is running (the timer
146 has a reference to self.Notify) but the cycle will be broken when
147 the timer completes, automatically cleaning up the wx.FutureCall
148 object.
61863841
RD
149
150 :see: `wx.CallAfter`
d14a1e28
RD
151 """
152 def __init__(self, millis, callable, *args, **kwargs):
153 self.millis = millis
154 self.callable = callable
155 self.SetArgs(*args, **kwargs)
156 self.runCount = 0
66065839 157 self.running = False
d14a1e28
RD
158 self.hasRun = False
159 self.result = None
160 self.timer = None
161 self.Start()
162
163 def __del__(self):
164 self.Stop()
165
166
167 def Start(self, millis=None, *args, **kwargs):
168 """
169 (Re)start the timer
170 """
171 self.hasRun = False
172 if millis is not None:
173 self.millis = millis
174 if args or kwargs:
175 self.SetArgs(*args, **kwargs)
176 self.Stop()
177 self.timer = wx.PyTimer(self.Notify)
178 self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
66065839 179 self.running = True
d14a1e28
RD
180 Restart = Start
181
182
183 def Stop(self):
184 """
185 Stop and destroy the timer.
186 """
187 if self.timer is not None:
188 self.timer.Stop()
189 self.timer = None
190
191
192 def GetInterval(self):
193 if self.timer is not None:
194 return self.timer.GetInterval()
195 else:
196 return 0
197
198
199 def IsRunning(self):
200 return self.timer is not None and self.timer.IsRunning()
201
202
203 def SetArgs(self, *args, **kwargs):
204 """
205 (Re)set the args passed to the callable object. This is
206 useful in conjunction with Restart if you want to schedule a
207 new call to the same callable object but with different
208 parameters.
209 """
210 self.args = args
211 self.kwargs = kwargs
212
213
214 def HasRun(self):
215 return self.hasRun
216
217 def GetResult(self):
218 return self.result
219
220 def Notify(self):
221 """
222 The timer has expired so call the callable.
223 """
224 if self.callable and getattr(self.callable, 'im_self', True):
225 self.runCount += 1
66065839 226 self.running = False
d14a1e28
RD
227 self.result = self.callable(*self.args, **self.kwargs)
228 self.hasRun = True
66065839
RD
229 if not self.running:
230 # if it wasn't restarted, then cleanup
231 wx.CallAfter(self.Stop)
d14a1e28
RD
232
233
5b29df3f
RD
234
235#----------------------------------------------------------------------------
236# Control which items in this module should be documented by epydoc.
237# We allow only classes and functions, which will help reduce the size
238# of the docs by filtering out the zillions of constants, EVT objects,
239# and etc that don't make much sense by themselves, but are instead
240# documented (or will be) as part of the classes/functions/methods
241# where they should be used.
242
99109c0f
RD
243class __DocFilter:
244 """
245 A filter for epydoc that only allows non-Ptr classes and
246 fucntions, in order to reduce the clutter in the API docs.
247 """
248 def __init__(self, globals):
249 self._globals = globals
250
251 def __call__(self, name):
252 import types
253 obj = self._globals.get(name, None)
254 if type(obj) not in [type, types.ClassType, types.FunctionType, types.BuiltinFunctionType]:
255 return False
256 if name.startswith('_') or name.endswith('Ptr') or name.startswith('EVT'):
257 return False
258 return True
5b29df3f 259
d14a1e28
RD
260#----------------------------------------------------------------------------
261#----------------------------------------------------------------------------
262
263# Import other modules in this package that should show up in the
264# "core" wx namespace
54f9ee45
RD
265from _gdi import *
266from _windows import *
267from _controls import *
268from _misc import *
d14a1e28 269
9e58eb56
RD
270
271# Fixup the stock objects since they can't be used yet. (They will be
272# restored in wx.PyApp.OnInit.)
54f9ee45 273_core_._wxPyFixStockObjects()
9e58eb56 274
d14a1e28
RD
275#----------------------------------------------------------------------------
276#----------------------------------------------------------------------------