]> git.saurik.com Git - wxWidgets.git/blame - utils/wxPython/src/helpers.cpp
Now uses proper wxUSE_xxx flags
[wxWidgets.git] / utils / wxPython / src / helpers.cpp
CommitLineData
7bf85405
RD
1/////////////////////////////////////////////////////////////////////////////
2// Name: helpers.cpp
03e9bead 3// Purpose: Helper functions/classes for the wxPython extension module
7bf85405
RD
4//
5// Author: Robin Dunn
6//
7// Created: 7/1/97
8// RCS-ID: $Id$
9// Copyright: (c) 1998 by Total Control Software
10// Licence: wxWindows license
11/////////////////////////////////////////////////////////////////////////////
12
21f4bf45 13
08127323
RD
14#ifdef __WXGTK__
15#include "gtk/gtk.h"
16#endif
17
7bf85405
RD
18#undef DEBUG
19#include <Python.h>
20#include "helpers.h"
af309447
RD
21#ifdef __WXMSW__
22#include <wx/msw/private.h>
23#undef FindWindow
24#undef GetCharWidth
25#undef LoadAccelerators
26#undef GetClassInfo
27#undef GetClassName
28#endif
dd9a3de8 29#include <wx/module.h>
7bf85405 30
cf694132 31
7bf85405
RD
32//---------------------------------------------------------------------------
33
34//wxHashTable* wxPyWindows = NULL;
35
36
37wxPoint wxPyDefaultPosition; //wxDefaultPosition);
38wxSize wxPyDefaultSize; //wxDefaultSize);
39wxString wxPyEmptyStr("");
40
41
42
21f4bf45 43#ifdef __WXMSW__ // If building for win32...
21f4bf45
RD
44//----------------------------------------------------------------------
45// This gets run when the DLL is loaded. We just need to save a handle.
46//----------------------------------------------------------------------
9c039d08 47
21f4bf45
RD
48BOOL WINAPI DllMain(
49 HINSTANCE hinstDLL, // handle to DLL module
50 DWORD fdwReason, // reason for calling function
51 LPVOID lpvReserved // reserved
52 )
53{
af309447 54 wxSetInstance(hinstDLL);
21f4bf45
RD
55 return 1;
56}
57#endif
58
7bf85405
RD
59//----------------------------------------------------------------------
60// Class for implementing the wxp main application shell.
61//----------------------------------------------------------------------
62
63wxPyApp *wxPythonApp = NULL; // Global instance of application object
64
65
cf694132
RD
66wxPyApp::wxPyApp() {
67// printf("**** ctor\n");
68}
69
70wxPyApp::~wxPyApp() {
71// printf("**** dtor\n");
72}
73
74
7bf85405
RD
75// This one isn't acutally called... See __wxStart()
76bool wxPyApp::OnInit(void) {
77 return false;
78}
79
80int wxPyApp::MainLoop(void) {
81 int retval = wxApp::MainLoop();
82 AfterMainLoop();
83 return retval;
84}
85
af309447 86
7bf85405
RD
87void wxPyApp::AfterMainLoop(void) {
88 // more stuff from wxEntry...
0d6f9504 89
7bf85405
RD
90 if (wxPythonApp->GetTopWindow()) {
91 // Forcibly delete the window.
92 if (wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)) ||
93 wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog))) {
94
95 wxPythonApp->GetTopWindow()->Close(TRUE);
96 wxPythonApp->DeletePendingObjects();
97 }
98 else {
99 delete wxPythonApp->GetTopWindow();
100 wxPythonApp->SetTopWindow(NULL);
101 }
102 }
0d6f9504
RD
103#ifdef __WXGTK__
104 wxPythonApp->DeletePendingObjects();
105#endif
7bf85405
RD
106
107 wxPythonApp->OnExit();
7bf85405 108 wxApp::CleanUp();
b8b8dda7 109// delete wxPythonApp;
7bf85405
RD
110}
111
112
fb5e0af0 113//---------------------------------------------------------------------
7bf85405
RD
114// a few native methods to add to the module
115//----------------------------------------------------------------------
116
117
0d6f9504 118// This is where we pick up the first part of the wxEntry functionality...
4464bbee 119// The rest is in __wxStart and AfterMainLoop. This function is called when
0d6f9504
RD
120// wxpc is imported. (Before there is a wxApp object.)
121void __wxPreStart()
7bf85405 122{
0d6f9504
RD
123 // Bail out if there is already windows created. This means that the
124 // toolkit has already been initialized, as in embedding wxPython in
125 // a C++ wxWindows app.
126 if (wxTopLevelWindows.Number() > 0)
127 return;
7bf85405 128
7bf85405 129#ifdef __WXMSW__
9c039d08 130 wxApp::Initialize();
7bf85405 131#endif
21f4bf45 132
08127323 133#ifdef __WXGTK__
fb5e0af0
RD
134 PyObject* sysargv = PySys_GetObject("argv");
135 int argc = PyList_Size(sysargv);
136 char** argv = new char*[argc+1];
137 int x;
138 for(x=0; x<argc; x++)
139 argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
140 argv[argc] = NULL;
141
08127323 142 gtk_set_locale();
0d6f9504
RD
143 gtk_init( &argc, &argv );
144 delete [] argv;
7bf85405 145
08127323 146 wxApp::Initialize(); // may return FALSE. Should we check?
7bf85405
RD
147#endif
148
0d6f9504
RD
149}
150
151
cf694132 152#ifdef WXP_WITH_THREAD
bb0054cd
RD
153PyThreadState* wxPyEventThreadState = NULL;
154bool wxPyInEvent = false;
cf694132 155#endif
0d6f9504
RD
156static char* __nullArgv[1] = { 0 };
157
158// Start the user application, user App's OnInit method is a parameter here
159PyObject* __wxStart(PyObject* /* self */, PyObject* args)
160{
161 PyObject* onInitFunc = NULL;
162 PyObject* arglist;
163 PyObject* result;
164 long bResult;
165
cf694132 166#ifdef WXP_WITH_THREAD
bb0054cd 167 wxPyEventThreadState = PyThreadState_Get();
cf694132 168#endif
0d6f9504
RD
169
170 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
171 return NULL;
172
173 if (wxTopLevelWindows.Number() > 0) {
174 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
175 return NULL;
176 }
177
178
179 // This is the next part of the wxEntry functionality...
180 wxPythonApp->argc = 0;
cf694132 181 wxPythonApp->argv = NULL;
0d6f9504
RD
182 wxPythonApp->OnInitGui();
183
7bf85405
RD
184
185 // Call the Python App's OnInit function
186 arglist = PyTuple_New(0);
cf694132
RD
187
188 // Py_END_ALLOW_THREADS; **** __wxStart was called from Python,
189 // should already have the lock
7bf85405 190 result = PyEval_CallObject(onInitFunc, arglist);
cf694132
RD
191 // Py_BEGIN_ALLOW_THREADS;
192
7bf85405
RD
193 if (!result) {
194 PyErr_Print();
195 exit(1);
196 }
197
198 if (! PyInt_Check(result)) {
199 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
200 return NULL;
201 }
202 bResult = PyInt_AS_LONG(result);
203 if (! bResult) {
204 wxPythonApp->DeletePendingObjects();
205 wxPythonApp->OnExit();
fb5e0af0 206 wxApp::CleanUp();
7bf85405
RD
207 PyErr_SetString(PyExc_SystemExit, "OnInit returned false, exiting...");
208 return NULL;
209 }
210
13dfc243 211#ifdef __WXGTK__
fb5e0af0 212 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
13dfc243 213#endif
fb5e0af0 214
7bf85405
RD
215 Py_INCREF(Py_None);
216 return Py_None;
217}
218
219
7bf85405
RD
220
221
222
223PyObject* wxPython_dict;
224PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
225{
226
227 if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
228 return NULL;
229
230 if (!PyDict_Check(wxPython_dict)) {
231 PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
232 return NULL;
233 }
234#ifdef __WXMOTIF__
21f4bf45
RD
235#define wxPlatform "__WXMOTIF__"
236#endif
237#ifdef __WXQT__
238#define wxPlatform "__WXQT__"
7bf85405
RD
239#endif
240#ifdef __WXGTK__
21f4bf45 241#define wxPlatform "__WXGTK__"
7bf85405
RD
242#endif
243#if defined(__WIN32__) || defined(__WXMSW__)
fb5e0af0 244#define wxPlatform "__WXMSW__"
7bf85405
RD
245#endif
246#ifdef __WXMAC__
21f4bf45 247#define wxPlatform "__WXMAC__"
7bf85405
RD
248#endif
249
250 PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
251
252 Py_INCREF(Py_None);
253 return Py_None;
254}
255
256
257//---------------------------------------------------------------------------
258
259
260static
261PyObject* wxPyConstructObject(void* ptr, char* className)
262{
9c039d08 263 char buff[64]; // should always be big enough...
7bf85405
RD
264 char swigptr[64];
265
266 sprintf(buff, "_%s_p", className);
267 SWIG_MakePtr(swigptr, ptr, buff);
268
269 sprintf(buff, "%sPtr", className);
270 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
271 if (! classobj) {
272 Py_INCREF(Py_None);
273 return Py_None;
274 }
275
276 PyObject* arg = Py_BuildValue("(s)", swigptr);
277 PyObject* obj = PyInstance_New(classobj, arg, NULL);
278 Py_DECREF(arg);
279
280 return obj;
281}
282
283
cf694132
RD
284
285wxPyCallback::wxPyCallback(PyObject* func) {
286 m_func = func;
287 Py_INCREF(m_func);
288}
289
290wxPyCallback::~wxPyCallback() {
291#ifdef WXP_WITH_THREAD
bb0054cd
RD
292 //if (! wxPyInEvent)
293 PyEval_RestoreThread(wxPyEventThreadState);
cf694132
RD
294#endif
295
296 Py_DECREF(m_func);
297
298#ifdef WXP_WITH_THREAD
bb0054cd
RD
299 //if (! wxPyInEvent)
300 PyEval_SaveThread();
cf694132
RD
301#endif
302}
303
304
305
306
7bf85405
RD
307// This function is used for all events destined for Python event handlers.
308void wxPyCallback::EventThunker(wxEvent& event) {
309 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
310 PyObject* func = cb->m_func;
311 PyObject* result;
312 PyObject* arg;
313 PyObject* tuple;
314
cf694132
RD
315
316#ifdef WXP_WITH_THREAD
bb0054cd
RD
317 PyEval_RestoreThread(wxPyEventThreadState);
318 wxPyInEvent = true;
cf694132 319#endif
7bf85405
RD
320 arg = wxPyConstructObject((void*)&event, event.GetClassInfo()->GetClassName());
321
322 tuple = PyTuple_New(1);
323 PyTuple_SET_ITEM(tuple, 0, arg);
324 result = PyEval_CallObject(func, tuple);
7bf85405
RD
325 Py_DECREF(tuple);
326 if (result) {
327 Py_DECREF(result);
328 PyErr_Clear();
329 } else {
330 PyErr_Print();
331 }
cf694132
RD
332#ifdef WXP_WITH_THREAD
333 PyEval_SaveThread();
bb0054cd 334 wxPyInEvent = false;
cf694132 335#endif
7bf85405
RD
336}
337
338
339//---------------------------------------------------------------------------
340
341wxPyMenu::wxPyMenu(const wxString& title, PyObject* _func)
342 : wxMenu(title, (wxFunction)(func ? MenuCallback : NULL)), func(0) {
343
344 if (_func) {
345 func = _func;
346 Py_INCREF(func);
347 }
348}
349
350wxPyMenu::~wxPyMenu() {
bb0054cd
RD
351#ifdef WXP_WITH_THREAD
352 //if (! wxPyInEvent)
353 PyEval_RestoreThread(wxPyEventThreadState);
354#endif
355
7bf85405
RD
356 if (func)
357 Py_DECREF(func);
bb0054cd
RD
358
359#ifdef WXP_WITH_THREAD
360 //if (! wxPyInEvent)
361 PyEval_SaveThread();
362#endif
7bf85405
RD
363}
364
365
366void wxPyMenu::MenuCallback(wxMenu& menu, wxCommandEvent& evt) {
bb0054cd
RD
367 PyObject* evtobj;
368 PyObject* menuobj;
369 PyObject* func;
370 PyObject* args;
371 PyObject* res;
372
cf694132 373#ifdef WXP_WITH_THREAD
bb0054cd
RD
374 PyEval_RestoreThread(wxPyEventThreadState);
375 wxPyInEvent = true;
cf694132 376#endif
bb0054cd
RD
377 evtobj = wxPyConstructObject((void*)&evt, "wxCommandEvent");
378 menuobj = wxPyConstructObject((void*)&menu, "wxMenu");
7bf85405
RD
379 if (PyErr_Occurred()) {
380 // bail out if a problem
381 PyErr_Print();
bb0054cd 382 goto done;
7bf85405
RD
383 }
384 // Now call the callback...
bb0054cd
RD
385 func = ((wxPyMenu*)&menu)->func;
386 args = PyTuple_New(2);
d5c9047a
RD
387 PyTuple_SET_ITEM(args, 0, menuobj);
388 PyTuple_SET_ITEM(args, 1, evtobj);
bb0054cd 389 res = PyEval_CallObject(func, args);
7bf85405 390 Py_DECREF(args);
d5c9047a 391 Py_XDECREF(res); /* In case res is a NULL pointer */
bb0054cd 392 done:
cf694132
RD
393#ifdef WXP_WITH_THREAD
394 PyEval_SaveThread();
bb0054cd 395 wxPyInEvent = false;
cf694132 396#endif
7bf85405 397}
714e6a9e 398
7bf85405
RD
399
400//---------------------------------------------------------------------------
401
402wxPyTimer::wxPyTimer(PyObject* callback) {
403 func = callback;
404 Py_INCREF(func);
405}
406
407wxPyTimer::~wxPyTimer() {
bb0054cd
RD
408#ifdef WXP_WITH_THREAD
409 //if (! wxPyInEvent)
410 PyEval_RestoreThread(wxPyEventThreadState);
411#endif
412
7bf85405 413 Py_DECREF(func);
bb0054cd
RD
414
415#ifdef WXP_WITH_THREAD
416 //if (! wxPyInEvent)
417 PyEval_SaveThread();
418#endif
7bf85405
RD
419}
420
421void wxPyTimer::Notify() {
cf694132 422#ifdef WXP_WITH_THREAD
bb0054cd
RD
423 PyEval_RestoreThread(wxPyEventThreadState);
424 wxPyInEvent = true;
cf694132 425#endif
7bf85405
RD
426 PyObject* result;
427 PyObject* args = Py_BuildValue("()");
428
429 result = PyEval_CallObject(func, args);
430 Py_DECREF(args);
431 if (result) {
432 Py_DECREF(result);
433 PyErr_Clear();
434 } else {
435 PyErr_Print();
436 }
cf694132
RD
437#ifdef WXP_WITH_THREAD
438 PyEval_SaveThread();
bb0054cd 439 wxPyInEvent = false;
cf694132 440#endif
7bf85405
RD
441}
442
443
cf694132
RD
444//----------------------------------------------------------------------
445
446IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxCommandEvent)
447
448wxPyEvent::wxPyEvent(wxEventType commandType, PyObject* userData)
449 : wxCommandEvent(commandType), m_userData(Py_None)
450{
451 m_userData = userData;
452 if (m_userData != Py_None) {
453 Py_INCREF(m_userData);
454 }
455}
456
457
458wxPyEvent::~wxPyEvent() {
bb0054cd
RD
459#ifdef WXP_WITH_THREAD
460 //if (! wxPyInEvent)
461 PyEval_RestoreThread(wxPyEventThreadState);
462#endif
cf694132
RD
463 if (m_userData != Py_None) {
464 Py_DECREF(m_userData);
465 m_userData = Py_None;
466 }
bb0054cd
RD
467#ifdef WXP_WITH_THREAD
468 //if (! wxPyInEvent)
469 PyEval_SaveThread();
470#endif
cf694132
RD
471}
472
473
474void wxPyEvent::SetUserData(PyObject* userData) {
475 if (m_userData != Py_None) {
476 Py_DECREF(m_userData);
477 m_userData = Py_None;
478 }
479 m_userData = userData;
480 if (m_userData != Py_None) {
481 Py_INCREF(m_userData);
482 }
483}
484
485
486PyObject* wxPyEvent::GetUserData() {
487 return m_userData;
488}
7bf85405 489
7bf85405
RD
490//----------------------------------------------------------------------
491//----------------------------------------------------------------------
492// Some helper functions for typemaps in my_typemaps.i, so they won't be
493// imcluded in every file...
494
495
b639c3c5
RD
496byte* byte_LIST_helper(PyObject* source) {
497 if (!PyList_Check(source)) {
498 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
499 return NULL;
500 }
501 int count = PyList_Size(source);
502 byte* temp = new byte[count];
503 if (! temp) {
504 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
505 return NULL;
506 }
507 for (int x=0; x<count; x++) {
508 PyObject* o = PyList_GetItem(source, x);
509 if (! PyInt_Check(o)) {
510 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
511 return NULL;
512 }
513 temp[x] = (byte)PyInt_AsLong(o);
514 }
515 return temp;
516}
517
518
7bf85405
RD
519int* int_LIST_helper(PyObject* source) {
520 if (!PyList_Check(source)) {
521 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
522 return NULL;
523 }
524 int count = PyList_Size(source);
525 int* temp = new int[count];
526 if (! temp) {
527 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
528 return NULL;
529 }
530 for (int x=0; x<count; x++) {
531 PyObject* o = PyList_GetItem(source, x);
532 if (! PyInt_Check(o)) {
533 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
534 return NULL;
535 }
536 temp[x] = PyInt_AsLong(o);
537 }
538 return temp;
539}
540
541
542long* long_LIST_helper(PyObject* source) {
543 if (!PyList_Check(source)) {
544 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
545 return NULL;
546 }
547 int count = PyList_Size(source);
548 long* temp = new long[count];
549 if (! temp) {
550 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
551 return NULL;
552 }
553 for (int x=0; x<count; x++) {
554 PyObject* o = PyList_GetItem(source, x);
555 if (! PyInt_Check(o)) {
556 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
557 return NULL;
558 }
559 temp[x] = PyInt_AsLong(o);
560 }
561 return temp;
562}
563
564
565char** string_LIST_helper(PyObject* source) {
566 if (!PyList_Check(source)) {
567 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
568 return NULL;
569 }
570 int count = PyList_Size(source);
571 char** temp = new char*[count];
572 if (! temp) {
573 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
574 return NULL;
575 }
576 for (int x=0; x<count; x++) {
577 PyObject* o = PyList_GetItem(source, x);
578 if (! PyString_Check(o)) {
579 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
580 return NULL;
581 }
582 temp[x] = PyString_AsString(o);
583 }
584 return temp;
585}
586
587
588
589wxPoint* wxPoint_LIST_helper(PyObject* source) {
590 if (!PyList_Check(source)) {
591 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
592 return NULL;
593 }
594 int count = PyList_Size(source);
595 wxPoint* temp = new wxPoint[count];
596 if (! temp) {
597 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
598 return NULL;
599 }
600 for (int x=0; x<count; x++) {
601 PyObject* o = PyList_GetItem(source, x);
602 if (PyString_Check(o)) {
603 char* st = PyString_AsString(o);
604 wxPoint* pt;
605 if (SWIG_GetPtr(st,(void **) &pt,"_wxPoint_p")) {
606 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
607 return NULL;
608 }
609 temp[x] = *pt;
610 }
611 else if (PyTuple_Check(o)) {
612 PyObject* o1 = PyTuple_GetItem(o, 0);
613 PyObject* o2 = PyTuple_GetItem(o, 1);
614
615 temp[x].x = PyInt_AsLong(o1);
616 temp[x].y = PyInt_AsLong(o2);
617 }
618 else {
619 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
620 return NULL;
621 }
622 }
623 return temp;
624}
625
626
627wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
628 if (!PyList_Check(source)) {
629 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
630 return NULL;
631 }
632 int count = PyList_Size(source);
633 wxBitmap** temp = new wxBitmap*[count];
634 if (! temp) {
635 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
636 return NULL;
637 }
638 for (int x=0; x<count; x++) {
639 PyObject* o = PyList_GetItem(source, x);
640 if (PyString_Check(o)) {
641 char* st = PyString_AsString(o);
642 wxBitmap* pt;
643 if (SWIG_GetPtr(st,(void **) &pt,"_wxBitmap_p")) {
644 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
645 return NULL;
646 }
647 temp[x] = pt;
648 }
649 else {
650 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
651 return NULL;
652 }
653 }
654 return temp;
655}
656
657
658
659wxString* wxString_LIST_helper(PyObject* source) {
660 if (!PyList_Check(source)) {
661 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
662 return NULL;
663 }
664 int count = PyList_Size(source);
665 wxString* temp = new wxString[count];
666 if (! temp) {
667 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
668 return NULL;
669 }
670 for (int x=0; x<count; x++) {
671 PyObject* o = PyList_GetItem(source, x);
672 if (! PyString_Check(o)) {
673 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
674 return NULL;
675 }
676 temp[x] = PyString_AsString(o);
677 }
678 return temp;
679}
680
681
682wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
683 if (!PyList_Check(source)) {
684 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
685 return NULL;
686 }
687 int count = PyList_Size(source);
688 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
689 if (! temp) {
690 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
691 return NULL;
692 }
693 for (int x=0; x<count; x++) {
694 PyObject* o = PyList_GetItem(source, x);
695 if (PyString_Check(o)) {
696 char* st = PyString_AsString(o);
697 wxAcceleratorEntry* ae;
698 if (SWIG_GetPtr(st,(void **) &ae,"_wxAcceleratorEntry_p")) {
699 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
700 return NULL;
701 }
702 temp[x] = *ae;
703 }
704 else if (PyTuple_Check(o)) {
705 PyObject* o1 = PyTuple_GetItem(o, 0);
706 PyObject* o2 = PyTuple_GetItem(o, 1);
707 PyObject* o3 = PyTuple_GetItem(o, 2);
708
709 temp[x].m_flags = PyInt_AsLong(o1);
710 temp[x].m_keyCode = PyInt_AsLong(o2);
711 temp[x].m_command = PyInt_AsLong(o3);
712 }
713 else {
714 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
715 return NULL;
716 }
717 }
718 return temp;
719}
720
bb0054cd
RD
721
722
723//----------------------------------------------------------------------
724//----------------------------------------------------------------------
725
726wxPyCallbackHelper::wxPyCallbackHelper() {
727 m_self = NULL;
728 m_lastFound = NULL;
729}
730
731
732wxPyCallbackHelper::~wxPyCallbackHelper() {
733#ifdef WXP_WITH_THREAD
734 PyEval_RestoreThread(wxPyEventThreadState);
735#endif
736
737 Py_XDECREF(m_self);
738
739#ifdef WXP_WITH_THREAD
740 PyEval_SaveThread();
741#endif
742}
743
744void wxPyCallbackHelper::setSelf(PyObject* self) {
745 m_self = self;
746 Py_INCREF(m_self);
747}
748
749
750
751bool wxPyCallbackHelper::findCallback(const wxString& name) {
752 m_lastFound = NULL;
753 if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str()))
754 m_lastFound = PyObject_GetAttrString(m_self, (char*)name.c_str());
755
756 return m_lastFound != NULL;
757}
758
759
760int wxPyCallbackHelper::callCallback(PyObject* argTuple) {
761 PyObject* result;
762 int retval = FALSE;
763
764 result = callCallbackObj(argTuple);
765 if (result) { // Assumes an integer return type...
766 retval = PyInt_AsLong(result);
767 Py_DECREF(result);
768 PyErr_Clear(); // forget about it if it's not...
769 }
770#ifdef WXP_WITH_THREAD
771 PyEval_SaveThread();
772#endif
773 return retval;
774}
775
776// Invoke the Python callable object, returning the raw PyObject return
777// value. Caller should DECREF the return value and also call PyEval_SaveThread.
778PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) {
779#ifdef WXP_WITH_THREAD
780 PyEval_RestoreThread(wxPyEventThreadState);
781#endif
782 PyObject* result;
783
784 result = PyEval_CallObject(m_lastFound, argTuple);
785 Py_DECREF(argTuple);
786 if (!result) {
787 PyErr_Print();
788 }
789 return result;
790}
791
792
793
794
795//----------------------------------------------------------------------
796//----------------------------------------------------------------------
7bf85405 797//----------------------------------------------------------------------
7bf85405 798
7bf85405 799
7bf85405 800