##// END OF EJS Templates
updated to upstream state in MeVisLab repository...
florianlink -
r157:78da86ccde11
parent child
Show More
@@ -245,6 +245,14 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* p
245 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
245 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
246 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo));
246 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo));
247 }
247 }
248 } else if (first && module) {
249 // There is a wrapper already, but if we got a module, we want to place the wrapper into that module as well,
250 // since it might have been placed into "private" earlier on.
251 // If the wrapper was already added to module before, it is just readded, which does no harm.
252 PyObject* classWrapper = info->pythonQtClassWrapper();
253 // AddObject steals a reference, so we need to INCREF
254 Py_INCREF(classWrapper);
255 PyModule_AddObject(module, info->className(), classWrapper);
248 }
256 }
249 if (first) {
257 if (first) {
250 first = false;
258 first = false;
@@ -913,6 +921,7 PythonQtPrivate::PythonQtPrivate()
913 _noLongerWrappedCB = NULL;
921 _noLongerWrappedCB = NULL;
914 _wrappedCB = NULL;
922 _wrappedCB = NULL;
915 _currentClassInfoForClassWrapperCreation = NULL;
923 _currentClassInfoForClassWrapperCreation = NULL;
924 _profilingCB = NULL;
916 }
925 }
917
926
918 void PythonQtPrivate::setupSharedLibrarySuffixes()
927 void PythonQtPrivate::setupSharedLibrarySuffixes()
@@ -922,6 +931,14 void PythonQtPrivate::setupSharedLibrarySuffixes()
922 imp.setNewRef(PyImport_ImportModule("imp"));
931 imp.setNewRef(PyImport_ImportModule("imp"));
923 int cExtensionCode = imp.getVariable("C_EXTENSION").toInt();
932 int cExtensionCode = imp.getVariable("C_EXTENSION").toInt();
924 QVariant result = imp.call("get_suffixes");
933 QVariant result = imp.call("get_suffixes");
934 #ifdef __linux
935 #ifdef _DEBUG
936 // First look for shared libraries with the '_d' suffix in debug mode on Linux.
937 // This is a workaround, because python does not append the '_d' suffix on Linux
938 // and would always load the release library otherwise.
939 _sharedLibrarySuffixes << "_d.so";
940 #endif
941 #endif
925 foreach (QVariant entry, result.toList()) {
942 foreach (QVariant entry, result.toList()) {
926 QVariantList suffixEntry = entry.toList();
943 QVariantList suffixEntry = entry.toList();
927 if (suffixEntry.count()==3) {
944 if (suffixEntry.count()==3) {
@@ -1066,6 +1083,10 void PythonQt::setQObjectNoLongerWrappedCallback(PythonQtQObjectNoLongerWrappedC
1066 _p->_noLongerWrappedCB = cb;
1083 _p->_noLongerWrappedCB = cb;
1067 }
1084 }
1068
1085
1086 void PythonQt::setProfilingCallback(ProfilingCB* cb)
1087 {
1088 _p->_profilingCB = cb;
1089 }
1069
1090
1070
1091
1071 static PyMethodDef PythonQtMethods[] = {
1092 static PyMethodDef PythonQtMethods[] = {
@@ -1194,6 +1215,13 PyObject* PythonQt::helpCalled(PythonQtClassInfo* info)
1194 }
1215 }
1195 }
1216 }
1196
1217
1218 void PythonQt::clearNotFoundCachedMembers()
1219 {
1220 foreach(PythonQtClassInfo* info, _p->_knownClassInfos) {
1221 info->clearNotFoundCachedMembers();
1222 }
1223 }
1224
1197 void PythonQtPrivate::removeWrapperPointer(void* obj)
1225 void PythonQtPrivate::removeWrapperPointer(void* obj)
1198 {
1226 {
1199 _wrappedObjects.remove(obj);
1227 _wrappedObjects.remove(obj);
@@ -143,6 +143,16 public:
143
143
144 };
144 };
145
145
146 //! enum for profiling callback
147 enum ProfilingCallbackState {
148 Enter = 1,
149 Leave = 2
150 };
151
152 //! callback for profiling. className and methodName are only passed when state == Enter, otherwise
153 //! they are NULL.
154 typedef void ProfilingCB(ProfilingCallbackState state, const char* className, const char* methodName);
155
146 //---------------------------------------------------------------------------
156 //---------------------------------------------------------------------------
147 //! \name Singleton Initialization
157 //! \name Singleton Initialization
148 //@{
158 //@{
@@ -427,6 +437,10 public:
427 //! The error is currently just output to the python stderr, future version might implement better trace printing
437 //! The error is currently just output to the python stderr, future version might implement better trace printing
428 bool handleError();
438 bool handleError();
429
439
440 //! clear all NotFound entries on all class infos, to ensure that
441 //! newly loaded wrappers can add methods even when the object was wrapped by PythonQt before the wrapper was loaded
442 void clearNotFoundCachedMembers();
443
430 //! set a callback that is called when a QObject with parent == NULL is wrapped by pythonqt
444 //! set a callback that is called when a QObject with parent == NULL is wrapped by pythonqt
431 void setQObjectWrappedCallback(PythonQtQObjectWrappedCB* cb);
445 void setQObjectWrappedCallback(PythonQtQObjectWrappedCB* cb);
432 //! set a callback that is called when a QObject with parent == NULL is no longer wrapped by pythonqt
446 //! set a callback that is called when a QObject with parent == NULL is no longer wrapped by pythonqt
@@ -442,6 +456,9 public:
442 //! @return new reference
456 //! @return new reference
443 PythonQtObjectPtr lookupObject(PyObject* module, const QString& name);
457 PythonQtObjectPtr lookupObject(PyObject* module, const QString& name);
444
458
459 //! sets a callback that is called before and after function calls for profiling
460 void setProfilingCallback(ProfilingCB* cb);
461
445 //@}
462 //@}
446
463
447 signals:
464 signals:
@@ -575,6 +592,9 public:
575 //! get access to the PythonQt module
592 //! get access to the PythonQt module
576 PythonQtObjectPtr pythonQtModule() const { return _pythonQtModule; }
593 PythonQtObjectPtr pythonQtModule() const { return _pythonQtModule; }
577
594
595 //! returns the profiling callback, which may be NULL
596 PythonQt::ProfilingCB* profilingCB() const { return _profilingCB; }
597
578 private:
598 private:
579 //! Setup the shared library suffixes by getting them from the "imp" module.
599 //! Setup the shared library suffixes by getting them from the "imp" module.
580 void setupSharedLibrarySuffixes();
600 void setupSharedLibrarySuffixes();
@@ -625,6 +645,8 private:
625
645
626 PythonQtClassInfo* _currentClassInfoForClassWrapperCreation;
646 PythonQtClassInfo* _currentClassInfoForClassWrapperCreation;
627
647
648 PythonQt::ProfilingCB* _profilingCB;
649
628 int _initFlags;
650 int _initFlags;
629 int _PythonQtObjectPtr_metaId;
651 int _PythonQtObjectPtr_metaId;
630
652
@@ -847,3 +847,22 PyObject* PythonQtClassInfo::findEnumWrapper(const char* name) {
847 return NULL;
847 return NULL;
848 }
848 }
849
849
850 void PythonQtClassInfo::setDecoratorProvider( PythonQtQObjectCreatorFunctionCB* cb )
851 {
852 _decoratorProviderCB = cb;
853 _decoratorProvider = NULL;
854 _enumsCreated = false;
855 }
856
857 void PythonQtClassInfo::clearNotFoundCachedMembers()
858 {
859 // remove all not found entries, since a new decorator means new slots,
860 // which might have been cached as "NotFound" already.
861 QMutableHashIterator<QByteArray, PythonQtMemberInfo> it(_cachedMembers);
862 while (it.hasNext()) {
863 it.next();
864 if (it.value()._type == PythonQtMemberInfo::NotFound) {
865 it.remove();
866 }
867 }
868 }
@@ -166,7 +166,7 public:
166 int metaTypeId() { return _metaTypeId; }
166 int metaTypeId() { return _metaTypeId; }
167
167
168 //! set an additional decorator provider that offers additional decorator slots for this class
168 //! set an additional decorator provider that offers additional decorator slots for this class
169 void setDecoratorProvider(PythonQtQObjectCreatorFunctionCB* cb) { _decoratorProviderCB = cb; _decoratorProvider = NULL; }
169 void setDecoratorProvider(PythonQtQObjectCreatorFunctionCB* cb);
170
170
171 //! get the decorator qobject instance
171 //! get the decorator qobject instance
172 QObject* decorator();
172 QObject* decorator();
@@ -202,6 +202,9 public:
202 //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum
202 //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum
203 static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum = NULL);
203 static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum = NULL);
204
204
205 //! clear all members that where cached as "NotFound"
206 void clearNotFoundCachedMembers();
207
205 private:
208 private:
206 void createEnumWrappers();
209 void createEnumWrappers();
207 void createEnumWrappers(const QMetaObject* meta);
210 void createEnumWrappers(const QMetaObject* meta);
@@ -266,6 +266,31 static PyObject *PythonQtClassWrapper_help(PythonQtClassWrapper* type)
266 return PythonQt::self()->helpCalled(type->classInfo());
266 return PythonQt::self()->helpCalled(type->classInfo());
267 }
267 }
268
268
269 PyObject *PythonQtClassWrapper_delete(PythonQtClassWrapper *type, PyObject *args)
270 {
271 Q_UNUSED(type);
272
273 Py_ssize_t argc = PyTuple_Size(args);
274 if (argc>0) {
275 PyObject* self = PyTuple_GET_ITEM(args, 0);
276 if (PyObject_TypeCheck(self, &PythonQtInstanceWrapper_Type)) {
277 return PythonQtInstanceWrapper_delete((PythonQtInstanceWrapper*)self);
278 }
279 }
280 return NULL;
281 }
282
283 PyObject *PythonQtClassWrapper_inherits(PythonQtClassWrapper *type, PyObject *args)
284 {
285 Q_UNUSED(type);
286 PythonQtInstanceWrapper* wrapper = NULL;
287 char *name = NULL;
288 if (!PyArg_ParseTuple(args, "O!s:PythonQtClassWrapper.inherits",&PythonQtInstanceWrapper_Type, &wrapper, &name)) {
289 return NULL;
290 }
291 return PythonQtConv::GetPyBool(wrapper->classInfo()->inherits(name));
292 }
293
269 PyObject *PythonQtClassWrapper__init__(PythonQtClassWrapper *type, PyObject *args)
294 PyObject *PythonQtClassWrapper__init__(PythonQtClassWrapper *type, PyObject *args)
270 {
295 {
271 Py_ssize_t argc = PyTuple_Size(args);
296 Py_ssize_t argc = PyTuple_Size(args);
@@ -295,16 +320,23 PyObject *PythonQtClassWrapper__init__(PythonQtClassWrapper *type, PyObject *arg
295 return NULL;
320 return NULL;
296 }
321 }
297
322
323
298 static PyMethodDef PythonQtClassWrapper_methods[] = {
324 static PyMethodDef PythonQtClassWrapper_methods[] = {
299 {"__init__", (PyCFunction)PythonQtClassWrapper__init__, METH_VARARGS,
325 {"__init__", (PyCFunction)PythonQtClassWrapper__init__, METH_VARARGS,
300 "Return the classname of the object"
326 "Init function"
301 },
327 },
302 {"className", (PyCFunction)PythonQtClassWrapper_classname, METH_NOARGS,
328 {"className", (PyCFunction)PythonQtClassWrapper_classname, METH_NOARGS,
303 "Return the classname of the object"
329 "Return the classname of the object"
304 },
330 },
331 {"inherits", (PyCFunction)PythonQtClassWrapper_inherits, METH_VARARGS,
332 "Returns if the class inherits or is of given type name"
333 },
305 {"help", (PyCFunction)PythonQtClassWrapper_help, METH_NOARGS,
334 {"help", (PyCFunction)PythonQtClassWrapper_help, METH_NOARGS,
306 "Shows the help of available methods for this class"
335 "Shows the help of available methods for this class"
307 },
336 },
337 {"delete", (PyCFunction)PythonQtClassWrapper_delete, METH_VARARGS,
338 "Deletes the given C++ object"
339 },
308 {NULL, NULL, 0 , NULL} /* Sentinel */
340 {NULL, NULL, 0 , NULL} /* Sentinel */
309 };
341 };
310
342
@@ -344,7 +376,7 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)
344 PyDict_SetItemString(dict, "__init__", func);
376 PyDict_SetItemString(dict, "__init__", func);
345 Py_DECREF(func);
377 Py_DECREF(func);
346 }
378 }
347 for (int i = 1;i<3;i++) {
379 for (int i = 1; PythonQtClassWrapper_methods[i].ml_name != NULL; i++) {
348 PyObject* func = PyCFunction_New(&PythonQtClassWrapper_methods[i], obj);
380 PyObject* func = PyCFunction_New(&PythonQtClassWrapper_methods[i], obj);
349 PyDict_SetItemString(dict, PythonQtClassWrapper_methods[i].ml_name, func);
381 PyDict_SetItemString(dict, PythonQtClassWrapper_methods[i].ml_name, func);
350 Py_DECREF(func);
382 Py_DECREF(func);
@@ -47,7 +47,7
47
47
48 PythonQtValueStorage<qint64, 128> PythonQtConv::global_valueStorage;
48 PythonQtValueStorage<qint64, 128> PythonQtConv::global_valueStorage;
49 PythonQtValueStorage<void*, 128> PythonQtConv::global_ptrStorage;
49 PythonQtValueStorage<void*, 128> PythonQtConv::global_ptrStorage;
50 PythonQtValueStorage<QVariant, 32> PythonQtConv::global_variantStorage;
50 PythonQtValueStorageWithCleanup<QVariant, 128> PythonQtConv::global_variantStorage;
51
51
52 QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
52 QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
53 QHash<int, PythonQtConvertPythonToMetaTypeCB*> PythonQtConv::_pythonToMetaTypeConverters;
53 QHash<int, PythonQtConvertPythonToMetaTypeCB*> PythonQtConv::_pythonToMetaTypeConverters;
@@ -144,7 +144,7 public:
144
144
145 static PythonQtValueStorage<qint64, 128> global_valueStorage;
145 static PythonQtValueStorage<qint64, 128> global_valueStorage;
146 static PythonQtValueStorage<void*, 128> global_ptrStorage;
146 static PythonQtValueStorage<void*, 128> global_ptrStorage;
147 static PythonQtValueStorage<QVariant, 32> global_variantStorage;
147 static PythonQtValueStorageWithCleanup<QVariant, 128> global_variantStorage;
148
148
149 protected:
149 protected:
150 static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
150 static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
1 NO CONTENT: modified file
NO CONTENT: modified file
@@ -67,6 +67,9 public:
67 //! get the last modified data of a file
67 //! get the last modified data of a file
68 virtual QDateTime lastModifiedDate(const QString& filename) = 0;
68 virtual QDateTime lastModifiedDate(const QString& filename) = 0;
69
69
70 //! indicates that *.py files which are newer than their corresponding *.pyc files
71 //! are ignored
72 virtual bool ignoreUpdatedPythonSourceFiles() { return false; }
70 };
73 };
71
74
72 #endif
75 #endif
@@ -114,6 +114,7 PythonQtImport::ModuleInfo PythonQtImport::getModuleInfo(PythonQtImporter* self,
114 info.fullPath = test;
114 info.fullPath = test;
115 info.moduleName = subname;
115 info.moduleName = subname;
116 info.type = MI_SHAREDLIBRARY;
116 info.type = MI_SHAREDLIBRARY;
117 return info;
117 }
118 }
118 }
119 }
119 return info;
120 return info;
@@ -276,12 +277,21 PythonQtImporter_load_module(PyObject *obj, PyObject *args)
276 args.append(QVariant::fromValue(pathList));
277 args.append(QVariant::fromValue(pathList));
277 QVariant result = imp.call("find_module", args);
278 QVariant result = imp.call("find_module", args);
278 if (result.isValid()) {
279 if (result.isValid()) {
279 // This will return a tuple with (file, pathname, description)
280 // This will return a tuple with (file, pathname, description=(suffix,mode,type))
280 QVariantList list = result.toList();
281 QVariantList list = result.toList();
281 if (list.count()==3) {
282 if (list.count()==3) {
282 // We prepend the full module name (including package prefix)
283 // We prepend the full module name (including package prefix)
283 list.prepend(fullname);
284 list.prepend(fullname);
284 // And call "load_module" with (fullname, file, pathname, description)
285 #ifdef __linux
286 #ifdef _DEBUG
287 // imp_find_module() does not respect the debug suffix '_d' on Linux,
288 // so it does not return the correct file path and we correct it now
289 // find_module opened a file to the release library, but that file handle is
290 // ignored on Linux and Windows, maybe on MacOS also.
291 list[2] = info.fullPath;
292 #endif
293 #endif
294 // And call "load_module" with (fullname, file, pathname, description=(suffix,mode,type))
285 PythonQtObjectPtr module = imp.call("load_module", list);
295 PythonQtObjectPtr module = imp.call("load_module", list);
286 mod = module.object();
296 mod = module.object();
287 if (mod) {
297 if (mod) {
@@ -559,13 +569,17 PythonQtImport::unmarshalCode(const QString& path, const QByteArray& data, time_
559 return Py_None;
569 return Py_None;
560 }
570 }
561
571
562 if (mtime != 0 && !(getLong((unsigned char *)buf + 4) == mtime)) {
572 if (mtime != 0) {
573 time_t timeDiff = getLong((unsigned char *)buf + 4) - mtime;
574 if (timeDiff<0) { timeDiff = -timeDiff; }
575 if (timeDiff > 1) {
563 if (Py_VerboseFlag)
576 if (Py_VerboseFlag)
564 PySys_WriteStderr("# %s has bad mtime\n",
577 PySys_WriteStderr("# %s has bad mtime\n",
565 path.toLatin1().constData());
578 path.toLatin1().constData());
566 Py_INCREF(Py_None);
579 Py_INCREF(Py_None);
567 return Py_None;
580 return Py_None;
568 }
581 }
582 }
569
583
570 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
584 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
571 if (code == NULL)
585 if (code == NULL)
@@ -645,7 +659,10 PythonQtImport::getMTimeOfSource(const QString& path)
645 path2.truncate(path.length()-1);
659 path2.truncate(path.length()-1);
646
660
647 if (PythonQt::importInterface()->exists(path2)) {
661 if (PythonQt::importInterface()->exists(path2)) {
648 mtime = PythonQt::importInterface()->lastModifiedDate(path2).toTime_t();
662 QDateTime t = PythonQt::importInterface()->lastModifiedDate(path2);
663 if (t.isValid()) {
664 mtime = t.toTime_t();
665 }
649 }
666 }
650
667
651 return mtime;
668 return mtime;
@@ -675,7 +692,12 PythonQtImport::getModuleCode(PythonQtImporter *self, const char* fullname, QStr
675 int ispackage = zso->type & IS_PACKAGE;
692 int ispackage = zso->type & IS_PACKAGE;
676 int isbytecode = zso->type & IS_BYTECODE;
693 int isbytecode = zso->type & IS_BYTECODE;
677
694
678 if (isbytecode) {
695 // if ignoreUpdatedPythonSourceFiles() returns true, then mtime stays 0
696 // and unmarshalCode() in getCodeFromData() will always read an existing *.pyc file,
697 // even if a newer *.py file exists. This is a release optimization where
698 // typically only *.pyc files are delivered without *.py files and reading file
699 // modification time is slow.
700 if (isbytecode && !PythonQt::importInterface()->ignoreUpdatedPythonSourceFiles()) {
679 mtime = getMTimeOfSource(test);
701 mtime = getMTimeOfSource(test);
680 }
702 }
681 code = getCodeFromData(test, isbytecode, ispackage, mtime);
703 code = getCodeFromData(test, isbytecode, ispackage, mtime);
@@ -713,7 +735,14 PyObject* PythonQtImport::getCodeFromPyc(const QString& file)
713 QString pyc = replaceExtension(file, pycStr);
735 QString pyc = replaceExtension(file, pycStr);
714 if (PythonQt::importInterface()->exists(pyc)) {
736 if (PythonQt::importInterface()->exists(pyc)) {
715 time_t mtime = 0;
737 time_t mtime = 0;
738 // if ignoreUpdatedPythonSourceFiles() returns true, then mtime stays 0
739 // and unmarshalCode() in getCodeFromData() will always read an existing *.pyc file,
740 // even if a newer *.py file exists. This is a release optimization where
741 // typically only *.pyc files are delivered without *.py files and reading file
742 // modification time is slow.
743 if (!PythonQt::importInterface()->ignoreUpdatedPythonSourceFiles()) {
716 mtime = getMTimeOfSource(pyc);
744 mtime = getMTimeOfSource(pyc);
745 }
717 code = getCodeFromData(pyc, true, false, mtime);
746 code = getCodeFromData(pyc, true, false, mtime);
718 if (code != Py_None && code != NULL) {
747 if (code != Py_None && code != NULL) {
719 return code;
748 return code;
@@ -288,12 +288,21 static PyObject *PythonQtInstanceWrapper_classname(PythonQtInstanceWrapper* obj)
288 return PyString_FromString(obj->ob_type->tp_name);
288 return PyString_FromString(obj->ob_type->tp_name);
289 }
289 }
290
290
291 PyObject *PythonQtInstanceWrapper_inherits(PythonQtInstanceWrapper* obj, PyObject *args)
292 {
293 char *name = NULL;
294 if (!PyArg_ParseTuple(args, "s:PythonQtInstanceWrapper.inherits",&name)) {
295 return NULL;
296 }
297 return PythonQtConv::GetPyBool(obj->classInfo()->inherits(name));
298 }
299
291 static PyObject *PythonQtInstanceWrapper_help(PythonQtInstanceWrapper* obj)
300 static PyObject *PythonQtInstanceWrapper_help(PythonQtInstanceWrapper* obj)
292 {
301 {
293 return PythonQt::self()->helpCalled(obj->classInfo());
302 return PythonQt::self()->helpCalled(obj->classInfo());
294 }
303 }
295
304
296 static PyObject *PythonQtInstanceWrapper_delete(PythonQtInstanceWrapper * self)
305 PyObject *PythonQtInstanceWrapper_delete(PythonQtInstanceWrapper * self)
297 {
306 {
298 PythonQtInstanceWrapper_deleteObject(self, true);
307 PythonQtInstanceWrapper_deleteObject(self, true);
299 Py_INCREF(Py_None);
308 Py_INCREF(Py_None);
@@ -305,6 +314,9 static PyMethodDef PythonQtInstanceWrapper_methods[] = {
305 {"className", (PyCFunction)PythonQtInstanceWrapper_classname, METH_NOARGS,
314 {"className", (PyCFunction)PythonQtInstanceWrapper_classname, METH_NOARGS,
306 "Return the classname of the object"
315 "Return the classname of the object"
307 },
316 },
317 {"inherits", (PyCFunction)PythonQtInstanceWrapper_inherits, METH_VARARGS,
318 "Returns if the class inherits or is of given type name"
319 },
308 {"help", (PyCFunction)PythonQtInstanceWrapper_help, METH_NOARGS,
320 {"help", (PyCFunction)PythonQtInstanceWrapper_help, METH_NOARGS,
309 "Shows the help of available methods for this class"
321 "Shows the help of available methods for this class"
310 },
322 },
@@ -371,7 +383,23 static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name)
371 case PythonQtMemberInfo::Property:
383 case PythonQtMemberInfo::Property:
372 if (wrapper->_obj) {
384 if (wrapper->_obj) {
373 if (member._property.userType() != QVariant::Invalid) {
385 if (member._property.userType() != QVariant::Invalid) {
374 return PythonQtConv::QVariantToPyObject(member._property.read(wrapper->_obj));
386
387 PythonQt::ProfilingCB* profilingCB = PythonQt::priv()->profilingCB();
388 if (profilingCB) {
389 QString methodName = "getProperty(";
390 methodName += attributeName;
391 methodName += ")";
392 profilingCB(PythonQt::Enter, wrapper->_obj->metaObject()->className(), methodName.toLatin1());
393 }
394
395 PyObject* value = PythonQtConv::QVariantToPyObject(member._property.read(wrapper->_obj));
396
397 if (profilingCB) {
398 profilingCB(PythonQt::Leave, NULL, NULL);
399 }
400
401 return value;
402
375 } else {
403 } else {
376 Py_INCREF(Py_None);
404 Py_INCREF(Py_None);
377 return Py_None;
405 return Py_None;
@@ -475,7 +503,19 static int PythonQtInstanceWrapper_setattro(PyObject *obj,PyObject *name,PyObjec
475 }
503 }
476 bool success = false;
504 bool success = false;
477 if (v.isValid()) {
505 if (v.isValid()) {
506 PythonQt::ProfilingCB* profilingCB = PythonQt::priv()->profilingCB();
507 if (profilingCB) {
508 QString methodName = "setProperty(";
509 methodName += attributeName;
510 methodName += ")";
511 profilingCB(PythonQt::Enter, wrapper->_obj->metaObject()->className(), methodName.toLatin1());
512 }
513
478 success = prop.write(wrapper->_obj, v);
514 success = prop.write(wrapper->_obj, v);
515
516 if (profilingCB) {
517 profilingCB(PythonQt::Leave, NULL, NULL);
518 }
479 }
519 }
480 if (success) {
520 if (success) {
481 return 0;
521 return 0;
@@ -605,17 +645,17 static PyObject * PythonQtInstanceWrapper_repr(PyObject * obj)
605 if (str.startsWith(typeName)) {
645 if (str.startsWith(typeName)) {
606 return PyString_FromFormat("%s", str.toLatin1().constData());
646 return PyString_FromFormat("%s", str.toLatin1().constData());
607 } else {
647 } else {
608 return PyString_FromFormat("%s(%s, %p)", typeName, str.toLatin1().constData(), wrapper->_wrappedPtr);
648 return PyString_FromFormat("%s (%s, at: %p)", typeName, str.toLatin1().constData(), wrapper->_wrappedPtr ? wrapper->_wrappedPtr : qobj);
609 }
649 }
610 }
650 }
611 if (wrapper->_wrappedPtr) {
651 if (wrapper->_wrappedPtr) {
612 if (wrapper->_obj) {
652 if (wrapper->_obj) {
613 return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
653 return PyString_FromFormat("%s (C++ object at: %p wrapped by %s at: %p)", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj);
614 } else {
654 } else {
615 return PyString_FromFormat("%s (C++ Object %p)", typeName, wrapper->_wrappedPtr);
655 return PyString_FromFormat("%s (C++ object at: %p)", typeName, wrapper->_wrappedPtr);
616 }
656 }
617 } else {
657 } else {
618 return PyString_FromFormat("%s (%s %p)", typeName, wrapper->classInfo()->className(), qobj);
658 return PyString_FromFormat("%s (%s at: %p)", typeName, wrapper->classInfo()->className(), qobj);
619 }
659 }
620 }
660 }
621
661
@@ -95,4 +95,6 typedef struct PythonQtInstanceWrapperStruct {
95
95
96 int PythonQtInstanceWrapper_init(PythonQtInstanceWrapper * self, PyObject * args, PyObject * kwds);
96 int PythonQtInstanceWrapper_init(PythonQtInstanceWrapper * self, PyObject * args, PyObject * kwds);
97
97
98 PyObject *PythonQtInstanceWrapper_delete(PythonQtInstanceWrapper * self);
99
98 #endif
100 #endif
@@ -192,7 +192,6 int PythonQtMethodInfo::nameToType(const char* name)
192 _parameterTypeDict.insert("qreal", QMetaType::Double);
192 _parameterTypeDict.insert("qreal", QMetaType::Double);
193 _parameterTypeDict.insert("QChar", QMetaType::QChar);
193 _parameterTypeDict.insert("QChar", QMetaType::QChar);
194 _parameterTypeDict.insert("QByteArray", QMetaType::QByteArray);
194 _parameterTypeDict.insert("QByteArray", QMetaType::QByteArray);
195 _parameterTypeDict.insert("Q3CString", QMetaType::QByteArray);
196 _parameterTypeDict.insert("QString", QMetaType::QString);
195 _parameterTypeDict.insert("QString", QMetaType::QString);
197 _parameterTypeDict.insert("", QMetaType::Void);
196 _parameterTypeDict.insert("", QMetaType::Void);
198 _parameterTypeDict.insert("void", QMetaType::Void);
197 _parameterTypeDict.insert("void", QMetaType::Void);
@@ -203,7 +202,6 int PythonQtMethodInfo::nameToType(const char* name)
203 _parameterTypeDict.insert("qulonglong", QMetaType::ULongLong);
202 _parameterTypeDict.insert("qulonglong", QMetaType::ULongLong);
204 _parameterTypeDict.insert("qint64", QMetaType::LongLong);
203 _parameterTypeDict.insert("qint64", QMetaType::LongLong);
205 _parameterTypeDict.insert("quint64", QMetaType::ULongLong);
204 _parameterTypeDict.insert("quint64", QMetaType::ULongLong);
206 _parameterTypeDict.insert("QIconSet", QMetaType::QIcon);
207 _parameterTypeDict.insert("QVariantMap", QMetaType::QVariantMap);
205 _parameterTypeDict.insert("QVariantMap", QMetaType::QVariantMap);
208 _parameterTypeDict.insert("QVariantList", QMetaType::QVariantList);
206 _parameterTypeDict.insert("QVariantList", QMetaType::QVariantList);
209 _parameterTypeDict.insert("QMap<QString,QVariant>", QMetaType::QVariantMap);
207 _parameterTypeDict.insert("QMap<QString,QVariant>", QMetaType::QVariantMap);
@@ -216,15 +214,14 int PythonQtMethodInfo::nameToType(const char* name)
216 _parameterTypeDict.insert("QUrl", QMetaType::QUrl);
214 _parameterTypeDict.insert("QUrl", QMetaType::QUrl);
217 _parameterTypeDict.insert("QLocale", QMetaType::QLocale);
215 _parameterTypeDict.insert("QLocale", QMetaType::QLocale);
218 _parameterTypeDict.insert("QRect", QMetaType::QRect);
216 _parameterTypeDict.insert("QRect", QMetaType::QRect);
219 _parameterTypeDict.insert("QRectf", QMetaType::QRectF);
217 _parameterTypeDict.insert("QRectF", QMetaType::QRectF);
220 _parameterTypeDict.insert("QSize", QMetaType::QSize);
218 _parameterTypeDict.insert("QSize", QMetaType::QSize);
221 _parameterTypeDict.insert("QSizef", QMetaType::QSizeF);
219 _parameterTypeDict.insert("QSizeF", QMetaType::QSizeF);
222 _parameterTypeDict.insert("QLine", QMetaType::QLine);
220 _parameterTypeDict.insert("QLine", QMetaType::QLine);
223 _parameterTypeDict.insert("QLinef", QMetaType::QLineF);
221 _parameterTypeDict.insert("QLineF", QMetaType::QLineF);
224 _parameterTypeDict.insert("QPoint", QMetaType::QPoint);
222 _parameterTypeDict.insert("QPoint", QMetaType::QPoint);
225 _parameterTypeDict.insert("QPointf", QMetaType::QPointF);
223 _parameterTypeDict.insert("QPointF", QMetaType::QPointF);
226 _parameterTypeDict.insert("QRegExp", QMetaType::QRegExp);
224 _parameterTypeDict.insert("QRegExp", QMetaType::QRegExp);
227 // _parameterTypeDict.insert("QColorGroup", QMetaType::QColorGroup);
228 _parameterTypeDict.insert("QFont", QMetaType::QFont);
225 _parameterTypeDict.insert("QFont", QMetaType::QFont);
229 _parameterTypeDict.insert("QPixmap", QMetaType::QPixmap);
226 _parameterTypeDict.insert("QPixmap", QMetaType::QPixmap);
230 _parameterTypeDict.insert("QBrush", QMetaType::QBrush);
227 _parameterTypeDict.insert("QBrush", QMetaType::QBrush);
@@ -232,7 +229,7 int PythonQtMethodInfo::nameToType(const char* name)
232 _parameterTypeDict.insert("QCursor", QMetaType::QCursor);
229 _parameterTypeDict.insert("QCursor", QMetaType::QCursor);
233 _parameterTypeDict.insert("QPalette", QMetaType::QPalette);
230 _parameterTypeDict.insert("QPalette", QMetaType::QPalette);
234 _parameterTypeDict.insert("QIcon", QMetaType::QIcon);
231 _parameterTypeDict.insert("QIcon", QMetaType::QIcon);
235 _parameterTypeDict.insert("QImage", QMetaType::QPolygon);
232 _parameterTypeDict.insert("QImage", QMetaType::QImage);
236 _parameterTypeDict.insert("QRegion", QMetaType::QRegion);
233 _parameterTypeDict.insert("QRegion", QMetaType::QRegion);
237 _parameterTypeDict.insert("QBitmap", QMetaType::QBitmap);
234 _parameterTypeDict.insert("QBitmap", QMetaType::QBitmap);
238 _parameterTypeDict.insert("QSizePolicy", QMetaType::QSizePolicy);
235 _parameterTypeDict.insert("QSizePolicy", QMetaType::QSizePolicy);
@@ -89,13 +89,6 public:
89 _chunks.clear();
89 _chunks.clear();
90 }
90 }
91
91
92 //! reset the storage to 0 (without freeing memory, thus caching old entries for reuse)
93 void reset() {
94 _chunkIdx = 0;
95 _chunkOffset = 0;
96 _currentChunk = _chunks.at(0);
97 }
98
99 //! get the current position to be restored with setPos
92 //! get the current position to be restored with setPos
100 void getPos(PythonQtValueStoragePosition & pos) {
93 void getPos(PythonQtValueStoragePosition & pos) {
101 pos.chunkIdx = _chunkIdx;
94 pos.chunkIdx = _chunkIdx;
@@ -129,7 +122,7 public:
129 return newEntry;
122 return newEntry;
130 };
123 };
131
124
132 private:
125 protected:
133 QList<T*> _chunks;
126 QList<T*> _chunks;
134
127
135 int _chunkIdx;
128 int _chunkIdx;
@@ -138,5 +131,45 private:
138
131
139 };
132 };
140
133
134 //! a helper class that stores basic C++ value types in chunks and clears the unused values on setPos() usage.
135 template <typename T, int chunkEntries> class PythonQtValueStorageWithCleanup : public PythonQtValueStorage<T, chunkEntries>
136 {
137 public:
138 void setPos(const PythonQtValueStoragePosition& pos) {
139 if (_chunkIdx > pos.chunkIdx) {
140 T* firstChunk = _chunks.at(pos.chunkIdx);
141 // clear region in first chunk
142 for (int i = pos.chunkOffset; i < chunkEntries; i++) {
143 firstChunk[i] = T();
144 }
145 for (int chunk = pos.chunkIdx + 1; chunk < _chunkIdx; chunk++) {
146 // clear the full chunks between the first and last chunk
147 T* fullChunk = _chunks.at(chunk);
148 for (int i = 0; i < chunkEntries; i++) {
149 fullChunk[i] = T();
150 }
151 }
152 // clear region in last chunk
153 T* lastChunk = _chunks.at(_chunkIdx);
154 for (int i = 0; i < _chunkOffset; i++) {
155 lastChunk[i] = T();
156 }
157 } else if (_chunkIdx == pos.chunkIdx) {
158 // clear the region in the last chunk only
159 T* lastChunk = _chunks.at(_chunkIdx);
160 for (int i = pos.chunkOffset; i<_chunkOffset; i++) {
161 lastChunk[i] = T();
162 }
163 }
164
165 PythonQtValueStorage<T, chunkEntries>::setPos(pos);
166 }
167
168 private:
169 using PythonQtValueStorage<T, chunkEntries>::_chunks;
170 using PythonQtValueStorage<T, chunkEntries>::_chunkIdx;
171 using PythonQtValueStorage<T, chunkEntries>::_chunkOffset;
172 using PythonQtValueStorage<T, chunkEntries>::_currentChunk;
173 };
141
174
142 #endif
175 #endif
@@ -67,7 +67,7 public:
67 if (o) Py_INCREF(_object);
67 if (o) Py_INCREF(_object);
68 }
68 }
69
69
70 ~PythonQtObjectPtr() { if (_object) Py_DECREF(_object); }
70 ~PythonQtObjectPtr() { if (_object) { Py_DECREF(_object); } }
71
71
72 //! If the given variant holds a PythonQtObjectPtr, extract the value from it and hold onto the reference. This results in an increment of the reference count.
72 //! If the given variant holds a PythonQtObjectPtr, extract the value from it and hold onto the reference. This results in an increment of the reference count.
73 bool fromVariant(const QVariant& variant);
73 bool fromVariant(const QVariant& variant);
@@ -116,7 +116,7 public:
116 //! sets the object and passes the ownership (stealing the reference, in Python slang)
116 //! sets the object and passes the ownership (stealing the reference, in Python slang)
117 void setNewRef(PyObject* o) {
117 void setNewRef(PyObject* o) {
118 if (o != _object) {
118 if (o != _object) {
119 if (_object) Py_DECREF(_object);
119 if (_object) { Py_DECREF(_object); }
120 _object = o;
120 _object = o;
121 }
121 }
122 }
122 }
@@ -157,9 +157,9 protected:
157
157
158 void setObject(PyObject* o) {
158 void setObject(PyObject* o) {
159 if (o != _object) {
159 if (o != _object) {
160 if (_object) Py_DECREF(_object);
160 if (_object) { Py_DECREF(_object); }
161 _object = o;
161 _object = o;
162 if (_object) Py_INCREF(_object);
162 if (_object) { Py_INCREF(_object); }
163 }
163 }
164 }
164 }
165
165
@@ -56,6 +56,8 void PythonQtSignalTarget::call(void **arguments) const {
56
56
57 PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInfo* methodInfos, void **arguments, bool skipFirstArgumentOfMethodInfo)
57 PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInfo* methodInfos, void **arguments, bool skipFirstArgumentOfMethodInfo)
58 {
58 {
59 Q_UNUSED(skipFirstArgumentOfMethodInfo)
60
59 // Note: we check if the callable is a PyFunctionObject and has a fixed number of arguments
61 // Note: we check if the callable is a PyFunctionObject and has a fixed number of arguments
60 // if that is the case, we only pass these arguments to python and skip the additional arguments from the signal
62 // if that is the case, we only pass these arguments to python and skip the additional arguments from the signal
61
63
@@ -50,7 +50,7 class PythonQtMethodInfo;
50 class PythonQtClassInfo;
50 class PythonQtClassInfo;
51
51
52 //! stores information about a signal target
52 //! stores information about a signal target
53 /*! copy construction and assignment works fine with the C++ standard behaviour and are thus not implemented
53 /*! copy construction and assignment works fine with the C++ standard behavior and are thus not implemented
54 */
54 */
55 class PYTHONQT_EXPORT PythonQtSignalTarget {
55 class PYTHONQT_EXPORT PythonQtSignalTarget {
56 public:
56 public:
@@ -142,9 +142,26 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
142 }
142 }
143 }
143 }
144
144
145
146 PythonQt::ProfilingCB* profilingCB = PythonQt::priv()->profilingCB();
147 if (profilingCB) {
148 const char* className = NULL;
149 if (info->decorator()) {
150 className = info->decorator()->metaObject()->className();
151 } else {
152 className = objectToCall->metaObject()->className();
153 }
154
155 profilingCB(PythonQt::Enter, className, info->metaMethod()->signature());
156 }
157
145 // invoke the slot via metacall
158 // invoke the slot via metacall
146 (info->decorator()?info->decorator():objectToCall)->qt_metacall(QMetaObject::InvokeMetaMethod, info->slotIndex(), argList);
159 (info->decorator()?info->decorator():objectToCall)->qt_metacall(QMetaObject::InvokeMetaMethod, info->slotIndex(), argList);
147
160
161 if (profilingCB) {
162 profilingCB(PythonQt::Leave, NULL, NULL);
163 }
164
148 // handle the return value (which in most cases still needs to be converted to a Python object)
165 // handle the return value (which in most cases still needs to be converted to a Python object)
149 if (argList[0] || returnValueParam.typeId == QMetaType::Void) {
166 if (argList[0] || returnValueParam.typeId == QMetaType::Void) {
150 if (directReturnValuePointer) {
167 if (directReturnValuePointer) {
@@ -126,15 +126,6 bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal
126 return r;
126 return r;
127 }
127 }
128
128
129 #undef emit
130 void PythonQtStdDecorators::emit(QObject* sender, const QByteArray& signal, PyObject* arg1 ,PyObject* arg2 ,
131 PyObject* arg3 ,PyObject* arg4 ,PyObject* arg5 ,PyObject* arg6 ,PyObject* arg7 )
132 {
133 // TODO xxx
134 // use normal PythonQtSlot calling code, add "allowSignal" to member lookup?!
135 }
136 #define emit
137
138 QObject* PythonQtStdDecorators::parent(QObject* o) {
129 QObject* PythonQtStdDecorators::parent(QObject* o) {
139 return o->parent();
130 return o->parent();
140 }
131 }
@@ -62,11 +62,6 public slots:
62 bool disconnect(QObject* sender, const QByteArray& signal, PyObject* callable);
62 bool disconnect(QObject* sender, const QByteArray& signal, PyObject* callable);
63 bool disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot);
63 bool disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot);
64
64
65 #undef emit
66 void emit(QObject* sender, const QByteArray& signal, PyObject* arg1 = NULL,PyObject* arg2 = NULL,
67 PyObject* arg3 = NULL,PyObject* arg4 = NULL,PyObject* arg5 = NULL,PyObject* arg6 = NULL,PyObject* arg7 = NULL);
68 #define emit
69
70 QObject* parent(QObject* o);
65 QObject* parent(QObject* o);
71 void setParent(QObject* o, QObject* parent);
66 void setParent(QObject* o, QObject* parent);
72
67
@@ -80,13 +75,13 public slots:
80
75
81 double static_Qt_qAbs(double a) { return qAbs(a); }
76 double static_Qt_qAbs(double a) { return qAbs(a); }
82 double static_Qt_qBound(double a,double b,double c) { return qBound(a,b,c); }
77 double static_Qt_qBound(double a,double b,double c) { return qBound(a,b,c); }
83 void static_Qt_qDebug(const QByteArray& msg) { qDebug(msg.constData()); }
78 void static_Qt_qDebug(const QByteArray& msg) { qDebug("%s", msg.constData()); }
84 // TODO: multi arg qDebug...
79 // TODO: multi arg qDebug...
85 void static_Qt_qWarning(const QByteArray& msg) { qWarning(msg.constData()); }
80 void static_Qt_qWarning(const QByteArray& msg) { qWarning("%s", msg.constData()); }
86 // TODO: multi arg qWarning...
81 // TODO: multi arg qWarning...
87 void static_Qt_qCritical(const QByteArray& msg) { qCritical(msg.constData()); }
82 void static_Qt_qCritical(const QByteArray& msg) { qCritical("%s", msg.constData()); }
88 // TODO: multi arg qCritical...
83 // TODO: multi arg qCritical...
89 void static_Qt_qFatal(const QByteArray& msg) { qFatal(msg.constData()); }
84 void static_Qt_qFatal(const QByteArray& msg) { qFatal("%s", msg.constData()); }
90 // TODO: multi arg qFatal...
85 // TODO: multi arg qFatal...
91 bool static_Qt_qFuzzyCompare(double a, double b) { return qFuzzyCompare(a, b); }
86 bool static_Qt_qFuzzyCompare(double a, double b) { return qFuzzyCompare(a, b); }
92 double static_Qt_qMax(double a, double b) { return qMax(a, b); }
87 double static_Qt_qMax(double a, double b) { return qMax(a, b); }
General Comments 0
You need to be logged in to leave comments. Login now