2012/9/13 Nick Hall <nick__hall@hotmail.com>
On 12/09/12 22:15, Benny Malengier wrote:
If I look in git of pygobject, I see in gi/overrides/Gtk.py:

        for cur_col, value in enumerate(row):
            # do not try to set None values, they are causing warnings
            if value is None:
                continue

So they seem to be aware that None causes a problem, and there they skip the line with None. So the C code is never called, the override defined there has already intervened. You see in this override that they set GValue for us, we don't have to do that in our python code.

OK.  So they know that there is a problem.



About setting None then for the stock item colomn, in dbman.py I see:

            store.set_value(node, STOCK_COL, "")
So empty string.

Yes.  This is the line that causes the problem.  With Gtk2 it needed the column set to an empty string.  In Gtk3 this gives an error (and hence sort of works!), but we need None.

Long post, thought about a solution at the end, so see bottom for that.

Ok, I now fully follow. The error
gramps.py:3315): Gtk-CRITICAL **: gtk_icon_set_render_icon_pixbuf: assertion `icon_set != NULL' failed
is due to the setting to '' of the stock column after break lock.

I see that for archive we also set '', so that will give errors also.
Looking into the code, we set None on build of the model. However, this means that in Gtk.py the column is just skipped when setting content. So in the low_level interface, there is nothing set, I suppose it will be NULL
We cannot set the value to NULL once it has been set to something. This should be allowed in some way, you should indeed open a bug ticket to pygobject to indicate this lack.
The only workaround I can see is to do delete of the row, then reset it with a None in the column, as this will cause the NULL value we need to avoid the error on the terminal.

Alternative is that they override the cellrendererpixbuf, so that on stock_id == "", they assume this means NULL in some way.

From the point of view of GTK, we set the column type, eg in dbman:

        self.model = Gtk.TreeStore(str, str, str, str, int, bool, str)
Looking at this, we cannot pass None, as that is not str, int or bool.

Yes we can.  That is what I did with the append method which fixes some of the problem.  With the append you can set a str column to either a string or None.

So, None means the column is never set, so probably it is NULL assumed then. But we don't set None in it by passing None. Looking at it from C, if something is str, it is better if always str, but probably they allow NULL.


You could pass in a pygobject, and then have that have an attribute which is None.


How do I do this?


To pass a python object, you need to set the column type to TYPE_PYOBJECT:

>>> from gi.repository import GObject
>>> GObject.TYPE_PYOBJECT
<GType PyObject (31501200)>

However, we want to pass to the cellrendererpixbuf what column it can use for the stock_id, and that will not work with a python object.
If we would have a transparent pixbuf, we could use that for those cases that need no icon needed. We can make one and call it 'gramps-transparent'
 
Another workaround would be to delete to whole row and then re-insert it.  Not very neat!  Do you think that they will fix the original bug?  It is really not a Gramps problem as such.

Indeed. If you post a bug about the inability to unset a column value so it becomes NULL, they can tackle it.  A test case would be required :-(

These problems take time to debug.  I am having to read the source code (and documentation is poor), for gobject, pygobject and gtk3 in order to understand this.  I have just been reading up on GValue to see what it is.  Without knowing the details I was having problems understanding what you and John were talking about.

Yes, it is more difficult for those who want to go deep into it.

To solve the problem now, there is an easy workaround however:

http://developer.gnome.org/gtk3/stable/GtkTreeViewColumn.html#gtk-tree-view-column-set-cell-data-func

So not use the column directly to set the stock_id, but instead use a function. This function then passes None if stock_id = "", and otherwise the value. This would mean we always set "" in the column, instead of None.
Do I try this, or do you?

Benny