]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/treeentry_gtk.c
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[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(GtkTreeEntryClass* klass);
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
42 /* public */
43 GtkTreeEntry*
44 gtk_tree_entry_new()
45 {
46 return GTK_TREE_ENTRY(g_object_new(GTK_TYPE_TREE_ENTRY, NULL));
47 }
48
49 GType
50 gtk_tree_entry_get_type ()
51 {
52 static GType tree_entry_type = 0;
53
54 if (!tree_entry_type)
55 {
56 const GTypeInfo tree_entry_info =
57 {
58 sizeof (GtkTreeEntryClass),
59 NULL, /* base_init */
60 NULL, /* base_finalize */
61 (GClassInitFunc) gtk_tree_entry_class_init, /* class_init */
62 NULL, /* class_finalize */
63 NULL, /* class_data */
64 sizeof (GtkTreeEntry),
65 16, /* n_preallocs */
66 (GInstanceInitFunc) gtk_tree_entry_init, /*instance_init*/
67 NULL /* value_table */
68 };
69 tree_entry_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeEntry",
70 &tree_entry_info,
71 (GTypeFlags)0);
72 g_value_register_transform_func(tree_entry_type, G_TYPE_STRING,
73 gtk_tree_entry_string_transform_func);
74 }
75
76 return tree_entry_type;
77 }
78
79 gchar* gtk_tree_entry_get_collate_key (GtkTreeEntry* entry)
80 {
81 return entry->collate_key;
82 }
83
84 gchar* gtk_tree_entry_get_label (GtkTreeEntry* entry)
85 {
86 g_assert(GTK_IS_TREE_ENTRY(entry));
87 return entry->label;
88 }
89
90 gpointer gtk_tree_entry_get_userdata (GtkTreeEntry* entry)
91 {
92 g_assert(GTK_IS_TREE_ENTRY(entry));
93 return entry->userdata;
94 }
95
96 void gtk_tree_entry_set_label (GtkTreeEntry* entry, const gchar* label)
97 {
98 gchar *temp;
99 g_assert(GTK_IS_TREE_ENTRY(entry));
100
101 /* free previous if it exists */
102 if(entry->label)
103 {
104 g_free(entry->label);
105 g_free(entry->collate_key);
106 }
107
108 entry->label = g_strdup(label);
109 temp = g_utf8_casefold(label, -1); /* -1 == null terminated */
110 entry->collate_key = g_utf8_collate_key(temp, -1); /* -1 == null terminated */
111 g_free( temp );
112 }
113
114 void gtk_tree_entry_set_userdata (GtkTreeEntry* entry, gpointer userdata)
115 {
116 g_assert(GTK_IS_TREE_ENTRY(entry));
117 entry->userdata = userdata;
118 }
119
120 void gtk_tree_entry_set_destroy_func (GtkTreeEntry* entry,
121 GtkTreeEntryDestroy destroy_func,
122 gpointer destroy_func_data)
123 {
124 g_assert(GTK_IS_TREE_ENTRY(entry));
125 entry->destroy_func = destroy_func;
126 entry->destroy_func_data = destroy_func_data;
127 }
128
129 /* private */
130 static void gtk_tree_entry_class_init(GtkTreeEntryClass* klass)
131 {
132 GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
133 gobject_class->dispose = gtk_tree_entry_dispose;
134 }
135
136 static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class)
137 {
138 GtkTreeEntry* entry = (GtkTreeEntry*) instance;
139
140 /* clear */
141 entry->label = NULL;
142 entry->collate_key = NULL;
143 entry->userdata = NULL;
144 entry->destroy_func_data = NULL;
145 entry->destroy_func = NULL;
146 }
147
148 static void gtk_tree_entry_string_transform_func(const GValue *src_value,
149 GValue *dest_value)
150 {
151 GtkTreeEntry *entry;
152
153 /* Make sure src is a treeentry and dest can hold a string */
154 g_assert(GTK_IS_TREE_ENTRY(src_value->data[0].v_pointer));
155 g_assert(G_VALUE_HOLDS(dest_value, G_TYPE_STRING));
156
157 /* TODO: Use strdup here or just pass it? */
158 entry = GTK_TREE_ENTRY(src_value->data[0].v_pointer);
159
160 g_value_set_string(dest_value, entry->label);
161 }
162
163 static void gtk_tree_entry_dispose(GObject* obj)
164 {
165 GtkTreeEntry *entry;
166
167 g_assert(GTK_IS_TREE_ENTRY(obj));
168
169 entry = GTK_TREE_ENTRY(obj);
170
171 /* free label if it exists */
172 if(entry->label)
173 {
174 g_free(entry->label);
175 g_free(entry->collate_key);
176 entry->label = NULL;
177 entry->collate_key = NULL;
178 }
179
180 /* call destroy callback if it exists */
181 if(entry->destroy_func)
182 {
183 (*entry->destroy_func) (entry, entry->destroy_func_data);
184 entry->destroy_func = NULL;
185 entry->destroy_func_data = NULL;
186 }
187
188 /* clear userdata */
189 entry->userdata = NULL;
190 }