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