X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktreedatalist.c;h=d24b135f7351c5c53b5373b4d5e2c1cf07197bae;hb=HEAD;hp=137de3e27a5a6cc87ff06fe1ede43214999715a7;hpb=64e33eb68f6e3c999a98147c2d7ccf2698f3ce20;p=~andy%2Fgtk diff --git a/gtk/gtktreedatalist.c b/gtk/gtktreedatalist.c index 137de3e27..d24b135f7 100644 --- a/gtk/gtktreedatalist.c +++ b/gtk/gtktreedatalist.c @@ -12,18 +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 "config.h" #include "gtktreedatalist.h" #include -static GMemChunk *tree_chunk = NULL; -#define TREE_CHUNK_PREALLOCS 64 /* node allocation */ @@ -32,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; } @@ -59,11 +49,13 @@ _gtk_tree_data_list_free (GtkTreeDataList *list, if (g_type_is_a (column_headers [i], G_TYPE_STRING)) g_free ((gchar *) tmp->data.v_pointer); else if (g_type_is_a (column_headers [i], G_TYPE_OBJECT) && tmp->data.v_pointer != NULL) - g_object_unref (G_OBJECT (tmp->data.v_pointer)); + 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; } @@ -73,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, @@ -92,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 }; @@ -108,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, @@ -116,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); @@ -133,11 +140,23 @@ _gtk_tree_data_list_node_to_value (GtkTreeDataList *list, case G_TYPE_UINT: g_value_set_uint (value, (guint) list->data.v_uint); break; + case G_TYPE_LONG: + g_value_set_long (value, list->data.v_long); + break; + case G_TYPE_ULONG: + g_value_set_ulong (value, list->data.v_ulong); + break; + case G_TYPE_INT64: + g_value_set_int64 (value, list->data.v_int64); + break; + case G_TYPE_UINT64: + g_value_set_uint64 (value, list->data.v_uint64); + break; case G_TYPE_ENUM: g_value_set_enum (value, list->data.v_int); break; case G_TYPE_FLAGS: - g_value_set_flags (value, (int) list->data.v_int); + g_value_set_flags (value, list->data.v_uint); break; case G_TYPE_FLOAT: g_value_set_float (value, (gfloat) list->data.v_float); @@ -154,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; @@ -167,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); @@ -181,14 +203,26 @@ _gtk_tree_data_list_value_to_node (GtkTreeDataList *list, case G_TYPE_INT: list->data.v_int = g_value_get_int (value); break; + case G_TYPE_UINT: + list->data.v_uint = g_value_get_uint (value); + break; + case G_TYPE_LONG: + list->data.v_long = g_value_get_long (value); + break; + case G_TYPE_ULONG: + list->data.v_ulong = g_value_get_ulong (value); + break; + case G_TYPE_INT64: + list->data.v_int64 = g_value_get_int64 (value); + break; + case G_TYPE_UINT64: + list->data.v_uint64 = g_value_get_uint64 (value); + break; case G_TYPE_ENUM: list->data.v_int = g_value_get_enum (value); break; case G_TYPE_FLAGS: - list->data.v_int = g_value_get_flags (value); - break; - case G_TYPE_UINT: - list->data.v_uint = g_value_get_uint (value); + list->data.v_uint = g_value_get_flags (value); break; case G_TYPE_POINTER: list->data.v_pointer = g_value_get_pointer (value); @@ -200,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: @@ -214,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; @@ -231,13 +269,19 @@ _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_UINT: - case G_TYPE_INT: - case G_TYPE_UCHAR: - case G_TYPE_CHAR: case G_TYPE_BOOLEAN: + case G_TYPE_CHAR: + case G_TYPE_UCHAR: + case G_TYPE_INT: + case G_TYPE_UINT: + case G_TYPE_LONG: + case G_TYPE_ULONG: + case G_TYPE_INT64: + case G_TYPE_UINT64: + case G_TYPE_ENUM: + case G_TYPE_FLAGS: case G_TYPE_POINTER: case G_TYPE_FLOAT: case G_TYPE_DOUBLE: @@ -247,9 +291,10 @@ _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 (G_OBJECT (new_list->data.v_pointer)); + g_object_ref (new_list->data.v_pointer); break; case G_TYPE_BOXED: if (list->data.v_pointer) @@ -257,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; @@ -266,35 +317,35 @@ _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_int (&a_value) < g_value_get_int (&b_value)) + if (g_value_get_boolean (&a_value) < g_value_get_boolean (&b_value)) retval = -1; - else if (g_value_get_int (&a_value) == g_value_get_int (&b_value)) + else if (g_value_get_boolean (&a_value) == g_value_get_boolean (&b_value)) retval = 0; else 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; @@ -323,20 +374,52 @@ gtk_tree_data_list_compare_func (GtkTreeModel *model, else retval = 1; break; + case G_TYPE_LONG: + if (g_value_get_long (&a_value) < g_value_get_long (&b_value)) + retval = -1; + else if (g_value_get_long (&a_value) == g_value_get_long (&b_value)) + retval = 0; + else + retval = 1; + break; + case G_TYPE_ULONG: + if (g_value_get_ulong (&a_value) < g_value_get_ulong (&b_value)) + retval = -1; + else if (g_value_get_ulong (&a_value) == g_value_get_ulong (&b_value)) + retval = 0; + else + retval = 1; + break; + case G_TYPE_INT64: + if (g_value_get_int64 (&a_value) < g_value_get_int64 (&b_value)) + retval = -1; + else if (g_value_get_int64 (&a_value) == g_value_get_int64 (&b_value)) + retval = 0; + else + retval = 1; + break; + case G_TYPE_UINT64: + if (g_value_get_uint64 (&a_value) < g_value_get_uint64 (&b_value)) + retval = -1; + else if (g_value_get_uint64 (&a_value) == g_value_get_uint64 (&b_value)) + retval = 0; + else + retval = 1; + break; case G_TYPE_ENUM: /* this is somewhat bogus. */ - if (g_value_get_int (&a_value) < g_value_get_int (&b_value)) + if (g_value_get_enum (&a_value) < g_value_get_enum (&b_value)) retval = -1; - else if (g_value_get_int (&a_value) == g_value_get_int (&b_value)) + else if (g_value_get_enum (&a_value) == g_value_get_enum (&b_value)) retval = 0; else retval = 1; break; case G_TYPE_FLAGS: /* this is even more bogus. */ - if (g_value_get_uint (&a_value) < g_value_get_uint (&b_value)) + if (g_value_get_flags (&a_value) < g_value_get_flags (&b_value)) retval = -1; - else if (g_value_get_uint (&a_value) == g_value_get_uint (&b_value)) + else if (g_value_get_flags (&a_value) == g_value_get_flags (&b_value)) retval = 0; else retval = 1; @@ -364,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: @@ -392,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); } @@ -414,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; @@ -439,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; +}