Applied Ryan's native wxListBox and wxCheckListBox patch
[wxWidgets.git] / src / gtk / treeentry_gtk.c
1 /* ///////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/treeentry_gtk.c
3 // Purpose: GtkTreeEntry implementation
4 // Author: Ryan Norton
5 // Id: $Id$
6 // Copyright: (c) 2006 Ryan Norton
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////// */
9
10 #include "wx/gtk/treeentry_gtk.h"
11
12 /*
13 GtkTreeEntry
14
15 The main reason for this class is to have a holder for both a string
16 and userdata for us to use in wxListXXX classes.
17
18 This is transformable to a string for the Gtk implementations,
19 and the string passed in is duplicated and freed upon destruction.
20
21 As mentioned the real magic here is the transforming it to a string
22 which lets us use it as a entry in a GtkTreeView/GtkListStore
23 and still display it. Otherwise we would need to implement our
24 own model etc..
25 */
26
27 /* forwards */
28 static void gtk_tree_entry_class_init(GtkTreeEntryClass* klass);
29 static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class);
30 static void gtk_tree_entry_string_transform_func(const GValue *src_value,
31 GValue *dest_value);
32 static void gtk_tree_entry_dispose(GObject* obj);
33
34
35 /* public */
36 GtkTreeEntry*
37 gtk_tree_entry_new()
38 {
39 return GTK_TREE_ENTRY(g_object_new(GTK_TYPE_TREE_ENTRY, NULL));
40 }
41
42 GtkType
43 gtk_tree_entry_get_type ()
44 {
45 static GtkType tree_entry_type = 0;
46
47 if (!tree_entry_type)
48 {
49 static const GTypeInfo tree_entry_info =
50 {
51 sizeof (GtkTreeEntryClass),
52 NULL, /* base_init */
53 NULL, /* base_finalize */
54 (GClassInitFunc) gtk_tree_entry_class_init, /* class_init */
55 NULL, /* class_finalize */
56 NULL, /* class_data */
57 sizeof (GtkTreeEntry),
58 16, /* n_preallocs */
59 (GInstanceInitFunc) gtk_tree_entry_init, /*instance_init*/
60 };
61 tree_entry_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeEntry",
62 &tree_entry_info,
63 (GTypeFlags)0);
64 g_value_register_transform_func(tree_entry_type, G_TYPE_STRING,
65 gtk_tree_entry_string_transform_func);
66 }
67
68 return tree_entry_type;
69 }
70
71 gchar* gtk_tree_entry_get_collate_key (GtkTreeEntry* entry)
72 {
73 return entry->collate_key;
74 }
75
76 gchar* gtk_tree_entry_get_label (GtkTreeEntry* entry)
77 {
78 g_assert(GTK_IS_TREE_ENTRY(entry));
79 return entry->label;
80 }
81
82 gpointer gtk_tree_entry_get_userdata (GtkTreeEntry* entry)
83 {
84 g_assert(GTK_IS_TREE_ENTRY(entry));
85 return entry->userdata;
86 }
87
88 void gtk_tree_entry_set_label (GtkTreeEntry* entry, const gchar* label)
89 {
90 g_assert(GTK_IS_TREE_ENTRY(entry));
91
92 /* free previous if it exists */
93 if(entry->label)
94 {
95 g_free(entry->label);
96 g_free(entry->collate_key);
97 }
98
99 entry->label = g_strdup(label);
100 entry->collate_key = g_utf8_collate_key(label, -1); /* -1 == null terminated */
101 }
102
103 void gtk_tree_entry_set_userdata (GtkTreeEntry* entry, gpointer userdata)
104 {
105 g_assert(GTK_IS_TREE_ENTRY(entry));
106 entry->userdata = userdata;
107 }
108
109 void gtk_tree_entry_set_destroy_func (GtkTreeEntry* entry,
110 GtkTreeEntryDestroy destroy_func,
111 gpointer destroy_func_data)
112 {
113 g_assert(GTK_IS_TREE_ENTRY(entry));
114 entry->destroy_func = destroy_func;
115 entry->destroy_func_data = destroy_func_data;
116 }
117
118 /* private */
119 static void gtk_tree_entry_class_init(GtkTreeEntryClass* klass)
120 {
121 GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
122 gobject_class->dispose = gtk_tree_entry_dispose;
123 }
124
125 static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class)
126 {
127 GtkTreeEntry* entry = (GtkTreeEntry*) instance;
128
129 /* clear */
130 entry->label = NULL;
131 entry->collate_key = NULL;
132 entry->userdata = NULL;
133 entry->destroy_func_data = NULL;
134 entry->destroy_func = NULL;
135 }
136
137 static void gtk_tree_entry_string_transform_func(const GValue *src_value,
138 GValue *dest_value)
139 {
140 /* Make sure src is a treeentry and dest can hold a string */
141 g_assert(GTK_IS_TREE_ENTRY(src_value->data[0].v_pointer));
142 g_assert(G_VALUE_HOLDS(dest_value, G_TYPE_STRING));
143
144 /* TODO: Use strdup here or just pass it? */
145 GtkTreeEntry* entry = GTK_TREE_ENTRY(src_value->data[0].v_pointer);
146
147 g_value_set_string(dest_value, g_strdup(entry->label));
148 }
149
150 static void gtk_tree_entry_dispose(GObject* obj)
151 {
152 g_assert(GTK_IS_TREE_ENTRY(obj));
153
154 GtkTreeEntry* entry = GTK_TREE_ENTRY(obj);
155
156 /* free label if it exists */
157 if(entry->label)
158 {
159 g_free(entry->label);
160 g_free(entry->collate_key);
161 entry->label = NULL;
162 entry->collate_key = NULL;
163 }
164
165 /* call destroy callback if it exists */
166 if(entry->destroy_func)
167 {
168 (*entry->destroy_func) (entry, entry->destroy_func_data);
169 entry->destroy_func = NULL;
170 entry->destroy_func_data = NULL;
171 }
172
173 /* clear userdata */
174 entry->userdata = NULL;
175 }