Index: bindings/python/rhythmdb.override
===================================================================
--- bindings/python/rhythmdb.override	(revision 5204)
+++ bindings/python/rhythmdb.override	(working copy)
@@ -37,48 +37,6 @@
 {
 	Py_XDECREF (o);
 }
-
-
-/* query model sorting stuff */
-typedef struct {
-	PyObject *func;
-	PyObject *data;
-} PyRhythmDBQueryModelSortData;
-
-static void
-_rhythmdb_query_model_sort_data_free (PyRhythmDBQueryModelSortData *data)
-{
-	Py_DECREF (data->func);
-	Py_DECREF (data->data);
-	g_free (data);
-}
-
-static int
-_rhythmdb_query_model_sort_func (RhythmDBEntry *a, RhythmDBEntry *b, PyRhythmDBQueryModelSortData *data)
-{
-	PyObject *args;
-	PyObject *py_result;
-	PyObject *py_a, *py_b;
-	int result;
-
-	py_a = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, a, TRUE, TRUE);
-	py_b = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, b, TRUE, TRUE);
-	if (data->data)
-		args = Py_BuildValue ("(OOO)", py_a, py_b, data->data);
-	else
-		args = Py_BuildValue ("(OO)", py_a, py_b);
-
-	py_result = PyEval_CallObject (data->func, args);
-	result = PyInt_AsLong (py_result);
-
-	Py_DECREF (py_a);
-	Py_DECREF (py_b);
-	Py_DECREF (args);
-	Py_DECREF (py_result);
-	return result;
-}
-/* end query model sorting stuff */
-
 %%
 modulename rhythmdb 
 %%
@@ -277,10 +235,10 @@
 	static char *kwlist[] = {"query", "func", "reverse", "data", NULL};
 	PyObject *py_query;
 	int reverse = 0;
-	PyRhythmDBQueryModelSortData *data;
+	PyRhythmDBCustomNotify *data;
 	RhythmDBQueryModel *query_model;
 
-	data = g_new0 (PyRhythmDBQueryModelSortData, 1);
+	data = g_new0 (PyRhythmDBCustomNotify, 1);
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiO:RhythmDB.query_model_new", kwlist,
 					 &py_query, &data->func, &reverse, &data->data)) {
@@ -306,12 +264,13 @@
 
 	if (data->func) {
 		query_model = rhythmdb_query_model_new (RHYTHMDB (self->obj), pyg_boxed_get (py_query, RhythmDBQuery),
-							(GCompareDataFunc) _rhythmdb_query_model_sort_func,
-							data, (GDestroyNotify) _rhythmdb_query_model_sort_data_free,
+							(GCompareDataFunc) _rhythmdb_entry_compare_data_func,
+							data, (GDestroyNotify) _rhythmdb_custom_notify_free,
 							(reverse != 0));
 	} else {
 		query_model = rhythmdb_query_model_new (RHYTHMDB (self->obj), pyg_boxed_get (py_query, RhythmDBQuery),
 							NULL, NULL, NULL, FALSE);
+		_rhythmdb_custom_notify_free (data);
 	}
 
 	return pygobject_new (G_OBJECT (query_model));
@@ -322,11 +281,11 @@
 static PyObject*
 _wrap_rhythmdb_query_model_set_sort_order (PyGObject *self, PyObject *args, PyObject *kwargs)
 {
-	static char *kwlist[] = {"func", "reverse", NULL};
+	static char *kwlist[] = {"func", "reverse", "data", NULL};
 	int reverse = 0;
-	PyRhythmDBQueryModelSortData *data;
+	PyRhythmDBCustomNotify *data;
 
-	data = g_new0 (PyRhythmDBQueryModelSortData, 1);
+	data = g_new0 (PyRhythmDBCustomNotify, 1);
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO:RhythmDB.query_model_set_sort_order", kwlist,
 					 &data->func, &reverse, &data->data)) {
@@ -342,12 +301,12 @@
 	}
 
 	Py_INCREF (data->func);
-	Py_INCREF (data->data);
+	Py_XINCREF (data->data);
 
 	rhythmdb_query_model_set_sort_order (RHYTHMDB_QUERY_MODEL (self->obj),
-						 (GCompareDataFunc) _rhythmdb_query_model_sort_func,
-						 data, (GDestroyNotify) _rhythmdb_query_model_sort_data_free,
-						 (reverse != 0));
+					     (GCompareDataFunc) _rhythmdb_entry_compare_data_func,
+					     data, (GDestroyNotify) _rhythmdb_custom_notify_free,
+					     (reverse != 0));
 
 	Py_INCREF(Py_None);
 	return Py_None;
Index: bindings/python/rb.override
===================================================================
--- bindings/python/rb.override	(revision 5204)
+++ bindings/python/rb.override	(working copy)
@@ -76,6 +76,80 @@
   *_get_type
   *_quark
 %%
+override rb_entry_view_append_column_custom kwargs
+static PyObject *
+_wrap_rb_entry_view_append_column_custom(PyGObject *self, PyObject *args,
+                                         PyObject *kwargs)
+{
+    static char *kwlist[] = { "column", "title", "key", "sort_func", "sort_data", NULL };
+    PyGObject *pycolumn = NULL;
+    PyObject *pyfunc, *pyarg = NULL;
+    PyRhythmDBCustomNotify *cunote;
+    char *title, *key;
+  
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "OzzO|O:RBEntryView.append_column_custom",
+                                     kwlist, &pycolumn, &title, &key, &pyfunc, &pyarg))
+        return NULL;
+
+    if (!PyCallable_Check(pyfunc)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "sort_func must be a callable object");
+        return NULL;
+    }
+    cunote = g_new0(PyRhythmDBCustomNotify, 1);
+    cunote->func = pyfunc;
+    cunote->data = pyarg;
+    Py_INCREF(cunote->func);
+    Py_XINCREF(cunote->data);
+ 
+    rb_entry_view_append_column_custom(RB_ENTRY_VIEW(self->obj),
+                                       GTK_TREE_VIEW_COLUMN(pycolumn->obj), title, key,
+                                       (GCompareDataFunc) _rhythmdb_entry_compare_data_func,
+                                       cunote, (GDestroyNotify) _rhythmdb_custom_notify_free);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+%%
+override rb_entry_view_insert_column_custom kwargs
+static PyObject *
+_wrap_rb_entry_view_insert_column_custom(PyGObject *self, PyObject *args,
+                                         PyObject *kwargs)
+{
+    static char *kwlist[] = { "column", "title", "key", "sort_func", "sort_data", "position", NULL };
+    PyGObject *pycolumn = NULL;
+    PyObject *pyfunc, *pyarg = NULL;
+    PyRhythmDBCustomNotify *cunote;
+    char *title, *key;
+    int position;
+  
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "OzzOOi:RBEntryView.insert_column_custom",
+                                     kwlist, &pycolumn, &title, &key, &pyfunc, &pyarg, &position))
+        return NULL;
+
+    if (!PyCallable_Check(pyfunc)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "sort_func must be a callable object");
+        return NULL;
+    }
+    cunote = g_new0(PyRhythmDBCustomNotify, 1);
+    cunote->func = pyfunc;
+    cunote->data = pyarg;
+    Py_INCREF(cunote->func);
+    Py_INCREF(cunote->data);
+ 
+    rb_entry_view_insert_column_custom(RB_ENTRY_VIEW(self->obj),
+                                       GTK_TREE_VIEW_COLUMN(pycolumn->obj), title, key,
+                                       (GCompareDataFunc) _rhythmdb_entry_compare_data_func,
+                                       cunote, (GDestroyNotify) _rhythmdb_custom_notify_free,
+                                       position);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+%%
 override rb_entry_view_get_selected_entries noargs
 static PyObject *
 _wrap_rb_entry_view_get_selected_entries(PyGObject *self)
Index: bindings/python/rb.defs
===================================================================
--- bindings/python/rb.defs	(revision 5204)
+++ bindings/python/rb.defs	(working copy)
@@ -1323,6 +1323,21 @@
   )
 )
 
+(define-method insert_column_custom
+  (of-object "RBEntryView")
+  (c-name "rb_entry_view_insert_column_custom")
+  (return-type "none")
+  (parameters
+    '("GtkTreeViewColumn*" "column")
+    '("const-char*" "title")
+    '("const-char*" "key")
+    '("GCompareDataFunc" "sort_func")
+    '("gpointer" "data")
+    '("GDestroyNotify" "data_destroy")
+    '("gint" "position")
+  )
+)
+
 (define-method set_columns_clickable
   (of-object "RBEntryView")
   (c-name "rb_entry_view_set_columns_clickable")
Index: bindings/python/override_common.c
===================================================================
--- bindings/python/override_common.c	(revision 5204)
+++ bindings/python/override_common.c	(working copy)
@@ -184,3 +184,44 @@
     return list;
 }
 
+/* query model sorting stuff */
+void
+_rhythmdb_custom_notify_free (PyRhythmDBCustomNotify *data)
+{
+	Py_XDECREF (data->func);
+	Py_XDECREF (data->data);
+	g_free (data);
+}
+
+int
+_rhythmdb_entry_compare_data_func (RhythmDBEntry *a,
+				   RhythmDBEntry *b,
+				   PyRhythmDBCustomNotify *data)
+{
+	PyObject *args;
+	PyObject *py_result;
+	PyObject *py_a, *py_b;
+	int result;
+
+	py_a = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, a, TRUE, TRUE);
+	py_b = pyg_boxed_new (RHYTHMDB_TYPE_ENTRY, b, TRUE, TRUE);
+	if (data->data)
+		args = Py_BuildValue ("(OOO)", py_a, py_b, data->data);
+	else
+		args = Py_BuildValue ("(OO)", py_a, py_b);
+
+	Py_DECREF (py_a);
+	Py_DECREF (py_b);
+	Py_DECREF (args);
+
+	py_result = PyEval_CallObject (data->func, args);
+	if (!py_result) {
+		PyErr_Print();
+		return NULL;
+	}
+
+	result = PyInt_AsLong (py_result);
+	Py_DECREF (py_result);
+	return result;
+}
+/* end query model sorting stuff */
Index: bindings/python/override_common.h
===================================================================
--- bindings/python/override_common.h	(revision 5204)
+++ bindings/python/override_common.h	(working copy)
@@ -26,6 +26,8 @@
 #ifndef __OVERRIDE_COMMON_H
 #define __OVERRIDE_COMMON_H
 
+#include "rhythmdb.h"
+
 PyObject * _helper_wrap_gobject_glist (const GList *list);
 PyObject * _helper_wrap_string_glist (const GList *list);
 PyObject * _helper_wrap_pointer_glist (const GList *list,
@@ -43,5 +45,17 @@
 				       GType type);
 GPtrArray* _helper_unwrap_boxed_gptrarray (PyObject *list,
 					   GType type);
+
+typedef struct {
+	PyObject *func;
+	PyObject *data;
+} PyRhythmDBCustomNotify;
+
+void
+_rhythmdb_custom_notify_free (PyRhythmDBCustomNotify *data);
+int
+_rhythmdb_entry_compare_data_func (RhythmDBEntry *a,
+				   RhythmDBEntry *b,
+				   PyRhythmDBCustomNotify *data);
 #endif /* __OVERRIDE_COMMON_H */
 
Index: widgets/rb-entry-view.c
===================================================================
--- widgets/rb-entry-view.c	(revision 5204)
+++ widgets/rb-entry-view.c	(working copy)
@@ -2124,7 +2124,7 @@
 	rhythmdb_query_model_set_sort_order (view->priv->model,
 					     sort_data->func,
 					     sort_data->data,
-					     sort_data->data_destroy,
+					     NULL,
 					     (view->priv->sorting_order == GTK_SORT_DESCENDING));
 }
 
