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