]> git.saurik.com Git - wxWidgets.git/blame - utils/wxPython/src/helpers.cpp
Removed some unnecessary bitmaps; other minor changes
[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
21f4bf45
RD
13#ifdef __WXMSW__
14#include <windows.h>
15#undef FindWindow
16#undef GetCharWidth
17#undef LoadAccelerators
18#endif
19
7bf85405
RD
20#undef DEBUG
21#include <Python.h>
22#include "helpers.h"
23
853b255a 24#ifdef __WXGTK__
47d67540 25#ifdef wxUSE_GDK_IMLIB
853b255a
RD
26#include "gdk_imlib/gdk_imlib.h"
27#endif
28#endif
7bf85405
RD
29
30//---------------------------------------------------------------------------
31
32//wxHashTable* wxPyWindows = NULL;
33
34
35wxPoint wxPyDefaultPosition; //wxDefaultPosition);
36wxSize wxPyDefaultSize; //wxDefaultSize);
37wxString wxPyEmptyStr("");
38
39
40
21f4bf45
RD
41#ifdef __WXMSW__ // If building for win32...
42extern HINSTANCE wxhInstance;
43
44//----------------------------------------------------------------------
45// This gets run when the DLL is loaded. We just need to save a handle.
46//----------------------------------------------------------------------
9c039d08 47
21f4bf45
RD
48BOOL WINAPI DllMain(
49 HINSTANCE hinstDLL, // handle to DLL module
50 DWORD fdwReason, // reason for calling function
51 LPVOID lpvReserved // reserved
52 )
53{
54 wxhInstance = hinstDLL;
55 return 1;
56}
57#endif
58
7bf85405
RD
59//----------------------------------------------------------------------
60// Class for implementing the wxp main application shell.
61//----------------------------------------------------------------------
62
63wxPyApp *wxPythonApp = NULL; // Global instance of application object
64
65
66// This one isn't acutally called... See __wxStart()
67bool wxPyApp::OnInit(void) {
68 return false;
69}
70
71int wxPyApp::MainLoop(void) {
72 int retval = wxApp::MainLoop();
73 AfterMainLoop();
74 return retval;
75}
76
77void wxPyApp::AfterMainLoop(void) {
78 // more stuff from wxEntry...
0d6f9504
RD
79
80#ifdef __WXMSW__
7bf85405
RD
81 if (wxPythonApp->GetTopWindow()) {
82 // Forcibly delete the window.
83 if (wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)) ||
84 wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog))) {
85
86 wxPythonApp->GetTopWindow()->Close(TRUE);
87 wxPythonApp->DeletePendingObjects();
88 }
89 else {
90 delete wxPythonApp->GetTopWindow();
91 wxPythonApp->SetTopWindow(NULL);
92 }
93 }
0d6f9504
RD
94#endif
95#ifdef __WXGTK__
96 wxPythonApp->DeletePendingObjects();
97#endif
7bf85405
RD
98
99 wxPythonApp->OnExit();
100#ifdef __WXMSW__
101 wxApp::CleanUp();
102#endif
103#ifdef __WXGTK__
853b255a 104 wxApp::CommonCleanUp();
7bf85405 105#endif
b8b8dda7 106// delete wxPythonApp;
7bf85405
RD
107}
108
109
fb5e0af0 110//---------------------------------------------------------------------
7bf85405
RD
111// a few native methods to add to the module
112//----------------------------------------------------------------------
113
114
0d6f9504 115// This is where we pick up the first part of the wxEntry functionality...
4464bbee 116// The rest is in __wxStart and AfterMainLoop. This function is called when
0d6f9504
RD
117// wxpc is imported. (Before there is a wxApp object.)
118void __wxPreStart()
7bf85405 119{
0d6f9504
RD
120 // Bail out if there is already windows created. This means that the
121 // toolkit has already been initialized, as in embedding wxPython in
122 // a C++ wxWindows app.
123 if (wxTopLevelWindows.Number() > 0)
124 return;
7bf85405 125
7bf85405 126#ifdef __WXMSW__
9c039d08 127 wxApp::Initialize();
7bf85405
RD
128#endif
129#ifdef __WXGTK__
fb5e0af0 130 wxClassInfo::InitializeClasses();
21f4bf45 131
fb5e0af0
RD
132 PyObject* sysargv = PySys_GetObject("argv");
133 int argc = PyList_Size(sysargv);
134 char** argv = new char*[argc+1];
135 int x;
136 for(x=0; x<argc; x++)
137 argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
138 argv[argc] = NULL;
139
0d6f9504
RD
140 gtk_init( &argc, &argv );
141 delete [] argv;
7bf85405 142
47d67540 143#ifdef wxUSE_GDK_IMLIB
7bf85405 144 gdk_imlib_init();
7bf85405 145 gtk_widget_push_visual(gdk_imlib_get_visual());
7bf85405 146 gtk_widget_push_colormap(gdk_imlib_get_colormap());
7bf85405
RD
147#endif
148
149 wxApp::CommonInit();
7bf85405
RD
150#endif
151
0d6f9504
RD
152}
153
154
155
156static char* __nullArgv[1] = { 0 };
157
158// Start the user application, user App's OnInit method is a parameter here
159PyObject* __wxStart(PyObject* /* self */, PyObject* args)
160{
161 PyObject* onInitFunc = NULL;
162 PyObject* arglist;
163 PyObject* result;
164 long bResult;
165
166
167 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
168 return NULL;
169
170 if (wxTopLevelWindows.Number() > 0) {
171 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
172 return NULL;
173 }
174
175
176 // This is the next part of the wxEntry functionality...
177 wxPythonApp->argc = 0;
178 wxPythonApp->argv = __nullArgv;
179 wxPythonApp->OnInitGui();
180
7bf85405
RD
181
182 // Call the Python App's OnInit function
183 arglist = PyTuple_New(0);
184 result = PyEval_CallObject(onInitFunc, arglist);
185 if (!result) {
186 PyErr_Print();
187 exit(1);
188 }
189
190 if (! PyInt_Check(result)) {
191 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
192 return NULL;
193 }
194 bResult = PyInt_AS_LONG(result);
195 if (! bResult) {
196 wxPythonApp->DeletePendingObjects();
197 wxPythonApp->OnExit();
198#ifdef __WXMSW__
fb5e0af0 199 wxApp::CleanUp();
7bf85405
RD
200#endif
201#ifdef __WXGTK__
fb5e0af0 202 wxApp::CommonCleanUp();
7bf85405
RD
203#endif
204 PyErr_SetString(PyExc_SystemExit, "OnInit returned false, exiting...");
205 return NULL;
206 }
207
13dfc243 208#ifdef __WXGTK__
fb5e0af0 209 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
13dfc243 210#endif
fb5e0af0 211
7bf85405
RD
212 Py_INCREF(Py_None);
213 return Py_None;
214}
215
216
7bf85405
RD
217
218
219
220PyObject* wxPython_dict;
221PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
222{
223
224 if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
225 return NULL;
226
227 if (!PyDict_Check(wxPython_dict)) {
228 PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
229 return NULL;
230 }
231#ifdef __WXMOTIF__
21f4bf45
RD
232#define wxPlatform "__WXMOTIF__"
233#endif
234#ifdef __WXQT__
235#define wxPlatform "__WXQT__"
7bf85405
RD
236#endif
237#ifdef __WXGTK__
21f4bf45 238#define wxPlatform "__WXGTK__"
7bf85405
RD
239#endif
240#if defined(__WIN32__) || defined(__WXMSW__)
fb5e0af0 241#define wxPlatform "__WXMSW__"
7bf85405
RD
242#endif
243#ifdef __WXMAC__
21f4bf45 244#define wxPlatform "__WXMAC__"
7bf85405
RD
245#endif
246
247 PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
248
249 Py_INCREF(Py_None);
250 return Py_None;
251}
252
253
254//---------------------------------------------------------------------------
255
256
257static
258PyObject* wxPyConstructObject(void* ptr, char* className)
259{
9c039d08 260 char buff[64]; // should always be big enough...
7bf85405
RD
261 char swigptr[64];
262
263 sprintf(buff, "_%s_p", className);
264 SWIG_MakePtr(swigptr, ptr, buff);
265
266 sprintf(buff, "%sPtr", className);
267 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
268 if (! classobj) {
269 Py_INCREF(Py_None);
270 return Py_None;
271 }
272
273 PyObject* arg = Py_BuildValue("(s)", swigptr);
274 PyObject* obj = PyInstance_New(classobj, arg, NULL);
275 Py_DECREF(arg);
276
277 return obj;
278}
279
280
281// This function is used for all events destined for Python event handlers.
282void wxPyCallback::EventThunker(wxEvent& event) {
283 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
284 PyObject* func = cb->m_func;
285 PyObject* result;
286 PyObject* arg;
287 PyObject* tuple;
288
289 arg = wxPyConstructObject((void*)&event, event.GetClassInfo()->GetClassName());
290
291 tuple = PyTuple_New(1);
292 PyTuple_SET_ITEM(tuple, 0, arg);
293 result = PyEval_CallObject(func, tuple);
7bf85405
RD
294 Py_DECREF(tuple);
295 if (result) {
296 Py_DECREF(result);
297 PyErr_Clear();
298 } else {
299 PyErr_Print();
300 }
301}
302
303
304//---------------------------------------------------------------------------
305
306wxPyMenu::wxPyMenu(const wxString& title, PyObject* _func)
307 : wxMenu(title, (wxFunction)(func ? MenuCallback : NULL)), func(0) {
308
309 if (_func) {
310 func = _func;
311 Py_INCREF(func);
312 }
313}
314
315wxPyMenu::~wxPyMenu() {
316 if (func)
317 Py_DECREF(func);
318}
319
320
321void wxPyMenu::MenuCallback(wxMenu& menu, wxCommandEvent& evt) {
322 PyObject* evtobj = wxPyConstructObject((void*)&evt, "wxCommandEvent");
323 PyObject* menuobj = wxPyConstructObject((void*)&menu, "wxMenu");
324 if (PyErr_Occurred()) {
325 // bail out if a problem
326 PyErr_Print();
327 return;
328 }
329 // Now call the callback...
330 PyObject* func = ((wxPyMenu*)&menu)->func;
d5c9047a
RD
331 PyObject* args = PyTuple_New(2);
332 PyTuple_SET_ITEM(args, 0, menuobj);
333 PyTuple_SET_ITEM(args, 1, evtobj);
7bf85405
RD
334 PyObject* res = PyEval_CallObject(func, args);
335 Py_DECREF(args);
d5c9047a 336 Py_XDECREF(res); /* In case res is a NULL pointer */
7bf85405 337}
714e6a9e 338
7bf85405
RD
339
340//---------------------------------------------------------------------------
341
342wxPyTimer::wxPyTimer(PyObject* callback) {
343 func = callback;
344 Py_INCREF(func);
345}
346
347wxPyTimer::~wxPyTimer() {
348 Py_DECREF(func);
349}
350
351void wxPyTimer::Notify() {
352 PyObject* result;
353 PyObject* args = Py_BuildValue("()");
354
355 result = PyEval_CallObject(func, args);
356 Py_DECREF(args);
357 if (result) {
358 Py_DECREF(result);
359 PyErr_Clear();
360 } else {
361 PyErr_Print();
362 }
363}
364
365
366
7bf85405
RD
367//----------------------------------------------------------------------
368//----------------------------------------------------------------------
369// Some helper functions for typemaps in my_typemaps.i, so they won't be
370// imcluded in every file...
371
372
b639c3c5
RD
373byte* byte_LIST_helper(PyObject* source) {
374 if (!PyList_Check(source)) {
375 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
376 return NULL;
377 }
378 int count = PyList_Size(source);
379 byte* temp = new byte[count];
380 if (! temp) {
381 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
382 return NULL;
383 }
384 for (int x=0; x<count; x++) {
385 PyObject* o = PyList_GetItem(source, x);
386 if (! PyInt_Check(o)) {
387 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
388 return NULL;
389 }
390 temp[x] = (byte)PyInt_AsLong(o);
391 }
392 return temp;
393}
394
395
7bf85405
RD
396int* int_LIST_helper(PyObject* source) {
397 if (!PyList_Check(source)) {
398 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
399 return NULL;
400 }
401 int count = PyList_Size(source);
402 int* temp = new int[count];
403 if (! temp) {
404 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
405 return NULL;
406 }
407 for (int x=0; x<count; x++) {
408 PyObject* o = PyList_GetItem(source, x);
409 if (! PyInt_Check(o)) {
410 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
411 return NULL;
412 }
413 temp[x] = PyInt_AsLong(o);
414 }
415 return temp;
416}
417
418
419long* long_LIST_helper(PyObject* source) {
420 if (!PyList_Check(source)) {
421 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
422 return NULL;
423 }
424 int count = PyList_Size(source);
425 long* temp = new long[count];
426 if (! temp) {
427 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
428 return NULL;
429 }
430 for (int x=0; x<count; x++) {
431 PyObject* o = PyList_GetItem(source, x);
432 if (! PyInt_Check(o)) {
433 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
434 return NULL;
435 }
436 temp[x] = PyInt_AsLong(o);
437 }
438 return temp;
439}
440
441
442char** string_LIST_helper(PyObject* source) {
443 if (!PyList_Check(source)) {
444 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
445 return NULL;
446 }
447 int count = PyList_Size(source);
448 char** temp = new char*[count];
449 if (! temp) {
450 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
451 return NULL;
452 }
453 for (int x=0; x<count; x++) {
454 PyObject* o = PyList_GetItem(source, x);
455 if (! PyString_Check(o)) {
456 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
457 return NULL;
458 }
459 temp[x] = PyString_AsString(o);
460 }
461 return temp;
462}
463
464
465
466wxPoint* wxPoint_LIST_helper(PyObject* source) {
467 if (!PyList_Check(source)) {
468 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
469 return NULL;
470 }
471 int count = PyList_Size(source);
472 wxPoint* temp = new wxPoint[count];
473 if (! temp) {
474 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
475 return NULL;
476 }
477 for (int x=0; x<count; x++) {
478 PyObject* o = PyList_GetItem(source, x);
479 if (PyString_Check(o)) {
480 char* st = PyString_AsString(o);
481 wxPoint* pt;
482 if (SWIG_GetPtr(st,(void **) &pt,"_wxPoint_p")) {
483 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
484 return NULL;
485 }
486 temp[x] = *pt;
487 }
488 else if (PyTuple_Check(o)) {
489 PyObject* o1 = PyTuple_GetItem(o, 0);
490 PyObject* o2 = PyTuple_GetItem(o, 1);
491
492 temp[x].x = PyInt_AsLong(o1);
493 temp[x].y = PyInt_AsLong(o2);
494 }
495 else {
496 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
497 return NULL;
498 }
499 }
500 return temp;
501}
502
503
504wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
505 if (!PyList_Check(source)) {
506 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
507 return NULL;
508 }
509 int count = PyList_Size(source);
510 wxBitmap** temp = new wxBitmap*[count];
511 if (! temp) {
512 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
513 return NULL;
514 }
515 for (int x=0; x<count; x++) {
516 PyObject* o = PyList_GetItem(source, x);
517 if (PyString_Check(o)) {
518 char* st = PyString_AsString(o);
519 wxBitmap* pt;
520 if (SWIG_GetPtr(st,(void **) &pt,"_wxBitmap_p")) {
521 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
522 return NULL;
523 }
524 temp[x] = pt;
525 }
526 else {
527 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
528 return NULL;
529 }
530 }
531 return temp;
532}
533
534
535
536wxString* wxString_LIST_helper(PyObject* source) {
537 if (!PyList_Check(source)) {
538 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
539 return NULL;
540 }
541 int count = PyList_Size(source);
542 wxString* temp = new wxString[count];
543 if (! temp) {
544 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
545 return NULL;
546 }
547 for (int x=0; x<count; x++) {
548 PyObject* o = PyList_GetItem(source, x);
549 if (! PyString_Check(o)) {
550 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
551 return NULL;
552 }
553 temp[x] = PyString_AsString(o);
554 }
555 return temp;
556}
557
558
559wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
560 if (!PyList_Check(source)) {
561 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
562 return NULL;
563 }
564 int count = PyList_Size(source);
565 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
566 if (! temp) {
567 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
568 return NULL;
569 }
570 for (int x=0; x<count; x++) {
571 PyObject* o = PyList_GetItem(source, x);
572 if (PyString_Check(o)) {
573 char* st = PyString_AsString(o);
574 wxAcceleratorEntry* ae;
575 if (SWIG_GetPtr(st,(void **) &ae,"_wxAcceleratorEntry_p")) {
576 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
577 return NULL;
578 }
579 temp[x] = *ae;
580 }
581 else if (PyTuple_Check(o)) {
582 PyObject* o1 = PyTuple_GetItem(o, 0);
583 PyObject* o2 = PyTuple_GetItem(o, 1);
584 PyObject* o3 = PyTuple_GetItem(o, 2);
585
586 temp[x].m_flags = PyInt_AsLong(o1);
587 temp[x].m_keyCode = PyInt_AsLong(o2);
588 temp[x].m_command = PyInt_AsLong(o3);
589 }
590 else {
591 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
592 return NULL;
593 }
594 }
595 return temp;
596}
597
7bf85405 598//----------------------------------------------------------------------
7bf85405 599
7bf85405 600
7bf85405
RD
601
602/////////////////////////////////////////////////////////////////////////////
603//
604// $Log$
b8b8dda7
RD
605// Revision 1.15 1998/12/15 20:41:19 RD
606// Changed the import semantics from "from wxPython import *" to "from
607// wxPython.wx import *" This is for people who are worried about
608// namespace pollution, they can use "from wxPython import wx" and then
609// prefix all the wxPython identifiers with "wx."
610//
611// Added wxTaskbarIcon for wxMSW.
612//
613// Made the events work for wxGrid.
614//
615// Added wxConfig.
616//
617// Added wxMiniFrame for wxGTK, (untested.)
618//
619// Changed many of the args and return values that were pointers to gdi
620// objects to references to reflect changes in the wxWindows API.
621//
622// Other assorted fixes and additions.
623//
b639c3c5 624// Revision 1.14 1998/11/25 08:45:25 RD
b8b8dda7 625//
b639c3c5
RD
626// Added wxPalette, wxRegion, wxRegionIterator, wxTaskbarIcon
627// Added events for wxGrid
628// Other various fixes and additions
629//
faf3cb35
RD
630// Revision 1.13 1998/11/15 23:03:45 RD
631// Removing some ifdef's for wxGTK
632//
4464bbee
RD
633// Revision 1.12 1998/11/03 09:21:08 RD
634// fixed a typo
635//
d5c9047a
RD
636// Revision 1.11 1998/10/20 06:43:58 RD
637// New wxTreeCtrl wrappers (untested)
638// some changes in helpers
639// etc.
640//
9c039d08 641// Revision 1.10 1998/10/02 06:40:39 RD
d5c9047a 642//
9c039d08
RD
643// Version 0.4 of wxPython for MSW.
644//
47d67540 645// Revision 1.9 1998/09/25 13:28:52 VZ
9c039d08 646//
47d67540
VZ
647// USE_xxx constants renamed to wxUSE_xxx. This is an incompatible change, you
648// must recompile everything after upgrading!
649//
0d6f9504
RD
650// Revision 1.8 1998/08/27 21:59:08 RD
651// Some chicken-and-egg problems solved for wxPython on wxGTK
652//
21f4bf45
RD
653// Revision 1.7 1998/08/27 00:00:26 RD
654// - more tweaks
655// - have discovered some problems but not yet discovered solutions...
656//
13dfc243 657// Revision 1.6 1998/08/18 21:54:12 RD
21f4bf45 658//
13dfc243
RD
659// ifdef out some wxGTK specific code
660//
fb5e0af0
RD
661// Revision 1.5 1998/08/18 19:48:17 RD
662// more wxGTK compatibility things.
663//
664// It builds now but there are serious runtime problems...
665//
714e6a9e
RD
666// Revision 1.4 1998/08/16 04:31:06 RD
667// More wxGTK work.
668//
03e9bead
RD
669// Revision 1.3 1998/08/15 07:36:36 RD
670// - Moved the header in the .i files out of the code that gets put into
671// the .cpp files. It caused CVS conflicts because of the RCS ID being
672// different each time.
673//
674// - A few minor fixes.
675//
853b255a
RD
676// Revision 1.2 1998/08/14 23:36:36 RD
677// Beginings of wxGTK compatibility
678//
7bf85405
RD
679// Revision 1.1 1998/08/09 08:25:51 RD
680// Initial version
681//
682//