chain up to parent in dispose handler
[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 #ifdef __VMS
11 #include <types.h>
12 typedef pid_t GPid;
13 #define G_GNUC_INTERNAL
14 #define GSEAL(x) x
15 #endif
16
17 #include "wx/gtk/treeentry_gtk.h"
18
19 /*
20 GtkTreeEntry
21
22 The main reason for this class is to have a holder for both a string
23 and userdata for us to use in wxListXXX classes.
24
25 This is transformable to a string for the Gtk implementations,
26 and the string passed in is duplicated and freed upon destruction.
27
28 As mentioned the real magic here is the transforming it to a string
29 which lets us use it as a entry in a GtkTreeView/GtkListStore
30 and still display it. Otherwise we would need to implement our
31 own model etc..
32 */
33
34 /* forwards */
35 static void gtk_tree_entry_class_init(void* g_class, void* class_data);
36 static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class);
37 static void gtk_tree_entry_string_transform_func(const GValue *src_value,
38 GValue *dest_value);
39 static void gtk_tree_entry_dispose(GObject* obj);
40
41 static GObjectClass* parent_class;
42
43 /* public */
44 GtkTreeEntry*
45 gtk_tree_entry_new()
46 {
47 return GTK_TREE_ENTRY(g_object_new(GTK_TYPE_TREE_ENTRY, NULL));
48 }
49
50 GType
51 gtk_tree_entry_get_type ()
52 {
53 static GType tree_entry_type = 0;
54
55 if (!tree_entry_type)
56 {
57 const GTypeInfo tree_entry_info =
58 {
59 sizeof (GtkTreeEntryClass),
60 NULL, /* base_init */
61 NULL, /* base_finalize */
62 gtk_tree_entry_class_init,
63 NULL, /* class_finalize */
64 NULL, /* class_data */
65 sizeof (GtkTreeEntry),
66 16, /* n_preallocs */
67 (GInstanceInitFunc) gtk_tree_entry_init, /*instance_init*/
68 NULL /* value_table */
69 };
70 tree_entry_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeEntry",
71 &tree_entry_info,
72 (GTypeFlags)0);
73 g_value_register_transform_func(tree_entry_type, G_TYPE_STRING,
74 gtk_tree_entry_string_transform_func);
75 }
76
77 return tree_entry_type;
78 }
79
80 gchar* gtk_tree_entry_get_collate_key (GtkTreeEntry* entry)
81 {
82 return entry->collate_key;
83 }
84
85 gchar* gtk_tree_entry_get_label (GtkTreeEntry* entry)
86 {
87 g_assert(GTK_IS_TREE_ENTRY(entry));
88 return entry->label;
89 }
90
91 gpointer gtk_tree_entry_get_userdata (GtkTreeEntry* entry)
92 {
93 g_assert(GTK_IS_TREE_ENTRY(entry));
94 return entry->userdata;
95 }
96
97 void gtk_tree_entry_set_label (GtkTreeEntry* entry, const gchar* label)
98 {
99 gchar *temp;
100 g_assert(GTK_IS_TREE_ENTRY(entry));
101
102 /* free previous if it exists */
103 if(entry->label)
104 {
105 g_free(entry->label);
106 g_free(entry->collate_key);
107 }
108
109 entry->label = g_strdup(label);
110 temp = g_utf8_casefold(label, -1); /* -1 == null terminated */
111 entry->collate_key = g_utf8_collate_key(temp, -1); /* -1 == null terminated */
112 g_free( temp );
113 }
114
115 void gtk_tree_entry_set_userdata (GtkTreeEntry* entry, gpointer userdata)
116 {
117 g_assert(GTK_IS_TREE_ENTRY(entry));
118 entry->userdata = userdata;
119 }
120
121 void gtk_tree_entry_set_destroy_func (GtkTreeEntry* entry,
122 GtkTreeEntryDestroy destroy_func,
123 gpointer destroy_func_data)
124 {
125 g_assert(GTK_IS_TREE_ENTRY(entry));
126 entry->destroy_func = destroy_func;
127 entry->destroy_func_data = destroy_func_data;
128 }
129
130 /* private */
131 static void gtk_tree_entry_class_init(void* g_class, void* class_data)
132 {
133 GObjectClass* gobject_class = G_OBJECT_CLASS(g_class);
134 gobject_class->dispose = gtk_tree_entry_dispose;
135 parent_class = G_OBJECT_CLASS(g_type_class_peek_parent(g_class));
136 }
137
138 static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class)
139 {
140 GtkTreeEntry* entry = (GtkTreeEntry*) instance;
141
142 /* clear */
143 entry->label = NULL;
144 entry->collate_key = NULL;
145 entry->userdata = NULL;
146 entry->destroy_func_data = NULL;
147 entry->destroy_func = NULL;
148 }
149
150 static void gtk_tree_entry_string_transform_func(const GValue *src_value,
151 GValue *dest_value)
152 {
153 GtkTreeEntry *entry;
154 void* src_ptr = g_value_peek_pointer(src_value);
155
156 /* Make sure src is a treeentry and dest can hold a string */
157 g_assert(GTK_IS_TREE_ENTRY(src_ptr));
158 g_assert(G_VALUE_HOLDS(dest_value, G_TYPE_STRING));
159
160 entry = GTK_TREE_ENTRY(src_ptr);
161 g_value_set_string(dest_value, entry->label);
162 }
163
164 static void gtk_tree_entry_dispose(GObject* obj)
165 {
166 GtkTreeEntry *entry;
167
168 g_assert(GTK_IS_TREE_ENTRY(obj));
169
170 entry = GTK_TREE_ENTRY(obj);
171
172 /* free label if it exists */
173 if(entry->label)
174 {
175 g_free(entry->label);
176 g_free(entry->collate_key);
177 entry->label = NULL;
178 entry->collate_key = NULL;
179 }
180
181 /* call destroy callback if it exists */
182 if(entry->destroy_func)
183 {
184 (*entry->destroy_func) (entry, entry->destroy_func_data);
185 entry->destroy_func = NULL;
186 entry->destroy_func_data = NULL;
187 }
188
189 /* clear userdata */
190 entry->userdata = NULL;
191
192 parent_class->dispose(obj);
193 }