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