+/* ///////////////////////////////////////////////////////////////////////////
+// Name: src/gtk/treeentry_gtk.c
+// Purpose: GtkTreeEntry implementation
+// Author: Ryan Norton
+// Id: $Id$
+// Copyright: (c) 2006 Ryan Norton
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////// */
+
+#include "wx/gtk/treeentry_gtk.h"
+
+/*
+ GtkTreeEntry
+
+ The main reason for this class is to have a holder for both a string
+ and userdata for us to use in wxListXXX classes.
+
+ This is transformable to a string for the Gtk implementations,
+ and the string passed in is duplicated and freed upon destruction.
+
+ As mentioned the real magic here is the transforming it to a string
+ which lets us use it as a entry in a GtkTreeView/GtkListStore
+ and still display it. Otherwise we would need to implement our
+ own model etc..
+*/
+
+/* forwards */
+static void gtk_tree_entry_class_init(GtkTreeEntryClass* klass);
+static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class);
+static void gtk_tree_entry_string_transform_func(const GValue *src_value,
+ GValue *dest_value);
+static void gtk_tree_entry_dispose(GObject* obj);
+
+
+/* public */
+GtkTreeEntry*
+gtk_tree_entry_new()
+{
+ return GTK_TREE_ENTRY(g_object_new(GTK_TYPE_TREE_ENTRY, NULL));
+}
+
+GtkType
+gtk_tree_entry_get_type ()
+{
+ static GtkType tree_entry_type = 0;
+
+ if (!tree_entry_type)
+ {
+ static const GTypeInfo tree_entry_info =
+ {
+ sizeof (GtkTreeEntryClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_tree_entry_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkTreeEntry),
+ 16, /* n_preallocs */
+ (GInstanceInitFunc) gtk_tree_entry_init, /*instance_init*/
+ };
+ tree_entry_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeEntry",
+ &tree_entry_info,
+ (GTypeFlags)0);
+ g_value_register_transform_func(tree_entry_type, G_TYPE_STRING,
+ gtk_tree_entry_string_transform_func);
+ }
+
+ return tree_entry_type;
+}
+
+gchar* gtk_tree_entry_get_collate_key (GtkTreeEntry* entry)
+{
+ return entry->collate_key;
+}
+
+gchar* gtk_tree_entry_get_label (GtkTreeEntry* entry)
+{
+ g_assert(GTK_IS_TREE_ENTRY(entry));
+ return entry->label;
+}
+
+gpointer gtk_tree_entry_get_userdata (GtkTreeEntry* entry)
+{
+ g_assert(GTK_IS_TREE_ENTRY(entry));
+ return entry->userdata;
+}
+
+void gtk_tree_entry_set_label (GtkTreeEntry* entry, const gchar* label)
+{
+ g_assert(GTK_IS_TREE_ENTRY(entry));
+
+ /* free previous if it exists */
+ if(entry->label)
+ {
+ g_free(entry->label);
+ g_free(entry->collate_key);
+ }
+
+ entry->label = g_strdup(label);
+ entry->collate_key = g_utf8_collate_key(label, -1); /* -1 == null terminated */
+}
+
+void gtk_tree_entry_set_userdata (GtkTreeEntry* entry, gpointer userdata)
+{
+ g_assert(GTK_IS_TREE_ENTRY(entry));
+ entry->userdata = userdata;
+}
+
+void gtk_tree_entry_set_destroy_func (GtkTreeEntry* entry,
+ GtkTreeEntryDestroy destroy_func,
+ gpointer destroy_func_data)
+{
+ g_assert(GTK_IS_TREE_ENTRY(entry));
+ entry->destroy_func = destroy_func;
+ entry->destroy_func_data = destroy_func_data;
+}
+
+/* private */
+static void gtk_tree_entry_class_init(GtkTreeEntryClass* klass)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+ gobject_class->dispose = gtk_tree_entry_dispose;
+}
+
+static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class)
+{
+ GtkTreeEntry* entry = (GtkTreeEntry*) instance;
+
+ /* clear */
+ entry->label = NULL;
+ entry->collate_key = NULL;
+ entry->userdata = NULL;
+ entry->destroy_func_data = NULL;
+ entry->destroy_func = NULL;
+}
+
+static void gtk_tree_entry_string_transform_func(const GValue *src_value,
+ GValue *dest_value)
+{
+ /* Make sure src is a treeentry and dest can hold a string */
+ g_assert(GTK_IS_TREE_ENTRY(src_value->data[0].v_pointer));
+ g_assert(G_VALUE_HOLDS(dest_value, G_TYPE_STRING));
+
+ /* TODO: Use strdup here or just pass it? */
+ GtkTreeEntry* entry = GTK_TREE_ENTRY(src_value->data[0].v_pointer);
+
+ g_value_set_string(dest_value, g_strdup(entry->label));
+}
+
+static void gtk_tree_entry_dispose(GObject* obj)
+{
+ g_assert(GTK_IS_TREE_ENTRY(obj));
+
+ GtkTreeEntry* entry = GTK_TREE_ENTRY(obj);
+
+ /* free label if it exists */
+ if(entry->label)
+ {
+ g_free(entry->label);
+ g_free(entry->collate_key);
+ entry->label = NULL;
+ entry->collate_key = NULL;
+ }
+
+ /* call destroy callback if it exists */
+ if(entry->destroy_func)
+ {
+ (*entry->destroy_func) (entry, entry->destroy_func_data);
+ entry->destroy_func = NULL;
+ entry->destroy_func_data = NULL;
+ }
+
+ /* clear userdata */
+ entry->userdata = NULL;
+}