]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/helpers.cpp
4495879274c95ffd9e6a9a5036046aead26d5875
[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 unsigned int _wxPyNestCount = 0;
305
306 static PyThreadState* myPyThreadState_Get() {
307 PyThreadState* current;
308 current = PyThreadState_Swap(NULL);
309 PyThreadState_Swap(current);
310 return current;
311 }
312
313
314 HELPEREXPORT bool wxPyRestoreThread() {
315 // NOTE: The Python API docs state that if a thread already has the
316 // interpreter lock and calls PyEval_RestoreThread again a deadlock
317 // occurs, so I put in this code as a guard condition since there are
318 // many possibilites for nested events and callbacks in wxPython. If
319 // The current thread is our thread, then we can assume that we
320 // already have the lock. (I hope!)
321 //
322 #ifdef WXP_WITH_THREAD
323 _wxPyNestCount += 1;
324 if (wxPyEventThreadState != myPyThreadState_Get()) {
325 PyEval_RestoreThread(wxPyEventThreadState);
326 return TRUE;
327 }
328 else
329 #endif
330 return FALSE;
331 }
332
333
334 HELPEREXPORT void wxPySaveThread(bool doSave) {
335 #ifdef WXP_WITH_THREAD
336 if (doSave) {
337 wxPyEventThreadState = PyEval_SaveThread();
338 }
339 _wxPyNestCount -= 1;
340 #endif
341 }
342
343 //---------------------------------------------------------------------------
344
345
346 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
347
348 wxPyCallback::wxPyCallback(PyObject* func) {
349 m_func = func;
350 Py_INCREF(m_func);
351 }
352
353 wxPyCallback::wxPyCallback(const wxPyCallback& other) {
354 m_func = other.m_func;
355 Py_INCREF(m_func);
356 }
357
358 wxPyCallback::~wxPyCallback() {
359 bool doSave = wxPyRestoreThread();
360 Py_DECREF(m_func);
361 wxPySaveThread(doSave);
362 }
363
364
365
366 // This function is used for all events destined for Python event handlers.
367 void wxPyCallback::EventThunker(wxEvent& event) {
368 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
369 PyObject* func = cb->m_func;
370 PyObject* result;
371 PyObject* arg;
372 PyObject* tuple;
373
374
375 bool doSave = wxPyRestoreThread();
376 wxString className = event.GetClassInfo()->GetClassName();
377
378 if (className == "wxPyEvent")
379 arg = ((wxPyEvent*)&event)->GetSelf();
380 else if (className == "wxPyCommandEvent")
381 arg = ((wxPyCommandEvent*)&event)->GetSelf();
382 else
383 arg = wxPyConstructObject((void*)&event, className);
384
385 tuple = PyTuple_New(1);
386 PyTuple_SET_ITEM(tuple, 0, arg);
387 result = PyEval_CallObject(func, tuple);
388 Py_DECREF(tuple);
389 if (result) {
390 Py_DECREF(result);
391 PyErr_Clear();
392 } else {
393 PyErr_Print();
394 }
395 wxPySaveThread(doSave);
396 }
397
398
399 //----------------------------------------------------------------------
400
401 wxPyCallbackHelper::wxPyCallbackHelper() {
402 m_class = NULL;
403 m_self = NULL;
404 m_lastFound = NULL;
405 m_incRef = FALSE;
406 }
407
408
409 wxPyCallbackHelper::~wxPyCallbackHelper() {
410 bool doSave = wxPyRestoreThread();
411 if (m_incRef) {
412 Py_XDECREF(m_self);
413 Py_XDECREF(m_class);
414 }
415 wxPySaveThread(doSave);
416 }
417
418 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
419 m_lastFound = NULL;
420 m_self = other.m_self;
421 m_class = other.m_class;
422 if (m_self) {
423 Py_INCREF(m_self);
424 Py_INCREF(m_class);
425 }
426 }
427
428
429 void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* klass, int incref) {
430 m_self = self;
431 m_class = klass;
432 m_incRef = incref;
433 if (incref) {
434 Py_INCREF(m_self);
435 Py_INCREF(m_class);
436 }
437 }
438
439
440 // If the object (m_self) has an attibute of the given name, and if that
441 // attribute is a method, and if that method's class is not from a base class,
442 // then we'll save a pointer to the method so callCallback can call it.
443 bool wxPyCallbackHelper::findCallback(const char* name) const {
444 wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
445 self->m_lastFound = NULL;
446 if (m_self && PyObject_HasAttrString(m_self, (char*)name)) {
447 PyObject* method;
448 method = PyObject_GetAttrString(m_self, (char*)name);
449
450 if (PyMethod_Check(method) &&
451 ((PyMethod_GET_CLASS(method) == m_class) ||
452 PyClass_IsSubclass(PyMethod_GET_CLASS(method), m_class))) {
453
454 self->m_lastFound = method;
455 }
456 else {
457 Py_DECREF(method);
458 }
459 }
460 return m_lastFound != NULL;
461 }
462
463
464 int wxPyCallbackHelper::callCallback(PyObject* argTuple) const {
465 PyObject* result;
466 int retval = FALSE;
467
468 result = callCallbackObj(argTuple);
469 if (result) { // Assumes an integer return type...
470 retval = PyInt_AsLong(result);
471 Py_DECREF(result);
472 PyErr_Clear(); // forget about it if it's not...
473 }
474 return retval;
475 }
476
477 // Invoke the Python callable object, returning the raw PyObject return
478 // value. Caller should DECREF the return value and also call PyEval_SaveThread.
479 PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const {
480 wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
481 PyObject* result;
482
483 // Save a copy of the pointer in case the callback generates another
484 // callback. In that case m_lastFound will have a different value when
485 // it gets back here...
486 PyObject* method = m_lastFound;
487
488 result = PyEval_CallObject(method, argTuple);
489 Py_DECREF(argTuple);
490 Py_DECREF(method);
491 if (!result) {
492 PyErr_Print();
493 }
494 return result;
495 }
496
497
498
499 //---------------------------------------------------------------------------
500 //---------------------------------------------------------------------------
501 // These classes can be derived from in Python and passed through the event
502 // system without losing anything. They do this by keeping a reference to
503 // themselves and some special case handling in wxPyCallback::EventThunker.
504
505
506 wxPyEvtSelfRef::wxPyEvtSelfRef() {
507 //m_self = Py_None; // **** We don't do normal ref counting to prevent
508 //Py_INCREF(m_self); // circular loops...
509 m_cloned = FALSE;
510 }
511
512 wxPyEvtSelfRef::~wxPyEvtSelfRef() {
513 bool doSave = wxPyRestoreThread();
514 if (m_cloned)
515 Py_DECREF(m_self);
516 wxPySaveThread(doSave);
517 }
518
519 void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) {
520 bool doSave = wxPyRestoreThread();
521 if (m_cloned)
522 Py_DECREF(m_self);
523 m_self = self;
524 if (clone) {
525 Py_INCREF(m_self);
526 m_cloned = TRUE;
527 }
528 wxPySaveThread(doSave);
529 }
530
531 PyObject* wxPyEvtSelfRef::GetSelf() const {
532 Py_INCREF(m_self);
533 return m_self;
534 }
535
536
537 wxPyEvent::wxPyEvent(int id)
538 : wxEvent(id) {
539 }
540
541 wxPyEvent::~wxPyEvent() {
542 }
543
544 // This one is so the event object can be Cloned...
545 void wxPyEvent::CopyObject(wxObject& dest) const {
546 wxEvent::CopyObject(dest);
547 ((wxPyEvent*)&dest)->SetSelf(m_self, TRUE);
548 }
549
550
551 IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxEvent);
552
553
554 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType, int id)
555 : wxCommandEvent(commandType, id) {
556 }
557
558 wxPyCommandEvent::~wxPyCommandEvent() {
559 }
560
561 void wxPyCommandEvent::CopyObject(wxObject& dest) const {
562 wxCommandEvent::CopyObject(dest);
563 ((wxPyCommandEvent*)&dest)->SetSelf(m_self, TRUE);
564 }
565
566
567 IMPLEMENT_DYNAMIC_CLASS(wxPyCommandEvent, wxCommandEvent);
568
569
570
571 //---------------------------------------------------------------------------
572 //---------------------------------------------------------------------------
573
574
575 wxPyTimer::wxPyTimer(PyObject* callback) {
576 func = callback;
577 Py_INCREF(func);
578 }
579
580 wxPyTimer::~wxPyTimer() {
581 bool doSave = wxPyRestoreThread();
582 Py_DECREF(func);
583 wxPySaveThread(doSave);
584 }
585
586 void wxPyTimer::Notify() {
587 if (!func || func == Py_None) {
588 wxTimer::Notify();
589 }
590 else {
591 bool doSave = wxPyRestoreThread();
592
593 PyObject* result;
594 PyObject* args = Py_BuildValue("()");
595
596 result = PyEval_CallObject(func, args);
597 Py_DECREF(args);
598 if (result) {
599 Py_DECREF(result);
600 PyErr_Clear();
601 } else {
602 PyErr_Print();
603 }
604
605 wxPySaveThread(doSave);
606 }
607 }
608
609
610
611 //---------------------------------------------------------------------------
612 //---------------------------------------------------------------------------
613 // Convert a wxList to a Python List
614
615 PyObject* wxPy_ConvertList(wxListBase* list, const char* className) {
616 PyObject* pyList;
617 PyObject* pyObj;
618 wxObject* wxObj;
619 wxNode* node = list->First();
620
621 bool doSave = wxPyRestoreThread();
622 pyList = PyList_New(0);
623 while (node) {
624 wxObj = node->Data();
625 pyObj = wxPyConstructObject(wxObj, className);
626 PyList_Append(pyList, pyObj);
627 node = node->Next();
628 }
629 wxPySaveThread(doSave);
630 return pyList;
631 }
632
633 //----------------------------------------------------------------------
634
635 long wxPyGetWinHandle(wxWindow* win) {
636 #ifdef __WXMSW__
637 return (long)win->GetHandle();
638 #endif
639
640 // Find and return the actual X-Window.
641 #ifdef __WXGTK__
642 if (win->m_wxwindow) {
643 GdkWindowPrivate* bwin = (GdkWindowPrivate*)GTK_PIZZA(win->m_wxwindow)->bin_window;
644 if (bwin) {
645 return (long)bwin->xwindow;
646 }
647 }
648 #endif
649 return 0;
650 }
651
652 //----------------------------------------------------------------------
653 // Some helper functions for typemaps in my_typemaps.i, so they won't be
654 // included in every file...
655
656
657 byte* byte_LIST_helper(PyObject* source) {
658 if (!PyList_Check(source)) {
659 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
660 return NULL;
661 }
662 int count = PyList_Size(source);
663 byte* temp = new byte[count];
664 if (! temp) {
665 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
666 return NULL;
667 }
668 for (int x=0; x<count; x++) {
669 PyObject* o = PyList_GetItem(source, x);
670 if (! PyInt_Check(o)) {
671 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
672 return NULL;
673 }
674 temp[x] = (byte)PyInt_AsLong(o);
675 }
676 return temp;
677 }
678
679
680 int* int_LIST_helper(PyObject* source) {
681 if (!PyList_Check(source)) {
682 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
683 return NULL;
684 }
685 int count = PyList_Size(source);
686 int* temp = new int[count];
687 if (! temp) {
688 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
689 return NULL;
690 }
691 for (int x=0; x<count; x++) {
692 PyObject* o = PyList_GetItem(source, x);
693 if (! PyInt_Check(o)) {
694 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
695 return NULL;
696 }
697 temp[x] = PyInt_AsLong(o);
698 }
699 return temp;
700 }
701
702
703 long* long_LIST_helper(PyObject* source) {
704 if (!PyList_Check(source)) {
705 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
706 return NULL;
707 }
708 int count = PyList_Size(source);
709 long* temp = new long[count];
710 if (! temp) {
711 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
712 return NULL;
713 }
714 for (int x=0; x<count; x++) {
715 PyObject* o = PyList_GetItem(source, x);
716 if (! PyInt_Check(o)) {
717 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
718 return NULL;
719 }
720 temp[x] = PyInt_AsLong(o);
721 }
722 return temp;
723 }
724
725
726 char** string_LIST_helper(PyObject* source) {
727 if (!PyList_Check(source)) {
728 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
729 return NULL;
730 }
731 int count = PyList_Size(source);
732 char** temp = new char*[count];
733 if (! temp) {
734 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
735 return NULL;
736 }
737 for (int x=0; x<count; x++) {
738 PyObject* o = PyList_GetItem(source, x);
739 if (! PyString_Check(o)) {
740 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
741 return NULL;
742 }
743 temp[x] = PyString_AsString(o);
744 }
745 return temp;
746 }
747
748
749
750 wxPoint* wxPoint_LIST_helper(PyObject* source) {
751 if (!PyList_Check(source)) {
752 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
753 return NULL;
754 }
755 int count = PyList_Size(source);
756 wxPoint* temp = new wxPoint[count];
757 if (! temp) {
758 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
759 return NULL;
760 }
761 for (int x=0; x<count; x++) {
762 PyObject* o = PyList_GetItem(source, x);
763 if (PyTuple_Check(o)) {
764 PyObject* o1 = PyTuple_GetItem(o, 0);
765 PyObject* o2 = PyTuple_GetItem(o, 1);
766
767 temp[x].x = PyInt_AsLong(o1);
768 temp[x].y = PyInt_AsLong(o2);
769 }
770 else if (PyInstance_Check(o)) {
771 wxPoint* pt;
772 if (SWIG_GetPtrObj(o,(void **) &pt,"_wxPoint_p")) {
773 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
774 return NULL;
775 }
776 temp[x] = *pt;
777 }
778 else {
779 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
780 return NULL;
781 }
782 }
783 return temp;
784 }
785
786
787 wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
788 if (!PyList_Check(source)) {
789 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
790 return NULL;
791 }
792 int count = PyList_Size(source);
793 wxBitmap** temp = new wxBitmap*[count];
794 if (! temp) {
795 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
796 return NULL;
797 }
798 for (int x=0; x<count; x++) {
799 PyObject* o = PyList_GetItem(source, x);
800 if (PyInstance_Check(o)) {
801 wxBitmap* pt;
802 if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
803 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
804 return NULL;
805 }
806 temp[x] = pt;
807 }
808 else {
809 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
810 return NULL;
811 }
812 }
813 return temp;
814 }
815
816
817
818 wxString* wxString_LIST_helper(PyObject* source) {
819 if (!PyList_Check(source)) {
820 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
821 return NULL;
822 }
823 int count = PyList_Size(source);
824 wxString* temp = new wxString[count];
825 if (! temp) {
826 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
827 return NULL;
828 }
829 for (int x=0; x<count; x++) {
830 PyObject* o = PyList_GetItem(source, x);
831 if (! PyString_Check(o)) {
832 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
833 return NULL;
834 }
835 temp[x] = PyString_AsString(o);
836 }
837 return temp;
838 }
839
840
841 wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
842 if (!PyList_Check(source)) {
843 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
844 return NULL;
845 }
846 int count = PyList_Size(source);
847 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
848 if (! temp) {
849 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
850 return NULL;
851 }
852 for (int x=0; x<count; x++) {
853 PyObject* o = PyList_GetItem(source, x);
854 if (PyInstance_Check(o)) {
855 wxAcceleratorEntry* ae;
856 if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
857 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
858 return NULL;
859 }
860 temp[x] = *ae;
861 }
862 else if (PyTuple_Check(o)) {
863 PyObject* o1 = PyTuple_GetItem(o, 0);
864 PyObject* o2 = PyTuple_GetItem(o, 1);
865 PyObject* o3 = PyTuple_GetItem(o, 2);
866
867 temp[x].m_flags = PyInt_AsLong(o1);
868 temp[x].m_keyCode = PyInt_AsLong(o2);
869 temp[x].m_command = PyInt_AsLong(o3);
870 }
871 else {
872 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
873 return NULL;
874 }
875 }
876 return temp;
877 }
878
879
880
881 //----------------------------------------------------------------------
882
883 bool wxSize_helper(PyObject* source, wxSize** obj) {
884
885 // If source is an object instance then it may already be the right type
886 if (PyInstance_Check(source)) {
887 wxSize* ptr;
888 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
889 goto error;
890 *obj = ptr;
891 return TRUE;
892 }
893 // otherwise a 2-tuple of integers is expected
894 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
895 PyObject* o1 = PySequence_GetItem(source, 0);
896 PyObject* o2 = PySequence_GetItem(source, 1);
897 **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
898 return TRUE;
899 }
900
901 error:
902 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
903 return FALSE;
904 }
905
906 bool wxPoint_helper(PyObject* source, wxPoint** obj) {
907
908 // If source is an object instance then it may already be the right type
909 if (PyInstance_Check(source)) {
910 wxPoint* ptr;
911 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
912 goto error;
913 *obj = ptr;
914 return TRUE;
915 }
916 // otherwise a 2-tuple of integers is expected
917 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
918 PyObject* o1 = PySequence_GetItem(source, 0);
919 PyObject* o2 = PySequence_GetItem(source, 1);
920 **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
921 return TRUE;
922 }
923
924 error:
925 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
926 return FALSE;
927 }
928
929
930
931 bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
932
933 // If source is an object instance then it may already be the right type
934 if (PyInstance_Check(source)) {
935 wxRealPoint* ptr;
936 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
937 goto error;
938 *obj = ptr;
939 return TRUE;
940 }
941 // otherwise a 2-tuple of floats is expected
942 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
943 PyObject* o1 = PySequence_GetItem(source, 0);
944 PyObject* o2 = PySequence_GetItem(source, 1);
945 **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
946 return TRUE;
947 }
948
949 error:
950 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
951 return FALSE;
952 }
953
954
955
956
957 bool wxRect_helper(PyObject* source, wxRect** obj) {
958
959 // If source is an object instance then it may already be the right type
960 if (PyInstance_Check(source)) {
961 wxRect* ptr;
962 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
963 goto error;
964 *obj = ptr;
965 return TRUE;
966 }
967 // otherwise a 4-tuple of integers is expected
968 else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
969 PyObject* o1 = PySequence_GetItem(source, 0);
970 PyObject* o2 = PySequence_GetItem(source, 1);
971 PyObject* o3 = PySequence_GetItem(source, 2);
972 PyObject* o4 = PySequence_GetItem(source, 3);
973 **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2),
974 PyInt_AsLong(o3), PyInt_AsLong(o4));
975 return TRUE;
976 }
977
978 error:
979 PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
980 return FALSE;
981 }
982
983
984
985 bool wxColour_helper(PyObject* source, wxColour** obj) {
986
987 // If source is an object instance then it may already be the right type
988 if (PyInstance_Check(source)) {
989 wxColour* ptr;
990 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxColour_p"))
991 goto error;
992 *obj = ptr;
993 return TRUE;
994 }
995 // otherwise a string is expected
996 else if (PyString_Check(source)) {
997 wxString spec = PyString_AS_STRING(source);
998 if (spec[0] == '#' && spec.Length() == 7) { // It's #RRGGBB
999 char* junk;
1000 int red = strtol(spec.Mid(1,2), &junk, 16);
1001 int green = strtol(spec.Mid(3,2), &junk, 16);
1002 int blue = strtol(spec.Mid(5,2), &junk, 16);
1003 **obj = wxColour(red, green, blue);
1004 return TRUE;
1005 }
1006 else { // it's a colour name
1007 **obj = wxColour(spec);
1008 return TRUE;
1009 }
1010 }
1011
1012 error:
1013 PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or '#RRGGBB'.");
1014 return FALSE;
1015 }
1016
1017
1018 //----------------------------------------------------------------------
1019 //----------------------------------------------------------------------
1020 //----------------------------------------------------------------------
1021
1022
1023
1024