]> git.saurik.com Git - wxWidgets.git/blame - utils/wxPython/src/helpers.cpp
wxPython 2.1b1: More more set of generated sources...
[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
d24a34bb 397 return;
7bf85405 398}
714e6a9e 399
7bf85405
RD
400
401//---------------------------------------------------------------------------
402
403wxPyTimer::wxPyTimer(PyObject* callback) {
404 func = callback;
405 Py_INCREF(func);
406}
407
408wxPyTimer::~wxPyTimer() {
bb0054cd
RD
409#ifdef WXP_WITH_THREAD
410 //if (! wxPyInEvent)
411 PyEval_RestoreThread(wxPyEventThreadState);
412#endif
413
7bf85405 414 Py_DECREF(func);
bb0054cd
RD
415
416#ifdef WXP_WITH_THREAD
417 //if (! wxPyInEvent)
418 PyEval_SaveThread();
419#endif
7bf85405
RD
420}
421
422void wxPyTimer::Notify() {
cf694132 423#ifdef WXP_WITH_THREAD
bb0054cd
RD
424 PyEval_RestoreThread(wxPyEventThreadState);
425 wxPyInEvent = true;
cf694132 426#endif
7bf85405
RD
427 PyObject* result;
428 PyObject* args = Py_BuildValue("()");
429
430 result = PyEval_CallObject(func, args);
431 Py_DECREF(args);
432 if (result) {
433 Py_DECREF(result);
434 PyErr_Clear();
435 } else {
436 PyErr_Print();
437 }
cf694132
RD
438#ifdef WXP_WITH_THREAD
439 PyEval_SaveThread();
bb0054cd 440 wxPyInEvent = false;
cf694132 441#endif
7bf85405
RD
442}
443
444
cf694132
RD
445//----------------------------------------------------------------------
446
447IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxCommandEvent)
448
449wxPyEvent::wxPyEvent(wxEventType commandType, PyObject* userData)
450 : wxCommandEvent(commandType), m_userData(Py_None)
451{
452 m_userData = userData;
453 if (m_userData != Py_None) {
454 Py_INCREF(m_userData);
455 }
456}
457
458
459wxPyEvent::~wxPyEvent() {
bb0054cd
RD
460#ifdef WXP_WITH_THREAD
461 //if (! wxPyInEvent)
462 PyEval_RestoreThread(wxPyEventThreadState);
463#endif
cf694132
RD
464 if (m_userData != Py_None) {
465 Py_DECREF(m_userData);
466 m_userData = Py_None;
467 }
bb0054cd
RD
468#ifdef WXP_WITH_THREAD
469 //if (! wxPyInEvent)
470 PyEval_SaveThread();
471#endif
cf694132
RD
472}
473
474
475void wxPyEvent::SetUserData(PyObject* userData) {
476 if (m_userData != Py_None) {
477 Py_DECREF(m_userData);
478 m_userData = Py_None;
479 }
480 m_userData = userData;
481 if (m_userData != Py_None) {
482 Py_INCREF(m_userData);
483 }
484}
485
486
487PyObject* wxPyEvent::GetUserData() {
488 return m_userData;
489}
7bf85405 490
7bf85405
RD
491//----------------------------------------------------------------------
492//----------------------------------------------------------------------
493// Some helper functions for typemaps in my_typemaps.i, so they won't be
494// imcluded in every file...
495
496
b639c3c5
RD
497byte* byte_LIST_helper(PyObject* source) {
498 if (!PyList_Check(source)) {
499 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
500 return NULL;
501 }
502 int count = PyList_Size(source);
503 byte* temp = new byte[count];
504 if (! temp) {
505 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
506 return NULL;
507 }
508 for (int x=0; x<count; x++) {
509 PyObject* o = PyList_GetItem(source, x);
510 if (! PyInt_Check(o)) {
511 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
512 return NULL;
513 }
514 temp[x] = (byte)PyInt_AsLong(o);
515 }
516 return temp;
517}
518
519
7bf85405
RD
520int* int_LIST_helper(PyObject* source) {
521 if (!PyList_Check(source)) {
522 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
523 return NULL;
524 }
525 int count = PyList_Size(source);
526 int* temp = new int[count];
527 if (! temp) {
528 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
529 return NULL;
530 }
531 for (int x=0; x<count; x++) {
532 PyObject* o = PyList_GetItem(source, x);
533 if (! PyInt_Check(o)) {
534 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
535 return NULL;
536 }
537 temp[x] = PyInt_AsLong(o);
538 }
539 return temp;
540}
541
542
543long* long_LIST_helper(PyObject* source) {
544 if (!PyList_Check(source)) {
545 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
546 return NULL;
547 }
548 int count = PyList_Size(source);
549 long* temp = new long[count];
550 if (! temp) {
551 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
552 return NULL;
553 }
554 for (int x=0; x<count; x++) {
555 PyObject* o = PyList_GetItem(source, x);
556 if (! PyInt_Check(o)) {
557 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
558 return NULL;
559 }
560 temp[x] = PyInt_AsLong(o);
561 }
562 return temp;
563}
564
565
566char** string_LIST_helper(PyObject* source) {
567 if (!PyList_Check(source)) {
568 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
569 return NULL;
570 }
571 int count = PyList_Size(source);
572 char** temp = new char*[count];
573 if (! temp) {
574 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
575 return NULL;
576 }
577 for (int x=0; x<count; x++) {
578 PyObject* o = PyList_GetItem(source, x);
579 if (! PyString_Check(o)) {
580 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
581 return NULL;
582 }
583 temp[x] = PyString_AsString(o);
584 }
585 return temp;
586}
587
588
589
590wxPoint* wxPoint_LIST_helper(PyObject* source) {
591 if (!PyList_Check(source)) {
592 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
593 return NULL;
594 }
595 int count = PyList_Size(source);
596 wxPoint* temp = new wxPoint[count];
597 if (! temp) {
598 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
599 return NULL;
600 }
601 for (int x=0; x<count; x++) {
602 PyObject* o = PyList_GetItem(source, x);
603 if (PyString_Check(o)) {
604 char* st = PyString_AsString(o);
605 wxPoint* pt;
606 if (SWIG_GetPtr(st,(void **) &pt,"_wxPoint_p")) {
607 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
608 return NULL;
609 }
610 temp[x] = *pt;
611 }
612 else if (PyTuple_Check(o)) {
613 PyObject* o1 = PyTuple_GetItem(o, 0);
614 PyObject* o2 = PyTuple_GetItem(o, 1);
615
616 temp[x].x = PyInt_AsLong(o1);
617 temp[x].y = PyInt_AsLong(o2);
618 }
619 else {
620 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
621 return NULL;
622 }
623 }
624 return temp;
625}
626
627
628wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
629 if (!PyList_Check(source)) {
630 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
631 return NULL;
632 }
633 int count = PyList_Size(source);
634 wxBitmap** temp = new wxBitmap*[count];
635 if (! temp) {
636 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
637 return NULL;
638 }
639 for (int x=0; x<count; x++) {
640 PyObject* o = PyList_GetItem(source, x);
641 if (PyString_Check(o)) {
642 char* st = PyString_AsString(o);
643 wxBitmap* pt;
644 if (SWIG_GetPtr(st,(void **) &pt,"_wxBitmap_p")) {
645 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
646 return NULL;
647 }
648 temp[x] = pt;
649 }
650 else {
651 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
652 return NULL;
653 }
654 }
655 return temp;
656}
657
658
659
660wxString* wxString_LIST_helper(PyObject* source) {
661 if (!PyList_Check(source)) {
662 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
663 return NULL;
664 }
665 int count = PyList_Size(source);
666 wxString* temp = new wxString[count];
667 if (! temp) {
668 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
669 return NULL;
670 }
671 for (int x=0; x<count; x++) {
672 PyObject* o = PyList_GetItem(source, x);
673 if (! PyString_Check(o)) {
674 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
675 return NULL;
676 }
677 temp[x] = PyString_AsString(o);
678 }
679 return temp;
680}
681
682
683wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
684 if (!PyList_Check(source)) {
685 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
686 return NULL;
687 }
688 int count = PyList_Size(source);
689 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
690 if (! temp) {
691 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
692 return NULL;
693 }
694 for (int x=0; x<count; x++) {
695 PyObject* o = PyList_GetItem(source, x);
696 if (PyString_Check(o)) {
697 char* st = PyString_AsString(o);
698 wxAcceleratorEntry* ae;
699 if (SWIG_GetPtr(st,(void **) &ae,"_wxAcceleratorEntry_p")) {
700 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
701 return NULL;
702 }
703 temp[x] = *ae;
704 }
705 else if (PyTuple_Check(o)) {
706 PyObject* o1 = PyTuple_GetItem(o, 0);
707 PyObject* o2 = PyTuple_GetItem(o, 1);
708 PyObject* o3 = PyTuple_GetItem(o, 2);
709
710 temp[x].m_flags = PyInt_AsLong(o1);
711 temp[x].m_keyCode = PyInt_AsLong(o2);
712 temp[x].m_command = PyInt_AsLong(o3);
713 }
714 else {
715 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
716 return NULL;
717 }
718 }
719 return temp;
720}
721
bb0054cd
RD
722
723
724//----------------------------------------------------------------------
725//----------------------------------------------------------------------
726
727wxPyCallbackHelper::wxPyCallbackHelper() {
728 m_self = NULL;
729 m_lastFound = NULL;
730}
731
732
733wxPyCallbackHelper::~wxPyCallbackHelper() {
734#ifdef WXP_WITH_THREAD
735 PyEval_RestoreThread(wxPyEventThreadState);
736#endif
737
738 Py_XDECREF(m_self);
739
740#ifdef WXP_WITH_THREAD
741 PyEval_SaveThread();
742#endif
743}
744
745void wxPyCallbackHelper::setSelf(PyObject* self) {
746 m_self = self;
747 Py_INCREF(m_self);
748}
749
750
751
752bool wxPyCallbackHelper::findCallback(const wxString& name) {
753 m_lastFound = NULL;
754 if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str()))
755 m_lastFound = PyObject_GetAttrString(m_self, (char*)name.c_str());
756
757 return m_lastFound != NULL;
758}
759
760
761int wxPyCallbackHelper::callCallback(PyObject* argTuple) {
762 PyObject* result;
763 int retval = FALSE;
764
765 result = callCallbackObj(argTuple);
766 if (result) { // Assumes an integer return type...
767 retval = PyInt_AsLong(result);
768 Py_DECREF(result);
769 PyErr_Clear(); // forget about it if it's not...
770 }
771#ifdef WXP_WITH_THREAD
772 PyEval_SaveThread();
773#endif
774 return retval;
775}
776
777// Invoke the Python callable object, returning the raw PyObject return
778// value. Caller should DECREF the return value and also call PyEval_SaveThread.
779PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) {
780#ifdef WXP_WITH_THREAD
781 PyEval_RestoreThread(wxPyEventThreadState);
782#endif
783 PyObject* result;
784
785 result = PyEval_CallObject(m_lastFound, argTuple);
786 Py_DECREF(argTuple);
787 if (!result) {
788 PyErr_Print();
789 }
790 return result;
791}
792
793
794
795
796//----------------------------------------------------------------------
797//----------------------------------------------------------------------
7bf85405 798//----------------------------------------------------------------------
7bf85405 799
7bf85405 800
7bf85405 801