aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--PySide/QtDeclarative/typesystem_declarative.xml9
-rw-r--r--PySide/QtGui/glue/qlayout_help_functions.h2
-rw-r--r--PySide/QtGui/typesystem_gui_common.xml2
-rw-r--r--doc/codesnippets/doc/src/snippets/network/tcpwait.cpp7
-rw-r--r--libpyside/dynamicqmetaobject.cpp47
-rw-r--r--libpyside/dynamicqmetaobject_p.h6
-rw-r--r--libpyside/globalreceiver.cpp9
-rw-r--r--libpyside/pyside.cpp11
-rw-r--r--libpyside/pysideproperty.cpp13
-rw-r--r--tests/QtCore/qobject_property_test.py16
-rw-r--r--tests/QtGui/CMakeLists.txt2
-rw-r--r--tests/QtGui/bug_467.py19
-rw-r--r--tests/QtGui/bug_480.py25
-rw-r--r--tests/QtNetwork/CMakeLists.txt2
-rw-r--r--tests/QtNetwork/bug_446.py48
15 files changed, 176 insertions, 42 deletions
diff --git a/PySide/QtDeclarative/typesystem_declarative.xml b/PySide/QtDeclarative/typesystem_declarative.xml
index c672a8c78..75c63e093 100644
--- a/PySide/QtDeclarative/typesystem_declarative.xml
+++ b/PySide/QtDeclarative/typesystem_declarative.xml
@@ -37,7 +37,14 @@
<object-type name="QDeclarativeComponent">
<enum-type name="Status"/>
</object-type>
- <object-type name="QDeclarativeContext" />
+ <object-type name="QDeclarativeContext">
+ <modify-function signature="setContextProperty(const QString &amp;, QObject*)">
+ <modify-argument index="2">
+ <reference-count action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
<object-type name="QDeclarativeEngine">
<enum-type name="ObjectOwnership" />
<modify-function signature="setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory*)">
diff --git a/PySide/QtGui/glue/qlayout_help_functions.h b/PySide/QtGui/glue/qlayout_help_functions.h
index b0e8a0e5d..8420cb3ac 100644
--- a/PySide/QtGui/glue/qlayout_help_functions.h
+++ b/PySide/QtGui/glue/qlayout_help_functions.h
@@ -39,7 +39,7 @@ inline void addLayoutOwnership(QLayout* layout, QLayout* other)
}
for (int i=0, i_max=other->count(); i < i_max; i++) {
- QLayoutItem* item = layout->itemAt(i);
+ QLayoutItem* item = other->itemAt(i);
if (PyErr_Occurred())
return;
diff --git a/PySide/QtGui/typesystem_gui_common.xml b/PySide/QtGui/typesystem_gui_common.xml
index a5f22d835..cf4b6744c 100644
--- a/PySide/QtGui/typesystem_gui_common.xml
+++ b/PySide/QtGui/typesystem_gui_common.xml
@@ -2110,7 +2110,7 @@
<enum-type name="MessageIcon"/>
<modify-function signature="setContextMenu(QMenu*)">
<modify-argument index="1">
- <parent index="this" action="add"/>
+ <reference-count action="add"/>
</modify-argument>
</modify-function>
</object-type>
diff --git a/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp b/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp
index 7ebdc692d..0712b3e5d 100644
--- a/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp
+++ b/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp
@@ -51,13 +51,12 @@ def main():
//! [0]
numRead = 0
numReadTotal = 0
- buffer = ""
while(True):
- numRead = socket.read(buffer, 50)
+ buffer = socket.read(50)
# do whatever with array
- numReadTotal += numRead
- if (numRead == 0 && !socket.waitForReadyRead()):
+ numReadTotal += buffer.size()
+ if (buffer.size() == 0 && !socket.waitForReadyRead()):
break
//! [0]
return app.exec_()
diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp
index 14fbe864e..43aeae66d 100644
--- a/libpyside/dynamicqmetaobject.cpp
+++ b/libpyside/dynamicqmetaobject.cpp
@@ -132,7 +132,6 @@ static bool isQRealType(const char *type)
}
-
/*
* Avoid API break keep this on cpp
*/
@@ -164,25 +163,31 @@ uint PropertyData::flags() const
if (PySide::Property::hasReset(m_data))
flags |= Resettable;
- if (!PySide::Property::isDesignable(m_data))
- flags |= ResolveDesignable;
- else
+ if (PySide::Property::isDesignable(m_data))
flags |= Designable;
-
- if (!PySide::Property::isScriptable(m_data))
- flags |= ResolveScriptable;
else
- flags |= Scriptable;
+ flags |= ResolveDesignable;
- if (!PySide::Property::isStored(m_data))
- flags |= ResolveStored;
+ if (PySide::Property::isScriptable(m_data))
+ flags |= Scriptable;
else
- flags |= Stored;
+ flags |= ResolveScriptable;
- if (!PySide::Property::isUser(m_data))
- flags |= ResolveUser;
+ if (PySide::Property::isStored(m_data))
+ flags |= Stored;
else
+ flags |= ResolveStored;
+
+ //EDITABLE
+ flags |= ResolveEditable;
+
+ if (PySide::Property::isUser(m_data))
flags |= User;
+ else
+ flags |= ResolveUser;
+
+ if (m_notifyId != -1)
+ flags |= Notify;
if (PySide::Property::isConstant(m_data))
flags |= Constant;
@@ -190,9 +195,6 @@ uint PropertyData::flags() const
if (PySide::Property::isFinal(m_data))
flags |= Final;
- if (m_notifyId)
- flags |= Notify;
-
return flags;
}
@@ -247,7 +249,7 @@ PropertyData::PropertyData()
{
}
-PropertyData::PropertyData(const char* name, uint notifyId, PySideProperty* data)
+PropertyData::PropertyData(const char* name, int notifyId, PySideProperty* data)
: m_name(name), m_notifyId(notifyId), m_data(data)
{
}
@@ -268,7 +270,7 @@ QByteArray PropertyData::name() const
return m_name;
}
-uint PropertyData::notifyId() const
+int PropertyData::notifyId() const
{
return m_notifyId;
}
@@ -370,10 +372,10 @@ void DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data)
// retrieve notifyId
PySideProperty* property = reinterpret_cast<PySideProperty*>(data);
const char* signalNotify = PySide::Property::getNotifyName(property);
- uint notifyId = 0;
+ int notifyId = -1;
if (signalNotify) {
QByteArray signalSignature(signalNotify);
- notifyId = m_d->m_signals.indexOf(signalNotify) + 1;
+ notifyId = m_d->m_signals.indexOf(signalNotify);
}
//search for a empty space
@@ -553,9 +555,8 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject
}
//write properties notify
- foreach(PropertyData pp, m_properties) {
- data[index++] = pp.notifyId(); //signal notify index
- }
+ foreach(PropertyData pp, m_properties)
+ data[index++] = pp.notifyId() >= 0 ? pp.notifyId() : 0; //signal notify index
data[index++] = 0; // the end
diff --git a/libpyside/dynamicqmetaobject_p.h b/libpyside/dynamicqmetaobject_p.h
index d2717524e..e69270041 100644
--- a/libpyside/dynamicqmetaobject_p.h
+++ b/libpyside/dynamicqmetaobject_p.h
@@ -54,18 +54,18 @@ namespace PySide
{
public:
PropertyData();
- PropertyData(const char* name, uint notifyId=0, PySideProperty* data = 0);
+ PropertyData(const char* name, int notifyId=0, PySideProperty* data = 0);
QByteArray name() const;
QByteArray type() const;
uint flags() const;
bool isValid() const;
- uint notifyId() const;
+ int notifyId() const;
bool operator==(const PropertyData& other) const;
bool operator==(const char* name) const;
private:
QByteArray m_name;
- uint m_notifyId;
+ int m_notifyId;
PySideProperty* m_data;
};
}
diff --git a/libpyside/globalreceiver.cpp b/libpyside/globalreceiver.cpp
index 2c126044e..d63ebdf66 100644
--- a/libpyside/globalreceiver.cpp
+++ b/libpyside/globalreceiver.cpp
@@ -116,7 +116,8 @@ GlobalReceiver::GlobalReceiver()
GlobalReceiver::~GlobalReceiver()
{
- foreach(DynamicSlotData* data, m_slotReceivers) {
+ while(!m_slotReceivers.empty()) {
+ DynamicSlotData* data = m_slotReceivers.take(m_slotReceivers.begin().key());
data->clear();
delete data;
}
@@ -203,8 +204,10 @@ int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
if (strcmp(slot.signature(), RECEIVER_DESTROYED_SLOT_NAME) == 0) {
QObject *arg = *(QObject**)args[1];
- QHash<int, DynamicSlotData*>::iterator i = m_slotReceivers.begin();
- while(i != m_slotReceivers.end()) {
+ //avoid hash changes during the destruction
+ QHash<int, DynamicSlotData*> copy = m_slotReceivers;
+ QHash<int, DynamicSlotData*>::iterator i = copy.begin();
+ while(i != copy.end()) {
if (i.value()->hasRefTo(arg)) {
disconnectNotify(arg, i.key());
break;
diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp
index 2e2f57428..bbec1fa63 100644
--- a/libpyside/pyside.cpp
+++ b/libpyside/pyside.cpp
@@ -114,12 +114,21 @@ void destroyQCoreApplication()
PyTypeObject* pyQObjectType = Shiboken::TypeResolver::get("QObject*")->pythonType();
assert(pyQObjectType);
+ QList<SbkObject*> objects;
+
+ //filter only QObjects which we have ownership, this will avoid list changes during the destruction of some parent object
foreach (SbkObject* pyObj, bm.getAllPyObjects()) {
if (pyObj != pyQApp && PyObject_TypeCheck(pyObj, pyQObjectType)) {
if (Shiboken::Object::hasOwnership(pyObj))
- Shiboken::callCppDestructor<QObject>(Shiboken::Object::cppPointer(pyObj, Shiboken::SbkType<QObject*>()));
+ objects << pyObj;
}
}
+
+ //Now we can destroy all object in the list
+ foreach (SbkObject* pyObj, objects)
+ Shiboken::callCppDestructor<QObject>(Shiboken::Object::cppPointer(pyObj, Shiboken::SbkType<QObject*>()));
+
+ // in the end destroy app
delete app;
}
diff --git a/libpyside/pysideproperty.cpp b/libpyside/pysideproperty.cpp
index 51f848d67..72b718c58 100644
--- a/libpyside/pysideproperty.cpp
+++ b/libpyside/pysideproperty.cpp
@@ -117,6 +117,7 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
pData->fget = 0;
pData->freset = 0;
pData->fdel = 0;
+ pData->final = 0;
pData->designable = true;
pData->scriptable = true;
pData->stored = true;
@@ -124,6 +125,7 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
pData->doc = 0;
pData->notify = 0;
pData->notifySignature = 0;
+ pData->constant = 0;
static const char *kwlist[] = {"type", "fget", "fset", "freset", "fdel", "doc", "notify",
"designable", "scriptable", "stored", "user",
@@ -134,12 +136,17 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
/*OOO*/ &(pData->fset), &(pData->freset), &(pData->fdel),
/*s*/ &(pData->doc),
/*O*/ &(pData->notify),
- /*bbbbbb*/ &(pData->designable), &(pData->scriptable), &(pData->stored), &(pData->user), &(pData->constant), &(pData->final)))
+ /*bbbbbb*/ &(pData->designable), &(pData->scriptable), &(pData->stored), &(pData->user), &(pData->constant), &(pData->final))) {
+ free(pData);
return 0;
+ }
- if (!pData->fset && pData->fget)
- pData->constant = true;
+ if (pData->constant && (pData->fset || pData->notify)) {
+ free(pData);
+ PyErr_SetString(PyExc_AttributeError, "A constant property cannot have a WRITE method or a NOTIFY signal.");
+ return 0;
+ }
pData->typeName = PySide::Signal::getTypeName(type);
return 1;
}
diff --git a/tests/QtCore/qobject_property_test.py b/tests/QtCore/qobject_property_test.py
index adb1679f3..bc38dbb18 100644
--- a/tests/QtCore/qobject_property_test.py
+++ b/tests/QtCore/qobject_property_test.py
@@ -34,7 +34,7 @@ class MyObject(QObject):
def trySetPP(self):
self.pp = 0
- pp = Property(int, readPP)
+ pp = Property(int, readPP, constant=True)
class MyObjectWithNotifyProperty(QObject):
def __init__(self, parent=None):
@@ -188,6 +188,20 @@ class PropertyWithNotify(unittest.TestCase):
obj.myProperty = 10
self.assert_(self.called_)
+class MetaPropertyTest(unittest.TestCase):
+ def testConstant(self):
+ obj = MyObject()
+ mo = obj.metaObject()
+ self.assertEqual(mo.propertyCount(), 2)
+ p = mo.property(1)
+ self.assertTrue(p.isConstant())
+
+ obj = MyObjectWithNotifyProperty()
+ mo = obj.metaObject()
+ self.assertEqual(mo.propertyCount(), 2)
+ p = mo.property(1)
+ self.assertFalse(p.isConstant())
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt
index 9086829f8..2ad8269a9 100644
--- a/tests/QtGui/CMakeLists.txt
+++ b/tests/QtGui/CMakeLists.txt
@@ -16,6 +16,8 @@ PYSIDE_TEST(bug_416.py)
PYSIDE_TEST(bug_429.py)
PYSIDE_TEST(bug_430.py)
PYSIDE_TEST(bug_433.py)
+PYSIDE_TEST(bug_467.py)
+PYSIDE_TEST(bug_480.py)
PYSIDE_TEST(customproxywidget_test.py)
PYSIDE_TEST(deepcopy_test.py)
PYSIDE_TEST(float_to_int_implicit_conversion_test.py)
diff --git a/tests/QtGui/bug_467.py b/tests/QtGui/bug_467.py
new file mode 100644
index 000000000..5c5af4b20
--- /dev/null
+++ b/tests/QtGui/bug_467.py
@@ -0,0 +1,19 @@
+''' Test bug 367: http://bugs.openbossa.org/show_bug.cgi?id=467'''
+
+import unittest
+from helper import UsesQApplication
+from PySide.QtGui import QMainWindow, QApplication
+
+class MyWidget(QMainWindow):
+ def __init__(self, parent = None):
+ QMainWindow.__init__(self, parent)
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ w = MyWidget()
+ widgets = QApplication.allWidgets()
+ self.assert_(w in widgets)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/QtGui/bug_480.py b/tests/QtGui/bug_480.py
new file mode 100644
index 000000000..bb28f3661
--- /dev/null
+++ b/tests/QtGui/bug_480.py
@@ -0,0 +1,25 @@
+import unittest
+
+from PySide import QtGui
+
+class BuggyWidget(QtGui.QWidget):
+ def setup(self):
+ self.verticalLayout = QtGui.QVBoxLayout(self)
+ self.gridLayout = QtGui.QGridLayout()
+ self.lbl = QtGui.QLabel(self)
+ self.gridLayout.addWidget(self.lbl, 0, 1, 1, 1)
+
+ # this cause a segfault during the ownership transfer
+ self.verticalLayout.addLayout(self.gridLayout)
+
+class LayoutTransferOwnerShip(unittest.TestCase):
+ def testBug(self):
+ app = QtGui.QApplication([])
+ w = BuggyWidget()
+ w.setup()
+ w.show()
+ self.assert_(True)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/QtNetwork/CMakeLists.txt b/tests/QtNetwork/CMakeLists.txt
index 0eb503714..9b0be3abf 100644
--- a/tests/QtNetwork/CMakeLists.txt
+++ b/tests/QtNetwork/CMakeLists.txt
@@ -1,4 +1,4 @@
-
+PYSIDE_TEST(bug_446.py)
PYSIDE_TEST(basic_auth_test.py)
PYSIDE_TEST(accessManager_test.py)
PYSIDE_TEST(http_test.py)
diff --git a/tests/QtNetwork/bug_446.py b/tests/QtNetwork/bug_446.py
new file mode 100644
index 000000000..d3a9d0986
--- /dev/null
+++ b/tests/QtNetwork/bug_446.py
@@ -0,0 +1,48 @@
+import unittest
+
+from PySide.QtCore import *
+from PySide.QtNetwork import *
+
+from helper import UsesQCoreApplication
+
+class HttpSignalsCase(UsesQCoreApplication):
+ '''Test case for launching QHttp signals'''
+ DATA = "PySide rocks"
+
+ def onError(self):
+ self.assert_(False)
+
+ def onNewConnection(self):
+ self.serverConnection = self.server.nextPendingConnection()
+ self.serverConnection.error.connect(self.onError)
+ self.serverConnection.write(HttpSignalsCase.DATA)
+ self.server.close()
+
+ def onReadReady(self):
+ data = self.client.read(100)
+ self.assertEqual(data.size(), len(HttpSignalsCase.DATA))
+ self.assertEqual(data, HttpSignalsCase.DATA)
+ self.done()
+
+ def onClientConnect(self):
+ self.client.readyRead.connect(self.onReadReady)
+
+ def initServer(self):
+ self.server = QTcpServer()
+ self.server.newConnection.connect(self.onNewConnection)
+ self.assert_(self.server.listen())
+ self.client = QTcpSocket()
+ self.client.connected.connect(self.onClientConnect)
+ self.client.connectToHost(QHostAddress(QHostAddress.LocalHost), self.server.serverPort())
+
+ def done(self):
+ self.serverConnection.close()
+ self.client.close()
+ self.app.quit()
+
+ def testRun(self):
+ self.initServer()
+ self.app.exec_()
+
+if __name__ == '__main__':
+ unittest.main()