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