1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Helper functions/classes for the wxPython extenaion module
9 // Copyright: (c) 1998 by Total Control Software
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
13 #ifndef __wxp_helpers__
14 #define __wxp_helpers__
19 //----------------------------------------------------------------------
21 // if we want to handle threads and Python threads are available...
22 #if defined(WXP_USE_THREAD) && defined(WITH_THREAD)
24 #define WXP_WITH_THREAD
25 #define wxPy_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
26 #define wxPy_END_ALLOW_THREADS Py_END_ALLOW_THREADS
28 #else // no Python threads...
29 #undef WXP_WITH_THREAD
30 #define wxPy_BEGIN_ALLOW_THREADS
31 #define wxPy_END_ALLOW_THREADS
35 //---------------------------------------------------------------------------
37 #if defined(__WXMSW__)
38 # define HELPEREXPORT __declspec(dllexport)
43 //----------------------------------------------------------------------
45 class wxPyApp
: public wxApp
52 //# void AfterMainLoop(void);
55 extern wxPyApp
*wxPythonApp
;
57 //----------------------------------------------------------------------
60 PyObject
* __wxStart(PyObject
*, PyObject
* args
);
62 extern PyObject
* wxPython_dict
;
63 PyObject
* __wxSetDictionary(PyObject
*, PyObject
* args
);
65 void wxPyEventThunker(wxObject
*, wxEvent
& event
);
67 HELPEREXPORT PyObject
* wxPyConstructObject(void* ptr
, char* className
);
68 HELPEREXPORT
bool wxPyRestoreThread();
69 HELPEREXPORT
void wxPySaveThread(bool doSave
);
70 HELPEREXPORT PyObject
* wxPy_ConvertList(wxListBase
* list
, char* className
);
72 //----------------------------------------------------------------------
76 extern "C" void SWIG_MakePtr(char *, void *, char *);
77 extern "C" char *SWIG_GetPtr(char *, void **, char *);
78 extern "C" char *SWIG_GetPtrObj(PyObject
*obj
, void **ptr
, char *type
);
83 # pragma warning(disable:4800)
86 typedef unsigned char byte
;
89 // Non-const versions to keep SWIG happy.
90 extern wxPoint wxPyDefaultPosition
;
91 extern wxSize wxPyDefaultSize
;
92 extern wxString wxPyEmptyStr
;
94 //----------------------------------------------------------------------
96 class wxPyCallback
: public wxObject
{
98 wxPyCallback(PyObject
* func
);
101 void EventThunker(wxEvent
& event
);
106 //---------------------------------------------------------------------------
108 // class wxPyMenu : public wxMenu {
110 // wxPyMenu(const wxString& title = "", PyObject* func=NULL);
114 // static void MenuCallback(wxMenu& menu, wxCommandEvent& evt);
119 //---------------------------------------------------------------------------
121 class wxPyTimer
: public wxTimer
{
123 wxPyTimer(PyObject
* callback
);
132 //---------------------------------------------------------------------------
134 class wxPyEvent
: public wxCommandEvent
{
135 DECLARE_DYNAMIC_CLASS(wxPyEvent
)
137 wxPyEvent(wxEventType commandType
= wxEVT_NULL
, PyObject
* userData
= Py_None
);
140 void SetUserData(PyObject
* userData
);
141 PyObject
* GetUserData();
144 PyObject
* m_userData
;
151 //---------------------------------------------------------------------------
152 // This class holds an instance of a Python Shadow Class object and assists
153 // with looking up and invoking Python callback methods from C++ virtual
154 // method redirections. For all classes which have virtuals which should be
155 // overridable in wxPython, a new subclass is created that contains a
156 // wxPyCallbackHelper.
158 // **** This class should be combined with wxPyCallback defined above.
160 //---------------------------------------------------------------------------
162 class HELPEREXPORT wxPyCallbackHelper
{
164 wxPyCallbackHelper();
165 ~wxPyCallbackHelper();
167 void setSelf(PyObject
* self
);
169 bool findCallback(const wxString
& name
);
170 int callCallback(PyObject
* argTuple
);
171 PyObject
* callCallbackObj(PyObject
* argTuple
);
175 PyObject
* m_lastFound
;
180 //---------------------------------------------------------------------------
181 // These macros are used to implement the virtual methods that should
182 // redirect to a Python method if one exists. The names designate the
183 // return type, if any as well as any parameter types.
184 //---------------------------------------------------------------------------
187 void _setSelf(PyObject* self) { \
188 m_myInst.setSelf(self); \
190 private: wxPyCallbackHelper m_myInst;
192 //---------------------------------------------------------------------------
194 #define DEC_PYCALLBACK__(CBNAME) \
196 void base_##CBNAME();
199 #define IMP_PYCALLBACK__(CLASS, PCLASS, CBNAME) \
200 void CLASS::CBNAME() { \
201 bool doSave = wxPyRestoreThread(); \
202 if (m_myInst.findCallback(#CBNAME)) \
203 m_myInst.callCallback(Py_BuildValue("()")); \
206 wxPySaveThread(doSave); \
208 void CLASS::base_##CBNAME() { \
212 //---------------------------------------------------------------------------
214 #define DEC_PYCALLBACK_BOOL_INTINT(CBNAME) \
215 bool CBNAME(int a, int b); \
216 bool base_##CBNAME(int a, int b);
219 #define IMP_PYCALLBACK_BOOL_INTINT(CLASS, PCLASS, CBNAME) \
220 bool CLASS::CBNAME(int a, int b) { \
222 bool doSave = wxPyRestoreThread(); \
223 if (m_myInst.findCallback(#CBNAME)) \
224 rval = m_myInst.callCallback(Py_BuildValue("(ii)",a,b)); \
226 rval = PCLASS::CBNAME(a,b); \
227 wxPySaveThread(doSave); \
230 bool CLASS::base_##CBNAME(int a, int b) { \
231 return PCLASS::CBNAME(a,b); \
234 //---------------------------------------------------------------------------
236 #define DEC_PYCALLBACK_BOOL_INT(CBNAME) \
237 bool CBNAME(int a); \
238 bool base_##CBNAME(int a);
241 #define IMP_PYCALLBACK_BOOL_INT(CLASS, PCLASS, CBNAME) \
242 bool CLASS::CBNAME(int a) { \
244 bool doSave = wxPyRestoreThread(); \
245 if (m_myInst.findCallback(#CBNAME)) \
246 rval = m_myInst.callCallback(Py_BuildValue("(i)",a)); \
248 rval = PCLASS::CBNAME(a); \
249 wxPySaveThread(doSave); \
252 bool CLASS::base_##CBNAME(int a) { \
253 return PCLASS::CBNAME(a); \
256 //---------------------------------------------------------------------------
258 #define DEC_PYCALLBACK_BOOL_INT_pure(CBNAME) \
262 #define IMP_PYCALLBACK_BOOL_INT_pure(CLASS, PCLASS, CBNAME) \
263 bool CLASS::CBNAME(int a) { \
265 bool doSave = wxPyRestoreThread(); \
266 if (m_myInst.findCallback(#CBNAME)) \
267 rval = m_myInst.callCallback(Py_BuildValue("(i)",a)); \
269 wxPySaveThread(doSave); \
274 //---------------------------------------------------------------------------
276 #define DEC_PYCALLBACK__DC(CBNAME) \
277 void CBNAME(wxDC& a); \
278 void base_##CBNAME(wxDC& a);
281 #define IMP_PYCALLBACK__DC(CLASS, PCLASS, CBNAME) \
282 void CLASS::CBNAME(wxDC& a) { \
283 bool doSave = wxPyRestoreThread(); \
284 if (m_myInst.findCallback(#CBNAME)) \
285 m_myInst.callCallback(Py_BuildValue("(O)", \
286 wxPyConstructObject(&a, "wxDC"))); \
289 wxPySaveThread(doSave); \
291 void CLASS::base_##CBNAME(wxDC& a) { \
297 //---------------------------------------------------------------------------
299 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
300 void CBNAME(wxDC& a, bool b); \
301 void base_##CBNAME(wxDC& a, bool b);
304 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
305 void CLASS::CBNAME(wxDC& a, bool b) { \
306 bool doSave = wxPyRestoreThread(); \
307 if (m_myInst.findCallback(#CBNAME)) \
308 m_myInst.callCallback(Py_BuildValue("(Oi)", \
309 wxPyConstructObject(&a, "wxDC"), (int)b)); \
311 PCLASS::CBNAME(a, b); \
312 wxPySaveThread(doSave); \
314 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
315 PCLASS::CBNAME(a, b); \
318 //---------------------------------------------------------------------------
320 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
321 void CBNAME(wxDC& a, bool b); \
322 void base_##CBNAME(wxDC& a, bool b);
325 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
326 void CLASS::CBNAME(wxDC& a, bool b) { \
327 bool doSave = wxPyRestoreThread(); \
328 if (m_myInst.findCallback(#CBNAME)) \
329 m_myInst.callCallback(Py_BuildValue("(Oi)", \
330 wxPyConstructObject(&a, "wxDC"), (int)b)); \
332 PCLASS::CBNAME(a, b); \
333 wxPySaveThread(doSave); \
335 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
336 PCLASS::CBNAME(a, b); \
339 //---------------------------------------------------------------------------
341 #define DEC_PYCALLBACK__2DBL(CBNAME) \
342 void CBNAME(double a, double b); \
343 void base_##CBNAME(double a, double b);
346 #define IMP_PYCALLBACK__2DBL(CLASS, PCLASS, CBNAME) \
347 void CLASS::CBNAME(double a, double b) { \
348 bool doSave = wxPyRestoreThread(); \
349 if (m_myInst.findCallback(#CBNAME)) \
350 m_myInst.callCallback(Py_BuildValue("(dd)",a,b)); \
352 PCLASS::CBNAME(a, b); \
353 wxPySaveThread(doSave); \
355 void CLASS::base_##CBNAME(double a, double b) { \
356 PCLASS::CBNAME(a, b); \
359 //---------------------------------------------------------------------------
361 #define DEC_PYCALLBACK__2DBL2INT(CBNAME) \
362 void CBNAME(double a, double b, int c, int d); \
363 void base_##CBNAME(double a, double b, int c, int d);
366 #define IMP_PYCALLBACK__2DBL2INT(CLASS, PCLASS, CBNAME) \
367 void CLASS::CBNAME(double a, double b, int c, int d) { \
368 bool doSave = wxPyRestoreThread(); \
369 if (m_myInst.findCallback(#CBNAME)) \
370 m_myInst.callCallback(Py_BuildValue("(ddii)", \
373 PCLASS::CBNAME(a, b, c, d); \
374 wxPySaveThread(doSave); \
376 void CLASS::base_##CBNAME(double a, double b, int c, int d) { \
377 PCLASS::CBNAME(a, b, c, d); \
380 //---------------------------------------------------------------------------
382 #define DEC_PYCALLBACK__DC4DBLBOOL(CBNAME) \
383 void CBNAME(wxDC& a, double b, double c, double d, double e, bool f); \
384 void base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
387 #define IMP_PYCALLBACK__DC4DBLBOOL(CLASS, PCLASS, CBNAME) \
388 void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \
389 bool doSave = wxPyRestoreThread(); \
390 if (m_myInst.findCallback(#CBNAME)) \
391 m_myInst.callCallback(Py_BuildValue("(Oddddi)", \
392 wxPyConstructObject(&a, "wxDC"), \
393 b, c, d, e, (int)f)); \
395 PCLASS::CBNAME(a, b, c, d, e, f); \
396 wxPySaveThread(doSave); \
398 void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
399 PCLASS::CBNAME(a, b, c, d, e, f); \
402 //---------------------------------------------------------------------------
404 #define DEC_PYCALLBACK_BOOL_DC4DBLBOOL(CBNAME) \
405 bool CBNAME(wxDC& a, double b, double c, double d, double e, bool f); \
406 bool base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
409 #define IMP_PYCALLBACK_BOOL_DC4DBLBOOL(CLASS, PCLASS, CBNAME) \
410 bool CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \
411 bool doSave = wxPyRestoreThread(); \
412 if (m_myInst.findCallback(#CBNAME)) \
413 return m_myInst.callCallback(Py_BuildValue("(Oddddi)", \
414 wxPyConstructObject(&a, "wxDC"), \
415 b, c, d, e, (int)f)); \
417 return PCLASS::CBNAME(a, b, c, d, e, f); \
418 wxPySaveThread(doSave); \
420 bool CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
421 return PCLASS::CBNAME(a, b, c, d, e, f); \
424 //---------------------------------------------------------------------------
426 #define DEC_PYCALLBACK__BOOL2DBL2INT(CBNAME) \
427 void CBNAME(bool a, double b, double c, int d, int e); \
428 void base_##CBNAME(bool a, double b, double c, int d, int e);
431 #define IMP_PYCALLBACK__BOOL2DBL2INT(CLASS, PCLASS, CBNAME) \
432 void CLASS::CBNAME(bool a, double b, double c, int d, int e) { \
433 bool doSave = wxPyRestoreThread(); \
434 if (m_myInst.findCallback(#CBNAME)) \
435 m_myInst.callCallback(Py_BuildValue("(idii)", \
438 PCLASS::CBNAME(a, b, c, d, e); \
439 wxPySaveThread(doSave); \
441 void CLASS::base_##CBNAME(bool a, double b, double c, int d, int e) { \
442 PCLASS::CBNAME(a, b, c, d, e); \
445 //---------------------------------------------------------------------------
447 #define DEC_PYCALLBACK__DC4DBL(CBNAME) \
448 void CBNAME(wxDC& a, double b, double c, double d, double e); \
449 void base_##CBNAME(wxDC& a, double b, double c, double d, double e);
452 #define IMP_PYCALLBACK__DC4DBL(CLASS, PCLASS, CBNAME) \
453 void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e) { \
454 bool doSave = wxPyRestoreThread(); \
455 if (m_myInst.findCallback(#CBNAME)) \
456 m_myInst.callCallback(Py_BuildValue("(Odddd)", \
457 wxPyConstructObject(&a, "wxDC"), \
460 PCLASS::CBNAME(a, b, c, d, e); \
461 wxPySaveThread(doSave); \
463 void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e) {\
464 PCLASS::CBNAME(a, b, c, d, e); \
467 //---------------------------------------------------------------------------
469 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
470 void CBNAME(wxDC& a, bool b); \
471 void base_##CBNAME(wxDC& a, bool b);
474 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
475 void CLASS::CBNAME(wxDC& a, bool b) { \
476 bool doSave = wxPyRestoreThread(); \
477 if (m_myInst.findCallback(#CBNAME)) \
478 m_myInst.callCallback(Py_BuildValue("(Oi)", \
479 wxPyConstructObject(&a, "wxDC"), \
482 PCLASS::CBNAME(a, b); \
483 wxPySaveThread(doSave); \
485 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
486 PCLASS::CBNAME(a, b); \
489 //---------------------------------------------------------------------------
491 #define DEC_PYCALLBACK__WXCPBOOL2DBL2INT(CBNAME) \
492 void CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f); \
493 void base_##CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f);
496 #define IMP_PYCALLBACK__WXCPBOOL2DBL2INT(CLASS, PCLASS, CBNAME) \
497 void CLASS::CBNAME(wxControlPoint* a, bool b, double c, double d, \
499 bool doSave = wxPyRestoreThread(); \
500 if (m_myInst.findCallback(#CBNAME)) \
501 m_myInst.callCallback(Py_BuildValue("(Oiddii)", \
502 wxPyConstructObject(a, "wxControlPoint"), \
503 (int)b, c, d, e, f)); \
505 PCLASS::CBNAME(a, b, c, d, e, f); \
506 wxPySaveThread(doSave); \
508 void CLASS::base_##CBNAME(wxControlPoint* a, bool b, double c, double d, \
510 PCLASS::CBNAME(a, b, c, d, e, f); \
513 //---------------------------------------------------------------------------
515 #define DEC_PYCALLBACK__WXCP2DBL2INT(CBNAME) \
516 void CBNAME(wxControlPoint* a, double b, double c, int d, int e); \
517 void base_##CBNAME(wxControlPoint* a, double b, double c, int d, int e);
520 #define IMP_PYCALLBACK__WXCP2DBL2INT(CLASS, PCLASS, CBNAME) \
521 void CLASS::CBNAME(wxControlPoint* a, double b, double c, int d, int e) { \
522 bool doSave = wxPyRestoreThread(); \
523 if (m_myInst.findCallback(#CBNAME)) \
524 m_myInst.callCallback(Py_BuildValue("(Oddii)", \
525 wxPyConstructObject(a, "wxControlPoint"), \
528 PCLASS::CBNAME(a, b, c, d, e); \
529 wxPySaveThread(doSave); \
531 void CLASS::base_##CBNAME(wxControlPoint* a, double b, double c, \
533 PCLASS::CBNAME(a, b, c, d, e); \
536 //---------------------------------------------------------------------------
538 #define DEC_PYCALLBACK__2DBLINT(CBNAME) \
539 void CBNAME(double a, double b, int c); \
540 void base_##CBNAME(double a, double b, int c);
543 #define IMP_PYCALLBACK__2DBLINT(CLASS, PCLASS, CBNAME) \
544 void CLASS::CBNAME(double a, double b, int c) { \
545 bool doSave = wxPyRestoreThread(); \
546 if (m_myInst.findCallback(#CBNAME)) \
547 m_myInst.callCallback(Py_BuildValue("(ddi)", a,b,c)); \
549 PCLASS::CBNAME(a, b, c); \
550 wxPySaveThread(doSave); \
552 void CLASS::base_##CBNAME(double a, double b, int c) { \
553 PCLASS::CBNAME(a, b, c); \
556 //---------------------------------------------------------------------------
558 #define DEC_PYCALLBACK__BOOL2DBLINT(CBNAME) \
559 void CBNAME(bool a, double b, double c, int d); \
560 void base_##CBNAME(bool a, double b, double c, int d);
563 #define IMP_PYCALLBACK__BOOL2DBLINT(CLASS, PCLASS, CBNAME) \
564 void CLASS::CBNAME(bool a, double b, double c, int d) { \
565 bool doSave = wxPyRestoreThread(); \
566 if (m_myInst.findCallback(#CBNAME)) \
567 m_myInst.callCallback(Py_BuildValue("(iddi)", (int)a,b,c,d)); \
569 PCLASS::CBNAME(a, b, c, d); \
570 wxPySaveThread(doSave); \
572 void CLASS::base_##CBNAME(bool a, double b, double c, int d) { \
573 PCLASS::CBNAME(a, b, c, d); \
576 //---------------------------------------------------------------------------
577 //---------------------------------------------------------------------------
579 #define DEC_PYCALLBACK__STRING(CBNAME) \
580 void CBNAME(const wxString& a); \
581 void base_##CBNAME(const wxString& a);
584 #define IMP_PYCALLBACK__STRING(CLASS, PCLASS, CBNAME) \
585 void CLASS::CBNAME(const wxString& a) { \
586 bool doSave = wxPyRestoreThread(); \
587 if (m_myInst.findCallback(#CBNAME)) \
588 m_myInst.callCallback(Py_BuildValue("(s)", a.c_str())); \
591 wxPySaveThread(doSave); \
593 void CLASS::base_##CBNAME(const wxString& a) { \
597 //---------------------------------------------------------------------------
599 #define DEC_PYCALLBACK_BOOL_STRING(CBNAME) \
600 bool CBNAME(const wxString& a); \
601 bool base_##CBNAME(const wxString& a);
604 #define IMP_PYCALLBACK_BOOL_STRING(CLASS, PCLASS, CBNAME) \
605 bool CLASS::CBNAME(const wxString& a) { \
607 bool doSave = wxPyRestoreThread(); \
608 if (m_myInst.findCallback(#CBNAME)) \
609 rval = m_myInst.callCallback(Py_BuildValue("(s)", a.c_str())); \
611 rval = PCLASS::CBNAME(a); \
612 wxPySaveThread(doSave); \
615 bool CLASS::base_##CBNAME(const wxString& a) { \
616 return PCLASS::CBNAME(a); \
619 //---------------------------------------------------------------------------
621 #define DEC_PYCALLBACK_STRING_(CBNAME) \
623 wxString base_##CBNAME();
626 #define IMP_PYCALLBACK_STRING_(CLASS, PCLASS, CBNAME) \
627 wxString CLASS::CBNAME() { \
629 bool doSave = wxPyRestoreThread(); \
630 if (m_myInst.findCallback(#CBNAME)) { \
632 ro = m_myInst.callCallbackObj(Py_BuildValue("()")); \
633 rval = PyString_AsString(PyObject_Str(ro)); \
636 rval = PCLASS::CBNAME(a); \
637 wxPySaveThread(doSave); \
640 bool CLASS::base_##CBNAME(const wxString& a) { \
641 return PCLASS::CBNAME(a); \
644 //---------------------------------------------------------------------------
646 #define DEC_PYCALLBACK_STRING__pure(CBNAME) \
650 #define IMP_PYCALLBACK_STRING__pure(CLASS, PCLASS, CBNAME) \
651 wxString CLASS::CBNAME() { \
653 bool doSave = wxPyRestoreThread(); \
654 if (m_myInst.findCallback(#CBNAME)) { \
656 ro = m_myInst.callCallbackObj(Py_BuildValue("()")); \
657 rval = PyString_AsString(PyObject_Str(ro)); \
659 wxPySaveThread(doSave); \
663 //---------------------------------------------------------------------------
665 #define DEC_PYCALLBACK_BOOL_TAG_pure(CBNAME) \
666 bool CBNAME(const wxHtmlTag& a); \
669 #define IMP_PYCALLBACK_BOOL_TAG_pure(CLASS, PCLASS, CBNAME) \
670 bool CLASS::CBNAME(const wxHtmlTag& a) { \
672 bool doSave = wxPyRestoreThread(); \
673 if (m_myInst.findCallback(#CBNAME)) \
674 rval = m_myInst.callCallback(Py_BuildValue("(O)", \
675 wxPyConstructObject((void*)&a,"wxHtmlTag"))); \
676 wxPySaveThread(doSave); \
680 //---------------------------------------------------------------------------
681 //---------------------------------------------------------------------------
682 //---------------------------------------------------------------------------
683 //---------------------------------------------------------------------------
684 //---------------------------------------------------------------------------