| File: | ctk/ctkbuilder.c |
| Warning: | line 783, column 43 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* CTK - The GIMP Toolkit |
| 2 | * Copyright (C) 1998-2002 James Henstridge <james@daa.com.au> |
| 3 | * Copyright (C) 2006-2007 Async Open Source, |
| 4 | * Johan Dahlin <jdahlin@async.com.br>, |
| 5 | * Henrique Romano <henrique@async.com.br> |
| 6 | * |
| 7 | * This library is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU Library General Public |
| 9 | * License as published by the Free Software Foundation; either |
| 10 | * version 2 of the License, or (at your option) any later version. |
| 11 | * |
| 12 | * This library is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * Library General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU Library General Public |
| 18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 19 | */ |
| 20 | |
| 21 | /** |
| 22 | * SECTION:ctkbuilder |
| 23 | * @Short_description: Build an interface from an XML UI definition |
| 24 | * @Title: CtkBuilder |
| 25 | * |
| 26 | * A CtkBuilder is an auxiliary object that reads textual descriptions |
| 27 | * of a user interface and instantiates the described objects. To create |
| 28 | * a CtkBuilder from a user interface description, call |
| 29 | * ctk_builder_new_from_file(), ctk_builder_new_from_resource() or |
| 30 | * ctk_builder_new_from_string(). |
| 31 | * |
| 32 | * In the (unusual) case that you want to add user interface |
| 33 | * descriptions from multiple sources to the same CtkBuilder you can |
| 34 | * call ctk_builder_new() to get an empty builder and populate it by |
| 35 | * (multiple) calls to ctk_builder_add_from_file(), |
| 36 | * ctk_builder_add_from_resource() or ctk_builder_add_from_string(). |
| 37 | * |
| 38 | * A CtkBuilder holds a reference to all objects that it has constructed |
| 39 | * and drops these references when it is finalized. This finalization can |
| 40 | * cause the destruction of non-widget objects or widgets which are not |
| 41 | * contained in a toplevel window. For toplevel windows constructed by a |
| 42 | * builder, it is the responsibility of the user to call ctk_widget_destroy() |
| 43 | * to get rid of them and all the widgets they contain. |
| 44 | * |
| 45 | * The functions ctk_builder_get_object() and ctk_builder_get_objects() |
| 46 | * can be used to access the widgets in the interface by the names assigned |
| 47 | * to them inside the UI description. Toplevel windows returned by these |
| 48 | * functions will stay around until the user explicitly destroys them |
| 49 | * with ctk_widget_destroy(). Other widgets will either be part of a |
| 50 | * larger hierarchy constructed by the builder (in which case you should |
| 51 | * not have to worry about their lifecycle), or without a parent, in which |
| 52 | * case they have to be added to some container to make use of them. |
| 53 | * Non-widget objects need to be reffed with g_object_ref() to keep them |
| 54 | * beyond the lifespan of the builder. |
| 55 | * |
| 56 | * The function ctk_builder_connect_signals() and variants thereof can be |
| 57 | * used to connect handlers to the named signals in the description. |
| 58 | * |
| 59 | * # CtkBuilder UI Definitions # {#BUILDER-UI} |
| 60 | * |
| 61 | * CtkBuilder parses textual descriptions of user interfaces which are |
| 62 | * specified in an XML format which can be roughly described by the |
| 63 | * RELAX NG schema below. We refer to these descriptions as “CtkBuilder |
| 64 | * UI definitions” or just “UI definitions” if the context is clear. |
| 65 | * Do not confuse CtkBuilder UI Definitions with |
| 66 | * [CtkUIManager UI Definitions][XML-UI], which are more limited in scope. |
| 67 | * It is common to use `.ui` as the filename extension for files containing |
| 68 | * CtkBuilder UI definitions. |
| 69 | * |
| 70 | * [RELAX NG Compact Syntax](https://gitlab.gnome.org/GNOME/ctk/-/blob/ctk-3-24/ctk/ctkbuilder.rnc) |
| 71 | * |
| 72 | * The toplevel element is <interface>. It optionally takes a “domain” |
| 73 | * attribute, which will make the builder look for translated strings |
| 74 | * using dgettext() in the domain specified. This can also be done by |
| 75 | * calling ctk_builder_set_translation_domain() on the builder. |
| 76 | * Objects are described by <object> elements, which can contain |
| 77 | * <property> elements to set properties, <signal> elements which |
| 78 | * connect signals to handlers, and <child> elements, which describe |
| 79 | * child objects (most often widgets inside a container, but also e.g. |
| 80 | * actions in an action group, or columns in a tree model). A <child> |
| 81 | * element contains an <object> element which describes the child object. |
| 82 | * The target toolkit version(s) are described by <requires> elements, |
| 83 | * the “lib” attribute specifies the widget library in question (currently |
| 84 | * the only supported value is “ctk+”) and the “version” attribute specifies |
| 85 | * the target version in the form “<major>.<minor>”. The builder will error |
| 86 | * out if the version requirements are not met. |
| 87 | * |
| 88 | * Typically, the specific kind of object represented by an <object> |
| 89 | * element is specified by the “class” attribute. If the type has not |
| 90 | * been loaded yet, CTK+ tries to find the get_type() function from the |
| 91 | * class name by applying heuristics. This works in most cases, but if |
| 92 | * necessary, it is possible to specify the name of the get_type() function |
| 93 | * explictly with the "type-func" attribute. As a special case, CtkBuilder |
| 94 | * allows to use an object that has been constructed by a #CtkUIManager in |
| 95 | * another part of the UI definition by specifying the id of the #CtkUIManager |
| 96 | * in the “constructor” attribute and the name of the object in the “id” |
| 97 | * attribute. |
| 98 | * |
| 99 | * Objects may be given a name with the “id” attribute, which allows the |
| 100 | * application to retrieve them from the builder with ctk_builder_get_object(). |
| 101 | * An id is also necessary to use the object as property value in other |
| 102 | * parts of the UI definition. CTK+ reserves ids starting and ending |
| 103 | * with ___ (3 underscores) for its own purposes. |
| 104 | * |
| 105 | * Setting properties of objects is pretty straightforward with the |
| 106 | * <property> element: the “name” attribute specifies the name of the |
| 107 | * property, and the content of the element specifies the value. |
| 108 | * If the “translatable” attribute is set to a true value, CTK+ uses |
| 109 | * gettext() (or dgettext() if the builder has a translation domain set) |
| 110 | * to find a translation for the value. This happens before the value |
| 111 | * is parsed, so it can be used for properties of any type, but it is |
| 112 | * probably most useful for string properties. It is also possible to |
| 113 | * specify a context to disambiguate short strings, and comments which |
| 114 | * may help the translators. |
| 115 | * |
| 116 | * CtkBuilder can parse textual representations for the most common |
| 117 | * property types: characters, strings, integers, floating-point numbers, |
| 118 | * booleans (strings like “TRUE”, “t”, “yes”, “y”, “1” are interpreted |
| 119 | * as %TRUE, strings like “FALSE”, “f”, “no”, “n”, “0” are interpreted |
| 120 | * as %FALSE), enumerations (can be specified by their name, nick or |
| 121 | * integer value), flags (can be specified by their name, nick, integer |
| 122 | * value, optionally combined with “|”, e.g. “CTK_VISIBLE|CTK_REALIZED”) |
| 123 | * and colors (in a format understood by cdk_rgba_parse()). |
| 124 | * |
| 125 | * GVariants can be specified in the format understood by g_variant_parse(), |
| 126 | * and pixbufs can be specified as a filename of an image file to load. |
| 127 | * |
| 128 | * Objects can be referred to by their name and by default refer to |
| 129 | * objects declared in the local xml fragment and objects exposed via |
| 130 | * ctk_builder_expose_object(). In general, CtkBuilder allows forward |
| 131 | * references to objects — declared in the local xml; an object doesn’t |
| 132 | * have to be constructed before it can be referred to. The exception |
| 133 | * to this rule is that an object has to be constructed before it can |
| 134 | * be used as the value of a construct-only property. |
| 135 | * |
| 136 | * It is also possible to bind a property value to another object's |
| 137 | * property value using the attributes |
| 138 | * "bind-source" to specify the source object of the binding, |
| 139 | * "bind-property" to specify the source property and optionally |
| 140 | * "bind-flags" to specify the binding flags. |
| 141 | * Internally builder implements this using GBinding objects. |
| 142 | * For more information see g_object_bind_property() |
| 143 | * |
| 144 | * Signal handlers are set up with the <signal> element. The “name” |
| 145 | * attribute specifies the name of the signal, and the “handler” attribute |
| 146 | * specifies the function to connect to the signal. By default, CTK+ tries |
| 147 | * to find the handler using g_module_symbol(), but this can be changed by |
| 148 | * passing a custom #CtkBuilderConnectFunc to |
| 149 | * ctk_builder_connect_signals_full(). The remaining attributes, “after”, |
| 150 | * “swapped” and “object”, have the same meaning as the corresponding |
| 151 | * parameters of the g_signal_connect_object() or |
| 152 | * g_signal_connect_data() functions. A “last_modification_time” |
| 153 | * attribute is also allowed, but it does not have a meaning to the |
| 154 | * builder. |
| 155 | * |
| 156 | * Sometimes it is necessary to refer to widgets which have implicitly |
| 157 | * been constructed by CTK+ as part of a composite widget, to set |
| 158 | * properties on them or to add further children (e.g. the @vbox of |
| 159 | * a #CtkDialog). This can be achieved by setting the “internal-child” |
| 160 | * property of the <child> element to a true value. Note that CtkBuilder |
| 161 | * still requires an <object> element for the internal child, even if it |
| 162 | * has already been constructed. |
| 163 | * |
| 164 | * A number of widgets have different places where a child can be added |
| 165 | * (e.g. tabs vs. page content in notebooks). This can be reflected in |
| 166 | * a UI definition by specifying the “type” attribute on a <child> |
| 167 | * The possible values for the “type” attribute are described in the |
| 168 | * sections describing the widget-specific portions of UI definitions. |
| 169 | * |
| 170 | * # A CtkBuilder UI Definition |
| 171 | * |
| 172 | * |[ |
| 173 | * <interface> |
| 174 | * <object class="CtkDialog" id="dialog1"> |
| 175 | * <child internal-child="vbox"> |
| 176 | * <object class="CtkBox" id="vbox1"> |
| 177 | * <property name="border-width">10</property> |
| 178 | * <child internal-child="action_area"> |
| 179 | * <object class="CtkButtonBox" id="hbuttonbox1"> |
| 180 | * <property name="border-width">20</property> |
| 181 | * <child> |
| 182 | * <object class="CtkButton" id="ok_button"> |
| 183 | * <property name="label">ctk-ok</property> |
| 184 | * <property name="use-stock">TRUE</property> |
| 185 | * <signal name="clicked" handler="ok_button_clicked"/> |
| 186 | * </object> |
| 187 | * </child> |
| 188 | * </object> |
| 189 | * </child> |
| 190 | * </object> |
| 191 | * </child> |
| 192 | * </object> |
| 193 | * </interface> |
| 194 | * ]| |
| 195 | * |
| 196 | * Beyond this general structure, several object classes define their |
| 197 | * own XML DTD fragments for filling in the ANY placeholders in the DTD |
| 198 | * above. Note that a custom element in a <child> element gets parsed by |
| 199 | * the custom tag handler of the parent object, while a custom element in |
| 200 | * an <object> element gets parsed by the custom tag handler of the object. |
| 201 | * |
| 202 | * These XML fragments are explained in the documentation of the |
| 203 | * respective objects. |
| 204 | * |
| 205 | * Additionally, since 3.10 a special <template> tag has been added |
| 206 | * to the format allowing one to define a widget class’s components. |
| 207 | * See the [CtkWidget documentation][composite-templates] for details. |
| 208 | */ |
| 209 | |
| 210 | #include "config.h" |
| 211 | #include <errno(*__errno_location ()).h> /* errno */ |
| 212 | #include <stdlib.h> |
| 213 | #include <string.h> /* strlen */ |
| 214 | |
| 215 | #include "ctkbuilder.h" |
| 216 | #include "ctkbuildable.h" |
| 217 | #include "ctkbuilderprivate.h" |
| 218 | #include "ctkdebug.h" |
| 219 | #include "ctkmain.h" |
| 220 | #include "ctkintl.h" |
| 221 | #include "ctkprivate.h" |
| 222 | #include "ctktypebuiltins.h" |
| 223 | #include "ctkwindow.h" |
| 224 | #include "ctkicontheme.h" |
| 225 | #include "ctktestutils.h" |
| 226 | #include "ctkstock.h" |
| 227 | |
| 228 | |
| 229 | static void ctk_builder_class_init (CtkBuilderClass *klass); |
| 230 | static void ctk_builder_init (CtkBuilder *builder); |
| 231 | static void ctk_builder_finalize (GObject *object); |
| 232 | static void ctk_builder_set_property (GObject *object, |
| 233 | guint prop_id, |
| 234 | const GValue *value, |
| 235 | GParamSpec *pspec); |
| 236 | static void ctk_builder_get_property (GObject *object, |
| 237 | guint prop_id, |
| 238 | GValue *value, |
| 239 | GParamSpec *pspec); |
| 240 | static GType ctk_builder_real_get_type_from_name (CtkBuilder *builder, |
| 241 | const gchar *type_name); |
| 242 | |
| 243 | enum { |
| 244 | PROP_0, |
| 245 | PROP_TRANSLATION_DOMAIN, |
| 246 | LAST_PROP |
| 247 | }; |
| 248 | |
| 249 | static GParamSpec *builder_props[LAST_PROP]; |
| 250 | |
| 251 | struct _CtkBuilderPrivate |
| 252 | { |
| 253 | gchar *domain; |
| 254 | GHashTable *objects; |
| 255 | GHashTable *callbacks; |
| 256 | GSList *delayed_properties; |
| 257 | GSList *signals; |
| 258 | GSList *bindings; |
| 259 | gchar *filename; |
| 260 | gchar *resource_prefix; |
| 261 | GType template_type; |
| 262 | CtkApplication *application; |
| 263 | }; |
| 264 | |
| 265 | G_DEFINE_TYPE_WITH_PRIVATE (CtkBuilder, ctk_builder, G_TYPE_OBJECT)static void ctk_builder_init (CtkBuilder *self); static void ctk_builder_class_init (CtkBuilderClass *klass); static GType ctk_builder_get_type_once (void); static gpointer ctk_builder_parent_class = ((void*)0 ); static gint CtkBuilder_private_offset; static void ctk_builder_class_intern_init (gpointer klass) { ctk_builder_parent_class = g_type_class_peek_parent (klass); if (CtkBuilder_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkBuilder_private_offset); ctk_builder_class_init ((CtkBuilderClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_builder_get_instance_private (CtkBuilder *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkBuilder_private_offset )))); } GType ctk_builder_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_builder_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_builder_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((( GType) ((20) << (2))), g_intern_static_string ("CtkBuilder" ), sizeof (CtkBuilderClass), (GClassInitFunc)(void (*)(void)) ctk_builder_class_intern_init, sizeof (CtkBuilder), (GInstanceInitFunc )(void (*)(void)) ctk_builder_init, (GTypeFlags) 0); { {{ CtkBuilder_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkBuilderPrivate )); };} } return g_define_type_id; } |
| 266 | |
| 267 | static void |
| 268 | ctk_builder_class_init (CtkBuilderClass *klass) |
| 269 | { |
| 270 | GObjectClass *gobject_class; |
| 271 | |
| 272 | gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); |
| 273 | |
| 274 | gobject_class->finalize = ctk_builder_finalize; |
| 275 | gobject_class->set_property = ctk_builder_set_property; |
| 276 | gobject_class->get_property = ctk_builder_get_property; |
| 277 | |
| 278 | klass->get_type_from_name = ctk_builder_real_get_type_from_name; |
| 279 | |
| 280 | /** |
| 281 | * CtkBuilder:translation-domain: |
| 282 | * |
| 283 | * The translation domain used when translating property values that |
| 284 | * have been marked as translatable in interface descriptions. |
| 285 | * If the translation domain is %NULL, #CtkBuilder uses gettext(), |
| 286 | * otherwise g_dgettext(). |
| 287 | * |
| 288 | * Since: 2.12 |
| 289 | */ |
| 290 | builder_props[PROP_TRANSLATION_DOMAIN] = |
| 291 | g_param_spec_string ("translation-domain", |
| 292 | P_("Translation Domain")g_dgettext("ctk30" "-properties","Translation Domain"), |
| 293 | P_("The translation domain used by gettext")g_dgettext("ctk30" "-properties","The translation domain used by gettext" ), |
| 294 | NULL((void*)0), |
| 295 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); |
| 296 | |
| 297 | g_object_class_install_properties (gobject_class, LAST_PROP, builder_props); |
| 298 | } |
| 299 | |
| 300 | static void |
| 301 | ctk_builder_init (CtkBuilder *builder) |
| 302 | { |
| 303 | builder->priv = ctk_builder_get_instance_private (builder); |
| 304 | builder->priv->domain = NULL((void*)0); |
| 305 | builder->priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal, |
| 306 | g_free, g_object_unref); |
| 307 | } |
| 308 | |
| 309 | |
| 310 | /* |
| 311 | * GObject virtual methods |
| 312 | */ |
| 313 | |
| 314 | static void |
| 315 | ctk_builder_finalize (GObject *object) |
| 316 | { |
| 317 | CtkBuilderPrivate *priv = CTK_BUILDER (object)((((CtkBuilder*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_builder_get_type ()))))))->priv; |
| 318 | |
| 319 | g_free (priv->domain); |
| 320 | g_free (priv->filename); |
| 321 | g_free (priv->resource_prefix); |
| 322 | |
| 323 | g_hash_table_destroy (priv->objects); |
| 324 | if (priv->callbacks) |
| 325 | g_hash_table_destroy (priv->callbacks); |
| 326 | |
| 327 | g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info); |
| 328 | |
| 329 | G_OBJECT_CLASS (ctk_builder_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_builder_parent_class)), (((GType) ((20) << (2) )))))))->finalize (object); |
| 330 | } |
| 331 | |
| 332 | static void |
| 333 | ctk_builder_set_property (GObject *object, |
| 334 | guint prop_id, |
| 335 | const GValue *value, |
| 336 | GParamSpec *pspec) |
| 337 | { |
| 338 | CtkBuilder *builder = CTK_BUILDER (object)((((CtkBuilder*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_builder_get_type ())))))); |
| 339 | |
| 340 | switch (prop_id) |
| 341 | { |
| 342 | case PROP_TRANSLATION_DOMAIN: |
| 343 | ctk_builder_set_translation_domain (builder, g_value_get_string (value)); |
| 344 | break; |
| 345 | default: |
| 346 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkbuilder.c", 346, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
| 347 | break; |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | static void |
| 352 | ctk_builder_get_property (GObject *object, |
| 353 | guint prop_id, |
| 354 | GValue *value, |
| 355 | GParamSpec *pspec) |
| 356 | { |
| 357 | CtkBuilder *builder = CTK_BUILDER (object)((((CtkBuilder*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_builder_get_type ())))))); |
| 358 | |
| 359 | switch (prop_id) |
| 360 | { |
| 361 | case PROP_TRANSLATION_DOMAIN: |
| 362 | g_value_set_string (value, builder->priv->domain); |
| 363 | break; |
| 364 | default: |
| 365 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkbuilder.c", 365, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
| 366 | break; |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | |
| 371 | /* |
| 372 | * Try to map a type name to a _get_type function |
| 373 | * and call it, eg: |
| 374 | * |
| 375 | * CtkWindow -> ctk_window_get_type |
| 376 | * CtkHBox -> ctk_hbox_get_type |
| 377 | * CtkUIManager -> ctk_ui_manager_get_type |
| 378 | * GWeatherLocation -> gweather_location_get_type |
| 379 | * |
| 380 | * Keep in sync with testsuite/ctk/typename.c ! |
| 381 | */ |
| 382 | static gchar * |
| 383 | type_name_mangle (const gchar *name) |
| 384 | { |
| 385 | GString *symbol_name = g_string_new (""); |
| 386 | gint i; |
| 387 | |
| 388 | for (i = 0; name[i] != '\0'; i++) |
| 389 | { |
| 390 | /* skip if uppercase, first or previous is uppercase */ |
| 391 | if ((name[i] == g_ascii_toupper (name[i]) && |
| 392 | i > 0 && name[i-1] != g_ascii_toupper (name[i-1])) || |
| 393 | (i > 2 && name[i] == g_ascii_toupper (name[i]) && |
| 394 | name[i-1] == g_ascii_toupper (name[i-1]) && |
| 395 | name[i-2] == g_ascii_toupper (name[i-2]))) |
| 396 | g_string_append_c (symbol_name, '_')g_string_append_c_inline (symbol_name, '_'); |
| 397 | g_string_append_c (symbol_name, g_ascii_tolower (name[i]))g_string_append_c_inline (symbol_name, g_ascii_tolower (name[ i])); |
| 398 | } |
| 399 | g_string_append (symbol_name, "_get_type")(__builtin_constant_p ("_get_type") ? __extension__ ({ const char * const __val = ("_get_type"); g_string_append_len_inline (symbol_name , __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (symbol_name , "_get_type", (gssize) -1)); |
| 400 | |
| 401 | return g_string_free (symbol_name, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((symbol_name ), ((0))) : g_string_free_and_steal (symbol_name)) : (g_string_free ) ((symbol_name), ((0)))); |
| 402 | } |
| 403 | |
| 404 | static GType |
| 405 | _ctk_builder_resolve_type_lazily (const gchar *name) |
| 406 | { |
| 407 | static GModule *module = NULL((void*)0); |
| 408 | GTypeGetFunc func; |
| 409 | gchar *symbol; |
| 410 | GType gtype = G_TYPE_INVALID((GType) ((0) << (2))); |
| 411 | |
| 412 | if (!module) |
| 413 | module = g_module_open (NULL((void*)0), 0); |
| 414 | |
| 415 | symbol = type_name_mangle (name); |
| 416 | |
| 417 | if (g_module_symbol (module, symbol, (gpointer)&func)) |
| 418 | gtype = func (); |
| 419 | |
| 420 | g_free (symbol); |
| 421 | |
| 422 | return gtype; |
| 423 | } |
| 424 | |
| 425 | /* |
| 426 | * CtkBuilder virtual methods |
| 427 | */ |
| 428 | |
| 429 | static GType |
| 430 | ctk_builder_real_get_type_from_name (CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)), |
| 431 | const gchar *type_name) |
| 432 | { |
| 433 | GType gtype; |
| 434 | |
| 435 | gtype = g_type_from_name (type_name); |
| 436 | if (gtype != G_TYPE_INVALID((GType) ((0) << (2)))) |
| 437 | return gtype; |
| 438 | |
| 439 | gtype = _ctk_builder_resolve_type_lazily (type_name); |
| 440 | if (gtype != G_TYPE_INVALID((GType) ((0) << (2)))) |
| 441 | return gtype; |
| 442 | |
| 443 | ctk_test_register_all_types (); |
| 444 | return g_type_from_name (type_name); |
| 445 | } |
| 446 | |
| 447 | typedef struct |
| 448 | { |
| 449 | gchar *object; |
| 450 | GParamSpec *pspec; |
| 451 | gchar *value; |
| 452 | gint line; |
| 453 | gint col; |
| 454 | } DelayedProperty; |
| 455 | |
| 456 | typedef struct |
| 457 | { |
| 458 | GPtrArray *names; |
| 459 | GArray *values; |
| 460 | guint len; |
| 461 | } ObjectProperties; |
| 462 | |
| 463 | static ObjectProperties * |
| 464 | object_properties_new (void) |
| 465 | { |
| 466 | ObjectProperties *res = g_new (ObjectProperties, 1)((ObjectProperties *) g_malloc_n ((1), sizeof (ObjectProperties ))); |
| 467 | |
| 468 | res->names = g_ptr_array_new (); |
| 469 | |
| 470 | res->values = g_array_new (FALSE(0), FALSE(0), sizeof (GValue)); |
| 471 | g_array_set_clear_func (res->values, (GDestroyNotify) g_value_unset); |
| 472 | |
| 473 | res->len = 0; |
| 474 | |
| 475 | return res; |
| 476 | } |
| 477 | |
| 478 | static void |
| 479 | object_properties_free (ObjectProperties *properties) |
| 480 | { |
| 481 | if (properties == NULL((void*)0)) |
| 482 | return; |
| 483 | |
| 484 | g_ptr_array_unref (properties->names); |
| 485 | g_array_unref (properties->values); |
| 486 | |
| 487 | g_free (properties); |
| 488 | } |
| 489 | |
| 490 | static void |
| 491 | object_properties_add (ObjectProperties *properties, |
| 492 | const char *name, |
| 493 | const GValue *value) |
| 494 | { |
| 495 | g_ptr_array_add (properties->names, (char *) name); |
| 496 | g_array_append_vals (properties->values, value, 1); |
| 497 | |
| 498 | g_assert (properties->names->len == properties->values->len)do { if (properties->names->len == properties->values ->len) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c" , 498, ((const char*) (__func__)), "properties->names->len == properties->values->len" ); } while (0); |
| 499 | |
| 500 | properties->len += 1; |
| 501 | } |
| 502 | |
| 503 | static const char * |
| 504 | object_properties_get_name (ObjectProperties *properties, |
| 505 | guint idx) |
| 506 | { |
| 507 | return g_ptr_array_index (properties->names, idx)((properties->names)->pdata)[idx]; |
| 508 | } |
| 509 | |
| 510 | static GValue * |
| 511 | object_properties_get_value (ObjectProperties *properties, |
| 512 | guint idx) |
| 513 | { |
| 514 | return &g_array_index (properties->values, GValue, idx)(((GValue*) (void *) (properties->values)->data) [(idx) ]); |
| 515 | } |
| 516 | |
| 517 | static void |
| 518 | ctk_builder_get_parameters (CtkBuilder *builder, |
| 519 | GType object_type, |
| 520 | const gchar *object_name, |
| 521 | GSList *properties, |
| 522 | GParamFlags filter_flags, |
| 523 | ObjectProperties **parameters, |
| 524 | ObjectProperties **filtered_parameters) |
| 525 | { |
| 526 | GSList *l; |
| 527 | DelayedProperty *property; |
| 528 | GError *error = NULL((void*)0); |
| 529 | |
| 530 | if (parameters) |
| 531 | *parameters = object_properties_new (); |
| 532 | if (filtered_parameters) |
| 533 | *filtered_parameters = object_properties_new (); |
| 534 | |
| 535 | for (l = properties; l; l = l->next) |
| 536 | { |
| 537 | PropertyInfo *prop = (PropertyInfo*)l->data; |
| 538 | const char *property_name = g_intern_string (prop->pspec->name); |
| 539 | GValue property_value = G_VALUE_INIT{ 0, { { 0 } } }; |
| 540 | |
| 541 | if (G_IS_PARAM_SPEC_OBJECT (prop->pspec)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (prop->pspec)); GType __t = ((g_param_spec_types[19])); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) && |
| 542 | (G_PARAM_SPEC_VALUE_TYPE (prop->pspec)(((((GParamSpec*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((prop->pspec)), (((GType) ((19) << (2))))))))-> value_type) != GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ())) && |
| 543 | (G_PARAM_SPEC_VALUE_TYPE (prop->pspec)(((((GParamSpec*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((prop->pspec)), (((GType) ((19) << (2))))))))-> value_type) != G_TYPE_FILE(g_file_get_type ()))) |
| 544 | { |
| 545 | GObject *object = g_hash_table_lookup (builder->priv->objects, |
| 546 | prop->text->str); |
| 547 | |
| 548 | if (object) |
| 549 | { |
| 550 | g_value_init (&property_value, G_OBJECT_TYPE (object)(((((GTypeClass*) (((GTypeInstance*) (object))->g_class))-> g_type)))); |
| 551 | g_value_set_object (&property_value, object); |
| 552 | } |
| 553 | else |
| 554 | { |
| 555 | if (prop->pspec->flags & G_PARAM_CONSTRUCT_ONLY) |
| 556 | { |
| 557 | g_warning ("Failed to get construct only property " |
| 558 | "%s of %s with value '%s'", |
| 559 | prop->pspec->name, object_name, prop->text->str); |
| 560 | continue; |
| 561 | } |
| 562 | /* Delay setting property */ |
| 563 | property = g_slice_new (DelayedProperty)((DelayedProperty*) g_slice_alloc (sizeof (DelayedProperty))); |
| 564 | property->pspec = prop->pspec; |
| 565 | property->object = g_strdup (object_name)g_strdup_inline (object_name); |
| 566 | property->value = g_strdup (prop->text->str)g_strdup_inline (prop->text->str); |
| 567 | property->line = prop->line; |
| 568 | property->col = prop->col; |
| 569 | builder->priv->delayed_properties = |
| 570 | g_slist_prepend (builder->priv->delayed_properties, property); |
| 571 | continue; |
| 572 | } |
| 573 | } |
| 574 | else if (prop->bound && (!prop->text || prop->text->len == 0)) |
| 575 | { |
| 576 | /* Ignore properties with a binding and no value since they are |
| 577 | * only there for to express the binding. |
| 578 | */ |
| 579 | continue; |
| 580 | } |
| 581 | else if (!ctk_builder_value_from_string (builder, prop->pspec, |
| 582 | prop->text->str, |
| 583 | &property_value, |
| 584 | &error)) |
| 585 | { |
| 586 | g_warning ("Failed to set property %s.%s to %s: %s", |
| 587 | g_type_name (object_type), prop->pspec->name, prop->text->str, |
| 588 | error->message); |
| 589 | g_error_free (error); |
| 590 | error = NULL((void*)0); |
| 591 | continue; |
| 592 | } |
| 593 | |
| 594 | if (prop->pspec->flags & filter_flags) |
| 595 | { |
| 596 | if (filtered_parameters) |
| 597 | object_properties_add (*filtered_parameters, property_name, &property_value); |
| 598 | } |
| 599 | else |
| 600 | { |
| 601 | if (parameters) |
| 602 | object_properties_add (*parameters, property_name, &property_value); |
| 603 | } |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | static const gchar * |
| 608 | object_get_name (GObject *object) |
| 609 | { |
| 610 | if (CTK_IS_BUILDABLE (object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (object)); GType __t = ((ctk_buildable_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 611 | return ctk_buildable_get_name (CTK_BUILDABLE (object)((((CtkBuildable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_buildable_get_type ()))))))); |
| 612 | else |
| 613 | return g_object_get_data (object, "ctk-builder-name"); |
| 614 | } |
| 615 | |
| 616 | static GObject * |
| 617 | ctk_builder_get_internal_child (CtkBuilder *builder, |
| 618 | ObjectInfo *info, |
| 619 | const gchar *childname, |
| 620 | GError **error) |
| 621 | { |
| 622 | GObject *obj = NULL((void*)0); |
| 623 | |
| 624 | while (!obj) |
| 625 | { |
| 626 | if (!info->parent) |
| 627 | break; |
| 628 | |
| 629 | info = (ObjectInfo*)((ChildInfo*)info->parent)->parent; |
| 630 | if (!info) |
| 631 | break; |
| 632 | |
| 633 | CTK_NOTE (BUILDER,do { if ((ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) { g_message ("Trying to get internal child %s from %s", childname, object_get_name (info->object)); }; } while (0) |
| 634 | g_message ("Trying to get internal child %s from %s",do { if ((ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) { g_message ("Trying to get internal child %s from %s", childname, object_get_name (info->object)); }; } while (0) |
| 635 | childname, object_get_name (info->object)))do { if ((ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) { g_message ("Trying to get internal child %s from %s", childname, object_get_name (info->object)); }; } while (0); |
| 636 | |
| 637 | if (CTK_IS_BUILDABLE (info->object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (info->object)); GType __t = ((ctk_buildable_get_type ())) ; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0) ); else __r = g_type_check_instance_is_a (__inst, __t); __r; } ))))) |
| 638 | obj = ctk_buildable_get_internal_child (CTK_BUILDABLE (info->object)((((CtkBuildable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((info->object)), ((ctk_buildable_get_type ())))))), |
| 639 | builder, |
| 640 | childname); |
| 641 | }; |
| 642 | |
| 643 | if (!obj) |
| 644 | { |
| 645 | g_set_error (error, |
| 646 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 647 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 648 | "Unknown internal child: %s", childname); |
| 649 | } |
| 650 | return obj; |
| 651 | } |
| 652 | |
| 653 | static inline void |
| 654 | object_set_name (GObject *object, |
| 655 | const gchar *name) |
| 656 | { |
| 657 | if (CTK_IS_BUILDABLE (object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (object)); GType __t = ((ctk_buildable_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 658 | ctk_buildable_set_name (CTK_BUILDABLE (object)((((CtkBuildable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_buildable_get_type ())))))), name); |
| 659 | else |
| 660 | g_object_set_data_full (object, "ctk-builder-name", g_strdup (name)g_strdup_inline (name), g_free); |
| 661 | } |
| 662 | |
| 663 | void |
| 664 | _ctk_builder_add_object (CtkBuilder *builder, |
| 665 | const gchar *id, |
| 666 | GObject *object) |
| 667 | { |
| 668 | object_set_name (object, id); |
| 669 | g_hash_table_insert (builder->priv->objects, g_strdup (id)g_strdup_inline (id), g_object_ref (object)((__typeof__ (object)) (g_object_ref) (object))); |
| 670 | } |
| 671 | |
| 672 | static void |
| 673 | ctk_builder_take_bindings (CtkBuilder *builder, |
| 674 | GObject *target, |
| 675 | GSList *bindings) |
| 676 | { |
| 677 | GSList *l; |
| 678 | |
| 679 | for (l = bindings; l; l = l->next) |
| 680 | { |
| 681 | BindingInfo *info = l->data; |
| 682 | info->target = target; |
| 683 | } |
| 684 | |
| 685 | builder->priv->bindings = g_slist_concat (builder->priv->bindings, bindings); |
| 686 | } |
| 687 | |
| 688 | GObject * |
| 689 | _ctk_builder_construct (CtkBuilder *builder, |
| 690 | ObjectInfo *info, |
| 691 | GError **error) |
| 692 | { |
| 693 | ObjectProperties *parameters, *construct_parameters; |
| 694 | GObject *obj; |
| 695 | int i; |
| 696 | CtkBuildableIface *iface; |
| 697 | gboolean custom_set_property; |
| 698 | CtkBuildable *buildable; |
| 699 | GParamFlags param_filter_flags; |
| 700 | |
| 701 | g_assert (info->type != G_TYPE_INVALID)do { if (info->type != ((GType) ((0) << (2)))) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 701, ((const char*) (__func__)), "info->type != G_TYPE_INVALID"); } while (0); |
| 702 | |
| 703 | if (builder->priv->template_type != 0 && |
| 704 | g_type_is_a (info->type, builder->priv->template_type)((info->type) == (builder->priv->template_type) || ( g_type_is_a) ((info->type), (builder->priv->template_type )))) |
| 705 | { |
| 706 | g_set_error (error, |
| 707 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 708 | CTK_BUILDER_ERROR_OBJECT_TYPE_REFUSED, |
| 709 | "Refused to build object of type '%s' because it " |
| 710 | "conforms to the template type '%s', avoiding infinite recursion.", |
| 711 | g_type_name (info->type), g_type_name (builder->priv->template_type)); |
| 712 | return NULL((void*)0); |
| 713 | } |
| 714 | |
| 715 | /* If there is a manual constructor (like UIManager), or if this is a |
| 716 | * reference to an internal child, then we filter out construct-only |
| 717 | * and warn that they cannot be set. |
| 718 | * |
| 719 | * Otherwise if we are calling g_object_new_with_properties(), we want |
| 720 | * to pass both G_PARAM_CONSTRUCT and G_PARAM_CONSTRUCT_ONLY to the |
| 721 | * object's constructor. |
| 722 | * |
| 723 | * Passing all construct properties to g_object_new_with_properties() |
| 724 | * slightly improves performance as the construct properties will only |
| 725 | * be set once. |
| 726 | */ |
| 727 | if (info->constructor || |
| 728 | (info->parent && ((ChildInfo*)info->parent)->internal_child != NULL((void*)0))) |
| 729 | param_filter_flags = G_PARAM_CONSTRUCT_ONLY; |
| 730 | else |
| 731 | param_filter_flags = G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY; |
| 732 | |
| 733 | ctk_builder_get_parameters (builder, info->type, |
| 734 | info->id, |
| 735 | info->properties, |
| 736 | param_filter_flags, |
| 737 | ¶meters, |
| 738 | &construct_parameters); |
| 739 | |
| 740 | if (info->constructor) |
| 741 | { |
| 742 | GObject *constructor; |
| 743 | |
| 744 | constructor = g_hash_table_lookup (builder->priv->objects, info->constructor); |
| 745 | if (constructor == NULL((void*)0)) |
| 746 | { |
| 747 | g_set_error (error, |
| 748 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 749 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 750 | "Unknown object constructor for %s: %s", |
| 751 | info->id, |
| 752 | info->constructor); |
| 753 | object_properties_free (parameters); |
| 754 | object_properties_free (construct_parameters); |
| 755 | return NULL((void*)0); |
| 756 | } |
| 757 | obj = ctk_buildable_construct_child (CTK_BUILDABLE (constructor)((((CtkBuildable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((constructor)), ((ctk_buildable_get_type ())))))), |
| 758 | builder, |
| 759 | info->id); |
| 760 | g_assert (obj != NULL)do { if (obj != ((void*)0)) ; else g_assertion_message_expr ( "Ctk", "ctkbuilder.c", 760, ((const char*) (__func__)), "obj != NULL" ); } while (0); |
| 761 | if (construct_parameters->len) |
| 762 | g_warning ("Can't pass in construct-only parameters to %s", info->id); |
| 763 | } |
| 764 | else if (info->parent && ((ChildInfo*)info->parent)->internal_child != NULL((void*)0)) |
| 765 | { |
| 766 | gchar *childname = ((ChildInfo*)info->parent)->internal_child; |
| 767 | obj = ctk_builder_get_internal_child (builder, info, childname, error); |
| 768 | if (!obj) |
| 769 | { |
| 770 | object_properties_free (parameters); |
| 771 | object_properties_free (construct_parameters); |
| 772 | return NULL((void*)0); |
| 773 | } |
| 774 | if (construct_parameters->len) |
| 775 | g_warning ("Can't pass in construct-only parameters to %s", childname); |
| 776 | g_object_ref (obj)((__typeof__ (obj)) (g_object_ref) (obj)); |
| 777 | } |
| 778 | else |
| 779 | { |
| 780 | obj = g_object_new_with_properties (info->type, |
| 781 | construct_parameters->len, |
| 782 | (const char **) construct_parameters->names->pdata, |
| 783 | (GValue *) construct_parameters->values->data); |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
| 784 | |
| 785 | /* No matter what, make sure we have a reference. |
| 786 | * |
| 787 | * If it's an initially unowned object, sink it. |
| 788 | * If it's not initially unowned then we have the reference already. |
| 789 | * |
| 790 | * In the case that this is a window it will be sunk already and |
| 791 | * this is effectively a call to g_object_ref(). That's what |
| 792 | * we want. |
| 793 | */ |
| 794 | if (G_IS_INITIALLY_UNOWNED (obj)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (obj)); GType __t = ((g_initially_unowned_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 795 | g_object_ref_sink (obj)((__typeof__ (obj)) (g_object_ref_sink) (obj)); |
| 796 | |
| 797 | CTK_NOTE (BUILDER,do { if ((ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) { g_message ("created %s of type %s", info->id, g_type_name (info-> type)); }; } while (0) |
| 798 | g_message ("created %s of type %s", info->id, g_type_name (info->type)))do { if ((ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) { g_message ("created %s of type %s", info->id, g_type_name (info-> type)); }; } while (0); |
| 799 | } |
| 800 | |
| 801 | object_properties_free (construct_parameters); |
| 802 | |
| 803 | custom_set_property = FALSE(0); |
| 804 | buildable = NULL((void*)0); |
| 805 | iface = NULL((void*)0); |
| 806 | if (CTK_IS_BUILDABLE (obj)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (obj)); GType __t = ((ctk_buildable_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 807 | { |
| 808 | buildable = CTK_BUILDABLE (obj)((((CtkBuildable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((obj)), ((ctk_buildable_get_type ())))))); |
| 809 | iface = CTK_BUILDABLE_GET_IFACE (obj)((((CtkBuildableIface*) g_type_interface_peek (((GTypeInstance *) ((obj)))->g_class, ((ctk_buildable_get_type ())))))); |
| 810 | if (iface->set_buildable_property) |
| 811 | custom_set_property = TRUE(!(0)); |
| 812 | } |
| 813 | |
| 814 | /* We're going to set multiple properties in one go, so it's better |
| 815 | * to notify changes at the end |
| 816 | */ |
| 817 | g_object_freeze_notify (obj); |
| 818 | |
| 819 | for (i = 0; i < parameters->len; i++) |
| 820 | { |
| 821 | const char *name = object_properties_get_name (parameters, i); |
| 822 | const GValue *value = object_properties_get_value (parameters, i); |
| 823 | |
| 824 | if (custom_set_property) |
| 825 | iface->set_buildable_property (buildable, builder, name, value); |
| 826 | else |
| 827 | g_object_set_property (obj, name, value); |
| 828 | |
| 829 | #ifdef G_ENABLE_DEBUG1 |
| 830 | if (CTK_DEBUG_CHECK (BUILDER)(ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) |
| 831 | { |
| 832 | gchar *str = g_strdup_value_contents (value); |
| 833 | g_message ("set %s: %s = %s", info->id, name, str); |
| 834 | g_free (str); |
| 835 | } |
| 836 | #endif |
| 837 | } |
| 838 | |
| 839 | g_object_thaw_notify (obj); |
| 840 | |
| 841 | object_properties_free (parameters); |
| 842 | |
| 843 | if (info->bindings) |
| 844 | ctk_builder_take_bindings (builder, obj, info->bindings); |
| 845 | |
| 846 | /* put it in the hash table. */ |
| 847 | _ctk_builder_add_object (builder, info->id, obj); |
| 848 | |
| 849 | /* we already own a reference to obj. */ |
| 850 | g_object_unref (obj); |
| 851 | |
| 852 | return obj; |
| 853 | } |
| 854 | |
| 855 | void |
| 856 | _ctk_builder_apply_properties (CtkBuilder *builder, |
| 857 | ObjectInfo *info, |
| 858 | GError **error G_GNUC_UNUSED__attribute__ ((__unused__))) |
| 859 | { |
| 860 | ObjectProperties *parameters; |
| 861 | CtkBuildableIface *iface; |
| 862 | CtkBuildable *buildable; |
| 863 | gboolean custom_set_property; |
| 864 | gint i; |
| 865 | |
| 866 | g_assert (info->object != NULL)do { if (info->object != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 866, ((const char*) (__func__)), "info->object != NULL" ); } while (0); |
| 867 | g_assert (info->type != G_TYPE_INVALID)do { if (info->type != ((GType) ((0) << (2)))) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 867, ((const char*) (__func__)), "info->type != G_TYPE_INVALID"); } while (0); |
| 868 | |
| 869 | /* Fetch all properties that are not construct-only */ |
| 870 | ctk_builder_get_parameters (builder, info->type, |
| 871 | info->id, |
| 872 | info->properties, |
| 873 | G_PARAM_CONSTRUCT_ONLY, |
| 874 | ¶meters, NULL((void*)0)); |
| 875 | |
| 876 | custom_set_property = FALSE(0); |
| 877 | buildable = NULL((void*)0); |
| 878 | iface = NULL((void*)0); |
| 879 | if (CTK_IS_BUILDABLE (info->object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (info->object)); GType __t = ((ctk_buildable_get_type ())) ; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0) ); else __r = g_type_check_instance_is_a (__inst, __t); __r; } ))))) |
| 880 | { |
| 881 | buildable = CTK_BUILDABLE (info->object)((((CtkBuildable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((info->object)), ((ctk_buildable_get_type ())))))); |
| 882 | iface = CTK_BUILDABLE_GET_IFACE (info->object)((((CtkBuildableIface*) g_type_interface_peek (((GTypeInstance *) ((info->object)))->g_class, ((ctk_buildable_get_type ())))))); |
| 883 | if (iface->set_buildable_property) |
| 884 | custom_set_property = TRUE(!(0)); |
| 885 | } |
| 886 | |
| 887 | g_object_freeze_notify (info->object); |
| 888 | |
| 889 | for (i = 0; i < parameters->len; i++) |
| 890 | { |
| 891 | const char *name = object_properties_get_name (parameters, i); |
| 892 | const GValue *value = object_properties_get_value (parameters, i); |
| 893 | if (custom_set_property) |
| 894 | iface->set_buildable_property (buildable, builder, name, value); |
| 895 | else |
| 896 | g_object_set_property (info->object, name, value); |
| 897 | |
| 898 | #ifdef G_ENABLE_DEBUG1 |
| 899 | if (CTK_DEBUG_CHECK (BUILDER)(ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) |
| 900 | { |
| 901 | gchar *str = g_strdup_value_contents (value); |
| 902 | g_message ("set %s: %s = %s", info->id, name, str); |
| 903 | g_free (str); |
| 904 | } |
| 905 | #endif |
| 906 | } |
| 907 | |
| 908 | g_object_thaw_notify (info->object); |
| 909 | |
| 910 | object_properties_free (parameters); |
| 911 | } |
| 912 | |
| 913 | void |
| 914 | _ctk_builder_add (CtkBuilder *builder, |
| 915 | ChildInfo *child_info) |
| 916 | { |
| 917 | GObject *object; |
| 918 | GObject *parent; |
| 919 | |
| 920 | /* Internal children are already added |
| 921 | * Also prevent us from being called twice. |
| 922 | */ |
| 923 | if (!child_info || |
| 924 | child_info->internal_child || |
| 925 | child_info->added) |
| 926 | return; |
| 927 | |
| 928 | object = child_info->object; |
| 929 | if (!object) |
| 930 | return; |
| 931 | |
| 932 | if (!child_info->parent) |
| 933 | { |
| 934 | g_warning ("%s: Not adding, No parent", object_get_name (object)); |
| 935 | return; |
| 936 | } |
| 937 | |
| 938 | g_assert (object != NULL)do { if (object != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 938, ((const char*) (__func__)), "object != NULL" ); } while (0); |
| 939 | |
| 940 | parent = ((ObjectInfo*)child_info->parent)->object; |
| 941 | g_assert (CTK_IS_BUILDABLE (parent))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((parent)); GType __t = ((ctk_buildable_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 941, ((const char*) (__func__)), "CTK_IS_BUILDABLE (parent)"); } while (0 ); |
| 942 | |
| 943 | CTK_NOTE (BUILDER,do { if ((ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) { g_message ("adding %s to %s", object_get_name (object), object_get_name (parent)); }; } while (0) |
| 944 | g_message ("adding %s to %s", object_get_name (object), object_get_name (parent)))do { if ((ctk_get_debug_flags () & CTK_DEBUG_BUILDER)) { g_message ("adding %s to %s", object_get_name (object), object_get_name (parent)); }; } while (0); |
| 945 | |
| 946 | ctk_buildable_add_child (CTK_BUILDABLE (parent)((((CtkBuildable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((parent)), ((ctk_buildable_get_type ())))))), builder, object, |
| 947 | child_info->type); |
| 948 | |
| 949 | child_info->added = TRUE(!(0)); |
| 950 | } |
| 951 | |
| 952 | void |
| 953 | _ctk_builder_add_signals (CtkBuilder *builder, |
| 954 | GSList *signals) |
| 955 | { |
| 956 | builder->priv->signals = g_slist_concat (builder->priv->signals, |
| 957 | g_slist_copy (signals)); |
| 958 | } |
| 959 | |
| 960 | static void |
| 961 | ctk_builder_apply_delayed_properties (CtkBuilder *builder) |
| 962 | { |
| 963 | GSList *l, *props; |
| 964 | |
| 965 | /* take the list over from the builder->priv. |
| 966 | * |
| 967 | * g_slist_reverse does not copy the list, so the list now |
| 968 | * belongs to us (and we free it at the end of this function). |
| 969 | */ |
| 970 | props = g_slist_reverse (builder->priv->delayed_properties); |
| 971 | builder->priv->delayed_properties = NULL((void*)0); |
| 972 | |
| 973 | for (l = props; l; l = l->next) |
| 974 | { |
| 975 | DelayedProperty *property = l->data; |
| 976 | GObject *object, *obj; |
| 977 | |
| 978 | object = g_hash_table_lookup (builder->priv->objects, property->object); |
| 979 | g_assert (object != NULL)do { if (object != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 979, ((const char*) (__func__)), "object != NULL" ); } while (0); |
| 980 | |
| 981 | obj = _ctk_builder_lookup_object (builder, property->value, property->line, property->col); |
| 982 | if (obj) |
| 983 | g_object_set (object, property->pspec->name, obj, NULL((void*)0)); |
| 984 | |
| 985 | g_free (property->value); |
| 986 | g_free (property->object); |
| 987 | g_slice_free (DelayedProperty, property)do { if (1) g_slice_free1 (sizeof (DelayedProperty), (property )); else (void) ((DelayedProperty*) 0 == (property)); } while (0); |
| 988 | } |
| 989 | g_slist_free (props); |
| 990 | } |
| 991 | |
| 992 | static inline void |
| 993 | free_binding_info (gpointer data, |
| 994 | gpointer user G_GNUC_UNUSED__attribute__ ((__unused__))) |
| 995 | { |
| 996 | BindingInfo *info = data; |
| 997 | |
| 998 | g_free (info->source); |
| 999 | g_free (info->source_property); |
| 1000 | g_slice_free (BindingInfo, data)do { if (1) g_slice_free1 (sizeof (BindingInfo), (data)); else (void) ((BindingInfo*) 0 == (data)); } while (0); |
| 1001 | } |
| 1002 | |
| 1003 | static inline void |
| 1004 | ctk_builder_create_bindings (CtkBuilder *builder) |
| 1005 | { |
| 1006 | GSList *l; |
| 1007 | |
| 1008 | for (l = builder->priv->bindings; l; l = l->next) |
| 1009 | { |
| 1010 | BindingInfo *info = l->data; |
| 1011 | GObject *source; |
| 1012 | |
| 1013 | source = _ctk_builder_lookup_object (builder, info->source, info->line, info->col); |
| 1014 | if (source) |
| 1015 | g_object_bind_property (source, info->source_property, |
| 1016 | info->target, info->target_pspec->name, |
| 1017 | info->flags); |
| 1018 | |
| 1019 | free_binding_info (info, NULL((void*)0)); |
| 1020 | } |
| 1021 | |
| 1022 | g_slist_free (builder->priv->bindings); |
| 1023 | builder->priv->bindings = NULL((void*)0); |
| 1024 | } |
| 1025 | |
| 1026 | void |
| 1027 | _ctk_builder_finish (CtkBuilder *builder) |
| 1028 | { |
| 1029 | ctk_builder_apply_delayed_properties (builder); |
| 1030 | ctk_builder_create_bindings (builder); |
| 1031 | } |
| 1032 | |
| 1033 | /** |
| 1034 | * ctk_builder_new: |
| 1035 | * |
| 1036 | * Creates a new empty builder object. |
| 1037 | * |
| 1038 | * This function is only useful if you intend to make multiple calls |
| 1039 | * to ctk_builder_add_from_file(), ctk_builder_add_from_resource() |
| 1040 | * or ctk_builder_add_from_string() in order to merge multiple UI |
| 1041 | * descriptions into a single builder. |
| 1042 | * |
| 1043 | * Most users will probably want to use ctk_builder_new_from_file(), |
| 1044 | * ctk_builder_new_from_resource() or ctk_builder_new_from_string(). |
| 1045 | * |
| 1046 | * Returns: a new (empty) #CtkBuilder object |
| 1047 | * |
| 1048 | * Since: 2.12 |
| 1049 | **/ |
| 1050 | CtkBuilder * |
| 1051 | ctk_builder_new (void) |
| 1052 | { |
| 1053 | return g_object_new (CTK_TYPE_BUILDER(ctk_builder_get_type ()), NULL((void*)0)); |
| 1054 | } |
| 1055 | |
| 1056 | /** |
| 1057 | * ctk_builder_add_from_file: |
| 1058 | * @builder: a #CtkBuilder |
| 1059 | * @filename: the name of the file to parse |
| 1060 | * @error: (allow-none): return location for an error, or %NULL |
| 1061 | * |
| 1062 | * Parses a file containing a [CtkBuilder UI definition][BUILDER-UI] |
| 1063 | * and merges it with the current contents of @builder. |
| 1064 | * |
| 1065 | * Most users will probably want to use ctk_builder_new_from_file(). |
| 1066 | * |
| 1067 | * If an error occurs, 0 will be returned and @error will be assigned a |
| 1068 | * #GError from the #CTK_BUILDER_ERROR, #G_MARKUP_ERROR or #G_FILE_ERROR |
| 1069 | * domain. |
| 1070 | * |
| 1071 | * It’s not really reasonable to attempt to handle failures of this |
| 1072 | * call. You should not use this function with untrusted files (ie: |
| 1073 | * files that are not part of your application). Broken #CtkBuilder |
| 1074 | * files can easily crash your program, and it’s possible that memory |
| 1075 | * was leaked leading up to the reported failure. The only reasonable |
| 1076 | * thing to do when an error is detected is to call g_error(). |
| 1077 | * |
| 1078 | * Returns: A positive value on success, 0 if an error occurred |
| 1079 | * |
| 1080 | * Since: 2.12 |
| 1081 | **/ |
| 1082 | guint |
| 1083 | ctk_builder_add_from_file (CtkBuilder *builder, |
| 1084 | const gchar *filename, |
| 1085 | GError **error) |
| 1086 | { |
| 1087 | gchar *buffer; |
| 1088 | gsize length; |
| 1089 | GError *tmp_error; |
| 1090 | |
| 1091 | g_return_val_if_fail (CTK_IS_BUILDER (builder), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (0); } } while (0); |
| 1092 | g_return_val_if_fail (filename != NULL, 0)do { if ((filename != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "filename != NULL"); return (0); } } while (0); |
| 1093 | g_return_val_if_fail (error == NULL || *error == NULL, 0)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return (0); } } while ( 0); |
| 1094 | |
| 1095 | tmp_error = NULL((void*)0); |
| 1096 | |
| 1097 | if (!g_file_get_contents (filename, &buffer, &length, &tmp_error)) |
| 1098 | { |
| 1099 | g_propagate_error (error, tmp_error); |
| 1100 | return 0; |
| 1101 | } |
| 1102 | |
| 1103 | g_free (builder->priv->filename); |
| 1104 | g_free (builder->priv->resource_prefix); |
| 1105 | builder->priv->filename = g_strdup (filename)g_strdup_inline (filename); |
| 1106 | builder->priv->resource_prefix = NULL((void*)0); |
| 1107 | |
| 1108 | _ctk_builder_parser_parse_buffer (builder, filename, |
| 1109 | buffer, length, |
| 1110 | NULL((void*)0), |
| 1111 | &tmp_error); |
| 1112 | |
| 1113 | g_free (buffer); |
| 1114 | |
| 1115 | if (tmp_error != NULL((void*)0)) |
| 1116 | { |
| 1117 | g_propagate_error (error, tmp_error); |
| 1118 | return 0; |
| 1119 | } |
| 1120 | |
| 1121 | return 1; |
| 1122 | } |
| 1123 | |
| 1124 | /** |
| 1125 | * ctk_builder_add_objects_from_file: |
| 1126 | * @builder: a #CtkBuilder |
| 1127 | * @filename: the name of the file to parse |
| 1128 | * @object_ids: (array zero-terminated=1) (element-type utf8): nul-terminated array of objects to build |
| 1129 | * @error: (allow-none): return location for an error, or %NULL |
| 1130 | * |
| 1131 | * Parses a file containing a [CtkBuilder UI definition][BUILDER-UI] |
| 1132 | * building only the requested objects and merges |
| 1133 | * them with the current contents of @builder. |
| 1134 | * |
| 1135 | * Upon errors 0 will be returned and @error will be assigned a |
| 1136 | * #GError from the #CTK_BUILDER_ERROR, #G_MARKUP_ERROR or #G_FILE_ERROR |
| 1137 | * domain. |
| 1138 | * |
| 1139 | * If you are adding an object that depends on an object that is not |
| 1140 | * its child (for instance a #CtkTreeView that depends on its |
| 1141 | * #CtkTreeModel), you have to explicitly list all of them in @object_ids. |
| 1142 | * |
| 1143 | * Returns: A positive value on success, 0 if an error occurred |
| 1144 | * |
| 1145 | * Since: 2.14 |
| 1146 | **/ |
| 1147 | guint |
| 1148 | ctk_builder_add_objects_from_file (CtkBuilder *builder, |
| 1149 | const gchar *filename, |
| 1150 | gchar **object_ids, |
| 1151 | GError **error) |
| 1152 | { |
| 1153 | gchar *buffer; |
| 1154 | gsize length; |
| 1155 | GError *tmp_error; |
| 1156 | |
| 1157 | g_return_val_if_fail (CTK_IS_BUILDER (builder), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (0); } } while (0); |
| 1158 | g_return_val_if_fail (filename != NULL, 0)do { if ((filename != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "filename != NULL"); return (0); } } while (0); |
| 1159 | g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0)do { if ((object_ids != ((void*)0) && object_ids[0] != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "object_ids != NULL && object_ids[0] != NULL" ); return (0); } } while (0); |
| 1160 | g_return_val_if_fail (error == NULL || *error == NULL, 0)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return (0); } } while ( 0); |
| 1161 | |
| 1162 | tmp_error = NULL((void*)0); |
| 1163 | |
| 1164 | if (!g_file_get_contents (filename, &buffer, &length, &tmp_error)) |
| 1165 | { |
| 1166 | g_propagate_error (error, tmp_error); |
| 1167 | return 0; |
| 1168 | } |
| 1169 | |
| 1170 | g_free (builder->priv->filename); |
| 1171 | g_free (builder->priv->resource_prefix); |
| 1172 | builder->priv->filename = g_strdup (filename)g_strdup_inline (filename); |
| 1173 | builder->priv->resource_prefix = NULL((void*)0); |
| 1174 | |
| 1175 | _ctk_builder_parser_parse_buffer (builder, filename, |
| 1176 | buffer, length, |
| 1177 | object_ids, |
| 1178 | &tmp_error); |
| 1179 | |
| 1180 | g_free (buffer); |
| 1181 | |
| 1182 | if (tmp_error != NULL((void*)0)) |
| 1183 | { |
| 1184 | g_propagate_error (error, tmp_error); |
| 1185 | return 0; |
| 1186 | } |
| 1187 | |
| 1188 | return 1; |
| 1189 | } |
| 1190 | |
| 1191 | |
| 1192 | /** |
| 1193 | * ctk_builder_extend_with_template: |
| 1194 | * @builder: a #CtkBuilder |
| 1195 | * @widget: the widget that is being extended |
| 1196 | * @template_type: the type that the template is for |
| 1197 | * @buffer: the string to parse |
| 1198 | * @length: the length of @buffer (may be -1 if @buffer is nul-terminated) |
| 1199 | * @error: (allow-none): return location for an error, or %NULL |
| 1200 | * |
| 1201 | * Main private entry point for building composite container |
| 1202 | * components from template XML. |
| 1203 | * |
| 1204 | * This is exported purely to let ctk-builder-tool validate |
| 1205 | * templates, applications have no need to call this function. |
| 1206 | * |
| 1207 | * Returns: A positive value on success, 0 if an error occurred |
| 1208 | */ |
| 1209 | guint |
| 1210 | ctk_builder_extend_with_template (CtkBuilder *builder, |
| 1211 | CtkWidget *widget, |
| 1212 | GType template_type, |
| 1213 | const gchar *buffer, |
| 1214 | gsize length, |
| 1215 | GError **error) |
| 1216 | { |
| 1217 | GError *tmp_error; |
| 1218 | |
| 1219 | g_return_val_if_fail (CTK_IS_BUILDER (builder), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (0); } } while (0); |
| 1220 | g_return_val_if_fail (CTK_IS_WIDGET (widget), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return (0); } } while (0); |
| 1221 | g_return_val_if_fail (g_type_name (template_type) != NULL, 0)do { if ((g_type_name (template_type) != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "g_type_name (template_type) != NULL"); return (0); } } while (0); |
| 1222 | g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (widget), template_type), 0)do { if (((((((((GTypeClass*) (((GTypeInstance*) (widget))-> g_class))->g_type)))) == (template_type) || (g_type_is_a) ( ((((((GTypeClass*) (((GTypeInstance*) (widget))->g_class)) ->g_type)))), (template_type))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "g_type_is_a (G_OBJECT_TYPE (widget), template_type)" ); return (0); } } while (0); |
| 1223 | g_return_val_if_fail (buffer && buffer[0], 0)do { if ((buffer && buffer[0])) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "buffer && buffer[0]" ); return (0); } } while (0); |
| 1224 | |
| 1225 | tmp_error = NULL((void*)0); |
| 1226 | |
| 1227 | g_free (builder->priv->filename); |
| 1228 | g_free (builder->priv->resource_prefix); |
| 1229 | builder->priv->filename = g_strdup (".")g_strdup_inline ("."); |
| 1230 | builder->priv->resource_prefix = NULL((void*)0); |
| 1231 | builder->priv->template_type = template_type; |
| 1232 | |
| 1233 | ctk_builder_expose_object (builder, g_type_name (template_type), G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2))))))))); |
| 1234 | _ctk_builder_parser_parse_buffer (builder, "<input>", |
| 1235 | buffer, length, |
| 1236 | NULL((void*)0), |
| 1237 | &tmp_error); |
| 1238 | |
| 1239 | if (tmp_error != NULL((void*)0)) |
| 1240 | { |
| 1241 | g_propagate_error (error, tmp_error); |
| 1242 | return 0; |
| 1243 | } |
| 1244 | |
| 1245 | return 1; |
| 1246 | } |
| 1247 | |
| 1248 | /** |
| 1249 | * ctk_builder_add_from_resource: |
| 1250 | * @builder: a #CtkBuilder |
| 1251 | * @resource_path: the path of the resource file to parse |
| 1252 | * @error: (allow-none): return location for an error, or %NULL |
| 1253 | * |
| 1254 | * Parses a resource file containing a [CtkBuilder UI definition][BUILDER-UI] |
| 1255 | * and merges it with the current contents of @builder. |
| 1256 | * |
| 1257 | * Most users will probably want to use ctk_builder_new_from_resource(). |
| 1258 | * |
| 1259 | * If an error occurs, 0 will be returned and @error will be assigned a |
| 1260 | * #GError from the #CTK_BUILDER_ERROR, #G_MARKUP_ERROR or #G_RESOURCE_ERROR |
| 1261 | * domain. |
| 1262 | * |
| 1263 | * It’s not really reasonable to attempt to handle failures of this |
| 1264 | * call. The only reasonable thing to do when an error is detected is |
| 1265 | * to call g_error(). |
| 1266 | * |
| 1267 | * Returns: A positive value on success, 0 if an error occurred |
| 1268 | * |
| 1269 | * Since: 3.4 |
| 1270 | **/ |
| 1271 | guint |
| 1272 | ctk_builder_add_from_resource (CtkBuilder *builder, |
| 1273 | const gchar *resource_path, |
| 1274 | GError **error) |
| 1275 | { |
| 1276 | GError *tmp_error; |
| 1277 | GBytes *data; |
| 1278 | char *filename_for_errors; |
| 1279 | char *slash; |
| 1280 | |
| 1281 | g_return_val_if_fail (CTK_IS_BUILDER (builder), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (0); } } while (0); |
| 1282 | g_return_val_if_fail (resource_path != NULL, 0)do { if ((resource_path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "resource_path != NULL") ; return (0); } } while (0); |
| 1283 | g_return_val_if_fail (error == NULL || *error == NULL, 0)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return (0); } } while ( 0); |
| 1284 | |
| 1285 | tmp_error = NULL((void*)0); |
| 1286 | |
| 1287 | data = g_resources_lookup_data (resource_path, 0, &tmp_error); |
| 1288 | if (data == NULL((void*)0)) |
| 1289 | { |
| 1290 | g_propagate_error (error, tmp_error); |
| 1291 | return 0; |
| 1292 | } |
| 1293 | |
| 1294 | g_free (builder->priv->filename); |
| 1295 | g_free (builder->priv->resource_prefix); |
| 1296 | builder->priv->filename = g_strdup (".")g_strdup_inline ("."); |
| 1297 | |
| 1298 | slash = strrchr (resource_path, '/'); |
| 1299 | if (slash != NULL((void*)0)) |
| 1300 | builder->priv->resource_prefix = |
| 1301 | g_strndup (resource_path, slash - resource_path + 1); |
| 1302 | else |
| 1303 | builder->priv->resource_prefix = |
| 1304 | g_strdup ("/")g_strdup_inline ("/"); |
| 1305 | |
| 1306 | filename_for_errors = g_strconcat ("<resource>", resource_path, NULL((void*)0)); |
| 1307 | |
| 1308 | _ctk_builder_parser_parse_buffer (builder, filename_for_errors, |
| 1309 | g_bytes_get_data (data, NULL((void*)0)), g_bytes_get_size (data), |
| 1310 | NULL((void*)0), |
| 1311 | &tmp_error); |
| 1312 | |
| 1313 | g_free (filename_for_errors); |
| 1314 | g_bytes_unref (data); |
| 1315 | |
| 1316 | if (tmp_error != NULL((void*)0)) |
| 1317 | { |
| 1318 | g_propagate_error (error, tmp_error); |
| 1319 | return 0; |
| 1320 | } |
| 1321 | |
| 1322 | return 1; |
| 1323 | } |
| 1324 | |
| 1325 | /** |
| 1326 | * ctk_builder_add_objects_from_resource: |
| 1327 | * @builder: a #CtkBuilder |
| 1328 | * @resource_path: the path of the resource file to parse |
| 1329 | * @object_ids: (array zero-terminated=1) (element-type utf8): nul-terminated array of objects to build |
| 1330 | * @error: (allow-none): return location for an error, or %NULL |
| 1331 | * |
| 1332 | * Parses a resource file containing a [CtkBuilder UI definition][BUILDER-UI] |
| 1333 | * building only the requested objects and merges |
| 1334 | * them with the current contents of @builder. |
| 1335 | * |
| 1336 | * Upon errors 0 will be returned and @error will be assigned a |
| 1337 | * #GError from the #CTK_BUILDER_ERROR, #G_MARKUP_ERROR or #G_RESOURCE_ERROR |
| 1338 | * domain. |
| 1339 | * |
| 1340 | * If you are adding an object that depends on an object that is not |
| 1341 | * its child (for instance a #CtkTreeView that depends on its |
| 1342 | * #CtkTreeModel), you have to explicitly list all of them in @object_ids. |
| 1343 | * |
| 1344 | * Returns: A positive value on success, 0 if an error occurred |
| 1345 | * |
| 1346 | * Since: 3.4 |
| 1347 | **/ |
| 1348 | guint |
| 1349 | ctk_builder_add_objects_from_resource (CtkBuilder *builder, |
| 1350 | const gchar *resource_path, |
| 1351 | gchar **object_ids, |
| 1352 | GError **error) |
| 1353 | { |
| 1354 | GError *tmp_error; |
| 1355 | GBytes *data; |
| 1356 | char *filename_for_errors; |
| 1357 | char *slash; |
| 1358 | |
| 1359 | g_return_val_if_fail (CTK_IS_BUILDER (builder), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (0); } } while (0); |
| 1360 | g_return_val_if_fail (resource_path != NULL, 0)do { if ((resource_path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "resource_path != NULL") ; return (0); } } while (0); |
| 1361 | g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0)do { if ((object_ids != ((void*)0) && object_ids[0] != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "object_ids != NULL && object_ids[0] != NULL" ); return (0); } } while (0); |
| 1362 | g_return_val_if_fail (error == NULL || *error == NULL, 0)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return (0); } } while ( 0); |
| 1363 | |
| 1364 | tmp_error = NULL((void*)0); |
| 1365 | |
| 1366 | data = g_resources_lookup_data (resource_path, 0, &tmp_error); |
| 1367 | if (data == NULL((void*)0)) |
| 1368 | { |
| 1369 | g_propagate_error (error, tmp_error); |
| 1370 | return 0; |
| 1371 | } |
| 1372 | |
| 1373 | g_free (builder->priv->filename); |
| 1374 | g_free (builder->priv->resource_prefix); |
| 1375 | builder->priv->filename = g_strdup (".")g_strdup_inline ("."); |
| 1376 | |
| 1377 | slash = strrchr (resource_path, '/'); |
| 1378 | if (slash != NULL((void*)0)) |
| 1379 | builder->priv->resource_prefix = |
| 1380 | g_strndup (resource_path, slash - resource_path + 1); |
| 1381 | else |
| 1382 | builder->priv->resource_prefix = |
| 1383 | g_strdup ("/")g_strdup_inline ("/"); |
| 1384 | |
| 1385 | filename_for_errors = g_strconcat ("<resource>", resource_path, NULL((void*)0)); |
| 1386 | |
| 1387 | _ctk_builder_parser_parse_buffer (builder, filename_for_errors, |
| 1388 | g_bytes_get_data (data, NULL((void*)0)), g_bytes_get_size (data), |
| 1389 | object_ids, |
| 1390 | &tmp_error); |
| 1391 | g_free (filename_for_errors); |
| 1392 | g_bytes_unref (data); |
| 1393 | |
| 1394 | if (tmp_error != NULL((void*)0)) |
| 1395 | { |
| 1396 | g_propagate_error (error, tmp_error); |
| 1397 | return 0; |
| 1398 | } |
| 1399 | |
| 1400 | return 1; |
| 1401 | } |
| 1402 | |
| 1403 | /** |
| 1404 | * ctk_builder_add_from_string: |
| 1405 | * @builder: a #CtkBuilder |
| 1406 | * @buffer: the string to parse |
| 1407 | * @length: the length of @buffer (may be -1 if @buffer is nul-terminated) |
| 1408 | * @error: (allow-none): return location for an error, or %NULL |
| 1409 | * |
| 1410 | * Parses a string containing a [CtkBuilder UI definition][BUILDER-UI] |
| 1411 | * and merges it with the current contents of @builder. |
| 1412 | * |
| 1413 | * Most users will probably want to use ctk_builder_new_from_string(). |
| 1414 | * |
| 1415 | * Upon errors 0 will be returned and @error will be assigned a |
| 1416 | * #GError from the #CTK_BUILDER_ERROR, #G_MARKUP_ERROR or |
| 1417 | * #G_VARIANT_PARSE_ERROR domain. |
| 1418 | * |
| 1419 | * It’s not really reasonable to attempt to handle failures of this |
| 1420 | * call. The only reasonable thing to do when an error is detected is |
| 1421 | * to call g_error(). |
| 1422 | * |
| 1423 | * Returns: A positive value on success, 0 if an error occurred |
| 1424 | * |
| 1425 | * Since: 2.12 |
| 1426 | **/ |
| 1427 | guint |
| 1428 | ctk_builder_add_from_string (CtkBuilder *builder, |
| 1429 | const gchar *buffer, |
| 1430 | gsize length, |
| 1431 | GError **error) |
| 1432 | { |
| 1433 | GError *tmp_error; |
| 1434 | |
| 1435 | g_return_val_if_fail (CTK_IS_BUILDER (builder), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (0); } } while (0); |
| 1436 | g_return_val_if_fail (buffer != NULL, 0)do { if ((buffer != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "buffer != NULL"); return (0); } } while (0); |
| 1437 | g_return_val_if_fail (error == NULL || *error == NULL, 0)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return (0); } } while ( 0); |
| 1438 | |
| 1439 | tmp_error = NULL((void*)0); |
| 1440 | |
| 1441 | g_free (builder->priv->filename); |
| 1442 | g_free (builder->priv->resource_prefix); |
| 1443 | builder->priv->filename = g_strdup (".")g_strdup_inline ("."); |
| 1444 | builder->priv->resource_prefix = NULL((void*)0); |
| 1445 | |
| 1446 | _ctk_builder_parser_parse_buffer (builder, "<input>", |
| 1447 | buffer, length, |
| 1448 | NULL((void*)0), |
| 1449 | &tmp_error); |
| 1450 | if (tmp_error != NULL((void*)0)) |
| 1451 | { |
| 1452 | g_propagate_error (error, tmp_error); |
| 1453 | return 0; |
| 1454 | } |
| 1455 | |
| 1456 | return 1; |
| 1457 | } |
| 1458 | |
| 1459 | /** |
| 1460 | * ctk_builder_add_objects_from_string: |
| 1461 | * @builder: a #CtkBuilder |
| 1462 | * @buffer: the string to parse |
| 1463 | * @length: the length of @buffer (may be -1 if @buffer is nul-terminated) |
| 1464 | * @object_ids: (array zero-terminated=1) (element-type utf8): nul-terminated array of objects to build |
| 1465 | * @error: (allow-none): return location for an error, or %NULL |
| 1466 | * |
| 1467 | * Parses a string containing a [CtkBuilder UI definition][BUILDER-UI] |
| 1468 | * building only the requested objects and merges |
| 1469 | * them with the current contents of @builder. |
| 1470 | * |
| 1471 | * Upon errors 0 will be returned and @error will be assigned a |
| 1472 | * #GError from the #CTK_BUILDER_ERROR or #G_MARKUP_ERROR domain. |
| 1473 | * |
| 1474 | * If you are adding an object that depends on an object that is not |
| 1475 | * its child (for instance a #CtkTreeView that depends on its |
| 1476 | * #CtkTreeModel), you have to explicitly list all of them in @object_ids. |
| 1477 | * |
| 1478 | * Returns: A positive value on success, 0 if an error occurred |
| 1479 | * |
| 1480 | * Since: 2.14 |
| 1481 | **/ |
| 1482 | guint |
| 1483 | ctk_builder_add_objects_from_string (CtkBuilder *builder, |
| 1484 | const gchar *buffer, |
| 1485 | gsize length, |
| 1486 | gchar **object_ids, |
| 1487 | GError **error) |
| 1488 | { |
| 1489 | GError *tmp_error; |
| 1490 | |
| 1491 | g_return_val_if_fail (CTK_IS_BUILDER (builder), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (0); } } while (0); |
| 1492 | g_return_val_if_fail (buffer != NULL, 0)do { if ((buffer != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "buffer != NULL"); return (0); } } while (0); |
| 1493 | g_return_val_if_fail (object_ids != NULL && object_ids[0] != NULL, 0)do { if ((object_ids != ((void*)0) && object_ids[0] != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "object_ids != NULL && object_ids[0] != NULL" ); return (0); } } while (0); |
| 1494 | g_return_val_if_fail (error == NULL || *error == NULL, 0)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return (0); } } while ( 0); |
| 1495 | |
| 1496 | tmp_error = NULL((void*)0); |
| 1497 | |
| 1498 | g_free (builder->priv->filename); |
| 1499 | g_free (builder->priv->resource_prefix); |
| 1500 | builder->priv->filename = g_strdup (".")g_strdup_inline ("."); |
| 1501 | builder->priv->resource_prefix = NULL((void*)0); |
| 1502 | |
| 1503 | _ctk_builder_parser_parse_buffer (builder, "<input>", |
| 1504 | buffer, length, |
| 1505 | object_ids, |
| 1506 | &tmp_error); |
| 1507 | |
| 1508 | if (tmp_error != NULL((void*)0)) |
| 1509 | { |
| 1510 | g_propagate_error (error, tmp_error); |
| 1511 | return 0; |
| 1512 | } |
| 1513 | |
| 1514 | return 1; |
| 1515 | } |
| 1516 | |
| 1517 | /** |
| 1518 | * ctk_builder_get_object: |
| 1519 | * @builder: a #CtkBuilder |
| 1520 | * @name: name of object to get |
| 1521 | * |
| 1522 | * Gets the object named @name. Note that this function does not |
| 1523 | * increment the reference count of the returned object. |
| 1524 | * |
| 1525 | * Returns: (nullable) (transfer none): the object named @name or %NULL if |
| 1526 | * it could not be found in the object tree. |
| 1527 | * |
| 1528 | * Since: 2.12 |
| 1529 | **/ |
| 1530 | GObject * |
| 1531 | ctk_builder_get_object (CtkBuilder *builder, |
| 1532 | const gchar *name) |
| 1533 | { |
| 1534 | g_return_val_if_fail (CTK_IS_BUILDER (builder), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (((void*)0)); } } while (0); |
| 1535 | g_return_val_if_fail (name != NULL, NULL)do { if ((name != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "name != NULL"); return ( ((void*)0)); } } while (0); |
| 1536 | |
| 1537 | return g_hash_table_lookup (builder->priv->objects, name); |
| 1538 | } |
| 1539 | |
| 1540 | /** |
| 1541 | * ctk_builder_get_objects: |
| 1542 | * @builder: a #CtkBuilder |
| 1543 | * |
| 1544 | * Gets all objects that have been constructed by @builder. Note that |
| 1545 | * this function does not increment the reference counts of the returned |
| 1546 | * objects. |
| 1547 | * |
| 1548 | * Returns: (element-type GObject) (transfer container): a newly-allocated #GSList containing all the objects |
| 1549 | * constructed by the #CtkBuilder instance. It should be freed by |
| 1550 | * g_slist_free() |
| 1551 | * |
| 1552 | * Since: 2.12 |
| 1553 | **/ |
| 1554 | GSList * |
| 1555 | ctk_builder_get_objects (CtkBuilder *builder) |
| 1556 | { |
| 1557 | GSList *objects = NULL((void*)0); |
| 1558 | GObject *object; |
| 1559 | GHashTableIter iter; |
| 1560 | |
| 1561 | g_return_val_if_fail (CTK_IS_BUILDER (builder), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (((void*)0)); } } while (0); |
| 1562 | |
| 1563 | g_hash_table_iter_init (&iter, builder->priv->objects); |
| 1564 | while (g_hash_table_iter_next (&iter, NULL((void*)0), (gpointer *)&object)) |
| 1565 | objects = g_slist_prepend (objects, object); |
| 1566 | |
| 1567 | return g_slist_reverse (objects); |
| 1568 | } |
| 1569 | |
| 1570 | /** |
| 1571 | * ctk_builder_set_translation_domain: |
| 1572 | * @builder: a #CtkBuilder |
| 1573 | * @domain: (allow-none): the translation domain or %NULL |
| 1574 | * |
| 1575 | * Sets the translation domain of @builder. |
| 1576 | * See #CtkBuilder:translation-domain. |
| 1577 | * |
| 1578 | * Since: 2.12 |
| 1579 | **/ |
| 1580 | void |
| 1581 | ctk_builder_set_translation_domain (CtkBuilder *builder, |
| 1582 | const gchar *domain) |
| 1583 | { |
| 1584 | gchar *new_domain; |
| 1585 | |
| 1586 | g_return_if_fail (CTK_IS_BUILDER (builder))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return; } } while (0); |
| 1587 | |
| 1588 | new_domain = g_strdup (domain)g_strdup_inline (domain); |
| 1589 | g_free (builder->priv->domain); |
| 1590 | builder->priv->domain = new_domain; |
| 1591 | |
| 1592 | g_object_notify_by_pspec (G_OBJECT (builder)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((builder)), (((GType) ((20) << (2)))))))), builder_props[PROP_TRANSLATION_DOMAIN]); |
| 1593 | } |
| 1594 | |
| 1595 | /** |
| 1596 | * ctk_builder_get_translation_domain: |
| 1597 | * @builder: a #CtkBuilder |
| 1598 | * |
| 1599 | * Gets the translation domain of @builder. |
| 1600 | * |
| 1601 | * Returns: the translation domain. This string is owned |
| 1602 | * by the builder object and must not be modified or freed. |
| 1603 | * |
| 1604 | * Since: 2.12 |
| 1605 | **/ |
| 1606 | const gchar * |
| 1607 | ctk_builder_get_translation_domain (CtkBuilder *builder) |
| 1608 | { |
| 1609 | g_return_val_if_fail (CTK_IS_BUILDER (builder), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (((void*)0)); } } while (0); |
| 1610 | |
| 1611 | return builder->priv->domain; |
| 1612 | } |
| 1613 | |
| 1614 | /** |
| 1615 | * ctk_builder_expose_object: |
| 1616 | * @builder: a #CtkBuilder |
| 1617 | * @name: the name of the object exposed to the builder |
| 1618 | * @object: the object to expose |
| 1619 | * |
| 1620 | * Add @object to the @builder object pool so it can be referenced just like any |
| 1621 | * other object built by builder. |
| 1622 | * |
| 1623 | * Since: 3.8 |
| 1624 | **/ |
| 1625 | void |
| 1626 | ctk_builder_expose_object (CtkBuilder *builder, |
| 1627 | const gchar *name, |
| 1628 | GObject *object) |
| 1629 | { |
| 1630 | g_return_if_fail (CTK_IS_BUILDER (builder))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return; } } while (0); |
| 1631 | g_return_if_fail (name && name[0])do { if ((name && name[0])) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "name && name[0]" ); return; } } while (0); |
| 1632 | g_return_if_fail (!g_hash_table_contains (builder->priv->objects, name))do { if ((!g_hash_table_contains (builder->priv->objects , name))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "!g_hash_table_contains (builder->priv->objects, name)" ); return; } } while (0); |
| 1633 | |
| 1634 | object_set_name (object, name); |
| 1635 | g_hash_table_insert (builder->priv->objects, |
| 1636 | g_strdup (name)g_strdup_inline (name), |
| 1637 | g_object_ref (object)((__typeof__ (object)) (g_object_ref) (object))); |
| 1638 | } |
| 1639 | |
| 1640 | |
| 1641 | typedef struct { |
| 1642 | GModule *module; |
| 1643 | gpointer data; |
| 1644 | } ConnectArgs; |
| 1645 | |
| 1646 | static void |
| 1647 | ctk_builder_connect_signals_default (CtkBuilder *builder, |
| 1648 | GObject *object, |
| 1649 | const gchar *signal_name, |
| 1650 | const gchar *handler_name, |
| 1651 | GObject *connect_object, |
| 1652 | GConnectFlags flags, |
| 1653 | gpointer user_data) |
| 1654 | { |
| 1655 | GCallback func; |
| 1656 | ConnectArgs *args = (ConnectArgs*) user_data; |
| 1657 | |
| 1658 | func = ctk_builder_lookup_callback_symbol (builder, handler_name); |
| 1659 | |
| 1660 | if (!func) |
| 1661 | { |
| 1662 | /* Only error out for missing GModule support if we've not |
| 1663 | * found the symbols explicitly added with ctk_builder_add_callback_symbol() |
| 1664 | */ |
| 1665 | if (args->module == NULL((void*)0)) |
| 1666 | g_error ("ctk_builder_connect_signals() requires working GModule"); |
| 1667 | |
| 1668 | if (!g_module_symbol (args->module, handler_name, (gpointer)&func)) |
| 1669 | { |
| 1670 | g_warning ("Could not find signal handler '%s'. Did you compile with -rdynamic?", handler_name); |
| 1671 | return; |
| 1672 | } |
| 1673 | } |
| 1674 | |
| 1675 | if (connect_object) |
| 1676 | g_signal_connect_object (object, signal_name, func, connect_object, flags); |
| 1677 | else |
| 1678 | g_signal_connect_data (object, signal_name, func, args->data, NULL((void*)0), flags); |
| 1679 | } |
| 1680 | |
| 1681 | |
| 1682 | /** |
| 1683 | * ctk_builder_connect_signals: |
| 1684 | * @builder: a #CtkBuilder |
| 1685 | * @user_data: user data to pass back with all signals |
| 1686 | * |
| 1687 | * This method is a simpler variation of ctk_builder_connect_signals_full(). |
| 1688 | * It uses symbols explicitly added to @builder with prior calls to |
| 1689 | * ctk_builder_add_callback_symbol(). In the case that symbols are not |
| 1690 | * explicitly added; it uses #GModule’s introspective features (by opening the module %NULL) |
| 1691 | * to look at the application’s symbol table. From here it tries to match |
| 1692 | * the signal handler names given in the interface description with |
| 1693 | * symbols in the application and connects the signals. Note that this |
| 1694 | * function can only be called once, subsequent calls will do nothing. |
| 1695 | * |
| 1696 | * Note that unless ctk_builder_add_callback_symbol() is called for |
| 1697 | * all signal callbacks which are referenced by the loaded XML, this |
| 1698 | * function will require that #GModule be supported on the platform. |
| 1699 | * |
| 1700 | * If you rely on #GModule support to lookup callbacks in the symbol table, |
| 1701 | * the following details should be noted: |
| 1702 | * |
| 1703 | * When compiling applications for Windows, you must declare signal callbacks |
| 1704 | * with #G_MODULE_EXPORT, or they will not be put in the symbol table. |
| 1705 | * On Linux and Unices, this is not necessary; applications should instead |
| 1706 | * be compiled with the -Wl,--export-dynamic CFLAGS, and linked against |
| 1707 | * gmodule-export-2.0. |
| 1708 | * |
| 1709 | * Since: 2.12 |
| 1710 | **/ |
| 1711 | void |
| 1712 | ctk_builder_connect_signals (CtkBuilder *builder, |
| 1713 | gpointer user_data) |
| 1714 | { |
| 1715 | ConnectArgs args; |
| 1716 | |
| 1717 | g_return_if_fail (CTK_IS_BUILDER (builder))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return; } } while (0); |
| 1718 | |
| 1719 | args.data = user_data; |
| 1720 | |
| 1721 | if (g_module_supported ()) |
| 1722 | args.module = g_module_open (NULL((void*)0), G_MODULE_BIND_LAZY); |
| 1723 | else |
| 1724 | args.module = NULL((void*)0); |
| 1725 | |
| 1726 | ctk_builder_connect_signals_full (builder, |
| 1727 | ctk_builder_connect_signals_default, |
| 1728 | &args); |
| 1729 | if (args.module) |
| 1730 | g_module_close (args.module); |
| 1731 | } |
| 1732 | |
| 1733 | /** |
| 1734 | * CtkBuilderConnectFunc: |
| 1735 | * @builder: a #CtkBuilder |
| 1736 | * @object: object to connect a signal to |
| 1737 | * @signal_name: name of the signal |
| 1738 | * @handler_name: name of the handler |
| 1739 | * @connect_object: (nullable): a #GObject, if non-%NULL, use g_signal_connect_object() |
| 1740 | * @flags: #GConnectFlags to use |
| 1741 | * @user_data: user data |
| 1742 | * |
| 1743 | * This is the signature of a function used to connect signals. It is used |
| 1744 | * by the ctk_builder_connect_signals() and ctk_builder_connect_signals_full() |
| 1745 | * methods. It is mainly intended for interpreted language bindings, but |
| 1746 | * could be useful where the programmer wants more control over the signal |
| 1747 | * connection process. Note that this function can only be called once, |
| 1748 | * subsequent calls will do nothing. |
| 1749 | * |
| 1750 | * Since: 2.12 |
| 1751 | */ |
| 1752 | |
| 1753 | /** |
| 1754 | * ctk_builder_connect_signals_full: |
| 1755 | * @builder: a #CtkBuilder |
| 1756 | * @func: (scope call): the function used to connect the signals |
| 1757 | * @user_data: arbitrary data that will be passed to the connection function |
| 1758 | * |
| 1759 | * This function can be thought of the interpreted language binding |
| 1760 | * version of ctk_builder_connect_signals(), except that it does not |
| 1761 | * require GModule to function correctly. |
| 1762 | * |
| 1763 | * Since: 2.12 |
| 1764 | */ |
| 1765 | void |
| 1766 | ctk_builder_connect_signals_full (CtkBuilder *builder, |
| 1767 | CtkBuilderConnectFunc func, |
| 1768 | gpointer user_data) |
| 1769 | { |
| 1770 | GSList *l; |
| 1771 | GObject *object; |
| 1772 | GObject *connect_object; |
| 1773 | GString *detailed_id = NULL((void*)0); |
| 1774 | |
| 1775 | g_return_if_fail (CTK_IS_BUILDER (builder))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return; } } while (0); |
| 1776 | g_return_if_fail (func != NULL)do { if ((func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "func != NULL"); return; } } while (0); |
| 1777 | |
| 1778 | if (!builder->priv->signals) |
| 1779 | return; |
| 1780 | |
| 1781 | builder->priv->signals = g_slist_reverse (builder->priv->signals); |
| 1782 | for (l = builder->priv->signals; l; l = l->next) |
| 1783 | { |
| 1784 | SignalInfo *signal = (SignalInfo*)l->data; |
| 1785 | const gchar *signal_name; |
| 1786 | |
| 1787 | g_assert (signal != NULL)do { if (signal != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 1787, ((const char*) (__func__)), "signal != NULL" ); } while (0); |
| 1788 | g_assert (signal->id != 0)do { if (signal->id != 0) ; else g_assertion_message_expr ( "Ctk", "ctkbuilder.c", 1788, ((const char*) (__func__)), "signal->id != 0" ); } while (0); |
| 1789 | |
| 1790 | signal_name = g_signal_name (signal->id); |
| 1791 | |
| 1792 | object = g_hash_table_lookup (builder->priv->objects, |
| 1793 | signal->object_name); |
| 1794 | g_assert (object != NULL)do { if (object != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctkbuilder.c", 1794, ((const char*) (__func__)), "object != NULL" ); } while (0); |
| 1795 | |
| 1796 | connect_object = NULL((void*)0); |
| 1797 | |
| 1798 | if (signal->connect_object_name) |
| 1799 | { |
| 1800 | connect_object = g_hash_table_lookup (builder->priv->objects, |
| 1801 | signal->connect_object_name); |
| 1802 | if (!connect_object) |
| 1803 | g_warning ("Could not lookup object %s on signal %s of object %s", |
| 1804 | signal->connect_object_name, signal_name, |
| 1805 | signal->object_name); |
| 1806 | } |
| 1807 | |
| 1808 | if (signal->detail) |
| 1809 | { |
| 1810 | if (detailed_id == NULL((void*)0)) |
| 1811 | detailed_id = g_string_new (""); |
| 1812 | |
| 1813 | g_string_printf (detailed_id, "%s::%s", signal_name, |
| 1814 | g_quark_to_string (signal->detail)); |
| 1815 | signal_name = detailed_id->str; |
| 1816 | } |
| 1817 | |
| 1818 | func (builder, object, signal_name, signal->handler, |
| 1819 | connect_object, signal->flags, user_data); |
| 1820 | } |
| 1821 | |
| 1822 | g_slist_free_full (builder->priv->signals, (GDestroyNotify)_free_signal_info); |
| 1823 | builder->priv->signals = NULL((void*)0); |
| 1824 | |
| 1825 | if (detailed_id) |
| 1826 | g_string_free (detailed_id, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (detailed_id), ((!(0)))) : g_string_free_and_steal (detailed_id )) : (g_string_free) ((detailed_id), ((!(0))))); |
| 1827 | } |
| 1828 | |
| 1829 | /** |
| 1830 | * ctk_builder_value_from_string: |
| 1831 | * @builder: a #CtkBuilder |
| 1832 | * @pspec: the #GParamSpec for the property |
| 1833 | * @string: the string representation of the value |
| 1834 | * @value: (out): the #GValue to store the result in |
| 1835 | * @error: (allow-none): return location for an error, or %NULL |
| 1836 | * |
| 1837 | * This function demarshals a value from a string. This function |
| 1838 | * calls g_value_init() on the @value argument, so it need not be |
| 1839 | * initialised beforehand. |
| 1840 | * |
| 1841 | * This function can handle char, uchar, boolean, int, uint, long, |
| 1842 | * ulong, enum, flags, float, double, string, #CdkColor, #CdkRGBA and |
| 1843 | * #CtkAdjustment type values. Support for #CtkWidget type values is |
| 1844 | * still to come. |
| 1845 | * |
| 1846 | * Upon errors %FALSE will be returned and @error will be assigned a |
| 1847 | * #GError from the #CTK_BUILDER_ERROR domain. |
| 1848 | * |
| 1849 | * Returns: %TRUE on success |
| 1850 | * |
| 1851 | * Since: 2.12 |
| 1852 | */ |
| 1853 | gboolean |
| 1854 | ctk_builder_value_from_string (CtkBuilder *builder, |
| 1855 | GParamSpec *pspec, |
| 1856 | const gchar *string, |
| 1857 | GValue *value, |
| 1858 | GError **error) |
| 1859 | { |
| 1860 | g_return_val_if_fail (CTK_IS_BUILDER (builder), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return ((0)); } } while (0); |
| 1861 | g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE)do { if (((((g_type_check_instance_is_fundamentally_a ((GTypeInstance *) ((pspec)), (((GType) ((19) << (2)))))))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "G_IS_PARAM_SPEC (pspec)"); return ((0)); } } while (0); |
| 1862 | g_return_val_if_fail (string != NULL, FALSE)do { if ((string != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "string != NULL"); return ((0)); } } while (0); |
| 1863 | g_return_val_if_fail (value != NULL, FALSE)do { if ((value != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "value != NULL"); return ((0)); } } while (0); |
| 1864 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return ((0)); } } while (0); |
| 1865 | |
| 1866 | /* |
| 1867 | * GParamSpecUnichar has the internal type G_TYPE_UINT, |
| 1868 | * so we cannot handle this in the switch, do it separately |
| 1869 | */ |
| 1870 | if (G_IS_PARAM_SPEC_UNICHAR (pspec)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (pspec)); GType __t = ((g_param_spec_types[9])); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 1871 | { |
| 1872 | gunichar c; |
| 1873 | g_value_init (value, G_TYPE_UINT((GType) ((7) << (2)))); |
| 1874 | c = g_utf8_get_char_validated (string, strlen (string)); |
| 1875 | if (c != 0 && c != (gunichar)-1 && c != (gunichar)-2) |
| 1876 | g_value_set_uint (value, c); |
| 1877 | return TRUE(!(0)); |
| 1878 | } |
| 1879 | |
| 1880 | /* |
| 1881 | * GParamSpecVariant can specify a GVariantType which can help with |
| 1882 | * parsing, so we need to take care of that here. |
| 1883 | */ |
| 1884 | if (G_IS_PARAM_SPEC_VARIANT (pspec)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (pspec)); GType __t = ((g_param_spec_types[22])); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 1885 | { |
| 1886 | GParamSpecVariant *variant_pspec = G_PARAM_SPEC_VARIANT (pspec)((((GParamSpecVariant*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((pspec)), ((g_param_spec_types[22])))))); |
| 1887 | const GVariantType *type; |
| 1888 | GVariant *variant; |
| 1889 | |
| 1890 | g_value_init (value, G_TYPE_VARIANT((GType) ((21) << (2)))); |
| 1891 | |
| 1892 | /* The GVariant parser doesn't deal with indefinite types */ |
| 1893 | if (g_variant_type_is_definite (variant_pspec->type)) |
| 1894 | type = variant_pspec->type; |
| 1895 | else |
| 1896 | type = NULL((void*)0); |
| 1897 | |
| 1898 | variant = g_variant_parse (type, string, NULL((void*)0), NULL((void*)0), error); |
| 1899 | if (variant == NULL((void*)0)) |
| 1900 | return FALSE(0); |
| 1901 | g_value_take_variant (value, variant); |
| 1902 | return TRUE(!(0)); |
| 1903 | } |
| 1904 | |
| 1905 | return ctk_builder_value_from_string_type (builder, |
| 1906 | G_PARAM_SPEC_VALUE_TYPE (pspec)(((((GParamSpec*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((pspec)), (((GType) ((19) << (2))))))))->value_type ), |
| 1907 | string, value, error); |
| 1908 | } |
| 1909 | |
| 1910 | /** |
| 1911 | * ctk_builder_value_from_string_type: |
| 1912 | * @builder: a #CtkBuilder |
| 1913 | * @type: the #GType of the value |
| 1914 | * @string: the string representation of the value |
| 1915 | * @value: (out): the #GValue to store the result in |
| 1916 | * @error: (allow-none): return location for an error, or %NULL |
| 1917 | * |
| 1918 | * Like ctk_builder_value_from_string(), this function demarshals |
| 1919 | * a value from a string, but takes a #GType instead of #GParamSpec. |
| 1920 | * This function calls g_value_init() on the @value argument, so it |
| 1921 | * need not be initialised beforehand. |
| 1922 | * |
| 1923 | * Upon errors %FALSE will be returned and @error will be assigned a |
| 1924 | * #GError from the #CTK_BUILDER_ERROR domain. |
| 1925 | * |
| 1926 | * Returns: %TRUE on success |
| 1927 | * |
| 1928 | * Since: 2.12 |
| 1929 | */ |
| 1930 | gboolean |
| 1931 | ctk_builder_value_from_string_type (CtkBuilder *builder, |
| 1932 | GType type, |
| 1933 | const gchar *string, |
| 1934 | GValue *value, |
| 1935 | GError **error) |
| 1936 | { |
| 1937 | gboolean ret = TRUE(!(0)); |
| 1938 | |
| 1939 | g_return_val_if_fail (string != NULL, FALSE)do { if ((string != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "string != NULL"); return ((0)); } } while (0); |
| 1940 | g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do { if ((error == ((void*)0) || *error == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "error == NULL || *error == NULL"); return ((0)); } } while (0); |
| 1941 | |
| 1942 | g_value_init (value, type); |
| 1943 | |
| 1944 | switch (G_TYPE_FUNDAMENTAL (type)(g_type_fundamental (type))) |
| 1945 | { |
| 1946 | case G_TYPE_CHAR((GType) ((3) << (2))): |
| 1947 | g_value_set_schar (value, string[0]); |
| 1948 | break; |
| 1949 | case G_TYPE_UCHAR((GType) ((4) << (2))): |
| 1950 | g_value_set_uchar (value, (guchar)string[0]); |
| 1951 | break; |
| 1952 | case G_TYPE_BOOLEAN((GType) ((5) << (2))): |
| 1953 | { |
| 1954 | gboolean b; |
| 1955 | |
| 1956 | if (!_ctk_builder_boolean_from_string (string, &b, error)) |
| 1957 | { |
| 1958 | ret = FALSE(0); |
| 1959 | break; |
| 1960 | } |
| 1961 | g_value_set_boolean (value, b); |
| 1962 | break; |
| 1963 | } |
| 1964 | case G_TYPE_INT((GType) ((6) << (2))): |
| 1965 | case G_TYPE_LONG((GType) ((8) << (2))): |
| 1966 | case G_TYPE_INT64((GType) ((10) << (2))): |
| 1967 | { |
| 1968 | gint64 l; |
| 1969 | gchar *endptr = NULL((void*)0); |
| 1970 | |
| 1971 | errno(*__errno_location ()) = 0; |
| 1972 | l = g_ascii_strtoll (string, &endptr, 0); |
| 1973 | if (errno(*__errno_location ()) || endptr == string) |
| 1974 | { |
| 1975 | g_set_error (error, |
| 1976 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 1977 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 1978 | "Could not parse integer '%s'", |
| 1979 | string); |
| 1980 | ret = FALSE(0); |
| 1981 | break; |
| 1982 | } |
| 1983 | if (G_VALUE_HOLDS_INT (value)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((GType) ((6) << (2)))); gboolean __r; if (!__val) __r = (0); else if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t); __r ; }))))) |
| 1984 | g_value_set_int (value, l); |
| 1985 | else if (G_VALUE_HOLDS_LONG (value)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((GType) ((8) << (2)))); gboolean __r; if (!__val) __r = (0); else if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t); __r ; }))))) |
| 1986 | g_value_set_long (value, l); |
| 1987 | else |
| 1988 | g_value_set_int64 (value, l); |
| 1989 | break; |
| 1990 | } |
| 1991 | case G_TYPE_UINT((GType) ((7) << (2))): |
| 1992 | case G_TYPE_ULONG((GType) ((9) << (2))): |
| 1993 | case G_TYPE_UINT64((GType) ((11) << (2))): |
| 1994 | { |
| 1995 | guint64 ul; |
| 1996 | gchar *endptr = NULL((void*)0); |
| 1997 | errno(*__errno_location ()) = 0; |
| 1998 | ul = g_ascii_strtoull (string, &endptr, 0); |
| 1999 | if (errno(*__errno_location ()) || endptr == string) |
| 2000 | { |
| 2001 | g_set_error (error, |
| 2002 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2003 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2004 | "Could not parse unsigned integer '%s'", |
| 2005 | string); |
| 2006 | ret = FALSE(0); |
| 2007 | break; |
| 2008 | } |
| 2009 | if (G_VALUE_HOLDS_UINT (value)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((GType) ((7) << (2)))); gboolean __r; if (!__val) __r = (0); else if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t); __r ; }))))) |
| 2010 | g_value_set_uint (value, ul); |
| 2011 | else if (G_VALUE_HOLDS_ULONG (value)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((GType) ((9) << (2)))); gboolean __r; if (!__val) __r = (0); else if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t); __r ; }))))) |
| 2012 | g_value_set_ulong (value, ul); |
| 2013 | else |
| 2014 | g_value_set_uint64 (value, ul); |
| 2015 | break; |
| 2016 | } |
| 2017 | case G_TYPE_ENUM((GType) ((12) << (2))): |
| 2018 | { |
| 2019 | gint enum_value; |
| 2020 | if (!_ctk_builder_enum_from_string (type, string, &enum_value, error)) |
| 2021 | { |
| 2022 | ret = FALSE(0); |
| 2023 | break; |
| 2024 | } |
| 2025 | g_value_set_enum (value, enum_value); |
| 2026 | break; |
| 2027 | } |
| 2028 | case G_TYPE_FLAGS((GType) ((13) << (2))): |
| 2029 | { |
| 2030 | guint flags_value; |
| 2031 | |
| 2032 | if (!_ctk_builder_flags_from_string (type, NULL((void*)0), string, &flags_value, error)) |
| 2033 | { |
| 2034 | ret = FALSE(0); |
| 2035 | break; |
| 2036 | } |
| 2037 | g_value_set_flags (value, flags_value); |
| 2038 | break; |
| 2039 | } |
| 2040 | case G_TYPE_FLOAT((GType) ((14) << (2))): |
| 2041 | case G_TYPE_DOUBLE((GType) ((15) << (2))): |
| 2042 | { |
| 2043 | gdouble d; |
| 2044 | gchar *endptr = NULL((void*)0); |
| 2045 | errno(*__errno_location ()) = 0; |
| 2046 | d = g_ascii_strtod (string, &endptr); |
| 2047 | if (errno(*__errno_location ()) || endptr == string) |
| 2048 | { |
| 2049 | g_set_error (error, |
| 2050 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2051 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2052 | "Could not parse double '%s'", |
| 2053 | string); |
| 2054 | ret = FALSE(0); |
| 2055 | break; |
| 2056 | } |
| 2057 | if (G_VALUE_HOLDS_FLOAT (value)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((GType) ((14) << (2)))); gboolean __r ; if (!__val) __r = (0); else if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t); __r ; }))))) |
| 2058 | g_value_set_float (value, d); |
| 2059 | else |
| 2060 | g_value_set_double (value, d); |
| 2061 | break; |
| 2062 | } |
| 2063 | case G_TYPE_STRING((GType) ((16) << (2))): |
| 2064 | g_value_set_string (value, string); |
| 2065 | break; |
| 2066 | case G_TYPE_VARIANT((GType) ((21) << (2))): |
| 2067 | { |
| 2068 | GVariant *variant; |
| 2069 | |
| 2070 | variant = g_variant_parse (NULL((void*)0), string, NULL((void*)0), NULL((void*)0), error); |
| 2071 | if (value != NULL((void*)0)) |
| 2072 | g_value_take_variant (value, variant); |
| 2073 | else |
| 2074 | ret = FALSE(0); |
| 2075 | } |
| 2076 | break; |
| 2077 | case G_TYPE_BOXED((GType) ((18) << (2))): |
| 2078 | if (G_VALUE_HOLDS (value, g_type_from_name ("CdkColor"))(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = ((g_type_from_name ("CdkColor"))); gboolean __r ; if (!__val) __r = (0); else if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t); __r ; }))))) |
| 2079 | { |
| 2080 | CdkColor color = { 0, }; |
| 2081 | |
| 2082 | if (cdk_color_parse (string, &color)) |
| 2083 | g_value_set_boxed (value, &color); |
| 2084 | else |
| 2085 | { |
| 2086 | g_set_error (error, |
| 2087 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2088 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2089 | "Could not parse color '%s'", |
| 2090 | string); |
| 2091 | ret = FALSE(0); |
| 2092 | } |
| 2093 | } |
| 2094 | else if (G_VALUE_HOLDS (value, CDK_TYPE_RGBA)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((cdk_rgba_get_type ()))); gboolean __r; if ( !__val) __r = (0); else if (__val->g_type == __t) __r = (! (0)); else __r = g_type_check_value_holds (__val, __t); __r; } ))))) |
| 2095 | { |
| 2096 | CdkRGBA rgba = { 0 }; |
| 2097 | |
| 2098 | if (cdk_rgba_parse (&rgba, string)) |
| 2099 | g_value_set_boxed (value, &rgba); |
| 2100 | else |
| 2101 | { |
| 2102 | g_set_error (error, |
| 2103 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2104 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2105 | "Could not parse RGBA color '%s'", |
| 2106 | string); |
| 2107 | ret = FALSE(0); |
| 2108 | } |
| 2109 | } |
| 2110 | else if (G_VALUE_HOLDS (value, G_TYPE_STRV)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((g_strv_get_type ()))); gboolean __r; if (! __val) __r = (0); else if (__val->g_type == __t) __r = (!( 0)); else __r = g_type_check_value_holds (__val, __t); __r; } ))))) |
| 2111 | { |
| 2112 | gchar **vector = g_strsplit (string, "\n", 0); |
| 2113 | g_value_take_boxed (value, vector); |
| 2114 | } |
| 2115 | else |
| 2116 | { |
| 2117 | g_set_error (error, |
| 2118 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2119 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2120 | "Could not parse '%s' as a %s", |
| 2121 | string, G_VALUE_TYPE_NAME (value)(g_type_name ((((GValue*) (value))->g_type)))); |
| 2122 | ret = FALSE(0); |
| 2123 | } |
| 2124 | break; |
| 2125 | case G_TYPE_OBJECT((GType) ((20) << (2))): |
| 2126 | case G_TYPE_INTERFACE((GType) ((2) << (2))): |
| 2127 | if (G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((gdk_pixbuf_get_type ()))); gboolean __r; if (!__val) __r = (0); else if (__val->g_type == __t) __r = ( !(0)); else __r = g_type_check_value_holds (__val, __t); __r; }))))) |
| 2128 | { |
| 2129 | gchar *filename; |
| 2130 | GError *tmp_error = NULL((void*)0); |
| 2131 | GdkPixbuf *pixbuf = NULL((void*)0); |
| 2132 | |
| 2133 | if (g_hash_table_contains (builder->priv->objects, string)) |
| 2134 | { |
| 2135 | g_set_error (error, |
| 2136 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2137 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2138 | "Could not load image '%s': " |
| 2139 | " '%s' is already used as object id", |
| 2140 | string, string); |
| 2141 | return FALSE(0); |
| 2142 | } |
| 2143 | |
| 2144 | filename = _ctk_builder_get_resource_path (builder, string); |
| 2145 | if (filename != NULL((void*)0)) |
| 2146 | { |
| 2147 | GInputStream *stream = g_resources_open_stream (filename, 0, &tmp_error); |
| 2148 | if (stream != NULL((void*)0)) |
| 2149 | { |
| 2150 | pixbuf = gdk_pixbuf_new_from_stream (stream, NULL((void*)0), &tmp_error); |
| 2151 | g_object_unref (stream); |
| 2152 | } |
| 2153 | } |
| 2154 | else |
| 2155 | { |
| 2156 | filename = _ctk_builder_get_absolute_filename (builder, string); |
| 2157 | pixbuf = gdk_pixbuf_new_from_file (filename, &tmp_error); |
| 2158 | } |
| 2159 | |
| 2160 | if (pixbuf == NULL((void*)0)) |
| 2161 | { |
| 2162 | CtkIconTheme *theme; |
| 2163 | |
| 2164 | g_warning ("Could not load image '%s': %s", |
| 2165 | string, tmp_error->message); |
| 2166 | g_error_free (tmp_error); |
| 2167 | |
| 2168 | /* fall back to a missing image */ |
| 2169 | theme = ctk_icon_theme_get_default (); |
| 2170 | pixbuf = ctk_icon_theme_load_icon (theme, |
| 2171 | "image-missing", |
| 2172 | 16, |
| 2173 | CTK_ICON_LOOKUP_USE_BUILTIN, |
| 2174 | NULL((void*)0)); |
| 2175 | } |
| 2176 | |
| 2177 | if (pixbuf) |
| 2178 | { |
| 2179 | g_value_set_object (value, pixbuf); |
| 2180 | g_object_unref (G_OBJECT (pixbuf)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((pixbuf)), (((GType) ((20) << (2))))))))); |
| 2181 | } |
| 2182 | |
| 2183 | g_free (filename); |
| 2184 | |
| 2185 | ret = TRUE(!(0)); |
| 2186 | } |
| 2187 | else if (G_VALUE_HOLDS (value, G_TYPE_FILE)(((__extension__ ({ const GValue *__val = (const GValue*) ((value )); GType __t = (((g_file_get_type ()))); gboolean __r; if (! __val) __r = (0); else if (__val->g_type == __t) __r = (!( 0)); else __r = g_type_check_value_holds (__val, __t); __r; } ))))) |
| 2188 | { |
| 2189 | GFile *file; |
| 2190 | |
| 2191 | if (g_hash_table_contains (builder->priv->objects, string)) |
| 2192 | { |
| 2193 | g_set_error (error, |
| 2194 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2195 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2196 | "Could not create file '%s': " |
| 2197 | " '%s' is already used as object id", |
| 2198 | string, string); |
| 2199 | return FALSE(0); |
| 2200 | } |
| 2201 | |
| 2202 | file = g_file_new_for_uri (string); |
| 2203 | g_value_set_object (value, file); |
| 2204 | g_object_unref (G_OBJECT (file)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((file)), (((GType) ((20) << (2))))))))); |
| 2205 | |
| 2206 | ret = TRUE(!(0)); |
| 2207 | } |
| 2208 | else |
| 2209 | ret = FALSE(0); |
| 2210 | break; |
| 2211 | default: |
| 2212 | ret = FALSE(0); |
| 2213 | break; |
| 2214 | } |
| 2215 | |
| 2216 | /* Catch unassigned error for object types as well as any unsupported types. |
| 2217 | * While parsing CtkBuilder; object types are deserialized |
| 2218 | * without calling ctk_builder_value_from_string_type(). |
| 2219 | */ |
| 2220 | if (!ret && error && *error == NULL((void*)0)) |
| 2221 | g_set_error (error, |
| 2222 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2223 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2224 | "Unsupported GType '%s'", g_type_name (type)); |
| 2225 | |
| 2226 | return ret; |
| 2227 | } |
| 2228 | |
| 2229 | gboolean |
| 2230 | _ctk_builder_enum_from_string (GType type, |
| 2231 | const gchar *string, |
| 2232 | gint *enum_value, |
| 2233 | GError **error) |
| 2234 | { |
| 2235 | GEnumClass *eclass; |
| 2236 | GEnumValue *ev; |
| 2237 | gchar *endptr; |
| 2238 | gint value; |
| 2239 | gboolean ret; |
| 2240 | |
| 2241 | g_return_val_if_fail (G_TYPE_IS_ENUM (type), FALSE)do { if ((((g_type_fundamental (type)) == ((GType) ((12) << (2)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "G_TYPE_IS_ENUM (type)"); return ((0)); } } while (0); |
| 2242 | g_return_val_if_fail (string != NULL, FALSE)do { if ((string != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "string != NULL"); return ((0)); } } while (0); |
| 2243 | |
| 2244 | ret = TRUE(!(0)); |
| 2245 | |
| 2246 | endptr = NULL((void*)0); |
| 2247 | errno(*__errno_location ()) = 0; |
| 2248 | value = g_ascii_strtoull (string, &endptr, 0); |
| 2249 | if (errno(*__errno_location ()) == 0 && endptr != string) /* parsed a number */ |
| 2250 | *enum_value = value; |
| 2251 | else |
| 2252 | { |
| 2253 | eclass = g_type_class_ref (type); |
| 2254 | ev = g_enum_get_value_by_name (eclass, string); |
| 2255 | if (!ev) |
| 2256 | ev = g_enum_get_value_by_nick (eclass, string); |
| 2257 | |
| 2258 | if (ev) |
| 2259 | *enum_value = ev->value; |
| 2260 | else |
| 2261 | { |
| 2262 | g_set_error (error, |
| 2263 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2264 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2265 | "Could not parse enum: '%s'", |
| 2266 | string); |
| 2267 | ret = FALSE(0); |
| 2268 | } |
| 2269 | |
| 2270 | g_type_class_unref (eclass); |
| 2271 | } |
| 2272 | |
| 2273 | return ret; |
| 2274 | } |
| 2275 | |
| 2276 | gboolean |
| 2277 | _ctk_builder_flags_from_string (GType type, |
| 2278 | GFlagsValue *aliases, |
| 2279 | const gchar *string, |
| 2280 | guint *flags_value, |
| 2281 | GError **error) |
| 2282 | { |
| 2283 | GFlagsClass *fclass; |
| 2284 | gchar *endptr, *prevptr; |
| 2285 | guint i, j, k, value; |
| 2286 | gchar *flagstr; |
| 2287 | GFlagsValue *fv; |
| 2288 | const gchar *flag; |
| 2289 | gunichar ch; |
| 2290 | gboolean eos, ret; |
| 2291 | |
| 2292 | g_return_val_if_fail (G_TYPE_IS_FLAGS (type), FALSE)do { if ((((g_type_fundamental (type)) == ((GType) ((13) << (2)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "G_TYPE_IS_FLAGS (type)"); return ((0)); } } while (0); |
| 2293 | g_return_val_if_fail (string != 0, FALSE)do { if ((string != 0)) { } else { g_return_if_fail_warning ( "Ctk", ((const char*) (__func__)), "string != 0"); return ((0 )); } } while (0); |
| 2294 | |
| 2295 | ret = TRUE(!(0)); |
| 2296 | |
| 2297 | endptr = NULL((void*)0); |
| 2298 | errno(*__errno_location ()) = 0; |
| 2299 | value = g_ascii_strtoull (string, &endptr, 0); |
| 2300 | if (errno(*__errno_location ()) == 0 && endptr != string) /* parsed a number */ |
| 2301 | *flags_value = value; |
| 2302 | else |
| 2303 | { |
| 2304 | fclass = g_type_class_ref (type); |
| 2305 | |
| 2306 | flagstr = g_strdup (string)g_strdup_inline (string); |
| 2307 | for (value = i = j = 0; ; i++) |
| 2308 | { |
| 2309 | |
| 2310 | eos = flagstr[i] == '\0'; |
| 2311 | |
| 2312 | if (!eos && flagstr[i] != '|') |
| 2313 | continue; |
| 2314 | |
| 2315 | flag = &flagstr[j]; |
| 2316 | endptr = &flagstr[i]; |
| 2317 | |
| 2318 | if (!eos) |
| 2319 | { |
| 2320 | flagstr[i++] = '\0'; |
| 2321 | j = i; |
| 2322 | } |
| 2323 | |
| 2324 | /* trim spaces */ |
| 2325 | for (;;) |
| 2326 | { |
| 2327 | ch = g_utf8_get_char (flag); |
| 2328 | if (!g_unichar_isspace (ch)) |
| 2329 | break; |
| 2330 | flag = g_utf8_next_char (flag)((flag) + g_utf8_skip[*(const guchar *)(flag)]); |
| 2331 | } |
| 2332 | |
| 2333 | while (endptr > flag) |
| 2334 | { |
| 2335 | prevptr = g_utf8_prev_char (endptr); |
| 2336 | ch = g_utf8_get_char (prevptr); |
| 2337 | if (!g_unichar_isspace (ch)) |
| 2338 | break; |
| 2339 | endptr = prevptr; |
| 2340 | } |
| 2341 | |
| 2342 | if (endptr > flag) |
| 2343 | { |
| 2344 | *endptr = '\0'; |
| 2345 | |
| 2346 | fv = NULL((void*)0); |
| 2347 | |
| 2348 | if (aliases) |
| 2349 | { |
| 2350 | for (k = 0; aliases[k].value_nick; k++) |
| 2351 | { |
| 2352 | if (g_ascii_strcasecmp (aliases[k].value_nick, flag) == 0) |
| 2353 | { |
| 2354 | fv = &aliases[k]; |
| 2355 | break; |
| 2356 | } |
| 2357 | } |
| 2358 | } |
| 2359 | |
| 2360 | if (!fv) |
| 2361 | fv = g_flags_get_value_by_name (fclass, flag); |
| 2362 | |
| 2363 | if (!fv) |
| 2364 | fv = g_flags_get_value_by_nick (fclass, flag); |
| 2365 | |
| 2366 | if (fv) |
| 2367 | value |= fv->value; |
| 2368 | else |
| 2369 | { |
| 2370 | g_set_error (error, |
| 2371 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2372 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2373 | "Unknown flag: '%s'", |
| 2374 | flag); |
| 2375 | ret = FALSE(0); |
| 2376 | break; |
| 2377 | } |
| 2378 | } |
| 2379 | |
| 2380 | if (eos) |
| 2381 | { |
| 2382 | *flags_value = value; |
| 2383 | break; |
| 2384 | } |
| 2385 | } |
| 2386 | |
| 2387 | g_free (flagstr); |
| 2388 | |
| 2389 | g_type_class_unref (fclass); |
| 2390 | } |
| 2391 | |
| 2392 | return ret; |
| 2393 | } |
| 2394 | |
| 2395 | gboolean |
| 2396 | _ctk_builder_boolean_from_string (const gchar *string, |
| 2397 | gboolean *value, |
| 2398 | GError **error) |
| 2399 | { |
| 2400 | if (string[0] == '\0') |
| 2401 | goto error; |
| 2402 | else if (string[1] == '\0') |
| 2403 | { |
| 2404 | gchar c; |
| 2405 | |
| 2406 | c = string[0]; |
| 2407 | if (c == '1' || |
| 2408 | c == 'y' || c == 't' || |
| 2409 | c == 'Y' || c == 'T') |
| 2410 | *value = TRUE(!(0)); |
| 2411 | else if (c == '0' || |
| 2412 | c == 'n' || c == 'f' || |
| 2413 | c == 'N' || c == 'F') |
| 2414 | *value = FALSE(0); |
| 2415 | else |
| 2416 | goto error; |
| 2417 | } |
| 2418 | else |
| 2419 | { |
| 2420 | if (g_ascii_strcasecmp (string, "true") == 0 || |
| 2421 | g_ascii_strcasecmp (string, "yes") == 0) |
| 2422 | *value = TRUE(!(0)); |
| 2423 | else if (g_ascii_strcasecmp (string, "false") == 0 || |
| 2424 | g_ascii_strcasecmp (string, "no") == 0) |
| 2425 | *value = FALSE(0); |
| 2426 | else |
| 2427 | goto error; |
| 2428 | } |
| 2429 | |
| 2430 | return TRUE(!(0)); |
| 2431 | |
| 2432 | error: |
| 2433 | g_set_error (error, |
| 2434 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2435 | CTK_BUILDER_ERROR_INVALID_VALUE, |
| 2436 | "Could not parse boolean '%s'", |
| 2437 | string); |
| 2438 | return FALSE(0); |
| 2439 | } |
| 2440 | |
| 2441 | /** |
| 2442 | * ctk_builder_get_type_from_name: |
| 2443 | * @builder: a #CtkBuilder |
| 2444 | * @type_name: type name to lookup |
| 2445 | * |
| 2446 | * Looks up a type by name, using the virtual function that |
| 2447 | * #CtkBuilder has for that purpose. This is mainly used when |
| 2448 | * implementing the #CtkBuildable interface on a type. |
| 2449 | * |
| 2450 | * Returns: the #GType found for @type_name or #G_TYPE_INVALID |
| 2451 | * if no type was found |
| 2452 | * |
| 2453 | * Since: 2.12 |
| 2454 | */ |
| 2455 | GType |
| 2456 | ctk_builder_get_type_from_name (CtkBuilder *builder, |
| 2457 | const gchar *type_name) |
| 2458 | { |
| 2459 | GType type; |
| 2460 | |
| 2461 | g_return_val_if_fail (CTK_IS_BUILDER (builder), G_TYPE_INVALID)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (((GType) ((0) << (2)))); } } while (0); |
| 2462 | g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID)do { if ((type_name != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "type_name != NULL"); return (((GType) ((0) << (2)))); } } while (0); |
| 2463 | |
| 2464 | type = CTK_BUILDER_GET_CLASS (builder)((((CtkBuilderClass*) (((GTypeInstance*) ((builder)))->g_class ))))->get_type_from_name (builder, type_name); |
| 2465 | |
| 2466 | if (G_TYPE_IS_CLASSED (type)(g_type_test_flags ((type), G_TYPE_FLAG_CLASSED))) |
| 2467 | g_type_class_unref (g_type_class_ref (type)); |
| 2468 | |
| 2469 | return type; |
| 2470 | } |
| 2471 | |
| 2472 | GQuark |
| 2473 | ctk_builder_error_quark (void) |
| 2474 | { |
| 2475 | return g_quark_from_static_string ("ctk-builder-error-quark"); |
| 2476 | } |
| 2477 | |
| 2478 | gchar * |
| 2479 | _ctk_builder_get_resource_path (CtkBuilder *builder, const gchar *string) |
| 2480 | { |
| 2481 | if (g_str_has_prefix (string, "resource:///")(__builtin_constant_p ("resource:///")? __extension__ ({ const char * const __str = (string); const char * const __prefix = ("resource:///"); gboolean __result = (0); if (__str == ((void *)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (( (__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix ) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len ) == 0; } __result; }) : (g_str_has_prefix) (string, "resource:///" ) )) |
| 2482 | return g_uri_unescape_string (string + 11, "/"); |
| 2483 | |
| 2484 | if (g_path_is_absolute (string) || |
| 2485 | builder->priv->resource_prefix == NULL((void*)0)) |
| 2486 | return NULL((void*)0); |
| 2487 | |
| 2488 | return g_build_path ("/", builder->priv->resource_prefix, string, NULL((void*)0)); |
| 2489 | } |
| 2490 | |
| 2491 | gchar * |
| 2492 | _ctk_builder_get_absolute_filename (CtkBuilder *builder, |
| 2493 | const gchar *string) |
| 2494 | { |
| 2495 | gchar *filename; |
| 2496 | gchar *dirname = NULL((void*)0); |
| 2497 | |
| 2498 | if (g_path_is_absolute (string)) |
| 2499 | return g_strdup (string)g_strdup_inline (string); |
| 2500 | |
| 2501 | if (builder->priv->filename && |
| 2502 | strcmp (builder->priv->filename, ".") != 0) |
| 2503 | { |
| 2504 | dirname = g_path_get_dirname (builder->priv->filename); |
| 2505 | |
| 2506 | if (strcmp (dirname, ".") == 0) |
| 2507 | { |
| 2508 | g_free (dirname); |
| 2509 | dirname = g_get_current_dir (); |
| 2510 | } |
| 2511 | } |
| 2512 | else |
| 2513 | dirname = g_get_current_dir (); |
| 2514 | |
| 2515 | filename = g_build_filename (dirname, string, NULL((void*)0)); |
| 2516 | g_free (dirname); |
| 2517 | |
| 2518 | return filename; |
| 2519 | } |
| 2520 | |
| 2521 | GType |
| 2522 | _ctk_builder_get_template_type (CtkBuilder *builder) |
| 2523 | { |
| 2524 | return builder->priv->template_type; |
| 2525 | } |
| 2526 | |
| 2527 | /** |
| 2528 | * ctk_builder_add_callback_symbol: |
| 2529 | * @builder: a #CtkBuilder |
| 2530 | * @callback_name: The name of the callback, as expected in the XML |
| 2531 | * @callback_symbol: (scope async): The callback pointer |
| 2532 | * |
| 2533 | * Adds the @callback_symbol to the scope of @builder under the given @callback_name. |
| 2534 | * |
| 2535 | * Using this function overrides the behavior of ctk_builder_connect_signals() |
| 2536 | * for any callback symbols that are added. Using this method allows for better |
| 2537 | * encapsulation as it does not require that callback symbols be declared in |
| 2538 | * the global namespace. |
| 2539 | * |
| 2540 | * Since: 3.10 |
| 2541 | */ |
| 2542 | void |
| 2543 | ctk_builder_add_callback_symbol (CtkBuilder *builder, |
| 2544 | const gchar *callback_name, |
| 2545 | GCallback callback_symbol) |
| 2546 | { |
| 2547 | g_return_if_fail (CTK_IS_BUILDER (builder))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return; } } while (0); |
| 2548 | g_return_if_fail (callback_name && callback_name[0])do { if ((callback_name && callback_name[0])) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "callback_name && callback_name[0]"); return; } } while (0); |
| 2549 | g_return_if_fail (callback_symbol != NULL)do { if ((callback_symbol != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "callback_symbol != NULL" ); return; } } while (0); |
| 2550 | |
| 2551 | if (!builder->priv->callbacks) |
| 2552 | builder->priv->callbacks = g_hash_table_new_full (g_str_hash, g_str_equal, |
| 2553 | g_free, NULL((void*)0)); |
| 2554 | |
| 2555 | g_hash_table_insert (builder->priv->callbacks, g_strdup (callback_name)g_strdup_inline (callback_name), callback_symbol); |
| 2556 | } |
| 2557 | |
| 2558 | /** |
| 2559 | * ctk_builder_add_callback_symbols: |
| 2560 | * @builder: a #CtkBuilder |
| 2561 | * @first_callback_name: The name of the callback, as expected in the XML |
| 2562 | * @first_callback_symbol: (scope async): The callback pointer |
| 2563 | * @...: A list of callback name and callback symbol pairs terminated with %NULL |
| 2564 | * |
| 2565 | * A convenience function to add many callbacks instead of calling |
| 2566 | * ctk_builder_add_callback_symbol() for each symbol. |
| 2567 | * |
| 2568 | * Since: 3.10 |
| 2569 | */ |
| 2570 | void |
| 2571 | ctk_builder_add_callback_symbols (CtkBuilder *builder, |
| 2572 | const gchar *first_callback_name, |
| 2573 | GCallback first_callback_symbol, |
| 2574 | ...) |
| 2575 | { |
| 2576 | va_list var_args; |
| 2577 | const gchar *callback_name; |
| 2578 | GCallback callback_symbol; |
| 2579 | |
| 2580 | g_return_if_fail (CTK_IS_BUILDER (builder))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return; } } while (0); |
| 2581 | g_return_if_fail (first_callback_name && first_callback_name[0])do { if ((first_callback_name && first_callback_name[ 0])) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "first_callback_name && first_callback_name[0]" ); return; } } while (0); |
| 2582 | g_return_if_fail (first_callback_symbol != NULL)do { if ((first_callback_symbol != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "first_callback_symbol != NULL" ); return; } } while (0); |
| 2583 | |
| 2584 | callback_name = first_callback_name; |
| 2585 | callback_symbol = first_callback_symbol; |
| 2586 | |
| 2587 | va_start (var_args, first_callback_symbol)__builtin_va_start(var_args, first_callback_symbol); |
| 2588 | |
| 2589 | do { |
| 2590 | |
| 2591 | ctk_builder_add_callback_symbol (builder, callback_name, callback_symbol); |
| 2592 | |
| 2593 | callback_name = va_arg (var_args, const gchar*)__builtin_va_arg(var_args, const gchar*); |
| 2594 | |
| 2595 | if (callback_name) |
| 2596 | callback_symbol = va_arg (var_args, GCallback)__builtin_va_arg(var_args, GCallback); |
| 2597 | |
| 2598 | } while (callback_name != NULL((void*)0)); |
| 2599 | |
| 2600 | va_end (var_args)__builtin_va_end(var_args); |
| 2601 | } |
| 2602 | |
| 2603 | /** |
| 2604 | * ctk_builder_lookup_callback_symbol: (skip) |
| 2605 | * @builder: a #CtkBuilder |
| 2606 | * @callback_name: The name of the callback |
| 2607 | * |
| 2608 | * Fetches a symbol previously added to @builder |
| 2609 | * with ctk_builder_add_callback_symbols() |
| 2610 | * |
| 2611 | * This function is intended for possible use in language bindings |
| 2612 | * or for any case that one might be cusomizing signal connections |
| 2613 | * using ctk_builder_connect_signals_full() |
| 2614 | * |
| 2615 | * Returns: (nullable): The callback symbol in @builder for @callback_name, or %NULL |
| 2616 | * |
| 2617 | * Since: 3.10 |
| 2618 | */ |
| 2619 | GCallback |
| 2620 | ctk_builder_lookup_callback_symbol (CtkBuilder *builder, |
| 2621 | const gchar *callback_name) |
| 2622 | { |
| 2623 | g_return_val_if_fail (CTK_IS_BUILDER (builder), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (((void*)0)); } } while (0); |
| 2624 | g_return_val_if_fail (callback_name && callback_name[0], NULL)do { if ((callback_name && callback_name[0])) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "callback_name && callback_name[0]"); return (((void *)0)); } } while (0); |
| 2625 | |
| 2626 | if (!builder->priv->callbacks) |
| 2627 | return NULL((void*)0); |
| 2628 | |
| 2629 | return g_hash_table_lookup (builder->priv->callbacks, callback_name); |
| 2630 | } |
| 2631 | |
| 2632 | /** |
| 2633 | * ctk_builder_new_from_file: |
| 2634 | * @filename: filename of user interface description file |
| 2635 | * |
| 2636 | * Builds the [CtkBuilder UI definition][BUILDER-UI] |
| 2637 | * in the file @filename. |
| 2638 | * |
| 2639 | * If there is an error opening the file or parsing the description then |
| 2640 | * the program will be aborted. You should only ever attempt to parse |
| 2641 | * user interface descriptions that are shipped as part of your program. |
| 2642 | * |
| 2643 | * Returns: a #CtkBuilder containing the described interface |
| 2644 | * |
| 2645 | * Since: 3.10 |
| 2646 | **/ |
| 2647 | CtkBuilder * |
| 2648 | ctk_builder_new_from_file (const gchar *filename) |
| 2649 | { |
| 2650 | GError *error = NULL((void*)0); |
| 2651 | CtkBuilder *builder; |
| 2652 | |
| 2653 | builder = ctk_builder_new (); |
| 2654 | if (!ctk_builder_add_from_file (builder, filename, &error)) |
| 2655 | g_error ("failed to add UI: %s", error->message); |
| 2656 | |
| 2657 | return builder; |
| 2658 | } |
| 2659 | |
| 2660 | /** |
| 2661 | * ctk_builder_new_from_resource: |
| 2662 | * @resource_path: a #GResource resource path |
| 2663 | * |
| 2664 | * Builds the [CtkBuilder UI definition][BUILDER-UI] |
| 2665 | * at @resource_path. |
| 2666 | * |
| 2667 | * If there is an error locating the resource or parsing the |
| 2668 | * description, then the program will be aborted. |
| 2669 | * |
| 2670 | * Returns: a #CtkBuilder containing the described interface |
| 2671 | * |
| 2672 | * Since: 3.10 |
| 2673 | **/ |
| 2674 | CtkBuilder * |
| 2675 | ctk_builder_new_from_resource (const gchar *resource_path) |
| 2676 | { |
| 2677 | GError *error = NULL((void*)0); |
| 2678 | CtkBuilder *builder; |
| 2679 | |
| 2680 | builder = ctk_builder_new (); |
| 2681 | if (!ctk_builder_add_from_resource (builder, resource_path, &error)) |
| 2682 | g_error ("failed to add UI: %s", error->message); |
| 2683 | |
| 2684 | return builder; |
| 2685 | } |
| 2686 | |
| 2687 | /** |
| 2688 | * ctk_builder_new_from_string: |
| 2689 | * @string: a user interface (XML) description |
| 2690 | * @length: the length of @string, or -1 |
| 2691 | * |
| 2692 | * Builds the user interface described by @string (in the |
| 2693 | * [CtkBuilder UI definition][BUILDER-UI] format). |
| 2694 | * |
| 2695 | * If @string is %NULL-terminated, then @length should be -1. |
| 2696 | * If @length is not -1, then it is the length of @string. |
| 2697 | * |
| 2698 | * If there is an error parsing @string then the program will be |
| 2699 | * aborted. You should not attempt to parse user interface description |
| 2700 | * from untrusted sources. |
| 2701 | * |
| 2702 | * Returns: a #CtkBuilder containing the interface described by @string |
| 2703 | * |
| 2704 | * Since: 3.10 |
| 2705 | **/ |
| 2706 | CtkBuilder * |
| 2707 | ctk_builder_new_from_string (const gchar *string, |
| 2708 | gssize length) |
| 2709 | { |
| 2710 | GError *error = NULL((void*)0); |
| 2711 | CtkBuilder *builder; |
| 2712 | |
| 2713 | builder = ctk_builder_new (); |
| 2714 | if (!ctk_builder_add_from_string (builder, string, length, &error)) |
| 2715 | g_error ("failed to add UI: %s", error->message); |
| 2716 | |
| 2717 | return builder; |
| 2718 | } |
| 2719 | |
| 2720 | /** |
| 2721 | * ctk_builder_set_application: |
| 2722 | * @builder: a #CtkBuilder |
| 2723 | * @application: a #CtkApplication |
| 2724 | * |
| 2725 | * Sets the application associated with @builder. |
| 2726 | * |
| 2727 | * You only need this function if there is more than one #GApplication |
| 2728 | * in your process. @application cannot be %NULL. |
| 2729 | * |
| 2730 | * Since: 3.10 |
| 2731 | **/ |
| 2732 | void |
| 2733 | ctk_builder_set_application (CtkBuilder *builder, |
| 2734 | CtkApplication *application) |
| 2735 | { |
| 2736 | g_return_if_fail (CTK_IS_BUILDER (builder))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return; } } while (0); |
| 2737 | g_return_if_fail (CTK_IS_APPLICATION (application))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((application)); GType __t = ((ctk_application_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_APPLICATION (application)"); return ; } } while (0); |
| 2738 | |
| 2739 | if (builder->priv->application) |
| 2740 | g_object_unref (builder->priv->application); |
| 2741 | |
| 2742 | builder->priv->application = g_object_ref (application)((__typeof__ (application)) (g_object_ref) (application)); |
| 2743 | } |
| 2744 | |
| 2745 | /** |
| 2746 | * ctk_builder_get_application: |
| 2747 | * @builder: a #CtkBuilder |
| 2748 | * |
| 2749 | * Gets the #CtkApplication associated with the builder. |
| 2750 | * |
| 2751 | * The #CtkApplication is used for creating action proxies as requested |
| 2752 | * from XML that the builder is loading. |
| 2753 | * |
| 2754 | * By default, the builder uses the default application: the one from |
| 2755 | * g_application_get_default(). If you want to use another application |
| 2756 | * for constructing proxies, use ctk_builder_set_application(). |
| 2757 | * |
| 2758 | * Returns: (nullable) (transfer none): the application being used by the builder, |
| 2759 | * or %NULL |
| 2760 | * |
| 2761 | * Since: 3.10 |
| 2762 | **/ |
| 2763 | CtkApplication * |
| 2764 | ctk_builder_get_application (CtkBuilder *builder) |
| 2765 | { |
| 2766 | g_return_val_if_fail (CTK_IS_BUILDER (builder), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((builder)); GType __t = ((ctk_builder_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_BUILDER (builder)"); return (((void*)0)); } } while (0); |
| 2767 | |
| 2768 | if (!builder->priv->application) |
| 2769 | { |
| 2770 | GApplication *application; |
| 2771 | |
| 2772 | application = g_application_get_default (); |
| 2773 | if (application && CTK_IS_APPLICATION (application)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (application)); GType __t = ((ctk_application_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 2774 | builder->priv->application = g_object_ref (CTK_APPLICATION (application))((__typeof__ (((((CtkApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((application)), ((ctk_application_get_type ())))))))) (g_object_ref) (((((CtkApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((application)), ((ctk_application_get_type ())))))))); |
| 2775 | } |
| 2776 | |
| 2777 | return builder->priv->application; |
| 2778 | } |
| 2779 | |
| 2780 | /*< private > |
| 2781 | * _ctk_builder_prefix_error: |
| 2782 | * @builder: a #CtkBuilder |
| 2783 | * @context: the #GMarkupParseContext |
| 2784 | * @error: an error |
| 2785 | * |
| 2786 | * Calls g_prefix_error() to prepend a filename:line:column marker |
| 2787 | * to the given error. The filename is taken from @builder, and |
| 2788 | * the line and column are obtained by calling |
| 2789 | * g_markup_parse_context_get_position(). |
| 2790 | * |
| 2791 | * This is intended to be called on errors returned by |
| 2792 | * g_markup_collect_attributes() in a start_element vfunc. |
| 2793 | */ |
| 2794 | void |
| 2795 | _ctk_builder_prefix_error (CtkBuilder *builder, |
| 2796 | GMarkupParseContext *context, |
| 2797 | GError **error) |
| 2798 | { |
| 2799 | gint line, col; |
| 2800 | |
| 2801 | g_markup_parse_context_get_position (context, &line, &col); |
| 2802 | g_prefix_error (error, "%s:%d:%d ", builder->priv->filename, line, col); |
| 2803 | } |
| 2804 | |
| 2805 | /*< private > |
| 2806 | * _ctk_builder_error_unhandled_tag: |
| 2807 | * @builder: a #CtkBuilder |
| 2808 | * @context: the #GMarkupParseContext |
| 2809 | * @object: name of the object that is being handled |
| 2810 | * @element_name: name of the element whose start tag is being handled |
| 2811 | * @error: return location for the error |
| 2812 | * |
| 2813 | * Sets @error to a suitable error indicating that an @element_name |
| 2814 | * tag is not expected in the custom markup for @object. |
| 2815 | * |
| 2816 | * This is intended to be called in a start_element vfunc. |
| 2817 | */ |
| 2818 | void |
| 2819 | _ctk_builder_error_unhandled_tag (CtkBuilder *builder, |
| 2820 | GMarkupParseContext *context, |
| 2821 | const gchar *object, |
| 2822 | const gchar *element_name, |
| 2823 | GError **error) |
| 2824 | { |
| 2825 | gint line, col; |
| 2826 | |
| 2827 | g_markup_parse_context_get_position (context, &line, &col); |
| 2828 | g_set_error (error, |
| 2829 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2830 | CTK_BUILDER_ERROR_UNHANDLED_TAG, |
| 2831 | "%s:%d:%d Unsupported tag for %s: <%s>", |
| 2832 | builder->priv->filename, line, col, |
| 2833 | object, element_name); |
| 2834 | } |
| 2835 | |
| 2836 | /*< private > |
| 2837 | * @builder: a #CtkBuilder |
| 2838 | * @context: the #GMarkupParseContext |
| 2839 | * @parent_name: the name of the expected parent element |
| 2840 | * @error: return location for an error |
| 2841 | * |
| 2842 | * Checks that the parent element of the currently handled |
| 2843 | * start tag is @parent_name and set @error if it isn't. |
| 2844 | * |
| 2845 | * This is intended to be called in start_element vfuncs to |
| 2846 | * ensure that element nesting is as intended. |
| 2847 | * |
| 2848 | * Returns: %TRUE if @parent_name is the parent element |
| 2849 | */ |
| 2850 | gboolean |
| 2851 | _ctk_builder_check_parent (CtkBuilder *builder, |
| 2852 | GMarkupParseContext *context, |
| 2853 | const gchar *parent_name, |
| 2854 | GError **error) |
| 2855 | { |
| 2856 | const GSList *stack; |
| 2857 | gint line, col; |
| 2858 | const gchar *parent; |
| 2859 | const gchar *element; |
| 2860 | |
| 2861 | stack = g_markup_parse_context_get_element_stack (context); |
| 2862 | |
| 2863 | element = (const gchar *)stack->data; |
| 2864 | parent = stack->next ? (const gchar *)stack->next->data : ""; |
| 2865 | |
| 2866 | if (g_str_equal (parent_name, parent)(strcmp ((const char *) (parent_name), (const char *) (parent )) == 0) || |
| 2867 | (g_str_equal (parent_name, "object")(strcmp ((const char *) (parent_name), (const char *) ("object" )) == 0) && g_str_equal (parent, "template")(strcmp ((const char *) (parent), (const char *) ("template") ) == 0))) |
| 2868 | return TRUE(!(0)); |
| 2869 | |
| 2870 | g_markup_parse_context_get_position (context, &line, &col); |
| 2871 | g_set_error (error, |
| 2872 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), |
| 2873 | CTK_BUILDER_ERROR_INVALID_TAG, |
| 2874 | "%s:%d:%d Can't use <%s> here", |
| 2875 | builder->priv->filename, line, col, element); |
| 2876 | |
| 2877 | return FALSE(0); |
| 2878 | } |
| 2879 | |
| 2880 | /*< private > |
| 2881 | * @builder: a #CtkBuilder |
| 2882 | * @name: object name to look up |
| 2883 | * @line: line number where @name was encountered |
| 2884 | * @col: column number where @name was encountered |
| 2885 | * |
| 2886 | * Looks up an object by name. Similar to ctk_builder_get_object(), |
| 2887 | * but sets an error if lookup fails during custom_tag_end, |
| 2888 | * custom_finished or parser_finished vfuncs. |
| 2889 | * |
| 2890 | * The reason for doing things this way is that these vfuncs don't |
| 2891 | * take a GError** parameter to return an error. |
| 2892 | * |
| 2893 | * Returns: the found object |
| 2894 | */ |
| 2895 | GObject * |
| 2896 | _ctk_builder_lookup_object (CtkBuilder *builder, |
| 2897 | const gchar *name, |
| 2898 | gint line, |
| 2899 | gint col) |
| 2900 | { |
| 2901 | GObject *obj; |
| 2902 | GError *error = NULL((void*)0); |
| 2903 | |
| 2904 | obj = g_hash_table_lookup (builder->priv->objects, name); |
| 2905 | error = (GError *) g_object_get_data (G_OBJECT (builder)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((builder)), (((GType) ((20) << (2)))))))), "lookup-error"); |
| 2906 | |
| 2907 | if (!obj && !error) |
| 2908 | { |
| 2909 | g_set_error (&error, |
| 2910 | CTK_BUILDER_ERROR(ctk_builder_error_quark ()), CTK_BUILDER_ERROR_INVALID_ID, |
| 2911 | "%s:%d:%d Object with ID %s not found", |
| 2912 | builder->priv->filename, line, col, name); |
| 2913 | g_object_set_data_full (G_OBJECT (builder)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((builder)), (((GType) ((20) << (2)))))))), "lookup-error", |
| 2914 | error, (GDestroyNotify)g_error_free); |
| 2915 | } |
| 2916 | |
| 2917 | return obj; |
| 2918 | } |
| 2919 | |
| 2920 | /*< private > |
| 2921 | * _ctk_builder_lookup_failed: |
| 2922 | * @CtkBuilder: a #CtkBuilder |
| 2923 | * @error: return location for error |
| 2924 | * |
| 2925 | * Finds whether any object lookups have failed. |
| 2926 | * |
| 2927 | * Returns: %TRUE if @error has been set |
| 2928 | */ |
| 2929 | gboolean |
| 2930 | _ctk_builder_lookup_failed (CtkBuilder *builder, |
| 2931 | GError **error) |
| 2932 | { |
| 2933 | GError *lookup_error; |
| 2934 | |
| 2935 | lookup_error = (GError*) g_object_steal_data (G_OBJECT (builder)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((builder)), (((GType) ((20) << (2)))))))), "lookup-error"); |
| 2936 | if (lookup_error) |
| 2937 | { |
| 2938 | g_propagate_error (error, lookup_error); |
| 2939 | return TRUE(!(0)); |
| 2940 | } |
| 2941 | |
| 2942 | return FALSE(0); |
| 2943 | } |