diff --git a/gtk/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c index 2cefba0bc43c9fe6027de8b9239c5a7ae516a521..c4590678120629b77b936696e53f3bd8a41ed6e3 100644 --- a/gtk/gtkaccessiblevalue.c +++ b/gtk/gtkaccessiblevalue.c @@ -45,10 +45,13 @@ #include "gtkaccessiblevalueprivate.h" #include "gtkaccessible.h" +#include "gtkbuilderprivate.h" #include "gtkenums.h" +#include "gtktypebuiltins.h" #include #include +#include G_DEFINE_QUARK (gtk-accessible-value-error-quark, gtk_accessible_value_error) @@ -637,6 +640,7 @@ typedef struct { */ GCallback ctor; GCallback getter; + GCallback parser; } GtkAccessibleCollect; static const GtkAccessibleCollect collect_states[] = { @@ -670,7 +674,8 @@ static const GtkAccessibleCollect collect_states[] = { .ctype = GTK_ACCESSIBLE_COLLECT_TOKEN, .name = "invalid", .ctor = (GCallback) gtk_invalid_accessible_value_new, - .getter = (GCallback) gtk_invalid_accessible_value_get + .getter = (GCallback) gtk_invalid_accessible_value_get, + .parser = (GCallback) gtk_invalid_accessible_value_parse, }, [GTK_ACCESSIBLE_STATE_PRESSED] = { .value = GTK_ACCESSIBLE_STATE_PRESSED, @@ -691,7 +696,8 @@ static const GtkAccessibleCollect collect_props[] = { .ctype = GTK_ACCESSIBLE_COLLECT_TOKEN, .name = "autocomplete", .ctor = (GCallback) gtk_autocomplete_accessible_value_new, - .getter = (GCallback) gtk_autocomplete_accessible_value_get + .getter = (GCallback) gtk_autocomplete_accessible_value_get, + .parser = (GCallback) gtk_autocomplete_accessible_value_parse, }, [GTK_ACCESSIBLE_PROPERTY_DESCRIPTION] = { .value = GTK_ACCESSIBLE_PROPERTY_DESCRIPTION, @@ -742,7 +748,8 @@ static const GtkAccessibleCollect collect_props[] = { .ctype = GTK_ACCESSIBLE_COLLECT_TOKEN | GTK_ACCESSIBLE_COLLECT_UNDEFINED, .name = "orientation", .ctor = (GCallback) gtk_orientation_accessible_value_new, - .getter = (GCallback) gtk_orientation_accessible_value_get + .getter = (GCallback) gtk_orientation_accessible_value_get, + .parser = (GCallback) gtk_orientation_accessible_value_parse, }, [GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER] = { .value = GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER, @@ -769,7 +776,8 @@ static const GtkAccessibleCollect collect_props[] = { .ctype = GTK_ACCESSIBLE_COLLECT_TOKEN, .name = "sort", .ctor = (GCallback) gtk_sort_accessible_value_new, - .getter = (GCallback) gtk_sort_accessible_value_get + .getter = (GCallback) gtk_sort_accessible_value_get, + .parser = (GCallback) gtk_sort_accessible_value_parse, }, [GTK_ACCESSIBLE_PROPERTY_VALUE_MAX] = { .value = GTK_ACCESSIBLE_PROPERTY_VALUE_MAX, @@ -896,6 +904,10 @@ typedef GtkAccessibleValue * (* GtkAccessibleValueStringCtor) (const char *val typedef GtkAccessibleValue * (* GtkAccessibleValueRefCtor) (GtkAccessible *value); typedef GtkAccessibleValue * (* GtkAccessibleValueRefListCtor) (GList *value); +typedef GtkAccessibleValue * (* GtkAccessibleValueEnumParser) (const char *str, + gsize len, + GError **error); + /*< private > * gtk_accessible_value_get_default_for_state: * @state: a #GtkAccessibleState @@ -1314,6 +1326,128 @@ gtk_accessible_value_collect_value (const GtkAccessibleCollect *cstate, return res; } +static GtkAccessibleValue * +gtk_accessible_value_parse (const GtkAccessibleCollect *cstate, + const char *str, + gsize len, + GError **error) +{ + GtkAccessibleValue *res = NULL; + GtkAccessibleCollectType ctype = cstate->ctype; + gboolean collects_undef = (ctype & GTK_ACCESSIBLE_COLLECT_UNDEFINED) != 0; + + ctype &= (GTK_ACCESSIBLE_COLLECT_UNDEFINED - 1); + + /* Tristate values include "undefined" by definition */ + if (ctype == GTK_ACCESSIBLE_COLLECT_TRISTATE) + collects_undef = TRUE; + + switch (ctype) + { + case GTK_ACCESSIBLE_COLLECT_BOOLEAN: + { + gboolean b; + + if (collects_undef && strncmp (str, "undefined", 9) == 0) + res = gtk_undefined_accessible_value_new (); + else if (_gtk_builder_boolean_from_string (str, &b, error)) + res = gtk_boolean_accessible_value_new (b); + } + break; + + case GTK_ACCESSIBLE_COLLECT_TRISTATE: + { + int value; + + if (collects_undef && strncmp (str, "undefined", 9) == 0) + res = gtk_undefined_accessible_value_new (); + else if (_gtk_builder_enum_from_string (GTK_TYPE_ACCESSIBLE_TRISTATE, str, &value, error)) + res = gtk_boolean_accessible_value_new (value); + } + break; + + case GTK_ACCESSIBLE_COLLECT_TOKEN: + { + GtkAccessibleValueEnumParser parser = + (GtkAccessibleValueEnumParser) cstate->parser; + + if (collects_undef && strncmp (str, "undefined", 9) == 0) + { + res = gtk_undefined_accessible_value_new (); + } + else + { + /* Token collection requires a constructor */ + g_assert (parser != NULL); + + res = (* parser) (str, len, error); + } + } + break; + + case GTK_ACCESSIBLE_COLLECT_INTEGER: + { + char *end = NULL; + gint64 value = g_ascii_strtoll (str, &end, 10); + + if (str == end) + { + int saved_errno = errno; + g_set_error (error, GTK_ACCESSIBLE_VALUE_ERROR, + GTK_ACCESSIBLE_VALUE_ERROR_INVALID_VALUE, + "Invalid integer value “%s”: %s", + str, g_strerror (saved_errno)); + + return NULL; + } + else + res = gtk_int_accessible_value_new ((int) value); + } + break; + + case GTK_ACCESSIBLE_COLLECT_NUMBER: + { + char *end = NULL; + double value = g_ascii_strtod (str, &end); + + if (str == end || isnan (value) || isinf (value)) + { + g_set_error (error, GTK_ACCESSIBLE_VALUE_ERROR, + GTK_ACCESSIBLE_VALUE_ERROR_INVALID_VALUE, + "Invalid numeric value “%s”", + str); + return NULL; + } + + res = gtk_number_accessible_value_new (value); + } + break; + + case GTK_ACCESSIBLE_COLLECT_STRING: + { + res = gtk_string_accessible_value_new (str); + } + break; + + case GTK_ACCESSIBLE_COLLECT_REFERENCE: + case GTK_ACCESSIBLE_COLLECT_REFERENCE_LIST: + { + /* We do not error out, to let the caller code deal + * with the references themselves + */ + res = NULL; + } + break; + + case GTK_ACCESSIBLE_COLLECT_UNDEFINED: + case GTK_ACCESSIBLE_COLLECT_INVALID: + default: + g_assert_not_reached (); + break; + } + + return res; +} /*< private > * gtk_accessible_value_collect_for_state: * @state: a #GtkAccessibleState @@ -1370,6 +1504,19 @@ gtk_accessible_value_collect_for_state_value (GtkAccessibleState state, return gtk_accessible_value_collect_value (cstate, value, error); } +GtkAccessibleValue * +gtk_accessible_value_parse_for_state (GtkAccessibleState state, + const char *str, + gsize len, + GError **error) +{ + const GtkAccessibleCollect *cstate = &collect_states[state]; + + g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_SELECTED, NULL); + + return gtk_accessible_value_parse (cstate, str, len, error); +} + /*< private > * gtk_accessible_value_get_default_for_property: * @property: a #GtkAccessibleProperty @@ -1487,6 +1634,19 @@ gtk_accessible_value_collect_for_property_value (GtkAccessibleProperty propert return gtk_accessible_value_collect_value (cstate, value, error); } +GtkAccessibleValue * +gtk_accessible_value_parse_for_property (GtkAccessibleProperty property, + const char *str, + gsize len, + GError **error) +{ + const GtkAccessibleCollect *cstate = &collect_props[property]; + + g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, NULL); + + return gtk_accessible_value_parse (cstate, str, len, error); +} + /*< private > * gtk_accessible_value_get_default_for_relation: * @relation: a #GtkAccessibleRelation @@ -1596,4 +1756,17 @@ gtk_accessible_value_collect_for_relation_value (GtkAccessibleRelation relatio return gtk_accessible_value_collect_value (cstate, value, error); } +GtkAccessibleValue * +gtk_accessible_value_parse_for_relation (GtkAccessibleRelation relation, + const char *str, + gsize len, + GError **error) +{ + const GtkAccessibleCollect *cstate = &collect_rels[relation]; + + g_return_val_if_fail (relation <= GTK_ACCESSIBLE_RELATION_SET_SIZE, NULL); + + return gtk_accessible_value_parse (cstate, str, len, error); +} + /* }}} */ diff --git a/gtk/gtkaccessiblevalueprivate.h b/gtk/gtkaccessiblevalueprivate.h index 073b2c2c45f4ec0848600ecbfb5ec60ce22b4c9b..3290fc1e6e1f2791e896edaeb04dc38bb09d51fb 100644 --- a/gtk/gtkaccessiblevalueprivate.h +++ b/gtk/gtkaccessiblevalueprivate.h @@ -98,6 +98,10 @@ GtkAccessibleValue * gtk_accessible_value_collect_for_state (GtkAcce GtkAccessibleValue * gtk_accessible_value_collect_for_state_value (GtkAccessibleState state, const GValue *value, GError **error); +GtkAccessibleValue * gtk_accessible_value_parse_for_state (GtkAccessibleState state, + const char *str, + gsize len, + GError **error); GtkAccessibleValue * gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property); GtkAccessibleValue * gtk_accessible_value_collect_for_property (GtkAccessibleProperty property, @@ -106,6 +110,10 @@ GtkAccessibleValue * gtk_accessible_value_collect_for_property (GtkAcce GtkAccessibleValue * gtk_accessible_value_collect_for_property_value (GtkAccessibleProperty property, const GValue *value, GError **error); +GtkAccessibleValue * gtk_accessible_value_parse_for_property (GtkAccessibleProperty property, + const char *str, + gsize len, + GError **error); GtkAccessibleValue * gtk_accessible_value_get_default_for_relation (GtkAccessibleRelation relation); GtkAccessibleValue * gtk_accessible_value_collect_for_relation (GtkAccessibleRelation relation, @@ -114,6 +122,10 @@ GtkAccessibleValue * gtk_accessible_value_collect_for_relation (GtkAcce GtkAccessibleValue * gtk_accessible_value_collect_for_relation_value (GtkAccessibleRelation relation, const GValue *value, GError **error); +GtkAccessibleValue * gtk_accessible_value_parse_for_relation (GtkAccessibleRelation relation, + const char *str, + gsize len, + GError **error); /* Basic values */ GtkAccessibleValue * gtk_undefined_accessible_value_new (void); @@ -143,14 +155,26 @@ GList * gtk_reference_list_accessible_value_get (const G /* Token values */ GtkAccessibleValue * gtk_invalid_accessible_value_new (GtkAccessibleInvalidState value); GtkAccessibleInvalidState gtk_invalid_accessible_value_get (const GtkAccessibleValue *value); +GtkAccessibleValue * gtk_invalid_accessible_value_parse (const char *str, + gsize len, + GError **error); GtkAccessibleValue * gtk_autocomplete_accessible_value_new (GtkAccessibleAutocomplete value); GtkAccessibleAutocomplete gtk_autocomplete_accessible_value_get (const GtkAccessibleValue *value); +GtkAccessibleValue * gtk_autocomplete_accessible_value_parse (const char *str, + gsize len, + GError **error); GtkAccessibleValue * gtk_orientation_accessible_value_new (GtkOrientation value); GtkOrientation gtk_orientation_accessible_value_get (const GtkAccessibleValue *value); +GtkAccessibleValue * gtk_orientation_accessible_value_parse (const char *str, + gsize len, + GError **error); GtkAccessibleValue * gtk_sort_accessible_value_new (GtkAccessibleSort value); GtkAccessibleSort gtk_sort_accessible_value_get (const GtkAccessibleValue *value); +GtkAccessibleValue * gtk_sort_accessible_value_parse (const char *str, + gsize len, + GError **error); G_END_DECLS diff --git a/gtk/gtkaccessiblevaluestatic.c b/gtk/gtkaccessiblevaluestatic.c index 6d26ea2900647ea3307e434d1046020c4f083cf4..07600def081345f76ec8eb98e7cde3eb23cc1d1c 100644 --- a/gtk/gtkaccessiblevaluestatic.c +++ b/gtk/gtkaccessiblevaluestatic.c @@ -21,6 +21,9 @@ #include "config.h" #include "gtkaccessiblevalueprivate.h" +#include "gtkbuilderprivate.h" +#include "gtkenums.h" +#include "gtktypebuiltins.h" /* {{{ Undefined value */ @@ -282,6 +285,19 @@ gtk_invalid_accessible_value_get (const GtkAccessibleValue *value) return self->value; } +GtkAccessibleValue * +gtk_invalid_accessible_value_parse (const char *str, + gsize len, + GError **error) +{ + int value; + + if (_gtk_builder_enum_from_string (GTK_TYPE_ACCESSIBLE_INVALID_STATE, str, &value, error)) + return gtk_invalid_accessible_value_new (value); + + return NULL; +} + static const GtkAccessibleValueClass GTK_AUTOCOMPLETE_ACCESSIBLE_VALUE = { .type = GTK_ACCESSIBLE_VALUE_TYPE_TOKEN, .type_name = "GtkAutocompleteAccessibleValue", @@ -327,6 +343,19 @@ gtk_autocomplete_accessible_value_get (const GtkAccessibleValue *value) return self->value; } +GtkAccessibleValue * +gtk_autocomplete_accessible_value_parse (const char *str, + gsize len, + GError **error) +{ + int value; + + if (_gtk_builder_enum_from_string (GTK_TYPE_ACCESSIBLE_AUTOCOMPLETE, str, &value, error)) + return gtk_autocomplete_accessible_value_new (value); + + return NULL; +} + static const GtkAccessibleValueClass GTK_ORIENTATION_ACCESSIBLE_VALUE = { .type = GTK_ACCESSIBLE_VALUE_TYPE_TOKEN, .type_name = "GtkOrientationAccessibleValue", @@ -366,6 +395,19 @@ gtk_orientation_accessible_value_get (const GtkAccessibleValue *value) return self->value; } +GtkAccessibleValue * +gtk_orientation_accessible_value_parse (const char *str, + gsize len, + GError **error) +{ + int value; + + if (_gtk_builder_enum_from_string (GTK_TYPE_ORIENTATION, str, &value, error)) + return gtk_orientation_accessible_value_new (value); + + return NULL; +} + static const GtkAccessibleValueClass GTK_SORT_ACCESSIBLE_VALUE = { .type = GTK_ACCESSIBLE_VALUE_TYPE_TOKEN, .type_name = "GtkSortAccessibleValue", @@ -411,4 +453,17 @@ gtk_sort_accessible_value_get (const GtkAccessibleValue *value) return self->value; } +GtkAccessibleValue * +gtk_sort_accessible_value_parse (const char *str, + gsize len, + GError **error) +{ + int value; + + if (_gtk_builder_enum_from_string (GTK_TYPE_ACCESSIBLE_SORT, str, &value, error)) + return gtk_sort_accessible_value_new (value); + + return NULL; +} + /* }}} */ diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c index 182ccad5f1bbf995a4a92a1596a0dfead480fe67..b6663126cffd8337af9f610ef805dc744462811b 100644 --- a/gtk/gtkbuilder.c +++ b/gtk/gtkbuilder.c @@ -1997,7 +1997,7 @@ gtk_builder_value_from_string (GtkBuilder *builder, string, value, error); } -static gboolean +gboolean _gtk_builder_boolean_from_string (const char *string, gboolean *value, GError **error) diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h index 5fe910486b3edd4d46a6c67b9a53a0a02067ca43..c6200685c475d4a8cc136a87efb819ae0e7f5113 100644 --- a/gtk/gtkbuilderprivate.h +++ b/gtk/gtkbuilderprivate.h @@ -242,6 +242,10 @@ gboolean _gtk_builder_flags_from_string (GType type, const char *string, guint *value, GError **error); +gboolean _gtk_builder_boolean_from_string (const char *string, + gboolean *value, + GError **error); + const char * _gtk_builder_parser_translate (const char *domain, const char *context, const char *text); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index fa744d1d9c70acbf68b763c164745db74f95cc9f..ad61b06674f1beea58066de819993472957ddfbe 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -248,8 +248,8 @@ * * # GtkWidget as GtkBuildable * - * The GtkWidget implementation of the GtkBuildable interface supports a - * custom element, which has attributes named ”key”, ”modifiers” + * The GtkWidget implementation of the #GtkBuildable interface supports a + * custom `` element, which has attributes named ”key”, ”modifiers” * and ”signal” and allows to specify accelerators. * * An example of a UI definition fragment specifying an accelerator: @@ -260,7 +260,7 @@ * ]| * * If the parent widget uses a #GtkLayoutManager, #GtkWidget supports a - * custom element, used to define layout properties: + * custom `` element, used to define layout properties: * * |[ * @@ -288,8 +288,8 @@ * * ]| * - * Finally, GtkWidget allows style information such as style classes to - * be associated with widgets, using the custom