1 /* gtkbuildable.c
2  * Copyright (C) 2006-2007 Async Open Source,
3  *                         Johan Dahlin <jdahlin@async.com.br>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * SECTION:gtkbuildable
21  * @Short_description: Interface for objects that can be built by GtkBuilder
22  * @Title: GtkBuildable
23  *
24  * GtkBuildable allows objects to extend and customize their deserialization
25  * from [GtkBuilder UI descriptions][BUILDER-UI].
26  * The interface includes methods for setting names and properties of objects,
27  * parsing custom tags and constructing child objects.
28  *
29  * The GtkBuildable interface is implemented by all widgets and
30  * many of the non-widget objects that are provided by GTK+. The
31  * main user of this interface is #GtkBuilder. There should be
32  * very little need for applications to call any of these functions directly.
33  *
34  * An object only needs to implement this interface if it needs to extend the
35  * #GtkBuilder format or run any extra routines at deserialization time.
36  */
37 
38 #include "config.h"
39 #include "gtkbuildable.h"
40 #include "gtkintl.h"
41 
42 
43 typedef GtkBuildableIface GtkBuildableInterface;
G_DEFINE_INTERFACE(GtkBuildable,gtk_buildable,G_TYPE_OBJECT)44 G_DEFINE_INTERFACE (GtkBuildable, gtk_buildable, G_TYPE_OBJECT)
45 
46 static void
47 gtk_buildable_default_init (GtkBuildableInterface *iface)
48 {
49 }
50 
51 /**
52  * gtk_buildable_set_name:
53  * @buildable: a #GtkBuildable
54  * @name: name to set
55  *
56  * Sets the name of the @buildable object.
57  *
58  * Since: 2.12
59  **/
60 void
gtk_buildable_set_name(GtkBuildable * buildable,const gchar * name)61 gtk_buildable_set_name (GtkBuildable *buildable,
62                         const gchar  *name)
63 {
64   GtkBuildableIface *iface;
65 
66   g_return_if_fail (GTK_IS_BUILDABLE (buildable));
67   g_return_if_fail (name != NULL);
68 
69   iface = GTK_BUILDABLE_GET_IFACE (buildable);
70 
71   if (iface->set_name)
72     (* iface->set_name) (buildable, name);
73   else
74     g_object_set_data_full (G_OBJECT (buildable),
75 			    "gtk-builder-name",
76 			    g_strdup (name),
77 			    g_free);
78 }
79 
80 /**
81  * gtk_buildable_get_name:
82  * @buildable: a #GtkBuildable
83  *
84  * Gets the name of the @buildable object.
85  *
86  * #GtkBuilder sets the name based on the
87  * [GtkBuilder UI definition][BUILDER-UI]
88  * used to construct the @buildable.
89  *
90  * Returns: the name set with gtk_buildable_set_name()
91  *
92  * Since: 2.12
93  **/
94 const gchar *
gtk_buildable_get_name(GtkBuildable * buildable)95 gtk_buildable_get_name (GtkBuildable *buildable)
96 {
97   GtkBuildableIface *iface;
98 
99   g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
100 
101   iface = GTK_BUILDABLE_GET_IFACE (buildable);
102 
103   if (iface->get_name)
104     return (* iface->get_name) (buildable);
105   else
106     return (const gchar*)g_object_get_data (G_OBJECT (buildable),
107 					    "gtk-builder-name");
108 }
109 
110 /**
111  * gtk_buildable_add_child:
112  * @buildable: a #GtkBuildable
113  * @builder: a #GtkBuilder
114  * @child: child to add
115  * @type: (allow-none): kind of child or %NULL
116  *
117  * Adds a child to @buildable. @type is an optional string
118  * describing how the child should be added.
119  *
120  * Since: 2.12
121  **/
122 void
gtk_buildable_add_child(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * type)123 gtk_buildable_add_child (GtkBuildable *buildable,
124 			 GtkBuilder   *builder,
125 			 GObject      *child,
126 			 const gchar  *type)
127 {
128   GtkBuildableIface *iface;
129 
130   g_return_if_fail (GTK_IS_BUILDABLE (buildable));
131   g_return_if_fail (GTK_IS_BUILDER (builder));
132 
133   iface = GTK_BUILDABLE_GET_IFACE (buildable);
134   g_return_if_fail (iface->add_child != NULL);
135 
136   (* iface->add_child) (buildable, builder, child, type);
137 }
138 
139 /**
140  * gtk_buildable_set_buildable_property:
141  * @buildable: a #GtkBuildable
142  * @builder: a #GtkBuilder
143  * @name: name of property
144  * @value: value of property
145  *
146  * Sets the property name @name to @value on the @buildable object.
147  *
148  * Since: 2.12
149  **/
150 void
gtk_buildable_set_buildable_property(GtkBuildable * buildable,GtkBuilder * builder,const gchar * name,const GValue * value)151 gtk_buildable_set_buildable_property (GtkBuildable *buildable,
152 				      GtkBuilder   *builder,
153 				      const gchar  *name,
154 				      const GValue *value)
155 {
156   GtkBuildableIface *iface;
157 
158   g_return_if_fail (GTK_IS_BUILDABLE (buildable));
159   g_return_if_fail (GTK_IS_BUILDER (builder));
160   g_return_if_fail (name != NULL);
161   g_return_if_fail (value != NULL);
162 
163   iface = GTK_BUILDABLE_GET_IFACE (buildable);
164   if (iface->set_buildable_property)
165     (* iface->set_buildable_property) (buildable, builder, name, value);
166   else
167     g_object_set_property (G_OBJECT (buildable), name, value);
168 }
169 
170 /**
171  * gtk_buildable_parser_finished:
172  * @buildable: a #GtkBuildable
173  * @builder: a #GtkBuilder
174  *
175  * Called when the builder finishes the parsing of a
176  * [GtkBuilder UI definition][BUILDER-UI].
177  * Note that this will be called once for each time
178  * gtk_builder_add_from_file() or gtk_builder_add_from_string()
179  * is called on a builder.
180  *
181  * Since: 2.12
182  **/
183 void
gtk_buildable_parser_finished(GtkBuildable * buildable,GtkBuilder * builder)184 gtk_buildable_parser_finished (GtkBuildable *buildable,
185 			       GtkBuilder   *builder)
186 {
187   GtkBuildableIface *iface;
188 
189   g_return_if_fail (GTK_IS_BUILDABLE (buildable));
190   g_return_if_fail (GTK_IS_BUILDER (builder));
191 
192   iface = GTK_BUILDABLE_GET_IFACE (buildable);
193   if (iface->parser_finished)
194     (* iface->parser_finished) (buildable, builder);
195 }
196 
197 /**
198  * gtk_buildable_construct_child:
199  * @buildable: A #GtkBuildable
200  * @builder: #GtkBuilder used to construct this object
201  * @name: name of child to construct
202  *
203  * Constructs a child of @buildable with the name @name.
204  *
205  * #GtkBuilder calls this function if a “constructor” has been
206  * specified in the UI definition.
207  *
208  * Returns: (transfer full): the constructed child
209  *
210  * Since: 2.12
211  **/
212 GObject *
gtk_buildable_construct_child(GtkBuildable * buildable,GtkBuilder * builder,const gchar * name)213 gtk_buildable_construct_child (GtkBuildable *buildable,
214                                GtkBuilder   *builder,
215                                const gchar  *name)
216 {
217   GtkBuildableIface *iface;
218 
219   g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
220   g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
221   g_return_val_if_fail (name != NULL, NULL);
222 
223   iface = GTK_BUILDABLE_GET_IFACE (buildable);
224   g_return_val_if_fail (iface->construct_child != NULL, NULL);
225 
226   return (* iface->construct_child) (buildable, builder, name);
227 }
228 
229 /**
230  * gtk_buildable_custom_tag_start:
231  * @buildable: a #GtkBuildable
232  * @builder: a #GtkBuilder used to construct this object
233  * @child: (allow-none): child object or %NULL for non-child tags
234  * @tagname: name of tag
235  * @parser: (out): a #GMarkupParser to fill in
236  * @data: (out): return location for user data that will be passed in
237  *   to parser functions
238  *
239  * This is called for each unknown element under `<child>`.
240  *
241  * Returns: %TRUE if a object has a custom implementation, %FALSE
242  *          if it doesn't.
243  *
244  * Since: 2.12
245  **/
246 gboolean
gtk_buildable_custom_tag_start(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,GMarkupParser * parser,gpointer * data)247 gtk_buildable_custom_tag_start (GtkBuildable  *buildable,
248                                 GtkBuilder    *builder,
249                                 GObject       *child,
250                                 const gchar   *tagname,
251                                 GMarkupParser *parser,
252                                 gpointer      *data)
253 {
254   GtkBuildableIface *iface;
255 
256   g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), FALSE);
257   g_return_val_if_fail (GTK_IS_BUILDER (builder), FALSE);
258   g_return_val_if_fail (tagname != NULL, FALSE);
259 
260   iface = GTK_BUILDABLE_GET_IFACE (buildable);
261   g_return_val_if_fail (iface->custom_tag_start != NULL, FALSE);
262 
263   return (* iface->custom_tag_start) (buildable, builder, child,
264                                       tagname, parser, data);
265 }
266 
267 /**
268  * gtk_buildable_custom_tag_end:
269  * @buildable: A #GtkBuildable
270  * @builder: #GtkBuilder used to construct this object
271  * @child: (allow-none): child object or %NULL for non-child tags
272  * @tagname: name of tag
273  * @data: (type gpointer): user data that will be passed in to parser functions
274  *
275  * This is called at the end of each custom element handled by
276  * the buildable.
277  *
278  * Since: 2.12
279  **/
280 void
gtk_buildable_custom_tag_end(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,gpointer * data)281 gtk_buildable_custom_tag_end (GtkBuildable  *buildable,
282                               GtkBuilder    *builder,
283                               GObject       *child,
284                               const gchar   *tagname,
285                               gpointer      *data)
286 {
287   GtkBuildableIface *iface;
288 
289   g_return_if_fail (GTK_IS_BUILDABLE (buildable));
290   g_return_if_fail (GTK_IS_BUILDER (builder));
291   g_return_if_fail (tagname != NULL);
292 
293   iface = GTK_BUILDABLE_GET_IFACE (buildable);
294   if (iface->custom_tag_end)
295     (* iface->custom_tag_end) (buildable, builder, child, tagname, data);
296 }
297 
298 /**
299  * gtk_buildable_custom_finished:
300  * @buildable: a #GtkBuildable
301  * @builder: a #GtkBuilder
302  * @child: (allow-none): child object or %NULL for non-child tags
303  * @tagname: the name of the tag
304  * @data: user data created in custom_tag_start
305  *
306  * This is similar to gtk_buildable_parser_finished() but is
307  * called once for each custom tag handled by the @buildable.
308  *
309  * Since: 2.12
310  **/
311 void
gtk_buildable_custom_finished(GtkBuildable * buildable,GtkBuilder * builder,GObject * child,const gchar * tagname,gpointer data)312 gtk_buildable_custom_finished (GtkBuildable  *buildable,
313 			       GtkBuilder    *builder,
314 			       GObject       *child,
315 			       const gchar   *tagname,
316 			       gpointer       data)
317 {
318   GtkBuildableIface *iface;
319 
320   g_return_if_fail (GTK_IS_BUILDABLE (buildable));
321   g_return_if_fail (GTK_IS_BUILDER (builder));
322 
323   iface = GTK_BUILDABLE_GET_IFACE (buildable);
324   if (iface->custom_finished)
325     (* iface->custom_finished) (buildable, builder, child, tagname, data);
326 }
327 
328 /**
329  * gtk_buildable_get_internal_child:
330  * @buildable: a #GtkBuildable
331  * @builder: a #GtkBuilder
332  * @childname: name of child
333  *
334  * Get the internal child called @childname of the @buildable object.
335  *
336  * Returns: (transfer none): the internal child of the buildable object
337  *
338  * Since: 2.12
339  **/
340 GObject *
gtk_buildable_get_internal_child(GtkBuildable * buildable,GtkBuilder * builder,const gchar * childname)341 gtk_buildable_get_internal_child (GtkBuildable *buildable,
342                                   GtkBuilder   *builder,
343                                   const gchar  *childname)
344 {
345   GtkBuildableIface *iface;
346 
347   g_return_val_if_fail (GTK_IS_BUILDABLE (buildable), NULL);
348   g_return_val_if_fail (GTK_IS_BUILDER (builder), NULL);
349   g_return_val_if_fail (childname != NULL, NULL);
350 
351   iface = GTK_BUILDABLE_GET_IFACE (buildable);
352   if (!iface->get_internal_child)
353     return NULL;
354 
355   return (* iface->get_internal_child) (buildable, builder, childname);
356 }
357