mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 10:00:45 -05:00
script: Support translatable strings for properties
ClutterScript should be able to automatically call gettext() and friends on strings loaded from a UI definition, prior to passing the string to the object it is constructing. The basic implementation is trivial: - set a translation domain on the ClutterScript instance - mark the translatable strings inside the JSON data, like: "property" : { "translatable" : true, "string" : "a translatable string" } The hard part is now getting the tools we use to extract the translatable strings to understand the JSON format we use inside ClutterScript.
This commit is contained in:
parent
4a9414ff87
commit
7646404196
@ -1088,6 +1088,54 @@ clutter_script_parser_parse_end (JsonParser *parser)
|
|||||||
clutter_script_ensure_objects (CLUTTER_SCRIPT_PARSER (parser)->script);
|
clutter_script_ensure_objects (CLUTTER_SCRIPT_PARSER (parser)->script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_clutter_script_parse_translatable_string (ClutterScript *script,
|
||||||
|
JsonNode *node,
|
||||||
|
char **str)
|
||||||
|
{
|
||||||
|
JsonObject *obj;
|
||||||
|
const char *string, *domain;
|
||||||
|
const char *res;
|
||||||
|
gboolean translatable;
|
||||||
|
|
||||||
|
if (!JSON_NODE_HOLDS_OBJECT (node))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
obj = json_node_get_object (node);
|
||||||
|
if (!(json_object_has_member (obj, "translatable") &&
|
||||||
|
json_object_has_member (obj, "string")))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
translatable = json_object_get_boolean_member (obj, "translatable");
|
||||||
|
|
||||||
|
string = json_object_get_string_member (obj, "string");
|
||||||
|
if (string == NULL || *string == '\0')
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (json_object_has_member (obj, "domain"))
|
||||||
|
domain = json_object_get_string_member (obj, "domain");
|
||||||
|
else
|
||||||
|
domain = NULL;
|
||||||
|
|
||||||
|
if (domain == NULL || *domain == '\0')
|
||||||
|
domain = clutter_script_get_translation_domain (script);
|
||||||
|
|
||||||
|
if (translatable)
|
||||||
|
{
|
||||||
|
if (domain != NULL && *domain != '\0')
|
||||||
|
res = g_dgettext (domain, string);
|
||||||
|
else
|
||||||
|
res = gettext (string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = string;
|
||||||
|
|
||||||
|
if (str != NULL)
|
||||||
|
*str = g_strdup (res);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_clutter_script_parse_node (ClutterScript *script,
|
_clutter_script_parse_node (ClutterScript *script,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
@ -1203,6 +1251,16 @@ _clutter_script_parse_node (ClutterScript *script,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (p_type == G_TYPE_STRING)
|
||||||
|
{
|
||||||
|
char *str = NULL;
|
||||||
|
|
||||||
|
if (_clutter_script_parse_translatable_string (script, node, &str))
|
||||||
|
{
|
||||||
|
g_value_take_string (value, str);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -130,6 +130,9 @@ gboolean _clutter_script_parse_color (ClutterScript *script,
|
|||||||
ClutterColor *color);
|
ClutterColor *color);
|
||||||
GObject *_clutter_script_parse_alpha (ClutterScript *script,
|
GObject *_clutter_script_parse_alpha (ClutterScript *script,
|
||||||
JsonNode *node);
|
JsonNode *node);
|
||||||
|
gboolean _clutter_script_parse_translatable_string (ClutterScript *script,
|
||||||
|
JsonNode *node,
|
||||||
|
char **str);
|
||||||
|
|
||||||
void _clutter_script_construct_object (ClutterScript *script,
|
void _clutter_script_construct_object (ClutterScript *script,
|
||||||
ObjectInfo *oinfo);
|
ObjectInfo *oinfo);
|
||||||
|
@ -256,6 +256,7 @@ enum
|
|||||||
|
|
||||||
PROP_FILENAME_SET,
|
PROP_FILENAME_SET,
|
||||||
PROP_FILENAME,
|
PROP_FILENAME,
|
||||||
|
PROP_TRANSLATION_DOMAIN,
|
||||||
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
@ -278,6 +279,8 @@ struct _ClutterScriptPrivate
|
|||||||
|
|
||||||
gchar **search_paths;
|
gchar **search_paths;
|
||||||
|
|
||||||
|
gchar *translation_domain;
|
||||||
|
|
||||||
gchar *filename;
|
gchar *filename;
|
||||||
guint is_filename : 1;
|
guint is_filename : 1;
|
||||||
};
|
};
|
||||||
@ -385,10 +388,31 @@ clutter_script_finalize (GObject *gobject)
|
|||||||
g_strfreev (priv->search_paths);
|
g_strfreev (priv->search_paths);
|
||||||
g_free (priv->filename);
|
g_free (priv->filename);
|
||||||
g_hash_table_destroy (priv->states);
|
g_hash_table_destroy (priv->states);
|
||||||
|
g_free (priv->translation_domain);
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_script_parent_class)->finalize (gobject);
|
G_OBJECT_CLASS (clutter_script_parent_class)->finalize (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_script_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterScript *script = CLUTTER_SCRIPT (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_TRANSLATION_DOMAIN:
|
||||||
|
clutter_script_set_translation_domain (script, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_script_get_property (GObject *gobject,
|
clutter_script_get_property (GObject *gobject,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -402,9 +426,15 @@ clutter_script_get_property (GObject *gobject,
|
|||||||
case PROP_FILENAME_SET:
|
case PROP_FILENAME_SET:
|
||||||
g_value_set_boolean (value, script->priv->is_filename);
|
g_value_set_boolean (value, script->priv->is_filename);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_FILENAME:
|
case PROP_FILENAME:
|
||||||
g_value_set_string (value, script->priv->filename);
|
g_value_set_string (value, script->priv->filename);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_TRANSLATION_DOMAIN:
|
||||||
|
g_value_set_string (value, script->priv->translation_domain);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -451,6 +481,25 @@ clutter_script_class_init (ClutterScriptClass *klass)
|
|||||||
NULL,
|
NULL,
|
||||||
CLUTTER_PARAM_READABLE);
|
CLUTTER_PARAM_READABLE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterScript:translation-domain:
|
||||||
|
*
|
||||||
|
* The translation domain, used to localize strings marked as translatable
|
||||||
|
* inside a UI definition.
|
||||||
|
*
|
||||||
|
* If #ClutterScript:translation-domain is set to %NULL, #ClutterScript
|
||||||
|
* will use gettext(), otherwise g_dgettext() will be used.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
*/
|
||||||
|
obj_props[PROP_TRANSLATION_DOMAIN] =
|
||||||
|
g_param_spec_string ("translation-domain",
|
||||||
|
P_("Translation Domain"),
|
||||||
|
P_("The translation domain used to localize string"),
|
||||||
|
NULL,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
|
||||||
|
gobject_class->set_property = clutter_script_set_property;
|
||||||
gobject_class->get_property = clutter_script_get_property;
|
gobject_class->get_property = clutter_script_get_property;
|
||||||
gobject_class->finalize = clutter_script_finalize;
|
gobject_class->finalize = clutter_script_finalize;
|
||||||
|
|
||||||
@ -1439,6 +1488,50 @@ clutter_script_get_states (ClutterScript *script,
|
|||||||
return g_hash_table_lookup (script->priv->states, name);
|
return g_hash_table_lookup (script->priv->states, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_script_set_translation_domain:
|
||||||
|
* @script: a #ClutterScript
|
||||||
|
* @domain: (allow-none): the translation domain, or %NULL
|
||||||
|
*
|
||||||
|
* Sets the translation domain for @script.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_script_set_translation_domain (ClutterScript *script,
|
||||||
|
const gchar *domain)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_SCRIPT (script));
|
||||||
|
|
||||||
|
if (g_strcmp0 (domain, script->priv->translation_domain) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free (script->priv->translation_domain);
|
||||||
|
script->priv->translation_domain = g_strdup (domain);
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (script), obj_props[PROP_TRANSLATION_DOMAIN]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_script_get_translation_domain:
|
||||||
|
* @script: a #ClutterScript
|
||||||
|
*
|
||||||
|
* Retrieves the translation domain set using
|
||||||
|
* clutter_script_set_translation_domain().
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): the translation domain, if any is set,
|
||||||
|
* or %NULL
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
clutter_script_get_translation_domain (ClutterScript *script)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), NULL);
|
||||||
|
|
||||||
|
return script->priv->translation_domain;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _clutter_script_generate_fake_id:
|
* _clutter_script_generate_fake_id:
|
||||||
* @script: a #ClutterScript
|
* @script: a #ClutterScript
|
||||||
|
@ -188,6 +188,12 @@ gchar * clutter_script_lookup_filename (ClutterScript
|
|||||||
GType clutter_script_get_type_from_name (ClutterScript *script,
|
GType clutter_script_get_type_from_name (ClutterScript *script,
|
||||||
const gchar *type_name);
|
const gchar *type_name);
|
||||||
|
|
||||||
|
CLUTTER_AVAILABLE_IN_1_10
|
||||||
|
void clutter_script_set_translation_domain (ClutterScript *script,
|
||||||
|
const gchar *domain);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_10
|
||||||
|
const gchar * clutter_script_get_translation_domain (ClutterScript *script);
|
||||||
|
|
||||||
const gchar * clutter_get_script_id (GObject *gobject);
|
const gchar * clutter_get_script_id (GObject *gobject);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"My Scene" : {
|
"My Scene" : {
|
||||||
"id" : "main-stage",
|
"id" : "main-stage",
|
||||||
"type" : "ClutterStage",
|
"type" : "ClutterStage",
|
||||||
"title" : "ClutterScript test",
|
"title" : { "translatable" : true, "string" : "ClutterScript test" },
|
||||||
"color" : "white",
|
"color" : "white",
|
||||||
"signals" : [
|
"signals" : [
|
||||||
{ "name" : "key-press-event", "handler" : "clutter_main_quit" },
|
{ "name" : "key-press-event", "handler" : "clutter_main_quit" },
|
||||||
@ -62,7 +62,7 @@
|
|||||||
"type" : "ClutterText",
|
"type" : "ClutterText",
|
||||||
"x" : 50,
|
"x" : 50,
|
||||||
"y" : 200,
|
"y" : 200,
|
||||||
"text" : "Clutter\tScript",
|
"text" : { "translatable" : true, "string" : "Clutter Script" },
|
||||||
"font-name" : "Sans 24px",
|
"font-name" : "Sans 24px",
|
||||||
"color" : "black",
|
"color" : "black",
|
||||||
"line-alignment" : "center",
|
"line-alignment" : "center",
|
||||||
|
Loading…
Reference in New Issue
Block a user