##// END OF EJS Templates
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
florianlink -
r84:8f25be796564
parent child
Show More
@@ -1,1241 +1,1241
1 /*
1 /*
2 *
2 *
3 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
3 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
4 *
4 *
5 * This library is free software; you can redistribute it and/or
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
8 * version 2.1 of the License, or (at your option) any later version.
9 *
9 *
10 * This library is distributed in the hope that it will be useful,
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
13 * Lesser General Public License for more details.
14 *
14 *
15 * Further, this software is distributed without any warranty that it is
15 * Further, this software is distributed without any warranty that it is
16 * free of the rightful claim of any third person regarding infringement
16 * free of the rightful claim of any third person regarding infringement
17 * or the like. Any license provided herein, whether implied or
17 * or the like. Any license provided herein, whether implied or
18 * otherwise, applies only to this software file. Patent licenses, if
18 * otherwise, applies only to this software file. Patent licenses, if
19 * any, provided herein do not apply to combinations of this program with
19 * any, provided herein do not apply to combinations of this program with
20 * other software, or any other product whatsoever.
20 * other software, or any other product whatsoever.
21 *
21 *
22 * You should have received a copy of the GNU Lesser General Public
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
25 *
26 * Contact information: MeVis Research GmbH, Universitaetsallee 29,
26 * Contact information: MeVis Research GmbH, Universitaetsallee 29,
27 * 28359 Bremen, Germany or:
27 * 28359 Bremen, Germany or:
28 *
28 *
29 * http://www.mevis.de
29 * http://www.mevis.de
30 *
30 *
31 */
31 */
32
32
33 //----------------------------------------------------------------------------------
33 //----------------------------------------------------------------------------------
34 /*!
34 /*!
35 // \file PythonQt.cpp
35 // \file PythonQt.cpp
36 // \author Florian Link
36 // \author Florian Link
37 // \author Last changed by $Author: florian $
37 // \author Last changed by $Author: florian $
38 // \date 2006-05
38 // \date 2006-05
39 */
39 */
40 //----------------------------------------------------------------------------------
40 //----------------------------------------------------------------------------------
41
41
42 #include "PythonQt.h"
42 #include "PythonQt.h"
43 #include "PythonQtImporter.h"
43 #include "PythonQtImporter.h"
44 #include "PythonQtClassInfo.h"
44 #include "PythonQtClassInfo.h"
45 #include "PythonQtMethodInfo.h"
45 #include "PythonQtMethodInfo.h"
46 #include "PythonQtSignalReceiver.h"
46 #include "PythonQtSignalReceiver.h"
47 #include "PythonQtConversion.h"
47 #include "PythonQtConversion.h"
48 #include "PythonQtStdOut.h"
48 #include "PythonQtStdOut.h"
49 #include "PythonQtCppWrapperFactory.h"
49 #include "PythonQtCppWrapperFactory.h"
50 #include "PythonQtVariants.h"
50 #include "PythonQtVariants.h"
51 #include "PythonQtStdDecorators.h"
51 #include "PythonQtStdDecorators.h"
52 #include "PythonQtQFileImporter.h"
52 #include "PythonQtQFileImporter.h"
53 #include <pydebug.h>
53 #include <pydebug.h>
54 #include <vector>
54 #include <vector>
55
55
56 PythonQt* PythonQt::_self = NULL;
56 PythonQt* PythonQt::_self = NULL;
57 int PythonQt::_uniqueModuleCount = 0;
57 int PythonQt::_uniqueModuleCount = 0;
58
58
59 void PythonQt::init(int flags)
59 void PythonQt::init(int flags)
60 {
60 {
61 if (!_self) {
61 if (!_self) {
62 _self = new PythonQt(flags);
62 _self = new PythonQt(flags);
63 }
63 }
64
64
65 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
65 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
66 qRegisterMetaType<QList<QObject*> >("QList<void*>");
66 qRegisterMetaType<QList<QObject*> >("QList<void*>");
67
67
68 PythonQtRegisterToolClassesTemplateConverter(int);
68 PythonQtRegisterToolClassesTemplateConverter(int);
69 PythonQtRegisterToolClassesTemplateConverter(float);
69 PythonQtRegisterToolClassesTemplateConverter(float);
70 PythonQtRegisterToolClassesTemplateConverter(double);
70 PythonQtRegisterToolClassesTemplateConverter(double);
71 // TODO: which other POD types should be available for QList etc.
71 // TODO: which other POD types should be available for QList etc.
72
72
73 PythonQt::self()->addDecorators(new PythonQtStdDecorators());
73 PythonQt::self()->addDecorators(new PythonQtStdDecorators());
74
74
75 PythonQt::self()->registerCPPClass("Qt", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_Qt>);
75 PythonQt::self()->registerCPPClass("Qt", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_Qt>);
76 PythonQt::self()->registerCPPClass("QBitArray", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QBitArray>);
76 PythonQt::self()->registerCPPClass("QBitArray", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QBitArray>);
77 PythonQt::self()->registerCPPClass("QDate", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QDate>);
77 PythonQt::self()->registerCPPClass("QDate", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QDate>);
78 PythonQt::self()->registerCPPClass("QTime", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QTime>);
78 PythonQt::self()->registerCPPClass("QTime", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QTime>);
79 PythonQt::self()->registerCPPClass("QDateTime", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QDateTime>);
79 PythonQt::self()->registerCPPClass("QDateTime", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QDateTime>);
80 PythonQt::self()->registerCPPClass("QUrl", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QUrl>);
80 PythonQt::self()->registerCPPClass("QUrl", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QUrl>);
81 PythonQt::self()->registerCPPClass("QLocale", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QLocale>);
81 PythonQt::self()->registerCPPClass("QLocale", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QLocale>);
82 PythonQt::self()->registerCPPClass("QRect", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QRect>);
82 PythonQt::self()->registerCPPClass("QRect", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QRect>);
83 PythonQt::self()->registerCPPClass("QRectF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QRectF>);
83 PythonQt::self()->registerCPPClass("QRectF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QRectF>);
84 PythonQt::self()->registerCPPClass("QSize", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QSize>);
84 PythonQt::self()->registerCPPClass("QSize", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QSize>);
85 PythonQt::self()->registerCPPClass("QSizeF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QSizeF>);
85 PythonQt::self()->registerCPPClass("QSizeF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QSizeF>);
86 PythonQt::self()->registerCPPClass("QLine", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QLine>);
86 PythonQt::self()->registerCPPClass("QLine", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QLine>);
87 PythonQt::self()->registerCPPClass("QLineF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QLineF>);
87 PythonQt::self()->registerCPPClass("QLineF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QLineF>);
88 PythonQt::self()->registerCPPClass("QPoint", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QPoint>);
88 PythonQt::self()->registerCPPClass("QPoint", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QPoint>);
89 PythonQt::self()->registerCPPClass("QPointF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QPointF>);
89 PythonQt::self()->registerCPPClass("QPointF", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QPointF>);
90 PythonQt::self()->registerCPPClass("QRegExp", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QRegExp>);
90 PythonQt::self()->registerCPPClass("QRegExp", "", "QtCore", PythonQtCreateObject<PythonQtWrapper_QRegExp>);
91
91
92 PythonQtRegisterToolClassesTemplateConverter(QDate);
92 PythonQtRegisterToolClassesTemplateConverter(QDate);
93 PythonQtRegisterToolClassesTemplateConverter(QTime);
93 PythonQtRegisterToolClassesTemplateConverter(QTime);
94 PythonQtRegisterToolClassesTemplateConverter(QDateTime);
94 PythonQtRegisterToolClassesTemplateConverter(QDateTime);
95 PythonQtRegisterToolClassesTemplateConverter(QUrl);
95 PythonQtRegisterToolClassesTemplateConverter(QUrl);
96 PythonQtRegisterToolClassesTemplateConverter(QLocale);
96 PythonQtRegisterToolClassesTemplateConverter(QLocale);
97 PythonQtRegisterToolClassesTemplateConverter(QRect);
97 PythonQtRegisterToolClassesTemplateConverter(QRect);
98 PythonQtRegisterToolClassesTemplateConverter(QRectF);
98 PythonQtRegisterToolClassesTemplateConverter(QRectF);
99 PythonQtRegisterToolClassesTemplateConverter(QSize);
99 PythonQtRegisterToolClassesTemplateConverter(QSize);
100 PythonQtRegisterToolClassesTemplateConverter(QSizeF);
100 PythonQtRegisterToolClassesTemplateConverter(QSizeF);
101 PythonQtRegisterToolClassesTemplateConverter(QLine);
101 PythonQtRegisterToolClassesTemplateConverter(QLine);
102 PythonQtRegisterToolClassesTemplateConverter(QLineF);
102 PythonQtRegisterToolClassesTemplateConverter(QLineF);
103 PythonQtRegisterToolClassesTemplateConverter(QPoint);
103 PythonQtRegisterToolClassesTemplateConverter(QPoint);
104 PythonQtRegisterToolClassesTemplateConverter(QPointF);
104 PythonQtRegisterToolClassesTemplateConverter(QPointF);
105 PythonQtRegisterToolClassesTemplateConverter(QRegExp);
105 PythonQtRegisterToolClassesTemplateConverter(QRegExp);
106
106
107 PythonQt::self()->registerCPPClass("QFont", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QFont>);
107 PythonQt::self()->registerCPPClass("QFont", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QFont>);
108 PythonQt::self()->registerCPPClass("QPixmap", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPixmap>);
108 PythonQt::self()->registerCPPClass("QPixmap", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPixmap>);
109 PythonQt::self()->registerCPPClass("QBrush", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QBrush>);
109 PythonQt::self()->registerCPPClass("QBrush", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QBrush>);
110 PythonQt::self()->registerCPPClass("QColor", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QColor>);
110 PythonQt::self()->registerCPPClass("QColor", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QColor>);
111 PythonQt::self()->registerCPPClass("QPalette", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPalette>);
111 PythonQt::self()->registerCPPClass("QPalette", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPalette>);
112 PythonQt::self()->registerCPPClass("QIcon", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QIcon>);
112 PythonQt::self()->registerCPPClass("QIcon", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QIcon>);
113 PythonQt::self()->registerCPPClass("QImage", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QImage>);
113 PythonQt::self()->registerCPPClass("QImage", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QImage>);
114 PythonQt::self()->registerCPPClass("QPolygon", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPolygon>);
114 PythonQt::self()->registerCPPClass("QPolygon", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPolygon>);
115 PythonQt::self()->registerCPPClass("QRegion", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QRegion>);
115 PythonQt::self()->registerCPPClass("QRegion", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QRegion>);
116 PythonQt::self()->registerCPPClass("QBitmap", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QBitmap>);
116 PythonQt::self()->registerCPPClass("QBitmap", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QBitmap>);
117 PythonQt::self()->registerCPPClass("QCursor", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QCursor>);
117 PythonQt::self()->registerCPPClass("QCursor", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QCursor>);
118 PythonQt::self()->registerCPPClass("QSizePolicy", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QSizePolicy>);
118 PythonQt::self()->registerCPPClass("QSizePolicy", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QSizePolicy>);
119 PythonQt::self()->registerCPPClass("QKeySequence", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QKeySequence>);
119 PythonQt::self()->registerCPPClass("QKeySequence", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QKeySequence>);
120 PythonQt::self()->registerCPPClass("QPen", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPen>);
120 PythonQt::self()->registerCPPClass("QPen", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QPen>);
121 PythonQt::self()->registerCPPClass("QTextLength", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QTextLength>);
121 PythonQt::self()->registerCPPClass("QTextLength", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QTextLength>);
122 PythonQt::self()->registerCPPClass("QTextFormat", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QTextFormat>);
122 PythonQt::self()->registerCPPClass("QTextFormat", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QTextFormat>);
123 PythonQt::self()->registerCPPClass("QMatrix", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QMatrix>);
123 PythonQt::self()->registerCPPClass("QMatrix", "", "QtGui", PythonQtCreateObject<PythonQtWrapper_QMatrix>);
124
124
125 PythonQtRegisterToolClassesTemplateConverter(QFont);
125 PythonQtRegisterToolClassesTemplateConverter(QFont);
126 PythonQtRegisterToolClassesTemplateConverter(QPixmap);
126 PythonQtRegisterToolClassesTemplateConverter(QPixmap);
127 PythonQtRegisterToolClassesTemplateConverter(QBrush);
127 PythonQtRegisterToolClassesTemplateConverter(QBrush);
128 PythonQtRegisterToolClassesTemplateConverter(QColor);
128 PythonQtRegisterToolClassesTemplateConverter(QColor);
129 PythonQtRegisterToolClassesTemplateConverter(QPalette);
129 PythonQtRegisterToolClassesTemplateConverter(QPalette);
130 PythonQtRegisterToolClassesTemplateConverter(QIcon);
130 PythonQtRegisterToolClassesTemplateConverter(QIcon);
131 PythonQtRegisterToolClassesTemplateConverter(QImage);
131 PythonQtRegisterToolClassesTemplateConverter(QImage);
132 PythonQtRegisterToolClassesTemplateConverter(QPolygon);
132 PythonQtRegisterToolClassesTemplateConverter(QPolygon);
133 PythonQtRegisterToolClassesTemplateConverter(QRegion);
133 PythonQtRegisterToolClassesTemplateConverter(QRegion);
134 PythonQtRegisterToolClassesTemplateConverter(QBitmap);
134 PythonQtRegisterToolClassesTemplateConverter(QBitmap);
135 PythonQtRegisterToolClassesTemplateConverter(QCursor);
135 PythonQtRegisterToolClassesTemplateConverter(QCursor);
136 PythonQtRegisterToolClassesTemplateConverter(QSizePolicy);
136 PythonQtRegisterToolClassesTemplateConverter(QSizePolicy);
137 PythonQtRegisterToolClassesTemplateConverter(QKeySequence);
137 PythonQtRegisterToolClassesTemplateConverter(QKeySequence);
138 PythonQtRegisterToolClassesTemplateConverter(QPen);
138 PythonQtRegisterToolClassesTemplateConverter(QPen);
139 PythonQtRegisterToolClassesTemplateConverter(QTextLength);
139 PythonQtRegisterToolClassesTemplateConverter(QTextLength);
140 PythonQtRegisterToolClassesTemplateConverter(QTextFormat);
140 PythonQtRegisterToolClassesTemplateConverter(QTextFormat);
141 PythonQtRegisterToolClassesTemplateConverter(QMatrix);
141 PythonQtRegisterToolClassesTemplateConverter(QMatrix);
142
142
143
143
144 PyObject* pack = PythonQt::priv()->packageByName("QtCore");
144 PyObject* pack = PythonQt::priv()->packageByName("QtCore");
145 PyObject* pack2 = PythonQt::priv()->packageByName("Qt");
145 PyObject* pack2 = PythonQt::priv()->packageByName("Qt");
146 PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper();
146 PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper();
147 const char* names[16] = {"SIGNAL", "SLOT", "qAbs", "qBound","qDebug","qWarning","qCritical","qFatal"
147 const char* names[16] = {"SIGNAL", "SLOT", "qAbs", "qBound","qDebug","qWarning","qCritical","qFatal"
148 ,"qFuzzyCompare", "qMax","qMin","qRound","qRound64","qVersion","qrand","qsrand"};
148 ,"qFuzzyCompare", "qMax","qMin","qRound","qRound64","qVersion","qrand","qsrand"};
149 for (unsigned int i = 0;i<16; i++) {
149 for (unsigned int i = 0;i<16; i++) {
150 PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]);
150 PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]);
151 if (obj) {
151 if (obj) {
152 PyModule_AddObject(pack, names[i], obj);
152 PyModule_AddObject(pack, names[i], obj);
153 Py_INCREF(obj);
153 Py_INCREF(obj);
154 PyModule_AddObject(pack2, names[i], obj);
154 PyModule_AddObject(pack2, names[i], obj);
155 } else {
155 } else {
156 std::cerr << "method not found " << names[i];
156 std::cerr << "method not found " << names[i];
157 }
157 }
158 }
158 }
159 }
159 }
160
160
161 void PythonQt::cleanup()
161 void PythonQt::cleanup()
162 {
162 {
163 if (_self) {
163 if (_self) {
164 delete _self;
164 delete _self;
165 _self = NULL;
165 _self = NULL;
166 }
166 }
167 }
167 }
168
168
169 PythonQt::PythonQt(int flags)
169 PythonQt::PythonQt(int flags)
170 {
170 {
171 _p = new PythonQtPrivate;
171 _p = new PythonQtPrivate;
172 _p->_initFlags = flags;
172 _p->_initFlags = flags;
173
173
174 _p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr");
174 _p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr");
175
175
176 Py_SetProgramName("PythonQt");
176 Py_SetProgramName("PythonQt");
177 if (flags & IgnoreSiteModule) {
177 if (flags & IgnoreSiteModule) {
178 // this prevents the automatic importing of Python site files
178 // this prevents the automatic importing of Python site files
179 Py_NoSiteFlag = 1;
179 Py_NoSiteFlag = 1;
180 }
180 }
181 Py_Initialize();
181 Py_Initialize();
182
182
183 // add our own python object types for qt object slots
183 // add our own python object types for qt object slots
184 if (PyType_Ready(&PythonQtSlotFunction_Type) < 0) {
184 if (PyType_Ready(&PythonQtSlotFunction_Type) < 0) {
185 std::cerr << "could not initialize PythonQtSlotFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
185 std::cerr << "could not initialize PythonQtSlotFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
186 }
186 }
187 Py_INCREF(&PythonQtSlotFunction_Type);
187 Py_INCREF(&PythonQtSlotFunction_Type);
188
188
189 // according to Python docs, set the type late here, since it can not safely be stored in the struct when declaring it
189 // according to Python docs, set the type late here, since it can not safely be stored in the struct when declaring it
190 PythonQtClassWrapper_Type.tp_base = &PyType_Type;
190 PythonQtClassWrapper_Type.tp_base = &PyType_Type;
191 // add our own python object types for classes
191 // add our own python object types for classes
192 if (PyType_Ready(&PythonQtClassWrapper_Type) < 0) {
192 if (PyType_Ready(&PythonQtClassWrapper_Type) < 0) {
193 std::cerr << "could not initialize PythonQtClassWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
193 std::cerr << "could not initialize PythonQtClassWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
194 }
194 }
195 Py_INCREF(&PythonQtClassWrapper_Type);
195 Py_INCREF(&PythonQtClassWrapper_Type);
196
196
197 // add our own python object types for CPP instances
197 // add our own python object types for CPP instances
198 if (PyType_Ready(&PythonQtInstanceWrapper_Type) < 0) {
198 if (PyType_Ready(&PythonQtInstanceWrapper_Type) < 0) {
199 PythonQt::handleError();
199 PythonQt::handleError();
200 std::cerr << "could not initialize PythonQtInstanceWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
200 std::cerr << "could not initialize PythonQtInstanceWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
201 }
201 }
202 Py_INCREF(&PythonQtInstanceWrapper_Type);
202 Py_INCREF(&PythonQtInstanceWrapper_Type);
203
203
204 // add our own python object types for redirection of stdout
204 // add our own python object types for redirection of stdout
205 if (PyType_Ready(&PythonQtStdOutRedirectType) < 0) {
205 if (PyType_Ready(&PythonQtStdOutRedirectType) < 0) {
206 std::cerr << "could not initialize PythonQtStdOutRedirectType" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
206 std::cerr << "could not initialize PythonQtStdOutRedirectType" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
207 }
207 }
208 Py_INCREF(&PythonQtStdOutRedirectType);
208 Py_INCREF(&PythonQtStdOutRedirectType);
209
209
210 initPythonQtModule(flags & RedirectStdOut);
210 initPythonQtModule(flags & RedirectStdOut);
211
211
212 _p->setupSharedLibrarySuffixes();
212 _p->setupSharedLibrarySuffixes();
213
213
214 }
214 }
215
215
216 PythonQt::~PythonQt() {
216 PythonQt::~PythonQt() {
217 delete _p;
217 delete _p;
218 _p = NULL;
218 _p = NULL;
219 }
219 }
220
220
221 PythonQtPrivate::~PythonQtPrivate() {
221 PythonQtPrivate::~PythonQtPrivate() {
222 delete _defaultImporter;
222 delete _defaultImporter;
223 _defaultImporter = NULL;
223 _defaultImporter = NULL;
224
224
225 {
225 {
226 QHashIterator<QByteArray, PythonQtClassInfo *> i(_knownClassInfos);
226 QHashIterator<QByteArray, PythonQtClassInfo *> i(_knownClassInfos);
227 while (i.hasNext()) {
227 while (i.hasNext()) {
228 delete i.next().value();
228 delete i.next().value();
229 }
229 }
230 }
230 }
231 PythonQtConv::global_valueStorage.clear();
231 PythonQtConv::global_valueStorage.clear();
232 PythonQtConv::global_ptrStorage.clear();
232 PythonQtConv::global_ptrStorage.clear();
233 PythonQtConv::global_variantStorage.clear();
233 PythonQtConv::global_variantStorage.clear();
234
234
235 PythonQtMethodInfo::cleanupCachedMethodInfos();
235 PythonQtMethodInfo::cleanupCachedMethodInfos();
236 }
236 }
237
237
238 PythonQtImportFileInterface* PythonQt::importInterface()
238 PythonQtImportFileInterface* PythonQt::importInterface()
239 {
239 {
240 return _self->_p->_importInterface?_self->_p->_importInterface:_self->_p->_defaultImporter;
240 return _self->_p->_importInterface?_self->_p->_importInterface:_self->_p->_defaultImporter;
241 }
241 }
242
242
243 void PythonQt::qObjectNoLongerWrappedCB(QObject* o)
243 void PythonQt::qObjectNoLongerWrappedCB(QObject* o)
244 {
244 {
245 if (_self->_p->_noLongerWrappedCB) {
245 if (_self->_p->_noLongerWrappedCB) {
246 (*_self->_p->_noLongerWrappedCB)(o);
246 (*_self->_p->_noLongerWrappedCB)(o);
247 };
247 };
248 }
248 }
249
249
250 void PythonQt::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
250 void PythonQt::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
251 {
251 {
252 _p->registerClass(metaobject, package, wrapperCreator, shell);
252 _p->registerClass(metaobject, package, wrapperCreator, shell);
253 }
253 }
254
254
255 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
255 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
256 {
256 {
257 // we register all classes in the hierarchy
257 // we register all classes in the hierarchy
258 const QMetaObject* m = metaobject;
258 const QMetaObject* m = metaobject;
259 bool first = true;
259 bool first = true;
260 while (m) {
260 while (m) {
261 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(m->className());
261 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(m->className());
262 if (!info->pythonQtClassWrapper()) {
262 if (!info->pythonQtClassWrapper()) {
263 info->setupQObject(m);
263 info->setupQObject(m);
264 createPythonQtClassWrapper(info, package);
264 createPythonQtClassWrapper(info, package);
265 if (m->superClass()) {
265 if (m->superClass()) {
266 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
266 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
267 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo));
267 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo));
268 }
268 }
269 }
269 }
270 if (first) {
270 if (first) {
271 first = false;
271 first = false;
272 if (wrapperCreator) {
272 if (wrapperCreator) {
273 info->setDecoratorProvider(wrapperCreator);
273 info->setDecoratorProvider(wrapperCreator);
274 }
274 }
275 if (shell) {
275 if (shell) {
276 info->setShellSetInstanceWrapperCB(shell);
276 info->setShellSetInstanceWrapperCB(shell);
277 }
277 }
278 }
278 }
279 m = m->superClass();
279 m = m->superClass();
280 }
280 }
281 }
281 }
282
282
283 void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package)
283 void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package)
284 {
284 {
285 PyObject* pack = packageByName(package);
285 PyObject* pack = packageByName(package);
286 PyObject* pyobj = (PyObject*)createNewPythonQtClassWrapper(info, package);
286 PyObject* pyobj = (PyObject*)createNewPythonQtClassWrapper(info, package);
287 PyModule_AddObject(pack, info->className(), pyobj);
287 PyModule_AddObject(pack, info->className(), pyobj);
288 if (package && strncmp(package,"Qt",2)==0) {
288 if (package && strncmp(package,"Qt",2)==0) {
289 // since PyModule_AddObject steals the reference, we need a incref once more...
289 // since PyModule_AddObject steals the reference, we need a incref once more...
290 Py_INCREF(pyobj);
290 Py_INCREF(pyobj);
291 // put all qt objects into Qt as well
291 // put all qt objects into Qt as well
292 PyModule_AddObject(packageByName("Qt"), info->className(), pyobj);
292 PyModule_AddObject(packageByName("Qt"), info->className(), pyobj);
293 }
293 }
294 info->setPythonQtClassWrapper(pyobj);
294 info->setPythonQtClassWrapper(pyobj);
295 }
295 }
296
296
297 PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
297 PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
298 {
298 {
299 if (!obj) {
299 if (!obj) {
300 Py_INCREF(Py_None);
300 Py_INCREF(Py_None);
301 return Py_None;
301 return Py_None;
302 }
302 }
303 PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(obj);
303 PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(obj);
304 if (!wrap) {
304 if (!wrap) {
305 // smuggling it in...
305 // smuggling it in...
306 PythonQtClassInfo* classInfo = _knownClassInfos.value(obj->metaObject()->className());
306 PythonQtClassInfo* classInfo = _knownClassInfos.value(obj->metaObject()->className());
307 if (!classInfo || classInfo->pythonQtClassWrapper()==NULL) {
307 if (!classInfo || classInfo->pythonQtClassWrapper()==NULL) {
308 registerClass(obj->metaObject());
308 registerClass(obj->metaObject());
309 classInfo = _knownClassInfos.value(obj->metaObject()->className());
309 classInfo = _knownClassInfos.value(obj->metaObject()->className());
310 }
310 }
311 wrap = createNewPythonQtInstanceWrapper(obj, classInfo);
311 wrap = createNewPythonQtInstanceWrapper(obj, classInfo);
312 // mlabDebugConst("MLABPython","new qobject wrapper added " << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
312 // mlabDebugConst("MLABPython","new qobject wrapper added " << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
313 } else {
313 } else {
314 Py_INCREF(wrap);
314 Py_INCREF(wrap);
315 // mlabDebugConst("MLABPython","qobject wrapper reused " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
315 // mlabDebugConst("MLABPython","qobject wrapper reused " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
316 }
316 }
317 return (PyObject*)wrap;
317 return (PyObject*)wrap;
318 }
318 }
319
319
320 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
320 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
321 {
321 {
322 if (!ptr) {
322 if (!ptr) {
323 Py_INCREF(Py_None);
323 Py_INCREF(Py_None);
324 return Py_None;
324 return Py_None;
325 }
325 }
326
326
327 PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(ptr);
327 PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(ptr);
328 if (!wrap) {
328 if (!wrap) {
329 PythonQtClassInfo* info = _knownClassInfos.value(name);
329 PythonQtClassInfo* info = _knownClassInfos.value(name);
330 if (!info) {
330 if (!info) {
331 // maybe it is a PyObject, which we can return directly
331 // maybe it is a PyObject, which we can return directly
332 if (name == "PyObject") {
332 if (name == "PyObject") {
333 PyObject* p = (PyObject*)ptr;
333 PyObject* p = (PyObject*)ptr;
334 Py_INCREF(p);
334 Py_INCREF(p);
335 return p;
335 return p;
336 }
336 }
337
337
338 // we do not know the metaobject yet, but we might know it by it's name:
338 // we do not know the metaobject yet, but we might know it by it's name:
339 if (_knownQObjectClassNames.find(name)!=_knownQObjectClassNames.end()) {
339 if (_knownQObjectClassNames.find(name)!=_knownQObjectClassNames.end()) {
340 // yes, we know it, so we can convert to QObject
340 // yes, we know it, so we can convert to QObject
341 QObject* qptr = (QObject*)ptr;
341 QObject* qptr = (QObject*)ptr;
342 registerClass(qptr->metaObject());
342 registerClass(qptr->metaObject());
343 info = _knownClassInfos.value(qptr->metaObject()->className());
343 info = _knownClassInfos.value(qptr->metaObject()->className());
344 }
344 }
345 }
345 }
346 if (info && info->isQObject()) {
346 if (info && info->isQObject()) {
347 QObject* qptr = (QObject*)ptr;
347 QObject* qptr = (QObject*)ptr;
348 // if the object is a derived object, we want to switch the class info to the one of the derived class:
348 // if the object is a derived object, we want to switch the class info to the one of the derived class:
349 if (name!=(qptr->metaObject()->className())) {
349 if (name!=(qptr->metaObject()->className())) {
350 registerClass(qptr->metaObject());
350 registerClass(qptr->metaObject());
351 info = _knownClassInfos.value(qptr->metaObject()->className());
351 info = _knownClassInfos.value(qptr->metaObject()->className());
352 }
352 }
353 wrap = createNewPythonQtInstanceWrapper(qptr, info);
353 wrap = createNewPythonQtInstanceWrapper(qptr, info);
354 // mlabDebugConst("MLABPython","new qobject wrapper added " << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
354 // mlabDebugConst("MLABPython","new qobject wrapper added " << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
355 return (PyObject*)wrap;
355 return (PyObject*)wrap;
356 }
356 }
357
357
358 // not a known QObject, so try our wrapper factory:
358 // not a known QObject, so try our wrapper factory:
359 QObject* wrapper = NULL;
359 QObject* wrapper = NULL;
360 for (int i=0; i<_cppWrapperFactories.size(); i++) {
360 for (int i=0; i<_cppWrapperFactories.size(); i++) {
361 wrapper = _cppWrapperFactories.at(i)->create(name, ptr);
361 wrapper = _cppWrapperFactories.at(i)->create(name, ptr);
362 if (wrapper) {
362 if (wrapper) {
363 break;
363 break;
364 }
364 }
365 }
365 }
366
366
367 if (info) {
367 if (info) {
368 // try to downcast in the class hierarchy, which will modify info and ptr if it is successfull
368 // try to downcast in the class hierarchy, which will modify info and ptr if it is successfull
369 ptr = info->castDownIfPossible(ptr, &info);
369 ptr = info->castDownIfPossible(ptr, &info);
370 }
370 }
371
371
372 if (!info || info->pythonQtClassWrapper()==NULL) {
372 if (!info || info->pythonQtClassWrapper()==NULL) {
373 // still unknown, register as CPP class
373 // still unknown, register as CPP class
374 registerCPPClass(name.constData());
374 registerCPPClass(name.constData());
375 info = _knownClassInfos.value(name);
375 info = _knownClassInfos.value(name);
376 }
376 }
377 if (wrapper && (info->metaObject() != wrapper->metaObject())) {
377 if (wrapper && (info->metaObject() != wrapper->metaObject())) {
378 // if we a have a QObject wrapper and the metaobjects do not match, set the metaobject again!
378 // if we a have a QObject wrapper and the metaobjects do not match, set the metaobject again!
379 info->setMetaObject(wrapper->metaObject());
379 info->setMetaObject(wrapper->metaObject());
380 }
380 }
381 wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
381 wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
382 // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
382 // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
383 } else {
383 } else {
384 Py_INCREF(wrap);
384 Py_INCREF(wrap);
385 //mlabDebugConst("MLABPython","c++ wrapper reused " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
385 //mlabDebugConst("MLABPython","c++ wrapper reused " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
386 }
386 }
387 return (PyObject*)wrap;
387 return (PyObject*)wrap;
388 }
388 }
389
389
390 PyObject* PythonQtPrivate::dummyTuple() {
390 PyObject* PythonQtPrivate::dummyTuple() {
391 static PyObject* dummyTuple = NULL;
391 static PyObject* dummyTuple = NULL;
392 if (dummyTuple==NULL) {
392 if (dummyTuple==NULL) {
393 dummyTuple = PyTuple_New(1);
393 dummyTuple = PyTuple_New(1);
394 PyTuple_SET_ITEM(dummyTuple, 0 , PyString_FromString("dummy"));
394 PyTuple_SET_ITEM(dummyTuple, 0 , PyString_FromString("dummy"));
395 }
395 }
396 return dummyTuple;
396 return dummyTuple;
397 }
397 }
398
398
399
399
400 PythonQtInstanceWrapper* PythonQtPrivate::createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr) {
400 PythonQtInstanceWrapper* PythonQtPrivate::createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr) {
401 // call the associated class type to create a new instance...
401 // call the associated class type to create a new instance...
402 PythonQtInstanceWrapper* result = (PythonQtInstanceWrapper*)PyObject_Call(info->pythonQtClassWrapper(), dummyTuple(), NULL);
402 PythonQtInstanceWrapper* result = (PythonQtInstanceWrapper*)PyObject_Call(info->pythonQtClassWrapper(), dummyTuple(), NULL);
403
403
404 result->setQObject(obj);
404 result->setQObject(obj);
405 result->_wrappedPtr = wrappedPtr;
405 result->_wrappedPtr = wrappedPtr;
406 result->_ownedByPythonQt = false;
406 result->_ownedByPythonQt = false;
407 result->_useQMetaTypeDestroy = false;
407 result->_useQMetaTypeDestroy = false;
408
408
409 if (wrappedPtr) {
409 if (wrappedPtr) {
410 _wrappedObjects.insert(wrappedPtr, result);
410 _wrappedObjects.insert(wrappedPtr, result);
411 } else {
411 } else {
412 _wrappedObjects.insert(obj, result);
412 _wrappedObjects.insert(obj, result);
413 if (obj->parent()== NULL && _wrappedCB) {
413 if (obj->parent()== NULL && _wrappedCB) {
414 // tell someone who is interested that the qobject is wrapped the first time, if it has no parent
414 // tell someone who is interested that the qobject is wrapped the first time, if it has no parent
415 (*_wrappedCB)(obj);
415 (*_wrappedCB)(obj);
416 }
416 }
417 }
417 }
418 return result;
418 return result;
419 }
419 }
420
420
421 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package) {
421 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package) {
422 PythonQtClassWrapper* result;
422 PythonQtClassWrapper* result;
423
423
424 PyObject* className = PyString_FromString(info->className());
424 PyObject* className = PyString_FromString(info->className());
425
425
426 PyObject* baseClasses = PyTuple_New(1);
426 PyObject* baseClasses = PyTuple_New(1);
427 PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type);
427 PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type);
428
428
429 PyObject* typeDict = PyDict_New();
429 PyObject* typeDict = PyDict_New();
430 QByteArray moduleName("PythonQt");
430 QByteArray moduleName("PythonQt");
431 if (package && strcmp(package, "")!=0) {
431 if (package && strcmp(package, "")!=0) {
432 moduleName += ".";
432 moduleName += ".";
433 moduleName += package;
433 moduleName += package;
434 }
434 }
435 PyDict_SetItemString(typeDict, "__module__", PyString_FromString(moduleName.constData()));
435 PyDict_SetItemString(typeDict, "__module__", PyString_FromString(moduleName.constData()));
436
436
437 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
437 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
438
438
439 // set the class info so that PythonQtClassWrapper_new can read it
439 // set the class info so that PythonQtClassWrapper_new can read it
440 _currentClassInfoForClassWrapperCreation = info;
440 _currentClassInfoForClassWrapperCreation = info;
441 // create the new type object by calling the type
441 // create the new type object by calling the type
442 result = (PythonQtClassWrapper *)PyObject_Call((PyObject *)&PythonQtClassWrapper_Type, args, NULL);
442 result = (PythonQtClassWrapper *)PyObject_Call((PyObject *)&PythonQtClassWrapper_Type, args, NULL);
443
443
444 Py_DECREF(baseClasses);
444 Py_DECREF(baseClasses);
445 Py_DECREF(typeDict);
445 Py_DECREF(typeDict);
446 Py_DECREF(args);
446 Py_DECREF(args);
447 Py_DECREF(className);
447 Py_DECREF(className);
448
448
449 return result;
449 return result;
450 }
450 }
451
451
452 PyObject* PythonQtPrivate::createEnumValueInstance(PyObject* enumType, unsigned int enumValue)
452 PyObject* PythonQtPrivate::createEnumValueInstance(PyObject* enumType, unsigned int enumValue)
453 {
453 {
454 PyObject* args = Py_BuildValue("(i)", enumValue);
454 PyObject* args = Py_BuildValue("(i)", enumValue);
455 PyObject* result = PyObject_Call(enumType, args, NULL);
455 PyObject* result = PyObject_Call(enumType, args, NULL);
456 Py_DECREF(args);
456 Py_DECREF(args);
457 return result;
457 return result;
458 }
458 }
459
459
460 PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) {
460 PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) {
461 PyObject* result;
461 PyObject* result;
462
462
463 PyObject* className = PyString_FromString(enumName);
463 PyObject* className = PyString_FromString(enumName);
464
464
465 PyObject* baseClasses = PyTuple_New(1);
465 PyObject* baseClasses = PyTuple_New(1);
466 PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyInt_Type);
466 PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyInt_Type);
467
467
468 PyObject* module = PyObject_GetAttrString(parentObject, "__module__");
468 PyObject* module = PyObject_GetAttrString(parentObject, "__module__");
469 PyObject* typeDict = PyDict_New();
469 PyObject* typeDict = PyDict_New();
470 PyDict_SetItemString(typeDict, "__module__", module);
470 PyDict_SetItemString(typeDict, "__module__", module);
471
471
472 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
472 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
473
473
474 // create the new int derived type object by calling the core type
474 // create the new int derived type object by calling the core type
475 result = PyObject_Call((PyObject *)&PyType_Type, args, NULL);
475 result = PyObject_Call((PyObject *)&PyType_Type, args, NULL);
476
476
477 Py_DECREF(baseClasses);
477 Py_DECREF(baseClasses);
478 Py_DECREF(typeDict);
478 Py_DECREF(typeDict);
479 Py_DECREF(args);
479 Py_DECREF(args);
480 Py_DECREF(className);
480 Py_DECREF(className);
481
481
482 return result;
482 return result;
483 }
483 }
484
484
485 PythonQtSignalReceiver* PythonQt::getSignalReceiver(QObject* obj)
485 PythonQtSignalReceiver* PythonQt::getSignalReceiver(QObject* obj)
486 {
486 {
487 PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
487 PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
488 if (!r) {
488 if (!r) {
489 r = new PythonQtSignalReceiver(obj);
489 r = new PythonQtSignalReceiver(obj);
490 _p->_signalReceivers.insert(obj, r);
490 _p->_signalReceivers.insert(obj, r);
491 }
491 }
492 return r;
492 return r;
493 }
493 }
494
494
495 bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname)
495 bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname)
496 {
496 {
497 bool flag = false;
497 bool flag = false;
498 PythonQtObjectPtr callable = lookupCallable(module, objectname);
498 PythonQtObjectPtr callable = lookupCallable(module, objectname);
499 if (callable) {
499 if (callable) {
500 PythonQtSignalReceiver* r = getSignalReceiver(obj);
500 PythonQtSignalReceiver* r = getSignalReceiver(obj);
501 flag = r->addSignalHandler(signal, callable);
501 flag = r->addSignalHandler(signal, callable);
502 if (!flag) {
502 if (!flag) {
503 // signal not found
503 // signal not found
504 }
504 }
505 } else {
505 } else {
506 // callable not found
506 // callable not found
507 }
507 }
508 return flag;
508 return flag;
509 }
509 }
510
510
511 bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* receiver)
511 bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* receiver)
512 {
512 {
513 bool flag = false;
513 bool flag = false;
514 PythonQtSignalReceiver* r = getSignalReceiver(obj);
514 PythonQtSignalReceiver* r = getSignalReceiver(obj);
515 if (r) {
515 if (r) {
516 flag = r->addSignalHandler(signal, receiver);
516 flag = r->addSignalHandler(signal, receiver);
517 }
517 }
518 return flag;
518 return flag;
519 }
519 }
520
520
521 bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname)
521 bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname)
522 {
522 {
523 bool flag = false;
523 bool flag = false;
524 PythonQtObjectPtr callable = lookupCallable(module, objectname);
524 PythonQtObjectPtr callable = lookupCallable(module, objectname);
525 if (callable) {
525 if (callable) {
526 PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
526 PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
527 if (r) {
527 if (r) {
528 flag = r->removeSignalHandler(signal, callable);
528 flag = r->removeSignalHandler(signal, callable);
529 }
529 }
530 } else {
530 } else {
531 // callable not found
531 // callable not found
532 }
532 }
533 return flag;
533 return flag;
534 }
534 }
535
535
536 bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* receiver)
536 bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* receiver)
537 {
537 {
538 bool flag = false;
538 bool flag = false;
539 PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
539 PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
540 if (r) {
540 if (r) {
541 flag = r->removeSignalHandler(signal, receiver);
541 flag = r->removeSignalHandler(signal, receiver);
542 }
542 }
543 return flag;
543 return flag;
544 }
544 }
545
545
546 PythonQtObjectPtr PythonQt::lookupCallable(PyObject* module, const QString& name)
546 PythonQtObjectPtr PythonQt::lookupCallable(PyObject* module, const QString& name)
547 {
547 {
548 PythonQtObjectPtr p = lookupObject(module, name);
548 PythonQtObjectPtr p = lookupObject(module, name);
549 if (p) {
549 if (p) {
550 if (PyCallable_Check(p)) {
550 if (PyCallable_Check(p)) {
551 return p;
551 return p;
552 }
552 }
553 }
553 }
554 PyErr_Clear();
554 PyErr_Clear();
555 return NULL;
555 return NULL;
556 }
556 }
557
557
558 PythonQtObjectPtr PythonQt::lookupObject(PyObject* module, const QString& name)
558 PythonQtObjectPtr PythonQt::lookupObject(PyObject* module, const QString& name)
559 {
559 {
560 QStringList l = name.split('.');
560 QStringList l = name.split('.');
561 PythonQtObjectPtr p = module;
561 PythonQtObjectPtr p = module;
562 PythonQtObjectPtr prev;
562 PythonQtObjectPtr prev;
563 QString s;
563 QString s;
564 QByteArray b;
564 QByteArray b;
565 for (QStringList::ConstIterator i = l.begin(); i!=l.end() && p; ++i) {
565 for (QStringList::ConstIterator i = l.begin(); i!=l.end() && p; ++i) {
566 prev = p;
566 prev = p;
567 b = (*i).toLatin1();
567 b = (*i).toLatin1();
568 if (PyDict_Check(p)) {
568 if (PyDict_Check(p)) {
569 p = PyDict_GetItemString(p, b.data());
569 p = PyDict_GetItemString(p, b.data());
570 } else {
570 } else {
571 p.setNewRef(PyObject_GetAttrString(p, b.data()));
571 p.setNewRef(PyObject_GetAttrString(p, b.data()));
572 }
572 }
573 }
573 }
574 PyErr_Clear();
574 PyErr_Clear();
575 return p;
575 return p;
576 }
576 }
577
577
578 PythonQtObjectPtr PythonQt::getMainModule() {
578 PythonQtObjectPtr PythonQt::getMainModule() {
579 //both borrowed
579 //both borrowed
580 PythonQtObjectPtr dict = PyImport_GetModuleDict();
580 PythonQtObjectPtr dict = PyImport_GetModuleDict();
581 return PyDict_GetItemString(dict, "__main__");
581 return PyDict_GetItemString(dict, "__main__");
582 }
582 }
583
583
584 QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
584 QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
585 QVariant result;
585 QVariant result;
586 if (pycode) {
586 if (pycode) {
587 PyObject* dict = NULL;
587 PyObject* dict = NULL;
588 if (PyModule_Check(object)) {
588 if (PyModule_Check(object)) {
589 dict = PyModule_GetDict(object);
589 dict = PyModule_GetDict(object);
590 } else if (PyDict_Check(object)) {
590 } else if (PyDict_Check(object)) {
591 dict = object;
591 dict = object;
592 }
592 }
593 PyObject* r = NULL;
593 PyObject* r = NULL;
594 if (dict) {
594 if (dict) {
595 r = PyEval_EvalCode((PyCodeObject*)pycode, dict , dict);
595 r = PyEval_EvalCode((PyCodeObject*)pycode, dict , dict);
596 }
596 }
597 if (r) {
597 if (r) {
598 result = PythonQtConv::PyObjToQVariant(r);
598 result = PythonQtConv::PyObjToQVariant(r);
599 Py_DECREF(r);
599 Py_DECREF(r);
600 } else {
600 } else {
601 handleError();
601 handleError();
602 }
602 }
603 } else {
603 } else {
604 handleError();
604 handleError();
605 }
605 }
606 return result;
606 return result;
607 }
607 }
608
608
609 QVariant PythonQt::evalScript(PyObject* object, const QString& script, int start)
609 QVariant PythonQt::evalScript(PyObject* object, const QString& script, int start)
610 {
610 {
611 QVariant result;
611 QVariant result;
612 PythonQtObjectPtr p;
612 PythonQtObjectPtr p;
613 PyObject* dict = NULL;
613 PyObject* dict = NULL;
614 if (PyModule_Check(object)) {
614 if (PyModule_Check(object)) {
615 dict = PyModule_GetDict(object);
615 dict = PyModule_GetDict(object);
616 } else if (PyDict_Check(object)) {
616 } else if (PyDict_Check(object)) {
617 dict = object;
617 dict = object;
618 }
618 }
619 if (dict) {
619 if (dict) {
620 p.setNewRef(PyRun_String(script.toLatin1().data(), start, dict, dict));
620 p.setNewRef(PyRun_String(script.toLatin1().data(), start, dict, dict));
621 }
621 }
622 if (p) {
622 if (p) {
623 result = PythonQtConv::PyObjToQVariant(p);
623 result = PythonQtConv::PyObjToQVariant(p);
624 } else {
624 } else {
625 handleError();
625 handleError();
626 }
626 }
627 return result;
627 return result;
628 }
628 }
629
629
630 void PythonQt::evalFile(PyObject* module, const QString& filename)
630 void PythonQt::evalFile(PyObject* module, const QString& filename)
631 {
631 {
632 PythonQtObjectPtr code = parseFile(filename);
632 PythonQtObjectPtr code = parseFile(filename);
633 if (code) {
633 if (code) {
634 evalCode(module, code);
634 evalCode(module, code);
635 } else {
635 } else {
636 handleError();
636 handleError();
637 }
637 }
638 }
638 }
639
639
640 PythonQtObjectPtr PythonQt::parseFile(const QString& filename)
640 PythonQtObjectPtr PythonQt::parseFile(const QString& filename)
641 {
641 {
642 PythonQtObjectPtr p;
642 PythonQtObjectPtr p;
643 p.setNewRef(PythonQtImport::getCodeFromPyc(filename));
643 p.setNewRef(PythonQtImport::getCodeFromPyc(filename));
644 if (!p) {
644 if (!p) {
645 handleError();
645 handleError();
646 }
646 }
647 return p;
647 return p;
648 }
648 }
649
649
650 PythonQtObjectPtr PythonQt::createModuleFromFile(const QString& name, const QString& filename)
650 PythonQtObjectPtr PythonQt::createModuleFromFile(const QString& name, const QString& filename)
651 {
651 {
652 PythonQtObjectPtr code = parseFile(filename);
652 PythonQtObjectPtr code = parseFile(filename);
653 PythonQtObjectPtr module = _p->createModule(name, code);
653 PythonQtObjectPtr module = _p->createModule(name, code);
654 return module;
654 return module;
655 }
655 }
656
656
657 PythonQtObjectPtr PythonQt::createModuleFromScript(const QString& name, const QString& script)
657 PythonQtObjectPtr PythonQt::createModuleFromScript(const QString& name, const QString& script)
658 {
658 {
659 PyErr_Clear();
659 PyErr_Clear();
660 QString scriptCode = script;
660 QString scriptCode = script;
661 if (scriptCode.isEmpty()) {
661 if (scriptCode.isEmpty()) {
662 // we always need at least a linefeed
662 // we always need at least a linefeed
663 scriptCode = "\n";
663 scriptCode = "\n";
664 }
664 }
665 PythonQtObjectPtr pycode;
665 PythonQtObjectPtr pycode;
666 pycode.setNewRef(Py_CompileString((char*)scriptCode.toLatin1().data(), "", Py_file_input));
666 pycode.setNewRef(Py_CompileString((char*)scriptCode.toLatin1().data(), "", Py_file_input));
667 PythonQtObjectPtr module = _p->createModule(name, pycode);
667 PythonQtObjectPtr module = _p->createModule(name, pycode);
668 return module;
668 return module;
669 }
669 }
670
670
671 PythonQtObjectPtr PythonQt::createUniqueModule()
671 PythonQtObjectPtr PythonQt::createUniqueModule()
672 {
672 {
673 static QString pyQtStr("PythonQt_module");
673 static QString pyQtStr("PythonQt_module");
674 QString moduleName = pyQtStr+QString::number(_uniqueModuleCount++);
674 QString moduleName = pyQtStr+QString::number(_uniqueModuleCount++);
675 return createModuleFromScript(moduleName);
675 return createModuleFromScript(moduleName);
676 }
676 }
677
677
678 void PythonQt::addObject(PyObject* object, const QString& name, QObject* qObject)
678 void PythonQt::addObject(PyObject* object, const QString& name, QObject* qObject)
679 {
679 {
680 if (PyModule_Check(object)) {
680 if (PyModule_Check(object)) {
681 PyModule_AddObject(object, name.toLatin1().data(), _p->wrapQObject(qObject));
681 PyModule_AddObject(object, name.toLatin1().data(), _p->wrapQObject(qObject));
682 } else if (PyDict_Check(object)) {
682 } else if (PyDict_Check(object)) {
683 PyDict_SetItemString(object, name.toLatin1().data(), _p->wrapQObject(qObject));
683 PyDict_SetItemString(object, name.toLatin1().data(), _p->wrapQObject(qObject));
684 } else {
684 } else {
685 PyObject_SetAttrString(object, name.toLatin1().data(), _p->wrapQObject(qObject));
685 PyObject_SetAttrString(object, name.toLatin1().data(), _p->wrapQObject(qObject));
686 }
686 }
687 }
687 }
688
688
689 void PythonQt::addVariable(PyObject* object, const QString& name, const QVariant& v)
689 void PythonQt::addVariable(PyObject* object, const QString& name, const QVariant& v)
690 {
690 {
691 if (PyModule_Check(object)) {
691 if (PyModule_Check(object)) {
692 PyModule_AddObject(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
692 PyModule_AddObject(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
693 } else if (PyDict_Check(object)) {
693 } else if (PyDict_Check(object)) {
694 PyDict_SetItemString(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
694 PyDict_SetItemString(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
695 } else {
695 } else {
696 PyObject_SetAttrString(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
696 PyObject_SetAttrString(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
697 }
697 }
698 }
698 }
699
699
700 void PythonQt::removeVariable(PyObject* object, const QString& name)
700 void PythonQt::removeVariable(PyObject* object, const QString& name)
701 {
701 {
702 if (PyDict_Check(object)) {
702 if (PyDict_Check(object)) {
703 PyDict_DelItemString(object, name.toLatin1().data());
703 PyDict_DelItemString(object, name.toLatin1().data());
704 } else {
704 } else {
705 PyObject_DelAttrString(object, name.toLatin1().data());
705 PyObject_DelAttrString(object, name.toLatin1().data());
706 }
706 }
707 }
707 }
708
708
709 QVariant PythonQt::getVariable(PyObject* object, const QString& objectname)
709 QVariant PythonQt::getVariable(PyObject* object, const QString& objectname)
710 {
710 {
711 QVariant result;
711 QVariant result;
712 PythonQtObjectPtr obj = lookupObject(object, objectname);
712 PythonQtObjectPtr obj = lookupObject(object, objectname);
713 if (obj) {
713 if (obj) {
714 result = PythonQtConv::PyObjToQVariant(obj);
714 result = PythonQtConv::PyObjToQVariant(obj);
715 }
715 }
716 return result;
716 return result;
717 }
717 }
718
718
719 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, PythonQt::ObjectType type)
719 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, PythonQt::ObjectType type)
720 {
720 {
721 QStringList results;
721 QStringList results;
722
722
723 PythonQtObjectPtr object;
723 PythonQtObjectPtr object;
724 if (objectname.isEmpty()) {
724 if (objectname.isEmpty()) {
725 object = module;
725 object = module;
726 } else {
726 } else {
727 object = lookupObject(module, objectname);
727 object = lookupObject(module, objectname);
728 if (!object && type == CallOverloads) {
728 if (!object && type == CallOverloads) {
729 PyObject* dict = lookupObject(module, "__builtins__");
729 PyObject* dict = lookupObject(module, "__builtins__");
730 if (dict) {
730 if (dict) {
731 object = PyDict_GetItemString(dict, objectname.toLatin1().constData());
731 object = PyDict_GetItemString(dict, objectname.toLatin1().constData());
732 }
732 }
733 }
733 }
734 }
734 }
735
735
736 if (object) {
736 if (object) {
737 if (type == CallOverloads) {
737 if (type == CallOverloads) {
738 if (PythonQtSlotFunction_Check(object)) {
738 if (PythonQtSlotFunction_Check(object)) {
739 PythonQtSlotFunctionObject* o = (PythonQtSlotFunctionObject*)object.object();
739 PythonQtSlotFunctionObject* o = (PythonQtSlotFunctionObject*)object.object();
740 PythonQtSlotInfo* info = o->m_ml;
740 PythonQtSlotInfo* info = o->m_ml;
741
741
742 while (info) {
742 while (info) {
743 results << info->fullSignature();
743 results << info->fullSignature();
744 info = info->nextInfo();
744 info = info->nextInfo();
745 }
745 }
746 } else if (object->ob_type == &PythonQtClassWrapper_Type) {
746 } else if (object->ob_type == &PythonQtClassWrapper_Type) {
747 PythonQtClassWrapper* o = (PythonQtClassWrapper*)object.object();
747 PythonQtClassWrapper* o = (PythonQtClassWrapper*)object.object();
748 PythonQtSlotInfo* info = o->classInfo()->constructors();
748 PythonQtSlotInfo* info = o->classInfo()->constructors();
749
749
750 while (info) {
750 while (info) {
751 results << info->fullSignature();
751 results << info->fullSignature();
752 info = info->nextInfo();
752 info = info->nextInfo();
753 }
753 }
754 } else {
754 } else {
755 //TODO: use pydoc!
755 //TODO: use pydoc!
756 PyObject* doc = PyObject_GetAttrString(object, "__doc__");
756 PyObject* doc = PyObject_GetAttrString(object, "__doc__");
757 if (doc) {
757 if (doc) {
758 results << PyString_AsString(doc);
758 results << PyString_AsString(doc);
759 Py_DECREF(doc);
759 Py_DECREF(doc);
760 }
760 }
761 }
761 }
762 } else {
762 } else {
763 PyObject* keys = NULL;
763 PyObject* keys = NULL;
764 bool isDict = false;
764 bool isDict = false;
765 if (PyDict_Check(object)) {
765 if (PyDict_Check(object)) {
766 keys = PyDict_Keys(object);
766 keys = PyDict_Keys(object);
767 isDict = true;
767 isDict = true;
768 } else {
768 } else {
769 keys = PyObject_Dir(object);
769 keys = PyObject_Dir(object);
770 }
770 }
771 if (keys) {
771 if (keys) {
772 int count = PyList_Size(keys);
772 int count = PyList_Size(keys);
773 PyObject* key;
773 PyObject* key;
774 PyObject* value;
774 PyObject* value;
775 QString keystr;
775 QString keystr;
776 for (int i = 0;i<count;i++) {
776 for (int i = 0;i<count;i++) {
777 key = PyList_GetItem(keys,i);
777 key = PyList_GetItem(keys,i);
778 if (isDict) {
778 if (isDict) {
779 value = PyDict_GetItem(object, key);
779 value = PyDict_GetItem(object, key);
780 Py_INCREF(value);
780 Py_INCREF(value);
781 } else {
781 } else {
782 value = PyObject_GetAttr(object, key);
782 value = PyObject_GetAttr(object, key);
783 }
783 }
784 if (!value) continue;
784 if (!value) continue;
785 keystr = PyString_AsString(key);
785 keystr = PyString_AsString(key);
786 static const QString underscoreStr("__tmp");
786 static const QString underscoreStr("__tmp");
787 if (!keystr.startsWith(underscoreStr)) {
787 if (!keystr.startsWith(underscoreStr)) {
788 switch (type) {
788 switch (type) {
789 case Anything:
789 case Anything:
790 results << keystr;
790 results << keystr;
791 break;
791 break;
792 case Class:
792 case Class:
793 if (value->ob_type == &PyClass_Type) {
793 if (value->ob_type == &PyClass_Type) {
794 results << keystr;
794 results << keystr;
795 }
795 }
796 break;
796 break;
797 case Variable:
797 case Variable:
798 if (value->ob_type != &PyClass_Type
798 if (value->ob_type != &PyClass_Type
799 && value->ob_type != &PyCFunction_Type
799 && value->ob_type != &PyCFunction_Type
800 && value->ob_type != &PyFunction_Type
800 && value->ob_type != &PyFunction_Type
801 && value->ob_type != &PyModule_Type
801 && value->ob_type != &PyModule_Type
802 ) {
802 ) {
803 results << keystr;
803 results << keystr;
804 }
804 }
805 break;
805 break;
806 case Function:
806 case Function:
807 if (value->ob_type == &PyFunction_Type ||
807 if (value->ob_type == &PyFunction_Type ||
808 value->ob_type == &PyMethod_Type
808 value->ob_type == &PyMethod_Type
809 ) {
809 ) {
810 results << keystr;
810 results << keystr;
811 }
811 }
812 break;
812 break;
813 case Module:
813 case Module:
814 if (value->ob_type == &PyModule_Type) {
814 if (value->ob_type == &PyModule_Type) {
815 results << keystr;
815 results << keystr;
816 }
816 }
817 break;
817 break;
818 default:
818 default:
819 std::cerr << "PythonQt: introspection: unknown case" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
819 std::cerr << "PythonQt: introspection: unknown case" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
820 }
820 }
821 }
821 }
822 Py_DECREF(value);
822 Py_DECREF(value);
823 }
823 }
824 Py_DECREF(keys);
824 Py_DECREF(keys);
825 }
825 }
826 }
826 }
827 }
827 }
828 return results;
828 return results;
829 }
829 }
830
830
831 QVariant PythonQt::call(PyObject* object, const QString& name, const QVariantList& args)
831 QVariant PythonQt::call(PyObject* object, const QString& name, const QVariantList& args)
832 {
832 {
833 PythonQtObjectPtr callable = lookupCallable(object, name);
833 PythonQtObjectPtr callable = lookupCallable(object, name);
834 if (callable) {
834 if (callable) {
835 return call(callable, args);
835 return call(callable, args);
836 } else {
836 } else {
837 return QVariant();
837 return QVariant();
838 }
838 }
839 }
839 }
840
840
841 QVariant PythonQt::call(PyObject* callable, const QVariantList& args)
841 QVariant PythonQt::call(PyObject* callable, const QVariantList& args)
842 {
842 {
843 QVariant r;
843 QVariant r;
844 PythonQtObjectPtr result;
844 PythonQtObjectPtr result;
845 result.setNewRef(callAndReturnPyObject(callable, args));
845 result.setNewRef(callAndReturnPyObject(callable, args));
846 if (result) {
846 if (result) {
847 r = PythonQtConv::PyObjToQVariant(result);
847 r = PythonQtConv::PyObjToQVariant(result);
848 } else {
848 } else {
849 PythonQt::self()->handleError();
849 PythonQt::self()->handleError();
850 }
850 }
851 return r;
851 return r;
852 }
852 }
853
853
854 PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList& args)
854 PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList& args)
855 {
855 {
856 PyObject* result = NULL;
856 PyObject* result = NULL;
857 if (callable) {
857 if (callable) {
858 PythonQtObjectPtr pargs;
858 PythonQtObjectPtr pargs;
859 int count = args.size();
859 int count = args.size();
860 if (count>0) {
860 if (count>0) {
861 pargs.setNewRef(PyTuple_New(count));
861 pargs.setNewRef(PyTuple_New(count));
862 }
862 }
863 bool err = false;
863 bool err = false;
864 // transform QVariants to Python
864 // transform QVariants to Python
865 for (int i = 0; i < count; i++) {
865 for (int i = 0; i < count; i++) {
866 PyObject* arg = PythonQtConv::QVariantToPyObject(args.at(i));
866 PyObject* arg = PythonQtConv::QVariantToPyObject(args.at(i));
867 if (arg) {
867 if (arg) {
868 // steals reference, no unref
868 // steals reference, no unref
869 PyTuple_SetItem(pargs, i,arg);
869 PyTuple_SetItem(pargs, i,arg);
870 } else {
870 } else {
871 err = true;
871 err = true;
872 break;
872 break;
873 }
873 }
874 }
874 }
875
875
876 if (!err) {
876 if (!err) {
877 PyErr_Clear();
877 PyErr_Clear();
878 result = PyObject_CallObject(callable, pargs);
878 result = PyObject_CallObject(callable, pargs);
879 }
879 }
880 }
880 }
881 return result;
881 return result;
882 }
882 }
883
883
884 void PythonQt::addInstanceDecorators(QObject* o)
884 void PythonQt::addInstanceDecorators(QObject* o)
885 {
885 {
886 _p->addDecorators(o, PythonQtPrivate::InstanceDecorator);
886 _p->addDecorators(o, PythonQtPrivate::InstanceDecorator);
887 }
887 }
888
888
889 void PythonQt::addClassDecorators(QObject* o)
889 void PythonQt::addClassDecorators(QObject* o)
890 {
890 {
891 _p->addDecorators(o, PythonQtPrivate::StaticDecorator | PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator);
891 _p->addDecorators(o, PythonQtPrivate::StaticDecorator | PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator);
892 }
892 }
893
893
894 void PythonQt::addDecorators(QObject* o)
894 void PythonQt::addDecorators(QObject* o)
895 {
895 {
896 _p->addDecorators(o, PythonQtPrivate::AllDecorators);
896 _p->addDecorators(o, PythonQtPrivate::AllDecorators);
897 }
897 }
898
898
899 void PythonQt::registerQObjectClassNames(const QStringList& names)
899 void PythonQt::registerQObjectClassNames(const QStringList& names)
900 {
900 {
901 _p->registerQObjectClassNames(names);
901 _p->registerQObjectClassNames(names);
902 }
902 }
903
903
904 void PythonQt::setImporter(PythonQtImportFileInterface* importInterface)
904 void PythonQt::setImporter(PythonQtImportFileInterface* importInterface)
905 {
905 {
906 PythonQtImport::init();
907 _p->_importInterface = importInterface;
906 _p->_importInterface = importInterface;
907 PythonQtImport::init();
908 }
908 }
909
909
910 void PythonQt::setImporterIgnorePaths(const QStringList& paths)
910 void PythonQt::setImporterIgnorePaths(const QStringList& paths)
911 {
911 {
912 _p->_importIgnorePaths = paths;
912 _p->_importIgnorePaths = paths;
913 }
913 }
914
914
915 const QStringList& PythonQt::getImporterIgnorePaths()
915 const QStringList& PythonQt::getImporterIgnorePaths()
916 {
916 {
917 return _p->_importIgnorePaths;
917 return _p->_importIgnorePaths;
918 }
918 }
919
919
920 void PythonQt::addWrapperFactory(PythonQtCppWrapperFactory* factory)
920 void PythonQt::addWrapperFactory(PythonQtCppWrapperFactory* factory)
921 {
921 {
922 _p->_cppWrapperFactories.append(factory);
922 _p->_cppWrapperFactories.append(factory);
923 }
923 }
924
924
925 //---------------------------------------------------------------------------------------------------
925 //---------------------------------------------------------------------------------------------------
926 PythonQtPrivate::PythonQtPrivate()
926 PythonQtPrivate::PythonQtPrivate()
927 {
927 {
928 _importInterface = NULL;
928 _importInterface = NULL;
929 _defaultImporter = new PythonQtQFileImporter;
929 _defaultImporter = new PythonQtQFileImporter;
930 _noLongerWrappedCB = NULL;
930 _noLongerWrappedCB = NULL;
931 _wrappedCB = NULL;
931 _wrappedCB = NULL;
932 _currentClassInfoForClassWrapperCreation = NULL;
932 _currentClassInfoForClassWrapperCreation = NULL;
933 }
933 }
934
934
935 void PythonQtPrivate::setupSharedLibrarySuffixes()
935 void PythonQtPrivate::setupSharedLibrarySuffixes()
936 {
936 {
937 _sharedLibrarySuffixes.clear();
937 _sharedLibrarySuffixes.clear();
938 PythonQtObjectPtr imp;
938 PythonQtObjectPtr imp;
939 imp.setNewRef(PyImport_ImportModule("imp"));
939 imp.setNewRef(PyImport_ImportModule("imp"));
940 int cExtensionCode = imp.getVariable("C_EXTENSION").toInt();
940 int cExtensionCode = imp.getVariable("C_EXTENSION").toInt();
941 QVariant result = imp.call("get_suffixes");
941 QVariant result = imp.call("get_suffixes");
942 foreach (QVariant entry, result.toList()) {
942 foreach (QVariant entry, result.toList()) {
943 QVariantList suffixEntry = entry.toList();
943 QVariantList suffixEntry = entry.toList();
944 if (suffixEntry.count()==3) {
944 if (suffixEntry.count()==3) {
945 int code = suffixEntry.at(2).toInt();
945 int code = suffixEntry.at(2).toInt();
946 if (code == cExtensionCode) {
946 if (code == cExtensionCode) {
947 _sharedLibrarySuffixes << suffixEntry.at(0).toString();
947 _sharedLibrarySuffixes << suffixEntry.at(0).toString();
948 }
948 }
949 }
949 }
950 }
950 }
951 }
951 }
952
952
953 PythonQtClassInfo* PythonQtPrivate::currentClassInfoForClassWrapperCreation()
953 PythonQtClassInfo* PythonQtPrivate::currentClassInfoForClassWrapperCreation()
954 {
954 {
955 PythonQtClassInfo* info = _currentClassInfoForClassWrapperCreation;
955 PythonQtClassInfo* info = _currentClassInfoForClassWrapperCreation;
956 _currentClassInfoForClassWrapperCreation = NULL;
956 _currentClassInfoForClassWrapperCreation = NULL;
957 return info;
957 return info;
958 }
958 }
959
959
960 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes)
960 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes)
961 {
961 {
962 o->setParent(this);
962 o->setParent(this);
963 int numMethods = o->metaObject()->methodCount();
963 int numMethods = o->metaObject()->methodCount();
964 for (int i = 0; i < numMethods; i++) {
964 for (int i = 0; i < numMethods; i++) {
965 QMetaMethod m = o->metaObject()->method(i);
965 QMetaMethod m = o->metaObject()->method(i);
966 if ((m.methodType() == QMetaMethod::Method ||
966 if ((m.methodType() == QMetaMethod::Method ||
967 m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
967 m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
968 if (qstrncmp(m.signature(), "new_", 4)==0) {
968 if (qstrncmp(m.signature(), "new_", 4)==0) {
969 if ((decoTypes & ConstructorDecorator) == 0) continue;
969 if ((decoTypes & ConstructorDecorator) == 0) continue;
970 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
970 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
971 if (info->parameters().at(0).isPointer) {
971 if (info->parameters().at(0).isPointer) {
972 QByteArray signature = m.signature();
972 QByteArray signature = m.signature();
973 QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4);
973 QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4);
974 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
974 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
975 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
975 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
976 classInfo->addConstructor(newSlot);
976 classInfo->addConstructor(newSlot);
977 }
977 }
978 } else if (qstrncmp(m.signature(), "delete_", 7)==0) {
978 } else if (qstrncmp(m.signature(), "delete_", 7)==0) {
979 if ((decoTypes & DestructorDecorator) == 0) continue;
979 if ((decoTypes & DestructorDecorator) == 0) continue;
980 QByteArray signature = m.signature();
980 QByteArray signature = m.signature();
981 QByteArray nameOfClass = signature.mid(7, signature.indexOf('(')-7);
981 QByteArray nameOfClass = signature.mid(7, signature.indexOf('(')-7);
982 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
982 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
983 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
983 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
984 classInfo->setDestructor(newSlot);
984 classInfo->setDestructor(newSlot);
985 } else if (qstrncmp(m.signature(), "static_", 7)==0) {
985 } else if (qstrncmp(m.signature(), "static_", 7)==0) {
986 if ((decoTypes & StaticDecorator) == 0) continue;
986 if ((decoTypes & StaticDecorator) == 0) continue;
987 QByteArray signature = m.signature();
987 QByteArray signature = m.signature();
988 QByteArray nameOfClass = signature.mid(signature.indexOf('_')+1);
988 QByteArray nameOfClass = signature.mid(signature.indexOf('_')+1);
989 nameOfClass = nameOfClass.mid(0, nameOfClass.indexOf('_'));
989 nameOfClass = nameOfClass.mid(0, nameOfClass.indexOf('_'));
990 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
990 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
991 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
991 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
992 classInfo->addDecoratorSlot(newSlot);
992 classInfo->addDecoratorSlot(newSlot);
993 } else {
993 } else {
994 if ((decoTypes & InstanceDecorator) == 0) continue;
994 if ((decoTypes & InstanceDecorator) == 0) continue;
995 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
995 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
996 if (info->parameters().count()>1) {
996 if (info->parameters().count()>1) {
997 PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1);
997 PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1);
998 if (p.isPointer) {
998 if (p.isPointer) {
999 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(p.name);
999 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(p.name);
1000 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::InstanceDecorator);
1000 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::InstanceDecorator);
1001 classInfo->addDecoratorSlot(newSlot);
1001 classInfo->addDecoratorSlot(newSlot);
1002 }
1002 }
1003 }
1003 }
1004 }
1004 }
1005 }
1005 }
1006 }
1006 }
1007 }
1007 }
1008
1008
1009 void PythonQtPrivate::registerQObjectClassNames(const QStringList& names)
1009 void PythonQtPrivate::registerQObjectClassNames(const QStringList& names)
1010 {
1010 {
1011 foreach(QString name, names) {
1011 foreach(QString name, names) {
1012 _knownQObjectClassNames.insert(name.toLatin1(), true);
1012 _knownQObjectClassNames.insert(name.toLatin1(), true);
1013 }
1013 }
1014 }
1014 }
1015
1015
1016 void PythonQtPrivate::removeSignalEmitter(QObject* obj)
1016 void PythonQtPrivate::removeSignalEmitter(QObject* obj)
1017 {
1017 {
1018 _signalReceivers.remove(obj);
1018 _signalReceivers.remove(obj);
1019 }
1019 }
1020
1020
1021 bool PythonQt::handleError()
1021 bool PythonQt::handleError()
1022 {
1022 {
1023 bool flag = false;
1023 bool flag = false;
1024 if (PyErr_Occurred()) {
1024 if (PyErr_Occurred()) {
1025
1025
1026 // currently we just print the error and the stderr handler parses the errors
1026 // currently we just print the error and the stderr handler parses the errors
1027 PyErr_Print();
1027 PyErr_Print();
1028
1028
1029 /*
1029 /*
1030 // EXTRA: the format of the ptype and ptraceback is not really documented, so I use PyErr_Print() above
1030 // EXTRA: the format of the ptype and ptraceback is not really documented, so I use PyErr_Print() above
1031 PyObject *ptype;
1031 PyObject *ptype;
1032 PyObject *pvalue;
1032 PyObject *pvalue;
1033 PyObject *ptraceback;
1033 PyObject *ptraceback;
1034 PyErr_Fetch( &ptype, &pvalue, &ptraceback);
1034 PyErr_Fetch( &ptype, &pvalue, &ptraceback);
1035
1035
1036 Py_XDECREF(ptype);
1036 Py_XDECREF(ptype);
1037 Py_XDECREF(pvalue);
1037 Py_XDECREF(pvalue);
1038 Py_XDECREF(ptraceback);
1038 Py_XDECREF(ptraceback);
1039 */
1039 */
1040 PyErr_Clear();
1040 PyErr_Clear();
1041 flag = true;
1041 flag = true;
1042 }
1042 }
1043 return flag;
1043 return flag;
1044 }
1044 }
1045
1045
1046 void PythonQt::addSysPath(const QString& path)
1046 void PythonQt::addSysPath(const QString& path)
1047 {
1047 {
1048 PythonQtObjectPtr sys;
1048 PythonQtObjectPtr sys;
1049 sys.setNewRef(PyImport_ImportModule("sys"));
1049 sys.setNewRef(PyImport_ImportModule("sys"));
1050 PythonQtObjectPtr obj = lookupObject(sys, "path");
1050 PythonQtObjectPtr obj = lookupObject(sys, "path");
1051 PyList_Insert(obj, 0, PythonQtConv::QStringToPyObject(path));
1051 PyList_Insert(obj, 0, PythonQtConv::QStringToPyObject(path));
1052 }
1052 }
1053
1053
1054 void PythonQt::overwriteSysPath(const QStringList& paths)
1054 void PythonQt::overwriteSysPath(const QStringList& paths)
1055 {
1055 {
1056 PythonQtObjectPtr sys;
1056 PythonQtObjectPtr sys;
1057 sys.setNewRef(PyImport_ImportModule("sys"));
1057 sys.setNewRef(PyImport_ImportModule("sys"));
1058 PyModule_AddObject(sys, "path", PythonQtConv::QStringListToPyList(paths));
1058 PyModule_AddObject(sys, "path", PythonQtConv::QStringListToPyList(paths));
1059 }
1059 }
1060
1060
1061 void PythonQt::setModuleImportPath(PyObject* module, const QStringList& paths)
1061 void PythonQt::setModuleImportPath(PyObject* module, const QStringList& paths)
1062 {
1062 {
1063 PyModule_AddObject(module, "__path__", PythonQtConv::QStringListToPyList(paths));
1063 PyModule_AddObject(module, "__path__", PythonQtConv::QStringListToPyList(paths));
1064 }
1064 }
1065
1065
1066 void PythonQt::stdOutRedirectCB(const QString& str)
1066 void PythonQt::stdOutRedirectCB(const QString& str)
1067 {
1067 {
1068 emit PythonQt::self()->pythonStdOut(str);
1068 emit PythonQt::self()->pythonStdOut(str);
1069 }
1069 }
1070
1070
1071 void PythonQt::stdErrRedirectCB(const QString& str)
1071 void PythonQt::stdErrRedirectCB(const QString& str)
1072 {
1072 {
1073 emit PythonQt::self()->pythonStdErr(str);
1073 emit PythonQt::self()->pythonStdErr(str);
1074 }
1074 }
1075
1075
1076 void PythonQt::setQObjectWrappedCallback(PythonQtQObjectWrappedCB* cb)
1076 void PythonQt::setQObjectWrappedCallback(PythonQtQObjectWrappedCB* cb)
1077 {
1077 {
1078 _p->_wrappedCB = cb;
1078 _p->_wrappedCB = cb;
1079 }
1079 }
1080
1080
1081 void PythonQt::setQObjectNoLongerWrappedCallback(PythonQtQObjectNoLongerWrappedCB* cb)
1081 void PythonQt::setQObjectNoLongerWrappedCallback(PythonQtQObjectNoLongerWrappedCB* cb)
1082 {
1082 {
1083 _p->_noLongerWrappedCB = cb;
1083 _p->_noLongerWrappedCB = cb;
1084 }
1084 }
1085
1085
1086
1086
1087
1087
1088 static PyMethodDef PythonQtMethods[] = {
1088 static PyMethodDef PythonQtMethods[] = {
1089 {NULL, NULL, 0, NULL}
1089 {NULL, NULL, 0, NULL}
1090 };
1090 };
1091
1091
1092 void PythonQt::initPythonQtModule(bool redirectStdOut)
1092 void PythonQt::initPythonQtModule(bool redirectStdOut)
1093 {
1093 {
1094 _p->_pythonQtModule = Py_InitModule("PythonQt", PythonQtMethods);
1094 _p->_pythonQtModule = Py_InitModule("PythonQt", PythonQtMethods);
1095
1095
1096 if (redirectStdOut) {
1096 if (redirectStdOut) {
1097 PythonQtObjectPtr sys;
1097 PythonQtObjectPtr sys;
1098 PythonQtObjectPtr out;
1098 PythonQtObjectPtr out;
1099 PythonQtObjectPtr err;
1099 PythonQtObjectPtr err;
1100 sys.setNewRef(PyImport_ImportModule("sys"));
1100 sys.setNewRef(PyImport_ImportModule("sys"));
1101 // create a redirection object for stdout and stderr
1101 // create a redirection object for stdout and stderr
1102 out = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
1102 out = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
1103 ((PythonQtStdOutRedirect*)out.object())->_cb = stdOutRedirectCB;
1103 ((PythonQtStdOutRedirect*)out.object())->_cb = stdOutRedirectCB;
1104 err = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
1104 err = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
1105 ((PythonQtStdOutRedirect*)err.object())->_cb = stdErrRedirectCB;
1105 ((PythonQtStdOutRedirect*)err.object())->_cb = stdErrRedirectCB;
1106 // replace the built in file objects with our own objects
1106 // replace the built in file objects with our own objects
1107 PyModule_AddObject(sys, "stdout", out);
1107 PyModule_AddObject(sys, "stdout", out);
1108 PyModule_AddObject(sys, "stderr", err);
1108 PyModule_AddObject(sys, "stderr", err);
1109 }
1109 }
1110 }
1110 }
1111
1111
1112 void PythonQt::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
1112 void PythonQt::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
1113 {
1113 {
1114 _p->registerCPPClass(typeName, parentTypeName, package, wrapperCreator, shell);
1114 _p->registerCPPClass(typeName, parentTypeName, package, wrapperCreator, shell);
1115 }
1115 }
1116
1116
1117
1117
1118 PythonQtClassInfo* PythonQtPrivate::lookupClassInfoAndCreateIfNotPresent(const char* typeName)
1118 PythonQtClassInfo* PythonQtPrivate::lookupClassInfoAndCreateIfNotPresent(const char* typeName)
1119 {
1119 {
1120 PythonQtClassInfo* info = _knownClassInfos.value(typeName);
1120 PythonQtClassInfo* info = _knownClassInfos.value(typeName);
1121 if (!info) {
1121 if (!info) {
1122 info = new PythonQtClassInfo();
1122 info = new PythonQtClassInfo();
1123 info->setupCPPObject(typeName);
1123 info->setupCPPObject(typeName);
1124 _knownClassInfos.insert(typeName, info);
1124 _knownClassInfos.insert(typeName, info);
1125 }
1125 }
1126 return info;
1126 return info;
1127 }
1127 }
1128
1128
1129 void PythonQt::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
1129 void PythonQt::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
1130 {
1130 {
1131 _p->addPolymorphicHandler(typeName, cb);
1131 _p->addPolymorphicHandler(typeName, cb);
1132 }
1132 }
1133
1133
1134 void PythonQtPrivate::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
1134 void PythonQtPrivate::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
1135 {
1135 {
1136 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1136 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1137 info->addPolymorphicHandler(cb);
1137 info->addPolymorphicHandler(cb);
1138 }
1138 }
1139
1139
1140 bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
1140 bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
1141 {
1141 {
1142 return _p->addParentClass(typeName, parentTypeName, upcastingOffset);
1142 return _p->addParentClass(typeName, parentTypeName, upcastingOffset);
1143 }
1143 }
1144
1144
1145 bool PythonQtPrivate::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
1145 bool PythonQtPrivate::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
1146 {
1146 {
1147 PythonQtClassInfo* info = _knownClassInfos.value(typeName);
1147 PythonQtClassInfo* info = _knownClassInfos.value(typeName);
1148 if (info) {
1148 if (info) {
1149 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(parentTypeName);
1149 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(parentTypeName);
1150 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo, upcastingOffset));
1150 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo, upcastingOffset));
1151 return true;
1151 return true;
1152 } else {
1152 } else {
1153 return false;
1153 return false;
1154 }
1154 }
1155 }
1155 }
1156
1156
1157 void PythonQtPrivate::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
1157 void PythonQtPrivate::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
1158 {
1158 {
1159 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1159 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1160 if (!info->pythonQtClassWrapper()) {
1160 if (!info->pythonQtClassWrapper()) {
1161 info->setupCPPObject(typeName);
1161 info->setupCPPObject(typeName);
1162 createPythonQtClassWrapper(info, package);
1162 createPythonQtClassWrapper(info, package);
1163 }
1163 }
1164 if (parentTypeName && strcmp(parentTypeName,"")!=0) {
1164 if (parentTypeName && strcmp(parentTypeName,"")!=0) {
1165 addParentClass(typeName, parentTypeName, 0);
1165 addParentClass(typeName, parentTypeName, 0);
1166 }
1166 }
1167 if (wrapperCreator) {
1167 if (wrapperCreator) {
1168 info->setDecoratorProvider(wrapperCreator);
1168 info->setDecoratorProvider(wrapperCreator);
1169 }
1169 }
1170 if (shell) {
1170 if (shell) {
1171 info->setShellSetInstanceWrapperCB(shell);
1171 info->setShellSetInstanceWrapperCB(shell);
1172 }
1172 }
1173 }
1173 }
1174
1174
1175 PyObject* PythonQtPrivate::packageByName(const char* name)
1175 PyObject* PythonQtPrivate::packageByName(const char* name)
1176 {
1176 {
1177 if (name==NULL || name[0]==0) {
1177 if (name==NULL || name[0]==0) {
1178 return _pythonQtModule;
1178 return _pythonQtModule;
1179 }
1179 }
1180 PyObject* v = _packages.value(name);
1180 PyObject* v = _packages.value(name);
1181 if (!v) {
1181 if (!v) {
1182 v = PyImport_AddModule((QByteArray("PythonQt.") + name).constData());
1182 v = PyImport_AddModule((QByteArray("PythonQt.") + name).constData());
1183 _packages.insert(name, v);
1183 _packages.insert(name, v);
1184 // AddObject steals the reference, so increment it!
1184 // AddObject steals the reference, so increment it!
1185 Py_INCREF(v);
1185 Py_INCREF(v);
1186 PyModule_AddObject(_pythonQtModule, name, v);
1186 PyModule_AddObject(_pythonQtModule, name, v);
1187 }
1187 }
1188 return v;
1188 return v;
1189 }
1189 }
1190
1190
1191 void PythonQtPrivate::handleVirtualOverloadReturnError(const char* signature, const PythonQtMethodInfo* methodInfo, PyObject* result)
1191 void PythonQtPrivate::handleVirtualOverloadReturnError(const char* signature, const PythonQtMethodInfo* methodInfo, PyObject* result)
1192 {
1192 {
1193 QString error = "Return value '" + PythonQtConv::PyObjGetString(result) + "' can not be converted to expected C++ type '" + methodInfo->parameters().at(0).name + "' as return value of virtual method " + signature;
1193 QString error = "Return value '" + PythonQtConv::PyObjGetString(result) + "' can not be converted to expected C++ type '" + methodInfo->parameters().at(0).name + "' as return value of virtual method " + signature;
1194 PyErr_SetString(PyExc_AttributeError, error.toLatin1().data());
1194 PyErr_SetString(PyExc_AttributeError, error.toLatin1().data());
1195 PythonQt::self()->handleError();
1195 PythonQt::self()->handleError();
1196 }
1196 }
1197
1197
1198 PyObject* PythonQt::helpCalled(PythonQtClassInfo* info)
1198 PyObject* PythonQt::helpCalled(PythonQtClassInfo* info)
1199 {
1199 {
1200 if (_p->_initFlags & ExternalHelp) {
1200 if (_p->_initFlags & ExternalHelp) {
1201 emit pythonHelpRequest(QByteArray(info->className()));
1201 emit pythonHelpRequest(QByteArray(info->className()));
1202 return Py_BuildValue("");
1202 return Py_BuildValue("");
1203 } else {
1203 } else {
1204 return PyString_FromString(info->help().toLatin1().data());
1204 return PyString_FromString(info->help().toLatin1().data());
1205 }
1205 }
1206 }
1206 }
1207
1207
1208 void PythonQtPrivate::removeWrapperPointer(void* obj)
1208 void PythonQtPrivate::removeWrapperPointer(void* obj)
1209 {
1209 {
1210 _wrappedObjects.remove(obj);
1210 _wrappedObjects.remove(obj);
1211 }
1211 }
1212
1212
1213 void PythonQtPrivate::addWrapperPointer(void* obj, PythonQtInstanceWrapper* wrapper)
1213 void PythonQtPrivate::addWrapperPointer(void* obj, PythonQtInstanceWrapper* wrapper)
1214 {
1214 {
1215 _wrappedObjects.insert(obj, wrapper);
1215 _wrappedObjects.insert(obj, wrapper);
1216 }
1216 }
1217
1217
1218 PythonQtInstanceWrapper* PythonQtPrivate::findWrapperAndRemoveUnused(void* obj)
1218 PythonQtInstanceWrapper* PythonQtPrivate::findWrapperAndRemoveUnused(void* obj)
1219 {
1219 {
1220 PythonQtInstanceWrapper* wrap = _wrappedObjects.value(obj);
1220 PythonQtInstanceWrapper* wrap = _wrappedObjects.value(obj);
1221 if (wrap && !wrap->_wrappedPtr && wrap->_obj == NULL) {
1221 if (wrap && !wrap->_wrappedPtr && wrap->_obj == NULL) {
1222 // this is a wrapper whose QObject was already removed due to destruction
1222 // this is a wrapper whose QObject was already removed due to destruction
1223 // so the obj pointer has to be a new QObject with the same address...
1223 // so the obj pointer has to be a new QObject with the same address...
1224 // we remove the old one and set the copy to NULL
1224 // we remove the old one and set the copy to NULL
1225 wrap->_objPointerCopy = NULL;
1225 wrap->_objPointerCopy = NULL;
1226 removeWrapperPointer(obj);
1226 removeWrapperPointer(obj);
1227 wrap = NULL;
1227 wrap = NULL;
1228 }
1228 }
1229 return wrap;
1229 return wrap;
1230 }
1230 }
1231
1231
1232 PythonQtObjectPtr PythonQtPrivate::createModule(const QString& name, PyObject* pycode)
1232 PythonQtObjectPtr PythonQtPrivate::createModule(const QString& name, PyObject* pycode)
1233 {
1233 {
1234 PythonQtObjectPtr result;
1234 PythonQtObjectPtr result;
1235 if (pycode) {
1235 if (pycode) {
1236 result.setNewRef(PyImport_ExecCodeModule((char*)name.toLatin1().data(), pycode));
1236 result.setNewRef(PyImport_ExecCodeModule((char*)name.toLatin1().data(), pycode));
1237 } else {
1237 } else {
1238 PythonQt::self()->handleError();
1238 PythonQt::self()->handleError();
1239 }
1239 }
1240 return result;
1240 return result;
1241 }
1241 }
General Comments 0
You need to be logged in to leave comments. Login now