]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/helpers.cpp
33838befc999c43a5bc43399380b7aecdc7b8ccd
[wxWidgets.git] / 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 #ifdef __WXMSW__
109 #include "wx/msw/msvcrt.h"
110 #endif
111
112
113 int WXDLLEXPORT wxEntryStart( int argc, char** argv );
114 int WXDLLEXPORT wxEntryInitGui();
115 void WXDLLEXPORT wxEntryCleanup();
116
117
118 #ifdef WXP_WITH_THREAD
119 PyThreadState* wxPyEventThreadState = NULL;
120 #endif
121 static char* __nullArgv[1] = { 0 };
122
123
124 // This is where we pick up the first part of the wxEntry functionality...
125 // The rest is in __wxStart and __wxCleanup. This function is called when
126 // wxcmodule is imported. (Before there is a wxApp object.)
127 void __wxPreStart()
128 {
129
130 #ifdef __WXMSW__
131 // wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
132 #endif
133
134 #ifdef WXP_WITH_THREAD
135 PyEval_InitThreads();
136 wxPyEventThreadState = PyThreadState_Get();
137 #endif
138
139 // Bail out if there is already windows created. This means that the
140 // toolkit has already been initialized, as in embedding wxPython in
141 // a C++ wxWindows app.
142 if (wxTopLevelWindows.Number() > 0)
143 return;
144
145
146 PyObject* sysargv = PySys_GetObject("argv");
147 int argc = PyList_Size(sysargv);
148 char** argv = new char*[argc+1];
149 int x;
150 for(x=0; x<argc; x++)
151 argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
152 argv[argc] = NULL;
153
154 wxEntryStart(argc, argv);
155 delete [] argv;
156 }
157
158
159
160 // Start the user application, user App's OnInit method is a parameter here
161 PyObject* __wxStart(PyObject* /* self */, PyObject* args)
162 {
163 PyObject* onInitFunc = NULL;
164 PyObject* arglist;
165 PyObject* result;
166 long bResult;
167
168 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
169 return NULL;
170
171 #if 0 // Try it out without this check, soo how it does...
172 if (wxTopLevelWindows.Number() > 0) {
173 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
174 return NULL;
175 }
176 #endif
177
178 // This is the next part of the wxEntry functionality...
179 PyObject* sysargv = PySys_GetObject("argv");
180 int argc = PyList_Size(sysargv);
181 char** argv = new char*[argc+1];
182 int x;
183 for(x=0; x<argc; x++)
184 argv[x] = copystring(PyString_AsString(PyList_GetItem(sysargv, x)));
185 argv[argc] = NULL;
186
187 wxPythonApp->argc = argc;
188 wxPythonApp->argv = argv;
189
190 wxEntryInitGui();
191
192 // Call the Python App's OnInit function
193 arglist = PyTuple_New(0);
194 result = PyEval_CallObject(onInitFunc, arglist);
195 if (!result) { // an exception was raised.
196 return NULL;
197 }
198
199 if (! PyInt_Check(result)) {
200 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
201 return NULL;
202 }
203 bResult = PyInt_AS_LONG(result);
204 if (! bResult) {
205 PyErr_SetString(PyExc_SystemExit, "OnInit returned FALSE, exiting...");
206 return NULL;
207 }
208
209 #ifdef __WXGTK__
210 wxTheApp->m_initialized = (wxTopLevelWindows.GetCount() > 0);
211 #endif
212
213 Py_INCREF(Py_None);
214 return Py_None;
215 }
216
217 void __wxCleanup() {
218 wxEntryCleanup();
219 }
220
221
222
223 PyObject* wxPython_dict;
224 PyObject* __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__
235 #define wxPlatform "__WXMOTIF__"
236 #endif
237 #ifdef __WXQT__
238 #define wxPlatform "__WXQT__"
239 #endif
240 #ifdef __WXGTK__
241 #define wxPlatform "__WXGTK__"
242 #endif
243 #if defined(__WIN32__) || defined(__WXMSW__)
244 #define wxPlatform "__WXMSW__"
245 #endif
246 #ifdef __WXMAC__
247 #define wxPlatform "__WXMAC__"
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 PyObject* wxPyConstructObject(void* ptr,
260 const char* className,
261 int setThisOwn) {
262 PyObject* obj;
263 PyObject* arg;
264
265 if (!ptr) {
266 Py_INCREF(Py_None);
267 return Py_None;
268 }
269
270 char buff[64]; // should always be big enough...
271 char swigptr[64];
272
273 sprintf(buff, "_%s_p", className);
274 SWIG_MakePtr(swigptr, ptr, buff);
275
276 sprintf(buff, "%sPtr", className);
277 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
278 if (! classobj) {
279 //Py_INCREF(Py_None);
280 //return Py_None;
281 char temp[128];
282 sprintf(temp,
283 "*** Unknown class name %s, tell Robin about it please ***",
284 buff);
285 obj = PyString_FromString(temp);
286 return obj;
287 }
288
289 arg = Py_BuildValue("(s)", swigptr);
290 obj = PyInstance_New(classobj, arg, NULL);
291 Py_DECREF(arg);
292
293 if (setThisOwn) {
294 PyObject* one = PyInt_FromLong(1);
295 PyObject_SetAttrString(obj, "thisown", one);
296 Py_DECREF(one);
297 }
298
299 return obj;
300 }
301
302 //---------------------------------------------------------------------------
303
304 static PyThreadState* myPyThreadState_Get() {
305 PyThreadState* current;
306 current = PyThreadState_Swap(NULL);
307 PyThreadState_Swap(current);
308 return current;
309 }
310
311
312 bool wxPyRestoreThread() {
313 // NOTE: The Python API docs state that if a thread already has the
314 // interpreter lock and calls PyEval_RestoreThread again a deadlock
315 // occurs, so I put in this code as a guard condition since there are
316 // many possibilites for nested events and callbacks in wxPython. If
317 // The current thread is our thread, then we can assume that we
318 // already have the lock. (I hope!)
319 //
320 #ifdef WXP_WITH_THREAD
321 if (wxPyEventThreadState != myPyThreadState_Get()) {
322 PyEval_RestoreThread(wxPyEventThreadState);
323 return TRUE;
324 }
325 else
326 #endif
327 return FALSE;
328 }
329
330
331 void wxPySaveThread(bool doSave) {
332 #ifdef WXP_WITH_THREAD
333 if (doSave) {
334 wxPyEventThreadState = PyEval_SaveThread();
335 }
336 #endif
337 }
338
339 //---------------------------------------------------------------------------
340
341
342 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
343
344 wxPyCallback::wxPyCallback(PyObject* func) {
345 m_func = func;
346 Py_INCREF(m_func);
347 }
348
349 wxPyCallback::wxPyCallback(const wxPyCallback& other) {
350 m_func = other.m_func;
351 Py_INCREF(m_func);
352 }
353
354 wxPyCallback::~wxPyCallback() {
355 bool doSave = wxPyRestoreThread();
356 Py_DECREF(m_func);
357 wxPySaveThread(doSave);
358 }
359
360
361
362 // This function is used for all events destined for Python event handlers.
363 void wxPyCallback::EventThunker(wxEvent& event) {
364 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
365 PyObject* func = cb->m_func;
366 PyObject* result;
367 PyObject* arg;
368 PyObject* tuple;
369
370
371 bool doSave = wxPyRestoreThread();
372 wxString className = event.GetClassInfo()->GetClassName();
373
374 if (className == "wxPyEvent")
375 arg = ((wxPyEvent*)&event)->GetSelf();
376 else if (className == "wxPyCommandEvent")
377 arg = ((wxPyCommandEvent*)&event)->GetSelf();
378 else
379 arg = wxPyConstructObject((void*)&event, className);
380
381 tuple = PyTuple_New(1);
382 PyTuple_SET_ITEM(tuple, 0, arg);
383 result = PyEval_CallObject(func, tuple);
384 Py_DECREF(tuple);
385 if (result) {
386 Py_DECREF(result);
387 PyErr_Clear();
388 } else {
389 PyErr_Print();
390 }
391 wxPySaveThread(doSave);
392 }
393
394
395 //----------------------------------------------------------------------
396
397 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
398 m_lastFound = NULL;
399 m_self = other.m_self;
400 m_class = other.m_class;
401 if (m_self) {
402 Py_INCREF(m_self);
403 Py_INCREF(m_class);
404 }
405 }
406
407
408 void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* klass, int incref) {
409 m_self = self;
410 m_class = klass;
411 m_incRef = incref;
412 if (incref) {
413 Py_INCREF(m_self);
414 Py_INCREF(m_class);
415 }
416 }
417
418
419 // If the object (m_self) has an attibute of the given name, and if that
420 // attribute is a method, and if that method's class is not from a base class,
421 // then we'll save a pointer to the method so callCallback can call it.
422 bool wxPyCallbackHelper::findCallback(const char* name) const {
423 wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
424 self->m_lastFound = NULL;
425 if (m_self && PyObject_HasAttrString(m_self, (char*)name)) {
426 PyObject* method;
427 method = PyObject_GetAttrString(m_self, (char*)name);
428
429 if (PyMethod_Check(method) &&
430 ((PyMethod_GET_CLASS(method) == m_class) ||
431 PyClass_IsSubclass(PyMethod_GET_CLASS(method), m_class))) {
432
433 self->m_lastFound = method;
434 }
435 else {
436 Py_DECREF(method);
437 }
438 }
439 return m_lastFound != NULL;
440 }
441
442
443 int wxPyCallbackHelper::callCallback(PyObject* argTuple) const {
444 PyObject* result;
445 int retval = FALSE;
446
447 result = callCallbackObj(argTuple);
448 if (result) { // Assumes an integer return type...
449 retval = PyInt_AsLong(result);
450 Py_DECREF(result);
451 PyErr_Clear(); // forget about it if it's not...
452 }
453 return retval;
454 }
455
456 // Invoke the Python callable object, returning the raw PyObject return
457 // value. Caller should DECREF the return value and also call PyEval_SaveThread.
458 PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const {
459 wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
460 PyObject* result;
461
462 // Save a copy of the pointer in case the callback generates another
463 // callback. In that case m_lastFound will have a different value when
464 // it gets back here...
465 PyObject* method = m_lastFound;
466
467 result = PyEval_CallObject(method, argTuple);
468 Py_DECREF(argTuple);
469 Py_DECREF(method);
470 if (!result) {
471 PyErr_Print();
472 }
473 return result;
474 }
475
476
477 void wxPyCBH_setSelf(wxPyCallbackHelper& cbh, PyObject* self, PyObject* klass, int incref) {
478 cbh.setSelf(self, klass, incref);
479 }
480
481 bool wxPyCBH_findCallback(const wxPyCallbackHelper& cbh, const char* name) {
482 return cbh.findCallback(name);
483 }
484
485 int wxPyCBH_callCallback(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
486 return cbh.callCallback(argTuple);
487 }
488
489 PyObject* wxPyCBH_callCallbackObj(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
490 return cbh.callCallbackObj(argTuple);
491 }
492
493
494 void wxPyCBH_delete(wxPyCallbackHelper* cbh) {
495 bool doSave = wxPyRestoreThread();
496 if (cbh->m_incRef) {
497 Py_XDECREF(cbh->m_self);
498 Py_XDECREF(cbh->m_class);
499 }
500 wxPySaveThread(doSave);
501 }
502
503 //---------------------------------------------------------------------------
504 //---------------------------------------------------------------------------
505 // These classes can be derived from in Python and passed through the event
506 // system without losing anything. They do this by keeping a reference to
507 // themselves and some special case handling in wxPyCallback::EventThunker.
508
509
510 wxPyEvtSelfRef::wxPyEvtSelfRef() {
511 //m_self = Py_None; // **** We don't do normal ref counting to prevent
512 //Py_INCREF(m_self); // circular loops...
513 m_cloned = FALSE;
514 }
515
516 wxPyEvtSelfRef::~wxPyEvtSelfRef() {
517 bool doSave = wxPyRestoreThread();
518 if (m_cloned)
519 Py_DECREF(m_self);
520 wxPySaveThread(doSave);
521 }
522
523 void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) {
524 bool doSave = wxPyRestoreThread();
525 if (m_cloned)
526 Py_DECREF(m_self);
527 m_self = self;
528 if (clone) {
529 Py_INCREF(m_self);
530 m_cloned = TRUE;
531 }
532 wxPySaveThread(doSave);
533 }
534
535 PyObject* wxPyEvtSelfRef::GetSelf() const {
536 Py_INCREF(m_self);
537 return m_self;
538 }
539
540
541 wxPyEvent::wxPyEvent(int id)
542 : wxEvent(id) {
543 }
544
545 wxPyEvent::~wxPyEvent() {
546 }
547
548 // This one is so the event object can be Cloned...
549 void wxPyEvent::CopyObject(wxObject& dest) const {
550 wxEvent::CopyObject(dest);
551 ((wxPyEvent*)&dest)->SetSelf(m_self, TRUE);
552 }
553
554
555 IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxEvent);
556
557
558 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType, int id)
559 : wxCommandEvent(commandType, id) {
560 }
561
562 wxPyCommandEvent::~wxPyCommandEvent() {
563 }
564
565 void wxPyCommandEvent::CopyObject(wxObject& dest) const {
566 wxCommandEvent::CopyObject(dest);
567 ((wxPyCommandEvent*)&dest)->SetSelf(m_self, TRUE);
568 }
569
570
571 IMPLEMENT_DYNAMIC_CLASS(wxPyCommandEvent, wxCommandEvent);
572
573
574
575 //---------------------------------------------------------------------------
576 //---------------------------------------------------------------------------
577
578
579 wxPyTimer::wxPyTimer(PyObject* callback) {
580 func = callback;
581 Py_INCREF(func);
582 }
583
584 wxPyTimer::~wxPyTimer() {
585 bool doSave = wxPyRestoreThread();
586 Py_DECREF(func);
587 wxPySaveThread(doSave);
588 }
589
590 void wxPyTimer::Notify() {
591 if (!func || func == Py_None) {
592 wxTimer::Notify();
593 }
594 else {
595 bool doSave = wxPyRestoreThread();
596
597 PyObject* result;
598 PyObject* args = Py_BuildValue("()");
599
600 result = PyEval_CallObject(func, args);
601 Py_DECREF(args);
602 if (result) {
603 Py_DECREF(result);
604 PyErr_Clear();
605 } else {
606 PyErr_Print();
607 }
608
609 wxPySaveThread(doSave);
610 }
611 }
612
613
614
615 //---------------------------------------------------------------------------
616 //---------------------------------------------------------------------------
617 // Convert a wxList to a Python List
618
619 PyObject* wxPy_ConvertList(wxListBase* list, const char* className) {
620 PyObject* pyList;
621 PyObject* pyObj;
622 wxObject* wxObj;
623 wxNode* node = list->First();
624
625 bool doSave = wxPyRestoreThread();
626 pyList = PyList_New(0);
627 while (node) {
628 wxObj = node->Data();
629 pyObj = wxPyConstructObject(wxObj, className);
630 PyList_Append(pyList, pyObj);
631 node = node->Next();
632 }
633 wxPySaveThread(doSave);
634 return pyList;
635 }
636
637 //----------------------------------------------------------------------
638
639 long wxPyGetWinHandle(wxWindow* win) {
640 #ifdef __WXMSW__
641 return (long)win->GetHandle();
642 #endif
643
644 // Find and return the actual X-Window.
645 #ifdef __WXGTK__
646 if (win->m_wxwindow) {
647 GdkWindowPrivate* bwin = (GdkWindowPrivate*)GTK_PIZZA(win->m_wxwindow)->bin_window;
648 if (bwin) {
649 return (long)bwin->xwindow;
650 }
651 }
652 #endif
653 return 0;
654 }
655
656 //----------------------------------------------------------------------
657 // Some helper functions for typemaps in my_typemaps.i, so they won't be
658 // included in every file...
659
660
661 byte* byte_LIST_helper(PyObject* source) {
662 if (!PyList_Check(source)) {
663 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
664 return NULL;
665 }
666 int count = PyList_Size(source);
667 byte* temp = new byte[count];
668 if (! temp) {
669 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
670 return NULL;
671 }
672 for (int x=0; x<count; x++) {
673 PyObject* o = PyList_GetItem(source, x);
674 if (! PyInt_Check(o)) {
675 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
676 return NULL;
677 }
678 temp[x] = (byte)PyInt_AsLong(o);
679 }
680 return temp;
681 }
682
683
684 int* int_LIST_helper(PyObject* source) {
685 if (!PyList_Check(source)) {
686 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
687 return NULL;
688 }
689 int count = PyList_Size(source);
690 int* temp = new int[count];
691 if (! temp) {
692 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
693 return NULL;
694 }
695 for (int x=0; x<count; x++) {
696 PyObject* o = PyList_GetItem(source, x);
697 if (! PyInt_Check(o)) {
698 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
699 return NULL;
700 }
701 temp[x] = PyInt_AsLong(o);
702 }
703 return temp;
704 }
705
706
707 long* long_LIST_helper(PyObject* source) {
708 if (!PyList_Check(source)) {
709 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
710 return NULL;
711 }
712 int count = PyList_Size(source);
713 long* temp = new long[count];
714 if (! temp) {
715 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
716 return NULL;
717 }
718 for (int x=0; x<count; x++) {
719 PyObject* o = PyList_GetItem(source, x);
720 if (! PyInt_Check(o)) {
721 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
722 return NULL;
723 }
724 temp[x] = PyInt_AsLong(o);
725 }
726 return temp;
727 }
728
729
730 char** string_LIST_helper(PyObject* source) {
731 if (!PyList_Check(source)) {
732 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
733 return NULL;
734 }
735 int count = PyList_Size(source);
736 char** temp = new char*[count];
737 if (! temp) {
738 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
739 return NULL;
740 }
741 for (int x=0; x<count; x++) {
742 PyObject* o = PyList_GetItem(source, x);
743 if (! PyString_Check(o)) {
744 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
745 return NULL;
746 }
747 temp[x] = PyString_AsString(o);
748 }
749 return temp;
750 }
751
752
753
754 wxPoint* wxPoint_LIST_helper(PyObject* source) {
755 if (!PyList_Check(source)) {
756 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
757 return NULL;
758 }
759 int count = PyList_Size(source);
760 wxPoint* temp = new wxPoint[count];
761 if (! temp) {
762 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
763 return NULL;
764 }
765 for (int x=0; x<count; x++) {
766 PyObject* o = PyList_GetItem(source, x);
767 if (PyTuple_Check(o)) {
768 PyObject* o1 = PyTuple_GetItem(o, 0);
769 PyObject* o2 = PyTuple_GetItem(o, 1);
770
771 temp[x].x = PyInt_AsLong(o1);
772 temp[x].y = PyInt_AsLong(o2);
773 }
774 else if (PyInstance_Check(o)) {
775 wxPoint* pt;
776 if (SWIG_GetPtrObj(o,(void **) &pt,"_wxPoint_p")) {
777 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
778 return NULL;
779 }
780 temp[x] = *pt;
781 }
782 else {
783 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
784 return NULL;
785 }
786 }
787 return temp;
788 }
789
790
791 wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
792 if (!PyList_Check(source)) {
793 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
794 return NULL;
795 }
796 int count = PyList_Size(source);
797 wxBitmap** temp = new wxBitmap*[count];
798 if (! temp) {
799 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
800 return NULL;
801 }
802 for (int x=0; x<count; x++) {
803 PyObject* o = PyList_GetItem(source, x);
804 if (PyInstance_Check(o)) {
805 wxBitmap* pt;
806 if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
807 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
808 return NULL;
809 }
810 temp[x] = pt;
811 }
812 else {
813 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
814 return NULL;
815 }
816 }
817 return temp;
818 }
819
820
821
822 wxString* wxString_LIST_helper(PyObject* source) {
823 if (!PyList_Check(source)) {
824 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
825 return NULL;
826 }
827 int count = PyList_Size(source);
828 wxString* temp = new wxString[count];
829 if (! temp) {
830 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
831 return NULL;
832 }
833 for (int x=0; x<count; x++) {
834 PyObject* o = PyList_GetItem(source, x);
835 if (! PyString_Check(o)) {
836 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
837 return NULL;
838 }
839 temp[x] = PyString_AsString(o);
840 }
841 return temp;
842 }
843
844
845 wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
846 if (!PyList_Check(source)) {
847 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
848 return NULL;
849 }
850 int count = PyList_Size(source);
851 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
852 if (! temp) {
853 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
854 return NULL;
855 }
856 for (int x=0; x<count; x++) {
857 PyObject* o = PyList_GetItem(source, x);
858 if (PyInstance_Check(o)) {
859 wxAcceleratorEntry* ae;
860 if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
861 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
862 return NULL;
863 }
864 temp[x] = *ae;
865 }
866 else if (PyTuple_Check(o)) {
867 PyObject* o1 = PyTuple_GetItem(o, 0);
868 PyObject* o2 = PyTuple_GetItem(o, 1);
869 PyObject* o3 = PyTuple_GetItem(o, 2);
870
871 temp[x].m_flags = PyInt_AsLong(o1);
872 temp[x].m_keyCode = PyInt_AsLong(o2);
873 temp[x].m_command = PyInt_AsLong(o3);
874 }
875 else {
876 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
877 return NULL;
878 }
879 }
880 return temp;
881 }
882
883
884
885 //----------------------------------------------------------------------
886
887 bool wxSize_helper(PyObject* source, wxSize** obj) {
888
889 // If source is an object instance then it may already be the right type
890 if (PyInstance_Check(source)) {
891 wxSize* ptr;
892 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
893 goto error;
894 *obj = ptr;
895 return TRUE;
896 }
897 // otherwise a 2-tuple of integers is expected
898 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
899 PyObject* o1 = PySequence_GetItem(source, 0);
900 PyObject* o2 = PySequence_GetItem(source, 1);
901 **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
902 return TRUE;
903 }
904
905 error:
906 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
907 return FALSE;
908 }
909
910 bool wxPoint_helper(PyObject* source, wxPoint** obj) {
911
912 // If source is an object instance then it may already be the right type
913 if (PyInstance_Check(source)) {
914 wxPoint* ptr;
915 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
916 goto error;
917 *obj = ptr;
918 return TRUE;
919 }
920 // otherwise a 2-tuple of integers is expected
921 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
922 PyObject* o1 = PySequence_GetItem(source, 0);
923 PyObject* o2 = PySequence_GetItem(source, 1);
924 **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
925 return TRUE;
926 }
927
928 error:
929 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
930 return FALSE;
931 }
932
933
934
935 bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
936
937 // If source is an object instance then it may already be the right type
938 if (PyInstance_Check(source)) {
939 wxRealPoint* ptr;
940 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
941 goto error;
942 *obj = ptr;
943 return TRUE;
944 }
945 // otherwise a 2-tuple of floats is expected
946 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
947 PyObject* o1 = PySequence_GetItem(source, 0);
948 PyObject* o2 = PySequence_GetItem(source, 1);
949 **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
950 return TRUE;
951 }
952
953 error:
954 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
955 return FALSE;
956 }
957
958
959
960
961 bool wxRect_helper(PyObject* source, wxRect** obj) {
962
963 // If source is an object instance then it may already be the right type
964 if (PyInstance_Check(source)) {
965 wxRect* ptr;
966 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
967 goto error;
968 *obj = ptr;
969 return TRUE;
970 }
971 // otherwise a 4-tuple of integers is expected
972 else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
973 PyObject* o1 = PySequence_GetItem(source, 0);
974 PyObject* o2 = PySequence_GetItem(source, 1);
975 PyObject* o3 = PySequence_GetItem(source, 2);
976 PyObject* o4 = PySequence_GetItem(source, 3);
977 **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2),
978 PyInt_AsLong(o3), PyInt_AsLong(o4));
979 return TRUE;
980 }
981
982 error:
983 PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
984 return FALSE;
985 }
986
987
988
989 bool wxColour_helper(PyObject* source, wxColour** obj) {
990
991 // If source is an object instance then it may already be the right type
992 if (PyInstance_Check(source)) {
993 wxColour* ptr;
994 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxColour_p"))
995 goto error;
996 *obj = ptr;
997 return TRUE;
998 }
999 // otherwise a string is expected
1000 else if (PyString_Check(source)) {
1001 wxString spec = PyString_AS_STRING(source);
1002 if (spec[0] == '#' && spec.Length() == 7) { // It's #RRGGBB
1003 char* junk;
1004 int red = strtol(spec.Mid(1,2), &junk, 16);
1005 int green = strtol(spec.Mid(3,2), &junk, 16);
1006 int blue = strtol(spec.Mid(5,2), &junk, 16);
1007 **obj = wxColour(red, green, blue);
1008 return TRUE;
1009 }
1010 else { // it's a colour name
1011 **obj = wxColour(spec);
1012 return TRUE;
1013 }
1014 }
1015
1016 error:
1017 PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or '#RRGGBB'.");
1018 return FALSE;
1019 }
1020
1021
1022 //----------------------------------------------------------------------
1023 //----------------------------------------------------------------------
1024 //----------------------------------------------------------------------
1025
1026
1027
1028