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