Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/pya/pya/pyaMarshal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class PythonBasedVariantAdaptor

virtual tl::Variant var () const;
virtual void set (const tl::Variant &v, tl::Heap & /*heap*/);
const PythonPtr &ptr () const { return m_var; }

private:
PythonPtr m_var;
Expand Down Expand Up @@ -641,7 +642,7 @@ struct reader<gsi::ByteArrayType>
};

static
PyObject *object_from_variant (tl::Variant &var, PYAObjectBase *self, const gsi::ArgType &atype)
PyObject *object_from_variant (tl::Variant &var, PYAObjectBase *self, const gsi::ArgType &atype, bool transfer = false)
{
if (var.is_user()) {

Expand All @@ -657,7 +658,7 @@ PyObject *object_from_variant (tl::Variant &var, PYAObjectBase *self, const gsi:
void *obj = var.to_user ();
const gsi::ClassBase *cls = var.user_cls ()->gsi_cls ();

if (pass_obj) {
if (pass_obj || transfer) {

if (holder) {

Expand Down Expand Up @@ -711,12 +712,17 @@ struct reader<gsi::VariantType>
*ret = PythonRef (Py_None, false /*borrowed*/);
} else {
gsi::VariantAdaptorImpl<tl::Variant> *aa = dynamic_cast<gsi::VariantAdaptorImpl<tl::Variant> *> (a.get ());
PythonBasedVariantAdaptor *pa = dynamic_cast<PythonBasedVariantAdaptor *> (a.get ());
if (aa) {
// A small optimization that saves one variant copy
*ret = object_from_variant (aa->var_ref_nc (), self, atype);
} else if (pa) {
// Optimization for Python to Python transfer
*ret = pa->ptr ();
} else {
tl::Variant v = a->var ();
*ret = object_from_variant (v, self, atype);
// NOTE: as v may hold the object, we need to transfer ownership
*ret = object_from_variant (v, self, atype, true);
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/rba/rba/rbaMarshal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class RubyBasedVariantAdaptor

virtual tl::Variant var () const;
virtual void set (const tl::Variant &v, tl::Heap &heap);
VALUE value () const { return m_var; }

private:
VALUE m_var;
Expand Down Expand Up @@ -662,7 +663,7 @@ struct reader<gsi::ByteArrayType>
}
};

static VALUE object_from_variant (tl::Variant &var, Proxy *self, const gsi::ArgType &atype)
static VALUE object_from_variant (tl::Variant &var, Proxy *self, const gsi::ArgType &atype, bool transfer = false)
{
if (var.is_user()) {

Expand All @@ -678,7 +679,7 @@ static VALUE object_from_variant (tl::Variant &var, Proxy *self, const gsi::ArgT
void *obj = var.to_user ();
const gsi::ClassBase *cls = var.user_cls ()->gsi_cls ();

if (pass_obj) {
if (pass_obj || transfer) {

if (holder) {

Expand Down Expand Up @@ -732,12 +733,17 @@ struct reader<gsi::VariantType>
*ret = Qnil;
} else {
gsi::VariantAdaptorImpl<tl::Variant> *aa = dynamic_cast<gsi::VariantAdaptorImpl<tl::Variant> *> (a.get ());
RubyBasedVariantAdaptor *pa = dynamic_cast<RubyBasedVariantAdaptor *> (a.get ());
if (aa) {
// A small optimization that saves one variant copy
*ret = object_from_variant (aa->var_ref_nc (), self, atype);
} else if (pa) {
// Optimization for Ruby to Ruby transfer
*ret = pa->value ();
} else {
tl::Variant v = a->var ();
*ret = object_from_variant (v, self, atype);
// NOTE: as v may hold the object, we need to transfer ownership
*ret = object_from_variant (v, self, atype, true);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions testdata/python/qtbinding.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,15 @@ def test_53(self):
else:
self.assertEqual(str(jsonData), 'b\'{"test":"test"}\'')

def test_54(self):

# issue #1029 (Crash for QBrush passed to setData)
item = pya.QTreeWidgetItem()
item.setBackground(0, pya.QBrush(pya.QColor(0xFF, 0xFF, 0x00)))
self.assertEqual(item.background(0).color.red, 255)
self.assertEqual(item.background(0).color.green, 255)
self.assertEqual(item.background(0).color.blue, 0)

# run unit tests
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(QtBindingTest)
Expand Down
12 changes: 12 additions & 0 deletions testdata/ruby/qtbinding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,18 @@ def test_53

end

def test_54

# issue #1029 (Crash for QBrush passed to setData)

item = RBA::QTreeWidgetItem::new
item.setBackground(0, RBA::QBrush::new(RBA::QColor::new(0xFF, 0xFF, 0x00)))
assert_equal(item.background(0).color.red, 255)
assert_equal(item.background(0).color.green, 255)
assert_equal(item.background(0).color.blue, 0)

end

end

load("test_epilogue.rb")