From 1783db758c1c8ed89b380133964e06526ae90e4d Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 22 Jun 2011 11:49:36 -0300 Subject: [PATCH 001/267] Remove reference leak on global receiver. --- libpyside/globalreceiver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libpyside/globalreceiver.cpp b/libpyside/globalreceiver.cpp index 1fb30d0..4d7bcf1 100644 --- a/libpyside/globalreceiver.cpp +++ b/libpyside/globalreceiver.cpp @@ -234,7 +234,6 @@ int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args) Shiboken::AutoDecRef preparedArgs(PyTuple_New(paramTypes.count())); for (int i = 0, max = paramTypes.count(); i < max; ++i) { PyObject* arg = Shiboken::TypeResolver::get(paramTypes[i].constData())->toPython(args[i+1]); // Do not increment the reference - Py_INCREF(arg); PyTuple_SET_ITEM(preparedArgs.object(), i, arg); } From 0d0981309edf7cf067d7485e89a2ce3993389604 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 22 Jun 2011 16:00:44 -0300 Subject: [PATCH 002/267] Fixed test case, when the destroyed() signal is emitted all C++ objects are just QObject because their up destructors were already called. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Luciano Wolf Renato Araújo --- tests/QtCore/destroysignal_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/QtCore/destroysignal_test.py b/tests/QtCore/destroysignal_test.py index 1c5f986..f6a9fb5 100644 --- a/tests/QtCore/destroysignal_test.py +++ b/tests/QtCore/destroysignal_test.py @@ -4,7 +4,7 @@ import unittest class TestDestroySignal(unittest.TestCase): def onObjectDestroyed(self, timer): - self.assert_(isinstance(timer, QTimer)) + self.assert_(isinstance(timer, QObject)) self._destroyed = True def testSignal(self): From b385e0c3edd0d9e99665cebbd8ee37055594d838 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 28 Jun 2011 11:39:04 -0300 Subject: [PATCH 003/267] Fixed propagation of properties for user-defined types. Fixes bug #897. Reviewer: Marcelo Lira Luciano Wolf --- libpyside/pysideproperty.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/libpyside/pysideproperty.cpp b/libpyside/pysideproperty.cpp index 5f11d36..b1cb19c 100644 --- a/libpyside/pysideproperty.cpp +++ b/libpyside/pysideproperty.cpp @@ -136,6 +136,7 @@ static void qpropertyMetaCall(PySideProperty* pp, PyObject* self, QMetaObject::C } } + static PyObject* qpropertyTpNew(PyTypeObject* subtype, PyObject* args, PyObject* kwds) { PySideProperty* me = reinterpret_cast(subtype->tp_alloc(subtype, 0)); @@ -193,6 +194,27 @@ void qpropertyFree(void *self) } // extern "C" +namespace { + +static PyObject* getFromType(PyTypeObject* type, PyObject* name) +{ + PyObject* attr = 0; + attr = PyDict_GetItem(type->tp_dict, name); + if (!attr) { + PyObject* bases = type->tp_bases; + int size = PyTuple_GET_SIZE(bases); + for(int i=0; i < size; i++) { + PyObject* base = PyTuple_GET_ITEM(bases, i); + attr = getFromType(reinterpret_cast(base), name); + if (attr) + return attr; + } + } + return attr; +} + +} //namespace + namespace PySide { namespace Property { @@ -275,9 +297,7 @@ PySideProperty* getObject(PyObject* source, PyObject* name) attr = PyDict_GetItem(dict, name); } - if (!attr) - attr = PyDict_GetItem(source->ob_type->tp_dict, name); - + attr = getFromType(source->ob_type, name); if (attr && isPropertyType(attr)) { Py_INCREF(attr); return reinterpret_cast(attr); From 7eb5694e17cbbf8c167ad3b483b4c7d6c89a5650 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 28 Jun 2011 11:40:33 -0300 Subject: [PATCH 004/267] Created unit test for bug #897. Reviewer: Marcelo Lira Luciano Wolf --- tests/QtCore/qobject_property_test.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/QtCore/qobject_property_test.py b/tests/QtCore/qobject_property_test.py index bc38dbb..7214505 100644 --- a/tests/QtCore/qobject_property_test.py +++ b/tests/QtCore/qobject_property_test.py @@ -36,6 +36,12 @@ class MyObject(QObject): pp = Property(int, readPP, constant=True) +class MySubObject(MyObject): + pass + +class MyMultipleObject(MyObject, object): + pass + class MyObjectWithNotifyProperty(QObject): def __init__(self, parent=None): QObject.__init__(self, parent) @@ -137,6 +143,14 @@ class PropertyCase(unittest.TestCase): self.assertFalse(obj.property('rect') is rect) self.assertEqual(obj.property('rect'), rect) + def testSubClassProperty(self): + o = MyObject() + self.assertEqual(o.property('pp'), 42) + so = MySubObject() + self.assertEqual(so.property('pp'), 42) + mo = MyMultipleObject() + self.assertEqual(mo.property('pp'), 42) + class PropertyWithConstructorCase(unittest.TestCase): '''Test case for QObject properties set using named arguments in the constructor.''' From b6f38556bd8cfcc61c537701a61cde56b4f704cf Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 28 Jun 2011 19:28:09 -0300 Subject: [PATCH 005/267] Created unittest for bug #407. --- tests/QtCore/qobject_inherits_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/QtCore/qobject_inherits_test.py b/tests/QtCore/qobject_inherits_test.py index fce383a..a3db11a 100644 --- a/tests/QtCore/qobject_inherits_test.py +++ b/tests/QtCore/qobject_inherits_test.py @@ -52,5 +52,12 @@ class InheritsCase(unittest.TestCase): # the exception to "reach the surface". obj1.objectName() + def testMultipleInheritance(self): + def declareClass(): + class Foo(object, QObject): + pass + + self.assertRaises(TypeError, declareClass) + if __name__ == '__main__': unittest.main() From da39716cc95ca03f20c32928709b092a1989ce26 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Wed, 29 Jun 2011 18:13:24 -0300 Subject: [PATCH 006/267] Fixes bug #899 - http://bugs.pyside.org/show_bug.cgi?id=899 Added unit test. Reviewed by Luciano Wolf Reviewed by Renato Araujo --- PySide/QtCore/typesystem_core.xml | 1 + tests/QtWebKit/CMakeLists.txt | 1 + tests/QtWebKit/qvariantlist_property_test.py | 43 ++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 tests/QtWebKit/qvariantlist_property_test.py diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 1c0baf7..e42663a 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -379,6 +379,7 @@ Shiboken::TypeResolver::createValueTypeResolver<QString>("unicode"); Shiboken::TypeResolver::createValueTypeResolver<QString>("str"); + Shiboken::TypeResolver::createValueTypeResolver<QVariantList>("QVariantList"); PySide::init(module); Py_AtExit(QtCoreModuleExit); diff --git a/tests/QtWebKit/CMakeLists.txt b/tests/QtWebKit/CMakeLists.txt index bfe5c0e..5e13440 100644 --- a/tests/QtWebKit/CMakeLists.txt +++ b/tests/QtWebKit/CMakeLists.txt @@ -1,6 +1,7 @@ PYSIDE_TEST(bug_448.py) PYSIDE_TEST(bug_694.py) PYSIDE_TEST(bug_803.py) +PYSIDE_TEST(qvariantlist_property_test.py) PYSIDE_TEST(webpage_test.py) PYSIDE_TEST(webview_test.py) PYSIDE_TEST(webframe_test.py) diff --git a/tests/QtWebKit/qvariantlist_property_test.py b/tests/QtWebKit/qvariantlist_property_test.py new file mode 100644 index 0000000..33ffc1d --- /dev/null +++ b/tests/QtWebKit/qvariantlist_property_test.py @@ -0,0 +1,43 @@ +import unittest +from PySide.QtCore import Property, QObject +from PySide.QtWebKit import QWebView +from helper import TimedQApplication + +class TestLoadFinished(TimedQApplication): + + def setUp(self): + TimedQApplication.setUp(self, timeout=1000) + + def tearDown(self): + TimedQApplication.tearDown(self) + + def testQVariantListProperty(self): + class Obj(object): + list = ['foo', 'bar', 'baz'] + + obj = Obj() + + wrapper_dict = {} + for name in ['list']: + getter = lambda arg=None, name=name: getattr(obj, name) + wrapper_dict[name] = Property('QVariantList', getter) + wrapper = type('PyObj', (QObject,), wrapper_dict) + + view = QWebView() + frame = view.page().mainFrame() + frame.addToJavaScriptWindowObject('py_obj', wrapper()) + + html = ''' + + + + ''' + view.setHtml(html) + view.show() + self.app.exec_() + + +if __name__ == '__main__': + unittest.main() From d82b8dbd8d01e0c52491c8b801675acc9bc7a6c9 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 4 Jul 2011 10:33:15 -0300 Subject: [PATCH 007/267] Fixed QMainWindow ownership control. Reviewer: Marcelo Lira Hugo Parente Lima --- PySide/QtGui/typesystem_gui_common.xml | 6 +++++- PySide/typesystem_templates.xml | 5 +++-- tests/QtGui/qmainwindow_test.py | 15 +++++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index d3473d4..c8ad97e 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -2134,6 +2134,7 @@ + @@ -2144,16 +2145,18 @@ + - + + @@ -2164,6 +2167,7 @@ + diff --git a/PySide/typesystem_templates.xml b/PySide/typesystem_templates.xml index 3a46c62..9c2be1e 100644 --- a/PySide/typesystem_templates.xml +++ b/PySide/typesystem_templates.xml @@ -21,9 +21,10 @@ diff --git a/tests/QtGui/qmainwindow_test.py b/tests/QtGui/qmainwindow_test.py index 372018c..6ea84ab 100644 --- a/tests/QtGui/qmainwindow_test.py +++ b/tests/QtGui/qmainwindow_test.py @@ -1,5 +1,6 @@ import unittest import sys +import weakref from PySide import QtGui from PySide import QtCore @@ -34,14 +35,19 @@ class TestMainWindow(UsesQApplication): QtCore.QTimer.singleShot(1000, self.app.quit) self.app.exec_() + def objDel(self, obj): + self.app.quit() + def testRefCountToNull(self): w = QtGui.QMainWindow() c = QtGui.QWidget() self.assertEqual(sys.getrefcount(c), 2) w.setCentralWidget(c) self.assertEqual(sys.getrefcount(c), 3) + wr = weakref.ref(c, self.objDel) w.setCentralWidget(None) - self.assertEqual(sys.getrefcount(c), 2) + c = None + self.app.exec_() def testRefCountToAnother(self): w = QtGui.QMainWindow() @@ -52,9 +58,14 @@ class TestMainWindow(UsesQApplication): c2 = QtGui.QWidget() w.setCentralWidget(c2) - self.assertEqual(sys.getrefcount(c), 2) self.assertEqual(sys.getrefcount(c2), 3) + wr = weakref.ref(c, self.objDel) + w.setCentralWidget(None) + c = None + + self.app.exec_() + def testSignalDisconect(self): w = QtGui.QMainWindow() b = MyButton("button") From f43d92fab4c1ea8818b6886e65427e1e355a249b Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 4 Jul 2011 10:37:37 -0300 Subject: [PATCH 008/267] Fix QUiLoader::load function ownership rules. fixes bug #909. Reviewer: Marcelo Lira Hugo Parente Lima --- PySide/QtUiTools/typesystem_uitools.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PySide/QtUiTools/typesystem_uitools.xml b/PySide/QtUiTools/typesystem_uitools.xml index 130880c..9d36d3e 100644 --- a/PySide/QtUiTools/typesystem_uitools.xml +++ b/PySide/QtUiTools/typesystem_uitools.xml @@ -102,7 +102,8 @@ - + + // Avoid calling the original function: %CPPSELF.%FUNCTION_NAME() @@ -120,7 +121,8 @@ - + + // Avoid calling the original function: %CPPSELF.%FUNCTION_NAME() From 0b5d8a1dec2a8af437b20395edbe7d6b3aea413e Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 4 Jul 2011 10:43:09 -0300 Subject: [PATCH 009/267] Created unit test for bug #909. Reviewer: Marcelo Lira Hugo Parente Lima --- tests/QtUiTools/CMakeLists.txt | 1 + tests/QtUiTools/bug_909.py | 24 ++++++++++++++++++++++++ tests/QtUiTools/bug_909.ui | 31 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 tests/QtUiTools/bug_909.py create mode 100644 tests/QtUiTools/bug_909.ui diff --git a/tests/QtUiTools/CMakeLists.txt b/tests/QtUiTools/CMakeLists.txt index 4c055ec..02fb89d 100644 --- a/tests/QtUiTools/CMakeLists.txt +++ b/tests/QtUiTools/CMakeLists.txt @@ -4,5 +4,6 @@ PYSIDE_TEST(bug_392.py) PYSIDE_TEST(bug_426.py) PYSIDE_TEST(bug_552.py) PYSIDE_TEST(bug_797.py) +PYSIDE_TEST(bug_909.py) PYSIDE_TEST(uiloader_test.py) PYSIDE_TEST(ui_test.py) diff --git a/tests/QtUiTools/bug_909.py b/tests/QtUiTools/bug_909.py new file mode 100644 index 0000000..18df7b3 --- /dev/null +++ b/tests/QtUiTools/bug_909.py @@ -0,0 +1,24 @@ +import sys +import unittest + +from PySide.QtCore import QFile +from PySide.QtGui import QTabWidget +from PySide.QtUiTools import QUiLoader + +from helper import UsesQApplication +from helper import adjust_filename + +class TestDestruction(UsesQApplication): + def testBug909(self): + fileName = QFile(adjust_filename('bug_909.ui', __file__)) + loader = QUiLoader() + main_win = loader.load(fileName) + self.assertEqual(sys.getrefcount(main_win), 2) + fileName.close() + + tw = QTabWidget(main_win) + main_win.setCentralWidget(tw) + main_win.show() + +if __name__ == '__main__': + unittest.main() diff --git a/tests/QtUiTools/bug_909.ui b/tests/QtUiTools/bug_909.ui new file mode 100644 index 0000000..b07f62d --- /dev/null +++ b/tests/QtUiTools/bug_909.ui @@ -0,0 +1,31 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 0 + 800 + 25 + + + + + + + + From 7d364bde656cd6246c1c2a533813762089679857 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 5 Jul 2011 12:02:15 -0300 Subject: [PATCH 010/267] Translate Shiboken enums to strings during the signal connection. Fixes bug #903. Reviewer: Marcelo Lira Luciano Wolf --- libpyside/pysidesignal.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libpyside/pysidesignal.cpp b/libpyside/pysidesignal.cpp index 0b2ad31..9664676 100644 --- a/libpyside/pysidesignal.cpp +++ b/libpyside/pysidesignal.cpp @@ -519,6 +519,8 @@ char* getTypeName(PyObject* type) typeName = strdup("double"); else if (objType == &PyBool_Type) typeName = strdup("bool"); + else if (objType->ob_type == &SbkEnumType_Type) + typeName = strdup(Shiboken::Enum::getCppName(objType)); else typeName = strdup("PyObject"); } From f3d69f65d18b641aeeedfbbfe8a0e16d2a75d9fe Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Mon, 4 Jul 2011 18:29:46 -0300 Subject: [PATCH 011/267] Fix bug 913 - "Widgets inside QTabWidget are not exported as members of the containing widget" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Marcelo Lira Renato Araújo --- PySide/QtUiTools/glue/uitools_loadui.h | 89 ++++++++++--------------- PySide/QtUiTools/typesystem_uitools.xml | 6 +- tests/QtUiTools/CMakeLists.txt | 1 + tests/QtUiTools/bug_392.py | 2 +- tests/QtUiTools/bug_913.py | 23 +++++++ tests/QtUiTools/bug_913.ui | 57 ++++++++++++++++ 6 files changed, 121 insertions(+), 57 deletions(-) create mode 100644 tests/QtUiTools/bug_913.py create mode 100644 tests/QtUiTools/bug_913.ui diff --git a/PySide/QtUiTools/glue/uitools_loadui.h b/PySide/QtUiTools/glue/uitools_loadui.h index a6e339a..18bb360 100644 --- a/PySide/QtUiTools/glue/uitools_loadui.h +++ b/PySide/QtUiTools/glue/uitools_loadui.h @@ -5,73 +5,56 @@ */ #include +#include +#include +#include -static void -_populate_parent(PyObject* pyParent, QObject *parent) +static void createChildrenNameAttributes(PyObject* root, QObject* object) { - if (parent->children().isEmpty()) - return; + foreach (QObject* child, object->children()) { + const QByteArray name = child->objectName().toLocal8Bit(); - foreach(QObject *child, parent->children()) { - QString name(child->objectName()); if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) { - bool has_attr = PyObject_HasAttrString(pyParent, qPrintable(name)); - Shiboken::AutoDecRef pyChild(Shiboken::Converter::toPython(child)); - if (!has_attr) - PyObject_SetAttrString(pyParent, qPrintable(name), pyChild); - - Shiboken::Object::setParent(pyParent, pyChild); - _populate_parent(pyChild, qobject_cast(child)); + bool hasAttr = PyObject_HasAttrString(root, name.constData()); + if (!hasAttr) { + Shiboken::AutoDecRef pyChild(Shiboken::Converter::toPython(child)); + PyObject_SetAttrString(root, name.constData(), pyChild); + } + createChildrenNameAttributes(root, child); } + createChildrenNameAttributes(root, child); } } -static PyObject* -quiloader_load_ui_from_device(QUiLoader* self, QIODevice* dev, QWidget *parent) +static PyObject* QUiLoadedLoadUiFromDevice(QUiLoader* self, QIODevice* dev, QWidget* parent) { - QWidget *w = self->load(dev, parent); - if (w) { - QObject* _parent = parent; - if (!_parent) - _parent = w; + QWidget* wdg = self->load(dev, parent); - if (parent && parent->layout()) + if (wdg) { + PyObject* pyWdg = Shiboken::Converter::toPython(wdg); + + if (!parent) + parent = wdg; + + if (parent->layout()) parent->layout()->deleteLater(); - PyObject* pyParent = Shiboken::Converter::toPython(w); - _populate_parent(pyParent, _parent); - - return pyParent; - } - - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_RuntimeError, "Unable to open ui file"); - return 0; -} - -static PyObject* -quiloader_load_ui(QUiLoader* self, const QString &ui_file, QWidget *parent) -{ - QFile fd(ui_file); - - if (fd.exists(ui_file) && fd.open(QFile::ReadOnly)) { - QWidget* w = self->load(&fd, parent); - fd.close(); - if (w != 0) { - QObject *_parent = parent; - if (!_parent) - _parent = w; - - Shiboken::AutoDecRef pyParent(Shiboken::Converter::toPython(_parent)); - if (parent && parent->layout()) - parent->layout()->deleteLater(); - - _populate_parent(pyParent, _parent); - - return Shiboken::Converter::toPython(w); + createChildrenNameAttributes(pyWdg, wdg); + if (parent) { + Shiboken::AutoDecRef pyParent(Shiboken::Converter::toPython(parent)); + Shiboken::Object::setParent(pyParent, pyWdg); } + + return pyWdg; } + if (!PyErr_Occurred()) - PyErr_SetString(PyExc_RuntimeError, "Unable to open ui file"); + PyErr_SetString(PyExc_RuntimeError, "Unable to open/read ui device"); return 0; } + +static PyObject* QUiLoaderLoadUiFromFileName(QUiLoader* self, const QString& uiFile, QWidget* parent) +{ + QFile fd(uiFile); + return QUiLoadedLoadUiFromDevice(self, &fd, parent); +} diff --git a/PySide/QtUiTools/typesystem_uitools.xml b/PySide/QtUiTools/typesystem_uitools.xml index 9d36d3e..46c325c 100644 --- a/PySide/QtUiTools/typesystem_uitools.xml +++ b/PySide/QtUiTools/typesystem_uitools.xml @@ -1,7 +1,7 @@ diff --git a/tests/QtCore/qobject_event_filter_test.py b/tests/QtCore/qobject_event_filter_test.py index 8018fcd..8fded79 100644 --- a/tests/QtCore/qobject_event_filter_test.py +++ b/tests/QtCore/qobject_event_filter_test.py @@ -2,6 +2,8 @@ '''Test cases for QObject.eventFilter''' import unittest +import weakref +import sys from PySide.QtCore import QObject, QTimerEvent @@ -76,5 +78,39 @@ class TestQObjectEventFilterPython(UsesQCoreApplication): self.assertEqual(filtered.times_called, 5) self.assertEqual(self.obj_filter.events_handled, 5) + def testInstallEventFilterRefCountAfterDelete(self): + '''Bug 910 - installEventFilter() increments reference count on target object + http://bugs.pyside.org/show_bug.cgi?id=910''' + obj = QObject() + filt = QObject() + + self.assertEqual(sys.getrefcount(obj), 2) + self.assertEqual(sys.getrefcount(filt), 2) + obj.installEventFilter(filt) + self.assertEqual(sys.getrefcount(obj), 2) + self.assertEqual(sys.getrefcount(filt), 2) + + wref = weakref.ref(obj) + del obj + self.assertEqual(wref(), None) + + def testInstallEventFilterRefCountAfterRemove(self): + # Bug 910 + obj = QObject() + filt = QObject() + + self.assertEqual(sys.getrefcount(obj), 2) + self.assertEqual(sys.getrefcount(filt), 2) + obj.installEventFilter(filt) + self.assertEqual(sys.getrefcount(obj), 2) + self.assertEqual(sys.getrefcount(filt), 2) + obj.removeEventFilter(filt) + self.assertEqual(sys.getrefcount(obj), 2) + self.assertEqual(sys.getrefcount(filt), 2) + + wref = weakref.ref(obj) + del obj + self.assertEqual(wref(), None) + if __name__ == '__main__': unittest.main() diff --git a/tests/QtGui/event_filter_test.py b/tests/QtGui/event_filter_test.py index 88dbd96..ec82515 100644 --- a/tests/QtGui/event_filter_test.py +++ b/tests/QtGui/event_filter_test.py @@ -2,7 +2,7 @@ import unittest import sys from helper import UsesQApplication -from PySide.QtCore import QObject, QEvent, QTimer +from PySide.QtCore import QObject, QEvent from PySide.QtGui import QWidget class MyFilter(QObject): @@ -17,10 +17,10 @@ class EventFilter(UsesQApplication): o = QObject() filt = MyFilter() o.installEventFilter(filt) - self.assertEqual(sys.getrefcount(o), 3) + self.assertEqual(sys.getrefcount(o), 2) o.installEventFilter(filt) - self.assertEqual(sys.getrefcount(o), 3) + self.assertEqual(sys.getrefcount(o), 2) o.removeEventFilter(filt) self.assertEqual(sys.getrefcount(o), 2) From e3539a09a8c6fdcea1ad3029c8f85f81e303e6ff Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 20 Jul 2011 17:48:15 -0300 Subject: [PATCH 040/267] Fix bug 821 - "Mapping interface for QPixmapCache" Reviewer: Marcelo Lira Luciano Wolf --- PySide/QtGui/typesystem_gui_common.xml | 12 +++++++++++- tests/QtGui/qpixmapcache_test.py | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index 66fe96b..8e2eec9 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -2382,8 +2382,18 @@ + + + QPixmap p; + if (%CPPSELF.%FUNCTION_NAME(%1, &p)) { + %PYARG_0 = %CONVERTTOPYTHON[QPixmap](p); + } else { + %PYARG_0 = Py_None; + Py_INCREF(%PYARG_0); + } + + - diff --git a/tests/QtGui/qpixmapcache_test.py b/tests/QtGui/qpixmapcache_test.py index 33d631b..68b4d92 100644 --- a/tests/QtGui/qpixmapcache_test.py +++ b/tests/QtGui/qpixmapcache_test.py @@ -10,6 +10,8 @@ class QPixmapCacheTest(UsesQApplication): ok = QPixmapCache.find('img', pm1) self.assertFalse(ok) + self.assertEqual(QPixmapCache.find('img'), None) + pm2 = QPixmap() ok = QPixmapCache.insert('img', pm2) self.assertTrue(ok) @@ -18,11 +20,15 @@ class QPixmapCacheTest(UsesQApplication): ok = QPixmapCache.find('img', pm3) self.assertTrue(ok) + self.assertEqual(QPixmapCache.find('img').toImage().bits(), pm3.toImage().bits()) + def testWithKey(self): pm1 = QPixmap() ok = QPixmapCache.find(QPixmapCache.Key(), pm1) self.assertFalse(ok) + self.assertEqual(QPixmapCache.find(QPixmapCache.Key()), None) + pm2 = QPixmap() key = QPixmapCache.insert(pm2) @@ -30,6 +36,7 @@ class QPixmapCacheTest(UsesQApplication): ok = QPixmapCache.find(key, pm3) self.assertTrue(ok) + self.assertEqual(QPixmapCache.find(key).toImage().bits(), pm3.toImage().bits()) if __name__ == '__main__': unittest.main() From 5d05c840bf9635be129804be584243cb005cfe06 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Thu, 21 Jul 2011 14:35:01 -0300 Subject: [PATCH 041/267] Moved test for bug #921 from QtCore's directory to QtGui's. Because it imports QtGui module. Reviewed by Hugo Parente Reviewed by Lauro Moura --- tests/QtCore/CMakeLists.txt | 1 - tests/QtGui/CMakeLists.txt | 1 + tests/{QtCore => QtGui}/bug_921.py | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename tests/{QtCore => QtGui}/bug_921.py (100%) diff --git a/tests/QtCore/CMakeLists.txt b/tests/QtCore/CMakeLists.txt index b7b1c89..9ddb44c 100644 --- a/tests/QtCore/CMakeLists.txt +++ b/tests/QtCore/CMakeLists.txt @@ -17,7 +17,6 @@ PYSIDE_TEST(bug_826.py) PYSIDE_TEST(bug_829.py) PYSIDE_TEST(bug_835.py) PYSIDE_TEST(bug_920.py) -PYSIDE_TEST(bug_921.py) PYSIDE_TEST(bug_927.py) PYSIDE_TEST(bug_931.py) PYSIDE_TEST(blocking_signals_test.py) diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index f1b9ade..99e688b 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -67,6 +67,7 @@ PYSIDE_TEST(bug_871.py) PYSIDE_TEST(bug_879.py) PYSIDE_TEST(bug_882.py) PYSIDE_TEST(bug_919.py) +PYSIDE_TEST(bug_921.py) PYSIDE_TEST(customproxywidget_test.py) PYSIDE_TEST(deepcopy_test.py) PYSIDE_TEST(event_filter_test.py) diff --git a/tests/QtCore/bug_921.py b/tests/QtGui/bug_921.py similarity index 100% rename from tests/QtCore/bug_921.py rename to tests/QtGui/bug_921.py From 673a7d1bccdaa522b8b8d9aee48cb6d0c0c5a342 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 21 Jul 2011 16:00:44 -0300 Subject: [PATCH 042/267] Fix bug 890 - "Add signal connection example for valueChanged(int) on QSpinBox to the docs" Reviewer: Luciano Wolf Marcelo Lira --- PySide/QtGui/typesystem_gui_common.xml | 31 +++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index 8e2eec9..b93ea0d 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -4993,7 +4993,36 @@ - + + + +:: + + def callback_int(value_as_int): + print 'int value changed:', repr(value_as_int) + + app = QApplication(sys.argv) + spinbox = QSpinBox() + spinbox.valueChanged[unicode].connect(callback_unicode) + spinbox.show() + sys.exit(app.exec_()) + + + + +:: + + def callback_unicode(value_as_unicode): + print 'unicode value changed:', repr(value_as_unicode) + + app = QApplication(sys.argv) + spinbox = QSpinBox() + spinbox.valueChanged[unicode].connect(callback_unicode) + spinbox.show() + sys.exit(app.exec_()) + + + From 0b6bafdd447f56c9910a41f039f9ed1431af04ee Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 21 Jul 2011 16:25:22 -0300 Subject: [PATCH 043/267] Fix bug 934 - "A __getitem__ of QByteArray behaves strange" --- PySide/QtCore/typesystem_core.xml | 2 +- tests/QtCore/qbytearray_operator_test.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index b94832a..fe38492 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -1885,7 +1885,7 @@ char res[2]; res[0] = %CPPSELF.at(_i); res[1] = 0; - return PyString_FromString(res); + return PyString_FromStringAndSize(res, 1); } diff --git a/tests/QtCore/qbytearray_operator_test.py b/tests/QtCore/qbytearray_operator_test.py index 662bc6e..50bb5f7 100644 --- a/tests/QtCore/qbytearray_operator_test.py +++ b/tests/QtCore/qbytearray_operator_test.py @@ -56,6 +56,10 @@ class QByteArrayOperatorAt(unittest.TestCase): obj = QByteArray(string) self.assertRaises(IndexError, lambda :obj[len(string)]) + def testNullStrings(self): + ba = QByteArray('\x00') + self.assertEqual(ba.at(0), '\x00') + self.assertEqual(ba[0], '\x00') class QByteArrayOperatorLen(unittest.TestCase): '''Test case for __len__ operator of QByteArray''' From 5902ca2e66913a374cbfde629b97807e4e2b4bc4 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 21 Jul 2011 17:12:49 -0300 Subject: [PATCH 044/267] Fix bug 937 - "missing pid method in QProcess" --- PySide/QtCore/typesystem_core.xml | 15 ++++++++++++++- tests/QtCore/qprocess_test.py | 12 ++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index fe38492..3a764c9 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -240,7 +240,6 @@ - @@ -2378,6 +2377,20 @@ %PYARG_0 = Shiboken::makeTuple(retval, pid); + + + + + long result; + #ifdef WIN32 + _PROCESS_INFORMATION* procInfo = %CPPSELF.%FUNCTION_NAME(); + result = procInfo ? procInfo->dwProcessId : 0; + #else + result = %CPPSELF.%FUNCTION_NAME(); + #endif + %PYARG_0 = %CONVERTTOPYTHON[long](result); + + diff --git a/tests/QtCore/qprocess_test.py b/tests/QtCore/qprocess_test.py index b01c68b..19d47f6 100644 --- a/tests/QtCore/qprocess_test.py +++ b/tests/QtCore/qprocess_test.py @@ -12,5 +12,17 @@ class TestQProcess (unittest.TestCase): self.assert_(isinstance(value, bool)) self.assert_(isinstance(pid, long)) + def testPid(self): + p = QProcess() + p.start("dir") + p.waitForStarted() + pid = p.pid() + # We can't test the pid method result because it returns 0 when the + # process isn't running + if p.state() == QProcess.Running: + self.assertNotEqual(pid, 0) + else: + print "PROCESS ALREADY DEAD :-/" + if __name__ == '__main__': unittest.main() From f10f4f70d4ffe21ace185db5da4ce4ab0fba9b34 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 21 Jul 2011 19:10:46 -0300 Subject: [PATCH 045/267] Fix bug 938 - "QTemporaryFile JPEG problem" Reviewer: Marcelo Lira Luciano Wolf --- PySide/QtCore/typesystem_core.xml | 5 +++++ tests/QtCore/CMakeLists.txt | 1 + tests/QtCore/bug_938.py | 14 ++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 tests/QtCore/bug_938.py diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 3a764c9..ea1544d 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -1978,6 +1978,11 @@ + + + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%CPPSELF.%FUNCTION_NAME(%1, PyString_GET_SIZE(%PYARG_1))); + + diff --git a/tests/QtCore/CMakeLists.txt b/tests/QtCore/CMakeLists.txt index 9ddb44c..c5147e8 100644 --- a/tests/QtCore/CMakeLists.txt +++ b/tests/QtCore/CMakeLists.txt @@ -19,6 +19,7 @@ PYSIDE_TEST(bug_835.py) PYSIDE_TEST(bug_920.py) PYSIDE_TEST(bug_927.py) PYSIDE_TEST(bug_931.py) +PYSIDE_TEST(bug_938.py) PYSIDE_TEST(blocking_signals_test.py) PYSIDE_TEST(classinfo_test.py) PYSIDE_TEST(child_event_test.py) diff --git a/tests/QtCore/bug_938.py b/tests/QtCore/bug_938.py new file mode 100644 index 0000000..b2ab565 --- /dev/null +++ b/tests/QtCore/bug_938.py @@ -0,0 +1,14 @@ +import unittest +from PySide.QtCore import * + +class TestBug938 (unittest.TestCase): + + def testIt(self): + b = QBuffer() + b.open(QBuffer.WriteOnly) + b.write("\x0023\x005") + b.close() + self.assertEqual(b.buffer().size(), 5) + +if __name__ == '__main__': + unittest.main() From 81f264913e25fde7f539a4f40b664040c5baca76 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Thu, 21 Jul 2011 17:44:57 -0300 Subject: [PATCH 046/267] Fixed unit test for bug_847 mandelbug. Reviewer: Luciano Wolf Lauro Neto --- tests/QtDeclarative/bug_847.py | 7 +++---- tests/QtDeclarative/bug_847.qml | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/QtDeclarative/bug_847.py b/tests/QtDeclarative/bug_847.py index faba8c9..91619c8 100644 --- a/tests/QtDeclarative/bug_847.py +++ b/tests/QtDeclarative/bug_847.py @@ -4,14 +4,12 @@ # Released under the same terms as PySide itself # 2011-05-04 Thomas Perl - import unittest from PySide.QtCore import Slot, Signal, QUrl -from PySide.QtGui import QApplication from PySide.QtDeclarative import QDeclarativeView -from helper import adjust_filename, TimedQApplication +from helper import adjust_filename, UsesQApplication class View(QDeclarativeView): def __init__(self): @@ -26,9 +24,10 @@ class View(QDeclarativeView): called = Signal(int, int) -class TestQML(TimedQApplication): +class TestQML(UsesQApplication): def done(self, x, y): self._sucess = True + self.app.quit() def testPythonSlot(self): self._sucess = False diff --git a/tests/QtDeclarative/bug_847.qml b/tests/QtDeclarative/bug_847.qml index e47819f..1cb40fa 100644 --- a/tests/QtDeclarative/bug_847.qml +++ b/tests/QtDeclarative/bug_847.qml @@ -15,7 +15,7 @@ Rectangle { } Timer { - interval: 1; running: true; + interval: 100; running: true; onTriggered: { if (pythonObject != undefined) { pythonObject.blubb(42, 84) From 7eae54e157f3b10dc1ce00da1a3253b92a18c4be Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Thu, 21 Jul 2011 17:46:40 -0300 Subject: [PATCH 047/267] Update unit test for max signals. Reviewer: Luciano Wolf Lauro Neto --- tests/QtCore/max_signals.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/QtCore/max_signals.py b/tests/QtCore/max_signals.py index 190eaa5..154eac4 100644 --- a/tests/QtCore/max_signals.py +++ b/tests/QtCore/max_signals.py @@ -1,32 +1,34 @@ import unittest -from PySide.QtCore import QObject, Signal, SIGNAL +from PySide.QtCore import QObject, SIGNAL class MyObject(QObject): pass class TestSignalLimitless(unittest.TestCase): + SIGNAL_MAX = 100 def test100DynamicSignals(self): + self.count = 0 def onSignal(): self.count += 1 #create 100 dynamic signals o = MyObject() - for i in range(100): + for i in range(self.SIGNAL_MAX): o.connect(SIGNAL('sig%d()'%i), onSignal) #chek if the signals are valid m = o.metaObject() - for i in range(100): + for i in range(self.SIGNAL_MAX): self.assert_(m.indexOfSignal('sig%d()'%i) > 0) #emit all 100 signals - for i in range(100): + for i in range(self.SIGNAL_MAX): o.emit(SIGNAL('sig%d()'%i)) - self.assertEqual(self.count, 100) + self.assertEqual(self.count, self.SIGNAL_MAX) if __name__ == '__main__': unittest.main() From a0566f992848f36311f48295c2d8d006802c9b35 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Thu, 21 Jul 2011 17:49:08 -0300 Subject: [PATCH 048/267] Update QMetaObject test to test optimization changes. Reviewer: Luciano Wolf Lauro Neto --- tests/QtCore/qmetaobject_test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/QtCore/qmetaobject_test.py b/tests/QtCore/qmetaobject_test.py index 667e763..2c3b07b 100644 --- a/tests/QtCore/qmetaobject_test.py +++ b/tests/QtCore/qmetaobject_test.py @@ -35,9 +35,11 @@ class qmetaobject_test(unittest.TestCase): o = DynObject() o2 = QObject() - method_count_base = o.metaObject().methodCount() - o.connect(o2, SIGNAL("bar()"), o.slot) + self.assertTrue(o2.metaObject().indexOfMethod("bar()") > -1) + self.assertTrue(o.metaObject().indexOfMethod("bar()") == -1) + self.assertTrue(o.metaObject().indexOfMethod("slot()") > -1) + slot_index = o.metaObject().indexOfMethod("slot()") o.connect(o, SIGNAL("foo()"), o2, SIGNAL("bar()")) From 9dd8f98e736dc70ae4f1a78f13ee643a63aa2e47 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Thu, 21 Jul 2011 17:52:28 -0300 Subject: [PATCH 049/267] Update unit test for static metaobjet to work with new optimizations Reviewer: Luciano Wolf Lauro Neto --- tests/signals/static_metaobject_test.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/tests/signals/static_metaobject_test.py b/tests/signals/static_metaobject_test.py index bce711f..9d62bcd 100644 --- a/tests/signals/static_metaobject_test.py +++ b/tests/signals/static_metaobject_test.py @@ -2,12 +2,10 @@ """Tests covering signal emission and receiving to python slots""" -import sys import unittest -import functools -from PySide.QtCore import * -from helper import BasicPySlotCase, UsesQCoreApplication +from PySide.QtCore import QObject, SIGNAL +from helper import UsesQCoreApplication class MyObject(QObject): def __init__(self, parent=None): @@ -24,27 +22,21 @@ class StaticMetaObjectTest(UsesQCoreApplication): o = MyObject() o2 = MyObject() - m = o.metaObject() # SIGNAL foo not created yet - self.assertEqual(m.indexOfSignal("foo()"), -1) + self.assertEqual(o.metaObject().indexOfSignal("foo()"), -1) o.connect(SIGNAL("foo()"), o2.mySlot) # SIGNAL foo create after connect - self.assert_(m.indexOfSignal("foo()") > 0) + self.assert_(o.metaObject().indexOfSignal("foo()") > 0) - m = o2.metaObject() - # SIGNAL propagate to others objects of the same type - self.assert_(m.indexOfSignal("foo()") > 0) + # SIGNAL does not propagate to others objects of the same type + self.assertEqual(o2.metaObject().indexOfSignal("foo()"), -1) del o - # SIGNAL foo continues registered after deletion of original object - self.assert_(m.indexOfSignal("foo()") > 0) - del o2 o = MyObject() - m = o.metaObject() - # new objects still have the SIGNAL foo registered - self.assert_(m.indexOfSignal("foo()") > 0) + # The SIGNAL was destroyed with old objects + self.assertEqual(o.metaObject().indexOfSignal("foo()"), -1) def testSharedSignalEmission(self): From ec45601aa14400b3d3e13f3f326e57d534da6ad2 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Thu, 21 Jul 2011 17:57:17 -0300 Subject: [PATCH 050/267] Implemented DynamicMetaObject optiomizations. Reviewer: Luciano Wolf Lauro Neto --- PySide/QtCore/glue/qobject_connect.cpp | 20 +++---- libpyside/dynamicqmetaobject.cpp | 72 ++++++++++++++++++-------- libpyside/dynamicqmetaobject.h | 11 ++-- libpyside/globalreceiver.cpp | 13 ++--- libpyside/globalreceiver.h | 2 +- libpyside/pyside.cpp | 4 +- libpyside/signalmanager.cpp | 68 +++++++++++++++++++++--- libpyside/signalmanager.h | 5 ++ 8 files changed, 144 insertions(+), 51 deletions(-) diff --git a/PySide/QtCore/glue/qobject_connect.cpp b/PySide/QtCore/glue/qobject_connect.cpp index 91a272c..3296c2e 100644 --- a/PySide/QtCore/glue/qobject_connect.cpp +++ b/PySide/QtCore/glue/qobject_connect.cpp @@ -59,11 +59,10 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject return false; signal++; - if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal)) + int signalIndex = PySide::SignalManager::registerMetaMethodGetIndex(source, signal, QMetaMethod::Signal); + if (signalIndex == -1) return false; - int signalIndex = source->metaObject()->indexOfMethod(signal); - PySide::SignalManager& signalManager = PySide::SignalManager::instance(); // Extract receiver from callback @@ -82,13 +81,14 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject qWarning() << "You can't add dynamic slots on an object originated from C++."; return false; } - if (usingGlobalReceiver) { - signalManager.addGlobalSlot(slot, callback); - } else { - if (!PySide::SignalManager::registerMetaMethod(receiver, slot, QMetaMethod::Slot)) - return false; - } - slotIndex = metaObject->indexOfSlot(slot); + + if (usingGlobalReceiver) + slotIndex = signalManager.addGlobalSlotGetIndex(slot, callback); + else + slotIndex = PySide::SignalManager::registerMetaMethodGetIndex(receiver, slot, QMetaMethod::Slot); + + if (slotIndex == -1) + return false; } if (QMetaObject::connect(source, signalIndex, receiver, slotIndex, type)) { if (usingGlobalReceiver) diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index 205c728..dfc8ce2 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -87,6 +87,10 @@ public: QList m_properties; QMap m_info; QByteArray m_className; + bool m_invalid; + int m_methodOffset; + int m_propertyOffset; + int m_count; void updateMetaObject(QMetaObject* metaObj); void writeMethodsData(const QList& methods, unsigned int** data, QList* strings, int* prtIndex, int nullIndex, int flags); @@ -95,8 +99,7 @@ public: static int registerString(const QByteArray& s, QList* strings) { int idx = 0; - for (int i = 0; i < strings->count(); ++i) { - const QString &str = strings->at(i); + foreach(QByteArray str, *strings) { if (str == s) return idx; idx += str.length() + 1; @@ -197,11 +200,13 @@ uint PropertyData::flags() const // const QByteArray with EMPTY_META_METHOD, used to save some memory const QByteArray MethodData::m_emptySig(EMPTY_META_METHOD); -MethodData::MethodData() : m_signature(m_emptySig) +MethodData::MethodData() + : m_signature(m_emptySig) { } -MethodData::MethodData(QMetaMethod::MethodType mtype, const char* signature, const char* type) : m_signature(signature), m_type(type), m_mtype(mtype) +MethodData::MethodData(QMetaMethod::MethodType mtype, const char* signature, const char* type) + : m_signature(signature), m_type(type), m_mtype(mtype) { } @@ -289,9 +294,12 @@ DynamicQMetaObject::DynamicQMetaObject(PyTypeObject* type, const QMetaObject* ba d.extradata = 0; m_d->m_className = QByteArray(type->tp_name).split('.').last(); + m_d->m_invalid = true; + m_d->m_methodOffset = base->methodCount() - 1; + m_d->m_propertyOffset = base->propertyCount() - 1; + m_d->m_count = 0; + //qDebug() << "CREATED: " << m_d->m_className << "OFFSET:" << base->methodOffset() << "COUNT" << base->methodCount(); parsePythonType(type); - //TODO : fill type userData - m_d->updateMetaObject(this); } DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject) @@ -301,8 +309,11 @@ DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* d.stringdata = 0; d.data = 0; d.extradata = 0; + m_d->m_count = 0; + m_d->m_invalid = true; m_d->m_className = className; - m_d->updateMetaObject(this); + m_d->m_methodOffset = metaObject->methodCount() - 1; + m_d->m_propertyOffset = metaObject->propertyCount() - 1; } DynamicQMetaObject::~DynamicQMetaObject() @@ -312,7 +323,7 @@ DynamicQMetaObject::~DynamicQMetaObject() delete m_d; } -void DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type) +int DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type) { int index = -1; int counter = 0; @@ -321,19 +332,24 @@ void DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* si QList::iterator it = m_d->m_methods.begin(); for (; it != m_d->m_methods.end(); ++it) { if ((it->signature() == signature) && (it->methodType() == mtype)) - return; + return m_d->m_methodOffset + counter; else if (*it == blank) index = counter; counter++; } + //qDebug() << "FIRST:" << index; //has blank method - if (index != -1) + if (index != -1) { m_d->m_methods[index] = MethodData(mtype, signature, type); - else + } else { m_d->m_methods << MethodData(mtype, signature, type); + index = m_d->m_methods.size(); + } - m_d->updateMetaObject(this); + m_d->m_invalid = true; + return m_d->m_methodOffset + index; + //qDebug() << "RESULTS(" << signature << "): " << result << "/" << indexOfMethod(signature) << "/" << m_d->m_methods.size() << "/" << m_d->m_methodOffset << (void*)this; } void DynamicQMetaObject::removeMethod(QMetaMethod::MethodType mtype, uint index) @@ -343,20 +359,20 @@ void DynamicQMetaObject::removeMethod(QMetaMethod::MethodType mtype, uint index) for (; it != m_d->m_methods.end(); ++it) { if ((it->signature() == methodSig) && (it->methodType() == mtype)){ it->clear(); - m_d->updateMetaObject(this); + m_d->m_invalid = true; break; } } } -void DynamicQMetaObject::addSignal(const char* signal, const char* type) +int DynamicQMetaObject::addSignal(const char* signal, const char* type) { - addMethod(QMetaMethod::Signal, signal, type); + return addMethod(QMetaMethod::Signal, signal, type); } -void DynamicQMetaObject::addSlot(const char* slot, const char* type) +int DynamicQMetaObject::addSlot(const char* slot, const char* type) { - addMethod(QMetaMethod::Slot, slot, type); + return addMethod(QMetaMethod::Slot, slot, type); } void DynamicQMetaObject::removeSlot(uint index) @@ -369,11 +385,11 @@ void DynamicQMetaObject::removeSignal(uint index) removeMethod(QMetaMethod::Signal, index); } -void DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data) +int DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data) { int index = m_d->m_properties.indexOf(propertyName); if (index != -1) - return; + return m_d->m_propertyOffset + index; // retrieve notifyId int notifyId = -1; @@ -393,8 +409,10 @@ void DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data) m_d->m_properties[index] = PropertyData(propertyName, notifyId, property); } else { m_d->m_properties << PropertyData(propertyName, notifyId, property); + index = m_d->m_properties.size(); } - m_d->updateMetaObject(this); + m_d->m_invalid = true; + return m_d->m_propertyOffset + index; } void DynamicQMetaObject::addInfo(const char* key, const char* value) @@ -409,7 +427,16 @@ void DynamicQMetaObject::addInfo(QMap info) m_d->m_info[i.key()] = i.value(); ++i; } - m_d->updateMetaObject(this); + m_d->m_invalid = true; +} + +const QMetaObject* DynamicQMetaObject::update() const +{ + if (m_d->m_invalid) { + m_d->updateMetaObject(const_cast(this)); + m_d->m_invalid = false; + } + return this; } void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList& methods, @@ -530,7 +557,8 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject } //write signals/slots - writeMethodsData(m_methods, &data, &strings, &index, NULL_INDEX, AccessPublic); + if (n_methods) + writeMethodsData(m_methods, &data, &strings, &index, NULL_INDEX, AccessPublic); if (m_properties.size()) data[7] = index; diff --git a/libpyside/dynamicqmetaobject.h b/libpyside/dynamicqmetaobject.h index f95070c..3ebaf1d 100644 --- a/libpyside/dynamicqmetaobject.h +++ b/libpyside/dynamicqmetaobject.h @@ -39,11 +39,11 @@ public: ~DynamicQMetaObject(); - void addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type); + int addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type); void removeMethod(QMetaMethod::MethodType mtype, uint index); - void addSignal(const char* signal, const char* type = 0); - void addSlot(const char* slot, const char* type = 0); - void addProperty(const char* property, PyObject* data); + int addSignal(const char* signal, const char* type = 0); + int addSlot(const char* slot, const char* type = 0); + int addProperty(const char* property, PyObject* data); void addInfo(const char* key, const char* value); void addInfo(QMap info); @@ -51,6 +51,8 @@ public: void removeSlot(uint index); void removeProperty(uint index); + const QMetaObject* update() const; + private: class DynamicQMetaObjectPrivate; DynamicQMetaObjectPrivate* m_d; @@ -58,5 +60,6 @@ private: void parsePythonType(PyTypeObject* type); }; + } #endif diff --git a/libpyside/globalreceiver.cpp b/libpyside/globalreceiver.cpp index 8990212..435e22a 100644 --- a/libpyside/globalreceiver.cpp +++ b/libpyside/globalreceiver.cpp @@ -162,6 +162,8 @@ GlobalReceiver::GlobalReceiver() { //slot used to be notifyed of object destrouction m_metaObject.addSlot(RECEIVER_DESTROYED_SLOT_NAME); + m_metaObject.update(); + setObjectName("GLOBAL RECEIVER"); } GlobalReceiver::~GlobalReceiver() @@ -198,13 +200,12 @@ void GlobalReceiver::disconnectNotify(QObject* source, int slotId) const QMetaObject* GlobalReceiver::metaObject() const { - return &m_metaObject; + return m_metaObject.update(); } -void GlobalReceiver::addSlot(const char* slot, PyObject* callback) +int GlobalReceiver::addSlot(const char* slot, PyObject* callback) { - m_metaObject.addSlot(slot); - int slotId = m_metaObject.indexOfSlot(slot); + int slotId = m_metaObject.addSlot(slot); if (!m_slotReceivers.contains(slotId)) m_slotReceivers[slotId] = new DynamicSlotData(slotId, callback, this); @@ -219,8 +220,8 @@ void GlobalReceiver::addSlot(const char* slot, PyObject* callback) if (isShortCircuit) m_shortCircuitSlots << slotId; - Q_ASSERT(slotId >= QObject::staticMetaObject.methodCount()); + return slotId; } void GlobalReceiver::removeSlot(int slotId) @@ -248,7 +249,7 @@ int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args) { Q_ASSERT(call == QMetaObject::InvokeMetaMethod); Q_ASSERT(id >= QObject::staticMetaObject.methodCount()); - QMetaMethod slot = m_metaObject.method(id); + QMetaMethod slot = metaObject()->method(id); Q_ASSERT(slot.methodType() == QMetaMethod::Slot); if (strcmp(slot.signature(), RECEIVER_DESTROYED_SLOT_NAME) == 0) { diff --git a/libpyside/globalreceiver.h b/libpyside/globalreceiver.h index 616d8d3..76c1246 100644 --- a/libpyside/globalreceiver.h +++ b/libpyside/globalreceiver.h @@ -41,7 +41,7 @@ public: ~GlobalReceiver(); int qt_metacall(QMetaObject::Call call, int id, void** args); const QMetaObject* metaObject() const; - void addSlot(const char* slot, PyObject* callback); + int addSlot(const char* slot, PyObject* callback); void removeSlot(int slotId); void connectNotify(QObject* sender, int slotId); void disconnectNotify(QObject* sender, int slotId); diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp index 325e274..45ada8f 100644 --- a/libpyside/pyside.cpp +++ b/libpyside/pyside.cpp @@ -168,6 +168,7 @@ void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const s //create DynamicMetaObject based on python type TypeUserData* userData = new TypeUserData(reinterpret_cast(type), base); userData->cppObjSize = cppObjSize; + userData->mo.update(); Shiboken::ObjectType::setTypeUserData(type, userData, Shiboken::callCppDestructor); //initialize staticQMetaObject property @@ -196,6 +197,7 @@ void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds) if (PyType_IsSubtype(base, qObjType)) { baseMo = reinterpret_cast(Shiboken::ObjectType::getTypeUserData(reinterpret_cast(base))); qobjBase = reinterpret_cast(base); + reinterpret_cast(baseMo)->update(); break; } } @@ -216,9 +218,9 @@ PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* nam if (attr && Property::isPropertyType(attr)) { PyObject *value = Property::getValue(reinterpret_cast(attr), self); + Py_DECREF(attr); if (!value) return 0; - Py_DECREF(attr); Py_INCREF(value); attr = value; } diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index bbbc1d3..b24d0b9 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -25,6 +25,7 @@ #include "pysideproperty.h" #include "pysideproperty_p.h" #include "pyside.h" +#include "dynamicqmetaobject.h" #include #include @@ -46,6 +47,14 @@ #define PYTHON_TYPE "PyObject" +namespace { + static PyObject *metaObjectAttr = 0; + static void destroyMetaObject(void* obj) + { + delete reinterpret_cast(obj); + } +} + namespace PySide { static int callMethod(QObject* object, int id, void** args); @@ -189,6 +198,9 @@ SignalManager::SignalManager() : m_d(new SignalManagerPrivate) TypeResolver::createValueTypeResolver("object"); TypeResolver::createValueTypeResolver("PySide::PyObjectWrapper"); PySide::registerCleanupFunction(clearSignalManager); + + if (!metaObjectAttr) + metaObjectAttr = PyString_FromString("__METAOBJECT__"); } void SignalManager::clear() @@ -225,7 +237,12 @@ void SignalManager::globalReceiverDisconnectNotify(QObject* source, int slotInde void SignalManager::addGlobalSlot(const char* slot, PyObject* callback) { - m_d->m_globalReceiver.addSlot(slot, callback); + addGlobalSlotGetIndex(slot, callback); +} + +int SignalManager::addGlobalSlotGetIndex(const char* slot, PyObject* callback) +{ + return m_d->m_globalReceiver.addSlot(slot, callback); } static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args) @@ -412,8 +429,13 @@ static int PySide::callMethod(QObject* object, int id, void** args) } return -1; } - bool SignalManager::registerMetaMethod(QObject* source, const char* signature, QMetaMethod::MethodType type) +{ + int ret = registerMetaMethodGetIndex(source, signature, type); + return (ret != -1); +} + +int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type) { Q_ASSERT(source); const QMetaObject* metaObject = source->metaObject(); @@ -423,19 +445,51 @@ bool SignalManager::registerMetaMethod(QObject* source, const char* signature, Q SbkObject* self = Shiboken::BindingManager::instance().retrieveWrapper(source); if (!Shiboken::Object::hasCppWrapper(self)) { qWarning() << "Invalid Signal signature:" << signature; - return false; + return -1; } else { - PySide::DynamicQMetaObject* dynMetaObj = reinterpret_cast(const_cast(metaObject)); + DynamicQMetaObject *dmo = 0; + PyObject *pySelf = reinterpret_cast(self); + PyObject* dict = self->ob_dict; + + // Create a instance meta object + if (!dict || !PyDict_Contains(dict, metaObjectAttr)) { + dmo = new DynamicQMetaObject(pySelf->ob_type, metaObject); + PyObject *pyDmo = PyCObject_FromVoidPtr(dmo, destroyMetaObject); + PyObject_SetAttr(pySelf, metaObjectAttr, pyDmo); + Py_DECREF(pyDmo); + } else { + dmo = reinterpret_cast(const_cast(metaObject)); + } + if (type == QMetaMethod::Signal) - dynMetaObj->addSignal(signature); + return dmo->addSignal(signature); else - dynMetaObj->addSlot(signature); + return dmo->addSlot(signature); } } - return true; + return methodIndex; } bool SignalManager::hasConnectionWith(const QObject *object) { return m_d->m_globalReceiver.hasConnectionWith(object); } + +const QMetaObject* SignalManager::retriveMetaObject(PyObject *self) +{ + Shiboken::GilState gil; + DynamicQMetaObject *mo = 0; + Q_ASSERT(self); + + PyObject* dict = reinterpret_cast(self)->ob_dict; + if (dict && PyDict_Contains(dict, metaObjectAttr)) { + PyObject *pyMo = PyDict_GetItem(dict, metaObjectAttr); + mo = reinterpret_cast(PyCObject_AsVoidPtr(pyMo)); + } else { + mo = reinterpret_cast(Shiboken::Object::getTypeUserData(reinterpret_cast(self))); + } + + mo->update(); + return mo; +} + diff --git a/libpyside/signalmanager.h b/libpyside/signalmanager.h index 5ea1366..b1b7986 100644 --- a/libpyside/signalmanager.h +++ b/libpyside/signalmanager.h @@ -62,12 +62,17 @@ public: static int qt_metacall(QObject* object, QMetaObject::Call call, int id, void** args); void addGlobalSlot(const char* slot, PyObject* callback); + int addGlobalSlotGetIndex(const char* slot, PyObject* callback); void globalReceiverConnectNotify(QObject *sender, int slotIndex); void globalReceiverDisconnectNotify(QObject *sender, int slotIndex); // Used to register a new signal/slot on QMetaobject of source. static bool registerMetaMethod(QObject* source, const char* signature, QMetaMethod::MethodType type); + static int registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type); + + // used to discovery metaobject + static const QMetaObject* retriveMetaObject(PyObject* self); // Used to discovery if SignalManager was connected with object "destroyed()" signal. bool hasConnectionWith(const QObject *object); From 51dad59dc7a6c9b2f571a3529361df1cd25fdbf6 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 22 Jul 2011 10:22:05 -0300 Subject: [PATCH 051/267] Use realloc functions on MetaObject functions. Reviewer: Luciano Wolf Lauro Neto --- libpyside/dynamicqmetaobject.cpp | 37 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index dfc8ce2..cc83007 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -99,10 +99,13 @@ public: static int registerString(const QByteArray& s, QList* strings) { int idx = 0; - foreach(QByteArray str, *strings) { - if (str == s) + QList::const_iterator it = strings->begin(); + QList::const_iterator it_end = strings->end(); + while(it != it_end) { + if (strcmp(*it, s) == 0) return idx; - idx += str.length() + 1; + idx += (*it).size() + 1; + ++it; } strings->append(s); return idx; @@ -289,16 +292,15 @@ DynamicQMetaObject::DynamicQMetaObject(PyTypeObject* type, const QMetaObject* ba : m_d(new DynamicQMetaObjectPrivate) { d.superdata = base; - d.stringdata = 0; - d.data = 0; - d.extradata = 0; + d.stringdata = NULL; + d.data = NULL; + d.extradata = NULL; m_d->m_className = QByteArray(type->tp_name).split('.').last(); m_d->m_invalid = true; m_d->m_methodOffset = base->methodCount() - 1; m_d->m_propertyOffset = base->propertyCount() - 1; m_d->m_count = 0; - //qDebug() << "CREATED: " << m_d->m_className << "OFFSET:" << base->methodOffset() << "COUNT" << base->methodCount(); parsePythonType(type); } @@ -318,8 +320,8 @@ DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* DynamicQMetaObject::~DynamicQMetaObject() { - delete[] d.stringdata; - delete[] d.data; + free(const_cast(d.stringdata)); + free(const_cast(d.data)); delete m_d; } @@ -338,7 +340,6 @@ int DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* sig counter++; } - //qDebug() << "FIRST:" << index; //has blank method if (index != -1) { m_d->m_methods[index] = MethodData(mtype, signature, type); @@ -349,7 +350,6 @@ int DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* sig m_d->m_invalid = true; return m_d->m_methodOffset + index; - //qDebug() << "RESULTS(" << signature << "): " << result << "/" << indexOfMethod(signature) << "/" << m_d->m_methods.size() << "/" << m_d->m_methodOffset << (void*)this; } void DynamicQMetaObject::removeMethod(QMetaMethod::MethodType mtype, uint index) @@ -533,9 +533,10 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject const int HEADER_LENGHT = sizeof(header)/sizeof(int); header[5] = HEADER_LENGHT; // header size + 5 indexes per method + an ending zero - delete[] metaObj->d.data; - unsigned int* data; - data = new unsigned int[HEADER_LENGHT + n_methods*5 + n_properties*4 + n_info*2 + 1]; + + + const int dataSize = HEADER_LENGHT + n_methods*5 + n_properties*4 + n_info*2 + 1; + uint* data = reinterpret_cast(realloc(const_cast(metaObj->d.data), dataSize * sizeof(uint))); std::memcpy(data, header, sizeof(header)); QList strings; @@ -587,9 +588,9 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject str.append(char(0)); } - delete[] metaObj->d.stringdata; - char* stringData = new char[str.count()]; - std::copy(str.begin(), str.end(), stringData); + char *stringdata = reinterpret_cast(realloc(const_cast(metaObj->d.stringdata), str.count() * sizeof(char))); + std::copy(str.begin(), str.end(), stringdata); + metaObj->d.data = data; - metaObj->d.stringdata = stringData; + metaObj->d.stringdata = stringdata; } From 3ab2d7b8c333ede505b92ec9293ddd63e190a098 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 22 Jul 2011 15:06:54 -0300 Subject: [PATCH 052/267] Fix typo on function modification signature. --- PySide/QtGui/typesystem_gui_common.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index b93ea0d..69929e8 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -2963,7 +2963,7 @@ - + From 10269a2c321d14f417bd6eb20e18f4661de2b96d Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 22 Jul 2011 15:07:27 -0300 Subject: [PATCH 053/267] Updated shiboken version dependency. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3e1a8f..b753a98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 2.6) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Macros/ ${CMAKE_MODULE_PATH}) find_package(GeneratorRunner 0.6.11 REQUIRED) -find_package(Shiboken 1.0.4 REQUIRED) +find_package(Shiboken 1.0.5 REQUIRED) find_package(Qt4 4.5.0 REQUIRED) find_file(GL_H "gl.h" PATH_SUFFIXES "GL") include(FindQt4Extra) From 6cd17da797977fc014e2828ff1abbf14060bf318 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 22 Jul 2011 15:09:08 -0300 Subject: [PATCH 054/267] Bumped version to 1.0.5 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b753a98..dd0f407 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,7 @@ endif() set(BINDING_NAME PySide) set(BINDING_API_MAJOR_VERSION "1") set(BINDING_API_MINOR_VERSION "0") -set(BINDING_API_MICRO_VERSION "4") +set(BINDING_API_MICRO_VERSION "5") set(BINDING_API_RELEASE_LEVEL "final") # alpha, beta, rc, or final set(BINDING_API_SERIAL 1) # leave as 0 when release level is final set(BINDING_API_VERSION "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}" CACHE STRING "PySide version" FORCE) From dffc9a21ead22af64143b6f3d568505b36333f9d Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 22 Jul 2011 18:17:47 -0300 Subject: [PATCH 055/267] Implemented Property decorator support. Fixes bug #900. Reviewer: Luciano Wolf Lauro Neto --- libpyside/pysideproperty.cpp | 70 ++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/libpyside/pysideproperty.cpp b/libpyside/pysideproperty.cpp index b3f5178..10a93c9 100644 --- a/libpyside/pysideproperty.cpp +++ b/libpyside/pysideproperty.cpp @@ -40,6 +40,19 @@ static PyObject* qpropertyTpNew(PyTypeObject* subtype, PyObject* args, PyObject* static int qpropertyTpInit(PyObject*, PyObject*, PyObject*); static void qpropertyFree(void*); +//methods +static PyObject* qPropertyCall(PyObject*, PyObject*, PyObject*); +static PyObject* qPropertySetter(PyObject*, PyObject*); +static PyObject* qPropertyGetter(PyObject*, PyObject*); + +static PyMethodDef PySidePropertyMethods[] = { + {"setter", (PyCFunction)qPropertySetter, METH_O}, + {"write", (PyCFunction)qPropertySetter, METH_O}, + {"getter", (PyCFunction)qPropertyGetter, METH_O}, + {"read", (PyCFunction)qPropertyGetter, METH_O}, + {0} +}; + PyTypeObject PySidePropertyType = { PyObject_HEAD_INIT(0) 0, /*ob_size*/ @@ -56,7 +69,7 @@ PyTypeObject PySidePropertyType = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ - 0, /*tp_call*/ + qPropertyCall, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ @@ -69,7 +82,7 @@ PyTypeObject PySidePropertyType = { 0, /*tp_weaklistoffset */ 0, /*tp_iter */ 0, /*tp_iternext */ - 0, /*tp_methods */ + PySidePropertyMethods, /*tp_methods */ 0, /*tp_members */ 0, /*tp_getset */ 0, /*tp_base */ @@ -160,7 +173,7 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds) "designable", "scriptable", "stored", "user", "constant", "final", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "OO|OOOsObbbbbb:QtCore.QProperty", (char**) kwlist, + "O|OOOOsObbbbbb:QtCore.QProperty", (char**) kwlist, /*OO*/ &type, &(pData->fget), /*OOO*/ &(pData->fset), &(pData->freset), &(pData->fdel), /*s*/ &(pData->doc), @@ -213,6 +226,57 @@ void qpropertyFree(void *self) pySelf->ob_type->tp_base->tp_free(self); } +PyObject* qPropertyCall(PyObject* self, PyObject* args, PyObject* kw) +{ + PyObject *callback = PyTuple_GetItem(args, 0); + if (PyFunction_Check(callback)) { + PySideProperty *prop = reinterpret_cast(self); + PySidePropertyPrivate* pData = prop->d; + + Py_INCREF(callback); + pData->fget = callback; + + Py_INCREF(self); + return self; + } else { + PyErr_SetString(PyExc_TypeError, "Invalid property usage."); + return 0; + } +} + +PyObject* qPropertySetter(PyObject* self, PyObject* callback) +{ + if (PyFunction_Check(callback)) { + PySideProperty *prop = reinterpret_cast(self); + PySidePropertyPrivate* pData = prop->d; + + Py_INCREF(callback); + pData->fset = callback; + + Py_INCREF(callback); + return callback; + } else { + PyErr_SetString(PyExc_TypeError, "Invalid property setter agument."); + return 0; + } +} + +PyObject* qPropertyGetter(PyObject* self, PyObject* callback) +{ + if (PyFunction_Check(callback)) { + PySideProperty *prop = reinterpret_cast(self); + PySidePropertyPrivate* pData = prop->d; + + Py_INCREF(callback); + pData->fget = callback; + + Py_INCREF(callback); + return callback; + } else { + PyErr_SetString(PyExc_TypeError, "Invalid property getter agument."); + return 0; + } +} } // extern "C" From 238222df8e3a2a5f00652ba47361cb6d9d1e0a16 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 22 Jul 2011 18:19:47 -0300 Subject: [PATCH 056/267] Created unit test for property decorator. Reviewer: Luciano Wolf Lauro Neto --- tests/QtCore/CMakeLists.txt | 1 + tests/QtCore/qproperty_decorator.py | 35 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/QtCore/qproperty_decorator.py diff --git a/tests/QtCore/CMakeLists.txt b/tests/QtCore/CMakeLists.txt index c5147e8..9900a85 100644 --- a/tests/QtCore/CMakeLists.txt +++ b/tests/QtCore/CMakeLists.txt @@ -73,6 +73,7 @@ PYSIDE_TEST(qobject_timer_event_test.py) PYSIDE_TEST(qobject_tr_as_instance_test.py) PYSIDE_TEST(qpoint_test.py) PYSIDE_TEST(qprocess_test.py) +PYSIDE_TEST(qproperty_decorator.py) PYSIDE_TEST(qrect_test.py) PYSIDE_TEST(qregexp_test.py) PYSIDE_TEST(qresource_test.py) diff --git a/tests/QtCore/qproperty_decorator.py b/tests/QtCore/qproperty_decorator.py new file mode 100644 index 0000000..404ce24 --- /dev/null +++ b/tests/QtCore/qproperty_decorator.py @@ -0,0 +1,35 @@ +import weakref +import unittest + +from PySide.QtCore import QObject, Property + +class MyObject(QObject): + def __init__(self): + QObject.__init__(self) + self._value = None + + @Property(int) + def value(self): + return self._value + + @value.setter + def valueSet(self, value): + self._value = value + + +class PropertyTest(unittest.TestCase): + def destroyCB(self, obj): + self._obDestroyed = True + + def testDecorator(self): + self._obDestroyed = False + o = MyObject() + weak = weakref.ref(o, self.destroyCB) + o.value = 10 + self.assertEqual(o._value, 10) + self.assertEqual(o.value, 10) + del o + self.assertTrue(self._obDestroyed) + +if __name__ == '__main__': + unittest.main() From 9a8531bfd6f2d05feb941aa368e61728471a351e Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Fri, 22 Jul 2011 16:10:29 -0300 Subject: [PATCH 057/267] Small optimizations on libpyside. --- libpyside/dynamicqmetaobject.cpp | 34 +++++++------------------------- libpyside/dynamicqmetaobject_p.h | 12 ++++++++--- libpyside/pysidesignal.cpp | 8 +++++--- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index cc83007..42447d7 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -100,11 +100,11 @@ static int registerString(const QByteArray& s, QList* strings) { int idx = 0; QList::const_iterator it = strings->begin(); - QList::const_iterator it_end = strings->end(); - while(it != it_end) { + QList::const_iterator itEnd = strings->end(); + while (it != itEnd) { if (strcmp(*it, s) == 0) return idx; - idx += (*it).size() + 1; + idx += it->size() + 1; ++it; } strings->append(s); @@ -209,8 +209,10 @@ MethodData::MethodData() } MethodData::MethodData(QMetaMethod::MethodType mtype, const char* signature, const char* type) - : m_signature(signature), m_type(type), m_mtype(mtype) + : m_signature(signature), m_mtype(mtype) { + if (qstrcmp(type, "void")) + m_type = type; } void MethodData::clear() @@ -219,23 +221,6 @@ void MethodData::clear() m_type.clear(); } -bool MethodData::operator==(const MethodData& other) const -{ - return ((m_signature == other.signature()) && (m_mtype == other.methodType())); -} - -QByteArray MethodData::signature() const -{ - return m_signature; -} - -QByteArray MethodData::type() const -{ - if (m_type == "void") - return QByteArray(); - return m_type; -} - bool MethodData::isValid() const { return m_signature.size(); @@ -267,11 +252,6 @@ bool PropertyData::isValid() const return !m_name.isEmpty(); } -QByteArray PropertyData::name() const -{ - return m_name; -} - int PropertyData::notifyId() const { return m_notifyId; @@ -304,7 +284,7 @@ DynamicQMetaObject::DynamicQMetaObject(PyTypeObject* type, const QMetaObject* ba parsePythonType(type); } -DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject) +DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject) : m_d(new DynamicQMetaObjectPrivate) { d.superdata = metaObject; diff --git a/libpyside/dynamicqmetaobject_p.h b/libpyside/dynamicqmetaobject_p.h index d8a2b6f..a4a17a1 100644 --- a/libpyside/dynamicqmetaobject_p.h +++ b/libpyside/dynamicqmetaobject_p.h @@ -43,8 +43,8 @@ namespace PySide MethodData(QMetaMethod::MethodType mtype, const char* signature, const char* type = 0); void clear(); bool isValid() const; - QByteArray signature() const; - QByteArray type() const; + const QByteArray& signature() const { return m_signature; } + const QByteArray& type() const { return m_type; } QMetaMethod::MethodType methodType() const; bool operator==(const MethodData& other) const; @@ -60,7 +60,7 @@ namespace PySide public: PropertyData(); PropertyData(const char* name, int notifyId=0, PySideProperty* data = 0); - QByteArray name() const; + const QByteArray& name() const { return m_name; } QByteArray type() const; uint flags() const; bool isValid() const; @@ -73,6 +73,12 @@ namespace PySide int m_notifyId; PySideProperty* m_data; }; + +inline bool MethodData::operator==(const MethodData& other) const +{ + return m_mtype == other.methodType() && m_signature == other.signature(); +} + } #endif diff --git a/libpyside/pysidesignal.cpp b/libpyside/pysidesignal.cpp index 1bdaa73..018e826 100644 --- a/libpyside/pysidesignal.cpp +++ b/libpyside/pysidesignal.cpp @@ -536,9 +536,11 @@ char* getTypeName(PyObject* type) char* buildSignature(const char *name, const char *signature) { - QString signal; - signal.sprintf("%s(%s)", name, signature); - return strdup(QMetaObject::normalizedSignature(signal.toAscii())); + QByteArray signal(name); + signal += '('; + signal += signature; + signal += ')'; + return strdup(QMetaObject::normalizedSignature(signal)); } char* parseSignature(PyObject *args) From 5922676bb1279d5ba7eeccc85ff55515ddc9c459 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Mon, 25 Jul 2011 18:56:52 -0300 Subject: [PATCH 058/267] Use linked lists instead of lists to speed up a bit. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Marcelo Lira Luciano Wolf Renato Araújo --- libpyside/dynamicqmetaobject.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index 42447d7..5476a37 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -93,14 +93,14 @@ public: int m_count; void updateMetaObject(QMetaObject* metaObj); - void writeMethodsData(const QList& methods, unsigned int** data, QList* strings, int* prtIndex, int nullIndex, int flags); + void writeMethodsData(const QList& methods, unsigned int** data, QLinkedList* strings, int* prtIndex, int nullIndex, int flags); }; -static int registerString(const QByteArray& s, QList* strings) +static int registerString(const QByteArray& s, QLinkedList* strings) { int idx = 0; - QList::const_iterator it = strings->begin(); - QList::const_iterator itEnd = strings->end(); + QLinkedList::const_iterator it = strings->begin(); + QLinkedList::const_iterator itEnd = strings->end(); while (it != itEnd) { if (strcmp(*it, s) == 0) return idx; @@ -421,7 +421,7 @@ const QMetaObject* DynamicQMetaObject::update() const void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList& methods, unsigned int** data, - QList* strings, + QLinkedList* strings, int* prtIndex, int nullIndex, int flags) @@ -451,7 +451,7 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject* type) Py_ssize_t pos = 0; typedef std::pair PropPair; - QList properties; + QLinkedList properties; Shiboken::AutoDecRef slotAttrName(PyString_FromString(PYSIDE_SLOT_LIST_ATTR)); @@ -519,7 +519,7 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject uint* data = reinterpret_cast(realloc(const_cast(metaObj->d.data), dataSize * sizeof(uint))); std::memcpy(data, header, sizeof(header)); - QList strings; + QLinkedList strings; registerString(m_className, &strings); // register class string const int NULL_INDEX = registerString("", &strings); // register a null string int index = HEADER_LENGHT; From 7de55917c9992d6594f503a1af8553fbccf054f2 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 25 Jul 2011 18:37:22 -0300 Subject: [PATCH 059/267] Implemented meta type for PySideSignal. This allow intercept isinstance function to make valid with any SignalInstance object. Fixes bug #931. Reviewer: Luciano Wolf Lauro Neto --- libpyside/pysidesignal.cpp | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/libpyside/pysidesignal.cpp b/libpyside/pysidesignal.cpp index 018e826..290ea84 100644 --- a/libpyside/pysidesignal.cpp +++ b/libpyside/pysidesignal.cpp @@ -61,15 +61,57 @@ static PyObject* signalInstanceGetItem(PyObject*, PyObject*); static PyObject* signalInstanceCall(PyObject* self, PyObject* args, PyObject* kw); static PyObject* signalCall(PyObject*, PyObject*, PyObject*); +static PyObject* metaSignalCheck(PyObject*, PyObject*); + static PyMappingMethods Signal_as_mapping = { 0, signalGetItem, 0 }; +static PyMethodDef Signal_methods[] = { + {"__instancecheck__", (PyCFunction)metaSignalCheck, METH_O, NULL}, + {0} +}; + +PyTypeObject PySideSignalMetaType = { + PyObject_HEAD_INIT(0) + /*ob_size*/ 0, + /*tp_name*/ "PySide.QtCore.MetaSignal", + /*tp_basicsize*/ sizeof(PyTypeObject), + /*tp_itemsize*/ 0, + /*tp_dealloc*/ 0, + /*tp_print*/ 0, + /*tp_getattr*/ 0, + /*tp_setattr*/ 0, + /*tp_compare*/ 0, + /*tp_repr*/ 0, + /*tp_as_number*/ 0, + /*tp_as_sequence*/ 0, + /*tp_as_mapping*/ 0, + /*tp_hash*/ 0, + /*tp_call*/ 0, + /*tp_str*/ 0, + /*tp_getattro*/ 0, + /*tp_setattro*/ 0, + /*tp_as_buffer*/ 0, + /*tp_flags*/ Py_TPFLAGS_DEFAULT, + /*tp_doc*/ 0, + /*tp_traverse*/ 0, + /*tp_clear*/ 0, + /*tp_richcompare*/ 0, + /*tp_weaklistoffset*/ 0, + /*tp_iter*/ 0, + /*tp_iternext*/ 0, + /*tp_methods*/ Signal_methods, + /*tp_members*/ 0, + /*tp_getset*/ 0, + /*tp_base*/ &PyType_Type, +}; PyTypeObject PySideSignalType = { - PyObject_HEAD_INIT(0) + PyObject_HEAD_INIT(&PySideSignalMetaType) + //PyObject_HEAD_INIT(0) /*ob_size*/ 0, /*tp_name*/ "PySide.QtCore."SIGNAL_CLASS_NAME, /*tp_basicsize*/ sizeof(PySideSignal), @@ -456,12 +498,24 @@ PyObject* signalInstanceCall(PyObject* self, PyObject* args, PyObject* kw) return PyCFunction_Call(homonymousMethod, args, kw); } + +static PyObject* metaSignalCheck(PyObject* klass, PyObject* args) +{ + if (PyType_IsSubtype(args->ob_type, &PySideSignalInstanceType)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + } // extern "C" namespace PySide { namespace Signal { void init(PyObject* module) { + if (PyType_Ready(&PySideSignalMetaType) < 0) + return; + if (PyType_Ready(&PySideSignalType) < 0) return; From 3482e2c114c7a9c639ad9ffc6710f1104c2c704c Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 25 Jul 2011 18:38:39 -0300 Subject: [PATCH 060/267] Update bug_931 unit test to check for isinstance. Reviewer: Luciano Wolf Lauro Neto --- tests/QtCore/bug_931.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/QtCore/bug_931.py b/tests/QtCore/bug_931.py index 0f0206a..32a33ac 100644 --- a/tests/QtCore/bug_931.py +++ b/tests/QtCore/bug_931.py @@ -2,6 +2,8 @@ import unittest from PySide.QtCore import QObject, Signal o = QObject() +class MyObject(QObject): + s = Signal(int) class CheckSignalType(unittest.TestCase): def testSignal(self): @@ -11,5 +13,9 @@ class CheckSignalType(unittest.TestCase): self.assertEqual(type(o.destroyed).__name__, "SignalInstance") self.assertNotEqual(type(o.destroyed), Signal) + self.assertTrue(isinstance(o.destroyed, Signal)) + self.assertTrue(isinstance(MyObject.s, Signal)) + self.assertFalse(isinstance(int, Signal)) + if __name__ == '__main__': unittest.main() From 75bf7f24b8962a58bddaac3a216abd5c78b898c2 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 26 Jul 2011 15:21:40 -0300 Subject: [PATCH 061/267] Implemented 'QGLShaderProgram' array functions support. Fixes bug #940. Reviewer: Luciano Wolf Hugo Parente --- PySide/QtOpenGL/typesystem_opengl.xml | 493 +++++++++++++++++++++++++- 1 file changed, 491 insertions(+), 2 deletions(-) diff --git a/PySide/QtOpenGL/typesystem_opengl.xml b/PySide/QtOpenGL/typesystem_opengl.xml index abed718..1bee27f 100644 --- a/PySide/QtOpenGL/typesystem_opengl.xml +++ b/PySide/QtOpenGL/typesystem_opengl.xml @@ -91,10 +91,499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + From d68d90a1445b7ba7f5d86ae133516bb48107b3c3 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 27 Jul 2011 17:54:27 -0300 Subject: [PATCH 062/267] Implement a more detailed __repr__ function for QScriptValue. Fixes bug #922. --- PySide/QtScript/typesystem_script.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/PySide/QtScript/typesystem_script.xml b/PySide/QtScript/typesystem_script.xml index 8c7ac10..738c44b 100644 --- a/PySide/QtScript/typesystem_script.xml +++ b/PySide/QtScript/typesystem_script.xml @@ -49,6 +49,16 @@ + + + if (%CPPSELF.isVariant() || %CPPSELF.isString()) { + QString format = QString().sprintf("%s(\"%s\")", ((PyObject*)%PYSELF)->ob_type->tp_name, qPrintable(%CPPSELF.toString())); + %PYARG_0 = PyString_FromString(qPrintable(format)); + } else { + %PYARG_0 = PyObject_Str((PyObject*)%PYSELF); + } + + Shiboken::AutoDecRef key(PyObject_Str(_key)); From fe4dd9d63f8113d978e4380a9333bbe3ade5d9ec Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 27 Jul 2011 18:02:06 -0300 Subject: [PATCH 063/267] Created unit test for QScriptValue __repr__ function. --- tests/QtScript/qscriptvalue_test.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/QtScript/qscriptvalue_test.py b/tests/QtScript/qscriptvalue_test.py index 3a03e96..d029bf9 100644 --- a/tests/QtScript/qscriptvalue_test.py +++ b/tests/QtScript/qscriptvalue_test.py @@ -1,12 +1,12 @@ import unittest -from PySide.QtCore import * -from PySide.QtScript import * +import PySide +from PySide.QtScript import QScriptEngine, QScriptValue -class TestQScriptValue (unittest.TestCase): +from helper import UsesQApplication + +class TestQScriptValue (UsesQApplication): def testOperator(self): - app = QCoreApplication([]) - engine = QScriptEngine() value = engine.evaluate('x = {"a": 1, "b":2}') self.assertEqual(value['a'], 1) @@ -15,6 +15,10 @@ class TestQScriptValue (unittest.TestCase): self.assertEqual(value[2], 'z') self.assertRaises(IndexError, value.__getitem__, 23) + def testRepr(self): + value = QScriptValue("somePerson = { firstName: 'John', lastName: 'Doe' }") + value2 = eval(repr(value)) + self.assertEqual(value.toString(), value2.toString()) if __name__ == '__main__': unittest.main() From aa091e00ef71fb309844de900dd9a8248d62af14 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Thu, 28 Jul 2011 11:15:26 -0300 Subject: [PATCH 064/267] Fixed windows compilation. --- PySide/QtOpenGL/typesystem_opengl.xml | 45 +++++++++++++++++---------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/PySide/QtOpenGL/typesystem_opengl.xml b/PySide/QtOpenGL/typesystem_opengl.xml index 1bee27f..58c6c12 100644 --- a/PySide/QtOpenGL/typesystem_opengl.xml +++ b/PySide/QtOpenGL/typesystem_opengl.xml @@ -94,28 +94,39 @@ From 7a5d2e693bdfde21c58b252e6c0c35def1a64e53 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 27 Jul 2011 19:24:54 -0300 Subject: [PATCH 065/267] Fix bug 941 - "Signals with QtCore.Qt types as arguments has invalid signatures" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Renato Araújo Luciano Wolf --- libpyside/pysidesignal.cpp | 53 ++++++++++++++++++++++ libpyside/pysidesignal.h | 11 +++-- tests/QtGui/CMakeLists.txt | 1 + tests/QtGui/bug_941.py | 17 +++++++ tests/pysidetest/typesystem_pysidetest.xml | 19 +++----- 5 files changed, 84 insertions(+), 17 deletions(-) create mode 100644 tests/QtGui/bug_941.py diff --git a/libpyside/pysidesignal.cpp b/libpyside/pysidesignal.cpp index 290ea84..782aeb5 100644 --- a/libpyside/pysidesignal.cpp +++ b/libpyside/pysidesignal.cpp @@ -731,6 +731,59 @@ PySideSignal* newObject(const char* name, ...) return self; } +template +static typename T::value_type join(T t, const char* sep) +{ + typename T::value_type res; + if (!t.size()) + return res; + + typename T::const_iterator it = t.begin(); + typename T::const_iterator end = t.end(); + res += *it; + ++it; + + while (it != end) { + res += sep; + res += *it; + ++it; + } + return res; +} + +void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject) +{ + typedef QHash > SignalSigMap; + SignalSigMap signalsFound; + for(int i = metaObject->methodOffset(), max = metaObject->methodCount(); i < max; ++i) { + QMetaMethod method = metaObject->method(i); + QByteArray methodName(method.signature()); + methodName.chop(methodName.size() - methodName.indexOf('(')); + + if (method.methodType() == QMetaMethod::Signal) + signalsFound[methodName] << join(method.parameterTypes(), ","); + } + + SignalSigMap::Iterator it = signalsFound.begin(); + SignalSigMap::Iterator end = signalsFound.end(); + for (; it != end; ++it) { + PySideSignal* self = PyObject_New(PySideSignal, &PySideSignalType); + self->signalName = strdup(it.key().constData()); + self->signaturesSize = 0; + self->signatures = 0; + self->initialized = 0; + self->homonymousMethod = 0; + + qSort(it.value().begin(), it.value().end()); + SignalSigMap::mapped_type::const_iterator j = it.value().begin(); + SignalSigMap::mapped_type::const_iterator endJ = it.value().end(); + for (; j != endJ; ++j) + appendSignature(self, strdup(j->constData())); + addSignalToWrapper(pyObj, it.key(), self); + Py_DECREF((PyObject*) self); + } +} + PyObject* buildQtCompatible(const char* signature) { diff --git a/libpyside/pysidesignal.h b/libpyside/pysidesignal.h index d0efe16..65c2ef3 100644 --- a/libpyside/pysidesignal.h +++ b/libpyside/pysidesignal.h @@ -57,9 +57,15 @@ PYSIDE_API bool checkType(PyObject* type); * @param name of the Signal to be registered on meta object * @param signatures a list of signatures supported by this signal, ended with a NULL pointer * @return Return a new reference to PyObject* of type PySideSignal + * @deprecated Use registerSignals **/ PYSIDE_API PySideSignal* newObject(const char* name, ...); +/** + * Register all C++ signals of a QObject on Python type. + */ +PYSIDE_API void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject); + /** * This function creates a Signal object which stay attached to QObject class based on a list of QMetaMethod * @@ -104,10 +110,7 @@ PYSIDE_API const char* getSignature(PySideSignalInstance* signal); PYSIDE_API void updateSourceObject(PyObject* source); /** - * This function is used to retrieve the signal signature - * - * @param self The Signal object - * @return Return the signal signature + * @deprecated Use registerSignals **/ PYSIDE_API void addSignalToWrapper(SbkObjectType* wrapperType, const char* signalName, PySideSignal* signal); diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 99e688b..9e5b0c3 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -68,6 +68,7 @@ PYSIDE_TEST(bug_879.py) PYSIDE_TEST(bug_882.py) PYSIDE_TEST(bug_919.py) PYSIDE_TEST(bug_921.py) +PYSIDE_TEST(bug_941.py) PYSIDE_TEST(customproxywidget_test.py) PYSIDE_TEST(deepcopy_test.py) PYSIDE_TEST(event_filter_test.py) diff --git a/tests/QtGui/bug_941.py b/tests/QtGui/bug_941.py new file mode 100644 index 0000000..cdf1190 --- /dev/null +++ b/tests/QtGui/bug_941.py @@ -0,0 +1,17 @@ +import unittest +from PySide.QtCore import * +from PySide.QtGui import * + +def foo(a, b): + pass + +class TestBug941 (unittest.TestCase): + + def testIt(self): + app = QApplication([]) + view = QHeaderView(Qt.Horizontal) + self.assertTrue(view.sortIndicatorChanged.connect(foo)) + view.sortIndicatorChanged.emit(0, Qt.Vertical) # this can't raise an exception! + +if __name__ == '__main__': + unittest.main() diff --git a/tests/pysidetest/typesystem_pysidetest.xml b/tests/pysidetest/typesystem_pysidetest.xml index c63d5e1..88cbf03 100644 --- a/tests/pysidetest/typesystem_pysidetest.xml +++ b/tests/pysidetest/typesystem_pysidetest.xml @@ -4,30 +4,23 @@ - + + Shiboken::TypeResolver::createObjectTypeResolver< ::PySideCPP2::TestObjectWithoutNamespace>("TestObjectWithoutNamespace*"); + Shiboken::TypeResolver::createValueTypeResolver< ::PySideCPP2::PySideLong>("PySideLong"); + Shiboken::TypeResolver::createObjectTypeResolver< ::PySideCPP::TestObjectWithNamespace>("TestObjectWithNamespace*"); + Shiboken::TypeResolver::createValueTypeResolver< ::PySideInt>("PySideInt"); qRegisterMetaType<PySideInt>("PySideInt"); qRegisterMetaType<PySideCPP2::PySideLong>("PySideLong"); - - - - - - - + - - - - - From 035265df107918c4e091bd55246d93df1d9092a1 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Thu, 28 Jul 2011 17:38:00 -0300 Subject: [PATCH 066/267] Fixes the support for QGLShaderProgram's array functions. Reviewed by Hugo Parente Reviewed by Luciano Wolf --- PySide/QtOpenGL/typesystem_opengl.xml | 220 ++++++++++++++++---------- 1 file changed, 134 insertions(+), 86 deletions(-) diff --git a/PySide/QtOpenGL/typesystem_opengl.xml b/PySide/QtOpenGL/typesystem_opengl.xml index 58c6c12..0a1579c 100644 --- a/PySide/QtOpenGL/typesystem_opengl.xml +++ b/PySide/QtOpenGL/typesystem_opengl.xml @@ -95,41 +95,21 @@ - - - @@ -138,7 +118,9 @@ - + + + @@ -149,7 +131,9 @@ - + + + @@ -160,7 +144,9 @@ - + + + @@ -171,7 +157,9 @@ - + + + @@ -182,7 +170,9 @@ - + + + @@ -193,7 +183,9 @@ - + + + @@ -208,8 +200,10 @@ - - + + + + @@ -222,8 +216,10 @@ - - + + + + @@ -236,8 +232,10 @@ - - + + + + @@ -250,8 +248,10 @@ - - + + + + @@ -264,8 +264,10 @@ - - + + + + @@ -278,8 +280,10 @@ - - + + + + @@ -292,8 +296,10 @@ - - + + + + @@ -306,8 +312,10 @@ - - + + + + @@ -320,8 +328,10 @@ - - + + + + @@ -334,8 +344,10 @@ - - + + + + @@ -348,8 +360,10 @@ - - + + + + @@ -362,8 +376,10 @@ - - + + + + @@ -376,8 +392,10 @@ - - + + + + @@ -390,8 +408,10 @@ - - + + + + @@ -404,8 +424,10 @@ - - + + + + @@ -418,8 +440,10 @@ - - + + + + @@ -432,8 +456,10 @@ - - + + + + @@ -446,8 +472,10 @@ - - + + + + @@ -460,8 +488,10 @@ - - + + + + @@ -474,8 +504,10 @@ - - + + + + @@ -488,8 +520,10 @@ - - + + + + @@ -502,8 +536,10 @@ - - + + + + @@ -516,8 +552,10 @@ - - + + + + @@ -530,8 +568,10 @@ - - + + + + @@ -544,8 +584,10 @@ - - + + + + @@ -558,8 +600,10 @@ - - + + + + @@ -572,8 +616,10 @@ - - + + + + @@ -586,8 +632,10 @@ - - + + + + From 09ef9957191abaf030f006585bb4858958504440 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Mon, 25 Jul 2011 14:59:13 -0300 Subject: [PATCH 067/267] Removed the remaining unnecessary QTextStream::operator>> methods. --- PySide/QtCore/typesystem_core.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index ea1544d..ae3188d 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -2808,11 +2808,16 @@ + + + + + From c4994bc1ab5b207aaac195f84dde974fd6ef2094 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Thu, 21 Jul 2011 18:14:43 -0300 Subject: [PATCH 068/267] Removed the "default-constructor" from some QtCore type entries. The generator was improved to do a better job figuring out a default constructor for types. Reviewed by Hugo Parente Reviewed by Luciano Wolf --- PySide/QtCore/typesystem_core.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index ae3188d..93e42ee 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -99,26 +99,26 @@ - - + + - + - + - + - + - + - - + + - + @@ -132,7 +132,7 @@ - + From d912655b5a00f44dc26be4ec6821c5e0aed1ab3c Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Fri, 29 Jul 2011 10:35:21 -0300 Subject: [PATCH 069/267] New CSS style for PySide docs. --- doc/_themes/pysidedocs/static/pysidedocs.css | 31 ++++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/doc/_themes/pysidedocs/static/pysidedocs.css b/doc/_themes/pysidedocs/static/pysidedocs.css index 49ea782..36f4edd 100644 --- a/doc/_themes/pysidedocs/static/pysidedocs.css +++ b/doc/_themes/pysidedocs/static/pysidedocs.css @@ -414,13 +414,32 @@ table.footnote { } tt.descname { + font-size: 120%; font-weight: bold; } -dl.method { - border-top: 1px solid #c2c2c2; - margin-right: -100px; - position: relative; - left: -50px; - padding: 10px 50px 0px 50px; +#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul { + list-style: none; + margin: 0px; + padding: 10px; + border: 1px solid #ddd; + background-color: #f4f4f4; + -moz-border-radius:10px; + -webkit-border-radius:10px; + -khtml-border-radius:10px; +} + +#synopsis span.pre { + color: #009491; + font-weight: bolder; +} + +#detailed-description .class dt, #detailed-description .method dt, #detailed-description .attribute dt { + margin: 0px; + padding: 10px; + border: 1px solid #ddd; + background-color: #f4f4f4; + -moz-border-radius:10px; + -webkit-border-radius:10px; + -khtml-border-radius:10px; } From 8d8c4cf308c6e066a4e625ff2a05c11e7b9fba0b Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 28 Jul 2011 16:37:12 -0300 Subject: [PATCH 070/267] Fix bug 923 - "Make QScriptValue (or QScriptValueIterator) implement the Python iterator protocol" Reviewer: Marcelo Lira Luciano Wolf --- PySide/QtScript/typesystem_script.xml | 23 ++++++++++++++++++++++- tests/QtScript/qscriptvalue_test.py | 16 +++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/PySide/QtScript/typesystem_script.xml b/PySide/QtScript/typesystem_script.xml index 738c44b..05afba2 100644 --- a/PySide/QtScript/typesystem_script.xml +++ b/PySide/QtScript/typesystem_script.xml @@ -72,7 +72,28 @@ } + + + %PYARG_0 = Shiboken::createWrapper(new QScriptValueIterator(*%CPPSELF), true, true); + + - + + + + + + + + + if (%CPPSELF.hasNext()) { + %CPPSELF.next(); + %PYARG_0 = Shiboken::makeTuple(%CPPSELF.name(), %CPPSELF.value().toVariant()); + } else { + PyErr_SetNone(PyExc_StopIteration); + } + + + diff --git a/tests/QtScript/qscriptvalue_test.py b/tests/QtScript/qscriptvalue_test.py index d029bf9..e5b6a63 100644 --- a/tests/QtScript/qscriptvalue_test.py +++ b/tests/QtScript/qscriptvalue_test.py @@ -1,6 +1,6 @@ import unittest import PySide -from PySide.QtScript import QScriptEngine, QScriptValue +from PySide.QtScript import * from helper import UsesQApplication @@ -19,6 +19,20 @@ class TestQScriptValue (UsesQApplication): value = QScriptValue("somePerson = { firstName: 'John', lastName: 'Doe' }") value2 = eval(repr(value)) self.assertEqual(value.toString(), value2.toString()) + self.assertEqual(value.toVariant(), value2.toVariant()) + + def testIteratorProtocol(self): + engine = QScriptEngine() + value = engine.evaluate('x = {"a": 1, "b":2}') + d = {} + for k, v in QScriptValueIterator(value): + d[k] = v + self.assertEqual(d, {'a': 1, 'b': 2}) + + d = {} + for k, v in value: + d[k] = v + self.assertEqual(d, {'a': 1, 'b': 2}) if __name__ == '__main__': unittest.main() From 151111bde2fcf7ab182495da16b3799fa2edf123 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Mon, 1 Aug 2011 13:12:49 -0300 Subject: [PATCH 071/267] Replaced hard coded variables by type system variables in QtCore and QtGui. --- PySide/QtCore/typesystem_core.xml | 10 +++++----- PySide/QtGui/typesystem_gui_common.xml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 93e42ee..6ca205a 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -1664,7 +1664,7 @@ - Shiboken::AutoDecRef str(PyUnicode_AsASCIIString(arg)); + Shiboken::AutoDecRef str(PyUnicode_AsASCIIString(%PYARG_1)); if (!str.isNull()) { QByteArray b(PyString_AS_STRING(str.object()), PyString_GET_SIZE(str.object())); b.prepend(*%CPPSELF); @@ -1674,7 +1674,7 @@ - Shiboken::AutoDecRef str(PyUnicode_AsASCIIString(arg)); + Shiboken::AutoDecRef str(PyUnicode_AsASCIIString(%PYARG_1)); if (!str.isNull()) { QByteArray b(PyString_AS_STRING(str.object()), PyString_GET_SIZE(str.object())); b.append(*%CPPSELF); @@ -1684,7 +1684,7 @@ - QByteArray b(PyString_AS_STRING(arg), PyString_GET_SIZE(arg)); + QByteArray b(PyString_AS_STRING(%PYARG_1), PyString_GET_SIZE(%PYARG_1)); %PYARG_0 = %CONVERTTOPYTHON[QByteArray](b + *%CPPSELF); @@ -1712,7 +1712,7 @@ - int size = PyString_GET_SIZE(pyargs[0]); + int size = PyString_GET_SIZE(%PYARG_1); %0 = new QByteArray(%1, size); @@ -2244,7 +2244,7 @@ const_cast<char*>("OsO"), pyTimer, SIGNAL(timeout()), - pyargs[1]) + %PYARG_2) ); } diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index 69929e8..2796708 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -562,7 +562,7 @@ Py_ssize_t bufferLen; - char* %out = (char*) Shiboken::Buffer::getPointer(arg, &bufferLen); + char* %out = (char*) Shiboken::Buffer::getPointer(%PYARG_1, &bufferLen); From 609f6bc8898f0df4f789e834e2f2e5c97be9866d Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Mon, 1 Aug 2011 13:42:42 -0300 Subject: [PATCH 072/267] Created template code for added QObject's trUtf8 methods. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed by Luciano Wolf Reviewed by Renato Araújo --- PySide/QtCore/typesystem_core.xml | 41 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 6ca205a..bf066b9 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -1430,6 +1430,18 @@ + @@ -1438,18 +1450,12 @@ - if (QCoreApplication::instance()) { - Shiboken::AutoDecRef klass(PyObject_GetAttrString(%PYSELF, "__class__")); - Shiboken::AutoDecRef cname(PyObject_GetAttrString(klass, "__name__")); - QString result = QCoreApplication::instance()->translate(PyString_AS_STRING(cname.object()), %1, %2, QCoreApplication::UnicodeUTF8, %3); - %PYARG_0 = %CONVERTTOPYTHON[QString](result); - } else { - Py_INCREF(%PYARG_1); - %PYARG_0 = %PYARG_1; - } + + + + - @@ -1458,20 +1464,13 @@ - if (QCoreApplication::instance()) { - Shiboken::AutoDecRef klass(PyObject_GetAttrString(%PYSELF, "__class__")); - Shiboken::AutoDecRef cname(PyObject_GetAttrString(klass, "__name__")); - Shiboken::AutoDecRef str(PyUnicode_AsUTF8String(%1)); - QString result = QCoreApplication::instance()->translate(PyString_AS_STRING(cname.object()), PyString_AS_STRING(str.object()), %2, QCoreApplication::UnicodeUTF8, %3); - %PYARG_0 = %CONVERTTOPYTHON[QString](result); - } else { - Py_INCREF(%PYARG_1); - %PYARG_0 = %PYARG_1; - } + + + + - // Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife From d7710810050f10b23364ad0507596140b975082f Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Fri, 29 Jul 2011 19:19:44 -0300 Subject: [PATCH 073/267] Cosmetic changes on docs. --- doc/_templates/index.html | 6 +++++ doc/_themes/pysidedocs/layout.html | 10 ++------ doc/_themes/pysidedocs/static/pysidedocs.css | 27 +++++++++++++++++++- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/doc/_templates/index.html b/doc/_templates/index.html index 4c50ab3..e1fb247 100644 --- a/doc/_templates/index.html +++ b/doc/_templates/index.html @@ -65,5 +65,11 @@

A collection of tutorials and "walkthrough" guides are provided with PySide to help new users get started with PySide development. These documents were ported from C++ to Python and cover a range of topics, from basic use of widgets to step-by-step tutorials that show how an application is put together.

+

Other stuff

+ + {% endblock %} diff --git a/doc/_themes/pysidedocs/layout.html b/doc/_themes/pysidedocs/layout.html index 9b6abe7..23f7d78 100644 --- a/doc/_themes/pysidedocs/layout.html +++ b/doc/_themes/pysidedocs/layout.html @@ -79,17 +79,11 @@
diff --git a/doc/_themes/pysidedocs/static/pysidedocs.css b/doc/_themes/pysidedocs/static/pysidedocs.css index 36f4edd..c3b1a8e 100644 --- a/doc/_themes/pysidedocs/static/pysidedocs.css +++ b/doc/_themes/pysidedocs/static/pysidedocs.css @@ -92,7 +92,7 @@ h1 { padding-bottom: 15px; padding-top: 15px; border-bottom: 1px solid #c2c2c2; - text-transform:uppercase; +/* text-transform:uppercase; */ margin-right: -100px; position: relative; left: -50px; @@ -443,3 +443,28 @@ tt.descname { -webkit-border-radius:10px; -khtml-border-radius:10px; } + +.pysidetoc ul { + list-style: none; + padding: 0px; + margin: 0px; +} + +.pysidetoc em { + font-style: normal; +} + +.pysidetoc strong { + display: block; + padding: 5px; + border: 1px solid #ddd; + background-color: #f4f4f4; + -moz-border-radius:6px; + -webkit-border-radius:6px; + -khtml-border-radius:6px; +} + +.hide { + display: none; +} + From 6c8ad3b83f0694e2b5b2ad7df34e793a69966682 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Tue, 2 Aug 2011 15:50:39 -0300 Subject: [PATCH 074/267] Translate QHistoryState code snippet to Python. --- PySide/QtCore/typesystem_core.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index bf066b9..6791ffb 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -3070,6 +3070,27 @@ + + <code>machine = QStateMachine() + +s1 = new QState() +s11 = new QState(s1) +s12 = new QState(s1) + +s1h = QHistoryState(s1) +s1h.setDefaultState(s11) + +machine.addState(s1) + +s2 = QState() +machine.addState(s2) + +button = QPushButton() +# Clicking the button will cause the state machine to enter the child state +# that s1 was in the last time s1 was exited, or the history state's default +# state if s1 has never been entered. +s1.addTransition(button.clicked, s1h)</code> + From 8a81e8da2114bdf5903def6ecdb5679c80e7534e Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Tue, 2 Aug 2011 15:51:21 -0300 Subject: [PATCH 075/267] Better looking module listing page. --- doc/modules.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/modules.rst b/doc/modules.rst index 5a54d83..38ec1f0 100644 --- a/doc/modules.rst +++ b/doc/modules.rst @@ -1,7 +1,10 @@ PySide modules ************** +Qt is splitted in several modules. + .. toctree:: + :maxdepth: 1 PySide/QtCore/index.rst PySide/QtDeclarative/index.rst From d129ca02f607068ded1ed6d073c20b56a3e9a276 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Tue, 2 Aug 2011 15:51:45 -0300 Subject: [PATCH 076/267] Don't color links black. Reviewer: Marcelo Lira Luciano Wolf --- doc/_themes/pysidedocs/static/pysidedocs.css | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/_themes/pysidedocs/static/pysidedocs.css b/doc/_themes/pysidedocs/static/pysidedocs.css index c3b1a8e..d577524 100644 --- a/doc/_themes/pysidedocs/static/pysidedocs.css +++ b/doc/_themes/pysidedocs/static/pysidedocs.css @@ -138,7 +138,6 @@ pre * { .pre { font: 100% monospace; - color: black; } .headerlink { From fae2dfd9b1bc948b72b4a34469a6e0e08e12a30f Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Wed, 3 Aug 2011 16:19:51 -0300 Subject: [PATCH 077/267] Moved AutoArrayPointer from libpyside to libshiboken. Reviewed by Hugo Parente Reviewed by Luciano Wolf --- PySide/QtGui/typesystem_gui_common.xml | 8 +--- .../glue/qudpsocket_read_datagram_glue.cpp | 2 +- PySide/QtNetwork/typesystem_network.xml | 12 ----- PySide/typesystem_templates.xml | 2 +- libpyside/autoarraypointer.h | 46 ------------------- 5 files changed, 4 insertions(+), 66 deletions(-) delete mode 100644 libpyside/autoarraypointer.h diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index 2796708..724d506 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -3257,10 +3257,6 @@ - - - - @@ -3272,7 +3268,7 @@ int numItems = PySequence_Size(%PYARG_1); - PySide::AutoArrayPointer<QGraphicsItem*> %out(numItems); + Shiboken::AutoArrayPointer<QGraphicsItem*> %out(numItems); for (int i=0; i < numItems; i++) { %out[i] = %CONVERTTOCPP[QGraphicsItem*](PySequence_Fast_GET_ITEM(%PYARG_1, i)); } @@ -3299,7 +3295,7 @@ int numOptions = PySequence_Size(%PYARG_2); - PySide::AutoArrayPointer<QStyleOptionGraphicsItem> %out(numOptions); + Shiboken::AutoArrayPointer<QStyleOptionGraphicsItem> %out(numOptions); for (int i=0; i < numOptions; i++) { %out[i] = %CONVERTTOCPP[QStyleOptionGraphicsItem](PySequence_Fast_GET_ITEM(%PYARG_1, i)); } diff --git a/PySide/QtNetwork/glue/qudpsocket_read_datagram_glue.cpp b/PySide/QtNetwork/glue/qudpsocket_read_datagram_glue.cpp index db38f45..bffc042 100644 --- a/PySide/QtNetwork/glue/qudpsocket_read_datagram_glue.cpp +++ b/PySide/QtNetwork/glue/qudpsocket_read_datagram_glue.cpp @@ -1,4 +1,4 @@ - PySide::AutoArrayPointer data(%ARGUMENT_NAMES); + Shiboken::AutoArrayPointer data(%ARGUMENT_NAMES); QHostAddress ha; quint16 port; diff --git a/PySide/QtNetwork/typesystem_network.xml b/PySide/QtNetwork/typesystem_network.xml index ab3f1ef..6acbdef 100644 --- a/PySide/QtNetwork/typesystem_network.xml +++ b/PySide/QtNetwork/typesystem_network.xml @@ -53,10 +53,6 @@ - - - - @@ -88,10 +84,6 @@ - - - - @@ -129,10 +121,6 @@ - - - - diff --git a/PySide/typesystem_templates.xml b/PySide/typesystem_templates.xml index 9c2be1e..4abe6ac 100644 --- a/PySide/typesystem_templates.xml +++ b/PySide/typesystem_templates.xml @@ -189,7 +189,7 @@ %PYARG_0 = Shiboken::makeTuple(a, b, c, d, e); @@ -1203,7 +1205,9 @@ } #endif default: - %PYARG_0 = 0; + { + %PYARG_0 = Py_BuildValue("(N(O))", PyObject_Type(%PYSELF), Py_None); + } } @@ -1240,8 +1244,10 @@ break; } default: + { %PYARG_0 = 0; } + } From 3da60153c00c693454fe80f1b3420b872becc4dd Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 22 Aug 2011 14:32:58 -0300 Subject: [PATCH 114/267] Created unit test for __reduce__ of empty QColor. Reviewer: Luciano Wolf Lauro Neto --- tests/QtGui/qcolor_test.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/QtGui/qcolor_test.py b/tests/QtGui/qcolor_test.py index 29b0d5d..26f3f4c 100644 --- a/tests/QtGui/qcolor_test.py +++ b/tests/QtGui/qcolor_test.py @@ -3,7 +3,7 @@ import unittest import colorsys import PySide -from PySide.QtCore import Qt, qFuzzyCompare +from PySide.QtCore import Qt from PySide.QtGui import QColor @@ -69,6 +69,17 @@ class QColorCopy(unittest.TestCase): del original self.assertEqual(copy, QColor(0, 0, 255)) + def testEmptyCopy(self): + from copy import deepcopy + + original = QColor() + copy = deepcopy([original])[0] + self.assert_(original is not copy) + self.assertEqual(original, copy) + del original + self.assertEqual(copy, QColor()) + + class QColorRepr(unittest.TestCase): def testReprFunction(self): c = QColor(100, 120, 200) From 84b0364b5da72196a8356d1c4e0cfcb3b55beb8a Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 22 Aug 2011 18:13:45 -0300 Subject: [PATCH 115/267] Dependency version update. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d87a1ac..02f435c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,8 @@ project(pysidebindings) cmake_minimum_required(VERSION 2.6) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Macros/ ${CMAKE_MODULE_PATH}) -find_package(GeneratorRunner 0.6.11 REQUIRED) -find_package(Shiboken 1.0.5 REQUIRED) +find_package(GeneratorRunner 0.6.12 REQUIRED) +find_package(Shiboken 1.0.6 REQUIRED) find_package(Qt4 4.5.0 REQUIRED) find_file(GL_H "gl.h" PATH_SUFFIXES "GL") include(FindQt4Extra) From 8492b69d3302dcf9bbe25fbd7f4ae2654fbbafae Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 23 Aug 2011 10:21:38 -0300 Subject: [PATCH 116/267] Fixed build for Qt 4.6. --- PySide/QtScript/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PySide/QtScript/CMakeLists.txt b/PySide/QtScript/CMakeLists.txt index 88b0a06..024d51f 100644 --- a/PySide/QtScript/CMakeLists.txt +++ b/PySide/QtScript/CMakeLists.txt @@ -1,10 +1,10 @@ project(QtScript) -if (${QT_VERSION_MAJOR} EQUAL 4 AND ${QT_VERSION_MINOR} LESS 6) - set (QtCore_46_SRC ) +if (${QT_VERSION_MAJOR} EQUAL 4 AND ${QT_VERSION_MINOR} LESS 7) + set (QtScript_47_SRC ) else() - set(QtScript_46_SRC - ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtScript/qscriptprogram_wrapper.cpp + set(QtScript_47_SRC + ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtScript/qscriptprogram_wrapper.cpp ) endif() @@ -22,7 +22,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtScript/qscriptextensionplugin_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtScript/qscriptstring_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtScript/qscriptvalue_wrapper.cpp ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtScript/qscriptvalueiterator_wrapper.cpp -${QtScript_46_SRC} +${QtScript_47_SRC} ) set(QtScript_typesystem_path "${QtCore_SOURCE_DIR}") From c31c7c60da668bc690dd0fde3659f64c7d5c5b9c Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 23 Aug 2011 14:27:15 -0300 Subject: [PATCH 117/267] Implement support to pyside debug mode on documentation generator. Reviewed by: Hugo Parente Lauro Moura --- doc/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 05584eb..61eeb09 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -8,9 +8,14 @@ add_custom_target(qdoc3 COMMENT "Running qdoc3 against Qt source code..." SOURCE "pyside.qdocconf") + +find_program(SPHINX_BUILD NAMES sphinx-build) +if (${SPHINX_BUILD} MATCHES "SPHINX_BUILD-NOTFOUND") + message(FATAL_ERROR "sphinx-build command not found.") +endif() add_custom_target(apidoc COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst - COMMAND sphinx-build -b html ${CMAKE_CURRENT_BINARY_DIR}/rst html + COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b html ${CMAKE_CURRENT_BINARY_DIR}/rst html ) # create conf.py based on conf.py.in From 544414cc0372d0f50c621f3785d43ba3a8c2cf04 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 24 Aug 2011 10:34:45 -0300 Subject: [PATCH 118/267] Created unit test for bug #959. Reviewed by: Hugo Parente Luciano Wolf --- tests/QtWebKit/CMakeLists.txt | 1 + tests/QtWebKit/bug_959.py | 87 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 tests/QtWebKit/bug_959.py diff --git a/tests/QtWebKit/CMakeLists.txt b/tests/QtWebKit/CMakeLists.txt index f9b4663..5f0820d 100644 --- a/tests/QtWebKit/CMakeLists.txt +++ b/tests/QtWebKit/CMakeLists.txt @@ -2,6 +2,7 @@ PYSIDE_TEST(bug_448.py) PYSIDE_TEST(bug_694.py) PYSIDE_TEST(bug_803.py) PYSIDE_TEST(bug_899.py) +PYSIDE_TEST(bug_959.py) PYSIDE_TEST(qvariantlist_property_test.py) PYSIDE_TEST(qml_plugin_test.py) PYSIDE_TEST(webpage_test.py) diff --git a/tests/QtWebKit/bug_959.py b/tests/QtWebKit/bug_959.py new file mode 100644 index 0000000..26cdad8 --- /dev/null +++ b/tests/QtWebKit/bug_959.py @@ -0,0 +1,87 @@ +from PySide.QtCore import QObject, Slot, QTimer +from PySide.QtWebKit import QWebView, QWebPage + +import unittest +from helper import UsesQApplication + +class JSFuncs(QObject): + functionID = -1 + @Slot(unicode,result=unicode) + def slot_str_str(self, x): + print "slot_str_str(%r)"%x + JSFuncs.functionID = 0 + return x.upper() + + @Slot(unicode,result='QVariant') + def slot_str_list(self, x): + print "slot_str_list(%r)"%x + JSFuncs.functionID = 1 + return [x, x] + + @Slot('QStringList',result=unicode) + def slot_strlist_str(self, x): + print "slot_strlist_str(%r)"%x + JSFuncs.functionID = 2 + return x[-1] + + @Slot('QVariant',result=unicode) + def slot_variant_str(self, x): + print "slot_variant_str(%r)"%x + JSFuncs.functionID = 3 + return unicode(x) + + @Slot('QVariantList',result=unicode) + def slot_variantlist_str(self, x): + print "slot_variantlist_str(%r)"%x + JSFuncs.functionID = 4 + return unicode(x[-1]) + + @Slot('QVariantMap',result=unicode) + def slot_variantmap_str(self, x): + print "slot_variantmap_str(%r)"%x + JSFuncs.functionID = 5 + return unicode(x["foo"]) + + + +PAGE_DATA = "data:text/html," +FUNCTIONS_LIST = ['jsfuncs.slot_str_str("hello")', + 'jsfuncs.slot_str_list("hello")', + 'jsfuncs.slot_strlist_str(["hello","world"])', + 'jsfuncs.slot_variant_str("hello")', + 'jsfuncs.slot_variantlist_str(["hello","world"])', + 'jsfuncs.slot_variantmap_str({"foo": "bar"})'] + + +class TestJsCall(UsesQApplication): + + @classmethod + def setUpClass(self): + super(TestJsCall, self).setUpClass() + + def createInstance(self): + self._view = QWebView() + self._jsfuncs = JSFuncs() + JSFuncs.functionID = -1 + self._view.page().mainFrame().addToJavaScriptWindowObject("jsfuncs", self._jsfuncs) + self._view.loadFinished[bool].connect(self.onLoadFinished) + self._view.load(PAGE_DATA % FUNCTIONS_LIST[self._functionID]) + self._view.show() + + def testJsCall(self): + self._functionID = 0 + self.createInstance() + self.app.exec_() + + def onLoadFinished(self, result): + self.assertEqual(self._functionID, JSFuncs.functionID) + if self._functionID == len(FUNCTIONS_LIST) - 1: + QTimer.singleShot(300, self.app.quit) + else: + #new test + self._functionID += 1 + self.createInstance() + + +if __name__ == "__main__": + unittest.main() From 34d424f89da117188a8994a78e042e3141808ea6 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 24 Aug 2011 14:57:24 -0300 Subject: [PATCH 119/267] Register QVariantMap on TypeManager. fixes bug #959. Reviewed by: Hugo Parente Luciano Wolf --- PySide/QtCore/typesystem_core.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 83f69df..6889b2e 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -155,6 +155,8 @@ + + From f5a1baac2f018bf75023c9ec98c06b885ac3c1ff Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 24 Aug 2011 17:21:32 -0300 Subject: [PATCH 120/267] Fixex return policy on QNetworkAccessManager.createRequest. Reviewed by: Hugo Parente Luciano Wolf --- PySide/QtNetwork/typesystem_network.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PySide/QtNetwork/typesystem_network.xml b/PySide/QtNetwork/typesystem_network.xml index d4aa34e..afa41ca 100644 --- a/PySide/QtNetwork/typesystem_network.xml +++ b/PySide/QtNetwork/typesystem_network.xml @@ -173,6 +173,9 @@ + + + From 138d8c42681a0fd2a73d8ac94aae375af21e6892 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 24 Aug 2011 17:22:56 -0300 Subject: [PATCH 121/267] Fixed QMenu, QMenuBar, QToolBar clear function. During the clear function all QActions need be destroyed. Reviewed by: Hugo Parente Luciano Wolf --- PySide/QtGui/typesystem_gui_common.xml | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index 626c249..c35a759 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -2370,6 +2370,10 @@ + + + + %PYARG_0 = addActionWithPyObject(%CPPSELF, QIcon(), %1, %2, %3); @@ -2379,11 +2383,25 @@ + + + + %PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2, %3, %4); + + + foreach(QAction *act, %CPPSELF.actions()) { + Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act)); + Shiboken::Object::setParent(NULL, pyAct); + Shiboken::Object::invalidate(pyAct); + } + + + @@ -2434,6 +2452,15 @@ + + + foreach(QAction *act, %CPPSELF.actions()) { + Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act)); + Shiboken::Object::setParent(NULL, pyAct); + Shiboken::Object::invalidate(pyAct); + } + + @@ -5123,6 +5150,10 @@ + + + + QAction* action = %CPPSELF.addAction(%1, %2); %PYARG_0 = %CONVERTTOPYTHON[QAction*](action); @@ -5136,6 +5167,9 @@ + + + QAction* action = %CPPSELF.addAction(%1); %PYARG_0 = %CONVERTTOPYTHON[QAction*](action); @@ -5189,6 +5223,14 @@ lst << pyChild; } } + + //Remove actions + foreach(QAction *act, %CPPSELF.actions()) { + Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act)); + Shiboken::Object::setParent(NULL, pyAct); + Shiboken::Object::invalidate(pyAct); + } + %CPPSELF.clear(); foreach(PyObject* obj, lst) { Shiboken::Object::invalidate(reinterpret_cast<SbkObject* >(obj)); From 6e9b7ffd5971d56101a304e3bd9e0a4205637aaf Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 24 Aug 2011 17:24:21 -0300 Subject: [PATCH 122/267] Created unit test for QMenu, QMenuBar, QToolBar clear function. Reviewed by: Hugo Parente Luciano Wolf --- tests/QtGui/CMakeLists.txt | 1 + tests/QtGui/action_clear.py | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/QtGui/action_clear.py diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 96920b4..9c9339d 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -1,5 +1,6 @@ #Keep this in alphabetical sort +PYSIDE_TEST(action_clear.py) PYSIDE_TEST(api2_test.py) PYSIDE_TEST(add_action_test.py) PYSIDE_TEST(bug_172.py) diff --git a/tests/QtGui/action_clear.py b/tests/QtGui/action_clear.py new file mode 100644 index 0000000..54d5e93 --- /dev/null +++ b/tests/QtGui/action_clear.py @@ -0,0 +1,46 @@ +from PySide.QtGui import QMenu, QWidget, QMenuBar, QToolBar +import weakref + +import unittest +from helper import UsesQApplication + + +class TestQActionLifeCycle(UsesQApplication): + def actionDestroyed(self, act): + self._actionDestroyed = True + + def testMenu(self): + self._actionDestroyed = False + w = QWidget() + menu = QMenu(w) + act = menu.addAction("MENU") + _ref = weakref.ref(act, self.actionDestroyed) + act = None + self.assertFalse(self._actionDestroyed) + menu.clear() + self.assertTrue(self._actionDestroyed) + + def testMenuBar(self): + self._actionDestroyed = False + w = QWidget() + menuBar = QMenuBar(w) + act = menuBar.addAction("MENU") + _ref = weakref.ref(act, self.actionDestroyed) + act = None + self.assertFalse(self._actionDestroyed) + menuBar.clear() + self.assertTrue(self._actionDestroyed) + + def testToolBar(self): + self._actionDestroyed = False + w = QWidget() + toolBar = QToolBar(w) + act = toolBar.addAction("MENU") + _ref = weakref.ref(act, self.actionDestroyed) + act = None + self.assertFalse(self._actionDestroyed) + toolBar.clear() + self.assertTrue(self._actionDestroyed) + +if __name__ == "__main__": + unittest.main() From 65d4cf2be4bf6071b03c9ae34368d9cffda597e5 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Thu, 25 Aug 2011 17:29:01 -0300 Subject: [PATCH 123/267] Fix complation warning relative to PyDateTime_IMPORT. --- PySide/QtCore/qdatetime_conversions.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/PySide/QtCore/qdatetime_conversions.h b/PySide/QtCore/qdatetime_conversions.h index 38c0336..44cf92c 100644 --- a/PySide/QtCore/qdatetime_conversions.h +++ b/PySide/QtCore/qdatetime_conversions.h @@ -1,3 +1,6 @@ +#define PySideDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import((char*)"datetime", \ + (char*)"datetime_CAPI") namespace Shiboken { inline bool Converter::checkType(PyObject* pyObj) @@ -16,7 +19,7 @@ inline bool Converter::isConvertible(PyObject* pyObj) return true; if (!PyDateTimeAPI) - PyDateTime_IMPORT; + PySideDateTime_IMPORT; SbkObjectType* shiboType = reinterpret_cast(SbkType< ::QDateTime >()); return PyDateTime_Check(pyObj) || ObjectType::isExternalConvertible(shiboType, pyObj); @@ -26,7 +29,7 @@ inline bool Converter::isConvertible(PyObject* pyObj) inline QDateTime Converter::toCpp(PyObject* pyObj) { if (!PyDateTimeAPI) - PyDateTime_IMPORT; + PySideDateTime_IMPORT; if (pyObj == Py_None) { return QDateTime(); From d5b645d3ab8faa5aa5887e7fecf370f7ef322bba Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 26 Aug 2011 15:38:23 -0300 Subject: [PATCH 124/267] Created utility function to call a python method usign args received in qt_metacall. Reviewed by: Hugo Parente Luciano Wolf --- libpyside/globalreceiverv2.cpp | 36 ++--- libpyside/signalmanager.cpp | 232 ++++++++++++++++++--------------- libpyside/signalmanager.h | 2 + 3 files changed, 140 insertions(+), 130 deletions(-) diff --git a/libpyside/globalreceiverv2.cpp b/libpyside/globalreceiverv2.cpp index c31a9d2..748332f 100644 --- a/libpyside/globalreceiverv2.cpp +++ b/libpyside/globalreceiverv2.cpp @@ -52,7 +52,7 @@ class DynamicSlotDataV2 int addSlot(const char* signature); int id(const char* signature) const; - PyObject* call(PyObject* args); + PyObject* callback(); QByteArray hash() const; void notify(); @@ -115,20 +115,17 @@ QByteArray DynamicSlotDataV2::hash(PyObject* callback) return QByteArray::number((qlonglong)PyObject_Hash(callback)); } -PyObject* DynamicSlotDataV2::call(PyObject* args) +PyObject* DynamicSlotDataV2::callback() { PyObject* callback = m_callback; //create a callback based on method data if (m_isMethod) callback = PyMethod_New(m_callback, m_pythonSelf, m_pyClass); + else + Py_INCREF(callback); - PyObject* result = PyObject_CallObject(callback, args); - - if (m_isMethod) - Py_DECREF(callback); - - return result; + return callback; } int DynamicSlotDataV2::id(const char* signature) const @@ -282,26 +279,9 @@ int GlobalReceiverV2::qt_metacall(QMetaObject::Call call, int id, void** args) m_refs.removeAll(obj); // remove all refs to this object decRef(); //remove the safe ref } else { - Shiboken::GilState gil; - PyObject* retval = 0; - - bool isShortCurt = (strstr(slot.signature(), "(") == 0); - if (isShortCurt) { - retval = m_data->call(reinterpret_cast(args[1])); - } else { - QList paramTypes = slot.parameterTypes(); - Shiboken::AutoDecRef preparedArgs(PyTuple_New(paramTypes.count())); - for (int i = 0, max = paramTypes.count(); i < max; ++i) { - PyObject* arg = Shiboken::TypeResolver::get(paramTypes[i].constData())->toPython(args[i+1]); // Do not increment the reference - PyTuple_SET_ITEM(preparedArgs.object(), i, arg); - } - retval = m_data->call(preparedArgs); - } - - if (!retval) - PyErr_Print(); - else - Py_DECREF(retval); + bool isShortCuit = (strstr(slot.signature(), "(") == 0); + Shiboken::AutoDecRef callback(m_data->callback()); + SignalManager::callPythonMetaMethod(slot, args, callback, isShortCuit); } return -1; diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index c0dffd4..bd455c9 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -50,6 +50,12 @@ namespace { static PyObject *metaObjectAttr = 0; + + static int callMethod(QObject* object, int id, void** args); + static PyObject* parseArguments(QList paramTypese, void** args); + static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args); + static bool emitNormalSignal(QObject* source, int signalIndex, const char* signal, PyObject* args, const QStringList& argTypes); + static void destroyMetaObject(void* obj) { delete reinterpret_cast(obj); @@ -58,7 +64,6 @@ namespace { namespace PySide { -static int callMethod(QObject* object, int id, void** args); PyObjectWrapper::PyObjectWrapper() :m_me(Py_None) @@ -309,58 +314,6 @@ int SignalManager::globalReceiverSlotIndex(QObject* receiver, const char* signat return reinterpret_cast(receiver)->addSlot(signature); } -static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args) -{ - void* signalArgs[2] = {0, args}; - source->qt_metacall(QMetaObject::InvokeMetaMethod, signalIndex, signalArgs); - return true; -} - -static bool emitNormalSignal(QObject* source, int signalIndex, const char* signal, PyObject* args, const QStringList& argTypes) -{ - Shiboken::AutoDecRef sequence(PySequence_Fast(args, 0)); - int argsGiven = PySequence_Fast_GET_SIZE(sequence.object()); - - if (argsGiven != argTypes.count()) { - PyErr_Format(PyExc_TypeError, "%s only accepts %d arguments, %d given!", signal, argTypes.count(), argsGiven); - return false; - } - - QVariant* signalValues = new QVariant[argsGiven]; - void** signalArgs = new void*[argsGiven + 1]; - signalArgs[0] = 0; - - int i; - for (i = 0; i < argsGiven; ++i) { - QByteArray typeName = argTypes[i].toAscii(); - Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(typeName); - if (typeResolver) { - if (Shiboken::TypeResolver::getType(typeName) == Shiboken::TypeResolver::ValueType) { - int typeId = QMetaType::type(typeName); - if (!typeId) { - PyErr_Format(PyExc_TypeError, "Value type used on signal needs to be registered on meta type: %s", typeName.data()); - break; - } - signalValues[i] = QVariant(typeId, (void*) 0); - } - signalArgs[i+1] = signalValues[i].data(); - typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i), &signalArgs[i+1]); - } else { - PyErr_Format(PyExc_TypeError, "Unknown type used to emit a signal: %s", qPrintable(argTypes[i])); - break; - } - } - - bool ok = i == argsGiven; - if (ok) - source->qt_metacall(QMetaObject::InvokeMetaMethod, signalIndex, signalArgs); - - delete[] signalArgs; - delete[] signalValues; - - return ok; -} - bool SignalManager::emitSignal(QObject* source, const char* signal, PyObject* args) { if (!Signal::checkQtSignal(signal)) @@ -444,60 +397,36 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id, return id; } -static int PySide::callMethod(QObject* object, int id, void** args) +int SignalManager::callPythonMetaMethod(const QMetaMethod& method, void** args, PyObject* pyMethod, bool isShortCuit) { - const QMetaObject* metaObject = object->metaObject(); - QMetaMethod method = metaObject->method(id); + Q_ASSERT(pyMethod); - if (method.methodType() == QMetaMethod::Signal) { - // emit python signal - QMetaObject::activate(object, id, args); + Shiboken::GilState gil; + PyObject* pyArguments = NULL; + + if (isShortCuit) + pyArguments = reinterpret_cast(args[1]); + else + pyArguments = parseArguments(method.parameterTypes(), args); + + //keep the returnType this call be destroyed after method call + QByteArray returnType = method.typeName(); + + Shiboken::AutoDecRef retval(PyObject_CallObject(pyMethod, pyArguments)); + + if (!isShortCuit) + Py_XDECREF(pyArguments); + + if (retval.isNull()) { + PyErr_Print(); } else { - // call python slot - Shiboken::GilState gil; - QList paramTypes = method.parameterTypes(); - PyObject* self = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(object); - PyObject* preparedArgs = NULL; - Py_ssize_t argsSize = paramTypes.count(); - - if (argsSize) - preparedArgs = PyTuple_New(argsSize); - - for (int i = 0, max = paramTypes.count(); i < max; ++i) { - void* data = args[i+1]; - const char* dataType = paramTypes[i].constData(); - - Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(dataType); - if (tr) { - PyObject* arg = tr->toPython(data); - PyTuple_SET_ITEM(preparedArgs, i, arg); - } else { - PyErr_Format(PyExc_TypeError, "Can't call meta function because I have no idea how to handle %s", dataType); - return -1; - } - } - - QString methodName = method.signature(); - methodName = methodName.left(methodName.indexOf('(')); - - Shiboken::AutoDecRef pyMethod(PyObject_GetAttrString(self, qPrintable(methodName))); - if (!pyMethod.isNull()) { - Shiboken::AutoDecRef retval(PyObject_CallObject(pyMethod, preparedArgs)); - if (retval.isNull()) { - qWarning() << "Error calling slot" << methodName; - PyErr_Print(); - } else { - const char* returnType = method.typeName(); - if (returnType && (strlen(returnType) > 0)) - Shiboken::TypeResolver::get(returnType)->toCpp(retval, &args[0]); - } - } else { - qWarning() << "Dynamic slot" << methodName << "not found!"; - } - Py_XDECREF(preparedArgs); + if (returnType.size() > 0) + Shiboken::TypeResolver::get(returnType)->toCpp(retval, &args[0]); } + return -1; } + bool SignalManager::registerMetaMethod(QObject* source, const char* signature, QMetaMethod::MethodType type) { int ret = registerMetaMethodGetIndex(source, signature, type); @@ -544,7 +473,6 @@ bool SignalManager::hasConnectionWith(const QObject *object) return m_d->m_globalReceiver.hasConnectionWith(object); } - const QMetaObject* SignalManager::retriveMetaObject(PyObject *self) { Shiboken::GilState gil; @@ -563,4 +491,104 @@ const QMetaObject* SignalManager::retriveMetaObject(PyObject *self) return mo; } +namespace { +static int callMethod(QObject* object, int id, void** args) +{ + const QMetaObject* metaObject = object->metaObject(); + QMetaMethod method = metaObject->method(id); + + if (method.methodType() == QMetaMethod::Signal) { + // emit python signal + QMetaObject::activate(object, id, args); + } else { + Shiboken::GilState gil; + PyObject* self = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(object); + QByteArray methodName = method.signature(); + methodName = methodName.left(methodName.indexOf('(')); + Shiboken::AutoDecRef pyMethod(PyObject_GetAttrString(self, methodName)); + SignalManager::callPythonMetaMethod(method, args, pyMethod, false); + } + return -1; +} + + +static PyObject* parseArguments(QList paramTypes, void** args) +{ + PyObject* preparedArgs = NULL; + Py_ssize_t argsSize = paramTypes.count(); + + if (argsSize) + preparedArgs = PyTuple_New(argsSize); + + for (int i = 0, max = paramTypes.count(); i < max; ++i) { + void* data = args[i+1]; + const char* dataType = paramTypes[i].constData(); + + Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(dataType); + if (tr) { + PyObject* arg = tr->toPython(data); + PyTuple_SET_ITEM(preparedArgs, i, arg); + } else { + PyErr_Format(PyExc_TypeError, "Can't call meta function because I have no idea how to handle %s", dataType); + Py_DECREF(preparedArgs); + return NULL; + } + } + + return preparedArgs; +} + +static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args) +{ + void* signalArgs[2] = {0, args}; + source->qt_metacall(QMetaObject::InvokeMetaMethod, signalIndex, signalArgs); + return true; +} + +static bool emitNormalSignal(QObject* source, int signalIndex, const char* signal, PyObject* args, const QStringList& argTypes) +{ + Shiboken::AutoDecRef sequence(PySequence_Fast(args, 0)); + int argsGiven = PySequence_Fast_GET_SIZE(sequence.object()); + + if (argsGiven != argTypes.count()) { + PyErr_Format(PyExc_TypeError, "%s only accepts %d arguments, %d given!", signal, argTypes.count(), argsGiven); + return false; + } + + QVariant* signalValues = new QVariant[argsGiven]; + void** signalArgs = new void*[argsGiven + 1]; + signalArgs[0] = 0; + + int i; + for (i = 0; i < argsGiven; ++i) { + QByteArray typeName = argTypes[i].toAscii(); + Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(typeName); + if (typeResolver) { + if (Shiboken::TypeResolver::getType(typeName) == Shiboken::TypeResolver::ValueType) { + int typeId = QMetaType::type(typeName); + if (!typeId) { + PyErr_Format(PyExc_TypeError, "Value type used on signal needs to be registered on meta type: %s", typeName.data()); + break; + } + signalValues[i] = QVariant(typeId, (void*) 0); + } + signalArgs[i+1] = signalValues[i].data(); + typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i), &signalArgs[i+1]); + } else { + PyErr_Format(PyExc_TypeError, "Unknown type used to emit a signal: %s", qPrintable(argTypes[i])); + break; + } + } + + bool ok = i == argsGiven; + if (ok) + source->qt_metacall(QMetaObject::InvokeMetaMethod, signalIndex, signalArgs); + + delete[] signalArgs; + delete[] signalValues; + + return ok; +} + +} //namespace diff --git a/libpyside/signalmanager.h b/libpyside/signalmanager.h index 1c8ecfc..744cf9e 100644 --- a/libpyside/signalmanager.h +++ b/libpyside/signalmanager.h @@ -79,6 +79,8 @@ public: // Disconnect all signals managed by Globalreceiver void clear(); + // Utility function to call a python method usign args received in qt_metacall + static int callPythonMetaMethod(const QMetaMethod& method, void** args, PyObject* obj, bool isShortCuit); PYSIDE_DEPRECATED(QObject* globalReceiver()); PYSIDE_DEPRECATED(void addGlobalSlot(const char* slot, PyObject* callback)); From e9b959ed8ef5bab7840220675c327f6b0ffc3204 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 26 Aug 2011 15:39:29 -0300 Subject: [PATCH 125/267] Implemented inject code for function QWebPage.qt_metacall. This inject code is necessary due a workaround on C++ class QWebPage. Check de C++ doc for more information: http://doc.qt.nokia.com/4.7-snapshot/qwebpage.html#shouldInterruptJavaScript Fixes bug #973. Reviewed by: Hugo Parente Luciano Wolf --- PySide/QtCore/typesystem_core.xml | 1 - PySide/QtWebKit/typesystem_webkit.xml | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 6889b2e..124b4cd 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -62,7 +62,6 @@ - diff --git a/PySide/QtWebKit/typesystem_webkit.xml b/PySide/QtWebKit/typesystem_webkit.xml index bd32ccc..5dbd449 100644 --- a/PySide/QtWebKit/typesystem_webkit.xml +++ b/PySide/QtWebKit/typesystem_webkit.xml @@ -163,6 +163,27 @@ + + + + static int _signalIndex = -1; + static QMetaMethod _m; + + if (_signalIndex == -1) { + _signalIndex = QWebPage::staticMetaObject.indexOfSlot("shouldInterruptJavaScript()"); + _m = QWebPage::staticMetaObject.method(_signalIndex); + } + + if (_signalIndex == id) { + Shiboken::GilState gil; + PyObject* self = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(this); + if (self) { + Shiboken::AutoDecRef _pyMethod(PyObject_GetAttrString(self, "shouldInterruptJavaScript")); + return PySide::SignalManager::callPythonMetaMethod(_m, args, _pyMethod, false); + } + } + + From b3e839c1f8cc0f2181ccafb4aebd9dd1a153eb8a Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 26 Aug 2011 15:49:38 -0300 Subject: [PATCH 126/267] Removed debug messages from the test. Reviewed by: Hugo Parente Luciano Wolf --- tests/QtWebKit/bug_959.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/QtWebKit/bug_959.py b/tests/QtWebKit/bug_959.py index 26cdad8..c4e53c7 100644 --- a/tests/QtWebKit/bug_959.py +++ b/tests/QtWebKit/bug_959.py @@ -8,37 +8,31 @@ class JSFuncs(QObject): functionID = -1 @Slot(unicode,result=unicode) def slot_str_str(self, x): - print "slot_str_str(%r)"%x JSFuncs.functionID = 0 return x.upper() @Slot(unicode,result='QVariant') def slot_str_list(self, x): - print "slot_str_list(%r)"%x JSFuncs.functionID = 1 return [x, x] @Slot('QStringList',result=unicode) def slot_strlist_str(self, x): - print "slot_strlist_str(%r)"%x JSFuncs.functionID = 2 return x[-1] @Slot('QVariant',result=unicode) def slot_variant_str(self, x): - print "slot_variant_str(%r)"%x JSFuncs.functionID = 3 return unicode(x) @Slot('QVariantList',result=unicode) def slot_variantlist_str(self, x): - print "slot_variantlist_str(%r)"%x JSFuncs.functionID = 4 return unicode(x[-1]) @Slot('QVariantMap',result=unicode) def slot_variantmap_str(self, x): - print "slot_variantmap_str(%r)"%x JSFuncs.functionID = 5 return unicode(x["foo"]) From 01bd258e107ca3ef58e1b1dd9d9bc62f2b602c59 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 26 Aug 2011 16:03:08 -0300 Subject: [PATCH 127/267] Created unit test for bug #973. Reviewed by: Hugo Parente Luciano Wolf --- tests/QtWebKit/CMakeLists.txt | 1 + .../shouldInterruptjavascript_test.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/QtWebKit/shouldInterruptjavascript_test.py diff --git a/tests/QtWebKit/CMakeLists.txt b/tests/QtWebKit/CMakeLists.txt index 5f0820d..7fab647 100644 --- a/tests/QtWebKit/CMakeLists.txt +++ b/tests/QtWebKit/CMakeLists.txt @@ -5,6 +5,7 @@ PYSIDE_TEST(bug_899.py) PYSIDE_TEST(bug_959.py) PYSIDE_TEST(qvariantlist_property_test.py) PYSIDE_TEST(qml_plugin_test.py) +PYSIDE_TEST(shouldInterruptjavascript_test.py) PYSIDE_TEST(webpage_test.py) PYSIDE_TEST(webview_test.py) PYSIDE_TEST(webframe_test.py) diff --git a/tests/QtWebKit/shouldInterruptjavascript_test.py b/tests/QtWebKit/shouldInterruptjavascript_test.py new file mode 100644 index 0000000..b624220 --- /dev/null +++ b/tests/QtWebKit/shouldInterruptjavascript_test.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import unittest +from PySide import QtCore, QtWebKit + +from helper import UsesQApplication + +class QWebPageHeadless(QtWebKit.QWebPage): + # FIXME: This is not working, the slot is not overriden! + # http://doc.qt.nokia.com/4.7-snapshot/qwebpage.html#shouldInterruptJavaScript + @QtCore.Slot() + def shouldInterruptJavaScript(self): + self._interrupted = True + QtCore.QTimer.singleShot(300, self._app.quit) + return True + +class TestSlotOverride(UsesQApplication): + def testFunctionCall(self): + page = QWebPageHeadless() + page._interrupted = False + page._app = self.app + page.mainFrame().setHtml('') + self.app.exec_() + self.assertTrue(page._interrupted) + +if __name__ == '__main__': + unittest.main() From 5eda2f136589c9e28fa9c16c55370627f54af73e Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 25 Aug 2011 19:27:48 -0300 Subject: [PATCH 128/267] Fix white space. --- PySide/QtCore/typesystem_core.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 124b4cd..ba25881 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -1510,7 +1510,7 @@ - + From e59a9f833f4cb1a891bd84bf87f11c1538496bef Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 25 Aug 2011 19:41:19 -0300 Subject: [PATCH 129/267] Added missing primitive types on QtCore type system. Reviewer: Marcelo Lira Luciano Wolf --- PySide/QtCore/typesystem_core.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index ba25881..71c9572 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -104,7 +104,9 @@ + + @@ -116,7 +118,9 @@ + + From b6068afc3eb822fea7846b294e56412a16d8da56 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 26 Aug 2011 18:42:26 -0300 Subject: [PATCH 130/267] Fixed SignalManager bug during anonymous signal connection. Reviewed by: Hugo Parente Luciano Wolf --- libpyside/signalmanager.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index bd455c9..002d8f9 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -275,10 +275,12 @@ QObject* SignalManager::globalReceiver(QObject *sender, PyObject *callback) SharedMap globalReceivers = m_d->m_globalReceivers; QByteArray hash = GlobalReceiverV2::hash(callback); GlobalReceiverV2* gr = 0; - if (!globalReceivers->contains(hash) && sender) { + if (!globalReceivers->contains(hash)) { gr = (*globalReceivers)[hash] = new GlobalReceiverV2(callback, globalReceivers); - gr->incRef(sender); // create a link reference - gr->decRef(); // remove extra reference + if (sender) { + gr->incRef(sender); // create a link reference + gr->decRef(); // remove extra reference + } } else { gr = (*globalReceivers)[hash]; if (sender) From d0decf40df7ec0f9474a2237fb0fd4809c43589f Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 26 Aug 2011 19:11:54 -0300 Subject: [PATCH 131/267] Fail during the signal connection or disconnection raises exception. Fixes bug #987. Reviewed by: Hugo Parente Luciano Wolf --- libpyside/pysidesignal.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/libpyside/pysidesignal.cpp b/libpyside/pysidesignal.cpp index 7fdb01f..b4940d5 100644 --- a/libpyside/pysidesignal.cpp +++ b/libpyside/pysidesignal.cpp @@ -374,9 +374,14 @@ PyObject* signalInstanceConnect(PyObject* self, PyObject* args, PyObject* kwds) if (match) { Shiboken::AutoDecRef tupleArgs(PyList_AsTuple(pyArgs)); Shiboken::AutoDecRef pyMethod(PyObject_GetAttrString(source->d->source, "connect")); - return PyObject_CallObject(pyMethod, tupleArgs); + PyObject* result = PyObject_CallObject(pyMethod, tupleArgs); + if (result == Py_True) + return result; + else + Py_DECREF(result); } + PyErr_Format(PyExc_RuntimeError, "Fail to connect signal %s.", source->d->signature); return 0; } @@ -416,7 +421,6 @@ PyObject* signalInstanceGetItem(PyObject* self, PyObject* key) } PyErr_Format(PyExc_IndexError, "Signature %s not found for signal: %s", sig, sigName); free(sig); - return 0; } @@ -460,9 +464,14 @@ PyObject* signalInstanceDisconnect(PyObject* self, PyObject* args) if (match) { Shiboken::AutoDecRef tupleArgs(PyList_AsTuple(pyArgs)); Shiboken::AutoDecRef pyMethod(PyObject_GetAttrString(source->d->source, "disconnect")); - return PyObject_CallObject(pyMethod, tupleArgs); + PyObject* result = PyObject_CallObject(pyMethod, tupleArgs); + if (result == Py_True) + return result; + else + Py_DECREF(result); } + PyErr_Format(PyExc_RuntimeError, "Fail to disconnect signal %s.", source->d->signature); return 0; } @@ -674,7 +683,13 @@ bool connect(PyObject* source, const char* signal, PyObject* callback) Shiboken::AutoDecRef pySignature(PyString_FromString(signal)); Shiboken::AutoDecRef pyArgs(PyTuple_Pack(3, source, pySignature.object(), callback)); - return PyObject_CallObject(pyMethod, pyArgs); + PyObject* result = PyObject_CallObject(pyMethod, pyArgs); + if (result == Py_False) { + PyErr_Format(PyExc_RuntimeError, "Fail to connect signal %s, to python callable object.", signal); + Py_DECREF(result); + result = 0; + } + return result; } PySideSignalInstance* newObjectFromMethod(PyObject* source, const QList& methodList) From 24838672f0b8256a4fddcb04cf30d7a4d53b7d52 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Fri, 26 Aug 2011 19:12:52 -0300 Subject: [PATCH 132/267] Created unit test for bug #987. Reviewed by: Hugo Parente Luciano Wolf --- tests/QtCore/CMakeLists.txt | 1 + tests/QtCore/bug_987.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/QtCore/bug_987.py diff --git a/tests/QtCore/CMakeLists.txt b/tests/QtCore/CMakeLists.txt index aa646d7..2438b09 100644 --- a/tests/QtCore/CMakeLists.txt +++ b/tests/QtCore/CMakeLists.txt @@ -21,6 +21,7 @@ PYSIDE_TEST(bug_927.py) PYSIDE_TEST(bug_931.py) PYSIDE_TEST(bug_938.py) PYSIDE_TEST(bug_953.py) +PYSIDE_TEST(bug_987.py) PYSIDE_TEST(blocking_signals_test.py) PYSIDE_TEST(classinfo_test.py) PYSIDE_TEST(child_event_test.py) diff --git a/tests/QtCore/bug_987.py b/tests/QtCore/bug_987.py new file mode 100644 index 0000000..9609a45 --- /dev/null +++ b/tests/QtCore/bug_987.py @@ -0,0 +1,15 @@ +from PySide.QtCore import QObject + +import unittest + + +class TestBug987(unittest.TestCase): + def callback(self): + pass + + def testInvalidDisconnection(self): + o = QObject() + self.assertRaises(RuntimeError, o.destroyed.disconnect, self.callback) + +if __name__ == '__main__': + unittest.main() From 1c4ebcbe8a79c7b5c9a9db8164493926009831db Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Mon, 29 Aug 2011 15:02:27 -0300 Subject: [PATCH 133/267] Fixed gcc warning during QDate conversion compilation. --- PySide/QtCore/qdate_conversions.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/PySide/QtCore/qdate_conversions.h b/PySide/QtCore/qdate_conversions.h index 7c45eec..586fc3c 100644 --- a/PySide/QtCore/qdate_conversions.h +++ b/PySide/QtCore/qdate_conversions.h @@ -1,3 +1,7 @@ +#define PySideDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import((char*)"datetime", \ + (char*)"datetime_CAPI") + namespace Shiboken { inline bool Converter::checkType(PyObject* pyObj) @@ -16,7 +20,7 @@ inline bool Converter::isConvertible(PyObject* pyObj) return true; if (!PyDateTimeAPI) - PyDateTime_IMPORT; + PySideDateTime_IMPORT; SbkObjectType* shiboType = reinterpret_cast(SbkType< ::QDate >()); return PyDate_Check(pyObj) || ObjectType::isExternalConvertible(shiboType, pyObj); @@ -25,7 +29,7 @@ inline bool Converter::isConvertible(PyObject* pyObj) inline QDate Converter::toCpp(PyObject* pyObj) { if (!PyDateTimeAPI) - PyDateTime_IMPORT; + PySideDateTime_IMPORT; if (pyObj == Py_None) { return QDate(); From 49ad2f9c1de0c8877f72a92ffab47d2895a48839 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 30 Aug 2011 11:19:20 -0300 Subject: [PATCH 134/267] Created unit test for repr function. Reviewer: Marcelo Lira Luciano Wolf --- tests/QtGui/CMakeLists.txt | 1 + tests/QtGui/bug_991.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/QtGui/bug_991.py diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 9c9339d..044366d 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -72,6 +72,7 @@ PYSIDE_TEST(bug_921.py) PYSIDE_TEST(bug_941.py) PYSIDE_TEST(bug_964.py) PYSIDE_TEST(bug_972.py) +PYSIDE_TEST(bug_991.py) PYSIDE_TEST(customproxywidget_test.py) PYSIDE_TEST(deepcopy_test.py) PYSIDE_TEST(event_filter_test.py) diff --git a/tests/QtGui/bug_991.py b/tests/QtGui/bug_991.py new file mode 100644 index 0000000..55ff81d --- /dev/null +++ b/tests/QtGui/bug_991.py @@ -0,0 +1,15 @@ +import unittest +from PySide.QtCore import QObject +from PySide.QtGui import QPen, QBrush + +class TestBug991 (unittest.TestCase): + def testReprFunction(self): + reprPen = repr(QPen()) + self.assertTrue(reprPen.startswith(" Date: Tue, 30 Aug 2011 15:53:36 -0300 Subject: [PATCH 135/267] Optimize my dumb code that do stuff with a QByteArray without knowing if will use it. --- libpyside/pysidesignal.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libpyside/pysidesignal.cpp b/libpyside/pysidesignal.cpp index b4940d5..9b8cbc0 100644 --- a/libpyside/pysidesignal.cpp +++ b/libpyside/pysidesignal.cpp @@ -783,11 +783,12 @@ void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject) SignalSigMap signalsFound; for(int i = metaObject->methodOffset(), max = metaObject->methodCount(); i < max; ++i) { QMetaMethod method = metaObject->method(i); - QByteArray methodName(method.signature()); - methodName.chop(methodName.size() - methodName.indexOf('(')); - if (method.methodType() == QMetaMethod::Signal) + if (method.methodType() == QMetaMethod::Signal) { + QByteArray methodName(method.signature()); + methodName.chop(methodName.size() - methodName.indexOf('(')); signalsFound[methodName] << join(method.parameterTypes(), ","); + } } SignalSigMap::Iterator it = signalsFound.begin(); From a7e4ddb8cae99fc17ab5e15a0a32c019c3f3a494 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Tue, 30 Aug 2011 16:02:43 -0300 Subject: [PATCH 136/267] Fix bug 988 - "The type supplied with currentChanged signal in QTabWidget has changed in 1.0.6" Reviewer: Luciano Wolf Marcelo Lira --- libpyside/pysidesignal.cpp | 9 ++++++++- tests/QtGui/CMakeLists.txt | 1 + tests/QtGui/bug_988.py | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/QtGui/bug_988.py diff --git a/libpyside/pysidesignal.cpp b/libpyside/pysidesignal.cpp index 9b8cbc0..3308035 100644 --- a/libpyside/pysidesignal.cpp +++ b/libpyside/pysidesignal.cpp @@ -777,6 +777,12 @@ static void _addSignalToWrapper(SbkObjectType* wrapperType, const char* signalNa PyDict_SetItemString(typeDict, signalName, reinterpret_cast(signal)); } +// This function is used by qStableSort to promote empty signatures +static bool compareSignals(const QByteArray& sig1, const QByteArray& sig2) +{ + return sig1.isEmpty(); +} + void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject) { typedef QHash > SignalSigMap; @@ -801,7 +807,8 @@ void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject) self->initialized = 0; self->homonymousMethod = 0; - qSort(it.value().begin(), it.value().end()); + // Empty signatures comes first! So they will be the default signal signature + qStableSort(it.value().begin(), it.value().end(), &compareSignals); SignalSigMap::mapped_type::const_iterator j = it.value().begin(); SignalSigMap::mapped_type::const_iterator endJ = it.value().end(); for (; j != endJ; ++j) diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 044366d..85e5988 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -72,6 +72,7 @@ PYSIDE_TEST(bug_921.py) PYSIDE_TEST(bug_941.py) PYSIDE_TEST(bug_964.py) PYSIDE_TEST(bug_972.py) +PYSIDE_TEST(bug_988.py) PYSIDE_TEST(bug_991.py) PYSIDE_TEST(customproxywidget_test.py) PYSIDE_TEST(deepcopy_test.py) diff --git a/tests/QtGui/bug_988.py b/tests/QtGui/bug_988.py new file mode 100644 index 0000000..12e2155 --- /dev/null +++ b/tests/QtGui/bug_988.py @@ -0,0 +1,18 @@ +import unittest +from PySide.QtGui import * + +class TestBug988 (unittest.TestCase): + + def callback(self, arg): + self.arg = arg + + def testIt(self): + self.arg = None + app = QApplication([]) + obj = QTabWidget() + obj.currentChanged.connect(self.callback) + obj.currentChanged.emit(5) + self.assertEqual(self.arg, 5) + +if __name__ == "__main__": + unittest.main() From 6e6e7f528d59b27349ba1fd33f27d743592f8959 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 30 Aug 2011 18:14:42 -0300 Subject: [PATCH 137/267] Created test for bug #979. --- tests/QtGui/CMakeLists.txt | 1 + tests/QtGui/bug_979.py | 9 +++++++++ tests/QtGui/import_test.py | 2 ++ 3 files changed, 12 insertions(+) create mode 100644 tests/QtGui/bug_979.py create mode 100644 tests/QtGui/import_test.py diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 85e5988..9fb62b4 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -72,6 +72,7 @@ PYSIDE_TEST(bug_921.py) PYSIDE_TEST(bug_941.py) PYSIDE_TEST(bug_964.py) PYSIDE_TEST(bug_972.py) +PYSIDE_TEST(bug_979.py) PYSIDE_TEST(bug_988.py) PYSIDE_TEST(bug_991.py) PYSIDE_TEST(customproxywidget_test.py) diff --git a/tests/QtGui/bug_979.py b/tests/QtGui/bug_979.py new file mode 100644 index 0000000..b780d35 --- /dev/null +++ b/tests/QtGui/bug_979.py @@ -0,0 +1,9 @@ +from PySide.QtGui import QDialog +from import_test import PysideImportTest2 + +class PysideImportTest1(QDialog, PysideImportTest2): + pass + +if __name__ == '__main__': + quit() + diff --git a/tests/QtGui/import_test.py b/tests/QtGui/import_test.py new file mode 100644 index 0000000..0b60241 --- /dev/null +++ b/tests/QtGui/import_test.py @@ -0,0 +1,2 @@ +class PysideImportTest2(object): + pass From 57b291fe66dde855ad2d6782eef6034ec914d6c1 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 31 Aug 2011 11:31:03 -0300 Subject: [PATCH 138/267] Unit test for bug 967, a side effect of bug 988. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Marcelo Lira Renato Araújo --- tests/QtGui/CMakeLists.txt | 1 + tests/QtGui/bug_967.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/QtGui/bug_967.py diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 9fb62b4..ab5bd39 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -71,6 +71,7 @@ PYSIDE_TEST(bug_919.py) PYSIDE_TEST(bug_921.py) PYSIDE_TEST(bug_941.py) PYSIDE_TEST(bug_964.py) +PYSIDE_TEST(bug_967.py) PYSIDE_TEST(bug_972.py) PYSIDE_TEST(bug_979.py) PYSIDE_TEST(bug_988.py) diff --git a/tests/QtGui/bug_967.py b/tests/QtGui/bug_967.py new file mode 100644 index 0000000..41faf2f --- /dev/null +++ b/tests/QtGui/bug_967.py @@ -0,0 +1,18 @@ +import unittest +from PySide.QtGui import * + +class TestBug967 (unittest.TestCase): + + def callback(self, arg): + self.arg = arg + + def testIt(self): + self.arg = None + app = QApplication([]) + obj = QComboBox() + obj.currentIndexChanged.connect(self.callback) + obj.currentIndexChanged.emit(5) + self.assertEqual(self.arg, 5) + +if __name__ == "__main__": + unittest.main() From 2487a080624a74a0db9dc068174d23453d18c114 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 31 Aug 2011 16:57:28 -0300 Subject: [PATCH 139/267] Fixed QColor reduce function. Fixes bug #989. Reviewer: Luciano Wolf Marcelo Lira --- PySide/QtGui/typesystem_gui_common.xml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index c35a759..e772cd9 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -1165,42 +1165,43 @@ + + + Shiboken::AutoDecRef func(PyObject_GetAttr(%PYSELF, PyTuple_GET_ITEM(%1, 0))); + PyObject* args = PyTuple_GET_ITEM(%1, 1); + %PYARG_0 = PyObject_Call(func, args, NULL); + + - PyObject *createFunction = 0; - switch(%CPPSELF.spec()) { case QColor::Rgb: { qreal r, g, b, a; - createFunction = PyObject_GetAttrString(%PYSELF, "fromRgbF"); %CPPSELF.getRgbF(&r, &g, &b, &a); - %PYARG_0 = Py_BuildValue("(N(ffff))", createFunction, r, g, b, a); + %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setRgbF", (float)r, (float)g, (float)b, (float)a); break; } case QColor::Hsv: { qreal h, s, v, a; - createFunction = PyObject_GetAttrString(%PYSELF, "fromHsvF"); %CPPSELF.getHsvF(&h, &s, &v, &a); - %PYARG_0 = Py_BuildValue("(N(ffff))", createFunction, h, s, v, a); + %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setHsvF", (float)h, (float)s, (float)v, (float)a); break; } case QColor::Cmyk: { qreal c, m, y, k, a; - createFunction = PyObject_GetAttrString(%PYSELF, "fromCmykF"); %CPPSELF.getCmykF(&c, &m, &y, &k, &a); - %PYARG_0 = Py_BuildValue("(N(fffff))", createFunction, c, m, y, k, a); + %PYARG_0 = Py_BuildValue("(ON(s(fffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setCmykF", (float)c, (float)m, (float)y, (float)k, (float)a); break; } #if QT_VERSION >= 0x040600 case QColor::Hsl: { qreal h, s, l, a; - createFunction = PyObject_GetAttrString(%PYSELF, "fromHslF"); %CPPSELF.getHslF(&h, &s, &l, &a); - %PYARG_0 = Py_BuildValue("(N(ffff))", createFunction, h, s, l, a); + %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setHslF", (float)h, (float)s, (float)l, (float)a); break; } #endif From 700a4cf95ca3723062dc6affc89a2bd6a5b66dee Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 31 Aug 2011 16:58:39 -0300 Subject: [PATCH 140/267] Created unit test for QColor reduce function. Reviewer: Luciano Wolf Marcelo Lira --- tests/QtGui/CMakeLists.txt | 1 + tests/QtGui/qcolor_reduce_test.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/QtGui/qcolor_reduce_test.py diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index ab5bd39..d4ea190 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -94,6 +94,7 @@ PYSIDE_TEST(qapplication_singleton_test.py) PYSIDE_TEST(qapp_test.py) PYSIDE_TEST(qbrush_test.py) PYSIDE_TEST(qcolor_test.py) +PYSIDE_TEST(qcolor_reduce_test.py) PYSIDE_TEST(qcursor_test.py) PYSIDE_TEST(qaction_test.py) PYSIDE_TEST(qdatastream_gui_operators_test.py) diff --git a/tests/QtGui/qcolor_reduce_test.py b/tests/QtGui/qcolor_reduce_test.py new file mode 100644 index 0000000..c846ae3 --- /dev/null +++ b/tests/QtGui/qcolor_reduce_test.py @@ -0,0 +1,31 @@ +import unittest +import pickle +from PySide.QtGui import QColor + +class TestQColor (unittest.TestCase): + def reduceColor(self, c): + p = pickle.dumps(c) + c2 = pickle.loads(p) + self.assertEqual(c.spec(), c2.spec()) + self.assertEqual(c, c2) + + def testReduceEmpty(self): + self.reduceColor(QColor()) + + def testReduceString(self): + self.reduceColor(QColor('gray')) + + def testReduceRGB(self): + self.reduceColor(QColor.fromRgbF(0.1, 0.2, 0.3, 0.4)) + + def testReduceCMYK(self): + self.reduceColor(QColor.fromCmykF(0.1, 0.2, 0.3, 0.4, 0.5)) + + def testReduceHsl(self): + self.reduceColor(QColor.fromHslF(0.1, 0.2, 0.3, 0.4)) + + def testReduceHsv(self): + self.reduceColor(QColor.fromHsvF(0.1, 0.2, 0.3, 0.4)) + +if __name__ == "__main__": + unittest.main() From 08d202e824ffc6221bd426084ac169324808e9da Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 31 Aug 2011 15:24:40 -0300 Subject: [PATCH 141/267] Fix bug 966 - "QX11Info.display() missing" --- PySide/QtGui/typesystem_gui_x11.xml | 19 +++++++++++++++---- tests/QtGui/CMakeLists.txt | 2 +- tests/QtGui/x11_symbols_test.py | 17 ++++++++++++----- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/PySide/QtGui/typesystem_gui_x11.xml b/PySide/QtGui/typesystem_gui_x11.xml index 96bfb24..54d8882 100644 --- a/PySide/QtGui/typesystem_gui_x11.xml +++ b/PySide/QtGui/typesystem_gui_x11.xml @@ -23,10 +23,21 @@ - - - - + + + %PYARG_0 = PyLong_FromVoidPtr(%TYPE::%FUNCTION_NAME()); + + + + + %PYARG_0 = PyLong_FromVoidPtr(%CPPSELF.%FUNCTION_NAME()); + + + + + %PYARG_0 = PyLong_FromVoidPtr(%CPPSELF.%FUNCTION_NAME()); + + diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index d4ea190..75f576f 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -160,6 +160,6 @@ PYSIDE_TEST(virtual_pure_override_test.py) PYSIDE_TEST(wrong_return_test.py) -if(X11) +if(Q_WS_X11) PYSIDE_TEST(x11_symbols_test.py) endif() diff --git a/tests/QtGui/x11_symbols_test.py b/tests/QtGui/x11_symbols_test.py index 29cce15..6a38eed 100644 --- a/tests/QtGui/x11_symbols_test.py +++ b/tests/QtGui/x11_symbols_test.py @@ -3,15 +3,22 @@ import unittest -from PySide.QtGui import QPixmap +from PySide.QtGui import * class X11Test(unittest.TestCase): def test(self): - self.assert_('handle' in dir(QPixmap)) - self.assert_('x11Info' in dir(QPixmap)) - self.assert_('x11PictureHandle' in dir(QPixmap)) - self.assert_('x11SetDefaultScreen' in dir(QPixmap)) + qpixmapFuncs = dir(QPixmap) + self.assert_('handle' in qpixmapFuncs) + self.assert_('x11Info' in qpixmapFuncs) + self.assert_('x11PictureHandle' in qpixmapFuncs) + self.assert_('x11SetDefaultScreen' in qpixmapFuncs) + + def testX11Functions(self): + qx11infoFuncs = dir(QX11Info) + self.assert_('display' in qx11infoFuncs) + self.assert_('appVisual' in qx11infoFuncs) + self.assert_('visual' in qx11infoFuncs) if __name__ == '__main__': unittest.main() From 9afe76796d365978ee4be04e195cc5ec43758868 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 31 Aug 2011 17:43:45 -0300 Subject: [PATCH 142/267] Fix bug 944 - "QIODevice.readData must use qmemcpy instead of qstrncpy" Reviewer: Luciano Wolf Marcelo Lira --- PySide/QtCore/typesystem_core.xml | 2 +- tests/QtCore/CMakeLists.txt | 1 + tests/QtCore/bug_994.py | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/QtCore/bug_994.py diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 71c9572..8271a1b 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -2043,7 +2043,7 @@ %out = -1; } else { %out = PyString_GET_SIZE((PyObject*)%PYARG_0); - qstrncpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out + 1); + memcpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out); } diff --git a/tests/QtCore/CMakeLists.txt b/tests/QtCore/CMakeLists.txt index 2438b09..398746d 100644 --- a/tests/QtCore/CMakeLists.txt +++ b/tests/QtCore/CMakeLists.txt @@ -22,6 +22,7 @@ PYSIDE_TEST(bug_931.py) PYSIDE_TEST(bug_938.py) PYSIDE_TEST(bug_953.py) PYSIDE_TEST(bug_987.py) +PYSIDE_TEST(bug_994.py) PYSIDE_TEST(blocking_signals_test.py) PYSIDE_TEST(classinfo_test.py) PYSIDE_TEST(child_event_test.py) diff --git a/tests/QtCore/bug_994.py b/tests/QtCore/bug_994.py new file mode 100644 index 0000000..74e352c --- /dev/null +++ b/tests/QtCore/bug_994.py @@ -0,0 +1,20 @@ +import unittest +from PySide.QtCore import * + +class MyIODevice (QIODevice): + def readData(self, amount): + return "\0a" * (amount/2) + + def atEnd(self): + return False + +class TestBug944 (unittest.TestCase): + + def testIt(self): + device = MyIODevice() + device.open(QIODevice.ReadOnly) + s = QTextStream(device) + self.assertEqual(s.read(4), "\0a\0a") + +if __name__ == "__main__": + unittest.main() From 7ee30db078e15913c0a50016deb33113f06aa5dd Mon Sep 17 00:00:00 2001 From: Lauro Neto Date: Thu, 1 Sep 2011 14:09:54 -0300 Subject: [PATCH 143/267] Add extra test on QByteArray explicit conversion Reviewer: Luciano Wolf Reviewer: Marcelo Lira --- tests/QtCore/qbytearray_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/QtCore/qbytearray_test.py b/tests/QtCore/qbytearray_test.py index 38ed2ab..b12f7f9 100644 --- a/tests/QtCore/qbytearray_test.py +++ b/tests/QtCore/qbytearray_test.py @@ -154,6 +154,13 @@ class QByteArrayBug720(unittest.TestCase): self.assertEqual(str(ba), "32\"1\x00123") self.assertEqual(repr(ba), "PySide.QtCore.QByteArray('32\"1\\x00123')") +class QByteArrayImplicitConvert(unittest.TestCase): + def testString(self): + # No implicit conversions from QByteArray to python string + ba = QByteArray("object name") + obj = QObject() + self.assertRaises(TypeError, obj.setObjectName, ba) + if __name__ == '__main__': unittest.main() From 8e43e10f4e901851069be5557ec0f3dad72dc954 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 1 Sep 2011 11:38:14 -0300 Subject: [PATCH 144/267] Fix other QIODevice read functions stopping at null bytes. --- PySide/QtCore/typesystem_core.xml | 2 +- tests/QtCore/bug_994.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 8271a1b..f450a29 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -2066,7 +2066,7 @@ %out = -1; } else { %out = PyString_GET_SIZE((PyObject*)%PYARG_0); - qstrncpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out + 1); + memcpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out); } diff --git a/tests/QtCore/bug_994.py b/tests/QtCore/bug_994.py index 74e352c..5f12a96 100644 --- a/tests/QtCore/bug_994.py +++ b/tests/QtCore/bug_994.py @@ -5,6 +5,9 @@ class MyIODevice (QIODevice): def readData(self, amount): return "\0a" * (amount/2) + def readLineData(self, maxSize): + return "\0b" * 4 + def atEnd(self): return False @@ -15,6 +18,7 @@ class TestBug944 (unittest.TestCase): device.open(QIODevice.ReadOnly) s = QTextStream(device) self.assertEqual(s.read(4), "\0a\0a") + self.assertEqual(device.readLine(), "\0b\0b\0b\0b") if __name__ == "__main__": unittest.main() From e9de49255b6b4a1749b729a02e9fe643c66a042f Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 1 Sep 2011 14:26:33 -0300 Subject: [PATCH 145/267] Fix QAbstractFileEngine read and readLine methods to accept data with null bytes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Marcelo Lira Renato Araújo --- PySide/QtCore/typesystem_core.xml | 4 ++-- tests/QtCore/bug_723.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index f450a29..6b8205e 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -2363,7 +2363,7 @@ %out = -1; } else { %out = PyString_GET_SIZE((PyObject*)%PYARG_0); - qstrncpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out + 1); + memcpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out); } @@ -2386,7 +2386,7 @@ %out = -1; } else { %out = PyString_GET_SIZE((PyObject*)%PYARG_0); - qstrncpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out + 1); + memcpy(%1, PyString_AS_STRING((PyObject*)%PYARG_0), %out); } diff --git a/tests/QtCore/bug_723.py b/tests/QtCore/bug_723.py index 68ebeab..319c04b 100644 --- a/tests/QtCore/bug_723.py +++ b/tests/QtCore/bug_723.py @@ -5,7 +5,7 @@ class MyFileEngine (QAbstractFileEngine): def __init__(self): QAbstractFileEngine.__init__(self) - self.contents = "Foo bar for the win!" + self.contents = "Foo \0bar for the win!" self.pos = 0 def open(self, mode): @@ -27,7 +27,6 @@ class MyFileEngine (QAbstractFileEngine): class MyFileEngineHandler (QAbstractFileEngineHandler): def create(self, fileName): - print "hey ho: ", fileName if fileName.startswith("foo:/"): return MyFileEngine() return None @@ -42,7 +41,7 @@ class TestBug723 (unittest.TestCase): assert(f.open(QFile.ReadOnly | QFile.Text)) contents = f.readAll() - self.assertEqual(contents, "Foo bar for the win!") + self.assertEqual(contents, "Foo \0bar for the win!") f.close() From b55ea7fd5ebf58cb6d141c0091f7d47ef761a2ad Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Thu, 1 Sep 2011 17:33:20 -0300 Subject: [PATCH 146/267] Fix bug 981 - "QSettings docs should empathize the behavior changes of value() on different platforms" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewer: Marcelo Lira Luciano Wolf Renato Araújo --- PySide/QtCore/typesystem_core.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 6b8205e..bb67540 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -2544,6 +2544,11 @@ + + + .. warning:: QSettings.value can return different types (QVariant types) depending on the platform it's running on, so the safest way to use it is always casting the result to the desired type, e.g.: int(settings.value("myKey")) + + From d29d9ad5ac54d19aa456d5d8b189766162733445 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Wed, 31 Aug 2011 15:00:55 -0300 Subject: [PATCH 147/267] Changed QStringList from container to primitive type. QStringList inherits from QList, and it isn't a reusable container itself, such as QList. Reviewed by Hugo Parente Reviewed by Luciano Wolf --- PySide/QtCore/typesystem_core.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index bb67540..67969cd 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -139,10 +139,10 @@ - + - + From bfcc30ab86727b65c0ab89118e35a45a1e683470 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 6 Sep 2011 11:04:18 -0300 Subject: [PATCH 148/267] Fixed problems in function that return None, and was not verified. Some functions with inject code didnot verify the result value before convert to Shiboken types. Fixes bug #998. Reviewed by: Hugo Parente Lauro Neto --- PySide/typesystem_templates.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/PySide/typesystem_templates.xml b/PySide/typesystem_templates.xml index c2c0474..a35602f 100644 --- a/PySide/typesystem_templates.xml +++ b/PySide/typesystem_templates.xml @@ -246,10 +246,12 @@ %END_ALLOW_THREADS %PYARG_0 = Shiboken::makeTuple(retval_, %5); - From 2a634aea05487732fe06c2935dc2893f75af79ed Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Mon, 12 Dec 2011 17:46:37 -0300 Subject: [PATCH 253/267] Updated the custom widget plugin to use the new converters. --- plugins/CMakeLists.txt | 2 +- plugins/customwidget.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index b17dbc2..a65a421 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -5,7 +5,7 @@ set(ui_plugin_src customwidget.cpp ) -set (ui_plugin_moc +set(ui_plugin_moc customwidget.h customwidgets.h ) diff --git a/plugins/customwidget.cpp b/plugins/customwidget.cpp index fb849f2..d573ef4 100644 --- a/plugins/customwidget.cpp +++ b/plugins/customwidget.cpp @@ -95,11 +95,12 @@ QWidget* PyCustomWidget::createWidget(QWidget* parent) bool unkowParent = false; if (parent) { pyParent = reinterpret_cast(Shiboken::BindingManager::instance().retrieveWrapper(parent)); - if (!pyParent) { - pyParent = Shiboken::Converter::toPython(parent); - unkowParent = true; - } else { + if (pyParent) { Py_INCREF(pyParent); + } else { + static Shiboken::Conversions::SpecificConverter converter("QWidget*"); + pyParent = converter.toPython(&parent); + unkowParent = true; } } else { Py_INCREF(Py_None); @@ -129,4 +130,3 @@ void PyCustomWidget::initialize(QDesignerFormEditorInterface* core) { m_data->initialized = true; } - From e76b2b76f51ab643d6e97842ac3d3adc50b6a851 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Mon, 12 Dec 2011 20:02:38 -0300 Subject: [PATCH 254/267] Added type system entries to the primitive types used by QtOpenGL. --- PySide/QtOpenGL/typesystem_opengl.xml | 39 ++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/PySide/QtOpenGL/typesystem_opengl.xml b/PySide/QtOpenGL/typesystem_opengl.xml index 4c2604a..60a2d18 100644 --- a/PySide/QtOpenGL/typesystem_opengl.xml +++ b/PySide/QtOpenGL/typesystem_opengl.xml @@ -21,6 +21,21 @@ + + + + + + + + + + + + + + + @@ -191,7 +206,7 @@ - + @@ -207,7 +222,7 @@ - + @@ -415,7 +430,7 @@ - + @@ -431,7 +446,7 @@ - + @@ -640,19 +655,19 @@ - - - - + + + + - - - - + + + + From c78b4686a1f98273cf4e730efae32fa7f93ebebd Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Mon, 12 Dec 2011 19:10:07 -0200 Subject: [PATCH 255/267] Add GC support to PySide Property type. This fixes GC errors when running PySide on a Python debug env. Reviewer: Marcelo Lira --- libpyside/pysideproperty.cpp | 68 ++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/libpyside/pysideproperty.cpp b/libpyside/pysideproperty.cpp index e5ae5d5..1e1cf29 100644 --- a/libpyside/pysideproperty.cpp +++ b/libpyside/pysideproperty.cpp @@ -38,12 +38,14 @@ extern "C" static PyObject* qpropertyTpNew(PyTypeObject* subtype, PyObject* args, PyObject* kwds); static int qpropertyTpInit(PyObject*, PyObject*, PyObject*); -static void qpropertyFree(void*); +static void qpropertyDeAlloc(PyObject* self); //methods static PyObject* qPropertyCall(PyObject*, PyObject*, PyObject*); static PyObject* qPropertySetter(PyObject*, PyObject*); static PyObject* qPropertyGetter(PyObject*, PyObject*); +static int qpropertyTraverse(PyObject* self, visitproc visit, void* arg); +static int qpropertyClear(PyObject* self); static PyMethodDef PySidePropertyMethods[] = { {"setter", (PyCFunction)qPropertySetter, METH_O}, @@ -58,7 +60,7 @@ PyTypeObject PySidePropertyType = { QPROPERTY_CLASS_NAME, /*tp_name*/ sizeof(PySideProperty), /*tp_basicsize*/ 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ + qpropertyDeAlloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -73,10 +75,10 @@ PyTypeObject PySidePropertyType = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc */ - 0, /*tp_traverse */ - 0, /*tp_clear */ + qpropertyTraverse, /*tp_traverse */ + qpropertyClear, /*tp_clear */ 0, /*tp_richcompare */ 0, /*tp_weaklistoffset */ 0, /*tp_iter */ @@ -92,7 +94,7 @@ PyTypeObject PySidePropertyType = { qpropertyTpInit, /*tp_init */ 0, /*tp_alloc */ qpropertyTpNew, /*tp_new */ - qpropertyFree, /*tp_free */ + 0, /*tp_free */ 0, /*tp_is_gc */ 0, /*tp_bases */ 0, /*tp_mro */ @@ -208,23 +210,10 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds) } } -void qpropertyFree(void *self) +void qpropertyDeAlloc(PyObject* self) { - PyObject *pySelf = reinterpret_cast(self); - PySideProperty *data = reinterpret_cast(self); - PySidePropertyPrivate* pData = data->d; - - Py_XDECREF(pData->fget); - Py_XDECREF(pData->fset); - Py_XDECREF(pData->freset); - Py_XDECREF(pData->fdel); - Py_XDECREF(pData->notify); - - free(pData->typeName); - free(pData->doc); - free(pData->notifySignature); - delete data->d; - pySelf->ob_type->tp_base->tp_free(self); + qpropertyClear(self); + Py_TYPE(self)->tp_free(self); } PyObject* qPropertyCall(PyObject* self, PyObject* args, PyObject* kw) @@ -279,6 +268,41 @@ PyObject* qPropertyGetter(PyObject* self, PyObject* callback) } } +static int qpropertyTraverse(PyObject* self, visitproc visit, void* arg) +{ + PySidePropertyPrivate* data = reinterpret_cast(self)->d; + if (!data) + return 0; + + Py_VISIT(data->fget); + Py_VISIT(data->fset); + Py_VISIT(data->freset); + Py_VISIT(data->fdel); + Py_VISIT(data->notify); + return 0; +} + +static int qpropertyClear(PyObject* self) +{ + PySidePropertyPrivate* data = reinterpret_cast(self)->d; + if (!data) + return 0; + + Py_CLEAR(data->fget); + Py_CLEAR(data->fset); + Py_CLEAR(data->freset); + Py_CLEAR(data->fdel); + Py_CLEAR(data->notify); + + + free(data->typeName); + free(data->doc); + free(data->notifySignature); + delete data; + reinterpret_cast(self)->d = 0; + return 0; +} + } // extern "C" namespace { From 7b8d2925dd61e2cb1edc78bd10cdda2e8ef19bf2 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Tue, 13 Dec 2011 16:58:30 -0200 Subject: [PATCH 256/267] Small code style changes. --- libpyside/pysideqflags.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libpyside/pysideqflags.cpp b/libpyside/pysideqflags.cpp index 4fe24b8..39f8b04 100644 --- a/libpyside/pysideqflags.cpp +++ b/libpyside/pysideqflags.cpp @@ -39,7 +39,7 @@ extern "C" { #define PYSIDE_QFLAGS(X) reinterpret_cast(X) - PyObject* PySideQFlagsNew(PyTypeObject *type, PyObject *args, PyObject *kwds) + PyObject* PySideQFlagsNew(PyTypeObject* type, PyObject* args, PyObject* kwds) { long val = 0; if (PyTuple_GET_SIZE(args)) { @@ -61,13 +61,11 @@ extern "C" { static long getNumberValue(PyObject* v) { - PyObject* number = PyNumber_Long(v); - long result = PyLong_AsLong(number); - Py_XDECREF(number); - return result; + Shiboken::AutoDecRef number(PyNumber_Long(v)); + return PyLong_AsLong(number); } - PyObject* PySideQFlagsRichCompare(PyObject *self, PyObject *other, int op) + PyObject* PySideQFlagsRichCompare(PyObject* self, PyObject* other, int op) { int result = 0; if (!PyNumber_Check(other)) { From 65d8f9fcef98f8a80015cc5e0b7526224332e7ec Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Wed, 14 Dec 2011 14:14:18 -0300 Subject: [PATCH 257/267] Fixes the QSettings related QVariant's save/load bug. --- libpyside/signalmanager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index 4bcfae5..81ce14d 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -250,6 +250,8 @@ SignalManager::SignalManager() : m_d(new SignalManagerPrivate) // Register PyObject type to use in queued signal and slot connections qRegisterMetaType(PYTHON_TYPE); qRegisterMetaTypeStreamOperators(PYTHON_TYPE); + qRegisterMetaTypeStreamOperators("PyObjectWrapper"); + qRegisterMetaTypeStreamOperators("PySide::PyObjectWrapper"); SbkConverter* converter = Shiboken::Conversions::createConverter(&PyBaseObject_Type, 0); Shiboken::Conversions::setCppPointerToPythonFunction(converter, PyObject_PTR_CppToPython_PyObject); From 8ddbd3167bba33820b19de36c2dbac83e9e8f55d Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Thu, 15 Dec 2011 14:47:39 -0300 Subject: [PATCH 258/267] The temporary file used in the test for bug #829 must not be deleted by the test. This fixes the test in win32 platforms. --- tests/QtCore/bug_829.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/QtCore/bug_829.py b/tests/QtCore/bug_829.py index da527ad..945d8df 100644 --- a/tests/QtCore/bug_829.py +++ b/tests/QtCore/bug_829.py @@ -3,12 +3,11 @@ import unittest from PySide.QtCore import QSettings -from helper import adjust_filename import tempfile class QVariantConversions(unittest.TestCase): def testDictionary(self): - confFile = tempfile.NamedTemporaryFile() + confFile = tempfile.NamedTemporaryFile(delete=False) s = QSettings(confFile.name, QSettings.IniFormat) # Save value s.setValue('x', {1: 'a'}) From 481ba5aa3ef94b417211fd25f07f30575b5afa68 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Fri, 16 Dec 2011 18:10:45 -0300 Subject: [PATCH 259/267] Fix BUG #1084 - "Crash (segfault) when writing unicode string on socket" See http://bugs.pyside.org/show_bug.cgi?id=1084. Signed-off-by: Paulo Alcantara Reviewed-by: Trust me --- PySide/QtCore/typesystem_core_common.xml | 21 ++++++++------------- tests/QtNetwork/CMakeLists.txt | 1 + tests/QtNetwork/bug_1084.py | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 tests/QtNetwork/bug_1084.py diff --git a/PySide/QtCore/typesystem_core_common.xml b/PySide/QtCore/typesystem_core_common.xml index aa39e95..a2e1deb 100644 --- a/PySide/QtCore/typesystem_core_common.xml +++ b/PySide/QtCore/typesystem_core_common.xml @@ -2666,20 +2666,15 @@ - + - + - + - - - - %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1)); - %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); - - - + + + @@ -2688,7 +2683,7 @@ - + QByteArray ba; ba.resize(%2); @@ -2712,7 +2707,7 @@ - + QByteArray ba; ba.resize(%2); diff --git a/tests/QtNetwork/CMakeLists.txt b/tests/QtNetwork/CMakeLists.txt index 3077155..7476f91 100644 --- a/tests/QtNetwork/CMakeLists.txt +++ b/tests/QtNetwork/CMakeLists.txt @@ -1,4 +1,5 @@ PYSIDE_TEST(bug_446.py) +PYSIDE_TEST(bug_1084.py) PYSIDE_TEST(basic_auth_test.py) PYSIDE_TEST(accessManager_test.py) PYSIDE_TEST(http_test.py) diff --git a/tests/QtNetwork/bug_1084.py b/tests/QtNetwork/bug_1084.py new file mode 100644 index 0000000..9d8471c --- /dev/null +++ b/tests/QtNetwork/bug_1084.py @@ -0,0 +1,16 @@ +''' unit test for BUG #1084 ''' + +import unittest +from PySide import QtNetwork +import py3kcompat as py3k + +class QTcpSocketTestCase(unittest.TestCase): + def setUp(self): + self.sock = QtNetwork.QTcpSocket() + self.sock.connectToHost('127.0.0.1', 25) + + def testIt(self): + self.sock.write(py3k.unicode_('quit')) + +if __name__ == "__main__": + unittest.main() From b2b14fe9b70cb233b003425328ef1f4d8749c744 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Wed, 21 Dec 2011 14:57:32 -0300 Subject: [PATCH 260/267] Fix BUG #1091 - "PixmapFragment and drawPixmapFragments are not bound" See http://bugs.pyside.org/show_bug.cgi?id=1091. Also minor coding style fixes in QtGui's typesystem. Signed-off-by: Paulo Alcantara Reviewed-by: Marcelo Lira --- PySide/QtGui/CMakeLists.txt | 10 +- PySide/QtGui/typesystem_gui_common.xml | 149 +++++++++++++------------ tests/QtGui/CMakeLists.txt | 3 + tests/QtGui/bug_1091.py | 12 ++ 4 files changed, 100 insertions(+), 74 deletions(-) create mode 100644 tests/QtGui/bug_1091.py diff --git a/PySide/QtGui/CMakeLists.txt b/PySide/QtGui/CMakeLists.txt index 6023a32..7625634 100644 --- a/PySide/QtGui/CMakeLists.txt +++ b/PySide/QtGui/CMakeLists.txt @@ -15,7 +15,6 @@ if(ENABLE_X11) endif() endif() - if (${QT_VERSION_MAJOR} EQUAL 4 AND ${QT_VERSION_MINOR} LESS 6) set(QtGui_46_SRC "") else() @@ -60,6 +59,14 @@ else() ) endif () +if (${QT_VERSION_MAJOR} EQUAL 4 AND ${QT_VERSION_MINOR} LESS 7) + set(QtGui_47_SRC "") +else() + set(QtGui_47_SRC + ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtGui/qpainter_pixmapfragment_wrapper.cpp + ) +endif() + set(QtGui_OPTIONAL_SRC ) set(QtGui_DROPPED_ENTRIES ) check_qt_class(QtGui QAbstractPageSetupDialog QtGui_OPTIONAL_SRC QtGui_DROPPED_ENTRIES) @@ -398,6 +405,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/PySide/QtGui/qworkspace_wrapper.cpp ${SPECIFIC_OS_FILES} ${QPYTEXTOBJECT_MOC} ${QtGui_46_SRC} +${QtGui_47_SRC} ${QtGui_OPTIONAL_SRC} ) diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml index e9058b5..552636a 100644 --- a/PySide/QtGui/typesystem_gui_common.xml +++ b/PySide/QtGui/typesystem_gui_common.xml @@ -3470,7 +3470,7 @@ - + @@ -3479,7 +3479,7 @@ - + @@ -3488,7 +3488,7 @@ - + @@ -3497,7 +3497,7 @@ - + @@ -3506,7 +3506,7 @@ - + @@ -3604,24 +3604,24 @@ - + - + - + - + @@ -3632,38 +3632,38 @@ - + - + - + - + - + - + - + @@ -3759,7 +3759,7 @@ - + @@ -3821,17 +3821,17 @@ - + - + - + @@ -3868,17 +3868,17 @@ - + - + - + @@ -3893,17 +3893,17 @@ - + - + - + @@ -3913,12 +3913,12 @@ - + - + @@ -3994,12 +3994,12 @@ - + - + @@ -4247,7 +4247,7 @@ - + @@ -4529,7 +4529,7 @@ - + @@ -4540,7 +4540,7 @@ - + @@ -4555,7 +4555,7 @@ - + @@ -4731,29 +4731,29 @@ - + - + - + - + - + // Clear parent from the old child QStandardItem* _i = %CPPSELF->item(%1, %2); @@ -4766,7 +4766,7 @@ - + // Clear parent from the old child QStandardItem* _i = %CPPSELF->item(%1); @@ -4779,13 +4779,13 @@ - + - + // Clear parent from the old child QStandardItem* _i = %CPPSELF->verticalHeaderItem(%1); @@ -4817,19 +4817,19 @@ - + - + - + @@ -5086,18 +5086,18 @@ - + - + - + @@ -5200,13 +5200,13 @@ - + - + @@ -5258,12 +5258,12 @@ Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0, "connect", "OsO", %PYARG_0, SIGNAL(triggered()), %PYARG_2)); - + - + @@ -5425,9 +5425,12 @@ + + + - + - + - + - - - - - - + + + + + + - + - + - + %BEGIN_ALLOW_THREADS @@ -5475,7 +5478,7 @@ %END_ALLOW_THREADS - + %BEGIN_ALLOW_THREADS @@ -5483,13 +5486,13 @@ %END_ALLOW_THREADS - + - + @@ -5503,32 +5506,32 @@ - + - + - + - + - + - + diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 1d95576..9bac913 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -164,6 +164,9 @@ PYSIDE_TEST(virtual_protected_inheritance_test.py) PYSIDE_TEST(virtual_pure_override_test.py) PYSIDE_TEST(wrong_return_test.py) +if (${QTVERSION} VERSION_GREATER 4.6.9) + PYSIDE_TEST(bug_1091.py) +endif() if(Q_WS_X11) PYSIDE_TEST(x11_symbols_test.py) diff --git a/tests/QtGui/bug_1091.py b/tests/QtGui/bug_1091.py new file mode 100644 index 0000000..b58d26f --- /dev/null +++ b/tests/QtGui/bug_1091.py @@ -0,0 +1,12 @@ +''' unit test for BUG #1091 ''' + +import unittest +from PySide import QtGui + +class QPainterTestCase(unittest.TestCase): + def testIt(self): + self.assertTrue("PixmapFragment" in dir(QtGui.QPainter)) + self.assertTrue("drawPixmapFragments" in dir(QtGui.QPainter)) + +if __name__ == "__main__": + unittest.main() From 98be0df6a55b45538d107421fd557fb77f8ab92b Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Wed, 21 Dec 2011 18:51:34 -0300 Subject: [PATCH 261/267] Fix BUG #1060 - "Subclassing of QUiLoader leads to "Internal C++ object already deleted" exception" See http://bugs.pyside.org/show_bug.cgi?id=1060. Signed-off-by: Paulo Alcantara Reviewed-by: Marcelo Lira --- PySide/QtUiTools/typesystem_uitools.xml | 11 ++++++----- tests/QtUiTools/CMakeLists.txt | 1 + tests/QtUiTools/bug_1060.py | 18 ++++++++++++++++++ tests/QtUiTools/bug_1060.ui | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 tests/QtUiTools/bug_1060.py create mode 100644 tests/QtUiTools/bug_1060.ui diff --git a/PySide/QtUiTools/typesystem_uitools.xml b/PySide/QtUiTools/typesystem_uitools.xml index c86ae44..08e98bd 100644 --- a/PySide/QtUiTools/typesystem_uitools.xml +++ b/PySide/QtUiTools/typesystem_uitools.xml @@ -70,27 +70,28 @@ %CPPSELF.addPluginPath(""); // force reload widgets - + - + - + - + - + + diff --git a/tests/QtUiTools/CMakeLists.txt b/tests/QtUiTools/CMakeLists.txt index eecf3df..68ed7f1 100644 --- a/tests/QtUiTools/CMakeLists.txt +++ b/tests/QtUiTools/CMakeLists.txt @@ -8,5 +8,6 @@ PYSIDE_TEST(bug_909.py) PYSIDE_TEST(bug_913.py) PYSIDE_TEST(bug_958.py) PYSIDE_TEST(bug_965.py) +PYSIDE_TEST(bug_1060.py) PYSIDE_TEST(uiloader_test.py) PYSIDE_TEST(ui_test.py) diff --git a/tests/QtUiTools/bug_1060.py b/tests/QtUiTools/bug_1060.py new file mode 100644 index 0000000..8b51501 --- /dev/null +++ b/tests/QtUiTools/bug_1060.py @@ -0,0 +1,18 @@ +''' unit test for BUG #1060 ''' + +from PySide.QtGui import QApplication +from PySide.QtUiTools import QUiLoader +from helper import adjust_filename + +class MyQUiLoader(QUiLoader): + def __init__(self): + super(MyQUiLoader, self).__init__() + + def createWidget(self, *args): + return super(MyQUiLoader, self).createWidget(*args) + +if __name__ == "__main__": + app = QApplication([]) + + ui = MyQUiLoader().load(adjust_filename("bug_1060.ui", __file__)) + ui.show() diff --git a/tests/QtUiTools/bug_1060.ui b/tests/QtUiTools/bug_1060.ui new file mode 100644 index 0000000..f4044a8 --- /dev/null +++ b/tests/QtUiTools/bug_1060.ui @@ -0,0 +1,19 @@ + + + Dialog + + + + 0 + 0 + 100 + 100 + + + + Dialog + + + + + From a8a07b77f8a781764eef62eb05bfeac864368cad Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Thu, 22 Dec 2011 21:49:08 -0300 Subject: [PATCH 262/267] Declares Python types using the new "" tag. Reviewed by Hugo Parente Reviewed by Paulo Alcantara --- PySide/QtCore/typesystem_core_common.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/PySide/QtCore/typesystem_core_common.xml b/PySide/QtCore/typesystem_core_common.xml index a2e1deb..8955612 100644 --- a/PySide/QtCore/typesystem_core_common.xml +++ b/PySide/QtCore/typesystem_core_common.xml @@ -21,6 +21,16 @@ + + + + + + + + + + From afc9a7e10b8fd1816b99628de5be3e84032fca03 Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Fri, 30 Dec 2011 15:30:29 -0300 Subject: [PATCH 263/267] Version bump to 1.1.0. --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 03f9db8..0151eea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,8 @@ project(pysidebindings) cmake_minimum_required(VERSION 2.6) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Macros/ ${CMAKE_MODULE_PATH}) -find_package(GeneratorRunner 0.6.15 REQUIRED) -find_package(Shiboken 1.0.10 REQUIRED) +find_package(GeneratorRunner 0.6.16 REQUIRED) +find_package(Shiboken 1.1.0 REQUIRED) find_package(Qt4 4.5.0 REQUIRED) find_file(GL_H "gl.h" PATH_SUFFIXES "GL") include(FindQt4Extra) @@ -62,8 +62,8 @@ endif() set(BINDING_NAME PySide) set(BINDING_API_MAJOR_VERSION "1") -set(BINDING_API_MINOR_VERSION "0") -set(BINDING_API_MICRO_VERSION "9") +set(BINDING_API_MINOR_VERSION "1") +set(BINDING_API_MICRO_VERSION "0") set(BINDING_API_RELEASE_LEVEL "final") # alpha, beta, rc, or final set(BINDING_API_SERIAL 1) # leave as 0 when release level is final set(BINDING_API_VERSION "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}" CACHE STRING "PySide version" FORCE) From d30a8672c3db038886273d194f5bcdcb19cc29bd Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Fri, 30 Dec 2011 15:31:11 -0300 Subject: [PATCH 264/267] Version bump to 1.1.1. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0151eea..696b4e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,7 @@ endif() set(BINDING_NAME PySide) set(BINDING_API_MAJOR_VERSION "1") set(BINDING_API_MINOR_VERSION "1") -set(BINDING_API_MICRO_VERSION "0") +set(BINDING_API_MICRO_VERSION "1") set(BINDING_API_RELEASE_LEVEL "final") # alpha, beta, rc, or final set(BINDING_API_SERIAL 1) # leave as 0 when release level is final set(BINDING_API_VERSION "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}" CACHE STRING "PySide version" FORCE) From db6f1e3306e626b871d6ed1a971638d106648b51 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Tue, 13 Mar 2012 14:26:42 -0300 Subject: [PATCH 265/267] Fix PySide compilation. Change-Id: Ie7a30961232526af59cbc21dbf1b58ab9a4e3e7b Reviewed-by: Hugo Parente Lima --- CMakeLists.txt | 3 +-- cmake/Macros/PySideModules.cmake | 2 +- doc/CMakeLists.txt | 2 +- tests/pysidetest/CMakeLists.txt | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 696b4e3..a7ffbd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,7 @@ project(pysidebindings) cmake_minimum_required(VERSION 2.6) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Macros/ ${CMAKE_MODULE_PATH}) -find_package(GeneratorRunner 0.6.16 REQUIRED) -find_package(Shiboken 1.1.0 REQUIRED) +find_package(Shiboken 1.1.1 REQUIRED) find_package(Qt4 4.5.0 REQUIRED) find_file(GL_H "gl.h" PATH_SUFFIXES "GL") include(FindQt4Extra) diff --git a/cmake/Macros/PySideModules.cmake b/cmake/Macros/PySideModules.cmake index 9eabd56..4877b12 100644 --- a/cmake/Macros/PySideModules.cmake +++ b/cmake/Macros/PySideModules.cmake @@ -20,7 +20,7 @@ macro(create_pyside_module module_name module_include_dir module_libraries modul endif() add_custom_command(OUTPUT ${${module_sources}} - COMMAND ${GENERATORRUNNER_BINARY} ${GENERATOR_EXTRA_FLAGS} + COMMAND ${SHIBOKEN_BINARY} ${GENERATOR_EXTRA_FLAGS} ${pyside_BINARY_DIR}/pyside_global.h --include-paths=${pyside_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR} --typesystem-paths=${pyside_SOURCE_DIR}${PATH_SEP}${${module_typesystem_path}} diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 61eeb09..967c289 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -23,7 +23,7 @@ configure_file("conf.py.in" "rst/conf.py" @ONLY) configure_file(typesystem_doc.xml.in typesystem_doc.xml @ONLY) add_custom_target("docrsts" - COMMAND ${GENERATORRUNNER_BINARY} --generator-set=qtdoc + COMMAND ${SHIBOKEN_BINARY} --generator-set=qtdoc ${pyside_BINARY_DIR}/pyside_global.h --include-paths="${QT_INCLUDE_DIR}${PATH_SEP}${pyside_SOURCE_DIR}" --api-version=${SUPPORTED_QT_VERSION} diff --git a/tests/pysidetest/CMakeLists.txt b/tests/pysidetest/CMakeLists.txt index 01d61f7..78c6f95 100644 --- a/tests/pysidetest/CMakeLists.txt +++ b/tests/pysidetest/CMakeLists.txt @@ -34,7 +34,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/testbinding/testbinding_module_wrapper.cpp ) add_custom_command(OUTPUT ${testbinding_SRC} -COMMAND ${GENERATORRUNNER_BINARY} ${GENERATOR_EXTRA_FLAGS} +COMMAND ${SHIBOKEN_BINARY} ${GENERATOR_EXTRA_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/pysidetest_global.h --include-paths=${pyside_BINARY_DIR}${PATH_SEP}${CMAKE_CURRENT_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR}${PATH_SEP}${QT_QTCORE_INCLUDE_DIR}${PATH_SEP}${QT_QTGUI_INCLUDE_DIR} --typesystem-paths=${CMAKE_CURRENT_SOURCE_DIR}${PATH_SEP}${pyside_SOURCE_DIR}${PATH_SEP}${QtCore_SOURCE_DIR}${PATH_SEP}${QtCore_BINARY_DIR}${PATH_SEP}${QtGui_SOURCE_DIR}${PATH_SEP}${QtGui_BINARY_DIR} From fe8dc36f90fe64590f7f13843a076f8d2d61f378 Mon Sep 17 00:00:00 2001 From: Juhapekka Piiroinen Date: Tue, 6 Mar 2012 13:57:16 +0200 Subject: [PATCH 266/267] Fix bug PYSIDE-6 This should resolve the issue in PYSIDE-6 "Fix phonon VideoCaptureDevice detection to properly use phonon_ namespace". Changed if check in PySideModules.cmake. Change-Id: Ie30d6858a0fc6073560ec4cd09508504cbeb667d Reviewed-by: Hugo Parente Lima --- cmake/Macros/PySideModules.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Macros/PySideModules.cmake b/cmake/Macros/PySideModules.cmake index 4877b12..2fe6cd1 100644 --- a/cmake/Macros/PySideModules.cmake +++ b/cmake/Macros/PySideModules.cmake @@ -71,7 +71,7 @@ macro(check_qt_class module class optional_source_files dropped_entries) endif () string(TOLOWER ${class} _class) string(TOUPPER ${module} _module) - if (${namespace}) + if (_namespace) set(_cppfile ${CMAKE_CURRENT_BINARY_DIR}/PySide/${module}/${_namespace}_${_class}_wrapper.cpp) else () set(_cppfile ${CMAKE_CURRENT_BINARY_DIR}/PySide/${module}/${_class}_wrapper.cpp) From f011ce2cb9e2b93a748874de007232ec88cc8ac1 Mon Sep 17 00:00:00 2001 From: Juhapekka Piiroinen Date: Mon, 5 Mar 2012 07:59:41 +0200 Subject: [PATCH 267/267] Bug fix for PYSIDE-7 This should resolve the issue in PYSIDE-7 "QDateTime does not support the 6-argument format". Added function signature for 6-argument version and a testcase. Change-Id: I617eefab6a41939c37e2f1bf800857bc2d74b6ee Reviewed-by: Hugo Parente Lima --- PySide/QtCore/typesystem_core_common.xml | 7 +++++++ tests/QtCore/python_conversion.py | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/PySide/QtCore/typesystem_core_common.xml b/PySide/QtCore/typesystem_core_common.xml index 8955612..2e83131 100644 --- a/PySide/QtCore/typesystem_core_common.xml +++ b/PySide/QtCore/typesystem_core_common.xml @@ -1257,6 +1257,13 @@ %0 = new %TYPE(date, time, Qt::TimeSpec(%8)); + + + QDate date(%1, %2, %3); + QTime time(%4, %5, %6); + %0 = new %TYPE(date, time); + + diff --git a/tests/QtCore/python_conversion.py b/tests/QtCore/python_conversion.py index 2472dee..84845c0 100644 --- a/tests/QtCore/python_conversion.py +++ b/tests/QtCore/python_conversion.py @@ -43,5 +43,22 @@ class TestDateTimeConversions (unittest.TestCase): self.assertEqual(dateTime, other.toPython()) + def testQDateTime6arg(self): + dateTime = datetime.datetime(2010, 4, 23, 11, 14, 7) + other = QDateTime(dateTime) + + otherDate = other.date() + self.assertEqual(dateTime.year, otherDate.year()) + self.assertEqual(dateTime.month, otherDate.month()) + self.assertEqual(dateTime.day, otherDate.day()) + + otherTime = other.time() + self.assertEqual(dateTime.hour, otherTime.hour()) + self.assertEqual(dateTime.minute, otherTime.minute()) + self.assertEqual(dateTime.second, otherTime.second()) + self.assertEqual(dateTime.microsecond/1000, otherTime.msec()) + + self.assertEqual(dateTime, other.toPython()) + if __name__ == '__main__': unittest.main()