X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktreedatalist.c;h=d24b135f7351c5c53b5373b4d5e2c1cf07197bae;hb=67f5e595a796a8321d6dc7737c58476564998c07;hp=d71e58024bb0898bb80900055efa7b2c41efc2db;hpb=80581c3011871fa000433a881554ffc1e9363468;p=~andy%2Fgtk diff --git a/gtk/gtktreedatalist.c b/gtk/gtktreedatalist.c index d71e58024..d24b135f7 100644 --- a/gtk/gtktreedatalist.c +++ b/gtk/gtktreedatalist.c @@ -12,19 +12,15 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . * * This file contains code shared between GtkTreeStore and GtkListStore. Please * do not use it. */ -#include +#include "config.h" #include "gtktreedatalist.h" #include -static GMemChunk *tree_chunk = NULL; -#define TREE_CHUNK_PREALLOCS 64 /* node allocation */ @@ -33,14 +29,7 @@ _gtk_tree_data_list_alloc (void) { GtkTreeDataList *list; - if (tree_chunk == NULL) - tree_chunk = g_mem_chunk_new ("treedatalist mem chunk", - sizeof (GtkTreeDataList), - sizeof (GtkTreeDataList) * TREE_CHUNK_PREALLOCS, - G_ALLOC_AND_FREE); - - list = g_chunk_new (GtkTreeDataList, tree_chunk); - memset (list, 0, sizeof (GtkTreeDataList)); + list = g_slice_new0 (GtkTreeDataList); return list; } @@ -63,8 +52,10 @@ _gtk_tree_data_list_free (GtkTreeDataList *list, g_object_unref (tmp->data.v_pointer); else if (g_type_is_a (column_headers [i], G_TYPE_BOXED) && tmp->data.v_pointer != NULL) g_boxed_free (column_headers [i], (gpointer) tmp->data.v_pointer); + else if (g_type_is_a (column_headers [i], G_TYPE_VARIANT) && tmp->data.v_pointer != NULL) + g_variant_unref ((gpointer) tmp->data.v_pointer); - g_mem_chunk_free (tree_chunk, tmp); + g_slice_free (GtkTreeDataList, tmp); i++; tmp = next; } @@ -74,7 +65,7 @@ gboolean _gtk_tree_data_list_check_type (GType type) { gint i = 0; - static GType type_list[] = + static const GType type_list[] = { G_TYPE_BOOLEAN, G_TYPE_CHAR, @@ -93,6 +84,7 @@ _gtk_tree_data_list_check_type (GType type) G_TYPE_POINTER, G_TYPE_BOXED, G_TYPE_OBJECT, + G_TYPE_VARIANT, G_TYPE_INVALID }; @@ -109,7 +101,21 @@ _gtk_tree_data_list_check_type (GType type) return FALSE; } +static inline GType +get_fundamental_type (GType type) +{ + GType result; + + result = G_TYPE_FUNDAMENTAL (type); + if (result == G_TYPE_INTERFACE) + { + if (g_type_is_a (type, G_TYPE_OBJECT)) + result = G_TYPE_OBJECT; + } + + return result; +} void _gtk_tree_data_list_node_to_value (GtkTreeDataList *list, GType type, @@ -117,13 +123,13 @@ _gtk_tree_data_list_node_to_value (GtkTreeDataList *list, { g_value_init (value, type); - switch (G_TYPE_FUNDAMENTAL (type)) + switch (get_fundamental_type (type)) { case G_TYPE_BOOLEAN: g_value_set_boolean (value, (gboolean) list->data.v_int); break; case G_TYPE_CHAR: - g_value_set_char (value, (gchar) list->data.v_char); + g_value_set_schar (value, (gchar) list->data.v_char); break; case G_TYPE_UCHAR: g_value_set_uchar (value, (guchar) list->data.v_uchar); @@ -167,6 +173,9 @@ _gtk_tree_data_list_node_to_value (GtkTreeDataList *list, case G_TYPE_BOXED: g_value_set_boxed (value, (gpointer) list->data.v_pointer); break; + case G_TYPE_VARIANT: + g_value_set_variant (value, (gpointer) list->data.v_pointer); + break; case G_TYPE_OBJECT: g_value_set_object (value, (GObject *) list->data.v_pointer); break; @@ -180,13 +189,13 @@ void _gtk_tree_data_list_value_to_node (GtkTreeDataList *list, GValue *value) { - switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) + switch (get_fundamental_type (G_VALUE_TYPE (value))) { case G_TYPE_BOOLEAN: list->data.v_int = g_value_get_boolean (value); break; case G_TYPE_CHAR: - list->data.v_char = g_value_get_char (value); + list->data.v_char = g_value_get_schar (value); break; case G_TYPE_UCHAR: list->data.v_uchar = g_value_get_uchar (value); @@ -225,8 +234,7 @@ _gtk_tree_data_list_value_to_node (GtkTreeDataList *list, list->data.v_double = g_value_get_double (value); break; case G_TYPE_STRING: - if (list->data.v_pointer) - g_free (list->data.v_pointer); + g_free (list->data.v_pointer); list->data.v_pointer = g_value_dup_string (value); break; case G_TYPE_OBJECT: @@ -239,6 +247,11 @@ _gtk_tree_data_list_value_to_node (GtkTreeDataList *list, g_boxed_free (G_VALUE_TYPE (value), list->data.v_pointer); list->data.v_pointer = g_value_dup_boxed (value); break; + case G_TYPE_VARIANT: + if (list->data.v_pointer) + g_variant_unref (list->data.v_pointer); + list->data.v_pointer = g_value_dup_variant (value); + break; default: g_warning ("%s: Unsupported type (%s) stored.", G_STRLOC, g_type_name (G_VALUE_TYPE (value))); break; @@ -256,7 +269,7 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list, new_list = _gtk_tree_data_list_alloc (); new_list->next = NULL; - switch (G_TYPE_FUNDAMENTAL (type)) + switch (get_fundamental_type (type)) { case G_TYPE_BOOLEAN: case G_TYPE_CHAR: @@ -278,6 +291,7 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list, new_list->data.v_pointer = g_strdup (list->data.v_pointer); break; case G_TYPE_OBJECT: + case G_TYPE_INTERFACE: new_list->data.v_pointer = list->data.v_pointer; if (new_list->data.v_pointer) g_object_ref (new_list->data.v_pointer); @@ -288,6 +302,12 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list, else new_list->data.v_pointer = NULL; break; + case G_TYPE_VARIANT: + if (list->data.v_pointer) + new_list->data.v_pointer = g_variant_ref (list->data.v_pointer); + else + new_list->data.v_pointer = NULL; + break; default: g_warning ("Unsupported node type (%s) copied.", g_type_name (type)); break; @@ -297,22 +317,22 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list, } gint -gtk_tree_data_list_compare_func (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) +_gtk_tree_data_list_compare_func (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data) { gint column = GPOINTER_TO_INT (user_data); GType type = gtk_tree_model_get_column_type (model, column); - GValue a_value = {0, }; - GValue b_value = {0, }; + GValue a_value = G_VALUE_INIT; + GValue b_value = G_VALUE_INIT; gint retval; const gchar *stra, *strb; gtk_tree_model_get_value (model, a, column, &a_value); gtk_tree_model_get_value (model, b, column, &b_value); - switch (G_TYPE_FUNDAMENTAL (type)) + switch (get_fundamental_type (type)) { case G_TYPE_BOOLEAN: if (g_value_get_boolean (&a_value) < g_value_get_boolean (&b_value)) @@ -323,9 +343,9 @@ gtk_tree_data_list_compare_func (GtkTreeModel *model, retval = 1; break; case G_TYPE_CHAR: - if (g_value_get_char (&a_value) < g_value_get_char (&b_value)) + if (g_value_get_schar (&a_value) < g_value_get_schar (&b_value)) retval = -1; - else if (g_value_get_char (&a_value) == g_value_get_char (&b_value)) + else if (g_value_get_schar (&a_value) == g_value_get_schar (&b_value)) retval = 0; else retval = 1; @@ -427,6 +447,7 @@ gtk_tree_data_list_compare_func (GtkTreeModel *model, if (strb == NULL) strb = ""; retval = g_utf8_collate (stra, strb); break; + case G_TYPE_VARIANT: case G_TYPE_POINTER: case G_TYPE_BOXED: case G_TYPE_OBJECT: @@ -455,11 +476,11 @@ _gtk_tree_data_list_header_new (gint n_columns, { GtkTreeDataSortHeader *header; - header = g_new (GtkTreeDataSortHeader, 1); + header = g_slice_new (GtkTreeDataSortHeader); retval = g_list_prepend (retval, header); header->sort_column_id = i; - header->func = gtk_tree_data_list_compare_func; + header->func = _gtk_tree_data_list_compare_func; header->destroy = NULL; header->data = GINT_TO_POINTER (i); } @@ -477,20 +498,20 @@ _gtk_tree_data_list_header_free (GList *list) if (header->destroy) { - GtkDestroyNotify d = header->destroy; + GDestroyNotify d = header->destroy; header->destroy = NULL; d (header->data); } - g_free (header); + g_slice_free (GtkTreeDataSortHeader, header); } g_list_free (list); } GtkTreeDataSortHeader * -_gtk_tree_data_list_get_header (GList *header_list, - gint sort_column_id) +_gtk_tree_data_list_get_header (GList *header_list, + gint sort_column_id) { GtkTreeDataSortHeader *header = NULL; @@ -502,3 +523,50 @@ _gtk_tree_data_list_get_header (GList *header_list, } return NULL; } + + +GList * +_gtk_tree_data_list_set_header (GList *header_list, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GDestroyNotify destroy) +{ + GList *list = header_list; + GtkTreeDataSortHeader *header = NULL; + + for (; list; list = list->next) + { + header = (GtkTreeDataSortHeader*) list->data; + if (header->sort_column_id == sort_column_id) + break; + header = NULL; + + if (list->next == NULL) + break; + } + + if (header == NULL) + { + header = g_slice_new0 (GtkTreeDataSortHeader); + header->sort_column_id = sort_column_id; + if (list) + list = g_list_append (list, header); + else + header_list = g_list_append (header_list, header); + } + + if (header->destroy) + { + GDestroyNotify d = header->destroy; + + header->destroy = NULL; + d (header->data); + } + + header->func = func; + header->data = data; + header->destroy = destroy; + + return header_list; +}