mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-16 15:14:17 +00:00
Multilanguage searching for GtkEmojiChooser
This commit is contained in:
parent
2a0286c19c
commit
985d964a34
Binary file not shown.
@ -22,13 +22,15 @@
|
||||
* language-specific data.raw.json as input
|
||||
*/
|
||||
|
||||
/* The format of the generated data is: a(ausasu).
|
||||
/* The format of the generated data is: a(aussasasu).
|
||||
* Each member of the array has the following fields:
|
||||
* au - sequence of unicode codepoints. If the
|
||||
* sequence contains a 0, it marks the point
|
||||
* where skin tone modifiers should be inserted
|
||||
* s - name, e.g. "man worker"
|
||||
* as - keywords, e.g. "man", "worker"
|
||||
* s - name in english, e.g. "man worker"
|
||||
* s - name in locale
|
||||
* as - keywords in english, e.g. "man", "worker"
|
||||
* as - keywords in locale
|
||||
* u - the group that this item belongs to:
|
||||
* 0: smileys-emotion
|
||||
* 1: people-body
|
||||
@ -77,90 +79,113 @@ main (int argc, char *argv[])
|
||||
{
|
||||
JsonParser *parser;
|
||||
JsonNode *root;
|
||||
JsonParser *parser_en;
|
||||
JsonNode *root_en;
|
||||
JsonObject *ro;
|
||||
JsonArray *array;
|
||||
JsonArray *array_en;
|
||||
JsonNode *node;
|
||||
const char *unicode;
|
||||
JsonObjectIter iter;
|
||||
GError *error = NULL;
|
||||
guint length, i;
|
||||
guint length, length_en, i;
|
||||
GVariantBuilder builder;
|
||||
GVariant *v;
|
||||
GString *s;
|
||||
GHashTable *names;
|
||||
GString *name_key;
|
||||
|
||||
if (argc != 3)
|
||||
if (argc != 4) //0 -> compiled file, 1 -> en/data.raw.json, 2 -> de/data.raw.json, 3 -> de.data
|
||||
{
|
||||
g_print ("Usage: emoji-convert INPUT OUTPUT\n");
|
||||
g_print ("Usage: emoji-convert INPUT1 INPUT2 OUTPUT\nINPUT1 should be raw json data for English\nINPUT2 should be raw json data for the locale\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
parser = json_parser_new ();
|
||||
parser_en = json_parser_new ();
|
||||
|
||||
if (!json_parser_load_from_file (parser, argv[1], &error))
|
||||
if (!json_parser_load_from_file (parser_en, argv[1], &error))
|
||||
{
|
||||
g_error ("%s", error->message);
|
||||
return 1;
|
||||
}
|
||||
if (!json_parser_load_from_file (parser, argv[2], &error))
|
||||
{
|
||||
g_error ("%s", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
root = json_parser_get_root (parser);
|
||||
array = json_node_get_array (root);
|
||||
length = json_array_get_length (array);
|
||||
root_en = json_parser_get_root (parser_en);
|
||||
array_en = json_node_get_array (root_en);
|
||||
length_en = json_array_get_length (array_en);
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ausasu)"));
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(aussasasu)"));
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
JsonObject *obj = json_array_get_object_element (array, i);
|
||||
GVariantBuilder b1;
|
||||
GVariantBuilder b2;
|
||||
guint group;
|
||||
const char *name;
|
||||
char *code;
|
||||
{
|
||||
JsonObject *obj = json_array_get_object_element (array, i);
|
||||
JsonObject *obj_en = json_array_get_object_element (array_en, i);
|
||||
GVariantBuilder b1;
|
||||
GVariantBuilder b2;
|
||||
GVariantBuilder b3;
|
||||
guint group;
|
||||
const char *name;
|
||||
const char *name_en;
|
||||
char *code;
|
||||
if (!json_object_has_member (obj, "group"))
|
||||
continue;
|
||||
if (!json_object_has_member (obj_en, "group"))
|
||||
continue;
|
||||
group = json_object_get_int_member (obj, "group");
|
||||
name = json_object_get_string_member (obj, "label");
|
||||
name_en = json_object_get_string_member (obj_en, "label");
|
||||
if (json_object_has_member (obj, "skins") && json_object_has_member (obj_en, "skins"))
|
||||
{
|
||||
JsonArray *a2 = json_object_get_array_member (obj, "skins");
|
||||
JsonNode *n2 = json_array_get_element (a2, 0);
|
||||
JsonObject *o2 = json_node_get_object (n2);
|
||||
code = g_strdup (json_object_get_string_member (o2, "hexcode"));
|
||||
}
|
||||
else
|
||||
{
|
||||
code = g_strdup (json_object_get_string_member (obj, "hexcode"));
|
||||
}
|
||||
g_variant_builder_init (&b1, G_VARIANT_TYPE ("au"));
|
||||
|
||||
if (!json_object_has_member (obj, "group"))
|
||||
continue;
|
||||
if (!parse_code (&b1, code))
|
||||
return 1;
|
||||
|
||||
group = json_object_get_int_member (obj, "group");
|
||||
name = json_object_get_string_member (obj, "label");
|
||||
|
||||
if (json_object_has_member (obj, "skins"))
|
||||
g_variant_builder_init (&b2, G_VARIANT_TYPE ("as"));
|
||||
if (json_object_has_member (obj_en, "tags"))
|
||||
{
|
||||
JsonArray *tags_en = json_object_get_array_member (obj_en, "tags");
|
||||
for (int j = 0; j < json_array_get_length (tags_en); j++)
|
||||
{
|
||||
JsonArray *a2 = json_object_get_array_member (obj, "skins");
|
||||
JsonNode *n2 = json_array_get_element (a2, 0);
|
||||
JsonObject *o2 = json_node_get_object (n2);
|
||||
code = g_strdup (json_object_get_string_member (o2, "hexcode"));
|
||||
g_variant_builder_add (&b2, "s", json_array_get_string_element (tags_en, j));
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
g_variant_builder_init (&b3, G_VARIANT_TYPE ("as"));
|
||||
if (json_object_has_member (obj, "tags"))
|
||||
{
|
||||
JsonArray *tags = json_object_get_array_member (obj, "tags");
|
||||
for (int j = 0; j < json_array_get_length (tags); j++)
|
||||
{
|
||||
code = g_strdup (json_object_get_string_member (obj, "hexcode"));
|
||||
g_variant_builder_add (&b3, "s", json_array_get_string_element (tags, j));
|
||||
}
|
||||
|
||||
g_variant_builder_init (&b1, G_VARIANT_TYPE ("au"));
|
||||
|
||||
if (!parse_code (&b1, code))
|
||||
return 1;
|
||||
|
||||
g_variant_builder_init (&b2, G_VARIANT_TYPE ("as"));
|
||||
if (json_object_has_member (obj, "tags"))
|
||||
{
|
||||
JsonArray *tags = json_object_get_array_member (obj, "tags");
|
||||
for (int j = 0; j < json_array_get_length (tags); j++)
|
||||
g_variant_builder_add (&b2, "s", json_array_get_string_element (tags, j));
|
||||
}
|
||||
|
||||
g_variant_builder_add (&builder, "(ausasu)", &b1, name, &b2, group);
|
||||
}
|
||||
|
||||
}
|
||||
g_variant_builder_add (&builder, "(aussasasu)", &b1, name_en, name, &b2, &b3, group);
|
||||
}
|
||||
v = g_variant_builder_end (&builder);
|
||||
if (g_str_has_suffix (argv[2], ".json"))
|
||||
if (g_str_has_suffix (argv[3], ".json"))
|
||||
{
|
||||
JsonNode *node;
|
||||
char *out;
|
||||
|
||||
node = json_gvariant_serialize (v);
|
||||
out = json_to_string (node, TRUE);
|
||||
if (!g_file_set_contents (argv[2], out, -1, &error))
|
||||
if (!g_file_set_contents (argv[3], out, -1, &error))
|
||||
{
|
||||
g_error ("%s", error->message);
|
||||
return 1;
|
||||
@ -171,7 +196,7 @@ main (int argc, char *argv[])
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_variant_get_data_as_bytes (v);
|
||||
if (!g_file_set_contents (argv[2], g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), &error))
|
||||
if (!g_file_set_contents (argv[3], g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), &error))
|
||||
{
|
||||
g_error ("%s", error->message);
|
||||
return 1;
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -321,7 +321,7 @@ populate_recent_section (GtkEmojiChooser *chooser)
|
||||
GVariantIter iter;
|
||||
gboolean empty = TRUE;
|
||||
|
||||
variant = g_settings_get_value (chooser->settings, "recent-emoji");
|
||||
variant = g_settings_get_value (chooser->settings, "recently-used-emoji");
|
||||
g_variant_iter_init (&iter, variant);
|
||||
while ((item = g_variant_iter_next_value (&iter)))
|
||||
{
|
||||
@ -354,8 +354,8 @@ add_recent_item (GtkEmojiChooser *chooser,
|
||||
|
||||
g_variant_ref (item);
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a((ausasu)u)"));
|
||||
g_variant_builder_add (&builder, "(@(ausasu)u)", item, modifier);
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a((aussasasu)u)"));
|
||||
g_variant_builder_add (&builder, "(@(aussasasu)u)", item, modifier);
|
||||
|
||||
children = NULL;
|
||||
for (child = gtk_widget_get_last_child (chooser->recent.box);
|
||||
@ -380,7 +380,7 @@ add_recent_item (GtkEmojiChooser *chooser,
|
||||
continue;
|
||||
}
|
||||
|
||||
g_variant_builder_add (&builder, "(@(ausasu)u)", item2, modifier2);
|
||||
g_variant_builder_add (&builder, "(@(aussasasu)u)", item2, modifier2);
|
||||
}
|
||||
g_list_free (children);
|
||||
|
||||
@ -390,7 +390,7 @@ add_recent_item (GtkEmojiChooser *chooser,
|
||||
gtk_widget_set_visible (chooser->recent.box, TRUE);
|
||||
gtk_widget_set_sensitive (chooser->recent.button, TRUE);
|
||||
|
||||
g_settings_set_value (chooser->settings, "recent-emoji", g_variant_builder_end (&builder));
|
||||
g_settings_set_value (chooser->settings, "recently-used-emoji", g_variant_builder_end (&builder));
|
||||
|
||||
g_variant_unref (item);
|
||||
}
|
||||
@ -720,7 +720,7 @@ populate_emoji_chooser (gpointer data)
|
||||
|
||||
bytes = get_emoji_data ();
|
||||
|
||||
chooser->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(ausasu)"), bytes, TRUE));
|
||||
chooser->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(aussasasu)"), bytes, TRUE));
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
@ -734,7 +734,7 @@ populate_emoji_chooser (gpointer data)
|
||||
{
|
||||
guint group;
|
||||
|
||||
g_variant_get_child (item, 3, "u", &group);
|
||||
g_variant_get_child (item, 5, "u", &group);
|
||||
|
||||
if (group == chooser->people.group)
|
||||
chooser->box = chooser->people.box;
|
||||
@ -866,9 +866,12 @@ filter_func (GtkFlowBoxChild *child,
|
||||
GtkEmojiChooser *chooser;
|
||||
GVariant *emoji_data;
|
||||
const char *text;
|
||||
const char *name_en;
|
||||
const char *name;
|
||||
const char **keywords_en;
|
||||
const char **keywords;
|
||||
char **term_tokens;
|
||||
char **name_tokens_en;
|
||||
char **name_tokens;
|
||||
gboolean res;
|
||||
|
||||
@ -885,16 +888,21 @@ filter_func (GtkFlowBoxChild *child,
|
||||
goto out;
|
||||
|
||||
term_tokens = g_str_tokenize_and_fold (text, "en", NULL);
|
||||
|
||||
g_variant_get_child (emoji_data, 1, "&s", &name);
|
||||
name_tokens = g_str_tokenize_and_fold (name, "en", NULL);
|
||||
g_variant_get_child (emoji_data, 2, "^a&s", &keywords);
|
||||
g_variant_get_child (emoji_data, 1, "&s", &name_en);
|
||||
name_tokens = g_str_tokenize_and_fold (name_en, "en", NULL);
|
||||
g_variant_get_child (emoji_data, 2, "&s", &name);
|
||||
name_tokens_en = g_str_tokenize_and_fold (name, "en", NULL);
|
||||
g_variant_get_child (emoji_data, 3, "^a&s", &keywords_en);
|
||||
g_variant_get_child (emoji_data, 4, "^a&s", &keywords);
|
||||
|
||||
res = match_tokens ((const char **)term_tokens, (const char **)name_tokens) ||
|
||||
match_tokens ((const char **)term_tokens, keywords);
|
||||
match_tokens ((const char **)term_tokens, (const char **)name_tokens_en) ||
|
||||
match_tokens ((const char **)term_tokens, keywords) ||
|
||||
match_tokens ((const char **)term_tokens, keywords_en);
|
||||
|
||||
g_strfreev (term_tokens);
|
||||
g_strfreev (name_tokens);
|
||||
g_strfreev (name_tokens_en);
|
||||
|
||||
out:
|
||||
if (res)
|
||||
|
@ -2,7 +2,7 @@
|
||||
<schemalist>
|
||||
|
||||
<schema id='org.gtk.gtk4.Settings.EmojiChooser' path='/org/gtk/gtk4/settings/emoji-chooser/'>
|
||||
<key name='recent-emoji' type='a((ausasu)u)'>
|
||||
<key name='recently-used-emoji' type='a((aussasasu)u)'>
|
||||
<default>[]</default>
|
||||
<summary>Recently used Emoji</summary>
|
||||
<description>
|
||||
|
Loading…
Reference in New Issue
Block a user