]> git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/src/helpers.cpp
2613693160f6c96336cadd8c4fafecef1dbce8ef
[wxWidgets.git] / utils / wxPython / src / helpers.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: helpers.cpp
3 // Purpose: Helper functions/classes for the wxPython extension module
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
13 #include <stdio.h> // get the correct definition of NULL
14
15 #undef DEBUG
16 #include <Python.h>
17 #include "helpers.h"
18
19 #ifdef __WXMSW__
20 #include <wx/msw/private.h>
21 #undef FindWindow
22 #undef GetCharWidth
23 #undef LoadAccelerators
24 #undef GetClassInfo
25 #undef GetClassName
26 #endif
27
28 #ifdef __WXGTK__
29 #include <gtk/gtk.h>
30 #include <gdk/gdkprivate.h>
31 #include <wx/gtk/win_gtk.h>
32 //#include <gdk/gdk.h>
33 //#include <gdk/gdkx.h>
34 //#include <gtk/gtkwindow.h>
35
36 extern GtkWidget *wxRootWindow;
37
38 #endif
39
40
41 //---------------------------------------------------------------------------
42
43 //wxHashTable* wxPyWindows = NULL;
44
45
46 wxPoint wxPyDefaultPosition; //wxDefaultPosition);
47 wxSize wxPyDefaultSize; //wxDefaultSize);
48 wxString wxPyEmptyStr("");
49
50
51
52 #ifdef __WXMSW__ // If building for win32...
53 //----------------------------------------------------------------------
54 // This gets run when the DLL is loaded. We just need to save a handle.
55 //----------------------------------------------------------------------
56
57 BOOL WINAPI DllMain(
58 HINSTANCE hinstDLL, // handle to DLL module
59 DWORD fdwReason, // reason for calling function
60 LPVOID lpvReserved // reserved
61 )
62 {
63 wxSetInstance(hinstDLL);
64 return 1;
65 }
66 #endif
67
68 //----------------------------------------------------------------------
69 // Class for implementing the wxp main application shell.
70 //----------------------------------------------------------------------
71
72 wxPyApp *wxPythonApp = NULL; // Global instance of application object
73
74
75 wxPyApp::wxPyApp() {
76 // printf("**** ctor\n");
77 }
78
79 wxPyApp::~wxPyApp() {
80 // printf("**** dtor\n");
81 }
82
83
84 // This one isn't acutally called... See __wxStart()
85 bool wxPyApp::OnInit(void) {
86 return FALSE;
87 }
88
89 int wxPyApp::MainLoop(void) {
90 int retval = 0;
91
92 DeletePendingObjects();
93 #ifdef __WXGTK__
94 m_initialized = wxTopLevelWindows.GetCount() != 0;
95 #endif
96
97 if (Initialized()) {
98 retval = wxApp::MainLoop();
99 wxPythonApp->OnExit();
100 }
101 return retval;
102 }
103
104
105 //---------------------------------------------------------------------
106 //----------------------------------------------------------------------
107
108 int wxEntryStart( int argc, char *argv[] );
109 int wxEntryInitGui();
110 void wxEntryCleanup();
111
112
113 // This is where we pick up the first part of the wxEntry functionality...
114 // The rest is in __wxStart and AfterMainLoop. This function is called when
115 // wxcmodule is imported. (Before there is a wxApp object.)
116 void __wxPreStart()
117 {
118 #ifdef WXP_WITH_THREAD
119 PyEval_InitThreads();
120 #endif
121
122 // Bail out if there is already windows created. This means that the
123 // toolkit has already been initialized, as in embedding wxPython in
124 // a C++ wxWindows app.
125 if (wxTopLevelWindows.Number() > 0)
126 return;
127
128 #if 0
129
130 #ifdef __WXMSW__
131 wxApp::Initialize();
132 #endif
133
134 #ifdef __WXGTK__
135 PyObject* sysargv = PySys_GetObject("argv");
136 int argc = PyList_Size(sysargv);
137 char** argv = new char*[argc+1];
138 int x;
139 for(x=0; x<argc; x++)
140 argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
141 argv[argc] = NULL;
142
143 #if wxUSE_THREADS
144 /* GTK 1.2 up to version 1.2.3 has broken threads */
145 if ((gtk_major_version == 1) &&
146 (gtk_minor_version == 2) &&
147 (gtk_micro_version < 4))
148 {
149 printf( "wxWindows warning: GUI threading disabled due to outdated GTK version\n" );
150 }
151 else
152 {
153 g_thread_init(NULL);
154 }
155 #endif
156
157 gtk_set_locale();
158
159 #if wxUSE_WCHAR_T
160 if (!wxOKlibc()) wxConvCurrent = &wxConvLocal;
161 #else
162 if (!wxOKlibc()) wxConvCurrent = (wxMBConv*) NULL;
163 #endif
164
165 gdk_threads_enter();
166 gtk_init( &argc, &argv );
167 wxSetDetectableAutoRepeat( TRUE );
168 delete [] argv;
169
170 if (!wxApp::Initialize())
171 {
172 gdk_threads_leave();
173 }
174 #endif
175 #endif // 0
176
177
178 PyObject* sysargv = PySys_GetObject("argv");
179 int argc = PyList_Size(sysargv);
180 char** argv = new char*[argc+1];
181 int x;
182 for(x=0; x<argc; x++)
183 argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
184 argv[argc] = NULL;
185
186 wxEntryStart(argc, argv);
187 }
188
189
190
191 #ifdef WXP_WITH_THREAD
192 PyThreadState* wxPyEventThreadState = NULL;
193 #endif
194 static char* __nullArgv[1] = { 0 };
195
196
197
198 // Start the user application, user App's OnInit method is a parameter here
199 PyObject* __wxStart(PyObject* /* self */, PyObject* args)
200 {
201 PyObject* onInitFunc = NULL;
202 PyObject* arglist;
203 PyObject* result;
204 long bResult;
205
206 #ifdef WXP_WITH_THREAD
207 wxPyEventThreadState = PyThreadState_Get();
208 #endif
209
210 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
211 return NULL;
212
213 if (wxTopLevelWindows.Number() > 0) {
214 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
215 return NULL;
216 }
217
218
219 // This is the next part of the wxEntry functionality...
220 wxPythonApp->argc = 0;
221 wxPythonApp->argv = NULL;
222
223 wxEntryInitGui();
224
225 // Call the Python App's OnInit function
226 arglist = PyTuple_New(0);
227 result = PyEval_CallObject(onInitFunc, arglist);
228 if (!result) { // an exception was raised.
229 return NULL;
230 }
231
232 if (! PyInt_Check(result)) {
233 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
234 return NULL;
235 }
236 bResult = PyInt_AS_LONG(result);
237 if (! bResult) {
238 PyErr_SetString(PyExc_SystemExit, "OnInit returned FALSE, exiting...");
239 return NULL;
240 }
241
242 #ifdef __WXGTK__
243 wxTheApp->m_initialized = (wxTopLevelWindows.GetCount() > 0);
244 #endif
245
246 Py_INCREF(Py_None);
247 return Py_None;
248 }
249
250 void __wxCleanup() {
251 wxEntryCleanup();
252 }
253
254
255
256 PyObject* wxPython_dict;
257 PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
258 {
259
260 if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
261 return NULL;
262
263 if (!PyDict_Check(wxPython_dict)) {
264 PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
265 return NULL;
266 }
267 #ifdef __WXMOTIF__
268 #define wxPlatform "__WXMOTIF__"
269 #endif
270 #ifdef __WXQT__
271 #define wxPlatform "__WXQT__"
272 #endif
273 #ifdef __WXGTK__
274 #define wxPlatform "__WXGTK__"
275 #endif
276 #if defined(__WIN32__) || defined(__WXMSW__)
277 #define wxPlatform "__WXMSW__"
278 #endif
279 #ifdef __WXMAC__
280 #define wxPlatform "__WXMAC__"
281 #endif
282
283 PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
284
285 Py_INCREF(Py_None);
286 return Py_None;
287 }
288
289
290 //---------------------------------------------------------------------------
291
292 PyObject* wxPyConstructObject(void* ptr, const char* className) {
293 char buff[64]; // should always be big enough...
294 char swigptr[64];
295
296 sprintf(buff, "_%s_p", className);
297 SWIG_MakePtr(swigptr, ptr, buff);
298
299 sprintf(buff, "%sPtr", className);
300 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
301 if (! classobj) {
302 Py_INCREF(Py_None);
303 return Py_None;
304 }
305
306 PyObject* arg = Py_BuildValue("(s)", swigptr);
307 PyObject* obj = PyInstance_New(classobj, arg, NULL);
308 Py_DECREF(arg);
309
310 return obj;
311 }
312
313 //---------------------------------------------------------------------------
314
315 static unsigned int _wxPyNestCount = 0;
316
317 static PyThreadState* myPyThreadState_Get() {
318 PyThreadState* current;
319 current = PyThreadState_Swap(NULL);
320 PyThreadState_Swap(current);
321 return current;
322 }
323
324
325 HELPEREXPORT bool wxPyRestoreThread() {
326 // NOTE: The Python API docs state that if a thread already has the
327 // interpreter lock and calls PyEval_RestoreThread again a deadlock
328 // occurs, so I put in this code as a guard condition since there are
329 // many possibilites for nested events and callbacks in wxPython. If
330 // The current thread is our thread, then we can assume that we
331 // already have the lock. (I hope!)
332 //
333 #ifdef WXP_WITH_THREAD
334 _wxPyNestCount += 1;
335 if (wxPyEventThreadState != myPyThreadState_Get()) {
336 PyEval_RestoreThread(wxPyEventThreadState);
337 return TRUE;
338 }
339 else
340 #endif
341 return FALSE;
342 }
343
344
345 HELPEREXPORT void wxPySaveThread(bool doSave) {
346 #ifdef WXP_WITH_THREAD
347 if (doSave) {
348 wxPyEventThreadState = PyEval_SaveThread();
349 }
350 _wxPyNestCount -= 1;
351 #endif
352 }
353
354 //---------------------------------------------------------------------------
355
356
357 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
358
359 wxPyCallback::wxPyCallback(PyObject* func) {
360 m_func = func;
361 Py_INCREF(m_func);
362 }
363
364 wxPyCallback::wxPyCallback(const wxPyCallback& other) {
365 m_func = other.m_func;
366 Py_INCREF(m_func);
367 }
368
369 wxPyCallback::~wxPyCallback() {
370 bool doSave = wxPyRestoreThread();
371 Py_DECREF(m_func);
372 wxPySaveThread(doSave);
373 }
374
375
376
377 // This function is used for all events destined for Python event handlers.
378 void wxPyCallback::EventThunker(wxEvent& event) {
379 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
380 PyObject* func = cb->m_func;
381 PyObject* result;
382 PyObject* arg;
383 PyObject* tuple;
384
385
386 bool doSave = wxPyRestoreThread();
387 wxString className = event.GetClassInfo()->GetClassName();
388
389 if (className == "wxPyEvent")
390 arg = ((wxPyEvent*)&event)->GetSelf();
391 else if (className == "wxPyCommandEvent")
392 arg = ((wxPyCommandEvent*)&event)->GetSelf();
393 else
394 arg = wxPyConstructObject((void*)&event, className);
395
396 tuple = PyTuple_New(1);
397 PyTuple_SET_ITEM(tuple, 0, arg);
398 result = PyEval_CallObject(func, tuple);
399 Py_DECREF(tuple);
400 if (result) {
401 Py_DECREF(result);
402 PyErr_Clear();
403 } else {
404 PyErr_Print();
405 }
406 wxPySaveThread(doSave);
407 }
408
409
410 //----------------------------------------------------------------------
411
412 wxPyCallbackHelper::wxPyCallbackHelper() {
413 m_self = NULL;
414 m_lastFound = NULL;
415 m_incRef = FALSE;
416 }
417
418
419 wxPyCallbackHelper::~wxPyCallbackHelper() {
420 bool doSave = wxPyRestoreThread();
421 if (m_incRef)
422 Py_XDECREF(m_self);
423 wxPySaveThread(doSave);
424 }
425
426 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
427 m_lastFound = NULL;
428 m_self = other.m_self;
429 if (m_self)
430 Py_INCREF(m_self);
431 }
432
433
434 void wxPyCallbackHelper::setSelf(PyObject* self, int incref) {
435 m_self = self;
436 m_incRef = incref;
437 if (incref)
438 Py_INCREF(m_self);
439 }
440
441
442 bool wxPyCallbackHelper::findCallback(const wxString& name) {
443 m_lastFound = NULL;
444 if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str()))
445 m_lastFound = PyObject_GetAttrString(m_self, (char*)name.c_str());
446
447 return m_lastFound != NULL;
448 }
449
450
451 int wxPyCallbackHelper::callCallback(PyObject* argTuple) {
452 PyObject* result;
453 int retval = FALSE;
454
455 result = callCallbackObj(argTuple);
456 if (result) { // Assumes an integer return type...
457 retval = PyInt_AsLong(result);
458 Py_DECREF(result);
459 PyErr_Clear(); // forget about it if it's not...
460 }
461 return retval;
462 }
463
464 // Invoke the Python callable object, returning the raw PyObject return
465 // value. Caller should DECREF the return value and also call PyEval_SaveThread.
466 PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) {
467 PyObject* result;
468
469 result = PyEval_CallObject(m_lastFound, argTuple);
470 Py_DECREF(argTuple);
471 if (!result) {
472 PyErr_Print();
473 }
474 return result;
475 }
476
477
478
479 //---------------------------------------------------------------------------
480 //---------------------------------------------------------------------------
481 // These classes can be derived from in Python and passed through the event
482 // system without loosing anything. They do this by keeping a reference to
483 // themselves and some special case handling in wxPyCallback::EventThunker.
484
485
486 wxPyEvtSelfRef::wxPyEvtSelfRef() {
487 //m_self = Py_None; // **** We don't do normal ref counting to prevent
488 //Py_INCREF(m_self); // circular loops...
489 m_cloned = FALSE;
490 }
491
492 wxPyEvtSelfRef::~wxPyEvtSelfRef() {
493 bool doSave = wxPyRestoreThread();
494 if (m_cloned)
495 Py_DECREF(m_self);
496 wxPySaveThread(doSave);
497 }
498
499 void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) {
500 bool doSave = wxPyRestoreThread();
501 if (m_cloned)
502 Py_DECREF(m_self);
503 m_self = self;
504 if (clone) {
505 Py_INCREF(m_self);
506 m_cloned = TRUE;
507 }
508 wxPySaveThread(doSave);
509 }
510
511 PyObject* wxPyEvtSelfRef::GetSelf() const {
512 Py_INCREF(m_self);
513 return m_self;
514 }
515
516
517 wxPyEvent::wxPyEvent(int id)
518 : wxEvent(id) {
519 }
520
521 wxPyEvent::~wxPyEvent() {
522 }
523
524 // This one is so the event object can be Cloned...
525 void wxPyEvent::CopyObject(wxObject& dest) const {
526 wxEvent::CopyObject(dest);
527 ((wxPyEvent*)&dest)->SetSelf(m_self, TRUE);
528 }
529
530
531 IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxEvent);
532
533
534 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType, int id)
535 : wxCommandEvent(commandType, id) {
536 }
537
538 wxPyCommandEvent::~wxPyCommandEvent() {
539 }
540
541 void wxPyCommandEvent::CopyObject(wxObject& dest) const {
542 wxCommandEvent::CopyObject(dest);
543 ((wxPyCommandEvent*)&dest)->SetSelf(m_self, TRUE);
544 }
545
546
547 IMPLEMENT_DYNAMIC_CLASS(wxPyCommandEvent, wxCommandEvent);
548
549
550
551 //---------------------------------------------------------------------------
552 //---------------------------------------------------------------------------
553
554
555 wxPyTimer::wxPyTimer(PyObject* callback) {
556 func = callback;
557 Py_INCREF(func);
558 }
559
560 wxPyTimer::~wxPyTimer() {
561 bool doSave = wxPyRestoreThread();
562 Py_DECREF(func);
563 wxPySaveThread(doSave);
564 }
565
566 void wxPyTimer::Notify() {
567 bool doSave = wxPyRestoreThread();
568
569 PyObject* result;
570 PyObject* args = Py_BuildValue("()");
571
572 result = PyEval_CallObject(func, args);
573 Py_DECREF(args);
574 if (result) {
575 Py_DECREF(result);
576 PyErr_Clear();
577 } else {
578 PyErr_Print();
579 }
580 wxPySaveThread(doSave);
581 }
582
583
584
585 //---------------------------------------------------------------------------
586 //---------------------------------------------------------------------------
587 // Convert a wxList to a Python List
588
589 PyObject* wxPy_ConvertList(wxListBase* list, const char* className) {
590 PyObject* pyList;
591 PyObject* pyObj;
592 wxObject* wxObj;
593 wxNode* node = list->First();
594
595 bool doSave = wxPyRestoreThread();
596 pyList = PyList_New(0);
597 while (node) {
598 wxObj = node->Data();
599 pyObj = wxPyConstructObject(wxObj, className);
600 PyList_Append(pyList, pyObj);
601 node = node->Next();
602 }
603 wxPySaveThread(doSave);
604 return pyList;
605 }
606
607 //----------------------------------------------------------------------
608
609 long wxPyGetWinHandle(wxWindow* win) {
610 #ifdef __WXMSW__
611 return (long)win->GetHandle();
612 #endif
613
614 // Find and return the actual X-Window.
615 #ifdef __WXGTK__
616 if (win->m_wxwindow) {
617 GdkWindowPrivate* bwin = (GdkWindowPrivate*)GTK_PIZZA(win->m_wxwindow)->bin_window;
618 if (bwin) {
619 return (long)bwin->xwindow;
620 }
621 }
622 #endif
623 return 0;
624 }
625
626 //----------------------------------------------------------------------
627 // Some helper functions for typemaps in my_typemaps.i, so they won't be
628 // included in every file...
629
630
631 byte* byte_LIST_helper(PyObject* source) {
632 if (!PyList_Check(source)) {
633 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
634 return NULL;
635 }
636 int count = PyList_Size(source);
637 byte* temp = new byte[count];
638 if (! temp) {
639 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
640 return NULL;
641 }
642 for (int x=0; x<count; x++) {
643 PyObject* o = PyList_GetItem(source, x);
644 if (! PyInt_Check(o)) {
645 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
646 return NULL;
647 }
648 temp[x] = (byte)PyInt_AsLong(o);
649 }
650 return temp;
651 }
652
653
654 int* int_LIST_helper(PyObject* source) {
655 if (!PyList_Check(source)) {
656 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
657 return NULL;
658 }
659 int count = PyList_Size(source);
660 int* temp = new int[count];
661 if (! temp) {
662 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
663 return NULL;
664 }
665 for (int x=0; x<count; x++) {
666 PyObject* o = PyList_GetItem(source, x);
667 if (! PyInt_Check(o)) {
668 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
669 return NULL;
670 }
671 temp[x] = PyInt_AsLong(o);
672 }
673 return temp;
674 }
675
676
677 long* long_LIST_helper(PyObject* source) {
678 if (!PyList_Check(source)) {
679 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
680 return NULL;
681 }
682 int count = PyList_Size(source);
683 long* temp = new long[count];
684 if (! temp) {
685 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
686 return NULL;
687 }
688 for (int x=0; x<count; x++) {
689 PyObject* o = PyList_GetItem(source, x);
690 if (! PyInt_Check(o)) {
691 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
692 return NULL;
693 }
694 temp[x] = PyInt_AsLong(o);
695 }
696 return temp;
697 }
698
699
700 char** string_LIST_helper(PyObject* source) {
701 if (!PyList_Check(source)) {
702 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
703 return NULL;
704 }
705 int count = PyList_Size(source);
706 char** temp = new char*[count];
707 if (! temp) {
708 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
709 return NULL;
710 }
711 for (int x=0; x<count; x++) {
712 PyObject* o = PyList_GetItem(source, x);
713 if (! PyString_Check(o)) {
714 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
715 return NULL;
716 }
717 temp[x] = PyString_AsString(o);
718 }
719 return temp;
720 }
721
722
723
724 wxPoint* wxPoint_LIST_helper(PyObject* source) {
725 if (!PyList_Check(source)) {
726 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
727 return NULL;
728 }
729 int count = PyList_Size(source);
730 wxPoint* temp = new wxPoint[count];
731 if (! temp) {
732 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
733 return NULL;
734 }
735 for (int x=0; x<count; x++) {
736 PyObject* o = PyList_GetItem(source, x);
737 if (PyTuple_Check(o)) {
738 PyObject* o1 = PyTuple_GetItem(o, 0);
739 PyObject* o2 = PyTuple_GetItem(o, 1);
740
741 temp[x].x = PyInt_AsLong(o1);
742 temp[x].y = PyInt_AsLong(o2);
743 }
744 else if (PyInstance_Check(o)) {
745 wxPoint* pt;
746 if (SWIG_GetPtrObj(o,(void **) &pt,"_wxPoint_p")) {
747 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
748 return NULL;
749 }
750 temp[x] = *pt;
751 }
752 else {
753 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
754 return NULL;
755 }
756 }
757 return temp;
758 }
759
760
761 wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
762 if (!PyList_Check(source)) {
763 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
764 return NULL;
765 }
766 int count = PyList_Size(source);
767 wxBitmap** temp = new wxBitmap*[count];
768 if (! temp) {
769 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
770 return NULL;
771 }
772 for (int x=0; x<count; x++) {
773 PyObject* o = PyList_GetItem(source, x);
774 if (PyInstance_Check(o)) {
775 wxBitmap* pt;
776 if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
777 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
778 return NULL;
779 }
780 temp[x] = pt;
781 }
782 else {
783 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
784 return NULL;
785 }
786 }
787 return temp;
788 }
789
790
791
792 wxString* wxString_LIST_helper(PyObject* source) {
793 if (!PyList_Check(source)) {
794 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
795 return NULL;
796 }
797 int count = PyList_Size(source);
798 wxString* temp = new wxString[count];
799 if (! temp) {
800 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
801 return NULL;
802 }
803 for (int x=0; x<count; x++) {
804 PyObject* o = PyList_GetItem(source, x);
805 if (! PyString_Check(o)) {
806 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
807 return NULL;
808 }
809 temp[x] = PyString_AsString(o);
810 }
811 return temp;
812 }
813
814
815 wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
816 if (!PyList_Check(source)) {
817 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
818 return NULL;
819 }
820 int count = PyList_Size(source);
821 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
822 if (! temp) {
823 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
824 return NULL;
825 }
826 for (int x=0; x<count; x++) {
827 PyObject* o = PyList_GetItem(source, x);
828 if (PyInstance_Check(o)) {
829 wxAcceleratorEntry* ae;
830 if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
831 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
832 return NULL;
833 }
834 temp[x] = *ae;
835 }
836 else if (PyTuple_Check(o)) {
837 PyObject* o1 = PyTuple_GetItem(o, 0);
838 PyObject* o2 = PyTuple_GetItem(o, 1);
839 PyObject* o3 = PyTuple_GetItem(o, 2);
840
841 temp[x].m_flags = PyInt_AsLong(o1);
842 temp[x].m_keyCode = PyInt_AsLong(o2);
843 temp[x].m_command = PyInt_AsLong(o3);
844 }
845 else {
846 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
847 return NULL;
848 }
849 }
850 return temp;
851 }
852
853
854
855 //----------------------------------------------------------------------
856
857 bool wxSize_helper(PyObject* source, wxSize** obj) {
858
859 // If source is an object instance then it may already be the right type
860 if (PyInstance_Check(source)) {
861 wxSize* ptr;
862 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
863 goto error;
864 *obj = ptr;
865 return TRUE;
866 }
867 // otherwise a 2-tuple of integers is expected
868 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
869 PyObject* o1 = PySequence_GetItem(source, 0);
870 PyObject* o2 = PySequence_GetItem(source, 1);
871 **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
872 return TRUE;
873 }
874
875 error:
876 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
877 return FALSE;
878 }
879
880 bool wxPoint_helper(PyObject* source, wxPoint** obj) {
881
882 // If source is an object instance then it may already be the right type
883 if (PyInstance_Check(source)) {
884 wxPoint* ptr;
885 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
886 goto error;
887 *obj = ptr;
888 return TRUE;
889 }
890 // otherwise a 2-tuple of integers is expected
891 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
892 PyObject* o1 = PySequence_GetItem(source, 0);
893 PyObject* o2 = PySequence_GetItem(source, 1);
894 **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
895 return TRUE;
896 }
897
898 error:
899 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
900 return FALSE;
901 }
902
903
904
905 bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
906
907 // If source is an object instance then it may already be the right type
908 if (PyInstance_Check(source)) {
909 wxRealPoint* ptr;
910 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
911 goto error;
912 *obj = ptr;
913 return TRUE;
914 }
915 // otherwise a 2-tuple of floats is expected
916 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
917 PyObject* o1 = PySequence_GetItem(source, 0);
918 PyObject* o2 = PySequence_GetItem(source, 1);
919 **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
920 return TRUE;
921 }
922
923 error:
924 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
925 return FALSE;
926 }
927
928
929
930
931 bool wxRect_helper(PyObject* source, wxRect** obj) {
932
933 // If source is an object instance then it may already be the right type
934 if (PyInstance_Check(source)) {
935 wxRect* ptr;
936 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
937 goto error;
938 *obj = ptr;
939 return TRUE;
940 }
941 // otherwise a 4-tuple of integers is expected
942 else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
943 PyObject* o1 = PySequence_GetItem(source, 0);
944 PyObject* o2 = PySequence_GetItem(source, 1);
945 PyObject* o3 = PySequence_GetItem(source, 2);
946 PyObject* o4 = PySequence_GetItem(source, 3);
947 **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2),
948 PyInt_AsLong(o3), PyInt_AsLong(o4));
949 return TRUE;
950 }
951
952 error:
953 PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
954 return FALSE;
955 }
956
957
958
959 //----------------------------------------------------------------------
960 //----------------------------------------------------------------------
961 //----------------------------------------------------------------------
962
963
964