c46a197882
- Enabled to type multiple code points on Emojier - Fixed IBusEmojiDialog_1_0_gir_LIBS for --as-needed LDFLAGS
4400 lines
165 KiB
Diff
4400 lines
165 KiB
Diff
From 7e477d5e0ffe19b6c52558c5b37fdd9cb82c097a Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 9 Mar 2017 11:31:21 +0900
|
|
Subject: [PATCH] tools: Fix `ibus emoji` SEGV when language is changed.
|
|
|
|
BUG=rhbz#1430290
|
|
|
|
Review URL: https://codereview.appspot.com/317410043
|
|
---
|
|
tools/main.vala | 3 +++
|
|
1 file changed, 3 insertions(+)
|
|
|
|
diff --git a/tools/main.vala b/tools/main.vala
|
|
index 73c6f57..fd9fd0e 100644
|
|
--- a/tools/main.vala
|
|
+++ b/tools/main.vala
|
|
@@ -353,6 +353,9 @@ int emoji_dialog(string[] argv) {
|
|
} else {
|
|
GLib.MainLoop loop = new GLib.MainLoop();
|
|
emojier.loaded_emoji_dict.connect(() => {
|
|
+ // The signal is called when the language is changed.
|
|
+ if (emojier.is_running())
|
|
+ return;
|
|
run_dialog(emojier);
|
|
loop.quit();
|
|
});
|
|
--
|
|
2.7.4
|
|
|
|
From 9dbea347050ae2ad79d1b53f2ad62a7a2cafadc6 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 9 Mar 2017 12:45:20 +0900
|
|
Subject: [PATCH] ui/gtk3: Get emoji colors from the theme
|
|
|
|
Get selected and normal text color from the theme.
|
|
Implement to activate an emoji with mouse motion.
|
|
Create back button on emoji language chooser dialog.
|
|
Set row_homogeneous on emoji table.
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/319470043
|
|
---
|
|
ui/gtk3/Makefile.am | 3 +
|
|
ui/gtk3/candidatearea.vala | 186 +++++++++++++++++++++++++------------------
|
|
ui/gtk3/emojier.vala | 192 ++++++++++++++++++++++++++++++++-------------
|
|
3 files changed, 251 insertions(+), 130 deletions(-)
|
|
|
|
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
|
|
index d5ddc42..4e7fd1b 100644
|
|
--- a/ui/gtk3/Makefile.am
|
|
+++ b/ui/gtk3/Makefile.am
|
|
@@ -172,8 +172,11 @@ libibus_emoji_dialog_1_0_la_LDFLAGS = \
|
|
-version-info @LT_VERSION_INFO@ \
|
|
$(NULL)
|
|
libibus_emoji_dialog_1_0_la_SOURCES = \
|
|
+ candidatearea.c \
|
|
emojier.c \
|
|
iconwidget.c \
|
|
+ pango.c \
|
|
+ separator.c \
|
|
$(NULL)
|
|
|
|
-include $(INTROSPECTION_MAKEFILE)
|
|
diff --git a/ui/gtk3/candidatearea.vala b/ui/gtk3/candidatearea.vala
|
|
index a095e76..e162a96 100644
|
|
--- a/ui/gtk3/candidatearea.vala
|
|
+++ b/ui/gtk3/candidatearea.vala
|
|
@@ -21,6 +21,108 @@
|
|
* USA
|
|
*/
|
|
|
|
+class ThemedRGBA {
|
|
+ public Gdk.RGBA *normal_fg { get; set; }
|
|
+ public Gdk.RGBA *normal_bg { get; set; }
|
|
+ public Gdk.RGBA *selected_fg { get; set; }
|
|
+ public Gdk.RGBA *selected_bg { get; set; }
|
|
+
|
|
+ private Gtk.StyleContext m_style_context;
|
|
+
|
|
+ public ThemedRGBA(Gtk.Widget widget) {
|
|
+ this.normal_fg = null;
|
|
+ this.normal_bg = null;
|
|
+ this.selected_fg = null;
|
|
+ this.selected_bg = null;
|
|
+
|
|
+ /* Use the color of Gtk.TextView instead of Gtk.Label
|
|
+ * because the selected label "color" is not configured
|
|
+ * in "Adwaita" theme and the selected label "background-color"
|
|
+ * is not configured in "Maia" theme.
|
|
+ * https://github.com/ibus/ibus/issues/1871
|
|
+ */
|
|
+ Gtk.WidgetPath widget_path = new Gtk.WidgetPath();
|
|
+ widget_path.append_type(typeof(Gtk.TextView));
|
|
+ m_style_context = new Gtk.StyleContext();
|
|
+ m_style_context.set_path(widget_path);
|
|
+ m_style_context.add_class(Gtk.STYLE_CLASS_VIEW);
|
|
+
|
|
+ /* "-gtk-secondary-caret-color" value is different
|
|
+ * if the parent widget is set in "Menta" theme.
|
|
+ */
|
|
+ m_style_context.set_parent(widget.get_style_context());
|
|
+
|
|
+ get_rgba();
|
|
+
|
|
+ m_style_context.changed.connect(() => { get_rgba(); });
|
|
+ }
|
|
+
|
|
+ ~ThemedRGBA() {
|
|
+ reset_rgba();
|
|
+ }
|
|
+
|
|
+ private void reset_rgba() {
|
|
+ if (this.normal_fg != null) {
|
|
+ this.normal_fg.free();
|
|
+ this.normal_fg = null;
|
|
+ }
|
|
+ if (this.normal_bg != null) {
|
|
+ this.normal_bg.free();
|
|
+ this.normal_bg = null;
|
|
+ }
|
|
+ if (this.selected_fg != null) {
|
|
+ this.selected_fg.free();
|
|
+ this.selected_fg = null;
|
|
+ }
|
|
+ if (this.selected_bg != null) {
|
|
+ this.selected_bg.free();
|
|
+ this.selected_bg = null;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void get_rgba() {
|
|
+ reset_rgba();
|
|
+ Gdk.RGBA *normal_fg = null;
|
|
+ Gdk.RGBA *normal_bg = null;
|
|
+ Gdk.RGBA *selected_fg = null;
|
|
+ Gdk.RGBA *selected_bg = null;
|
|
+ m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
+ "color",
|
|
+ out normal_fg);
|
|
+ m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
+ "color",
|
|
+ out selected_fg);
|
|
+
|
|
+ string bg_prop = "background-color";
|
|
+ m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
+ bg_prop,
|
|
+ out normal_bg);
|
|
+ m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
+ bg_prop,
|
|
+ out selected_bg);
|
|
+ if (normal_bg.red == selected_bg.red &&
|
|
+ normal_bg.green == selected_bg.green &&
|
|
+ normal_bg.blue == selected_bg.blue &&
|
|
+ normal_bg.alpha == selected_bg.alpha) {
|
|
+ normal_bg.free();
|
|
+ normal_bg = null;
|
|
+ normal_bg.free();
|
|
+ normal_bg = null;
|
|
+ bg_prop = "-gtk-secondary-caret-color";
|
|
+ m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
+ bg_prop,
|
|
+ out normal_bg);
|
|
+ m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
+ bg_prop,
|
|
+ out selected_bg);
|
|
+ }
|
|
+ this.normal_fg = normal_fg;
|
|
+ this.normal_bg = normal_bg;
|
|
+ this.selected_fg = selected_fg;
|
|
+ this.selected_bg = selected_bg;
|
|
+ }
|
|
+}
|
|
+
|
|
class CandidateArea : Gtk.Box {
|
|
private bool m_vertical;
|
|
private Gtk.Label[] m_labels;
|
|
@@ -30,9 +132,7 @@ class CandidateArea : Gtk.Box {
|
|
private IBus.Text[] m_ibus_candidates;
|
|
private uint m_focus_candidate;
|
|
private bool m_show_cursor;
|
|
- Gtk.StyleContext m_style_context;
|
|
- private Gdk.RGBA *m_selected_fg_color = null;
|
|
- private Gdk.RGBA *m_selected_bg_color = null;
|
|
+ private ThemedRGBA m_rgba;
|
|
|
|
private const string LABELS[] = {
|
|
"1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.",
|
|
@@ -58,38 +158,7 @@ class CandidateArea : Gtk.Box {
|
|
public CandidateArea(bool vertical) {
|
|
GLib.Object();
|
|
set_vertical(vertical, true);
|
|
-
|
|
- /* Use the color of Gtk.TextView instead of Gtk.Label
|
|
- * because the selected label "color" is not configured
|
|
- * in "Adwaita" theme and the selected label "background-color"
|
|
- * is not configured in "Maia" theme.
|
|
- * https://github.com/ibus/ibus/issues/1871
|
|
- */
|
|
- Gtk.WidgetPath widget_path = new Gtk.WidgetPath();
|
|
- widget_path.append_type(typeof(Gtk.TextView));
|
|
- m_style_context = new Gtk.StyleContext();
|
|
- m_style_context.set_path(widget_path);
|
|
- m_style_context.add_class(Gtk.STYLE_CLASS_VIEW);
|
|
-
|
|
- /* "-gtk-secondary-caret-color" value is different
|
|
- * if the parent widget is set in "Menta" theme.
|
|
- */
|
|
- m_style_context.set_parent(get_style_context());
|
|
-
|
|
- get_selected_color();
|
|
-
|
|
- m_style_context.changed.connect(() => { get_selected_color(); });
|
|
- }
|
|
-
|
|
- ~CandidateArea() {
|
|
- if (m_selected_bg_color != null) {
|
|
- m_selected_bg_color.free();
|
|
- m_selected_bg_color = null;
|
|
- }
|
|
- if (m_selected_bg_color != null) {
|
|
- m_selected_bg_color.free();
|
|
- m_selected_bg_color = null;
|
|
- }
|
|
+ m_rgba = new ThemedRGBA(this);
|
|
}
|
|
|
|
public bool candidate_scrolled(Gdk.EventScroll event) {
|
|
@@ -150,17 +219,17 @@ class CandidateArea : Gtk.Box {
|
|
Pango.AttrList attrs = get_pango_attr_list_from_ibus_text(candidates[i]);
|
|
if (i == focus_candidate && show_cursor) {
|
|
Pango.Attribute pango_attr = Pango.attr_foreground_new(
|
|
- (uint16)(m_selected_fg_color.red * uint16.MAX),
|
|
- (uint16)(m_selected_fg_color.green * uint16.MAX),
|
|
- (uint16)(m_selected_fg_color.blue * uint16.MAX));
|
|
+ (uint16)(m_rgba.selected_fg.red * uint16.MAX),
|
|
+ (uint16)(m_rgba.selected_fg.green * uint16.MAX),
|
|
+ (uint16)(m_rgba.selected_fg.blue * uint16.MAX));
|
|
pango_attr.start_index = 0;
|
|
pango_attr.end_index = candidates[i].get_text().length;
|
|
attrs.insert((owned)pango_attr);
|
|
|
|
pango_attr = Pango.attr_background_new(
|
|
- (uint16)(m_selected_bg_color.red * uint16.MAX),
|
|
- (uint16)(m_selected_bg_color.green * uint16.MAX),
|
|
- (uint16)(m_selected_bg_color.blue * uint16.MAX));
|
|
+ (uint16)(m_rgba.selected_bg.red * uint16.MAX),
|
|
+ (uint16)(m_rgba.selected_bg.green * uint16.MAX),
|
|
+ (uint16)(m_rgba.selected_bg.blue * uint16.MAX));
|
|
pango_attr.start_index = 0;
|
|
pango_attr.end_index = candidates[i].get_text().length;
|
|
attrs.insert((owned)pango_attr);
|
|
@@ -181,41 +250,6 @@ class CandidateArea : Gtk.Box {
|
|
}
|
|
}
|
|
|
|
- private void get_selected_color() {
|
|
- if (m_selected_fg_color != null) {
|
|
- m_selected_fg_color.free();
|
|
- m_selected_fg_color = null;
|
|
- }
|
|
- m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
- "color",
|
|
- out m_selected_fg_color);
|
|
-
|
|
- string bg_prop = "background-color";
|
|
- Gdk.RGBA *normal_color = null;
|
|
- if (m_selected_bg_color != null) {
|
|
- m_selected_bg_color.free();
|
|
- m_selected_bg_color = null;
|
|
- }
|
|
- m_style_context.get(Gtk.StateFlags.NORMAL,
|
|
- bg_prop,
|
|
- out normal_color);
|
|
- m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
- bg_prop,
|
|
- out m_selected_bg_color);
|
|
- if (normal_color.red == m_selected_bg_color.red &&
|
|
- normal_color.green == m_selected_bg_color.green &&
|
|
- normal_color.blue == m_selected_bg_color.blue &&
|
|
- normal_color.alpha == m_selected_bg_color.alpha) {
|
|
- m_selected_bg_color.free();
|
|
- m_selected_bg_color = null;
|
|
- bg_prop = "-gtk-secondary-caret-color";
|
|
- m_style_context.get(Gtk.StateFlags.SELECTED,
|
|
- bg_prop,
|
|
- out m_selected_bg_color);
|
|
- }
|
|
- normal_color.free();
|
|
- }
|
|
-
|
|
private void recreate_ui() {
|
|
foreach (Gtk.Widget w in get_children()) {
|
|
w.destroy();
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 5496c4e..bc1eff4 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -72,12 +72,31 @@ class IBusEmojier : Gtk.Window {
|
|
private class EGrid : Gtk.Grid {
|
|
public EGrid() {
|
|
GLib.Object(
|
|
+ row_homogeneous : false,
|
|
vexpand : true,
|
|
halign : Gtk.Align.FILL,
|
|
valign : Gtk.Align.FILL
|
|
);
|
|
}
|
|
}
|
|
+ private class EWhiteLabel : Gtk.Label {
|
|
+ public EWhiteLabel(string text) {
|
|
+ GLib.Object(
|
|
+ name : "IBusEmojierWhiteLabel"
|
|
+ );
|
|
+ if (text != "")
|
|
+ set_label(text);
|
|
+ }
|
|
+ }
|
|
+ private class ESelectedLabel : Gtk.Label {
|
|
+ public ESelectedLabel(string text) {
|
|
+ GLib.Object(
|
|
+ name : "IBusEmojierSelectedLabel"
|
|
+ );
|
|
+ if (text != "")
|
|
+ set_label(text);
|
|
+ }
|
|
+ }
|
|
private class EPaddedLabel : Gtk.Box {
|
|
public EPaddedLabel(string text,
|
|
Gtk.Align align,
|
|
@@ -161,6 +180,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
private const uint EMOJI_GRID_PAGE = 10;
|
|
+ private ThemedRGBA m_rgba;
|
|
private Gtk.Box m_vbox;
|
|
private ETitleLabel m_title;
|
|
private EEntry m_entry;
|
|
@@ -174,7 +194,8 @@ class IBusEmojier : Gtk.Window {
|
|
private GLib.MainLoop? m_loop;
|
|
private string? m_result;
|
|
private GLib.SList<string> m_lang_list;
|
|
- private string m_current_lang = "en";
|
|
+ private string m_current_lang_id = "en";
|
|
+ private string m_current_language = "English";
|
|
private string? m_unicode_point = null;
|
|
private bool m_candidate_panel_is_visible;
|
|
private GLib.HashTable<string, GLib.SList>?
|
|
@@ -189,11 +210,8 @@ class IBusEmojier : Gtk.Window {
|
|
private Gtk.Label[] m_candidates;
|
|
private string m_emoji_font = "Monospace 16";
|
|
private string[] m_favorites = {};
|
|
- // TODO: Get the selected color from CandidateArea
|
|
- private Gdk.RGBA m_selected_fg_color = Gdk.RGBA(){
|
|
- red = 1.0, green = 1.0, blue = 1.0, alpha = 1.0 };
|
|
- private Gdk.RGBA m_selected_bg_color = Gdk.RGBA(){
|
|
- red = 0.300, green = 0.565, blue = 0.851, alpha = 1.0 };
|
|
+ private bool m_enter_notify_enable = true;
|
|
+ private uint m_entry_notify_show_id;
|
|
|
|
public signal void candidate_clicked(uint index, uint button, uint state);
|
|
public signal void loaded_emoji_dict();
|
|
@@ -220,7 +238,33 @@ class IBusEmojier : Gtk.Window {
|
|
warning("Could not open display.");
|
|
return;
|
|
}
|
|
- string data = "grid { background-color: #ffffff; }";
|
|
+ m_rgba = new ThemedRGBA(this);
|
|
+ uint bg_red = (uint)(m_rgba.normal_bg.red * 255);
|
|
+ uint bg_green = (uint)(m_rgba.normal_bg.green * 255);
|
|
+ uint bg_blue = (uint)(m_rgba.normal_bg.blue * 255);
|
|
+ double bg_alpha = m_rgba.normal_bg.alpha;
|
|
+ string data =
|
|
+ "#IBusEmojierWhiteLabel { background-color: " +
|
|
+ "rgba(%u, %u, %u, %lf); ".printf(
|
|
+ bg_red, bg_green, bg_blue, bg_alpha) +
|
|
+ "border-width: 4px; border-radius: 3px; } ";
|
|
+
|
|
+ uint fg_red = (uint)(m_rgba.selected_fg.red * 255);
|
|
+ uint fg_green = (uint)(m_rgba.selected_fg.green * 255);
|
|
+ uint fg_blue = (uint)(m_rgba.selected_fg.blue * 255);
|
|
+ double fg_alpha = m_rgba.selected_fg.alpha;
|
|
+ bg_red = (uint)(m_rgba.selected_bg.red * 255);
|
|
+ bg_green = (uint)(m_rgba.selected_bg.green * 255);
|
|
+ bg_blue = (uint)(m_rgba.selected_bg.blue * 255);
|
|
+ bg_alpha = m_rgba.selected_bg.alpha;
|
|
+ data += "#IBusEmojierSelectedLabel { color: " +
|
|
+ "rgba(%u, %u, %u, %lf); ".printf(
|
|
+ fg_red, fg_green, fg_blue, fg_alpha) +
|
|
+ "background-color: " +
|
|
+ "rgba(%u, %u, %u, %lf); ".printf(
|
|
+ bg_red, bg_green, bg_blue, bg_alpha) +
|
|
+ "border-width: 4px; border-radius: 3px; }";
|
|
+
|
|
Gtk.CssProvider css_provider = new Gtk.CssProvider();
|
|
try {
|
|
css_provider.load_from_data(data, -1);
|
|
@@ -317,6 +361,8 @@ class IBusEmojier : Gtk.Window {
|
|
lang_list.sort((a, b) => {
|
|
string a_lang = IBus.get_language_name(a);
|
|
string b_lang = IBus.get_language_name(b);
|
|
+ a_lang = "%s (%s)".printf(a_lang, a);
|
|
+ b_lang = "%s (%s)".printf(b_lang, b);
|
|
return GLib.strcmp(a_lang, b_lang);
|
|
});
|
|
return lang_list;
|
|
@@ -325,8 +371,8 @@ class IBusEmojier : Gtk.Window {
|
|
private void reload_emoji_dict() {
|
|
init_emoji_dict();
|
|
make_emoji_dict("en");
|
|
- if (m_current_lang != "en")
|
|
- make_emoji_dict(m_current_lang);
|
|
+ if (m_current_lang_id != "en")
|
|
+ make_emoji_dict(m_current_lang_id);
|
|
loaded_emoji_dict();
|
|
}
|
|
|
|
@@ -458,22 +504,50 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+ private void activated_language(EBoxRow row) {
|
|
+ m_category_active_index = 0;
|
|
+ if (m_current_lang_id != row.id) {
|
|
+ m_current_lang_id = row.id;
|
|
+ m_current_language = row.text;
|
|
+ reload_emoji_dict();
|
|
+ }
|
|
+ m_current_category_type = CategoryType.EMOJI;
|
|
+ show_category_list();
|
|
+ }
|
|
+
|
|
private void show_category_list() {
|
|
remove_all_children();
|
|
m_scrolled_window = new EScrolledWindow();
|
|
set_fixed_size();
|
|
- string language = IBus.get_language_name(m_current_lang);
|
|
- EPaddedLabel label = new EPaddedLabel(language, Gtk.Align.CENTER);
|
|
+ EPaddedLabel label;
|
|
+ if (m_current_category_type == CategoryType.EMOJI) {
|
|
+ label = new EPaddedLabel(m_current_language, Gtk.Align.CENTER);
|
|
+ } else if (m_current_category_type == CategoryType.LANG) {
|
|
+ label = new EPaddedLabel(m_current_language,
|
|
+ Gtk.Align.CENTER,
|
|
+ TravelDirection.BACKWARD);
|
|
+ } else {
|
|
+ label = new EPaddedLabel("", Gtk.Align.CENTER);
|
|
+ }
|
|
Gtk.Button button = new Gtk.Button();
|
|
button.add(label);
|
|
m_vbox.add(button);
|
|
button.show_all();
|
|
- button.button_press_event.connect((e) => {
|
|
- m_category_active_index = 0;
|
|
- m_current_category_type = CategoryType.LANG;
|
|
- show_category_list();
|
|
- return true;
|
|
- });
|
|
+ if (m_current_category_type == CategoryType.EMOJI) {
|
|
+ button.button_press_event.connect((e) => {
|
|
+ m_category_active_index = 0;
|
|
+ m_current_category_type = CategoryType.LANG;
|
|
+ show_category_list();
|
|
+ return true;
|
|
+ });
|
|
+ } else if (m_current_category_type == CategoryType.LANG) {
|
|
+ button.button_press_event.connect((e) => {
|
|
+ m_category_active_index = 0;
|
|
+ m_current_category_type = CategoryType.EMOJI;
|
|
+ show_category_list();
|
|
+ return true;
|
|
+ });
|
|
+ }
|
|
|
|
m_vbox.add(m_scrolled_window);
|
|
Gtk.Viewport viewport = new Gtk.Viewport(null, null);
|
|
@@ -523,21 +597,19 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
} else if (m_current_category_type == CategoryType.LANG) {
|
|
m_list_box.row_activated.connect((box, gtkrow) => {
|
|
- m_category_active_index = 0;
|
|
- EBoxRow row = gtkrow as EBoxRow;
|
|
- if (m_current_lang != row.id) {
|
|
- m_current_lang = row.id;
|
|
- reload_emoji_dict();
|
|
- }
|
|
- m_current_category_type = CategoryType.EMOJI;
|
|
- show_category_list();
|
|
+ activated_language(gtkrow as EBoxRow);
|
|
});
|
|
uint n = 1;
|
|
+ string prev_language = null;
|
|
foreach (unowned string id in m_lang_list) {
|
|
- string selected_language = IBus.get_language_name(id);
|
|
- EBoxRow row = new EBoxRow("", id);
|
|
+ string language = IBus.get_language_name(id);
|
|
+ if (prev_language == language)
|
|
+ language = "%s (%s)".printf(language, id);
|
|
+ else
|
|
+ prev_language = language;
|
|
+ EBoxRow row = new EBoxRow(language, id);
|
|
EPaddedLabel widget =
|
|
- new EPaddedLabel(selected_language, Gtk.Align.CENTER);
|
|
+ new EPaddedLabel(language, Gtk.Align.CENTER);
|
|
row.add(widget);
|
|
m_list_box.add(row);
|
|
if (n++ == m_category_active_index)
|
|
@@ -573,27 +645,6 @@ class IBusEmojier : Gtk.Window {
|
|
show_candidate_panel();
|
|
}
|
|
|
|
- private void label_set_active_color(Gtk.Label label) {
|
|
- unowned string text = label.get_text();
|
|
- Pango.AttrList attrs = new Pango.AttrList();
|
|
- Pango.Attribute pango_attr = Pango.attr_foreground_new(
|
|
- (uint16)(m_selected_fg_color.red * uint16.MAX),
|
|
- (uint16)(m_selected_fg_color.green * uint16.MAX),
|
|
- (uint16)(m_selected_fg_color.blue * uint16.MAX));
|
|
- pango_attr.start_index = 0;
|
|
- pango_attr.end_index = text.char_count();
|
|
- attrs.insert((owned)pango_attr);
|
|
-
|
|
- pango_attr = Pango.attr_background_new(
|
|
- (uint16)(m_selected_bg_color.red * uint16.MAX),
|
|
- (uint16)(m_selected_bg_color.green * uint16.MAX),
|
|
- (uint16)(m_selected_bg_color.blue * uint16.MAX));
|
|
- pango_attr.start_index = 0;
|
|
- pango_attr.end_index = text.char_count();
|
|
- attrs.insert((owned)pango_attr);
|
|
- label.set_attributes(attrs);
|
|
- }
|
|
-
|
|
private void show_arrow_buttons() {
|
|
Gtk.Button next_button = new Gtk.Button();
|
|
next_button.clicked.connect(() => {
|
|
@@ -709,10 +760,17 @@ class IBusEmojier : Gtk.Window {
|
|
});
|
|
}
|
|
EGrid grid = new EGrid();
|
|
+ grid.set_row_spacing(5);
|
|
+ grid.set_column_spacing(5);
|
|
+ grid.set_border_width(2);
|
|
int n = 0;
|
|
for (uint i = page_start_pos; i < page_end_pos; i++) {
|
|
IBus.Text candidate = m_lookup_table.get_candidate(i);
|
|
- Gtk.Label label = new Gtk.Label(candidate.text);
|
|
+ Gtk.Label label;
|
|
+ if (i == cursor)
|
|
+ label = new ESelectedLabel(candidate.text) as Gtk.Label;
|
|
+ else
|
|
+ label = new EWhiteLabel(candidate.text) as Gtk.Label;
|
|
string emoji_font = m_emoji_font;
|
|
if (candidate.text.char_count() > 2) {
|
|
Pango.FontDescription font_desc =
|
|
@@ -726,9 +784,6 @@ class IBusEmojier : Gtk.Window {
|
|
label.set_markup(markup);
|
|
label.set_halign(Gtk.Align.FILL);
|
|
label.set_valign(Gtk.Align.FILL);
|
|
- if (i == cursor) {
|
|
- label_set_active_color(label);
|
|
- }
|
|
Gtk.EventBox candidate_ebox = new Gtk.EventBox();
|
|
candidate_ebox.add(label);
|
|
// Make a copy of i to workaround a bug in vala.
|
|
@@ -738,6 +793,23 @@ class IBusEmojier : Gtk.Window {
|
|
candidate_clicked(index, e.button, e.state);
|
|
return true;
|
|
});
|
|
+ // m_enter_notify_enable is added because
|
|
+ // enter_notify_event conflicts with keyboard operations.
|
|
+ if (m_enter_notify_enable) {
|
|
+ candidate_ebox.enter_notify_event.connect((e) => {
|
|
+ m_lookup_table.set_cursor_pos(index);
|
|
+ if (m_entry_notify_show_id > 0) {
|
|
+ GLib.Source.remove(m_entry_notify_show_id);
|
|
+ }
|
|
+ // If timeout is not added, memory leak happens and
|
|
+ // button_press_event signal does not work above.
|
|
+ m_entry_notify_show_id = GLib.Timeout.add(100, () => {
|
|
+ show_candidate_panel();
|
|
+ return false;
|
|
+ });
|
|
+ return true;
|
|
+ });
|
|
+ }
|
|
grid.attach(candidate_ebox,
|
|
n % (int)EMOJI_GRID_PAGE, n / (int)EMOJI_GRID_PAGE,
|
|
1, 1);
|
|
@@ -797,6 +869,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
private void hide_candidate_panel() {
|
|
+ m_enter_notify_enable = true;
|
|
m_candidate_panel_is_visible = false;
|
|
if (m_loop.is_running())
|
|
show_category_list();
|
|
@@ -841,6 +914,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
private void candidate_panel_cursor_down() {
|
|
+ m_enter_notify_enable = false;
|
|
uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
uint cursor = m_lookup_table.get_cursor_pos();
|
|
if ((cursor + EMOJI_GRID_PAGE) < ncandidates) {
|
|
@@ -854,6 +928,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
private void candidate_panel_cursor_up() {
|
|
+ m_enter_notify_enable = false;
|
|
int ncandidates = (int)m_lookup_table.get_number_of_candidates();
|
|
int cursor = (int)m_lookup_table.get_cursor_pos();
|
|
int highest_pos =
|
|
@@ -891,6 +966,7 @@ class IBusEmojier : Gtk.Window {
|
|
m_input_context_path = input_context_path;
|
|
m_candidate_panel_is_visible = false;
|
|
m_result = null;
|
|
+ m_enter_notify_enable = true;
|
|
|
|
/* Let gtk recalculate the window size. */
|
|
resize(1, 1);
|
|
@@ -1011,7 +1087,10 @@ class IBusEmojier : Gtk.Window {
|
|
} else if (m_category_active_index > 0) {
|
|
Gtk.ListBoxRow gtkrow = m_list_box.get_selected_row();
|
|
EBoxRow row = gtkrow as EBoxRow;
|
|
- show_emoji_for_category(row);
|
|
+ if (m_current_category_type == CategoryType.EMOJI)
|
|
+ show_emoji_for_category(row);
|
|
+ else if (m_current_category_type == CategoryType.LANG)
|
|
+ activated_language(row);
|
|
}
|
|
return true;
|
|
case Gdk.Key.BackSpace:
|
|
@@ -1026,6 +1105,7 @@ class IBusEmojier : Gtk.Window {
|
|
break;
|
|
}
|
|
if (m_candidate_panel_is_visible) {
|
|
+ m_enter_notify_enable = false;
|
|
m_lookup_table.cursor_down();
|
|
show_candidate_panel();
|
|
}
|
|
@@ -1035,6 +1115,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
case Gdk.Key.Right:
|
|
if (m_candidate_panel_is_visible) {
|
|
+ m_enter_notify_enable = false;
|
|
m_lookup_table.cursor_down();
|
|
show_candidate_panel();
|
|
return true;
|
|
@@ -1042,6 +1123,7 @@ class IBusEmojier : Gtk.Window {
|
|
break;
|
|
case Gdk.Key.Left:
|
|
if (m_candidate_panel_is_visible) {
|
|
+ m_enter_notify_enable = false;
|
|
m_lookup_table.cursor_up();
|
|
show_candidate_panel();
|
|
return true;
|
|
@@ -1061,6 +1143,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
case Gdk.Key.Page_Down:
|
|
if (m_candidate_panel_is_visible) {
|
|
+ m_enter_notify_enable = false;
|
|
m_lookup_table.page_down();
|
|
show_candidate_panel();
|
|
return true;
|
|
@@ -1068,6 +1151,7 @@ class IBusEmojier : Gtk.Window {
|
|
break;
|
|
case Gdk.Key.Page_Up:
|
|
if (m_candidate_panel_is_visible) {
|
|
+ m_enter_notify_enable = false;
|
|
m_lookup_table.page_up();
|
|
show_candidate_panel();
|
|
return true;
|
|
--
|
|
2.7.4
|
|
|
|
From 31ed31e5303c3946f53b035a63d76f5c1e3cd84a Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 13 Mar 2017 11:43:09 +0900
|
|
Subject: [PATCH] src: Fix ibus_emoji_dict_load()
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/320350043
|
|
---
|
|
configure.ac | 3 ++-
|
|
src/emoji-parser.c | 6 ++++--
|
|
src/ibusemoji.c | 6 +++---
|
|
3 files changed, 9 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 027c027..369485c 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -620,7 +620,8 @@ fi
|
|
|
|
AC_ARG_WITH(emoji-json-file,
|
|
AS_HELP_STRING([--with-emoji-json-file[=DIR/emoji.json]],
|
|
- [Set emoji.json. (default: "/usr/lib/node_modules/emojione/emoji.json")]),
|
|
+ [Set emoji.json. (default: "/usr/lib/node_modules/emojione/emoji.json")
|
|
+ You can get emoji.json with "npm install -g emojione".]),
|
|
EMOJI_JSON_FILE=$with_emoji_json_file,
|
|
EMOJI_JSON_FILE="/usr/lib/node_modules/emojione/emoji.json"
|
|
)
|
|
diff --git a/src/emoji-parser.c b/src/emoji-parser.c
|
|
index c5af42c..5965309 100644
|
|
--- a/src/emoji-parser.c
|
|
+++ b/src/emoji-parser.c
|
|
@@ -1,7 +1,7 @@
|
|
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
- * Copyright (C) 2016 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2016-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2016 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -20,9 +20,11 @@
|
|
* USA
|
|
*/
|
|
|
|
-/* Convert ../data/annotations/en.xml and
|
|
+/* Convert /usr/share/unicode/cldr/common/annotations/*.xml and
|
|
* /usr/lib/node_modules/emojione/emoji.json
|
|
* to the dictionary file which look up the Emoji from the annotation.
|
|
+ * Get *.xml from https://github.com/fujiwarat/cldr-emoji-annotation
|
|
+ * or http://www.unicode.org/repos/cldr/trunk/common/annotations .
|
|
* Get emoji.json with 'npm install -g emojione'.
|
|
* en.xml is used for the Unicode annotations and emoji.json is used
|
|
* for the aliases_ascii, e.g. ":)", and category, e.g. "people".
|
|
diff --git a/src/ibusemoji.c b/src/ibusemoji.c
|
|
index 8d88704..996d136 100644
|
|
--- a/src/ibusemoji.c
|
|
+++ b/src/ibusemoji.c
|
|
@@ -431,10 +431,10 @@ ibus_emoji_dict_load (const gchar *path)
|
|
GHashTable *dict = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
g_free,
|
|
- free_dict_words);
|
|
+ g_object_unref);
|
|
|
|
for (l = list; l; l = l->next) {
|
|
- IBusEmojiData *data = list->data;
|
|
+ IBusEmojiData *data = l->data;
|
|
if (!IBUS_IS_EMOJI_DATA (data)) {
|
|
g_warning ("Your dict format is no longer supported.\n"
|
|
"Need to create the dictionaries again.");
|
|
@@ -442,7 +442,7 @@ ibus_emoji_dict_load (const gchar *path)
|
|
}
|
|
g_hash_table_insert (dict,
|
|
g_strdup (ibus_emoji_data_get_emoji (data)),
|
|
- data);
|
|
+ g_object_ref_sink (data));
|
|
}
|
|
|
|
g_slist_free (list);
|
|
--
|
|
2.9.3
|
|
|
|
From c580845167b54ccab76d8b72bdc797ef8d64d554 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 13 Mar 2017 11:58:06 +0900
|
|
Subject: [PATCH] ui/gtk3: Fix emoji text entry cusor position
|
|
|
|
Focus on emoji text entry by default
|
|
Remove internal text buffer and use Gtk.Entry buffer instead.
|
|
Implement cusor left, right, home, end on emoji annotation preedit.
|
|
|
|
Review URL: https://codereview.appspot.com/313710043
|
|
---
|
|
ui/gtk3/emojier.vala | 104 +++++++++++++++++++++++++++++++++------------------
|
|
1 file changed, 68 insertions(+), 36 deletions(-)
|
|
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index bc1eff4..8cecea8 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -75,7 +75,10 @@ class IBusEmojier : Gtk.Window {
|
|
row_homogeneous : false,
|
|
vexpand : true,
|
|
halign : Gtk.Align.FILL,
|
|
- valign : Gtk.Align.FILL
|
|
+ valign : Gtk.Align.FILL,
|
|
+ row_spacing : 5,
|
|
+ column_spacing : 5,
|
|
+ border_width : 2
|
|
);
|
|
}
|
|
}
|
|
@@ -190,7 +193,6 @@ class IBusEmojier : Gtk.Window {
|
|
private CategoryType m_current_category_type = CategoryType.EMOJI;
|
|
private bool m_is_running = false;
|
|
private string m_input_context_path = "";
|
|
- private GLib.StringBuilder m_buffer_string;
|
|
private GLib.MainLoop? m_loop;
|
|
private string? m_result;
|
|
private GLib.SList<string> m_lang_list;
|
|
@@ -288,11 +290,9 @@ class IBusEmojier : Gtk.Window {
|
|
m_entry.set_placeholder_text(_("Type annotation or choose emoji"));
|
|
m_vbox.add(m_entry);
|
|
m_entry.changed.connect(() => {
|
|
- m_buffer_string.assign(m_entry.get_text());
|
|
- update_cadidate_window();
|
|
+ update_candidate_window();
|
|
});
|
|
m_entry.icon_release.connect((icon_pos, event) => {
|
|
- m_buffer_string.erase();
|
|
hide_candidate_panel();
|
|
});
|
|
|
|
@@ -303,7 +303,6 @@ class IBusEmojier : Gtk.Window {
|
|
Atk.Object obj = m_entry.get_accessible();
|
|
obj.set_role (Atk.Role.STATUSBAR);
|
|
|
|
- m_buffer_string = new StringBuilder();
|
|
grab_focus();
|
|
|
|
// The constructor of IBus.LookupTable does not support more than
|
|
@@ -680,11 +679,16 @@ class IBusEmojier : Gtk.Window {
|
|
buttons_hbox.show_all();
|
|
}
|
|
|
|
- private bool check_unicode_point(bool check_xdigit_only) {
|
|
- m_unicode_point = null;
|
|
+ private bool check_unicode_point(string? annotation=null) {
|
|
+ bool check_xdigit_only = true;
|
|
+ if (annotation == null) {
|
|
+ annotation = m_entry.get_text();
|
|
+ m_unicode_point = null;
|
|
+ check_xdigit_only = false;
|
|
+ }
|
|
GLib.StringBuilder buff = new GLib.StringBuilder();
|
|
- for (int i = 0; i < m_buffer_string.str.char_count(); i++) {
|
|
- unichar ch = m_buffer_string.str.get_char(i);
|
|
+ for (int i = 0; i < annotation.char_count(); i++) {
|
|
+ unichar ch = annotation.get_char(i);
|
|
if (ch == 0)
|
|
return false;
|
|
if (!ch.isxdigit())
|
|
@@ -704,7 +708,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
|
|
- public void update_cadidate_window() {
|
|
+ public void update_candidate_window() {
|
|
string annotation = m_entry.get_text();
|
|
if (annotation.length == 0) {
|
|
hide_candidate_panel();
|
|
@@ -716,7 +720,7 @@ class IBusEmojier : Gtk.Window {
|
|
return;
|
|
}
|
|
// Call check_unicode_point() to get m_unicode_point
|
|
- check_unicode_point(false);
|
|
+ check_unicode_point();
|
|
unowned GLib.SList<string>? emojis =
|
|
m_annotation_to_emojis_dict.lookup(annotation);
|
|
if (emojis == null && m_unicode_point == null) {
|
|
@@ -725,7 +729,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
m_lookup_table.clear();
|
|
// Call check_unicode_point() to update m_lookup_table
|
|
- check_unicode_point(false);
|
|
+ check_unicode_point();
|
|
foreach (unowned string emoji in emojis) {
|
|
IBus.Text text = new IBus.Text.from_string(emoji);
|
|
m_lookup_table.append_candidate(text);
|
|
@@ -760,9 +764,6 @@ class IBusEmojier : Gtk.Window {
|
|
});
|
|
}
|
|
EGrid grid = new EGrid();
|
|
- grid.set_row_spacing(5);
|
|
- grid.set_column_spacing(5);
|
|
- grid.set_border_width(2);
|
|
int n = 0;
|
|
for (uint i = page_start_pos; i < page_end_pos; i++) {
|
|
IBus.Text candidate = m_lookup_table.get_candidate(i);
|
|
@@ -878,14 +879,11 @@ class IBusEmojier : Gtk.Window {
|
|
private bool if_in_range_of_lookup(uint keyval) {
|
|
if (!m_candidate_panel_is_visible)
|
|
return false;
|
|
- string backup_annotation = m_buffer_string.str.dup();
|
|
+ StringBuilder buffer_string = new StringBuilder(m_entry.get_text());
|
|
unichar ch = IBus.keyval_to_unicode (keyval);
|
|
- m_buffer_string.append_unichar(ch);
|
|
- if (check_unicode_point(true)) {
|
|
- m_buffer_string.assign(backup_annotation);
|
|
+ buffer_string.append_unichar(ch);
|
|
+ if (check_unicode_point(buffer_string.str))
|
|
return false;
|
|
- }
|
|
- m_buffer_string.assign(backup_annotation);
|
|
if (keyval < Gdk.Key.@0 || keyval > Gdk.Key.@9)
|
|
return false;
|
|
if (keyval == Gdk.Key.@0)
|
|
@@ -958,6 +956,18 @@ class IBusEmojier : Gtk.Window {
|
|
show_category_list();
|
|
}
|
|
|
|
+ private void entry_enter_keyval(uint keyval) {
|
|
+ unichar ch = IBus.keyval_to_unicode(keyval);
|
|
+ if (!ch.isgraph())
|
|
+ return;
|
|
+ string str = ch.to_string();
|
|
+
|
|
+ // what gtk_entry_commit_cb() do
|
|
+ int pos = m_entry.get_position();
|
|
+ m_entry.insert_text(str, -1, ref pos);
|
|
+ m_entry.set_position(pos);
|
|
+ }
|
|
+
|
|
public string run(Gdk.Event event,
|
|
string input_context_path) {
|
|
assert (m_loop == null);
|
|
@@ -972,7 +982,7 @@ class IBusEmojier : Gtk.Window {
|
|
resize(1, 1);
|
|
|
|
m_entry.set_text("");
|
|
- m_buffer_string.erase();
|
|
+ m_entry.grab_focus();
|
|
|
|
Gdk.Device device = event.get_device();
|
|
if (device == null) {
|
|
@@ -1070,12 +1080,12 @@ class IBusEmojier : Gtk.Window {
|
|
m_current_category_type = CategoryType.EMOJI;
|
|
show_candidate_panel();
|
|
return true;
|
|
- } else if (m_buffer_string.str.length == 0) {
|
|
+ } else if (m_entry.get_text().length == 0) {
|
|
m_loop.quit();
|
|
hide_candidate_panel();
|
|
return true;
|
|
}
|
|
- m_buffer_string.erase();
|
|
+ m_entry.delete_text(0, -1);
|
|
break;
|
|
case Gdk.Key.Return:
|
|
if (m_candidate_panel_is_visible) {
|
|
@@ -1094,14 +1104,14 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
return true;
|
|
case Gdk.Key.BackSpace:
|
|
- if (m_buffer_string.len > 0)
|
|
- m_buffer_string.erase(m_buffer_string.len - 1);
|
|
+ if (m_entry.get_text().len() > 0) {
|
|
+ GLib.Signal.emit_by_name(m_entry, "backspace");
|
|
+ }
|
|
break;
|
|
case Gdk.Key.space:
|
|
case Gdk.Key.KP_Space:
|
|
if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
|
|
- unichar ch = IBus.keyval_to_unicode (keyval);
|
|
- m_buffer_string.append_unichar(ch);
|
|
+ entry_enter_keyval(keyval);
|
|
break;
|
|
}
|
|
if (m_candidate_panel_is_visible) {
|
|
@@ -1120,6 +1130,12 @@ class IBusEmojier : Gtk.Window {
|
|
show_candidate_panel();
|
|
return true;
|
|
}
|
|
+ if (m_entry.get_text().len() > 0) {
|
|
+ GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
+ Gtk.MovementStep.VISUAL_POSITIONS,
|
|
+ 1, false);
|
|
+ return true;
|
|
+ }
|
|
break;
|
|
case Gdk.Key.Left:
|
|
if (m_candidate_panel_is_visible) {
|
|
@@ -1128,6 +1144,12 @@ class IBusEmojier : Gtk.Window {
|
|
show_candidate_panel();
|
|
return true;
|
|
}
|
|
+ if (m_entry.get_text().len() > 0) {
|
|
+ GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
+ Gtk.MovementStep.VISUAL_POSITIONS,
|
|
+ -1, false);
|
|
+ return true;
|
|
+ }
|
|
break;
|
|
case Gdk.Key.Down:
|
|
if (m_candidate_panel_is_visible)
|
|
@@ -1157,17 +1179,27 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
break;
|
|
- default:
|
|
- unichar ch = IBus.keyval_to_unicode(keyval);
|
|
- if (!ch.isgraph())
|
|
+ case Gdk.Key.Home:
|
|
+ if (m_entry.get_text().len() > 0) {
|
|
+ GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
+ Gtk.MovementStep.DISPLAY_LINE_ENDS,
|
|
+ -1, false);
|
|
+ return true;
|
|
+ }
|
|
+ break;
|
|
+ case Gdk.Key.End:
|
|
+ if (m_entry.get_text().len() > 0) {
|
|
+ GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
+ Gtk.MovementStep.DISPLAY_LINE_ENDS,
|
|
+ 1, false);
|
|
return true;
|
|
- m_buffer_string.append_unichar(ch);
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ entry_enter_keyval(keyval);
|
|
break;
|
|
}
|
|
|
|
- string annotation = m_buffer_string.str;
|
|
- m_entry.set_text(annotation);
|
|
-
|
|
return true;
|
|
}
|
|
|
|
--
|
|
2.9.3
|
|
|
|
From fbe3de1789c73a8a175a451b2a6b967f5d3c6514 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 13 Mar 2017 12:08:21 +0900
|
|
Subject: [PATCH] src: Update emoji-parser to treat tts as emoji
|
|
description
|
|
|
|
unicode annotation xml files have a 'tts' attribute and seem
|
|
it is used as the emoji descriptions instead of emoji annotations.
|
|
This can show the translated descriptions.
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/319480043
|
|
---
|
|
src/emoji-parser.c | 26 +++++++++++++++++++-------
|
|
src/ibusemoji.c | 16 +++++++++++++---
|
|
src/ibusemoji.h | 11 +++++++++++
|
|
ui/gtk3/emojier.vala | 17 ++++++++++++++---
|
|
4 files changed, 57 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/src/emoji-parser.c b/src/emoji-parser.c
|
|
index 5965309..8ff04f1 100644
|
|
--- a/src/emoji-parser.c
|
|
+++ b/src/emoji-parser.c
|
|
@@ -43,6 +43,7 @@ struct _EmojiData {
|
|
GSList *annotations;
|
|
gboolean is_annotation;
|
|
gchar *description;
|
|
+ gboolean is_tts;
|
|
gchar *category;
|
|
GSList *list;
|
|
};
|
|
@@ -97,6 +98,8 @@ update_emoji_list (EmojiData *data)
|
|
(GCopyFunc) g_strdup,
|
|
NULL));
|
|
}
|
|
+ if (data->description)
|
|
+ ibus_emoji_data_set_description (emoji, data->description);
|
|
} else {
|
|
IBusEmojiData *emoji =
|
|
ibus_emoji_data_new ("emoji",
|
|
@@ -149,13 +152,12 @@ unicode_annotations_start_element_cb (GMarkupParseContext *context,
|
|
data->emoji = g_strdup (value);
|
|
}
|
|
}
|
|
- else if (g_strcmp0 (attribute, "tts") == 0) {
|
|
- GSList *duplicated = g_slist_find_custom (data->annotations,
|
|
- value,
|
|
- (GCompareFunc) g_strcmp0);
|
|
- if (duplicated == NULL) {
|
|
- data->annotations = g_slist_prepend (data->annotations,
|
|
- g_strdup (value));
|
|
+ /* tts seems 'text to speach' and it would be a description
|
|
+ * instead of annotation.
|
|
+ */
|
|
+ else if (g_strcmp0 (attribute, "type") == 0) {
|
|
+ if (g_strcmp0 (value, "tts") == 0) {
|
|
+ data->is_tts = TRUE;
|
|
}
|
|
}
|
|
}
|
|
@@ -177,6 +179,7 @@ unicode_annotations_end_element_cb (GMarkupParseContext *context,
|
|
|
|
update_emoji_list (data);
|
|
data->is_annotation = FALSE;
|
|
+ data->is_tts = FALSE;
|
|
}
|
|
|
|
void
|
|
@@ -194,6 +197,15 @@ unicode_annotations_text_cb (GMarkupParseContext *context,
|
|
g_assert (data != NULL);
|
|
if (!data->is_annotation)
|
|
return;
|
|
+ if (data->is_tts) {
|
|
+ if (data->description) {
|
|
+ g_warning ("Duplicated 'tts' is found: %s: %s",
|
|
+ data->description, text);
|
|
+ g_clear_pointer (&data->description, g_free);
|
|
+ }
|
|
+ data->description = g_strdup (text);
|
|
+ return;
|
|
+ }
|
|
annotations = g_strsplit (text, " | ", -1);
|
|
for (i = 0; (annotation = annotations[i]) != NULL; i++) {
|
|
GSList *duplicated = g_slist_find_custom (data->annotations,
|
|
diff --git a/src/ibusemoji.c b/src/ibusemoji.c
|
|
index 996d136..c61cd70 100644
|
|
--- a/src/ibusemoji.c
|
|
+++ b/src/ibusemoji.c
|
|
@@ -29,7 +29,7 @@
|
|
#include "ibusinternal.h"
|
|
|
|
#define IBUS_EMOJI_DATA_MAGIC "IBusEmojiData"
|
|
-#define IBUS_EMOJI_DATA_VERSION (1)
|
|
+#define IBUS_EMOJI_DATA_VERSION (2)
|
|
|
|
enum {
|
|
PROP_0 = 0,
|
|
@@ -128,7 +128,7 @@ ibus_emoji_data_class_init (IBusEmojiDataClass *class)
|
|
"emoji description",
|
|
"The emoji description",
|
|
"",
|
|
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
+ G_PARAM_READWRITE));
|
|
|
|
/**
|
|
* IBusEmojiData:category:
|
|
@@ -352,6 +352,16 @@ ibus_emoji_data_get_description (IBusEmojiData *emoji)
|
|
return emoji->priv->description;
|
|
}
|
|
|
|
+void
|
|
+ibus_emoji_data_set_description (IBusEmojiData *emoji,
|
|
+ const gchar *description)
|
|
+{
|
|
+ g_return_if_fail (IBUS_IS_EMOJI_DATA (emoji));
|
|
+
|
|
+ g_free (emoji->priv->description);
|
|
+ emoji->priv->description = g_strdup (description);
|
|
+}
|
|
+
|
|
const gchar *
|
|
ibus_emoji_data_get_category (IBusEmojiData *emoji)
|
|
{
|
|
@@ -541,7 +551,7 @@ ibus_emoji_data_load (const gchar *path)
|
|
goto out_load_cache;
|
|
}
|
|
|
|
- if (version != IBUS_EMOJI_DATA_VERSION) {
|
|
+ if (version > IBUS_EMOJI_DATA_VERSION) {
|
|
g_warning ("cache version is different: %u != %u",
|
|
version, IBUS_EMOJI_DATA_VERSION);
|
|
goto out_load_cache;
|
|
diff --git a/src/ibusemoji.h b/src/ibusemoji.h
|
|
index 3fd09a9..eb24fdd 100644
|
|
--- a/src/ibusemoji.h
|
|
+++ b/src/ibusemoji.h
|
|
@@ -134,6 +134,17 @@ void ibus_emoji_data_set_annotations (IBusEmojiData *emoji,
|
|
const gchar * ibus_emoji_data_get_description (IBusEmojiData *emoji);
|
|
|
|
/**
|
|
+ * ibus_emoji_data_set_description:
|
|
+ * @emoji : An #IBusEmojiData
|
|
+ * @description: An emoji description
|
|
+ *
|
|
+ * Sets the description in #IBusEmojiData.
|
|
+ */
|
|
+void ibus_emoji_data_set_description (IBusEmojiData *emoji,
|
|
+ const gchar *description);
|
|
+
|
|
+
|
|
+/**
|
|
* ibus_emoji_data_get_category:
|
|
* @emoji : An #IBusEmojiData
|
|
*
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 8cecea8..5e126e9 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -370,8 +370,14 @@ class IBusEmojier : Gtk.Window {
|
|
private void reload_emoji_dict() {
|
|
init_emoji_dict();
|
|
make_emoji_dict("en");
|
|
- if (m_current_lang_id != "en")
|
|
+ if (m_current_lang_id != "en") {
|
|
+ var lang_ids = m_current_lang_id.split("_");
|
|
+ if (lang_ids.length > 1) {
|
|
+ string sub_id = lang_ids[0];
|
|
+ make_emoji_dict(sub_id);
|
|
+ }
|
|
make_emoji_dict(m_current_lang_id);
|
|
+ }
|
|
loaded_emoji_dict();
|
|
}
|
|
|
|
@@ -393,8 +399,8 @@ class IBusEmojier : Gtk.Window {
|
|
if (emoji_list == null)
|
|
return;
|
|
foreach (IBus.EmojiData data in emoji_list) {
|
|
- update_annotation_to_emojis_dict(data);
|
|
update_emoji_to_data_dict(data, lang);
|
|
+ update_annotation_to_emojis_dict(data);
|
|
update_category_to_emojis_dict(data, lang);
|
|
}
|
|
GLib.List<unowned string> annotations =
|
|
@@ -434,11 +440,16 @@ class IBusEmojier : Gtk.Window {
|
|
unowned IBus.EmojiData? en_data =
|
|
m_emoji_to_data_dict.lookup(emoji);
|
|
if (en_data == null) {
|
|
- warning("No IBusEmojiData for English: %s".printf(emoji));
|
|
m_emoji_to_data_dict.insert(emoji, data);
|
|
return;
|
|
}
|
|
+ string trans_description = data.get_description();
|
|
+ en_data.set_description(trans_description);
|
|
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
+ var words = trans_description.split(" ");
|
|
+ // If the description has less than 3 words, add it to annotations
|
|
+ if (words.length < 3)
|
|
+ annotations.append(trans_description);
|
|
unowned GLib.SList<string> en_annotations
|
|
= en_data.get_annotations();
|
|
foreach (string annotation in en_annotations) {
|
|
--
|
|
2.9.3
|
|
|
|
From ab6c38c192cdf22356cbf254b98fb5b3d9d9a680 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Wed, 15 Mar 2017 11:48:24 +0900
|
|
Subject: [PATCH] client/x11: Add XSetIOErrorHandler() for GNOME3 desktop
|
|
|
|
When log into GNOME3 desktop immediately after the system is booted,
|
|
ibus-daemon is sometimes alive but ibus-x11 is dead after log out
|
|
the session. Because gdk_x_io_error() is called as the callback of
|
|
XSetIOErrorHandler() in gtk/gdk/x11/gdkmain-x11.c in ibus-x11.
|
|
Now I assume the callback is called in logout.
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/1907
|
|
|
|
Review URL: https://codereview.appspot.com/319490043
|
|
---
|
|
client/x11/main.c | 16 ++++++++++++++++
|
|
1 file changed, 16 insertions(+)
|
|
|
|
diff --git a/client/x11/main.c b/client/x11/main.c
|
|
index a717a2c..159f430 100644
|
|
--- a/client/x11/main.c
|
|
+++ b/client/x11/main.c
|
|
@@ -2,6 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus
|
|
* Copyright (C) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
|
|
+ * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2007-2015 Red Hat, Inc.
|
|
*
|
|
* main.c:
|
|
@@ -1131,6 +1132,20 @@ _xerror_handler (Display *dpy, XErrorEvent *e)
|
|
return 1;
|
|
}
|
|
|
|
+/* When log into GNOME3 desktop immediately after the system is booted,
|
|
+ * ibus-daemon is sometimes alive but ibus-x11 is dead after log out
|
|
+ * the session. Because gdk_x_io_error() is called as the callback of
|
|
+ * XSetIOErrorHandler() in gtk/gdk/x11/gdkmain-x11.c in ibus-x11.
|
|
+ * Now I assume the callback is called in logout.
|
|
+ */
|
|
+static int
|
|
+_xerror_io_handler (Display *dpy)
|
|
+{
|
|
+ if (_kill_daemon)
|
|
+ _atexit_cb ();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
@@ -1146,6 +1161,7 @@ main (int argc, char **argv)
|
|
|
|
gtk_init (&argc, &argv);
|
|
XSetErrorHandler (_xerror_handler);
|
|
+ XSetIOErrorHandler (_xerror_io_handler);
|
|
|
|
while (1) {
|
|
static struct option long_options [] = {
|
|
--
|
|
2.9.3
|
|
|
|
From 58f6140f427815adc947a5bb5c7dea4f3e315ae8 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Wed, 15 Mar 2017 11:52:39 +0900
|
|
Subject: [PATCH] ui/gtk3: Implement shortcut keys on emoji dialog
|
|
|
|
- Implement Ctrl-f, Ctrl-b, Ctrl-n, Ctrl-p, Ctrl-h, Ctrh-e for
|
|
cursor movements; forward, back, next, previous, head, end
|
|
on emoji grid.
|
|
- Implement Ctrl-a and Shift+arrow for text selection on emoji annotation.
|
|
- Implement Ctrl-u to delete text on emoji annotation.
|
|
- Implement to delete a selected text on emoji annotation.
|
|
- Change to show page indices to candidate indices on emoji.
|
|
- Sorted emoji categories.
|
|
- Added timeout of m_enter_notify_enable = false to bring back mouse.
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/315700043
|
|
---
|
|
ui/gtk3/emojier.vala | 311 +++++++++++++++++++++++++++++++++++----------------
|
|
1 file changed, 215 insertions(+), 96 deletions(-)
|
|
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 5e126e9..7da96c7 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -214,6 +214,7 @@ class IBusEmojier : Gtk.Window {
|
|
private string[] m_favorites = {};
|
|
private bool m_enter_notify_enable = true;
|
|
private uint m_entry_notify_show_id;
|
|
+ private uint m_entry_notify_disable_id;
|
|
|
|
public signal void candidate_clicked(uint index, uint button, uint state);
|
|
public signal void loaded_emoji_dict();
|
|
@@ -525,6 +526,18 @@ class IBusEmojier : Gtk.Window {
|
|
show_category_list();
|
|
}
|
|
|
|
+ private string get_title_string(string orig) {
|
|
+ StringBuilder buff = new StringBuilder();
|
|
+ for (int i = 0; i < orig.char_count(); i++) {
|
|
+ unichar ch = orig.get_char(i);
|
|
+ if (i == 0)
|
|
+ buff.append_unichar(ch.toupper());
|
|
+ else
|
|
+ buff.append_unichar(ch);
|
|
+ }
|
|
+ return buff.str;
|
|
+ }
|
|
+
|
|
private void show_category_list() {
|
|
remove_all_children();
|
|
m_scrolled_window = new EScrolledWindow();
|
|
@@ -586,19 +599,14 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
GLib.List<unowned string> categories =
|
|
m_category_to_emojis_dict.get_keys();
|
|
+ categories.sort((a, b) => {
|
|
+ return GLib.strcmp(_(a), _(b));
|
|
+ });
|
|
foreach (unowned string category in categories) {
|
|
EBoxRow row = new EBoxRow(category);
|
|
string locale_category = _(category);
|
|
- StringBuilder capital_category = new StringBuilder();
|
|
- for (int i = 0; i < locale_category.char_count(); i++) {
|
|
- unichar ch = locale_category.get_char(i);
|
|
- if (i == 0)
|
|
- capital_category.append_unichar(ch.toupper());
|
|
- else
|
|
- capital_category.append_unichar(ch);
|
|
- }
|
|
EPaddedLabel widget =
|
|
- new EPaddedLabel(capital_category.str,
|
|
+ new EPaddedLabel(get_title_string(locale_category),
|
|
Gtk.Align.CENTER);
|
|
row.add(widget);
|
|
m_list_box.add(row);
|
|
@@ -650,7 +658,7 @@ class IBusEmojier : Gtk.Window {
|
|
IBus.Text text = new IBus.Text.from_string(emoji);
|
|
m_lookup_table.append_candidate(text);
|
|
}
|
|
- m_backward = row.text;
|
|
+ m_backward = get_title_string(row.text);
|
|
}
|
|
show_candidate_panel();
|
|
}
|
|
@@ -759,9 +767,7 @@ class IBusEmojier : Gtk.Window {
|
|
uint page_end_pos = uint.min(page_start_pos + page_size, ncandidates);
|
|
if (m_backward != null) {
|
|
string backward_desc =
|
|
- "%s (%u / %u)".printf(m_backward,
|
|
- cursor / page_size + 1,
|
|
- ncandidates / page_size + 1);
|
|
+ "%s (%u / %u)".printf(m_backward, cursor, ncandidates - 1);
|
|
EPaddedLabel label = new EPaddedLabel(backward_desc,
|
|
Gtk.Align.CENTER,
|
|
TravelDirection.BACKWARD);
|
|
@@ -805,23 +811,23 @@ class IBusEmojier : Gtk.Window {
|
|
candidate_clicked(index, e.button, e.state);
|
|
return true;
|
|
});
|
|
- // m_enter_notify_enable is added because
|
|
- // enter_notify_event conflicts with keyboard operations.
|
|
- if (m_enter_notify_enable) {
|
|
- candidate_ebox.enter_notify_event.connect((e) => {
|
|
- m_lookup_table.set_cursor_pos(index);
|
|
- if (m_entry_notify_show_id > 0) {
|
|
+ candidate_ebox.enter_notify_event.connect((e) => {
|
|
+ // m_enter_notify_enable is added because
|
|
+ // enter_notify_event conflicts with keyboard operations.
|
|
+ if (!m_enter_notify_enable)
|
|
+ return true;
|
|
+ m_lookup_table.set_cursor_pos(index);
|
|
+ if (m_entry_notify_show_id > 0) {
|
|
GLib.Source.remove(m_entry_notify_show_id);
|
|
- }
|
|
- // If timeout is not added, memory leak happens and
|
|
- // button_press_event signal does not work above.
|
|
- m_entry_notify_show_id = GLib.Timeout.add(100, () => {
|
|
+ }
|
|
+ // If timeout is not added, memory leak happens and
|
|
+ // button_press_event signal does not work above.
|
|
+ m_entry_notify_show_id = GLib.Timeout.add(100, () => {
|
|
show_candidate_panel();
|
|
return false;
|
|
- });
|
|
- return true;
|
|
});
|
|
- }
|
|
+ return true;
|
|
+ });
|
|
grid.attach(candidate_ebox,
|
|
n % (int)EMOJI_GRID_PAGE, n / (int)EMOJI_GRID_PAGE,
|
|
1, 1);
|
|
@@ -844,16 +850,23 @@ class IBusEmojier : Gtk.Window {
|
|
widget.show_all();
|
|
return;
|
|
}
|
|
- unowned IBus.EmojiData data =
|
|
+ unowned IBus.EmojiData? data =
|
|
m_emoji_to_data_dict.lookup(candidate.text);
|
|
- unowned string description = data.get_description();
|
|
- if (description != "") {
|
|
+ if (data == null) {
|
|
+ // TODO: Provide a description for the favorite emojis.
|
|
EPaddedLabel widget = new EPaddedLabel(
|
|
- _("Description: %s").printf(description),
|
|
+ _("Description: %s").printf(_("None")),
|
|
Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
widget.show_all();
|
|
+ return;
|
|
}
|
|
+ unowned string description = data.get_description();
|
|
+ EPaddedLabel desc_widget = new EPaddedLabel(
|
|
+ _("Description: %s").printf(description),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(desc_widget);
|
|
+ desc_widget.show_all();
|
|
unowned GLib.SList<unowned string>? annotations =
|
|
data.get_annotations();
|
|
GLib.StringBuilder buff = new GLib.StringBuilder();
|
|
@@ -922,8 +935,21 @@ class IBusEmojier : Gtk.Window {
|
|
m_result = text.text;
|
|
}
|
|
|
|
- private void candidate_panel_cursor_down() {
|
|
+ private void enter_notify_disable_with_timer() {
|
|
+ // Enable keyboard operation and disable mouse operation.
|
|
m_enter_notify_enable = false;
|
|
+ if (m_entry_notify_disable_id > 0) {
|
|
+ GLib.Source.remove(m_entry_notify_disable_id);
|
|
+ }
|
|
+ // Bring back the mouse operation after a timeout.
|
|
+ m_entry_notify_show_id = GLib.Timeout.add(100, () => {
|
|
+ m_enter_notify_enable = true;
|
|
+ return false;
|
|
+ });
|
|
+ }
|
|
+
|
|
+ private void candidate_panel_cursor_down() {
|
|
+ enter_notify_disable_with_timer();
|
|
uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
uint cursor = m_lookup_table.get_cursor_pos();
|
|
if ((cursor + EMOJI_GRID_PAGE) < ncandidates) {
|
|
@@ -937,11 +963,11 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
private void candidate_panel_cursor_up() {
|
|
- m_enter_notify_enable = false;
|
|
+ enter_notify_disable_with_timer();
|
|
int ncandidates = (int)m_lookup_table.get_number_of_candidates();
|
|
int cursor = (int)m_lookup_table.get_cursor_pos();
|
|
int highest_pos =
|
|
- (ncandidates / (int)EMOJI_GRID_PAGE * (int)EMOJI_GRID_PAGE)
|
|
+ ((ncandidates - 1)/ (int)EMOJI_GRID_PAGE * (int)EMOJI_GRID_PAGE)
|
|
+ (cursor % (int)EMOJI_GRID_PAGE);
|
|
if ((cursor - (int)EMOJI_GRID_PAGE) >= 0) {
|
|
m_lookup_table.set_cursor_pos(cursor - (int)EMOJI_GRID_PAGE);
|
|
@@ -967,13 +993,119 @@ class IBusEmojier : Gtk.Window {
|
|
show_category_list();
|
|
}
|
|
|
|
+ private bool key_press_cursor_horizontal(uint keyval,
|
|
+ uint modifiers) {
|
|
+ assert (keyval == Gdk.Key.Left || keyval == Gdk.Key.Right);
|
|
+
|
|
+ if (m_candidate_panel_is_visible) {
|
|
+ enter_notify_disable_with_timer();
|
|
+ if (keyval == Gdk.Key.Left)
|
|
+ m_lookup_table.cursor_up();
|
|
+ else if (keyval == Gdk.Key.Right)
|
|
+ m_lookup_table.cursor_down();
|
|
+ show_candidate_panel();
|
|
+ } else if (m_entry.get_text().len() > 0) {
|
|
+ int step = 0;
|
|
+ if (keyval == Gdk.Key.Left)
|
|
+ step = -1;
|
|
+ else if (keyval == Gdk.Key.Right)
|
|
+ step = 1;
|
|
+ GLib.Signal.emit_by_name(
|
|
+ m_entry, "move-cursor",
|
|
+ Gtk.MovementStep.VISUAL_POSITIONS,
|
|
+ step,
|
|
+ (modifiers & Gdk.ModifierType.SHIFT_MASK) != 0
|
|
+ ? true : false);
|
|
+ } else {
|
|
+ // For Gdk.Key.f and Gdk.Key.b
|
|
+ if (keyval == Gdk.Key.Left)
|
|
+ keyval = Gdk.Key.Up;
|
|
+ else if (keyval == Gdk.Key.Right)
|
|
+ keyval = Gdk.Key.Down;
|
|
+ category_list_cursor_move(keyval);
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ private bool key_press_cursor_vertical(uint keyval) {
|
|
+ assert (keyval == Gdk.Key.Down || keyval == Gdk.Key.Up);
|
|
+
|
|
+ if (m_candidate_panel_is_visible) {
|
|
+ if (keyval == Gdk.Key.Down)
|
|
+ candidate_panel_cursor_down();
|
|
+ else if (keyval == Gdk.Key.Up)
|
|
+ candidate_panel_cursor_up();
|
|
+ } else {
|
|
+ category_list_cursor_move(keyval);
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ private bool key_press_cursor_home_end(uint keyval,
|
|
+ uint modifiers) {
|
|
+ assert (keyval == Gdk.Key.Home || keyval == Gdk.Key.End);
|
|
+
|
|
+ if (m_candidate_panel_is_visible) {
|
|
+ enter_notify_disable_with_timer();
|
|
+ if (keyval == Gdk.Key.Home) {
|
|
+ m_lookup_table.set_cursor_pos(0);
|
|
+ } else if (keyval == Gdk.Key.End) {
|
|
+ uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
+ m_lookup_table.set_cursor_pos(ncandidates - 1);
|
|
+ }
|
|
+ show_candidate_panel();
|
|
+ return true;
|
|
+ }
|
|
+ if (m_entry.get_text().len() > 0) {
|
|
+ int step = 0;
|
|
+ if (keyval == Gdk.Key.Home)
|
|
+ step = -1;
|
|
+ else if (keyval == Gdk.Key.End)
|
|
+ step = 1;
|
|
+ GLib.Signal.emit_by_name(
|
|
+ m_entry, "move-cursor",
|
|
+ Gtk.MovementStep.DISPLAY_LINE_ENDS,
|
|
+ step,
|
|
+ (modifiers & Gdk.ModifierType.SHIFT_MASK) != 0
|
|
+ ? true : false);
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ private bool key_press_cursor_escape() {
|
|
+ if (m_candidate_panel_is_visible) {
|
|
+ hide_candidate_panel();
|
|
+ return true;
|
|
+ } else if (m_current_category_type == CategoryType.LANG) {
|
|
+ m_current_category_type = CategoryType.EMOJI;
|
|
+ show_candidate_panel();
|
|
+ return true;
|
|
+ } else if (m_entry.get_text().length == 0) {
|
|
+ m_loop.quit();
|
|
+ hide_candidate_panel();
|
|
+ return true;
|
|
+ }
|
|
+ m_entry.delete_text(0, -1);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
private void entry_enter_keyval(uint keyval) {
|
|
unichar ch = IBus.keyval_to_unicode(keyval);
|
|
- if (!ch.isgraph())
|
|
+ if (ch.iscntrl())
|
|
return;
|
|
string str = ch.to_string();
|
|
|
|
// what gtk_entry_commit_cb() do
|
|
+ if (m_entry.get_selection_bounds(null, null)) {
|
|
+ m_entry.delete_selection();
|
|
+ } else {
|
|
+ if (m_entry.get_overwrite_mode()) {
|
|
+ uint text_length = m_entry.get_buffer().get_length();
|
|
+ if (m_entry.cursor_position < text_length)
|
|
+ m_entry.delete_from_cursor(Gtk.DeleteType.CHARS, 1);
|
|
+ }
|
|
+ }
|
|
int pos = m_entry.get_position();
|
|
m_entry.insert_text(str, -1, ref pos);
|
|
m_entry.set_position(pos);
|
|
@@ -1084,19 +1216,8 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
switch (keyval) {
|
|
case Gdk.Key.Escape:
|
|
- if (m_candidate_panel_is_visible) {
|
|
- hide_candidate_panel();
|
|
- return true;
|
|
- } else if (m_current_category_type == CategoryType.LANG) {
|
|
- m_current_category_type = CategoryType.EMOJI;
|
|
- show_candidate_panel();
|
|
+ if (key_press_cursor_escape())
|
|
return true;
|
|
- } else if (m_entry.get_text().length == 0) {
|
|
- m_loop.quit();
|
|
- hide_candidate_panel();
|
|
- return true;
|
|
- }
|
|
- m_entry.delete_text(0, -1);
|
|
break;
|
|
case Gdk.Key.Return:
|
|
if (m_candidate_panel_is_visible) {
|
|
@@ -1126,7 +1247,7 @@ class IBusEmojier : Gtk.Window {
|
|
break;
|
|
}
|
|
if (m_candidate_panel_is_visible) {
|
|
- m_enter_notify_enable = false;
|
|
+ enter_notify_disable_with_timer();
|
|
m_lookup_table.cursor_down();
|
|
show_candidate_panel();
|
|
}
|
|
@@ -1135,48 +1256,20 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
return true;
|
|
case Gdk.Key.Right:
|
|
- if (m_candidate_panel_is_visible) {
|
|
- m_enter_notify_enable = false;
|
|
- m_lookup_table.cursor_down();
|
|
- show_candidate_panel();
|
|
- return true;
|
|
- }
|
|
- if (m_entry.get_text().len() > 0) {
|
|
- GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
- Gtk.MovementStep.VISUAL_POSITIONS,
|
|
- 1, false);
|
|
- return true;
|
|
- }
|
|
- break;
|
|
+ key_press_cursor_horizontal(keyval, modifiers);
|
|
+ return true;
|
|
case Gdk.Key.Left:
|
|
- if (m_candidate_panel_is_visible) {
|
|
- m_enter_notify_enable = false;
|
|
- m_lookup_table.cursor_up();
|
|
- show_candidate_panel();
|
|
- return true;
|
|
- }
|
|
- if (m_entry.get_text().len() > 0) {
|
|
- GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
- Gtk.MovementStep.VISUAL_POSITIONS,
|
|
- -1, false);
|
|
- return true;
|
|
- }
|
|
- break;
|
|
+ key_press_cursor_horizontal(keyval, modifiers);
|
|
+ return true;
|
|
case Gdk.Key.Down:
|
|
- if (m_candidate_panel_is_visible)
|
|
- candidate_panel_cursor_down();
|
|
- else
|
|
- category_list_cursor_move(Gdk.Key.Down);
|
|
+ key_press_cursor_vertical(keyval);
|
|
return true;
|
|
case Gdk.Key.Up:
|
|
- if (m_candidate_panel_is_visible)
|
|
- candidate_panel_cursor_up();
|
|
- else
|
|
- category_list_cursor_move(Gdk.Key.Up);
|
|
+ key_press_cursor_vertical(keyval);
|
|
return true;
|
|
case Gdk.Key.Page_Down:
|
|
if (m_candidate_panel_is_visible) {
|
|
- m_enter_notify_enable = false;
|
|
+ enter_notify_disable_with_timer();
|
|
m_lookup_table.page_down();
|
|
show_candidate_panel();
|
|
return true;
|
|
@@ -1184,33 +1277,59 @@ class IBusEmojier : Gtk.Window {
|
|
break;
|
|
case Gdk.Key.Page_Up:
|
|
if (m_candidate_panel_is_visible) {
|
|
- m_enter_notify_enable = false;
|
|
+ enter_notify_disable_with_timer();
|
|
m_lookup_table.page_up();
|
|
show_candidate_panel();
|
|
return true;
|
|
}
|
|
break;
|
|
case Gdk.Key.Home:
|
|
- if (m_entry.get_text().len() > 0) {
|
|
- GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
- Gtk.MovementStep.DISPLAY_LINE_ENDS,
|
|
- -1, false);
|
|
+ if (key_press_cursor_home_end(keyval, modifiers))
|
|
return true;
|
|
- }
|
|
break;
|
|
case Gdk.Key.End:
|
|
- if (m_entry.get_text().len() > 0) {
|
|
- GLib.Signal.emit_by_name(m_entry, "move-cursor",
|
|
- Gtk.MovementStep.DISPLAY_LINE_ENDS,
|
|
- 1, false);
|
|
+ if (key_press_cursor_home_end(keyval, modifiers))
|
|
return true;
|
|
- }
|
|
- break;
|
|
- default:
|
|
- entry_enter_keyval(keyval);
|
|
break;
|
|
}
|
|
|
|
+ if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
|
|
+ switch (keyval) {
|
|
+ case Gdk.Key.f:
|
|
+ key_press_cursor_horizontal(Gdk.Key.Right, modifiers);
|
|
+ return true;
|
|
+ case Gdk.Key.b:
|
|
+ key_press_cursor_horizontal(Gdk.Key.Left, modifiers);
|
|
+ return true;
|
|
+ case Gdk.Key.n:
|
|
+ key_press_cursor_vertical(Gdk.Key.Down);
|
|
+ return true;
|
|
+ case Gdk.Key.p:
|
|
+ key_press_cursor_vertical(Gdk.Key.Up);
|
|
+ return true;
|
|
+ case Gdk.Key.h:
|
|
+ if (key_press_cursor_home_end(Gdk.Key.Home, modifiers))
|
|
+ return true;
|
|
+ break;
|
|
+ case Gdk.Key.e:
|
|
+ if (key_press_cursor_home_end(Gdk.Key.End, modifiers))
|
|
+ return true;
|
|
+ break;
|
|
+ case Gdk.Key.u:
|
|
+ if (key_press_cursor_escape())
|
|
+ return true;
|
|
+ break;
|
|
+ case Gdk.Key.a:
|
|
+ if (m_entry.get_text().len() > 0) {
|
|
+ m_entry.select_region(0, -1);
|
|
+ return true;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ entry_enter_keyval(keyval);
|
|
return true;
|
|
}
|
|
|
|
--
|
|
2.9.3
|
|
|
|
From 50e344afaffc29e626dbc27747a1aeee6cccafdf Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Fri, 17 Mar 2017 12:08:50 +0900
|
|
Subject: [PATCH] ui/gtk3: Enable strcasecmp to match emoji annotation
|
|
|
|
Users can type capital annotations.
|
|
Also shows emoji annotations in the status bar if the
|
|
typing unicode point matches a emoji character.
|
|
|
|
Review URL: https://codereview.appspot.com/314640043
|
|
---
|
|
ui/gtk3/emojier.vala | 97 +++++++++++++++++++++++++++++++++++-----------------
|
|
1 file changed, 65 insertions(+), 32 deletions(-)
|
|
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 7da96c7..b1dc50c 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -432,10 +432,45 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+ private string utf8_down(string str) {
|
|
+ GLib.StringBuilder buff = new GLib.StringBuilder();
|
|
+ int length = str.char_count();
|
|
+ for (int i = 0; i < length; i++) {
|
|
+ buff.append_unichar(str.get_char(0).tolower());
|
|
+ str = str.next_char();
|
|
+ }
|
|
+ return buff.str;
|
|
+ }
|
|
+
|
|
+ private string utf8_title(string str) {
|
|
+ StringBuilder buff = new StringBuilder();
|
|
+ int length = str.char_count();
|
|
+ for (int i = 0; i < length; i++) {
|
|
+ unichar ch = str.get_char(0);
|
|
+ if (i == 0)
|
|
+ buff.append_unichar(ch.toupper());
|
|
+ else
|
|
+ buff.append_unichar(ch);
|
|
+ str = str.next_char();
|
|
+ }
|
|
+ return buff.str;
|
|
+ }
|
|
+
|
|
private void update_emoji_to_data_dict(IBus.EmojiData data,
|
|
string lang) {
|
|
string emoji = data.get_emoji();
|
|
if (lang == "en") {
|
|
+ string description = utf8_down(data.get_description());
|
|
+ unowned GLib.SList<string> annotations = data.get_annotations();
|
|
+ var words = description.split(" ");
|
|
+ // If the description has less than 3 words, add it to annotations
|
|
+ if (words.length < 3 &&
|
|
+ annotations.find_custom(
|
|
+ description,
|
|
+ (GLib.CompareFunc<string>)GLib.strcmp) == null) {
|
|
+ annotations.append(description);
|
|
+ data.set_annotations(annotations.copy_deep(GLib.strdup));
|
|
+ }
|
|
m_emoji_to_data_dict.replace(emoji, data);
|
|
} else {
|
|
unowned IBus.EmojiData? en_data =
|
|
@@ -446,16 +481,24 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
string trans_description = data.get_description();
|
|
en_data.set_description(trans_description);
|
|
+ trans_description = utf8_down(trans_description);
|
|
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
var words = trans_description.split(" ");
|
|
// If the description has less than 3 words, add it to annotations
|
|
- if (words.length < 3)
|
|
+ if (words.length < 3 &&
|
|
+ annotations.find_custom(
|
|
+ trans_description,
|
|
+ (GLib.CompareFunc<string>)GLib.strcmp) == null) {
|
|
annotations.append(trans_description);
|
|
+ }
|
|
unowned GLib.SList<string> en_annotations
|
|
= en_data.get_annotations();
|
|
foreach (string annotation in en_annotations) {
|
|
- if (annotations.find_custom(annotation, GLib.strcmp) == null)
|
|
+ if (annotations.find_custom(
|
|
+ annotation,
|
|
+ (GLib.CompareFunc<string>)GLib.strcmp) == null) {
|
|
annotations.append(annotation.dup());
|
|
+ }
|
|
}
|
|
en_data.set_annotations(annotations.copy_deep(GLib.strdup));
|
|
}
|
|
@@ -526,18 +569,6 @@ class IBusEmojier : Gtk.Window {
|
|
show_category_list();
|
|
}
|
|
|
|
- private string get_title_string(string orig) {
|
|
- StringBuilder buff = new StringBuilder();
|
|
- for (int i = 0; i < orig.char_count(); i++) {
|
|
- unichar ch = orig.get_char(i);
|
|
- if (i == 0)
|
|
- buff.append_unichar(ch.toupper());
|
|
- else
|
|
- buff.append_unichar(ch);
|
|
- }
|
|
- return buff.str;
|
|
- }
|
|
-
|
|
private void show_category_list() {
|
|
remove_all_children();
|
|
m_scrolled_window = new EScrolledWindow();
|
|
@@ -606,7 +637,7 @@ class IBusEmojier : Gtk.Window {
|
|
EBoxRow row = new EBoxRow(category);
|
|
string locale_category = _(category);
|
|
EPaddedLabel widget =
|
|
- new EPaddedLabel(get_title_string(locale_category),
|
|
+ new EPaddedLabel(utf8_title(locale_category),
|
|
Gtk.Align.CENTER);
|
|
row.add(widget);
|
|
m_list_box.add(row);
|
|
@@ -658,7 +689,7 @@ class IBusEmojier : Gtk.Window {
|
|
IBus.Text text = new IBus.Text.from_string(emoji);
|
|
m_lookup_table.append_candidate(text);
|
|
}
|
|
- m_backward = get_title_string(row.text);
|
|
+ m_backward = utf8_title(row.text);
|
|
}
|
|
show_candidate_panel();
|
|
}
|
|
@@ -734,6 +765,7 @@ class IBusEmojier : Gtk.Window {
|
|
m_backward = null;
|
|
return;
|
|
}
|
|
+ annotation = utf8_down(annotation);
|
|
if (annotation.length > m_emoji_max_seq_len) {
|
|
hide_candidate_panel();
|
|
return;
|
|
@@ -841,6 +873,8 @@ class IBusEmojier : Gtk.Window {
|
|
m_vbox.add(grid);
|
|
grid.show_all();
|
|
IBus.Text candidate = m_lookup_table.get_candidate(cursor);
|
|
+ unowned IBus.EmojiData? data =
|
|
+ m_emoji_to_data_dict.lookup(candidate.text);
|
|
if (cursor == 0 && candidate.text == m_unicode_point) {
|
|
EPaddedLabel widget = new EPaddedLabel(
|
|
_("Description: Unicode point U+%04X").printf(
|
|
@@ -848,25 +882,25 @@ class IBusEmojier : Gtk.Window {
|
|
Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
widget.show_all();
|
|
- return;
|
|
- }
|
|
- unowned IBus.EmojiData? data =
|
|
- m_emoji_to_data_dict.lookup(candidate.text);
|
|
- if (data == null) {
|
|
- // TODO: Provide a description for the favorite emojis.
|
|
+ if (data == null)
|
|
+ return;
|
|
+ } else if (data == null) {
|
|
+ // TODO: Provide a custom description and annotation for
|
|
+ // the favorite emojis.
|
|
EPaddedLabel widget = new EPaddedLabel(
|
|
_("Description: %s").printf(_("None")),
|
|
Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
widget.show_all();
|
|
return;
|
|
+ } else {
|
|
+ unowned string description = data.get_description();
|
|
+ EPaddedLabel widget = new EPaddedLabel(
|
|
+ _("Description: %s").printf(description),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget);
|
|
+ widget.show_all();
|
|
}
|
|
- unowned string description = data.get_description();
|
|
- EPaddedLabel desc_widget = new EPaddedLabel(
|
|
- _("Description: %s").printf(description),
|
|
- Gtk.Align.START);
|
|
- m_vbox.add(desc_widget);
|
|
- desc_widget.show_all();
|
|
unowned GLib.SList<unowned string>? annotations =
|
|
data.get_annotations();
|
|
GLib.StringBuilder buff = new GLib.StringBuilder();
|
|
@@ -1243,10 +1277,9 @@ class IBusEmojier : Gtk.Window {
|
|
case Gdk.Key.space:
|
|
case Gdk.Key.KP_Space:
|
|
if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
|
|
- entry_enter_keyval(keyval);
|
|
- break;
|
|
- }
|
|
- if (m_candidate_panel_is_visible) {
|
|
+ if (m_entry.get_text().len() > 0)
|
|
+ entry_enter_keyval(keyval);
|
|
+ } else if (m_candidate_panel_is_visible) {
|
|
enter_notify_disable_with_timer();
|
|
m_lookup_table.cursor_down();
|
|
show_candidate_panel();
|
|
--
|
|
2.9.3
|
|
|
|
From bd7e0ba297f72ae1e2989743f2426c44df29f3ec Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Tue, 21 Mar 2017 12:56:23 +0900
|
|
Subject: [PATCH] Make more readable error messages if emoji xml files are
|
|
missed
|
|
|
|
Also Fix CONFIG_CLEAN_FILES for autoreconf
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/320750043
|
|
---
|
|
configure.ac | 26 +++++++++++++++++---------
|
|
src/Makefile.am | 5 ++++-
|
|
src/emoji-parser.c | 2 +-
|
|
ui/gtk3/Makefile.am | 4 +++-
|
|
4 files changed, 25 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 369485c..0a5f2d5 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -611,17 +611,11 @@ AC_ARG_ENABLE(emoji-dict,
|
|
[enable_emoji_dict=yes]
|
|
)
|
|
AM_CONDITIONAL([ENABLE_EMOJI_DICT], [test x"$enable_emoji_dict" = x"yes"])
|
|
-if test x"$enable_emoji_dict" = x"yes"; then
|
|
- PKG_CHECK_MODULES(JSON_GLIB1, [
|
|
- json-glib-1.0
|
|
- ])
|
|
- enable_emoji_dict="yes (enabled, use --disable-emoji-dict to disable)"
|
|
-fi
|
|
|
|
AC_ARG_WITH(emoji-json-file,
|
|
AS_HELP_STRING([--with-emoji-json-file[=DIR/emoji.json]],
|
|
[Set emoji.json. (default: "/usr/lib/node_modules/emojione/emoji.json")
|
|
- You can get emoji.json with "npm install -g emojione".]),
|
|
+ ]),
|
|
EMOJI_JSON_FILE=$with_emoji_json_file,
|
|
EMOJI_JSON_FILE="/usr/lib/node_modules/emojione/emoji.json"
|
|
)
|
|
@@ -630,13 +624,27 @@ AC_SUBST(EMOJI_JSON_FILE)
|
|
AC_ARG_WITH(emoji-annotation-dir,
|
|
AS_HELP_STRING([--with-emoji-annotation-dir[=DIR]],
|
|
[Set the directory of CLDR annotation files.
|
|
- (default: "/usr/share/unicode/cldr/common/annotations")
|
|
- You can get https://github.com/fujiwarat/cldr-emoji-annotation]),
|
|
+ (default: "/usr/share/unicode/cldr/common/annotations")]),
|
|
EMOJI_ANNOTATION_DIR=$with_emoji_annotation_dir,
|
|
EMOJI_ANNOTATION_DIR="/usr/share/unicode/cldr/common/annotations"
|
|
)
|
|
AC_SUBST(EMOJI_ANNOTATION_DIR)
|
|
|
|
+if test x"$enable_emoji_dict" = x"yes"; then
|
|
+ if test ! -f $EMOJI_JSON_FILE ; then
|
|
+ AC_MSG_ERROR(Not found $EMOJI_JSON_FILE. You can get emoji.json \
|
|
+with "npm install -g emojione".)
|
|
+ fi
|
|
+ if test ! -f $EMOJI_ANNOTATION_DIR/en.xml ; then
|
|
+ AC_MSG_ERROR(Not found $EMOJI_ANNOTATION_DIR/en.xml. You can get \
|
|
+https://github.com/fujiwarat/cldr-emoji-annotation)
|
|
+ fi
|
|
+ PKG_CHECK_MODULES(JSON_GLIB1, [
|
|
+ json-glib-1.0
|
|
+ ])
|
|
+ enable_emoji_dict="yes (enabled, use --disable-emoji-dict to disable)"
|
|
+fi
|
|
+
|
|
# Check iso-codes.
|
|
PKG_CHECK_MODULES(ISOCODES, [
|
|
iso-codes
|
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
index 0d403e8..7053e3e 100644
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -243,7 +243,10 @@ LANG_FILES = $(basename $(notdir $(wildcard $(EMOJI_ANNOTATION_DIR)/*.xml)))
|
|
noinst_PROGRAMS = emoji-parser
|
|
|
|
dicts/emoji-en.dict: emoji-parser
|
|
- $(AM_V_at)for f in $(LANG_FILES) ; do \
|
|
+ $(AM_V_at)if test x"$(LANG_FILES)" = x ; then \
|
|
+ echo "WARNING: Not found $(EMOJI_ANNOTATION_DIR)/en.xml" 1>&2; \
|
|
+ fi; \
|
|
+ for f in $(LANG_FILES) ; do \
|
|
if test x"$$f" = xen ; then \
|
|
$(builddir)/emoji-parser \
|
|
--xml $(EMOJI_ANNOTATION_DIR)/$$f.xml \
|
|
diff --git a/src/emoji-parser.c b/src/emoji-parser.c
|
|
index 8ff04f1..f9e3470 100644
|
|
--- a/src/emoji-parser.c
|
|
+++ b/src/emoji-parser.c
|
|
@@ -20,7 +20,7 @@
|
|
* USA
|
|
*/
|
|
|
|
-/* Convert /usr/share/unicode/cldr/common/annotations/*.xml and
|
|
+/* Convert /usr/share/unicode/cldr/common/annotations/\*.xml and
|
|
* /usr/lib/node_modules/emojione/emoji.json
|
|
* to the dictionary file which look up the Emoji from the annotation.
|
|
* Get *.xml from https://github.com/fujiwarat/cldr-emoji-annotation
|
|
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
|
|
index 4e7fd1b..b055f67 100644
|
|
--- a/ui/gtk3/Makefile.am
|
|
+++ b/ui/gtk3/Makefile.am
|
|
@@ -81,6 +81,8 @@ AM_VALAFLAGS = \
|
|
--target-glib="$(VALA_TARGET_GLIB_VERSION)" \
|
|
$(NULL)
|
|
|
|
+CONFIG_CLEAN_FILES =
|
|
+
|
|
if ENABLE_LIBNOTIFY
|
|
AM_CFLAGS += \
|
|
@LIBNOTIFY_CFLAGS@ \
|
|
@@ -239,7 +241,7 @@ vapi_DATA = $(VAPIGEN_VAPIS) $(VAPIGEN_VAPIS:.vapi=.deps)
|
|
|
|
MAINTAINERCLEANFILES = $(VAPIGEN_VAPIS)
|
|
# for make distclean
|
|
-CONFIG_CLEAN_FILES = $(VAPIGEN_VAPIS)
|
|
+CONFIG_CLEAN_FILES += $(VAPIGEN_VAPIS)
|
|
EXTRA_DIST += $(VAPIGEN_VAPIS)
|
|
|
|
endif
|
|
--
|
|
2.9.3
|
|
|
|
From 0efb1c503d5901bbddcdb6fa73007b364ba4368d Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 27 Mar 2017 15:12:42 +0900
|
|
Subject: [PATCH] Move language setting from IBusEmojier to ibus-setup
|
|
|
|
The language setting of emoji annotations now can be saved
|
|
with ibus-setup.
|
|
Implement `ibus emoji [--font|--lang|--help]`
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/323720043
|
|
---
|
|
data/ibus.schemas.in | 46 +++---
|
|
setup/Makefile.am | 26 ++--
|
|
setup/emojilang.py | 348 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
setup/main.py | 41 ++++--
|
|
setup/setup.ui | 97 ++++++++-----
|
|
tools/main.vala | 38 ++++-
|
|
ui/gtk3/emojier.vala | 295 +++++++++++++++------------------------
|
|
ui/gtk3/ibusemojidialog.h | 11 ++
|
|
ui/gtk3/panel.vala | 39 ++++--
|
|
9 files changed, 671 insertions(+), 270 deletions(-)
|
|
create mode 100644 setup/emojilang.py
|
|
|
|
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
|
|
index 218d223..c0bbd6f 100644
|
|
--- a/data/ibus.schemas.in
|
|
+++ b/data/ibus.schemas.in
|
|
@@ -106,18 +106,6 @@
|
|
</locale>
|
|
</schema>
|
|
<schema>
|
|
- <key>/schemas/desktop/ibus/general/hotkey/emoji</key>
|
|
- <applyto>/desktop/ibus/general/hotkey/emoji</applyto>
|
|
- <owner>ibus</owner>
|
|
- <type>list</type>
|
|
- <list_type>string</list_type>
|
|
- <default>[<Control><Shift>e]</default>
|
|
- <locale name="C">
|
|
- <short>Emoji shortcut keys for gtk_accelerator_parse</short>
|
|
- <long>The shortcut keys for turning emoji typing on or off</long>
|
|
- </locale>
|
|
- </schema>
|
|
- <schema>
|
|
<key>/schemas/desktop/ibus/general/hotkey/enable_unconditional</key>
|
|
<applyto>/desktop/ibus/general/hotkey/enable_unconditional</applyto>
|
|
<owner>ibus</owner>
|
|
@@ -366,8 +354,20 @@
|
|
</locale>
|
|
</schema>
|
|
<schema>
|
|
- <key>/schemas/desktop/ibus/panel/emoji_font</key>
|
|
- <applyto>/desktop/ibus/panel/emoji_font</applyto>
|
|
+ <key>/schemas/desktop/ibus/panel/emoji/hotkey</key>
|
|
+ <applyto>/desktop/ibus/panel/emoji/hotkey</applyto>
|
|
+ <owner>ibus</owner>
|
|
+ <type>list</type>
|
|
+ <list_type>string</list_type>
|
|
+ <default>[<Control><Shift>e]</default>
|
|
+ <locale name="C">
|
|
+ <short>Emoji shortcut keys for gtk_accelerator_parse</short>
|
|
+ <long>The shortcut keys for turning emoji typing on or off</long>
|
|
+ </locale>
|
|
+ </schema>
|
|
+ <schema>
|
|
+ <key>/schemas/desktop/ibus/panel/emoji/font</key>
|
|
+ <applyto>/desktop/ibus/panel/emoji/font</applyto>
|
|
<owner>ibus</owner>
|
|
<type>string</type>
|
|
<default>Monospace 16</default>
|
|
@@ -377,8 +377,22 @@
|
|
</locale>
|
|
</schema>
|
|
<schema>
|
|
- <key>/schemas/desktop/ibus/panel/emoji_favorites</key>
|
|
- <applyto>/desktop/ibus/panel/emoji_favorites</applyto>
|
|
+ <key>/schemas/desktop/ibus/panel/emoji/lang</key>
|
|
+ <applyto>/desktop/ibus/panel/emoji/lang</applyto>
|
|
+ <owner>ibus</owner>
|
|
+ <type>string</type>
|
|
+ <default>en</default>
|
|
+ <locale name="C">
|
|
+ <short>Default language for emoji dictionary</short>
|
|
+ <long>Choose a default language of emoji dictionaries on
|
|
+ the emoji dialog. The value $lang is applied to
|
|
+ /usr/share/unicode/cldr/common/annotations/$lang.xml
|
|
+ </long>
|
|
+ </locale>
|
|
+ </schema>
|
|
+ <schema>
|
|
+ <key>/schemas/desktop/ibus/panel/emoji/favorites</key>
|
|
+ <applyto>/desktop/ibus/panel/emoji/favorites</applyto>
|
|
<owner>ibus</owner>
|
|
<type>list</type>
|
|
<default>[]</default>
|
|
diff --git a/setup/Makefile.am b/setup/Makefile.am
|
|
index 2d822d2..b7dd755 100644
|
|
--- a/setup/Makefile.am
|
|
+++ b/setup/Makefile.am
|
|
@@ -3,7 +3,8 @@
|
|
# ibus - The Input Bus
|
|
#
|
|
# Copyright (c) 2007-2014 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2007-2014 Red Hat, Inc.
|
|
+# Copyright (c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2007-2017 Red Hat, Inc.
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -21,19 +22,20 @@
|
|
# USA
|
|
|
|
ibussetup_PYTHON = \
|
|
- main.py \
|
|
- i18n.py \
|
|
- icon.py \
|
|
- enginecombobox.py \
|
|
- enginedialog.py \
|
|
- enginetreeview.py \
|
|
- engineabout.py \
|
|
- keyboardshortcut.py \
|
|
- $(NULL)
|
|
+ emojilang.py \
|
|
+ enginecombobox.py \
|
|
+ enginedialog.py \
|
|
+ enginetreeview.py \
|
|
+ engineabout.py \
|
|
+ i18n.py \
|
|
+ icon.py \
|
|
+ keyboardshortcut.py \
|
|
+ main.py \
|
|
+ $(NULL)
|
|
|
|
ibussetup_DATA = \
|
|
- setup.ui \
|
|
- $(NULL)
|
|
+ setup.ui \
|
|
+ $(NULL)
|
|
|
|
bin_SCRIPTS = ibus-setup
|
|
ibussetupdir = $(pkgdatadir)/setup
|
|
diff --git a/setup/emojilang.py b/setup/emojilang.py
|
|
new file mode 100644
|
|
index 0000000..8250589
|
|
--- /dev/null
|
|
+++ b/setup/emojilang.py
|
|
@@ -0,0 +1,348 @@
|
|
+# vim:set et sts=4 sw=4:
|
|
+# -*- coding: utf-8 -*-
|
|
+#
|
|
+# ibus - The Input Bus
|
|
+#
|
|
+# Copyright (c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2017 Red Hat, Inc.
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or
|
|
+# modify it under the terms of the GNU General Public License as
|
|
+# published by the Free Software Foundation; either version 2 of the
|
|
+# License, or (at your option) any later version.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful, but
|
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+# General Public License for more details.
|
|
+#
|
|
+# You should have received a copy of the GNU General Public License
|
|
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
+
|
|
+# for python2
|
|
+from __future__ import print_function
|
|
+
|
|
+__all__ = (
|
|
+ "EmojiLangButton",
|
|
+);
|
|
+
|
|
+from gi.repository import Gtk
|
|
+from gi.repository import GLib
|
|
+from gi.repository import GObject
|
|
+from gi.repository import IBus
|
|
+
|
|
+import functools
|
|
+import gettext
|
|
+import i18n
|
|
+import locale
|
|
+import os
|
|
+
|
|
+from icon import load_icon
|
|
+from i18n import _, N_
|
|
+
|
|
+ROW_TRAVEL_DIRECTION_NONE, \
|
|
+ROW_TRAVEL_DIRECTION_FORWARD, \
|
|
+ROW_TRAVEL_DIRECTION_BACKWARD = list(range(3))
|
|
+
|
|
+class LanguageString:
|
|
+ def __init__(self, id, trans = ""):
|
|
+ self.id = id
|
|
+ self.trans = trans
|
|
+
|
|
+class EmojiLangChooser(Gtk.Dialog):
|
|
+ __gtype_name__ = 'EmojiLangChooser'
|
|
+ __initial_languages = [ IBus.get_language_name('en_US'),
|
|
+ IBus.get_language_name('en_GB'),
|
|
+ IBus.get_language_name('de_DE'),
|
|
+ IBus.get_language_name('fr_FR'),
|
|
+ IBus.get_language_name('es_ES'),
|
|
+ IBus.get_language_name('zh_CN'),
|
|
+ IBus.get_language_name('ja_JP'),
|
|
+ IBus.get_language_name('ru_RU'),
|
|
+ IBus.get_language_name('ar_EG') ]
|
|
+
|
|
+
|
|
+ def __init__(self, id = None, transient_for = None):
|
|
+ super(EmojiLangChooser, self).__init__(
|
|
+ title = _("Select a language"),
|
|
+ transient_for = transient_for,
|
|
+ resizable = True)
|
|
+ buttons = (_("_Cancel"), Gtk.ResponseType.CANCEL,
|
|
+ _("_OK"), Gtk.ResponseType.APPLY)
|
|
+ self.add_buttons(*buttons)
|
|
+
|
|
+ if id == None:
|
|
+ id = 'en'
|
|
+ self.__id = id
|
|
+ self.__engines_for_lang = {}
|
|
+ self.__untrans_for_lang = {}
|
|
+ self.__langs = {}
|
|
+ self.__lang_list = []
|
|
+
|
|
+ self.__scrolled = Gtk.ScrolledWindow(
|
|
+ hscrollbar_policy = Gtk.PolicyType.NEVER,
|
|
+ vscrollbar_policy = Gtk.PolicyType.NEVER,
|
|
+ shadow_type = Gtk.ShadowType.IN,
|
|
+ margin_left = 6,
|
|
+ margin_right = 6,
|
|
+ margin_top = 6,
|
|
+ margin_bottom = 6)
|
|
+ self.vbox.add(self.__scrolled)
|
|
+ viewport = Gtk.Viewport()
|
|
+ self.__scrolled.add(viewport)
|
|
+ self.__list = Gtk.ListBox(vexpand = True,
|
|
+ halign = Gtk.Align.FILL,
|
|
+ valign = Gtk.Align.FILL)
|
|
+ viewport.add(self.__list)
|
|
+
|
|
+ self.__adjustment = self.__scrolled.get_vadjustment()
|
|
+ self.__list.set_adjustment(self.__adjustment)
|
|
+ self.__list.set_filter_func(self.__list_filter, None)
|
|
+ self.__list.connect('row-activated', self.__row_activated)
|
|
+
|
|
+ self.__showing_extra = False
|
|
+ self.__more_row = self.__more_row_new()
|
|
+ self.__load_lang_list()
|
|
+ self.__show_lang_rows()
|
|
+ self.show_all()
|
|
+
|
|
+
|
|
+ def __load_lang_list(self):
|
|
+ dictdir = os.path.dirname(__file__) + '/../dicts'
|
|
+ for filename in os.listdir(dictdir):
|
|
+ suffix = '.dict'
|
|
+ if not filename.endswith(suffix):
|
|
+ continue
|
|
+ lang_id = filename[0:len(filename) - len(suffix)]
|
|
+ prefix = 'emoji-'
|
|
+ if not lang_id.startswith(prefix):
|
|
+ continue
|
|
+ lang_id = lang_id[len(prefix):]
|
|
+ lang = LanguageString(lang_id, IBus.get_language_name(lang_id))
|
|
+ self.__lang_list.append(lang)
|
|
+ if len(self.__lang_list) == 0:
|
|
+ print("Not found dicts in %s" % dictdir, file=sys.stderr)
|
|
+ lang = LanguageString('en', IBus.get_language_name('en'))
|
|
+ self.__lang_list.append(lang)
|
|
+ return
|
|
+
|
|
+ def cmp_lang(a, b):
|
|
+ label_a = a.trans + a.id
|
|
+ label_b = b.trans + b.id
|
|
+ return (label_a > label_b) - (label_a < label_b)
|
|
+
|
|
+ self.__lang_list.sort(key = functools.cmp_to_key(cmp_lang))
|
|
+
|
|
+ loc = locale.getlocale()[0]
|
|
+ # None on C locale
|
|
+ if loc == None or loc == 'C':
|
|
+ loc = 'en_US'
|
|
+ index = 0
|
|
+ for lang in self.__lang_list:
|
|
+ # move current language to the first place
|
|
+ if lang.trans == IBus.get_language_name(loc):
|
|
+ self.__lang_list.remove(lang)
|
|
+ self.__lang_list.insert(index, lang)
|
|
+ index += 1
|
|
+
|
|
+ for lang in self.__lang_list:
|
|
+ # move English to the second place
|
|
+ if lang.trans == IBus.get_language_name('en'):
|
|
+ self.__lang_list.remove(lang)
|
|
+ self.__lang_list.insert(index, lang)
|
|
+ index += 1
|
|
+
|
|
+
|
|
+ def __list_filter(self, row, data):
|
|
+ if row.id == self.__id:
|
|
+ self.__list.select_row(row)
|
|
+ if row == self.__more_row:
|
|
+ return not self.__showing_extra
|
|
+ if not self.__showing_extra and row.is_extra:
|
|
+ return False
|
|
+ return True
|
|
+
|
|
+
|
|
+ def __row_activated(self, box, row):
|
|
+ if row == self.__more_row:
|
|
+ self.__show_more()
|
|
+ return
|
|
+ self.__id = row.id
|
|
+
|
|
+
|
|
+ def __padded_label_new(self, text, icon, alignment, direction):
|
|
+ hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL)
|
|
+
|
|
+ if direction == ROW_TRAVEL_DIRECTION_BACKWARD:
|
|
+ rtl = (Gtk.Widget.get_default_direction() == \
|
|
+ Gtk.TextDirection.RTL)
|
|
+ if rtl:
|
|
+ arrow = Gtk.Image.new_from_icon_name(
|
|
+ 'go-previous-rtl-symbolic', Gtk.IconSize.MENU)
|
|
+ else:
|
|
+ arrow = Gtk.Image.new_from_icon_name(
|
|
+ 'go-previous-symbolic', Gtk.IconSize.MENU)
|
|
+ hbox.pack_start(arrow, False, True, 0)
|
|
+
|
|
+ if icon != None:
|
|
+ pixbuf = load_icon(icon, Gtk.IconSize.LARGE_TOOLBAR)
|
|
+ image = Gtk.Image(pixbuf = pixbuf)
|
|
+ hbox.pack_start(image, False, True, 0)
|
|
+
|
|
+ label = Gtk.Label(label = text)
|
|
+ label.set_halign(alignment)
|
|
+ label.set_valign(Gtk.Align.CENTER)
|
|
+ label.set_margin_left(20)
|
|
+ label.set_margin_right(20)
|
|
+ label.set_margin_top(6)
|
|
+ label.set_margin_bottom(6)
|
|
+ hbox.pack_start(label, True, True, 0)
|
|
+ return hbox
|
|
+
|
|
+
|
|
+ def __list_box_row_new(self, lang):
|
|
+ row = Gtk.ListBoxRow()
|
|
+ row.trans = lang.trans
|
|
+ row.id = lang.id
|
|
+ row.is_extra = False
|
|
+ return row
|
|
+
|
|
+
|
|
+ def __lang_row_new(self, lang, prev_lang):
|
|
+ row = self.__list_box_row_new(lang)
|
|
+ label = lang.trans
|
|
+ if lang.id == self.__id:
|
|
+ row.is_extra = False
|
|
+ elif prev_lang != None and label == prev_lang.trans:
|
|
+ label = "%s (%s)" % (lang.trans, lang.id)
|
|
+ row.is_extra = True
|
|
+ elif not self.__showing_extra and \
|
|
+ lang.trans not in self.__initial_languages:
|
|
+ row.is_extra = True
|
|
+ widget = self.__padded_label_new(label,
|
|
+ None,
|
|
+ Gtk.Align.CENTER,
|
|
+ ROW_TRAVEL_DIRECTION_NONE)
|
|
+ row.add(widget)
|
|
+ return row
|
|
+
|
|
+
|
|
+ def __more_row_new(self):
|
|
+ row = Gtk.ListBoxRow()
|
|
+ row.id = None
|
|
+ hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL)
|
|
+ row.add(hbox)
|
|
+ row.set_tooltip_text(_("More…"))
|
|
+ arrow = Gtk.Image.new_from_icon_name('view-more-symbolic',
|
|
+ Gtk.IconSize.MENU)
|
|
+ arrow.set_margin_left(20)
|
|
+ arrow.set_margin_right(20)
|
|
+ arrow.set_margin_top(6)
|
|
+ arrow.set_margin_bottom(6)
|
|
+ arrow.set_halign(Gtk.Align.CENTER)
|
|
+ arrow.set_valign(Gtk.Align.CENTER)
|
|
+ hbox.pack_start(arrow, True, True, 0)
|
|
+ return row
|
|
+
|
|
+
|
|
+ def __set_fixed_size(self):
|
|
+ if self.__scrolled.get_policy()[0] == Gtk.PolicyType.AUTOMATIC:
|
|
+ return
|
|
+ (width, height) = self.get_size()
|
|
+ self.set_size_request(width, height)
|
|
+ self.__scrolled.set_policy(Gtk.PolicyType.AUTOMATIC,
|
|
+ Gtk.PolicyType.AUTOMATIC)
|
|
+
|
|
+
|
|
+ def __remove_all_children(self):
|
|
+ for l in self.__list.get_children():
|
|
+ self.__list.remove(l)
|
|
+
|
|
+
|
|
+ def __show_lang_rows(self):
|
|
+ self.__remove_all_children()
|
|
+ prev_lang = None
|
|
+ for lang in self.__lang_list:
|
|
+ row = self.__lang_row_new(lang, prev_lang)
|
|
+ self.__list.add(row)
|
|
+ prev_lang = lang
|
|
+ self.__list.add(self.__more_row)
|
|
+ self.__list.show_all()
|
|
+ self.__adjustment.set_value(self.__adjustment.get_lower())
|
|
+ self.__list.invalidate_filter()
|
|
+ self.__list.set_selection_mode(Gtk.SelectionMode.SINGLE)
|
|
+
|
|
+
|
|
+ def __show_more(self):
|
|
+ self.__set_fixed_size()
|
|
+ self.__showing_extra = True
|
|
+ self.__list.invalidate_filter()
|
|
+
|
|
+
|
|
+ def get_selected_lang(self):
|
|
+ return self.__id
|
|
+
|
|
+
|
|
+class EmojiLangButton(Gtk.Button):
|
|
+ __gtype_name__ = 'EmojiLangButton'
|
|
+ __gproperties__ = {
|
|
+ 'lang' : (
|
|
+ str,
|
|
+ 'lang',
|
|
+ 'lang for emojo-*.dict',
|
|
+ 'en',
|
|
+ GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE)
|
|
+ }
|
|
+
|
|
+
|
|
+ def __init__(self):
|
|
+ super(EmojiLangButton, self).__init__()
|
|
+ self.__lang = ''
|
|
+
|
|
+
|
|
+ def do_get_property(self, prop):
|
|
+ if prop.name == 'lang':
|
|
+ return self.__lang
|
|
+ else:
|
|
+ raise AttributeError('unknown property %s' % prop.name)
|
|
+
|
|
+
|
|
+ def do_set_property(self, prop, value):
|
|
+ if prop.name == 'lang':
|
|
+ self.set_lang(value)
|
|
+ else:
|
|
+ raise AttributeError('unknown property %s' % prop.name)
|
|
+
|
|
+
|
|
+ def do_clicked(self):
|
|
+ dialog = EmojiLangChooser(id = self.__lang,
|
|
+ transient_for = self.get_toplevel())
|
|
+ id = dialog.run()
|
|
+ if id != Gtk.ResponseType.APPLY:
|
|
+ dialog.destroy()
|
|
+ return
|
|
+ self.set_lang(dialog.get_selected_lang())
|
|
+ dialog.destroy()
|
|
+
|
|
+
|
|
+ def set_lang(self, lang):
|
|
+ self.__lang = lang
|
|
+ self.notify("lang")
|
|
+ self.set_label(IBus.get_language_name(lang))
|
|
+
|
|
+
|
|
+ def get_lang(self, lang):
|
|
+ return self.__lang
|
|
+
|
|
+
|
|
+GObject.type_register(EmojiLangButton)
|
|
+
|
|
+
|
|
+if __name__ == "__main__":
|
|
+ dialog = EmojiLangChooser()
|
|
+ id = dialog.run()
|
|
+ if id != Gtk.ResponseType.APPLY:
|
|
+ dialog.destroy()
|
|
+ import sys
|
|
+ sys.exit(0)
|
|
+ print("Selected language:", dialog.get_selected_lang())
|
|
diff --git a/setup/main.py b/setup/main.py
|
|
index 09b0ebd..7839cea 100644
|
|
--- a/setup/main.py
|
|
+++ b/setup/main.py
|
|
@@ -51,6 +51,7 @@ from os import path
|
|
import i18n
|
|
import keyboardshortcut
|
|
import locale
|
|
+from emojilang import EmojiLangButton
|
|
from enginecombobox import EngineComboBox
|
|
from enginedialog import EngineDialog
|
|
from enginetreeview import EngineTreeView
|
|
@@ -92,6 +93,8 @@ class Setup(object):
|
|
schema = "org.freedesktop.ibus.general.hotkey");
|
|
self.__settings_panel = Gio.Settings(
|
|
schema = "org.freedesktop.ibus.panel");
|
|
+ self.__settings_emoji = Gio.Settings(
|
|
+ schema = "org.freedesktop.ibus.panel.emoji");
|
|
|
|
# IBus.Bus() calls ibus_bus_new().
|
|
# Gtk.Builder().add_from_file() also calls ibus_bus_new_async()
|
|
@@ -122,7 +125,10 @@ class Setup(object):
|
|
self.__init_hotkey(name, label)
|
|
|
|
def __init_hotkey(self, name, label, comment=None):
|
|
- shortcuts = self.__settings_hotkey.get_strv(name)
|
|
+ if name == 'emoji':
|
|
+ shortcuts = self.__settings_emoji.get_strv('hotkey')
|
|
+ else:
|
|
+ shortcuts = self.__settings_hotkey.get_strv(name)
|
|
button = self.__builder.get_object("button_%s" % label)
|
|
entry = self.__builder.get_object("entry_%s" % label)
|
|
entry.set_text("; ".join(shortcuts))
|
|
@@ -130,8 +136,12 @@ class Setup(object):
|
|
if comment != None:
|
|
tooltip += "\n" + comment
|
|
entry.set_tooltip_text(tooltip)
|
|
- button.connect("clicked", self.__shortcut_button_clicked_cb,
|
|
- name, "general/hotkey", label, entry)
|
|
+ if name == 'emoji':
|
|
+ button.connect("clicked", self.__shortcut_button_clicked_cb,
|
|
+ 'hotkey', 'panel/' + name, label, entry)
|
|
+ else:
|
|
+ button.connect("clicked", self.__shortcut_button_clicked_cb,
|
|
+ name, "general/hotkey", label, entry)
|
|
|
|
def __init_panel(self):
|
|
# lookup table orientation
|
|
@@ -169,21 +179,27 @@ class Setup(object):
|
|
|
|
self.__fontbutton_custom_font = self.__builder.get_object(
|
|
"fontbutton_custom_font")
|
|
- self.__fontbutton_emoji_font = self.__builder.get_object(
|
|
- "fontbutton_emoji_font")
|
|
- self.__fontbutton_emoji_font.set_preview_text("🙂🍎🚃💓📧⚽🐳");
|
|
self.__settings_panel.bind('custom-font',
|
|
self.__fontbutton_custom_font,
|
|
'font-name',
|
|
Gio.SettingsBindFlags.DEFAULT)
|
|
- self.__settings_panel.bind('emoji-font',
|
|
- self.__fontbutton_emoji_font,
|
|
- 'font-name',
|
|
- Gio.SettingsBindFlags.DEFAULT)
|
|
self.__settings_panel.bind('use-custom-font',
|
|
self.__fontbutton_custom_font,
|
|
'sensitive',
|
|
Gio.SettingsBindFlags.GET)
|
|
+ self.__fontbutton_emoji_font = self.__builder.get_object(
|
|
+ 'fontbutton_emoji_font')
|
|
+ self.__fontbutton_emoji_font.set_preview_text('🙂🍎🚃💓📧⚽🐳');
|
|
+ self.__settings_emoji.bind('font',
|
|
+ self.__fontbutton_emoji_font,
|
|
+ 'font-name',
|
|
+ Gio.SettingsBindFlags.DEFAULT)
|
|
+ self.__button_emoji_lang = self.__builder.get_object(
|
|
+ 'button_emoji_lang')
|
|
+ self.__settings_emoji.bind('lang',
|
|
+ self.__button_emoji_lang,
|
|
+ 'lang',
|
|
+ Gio.SettingsBindFlags.DEFAULT)
|
|
|
|
# show icon on system tray
|
|
self.__checkbutton_show_icon_on_systray = self.__builder.get_object(
|
|
@@ -458,7 +474,10 @@ class Setup(object):
|
|
dialog.destroy()
|
|
if id != Gtk.ResponseType.OK:
|
|
return
|
|
- self.__settings_hotkey.set_strv(name, shortcuts)
|
|
+ if section == 'panel/emoji':
|
|
+ self.__settings_emoji.set_strv(name, shortcuts)
|
|
+ else:
|
|
+ self.__settings_hotkey.set_strv(name, shortcuts)
|
|
text = "; ".join(shortcuts)
|
|
entry.set_text(text)
|
|
tooltip = "\n".join(shortcuts)
|
|
diff --git a/setup/setup.ui b/setup/setup.ui
|
|
index d5ee392..4ef3423 100644
|
|
--- a/setup/setup.ui
|
|
+++ b/setup/setup.ui
|
|
@@ -661,38 +661,11 @@
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkBox" id="fontbutton_box">
|
|
- <property name="orientation">vertical</property>
|
|
+ <object class="GtkFontButton" id="fontbutton_custom_font">
|
|
<property name="visible">True</property>
|
|
- <property name="can_focus">False</property>
|
|
- <child>
|
|
- <object class="GtkFontButton" id="fontbutton_custom_font">
|
|
- <property name="use_action_appearance">False</property>
|
|
- <property name="visible">True</property>
|
|
- <property name="can_focus">True</property>
|
|
- <property name="receives_default">True</property>
|
|
- <property name="use_action_appearance">False</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
- <property name="position">0</property>
|
|
- </packing>
|
|
- </child>
|
|
- <child>
|
|
- <object class="GtkFontButton" id="fontbutton_emoji_font">
|
|
- <property name="use_action_appearance">False</property>
|
|
- <property name="visible">True</property>
|
|
- <property name="can_focus">True</property>
|
|
- <property name="receives_default">True</property>
|
|
- <property name="use_action_appearance">False</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
- <property name="position">1</property>
|
|
- </packing>
|
|
- </child>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="receives_default">True</property>
|
|
+ <property name="use_action_appearance">False</property>
|
|
</object>
|
|
<packing>
|
|
<property name="left_attach">1</property>
|
|
@@ -702,6 +675,68 @@
|
|
<property name="y_options">GTK_FILL</property>
|
|
</packing>
|
|
</child>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="label_emoji_font">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="tooltip_text" translatable="yes">Set a font of emoji candidates on the emoji dialog</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="label" translatable="yes">Emoji font:</property>
|
|
+ <property name="justify">right</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="top_attach">7</property>
|
|
+ <property name="bottom_attach">8</property>
|
|
+ <property name="x_options">GTK_FILL</property>
|
|
+ <property name="y_options">GTK_FILL</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkFontButton" id="fontbutton_emoji_font">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="receives_default">True</property>
|
|
+ <property name="use_action_appearance">False</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="right_attach">2</property>
|
|
+ <property name="top_attach">7</property>
|
|
+ <property name="bottom_attach">8</property>
|
|
+ <property name="y_options">GTK_FILL</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="label_emoji_lang">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="tooltip_text" translatable="yes">Set a language of emoji annotations on the emoji dialog</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="label" translatable="yes">Emoji annotation language:</property>
|
|
+ <property name="justify">right</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="top_attach">8</property>
|
|
+ <property name="bottom_attach">9</property>
|
|
+ <property name="x_options">GTK_FILL</property>
|
|
+ <property name="y_options">GTK_FILL</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="EmojiLangButton" id="button_emoji_lang">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="receives_default">True</property>
|
|
+ <property name="use_action_appearance">False</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="right_attach">2</property>
|
|
+ <property name="top_attach">8</property>
|
|
+ <property name="bottom_attach">9</property>
|
|
+ <property name="y_options">GTK_FILL</property>
|
|
+ </packing>
|
|
+ </child>
|
|
</object>
|
|
</child>
|
|
<child type="label">
|
|
diff --git a/tools/main.vala b/tools/main.vala
|
|
index fd9fd0e..2bf1dc7 100644
|
|
--- a/tools/main.vala
|
|
+++ b/tools/main.vala
|
|
@@ -31,6 +31,8 @@ bool name_only = false;
|
|
/* system() exists as a public API. */
|
|
bool is_system = false;
|
|
string cache_file = null;
|
|
+string emoji_font = null;
|
|
+string annotation_lang = null;
|
|
|
|
class EngineList {
|
|
public IBus.EngineDesc[] data = {};
|
|
@@ -342,12 +344,40 @@ private void run_dialog(IBus.Emojier emojier) {
|
|
}
|
|
|
|
int emoji_dialog(string[] argv) {
|
|
+ const OptionEntry[] options = {
|
|
+ { "font", 0, 0, OptionArg.STRING, out emoji_font,
|
|
+ N_("FONT for emoji chracters on emoji dialog."), "FONT" },
|
|
+ { "lang", 0, 0, OptionArg.STRING, out annotation_lang,
|
|
+ N_("LANG for annotations on emoji dialog. E.g. \"en\""), "LANG" },
|
|
+ { null }
|
|
+ };
|
|
+
|
|
+ var option = new OptionContext();
|
|
+ option.add_main_entries(options, Config.GETTEXT_PACKAGE);
|
|
+
|
|
+ try {
|
|
+ option.parse(ref argv);
|
|
+ } catch (OptionError e) {
|
|
+ stderr.printf("%s\n", e.message);
|
|
+ return Posix.EXIT_FAILURE;
|
|
+ }
|
|
+
|
|
Gtk.init(ref argv);
|
|
- GLib.Settings settings_panel =
|
|
- new GLib.Settings("org.freedesktop.ibus.panel");
|
|
- string emoji_font = settings_panel.get_string("emoji-font");
|
|
+ if (emoji_font == null) {
|
|
+ GLib.Settings settings_emoji =
|
|
+ new GLib.Settings("org.freedesktop.ibus.panel.emoji");
|
|
+ emoji_font = settings_emoji.get_string("font");
|
|
+ }
|
|
+ if (annotation_lang == null) {
|
|
+ GLib.Settings settings_emoji =
|
|
+ new GLib.Settings("org.freedesktop.ibus.panel.emoji");
|
|
+ annotation_lang = settings_emoji.get_string("lang");
|
|
+ }
|
|
IBus.Emojier emojier = new IBus.Emojier();
|
|
- emojier.set_emoji_font(emoji_font);
|
|
+ if (emoji_font != null && emoji_font != "")
|
|
+ emojier.set_emoji_font(emoji_font);
|
|
+ if (annotation_lang != null && annotation_lang != "")
|
|
+ emojier.set_annotation_lang(annotation_lang);
|
|
if (emojier.has_loaded_emoji_dict()) {
|
|
run_dialog(emojier);
|
|
} else {
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index b1dc50c..20c1378 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -42,14 +42,11 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
private class EBoxRow : Gtk.ListBoxRow {
|
|
- public EBoxRow(string text,
|
|
- string id="") {
|
|
+ public EBoxRow(string text) {
|
|
this.text = text;
|
|
- this.id = id;
|
|
}
|
|
|
|
public string text { get; set; }
|
|
- public string id { get; set; }
|
|
}
|
|
private class EScrolledWindow : Gtk.ScrolledWindow {
|
|
public EScrolledWindow(Gtk.Adjustment? hadjustment=null,
|
|
@@ -132,6 +129,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
private class ETitleLabel : Gtk.Box {
|
|
+ private Gtk.Label m_label;
|
|
private Gtk.Button m_close_button;
|
|
private ulong m_close_handler;
|
|
|
|
@@ -142,14 +140,14 @@ class IBusEmojier : Gtk.Window {
|
|
orientation : Gtk.Orientation.HORIZONTAL,
|
|
spacing : 0
|
|
);
|
|
- Gtk.Label label = new Gtk.Label(text);
|
|
- label.set_halign(align);
|
|
- label.set_valign(align);
|
|
- label.set_margin_start(20);
|
|
- label.set_margin_end(20);
|
|
- label.set_margin_top(6);
|
|
- label.set_margin_bottom(6);
|
|
- pack_start(label, true, true, 0);
|
|
+ m_label = new Gtk.Label(text);
|
|
+ m_label.set_halign(align);
|
|
+ m_label.set_valign(align);
|
|
+ m_label.set_margin_start(20);
|
|
+ m_label.set_margin_end(20);
|
|
+ m_label.set_margin_top(6);
|
|
+ m_label.set_margin_bottom(6);
|
|
+ pack_start(m_label, true, true, 0);
|
|
IconWidget icon = new IconWidget("window-close", Gtk.IconSize.MENU);
|
|
m_close_button = new Gtk.Button();
|
|
m_close_button.add(icon);
|
|
@@ -170,6 +168,9 @@ class IBusEmojier : Gtk.Window {
|
|
m_close_handler = 0;
|
|
}
|
|
}
|
|
+ public void set_label(string str) {
|
|
+ m_label.set_label(str);
|
|
+ }
|
|
}
|
|
|
|
private enum TravelDirection {
|
|
@@ -177,11 +178,6 @@ class IBusEmojier : Gtk.Window {
|
|
BACKWARD,
|
|
}
|
|
|
|
- private enum CategoryType {
|
|
- EMOJI,
|
|
- LANG,
|
|
- }
|
|
-
|
|
private const uint EMOJI_GRID_PAGE = 10;
|
|
private ThemedRGBA m_rgba;
|
|
private Gtk.Box m_vbox;
|
|
@@ -190,14 +186,11 @@ class IBusEmojier : Gtk.Window {
|
|
private string? m_backward;
|
|
private EScrolledWindow? m_scrolled_window = null;
|
|
private EListBox m_list_box;
|
|
- private CategoryType m_current_category_type = CategoryType.EMOJI;
|
|
private bool m_is_running = false;
|
|
private string m_input_context_path = "";
|
|
private GLib.MainLoop? m_loop;
|
|
private string? m_result;
|
|
- private GLib.SList<string> m_lang_list;
|
|
private string m_current_lang_id = "en";
|
|
- private string m_current_language = "English";
|
|
private string? m_unicode_point = null;
|
|
private bool m_candidate_panel_is_visible;
|
|
private GLib.HashTable<string, GLib.SList>?
|
|
@@ -215,6 +208,7 @@ class IBusEmojier : Gtk.Window {
|
|
private bool m_enter_notify_enable = true;
|
|
private uint m_entry_notify_show_id;
|
|
private uint m_entry_notify_disable_id;
|
|
+ private uint m_reload_emoji_dict_id;
|
|
|
|
public signal void candidate_clicked(uint index, uint button, uint state);
|
|
public signal void loaded_emoji_dict();
|
|
@@ -323,50 +317,13 @@ class IBusEmojier : Gtk.Window {
|
|
hide_candidate_panel();
|
|
});
|
|
|
|
- GLib.Idle.add(() => {
|
|
- m_lang_list = read_lang_list();
|
|
+ m_reload_emoji_dict_id = GLib.Idle.add(() => {
|
|
reload_emoji_dict();
|
|
+ m_reload_emoji_dict_id = 0;
|
|
return false;
|
|
});
|
|
}
|
|
|
|
- private GLib.SList<string> read_lang_list() {
|
|
- GLib.SList<string> lang_list = new GLib.SList<string>();
|
|
- const string dict_path = Config.PKGDATADIR + "/dicts";
|
|
- GLib.Dir dir = null;
|
|
- try {
|
|
- dir = GLib.Dir.open(dict_path);
|
|
- } catch (GLib.FileError e) {
|
|
- warning("Error loading %s: %s", dict_path, e.message);
|
|
- return lang_list;
|
|
- }
|
|
- string name;
|
|
- while ((name = dir.read_name()) != null) {
|
|
- const string dict_suffix = ".dict";
|
|
- const string dict_prefix = "emoji-";
|
|
- if (name.has_suffix(dict_suffix)) {
|
|
- name = name[0:name.length - dict_suffix.length];
|
|
- if (name.has_prefix(dict_prefix)) {
|
|
- name = name[dict_prefix.length:name.length];
|
|
- lang_list.append(name);
|
|
- } else {
|
|
- warning("Need %s prefix in the filename: %s/%s%s",
|
|
- dict_prefix, dict_path, name, dict_suffix);
|
|
- }
|
|
- } else {
|
|
- warning("Need %s extention in the filename: %s/%s",
|
|
- dict_suffix, dict_path, name);
|
|
- }
|
|
- }
|
|
- lang_list.sort((a, b) => {
|
|
- string a_lang = IBus.get_language_name(a);
|
|
- string b_lang = IBus.get_language_name(b);
|
|
- a_lang = "%s (%s)".printf(a_lang, a);
|
|
- b_lang = "%s (%s)".printf(b_lang, b);
|
|
- return GLib.strcmp(a_lang, b_lang);
|
|
- });
|
|
- return lang_list;
|
|
- }
|
|
|
|
private void reload_emoji_dict() {
|
|
init_emoji_dict();
|
|
@@ -382,6 +339,7 @@ class IBusEmojier : Gtk.Window {
|
|
loaded_emoji_dict();
|
|
}
|
|
|
|
+
|
|
private void init_emoji_dict() {
|
|
m_annotation_to_emojis_dict =
|
|
new GLib.HashTable<string, GLib.SList>(GLib.str_hash,
|
|
@@ -394,6 +352,7 @@ class IBusEmojier : Gtk.Window {
|
|
GLib.str_equal);
|
|
}
|
|
|
|
+
|
|
private void make_emoji_dict(string lang) {
|
|
GLib.SList<IBus.EmojiData> emoji_list = IBus.EmojiData.load(
|
|
Config.PKGDATADIR + "/dicts/emoji-" + lang + ".dict");
|
|
@@ -412,6 +371,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+
|
|
private void update_annotation_to_emojis_dict(IBus.EmojiData data) {
|
|
string emoji = data.get_emoji();
|
|
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
@@ -432,6 +392,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+
|
|
private string utf8_down(string str) {
|
|
GLib.StringBuilder buff = new GLib.StringBuilder();
|
|
int length = str.char_count();
|
|
@@ -442,6 +403,7 @@ class IBusEmojier : Gtk.Window {
|
|
return buff.str;
|
|
}
|
|
|
|
+
|
|
private string utf8_title(string str) {
|
|
StringBuilder buff = new StringBuilder();
|
|
int length = str.char_count();
|
|
@@ -456,6 +418,7 @@ class IBusEmojier : Gtk.Window {
|
|
return buff.str;
|
|
}
|
|
|
|
+
|
|
private void update_emoji_to_data_dict(IBus.EmojiData data,
|
|
string lang) {
|
|
string emoji = data.get_emoji();
|
|
@@ -464,10 +427,11 @@ class IBusEmojier : Gtk.Window {
|
|
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
var words = description.split(" ");
|
|
// If the description has less than 3 words, add it to annotations
|
|
+ // FIXME: How to cast GLib.CompareFunc<string> to strcmp?
|
|
if (words.length < 3 &&
|
|
annotations.find_custom(
|
|
description,
|
|
- (GLib.CompareFunc<string>)GLib.strcmp) == null) {
|
|
+ GLib.strcmp) == null) {
|
|
annotations.append(description);
|
|
data.set_annotations(annotations.copy_deep(GLib.strdup));
|
|
}
|
|
@@ -485,18 +449,20 @@ class IBusEmojier : Gtk.Window {
|
|
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
var words = trans_description.split(" ");
|
|
// If the description has less than 3 words, add it to annotations
|
|
+ // FIXME: How to cast GLib.CompareFunc<string> to strcmp?
|
|
if (words.length < 3 &&
|
|
annotations.find_custom(
|
|
trans_description,
|
|
- (GLib.CompareFunc<string>)GLib.strcmp) == null) {
|
|
+ GLib.strcmp) == null) {
|
|
annotations.append(trans_description);
|
|
}
|
|
unowned GLib.SList<string> en_annotations
|
|
= en_data.get_annotations();
|
|
foreach (string annotation in en_annotations) {
|
|
+ // FIXME: How to cast GLib.CompareFunc<string> to strcmp?
|
|
if (annotations.find_custom(
|
|
annotation,
|
|
- (GLib.CompareFunc<string>)GLib.strcmp) == null) {
|
|
+ GLib.strcmp) == null) {
|
|
annotations.append(annotation.dup());
|
|
}
|
|
}
|
|
@@ -504,6 +470,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+
|
|
private void update_category_to_emojis_dict(IBus.EmojiData data,
|
|
string lang) {
|
|
string emoji = data.get_emoji();
|
|
@@ -525,29 +492,12 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+
|
|
private void set_fixed_size() {
|
|
- if (!m_candidate_panel_is_visible &&
|
|
- m_current_category_type == CategoryType.LANG) {
|
|
- Gtk.PolicyType vpolicy;
|
|
- m_scrolled_window.get_policy(null, out vpolicy);
|
|
- if (vpolicy == Gtk.PolicyType.AUTOMATIC)
|
|
- return;
|
|
- int width, height;
|
|
- get_size(out width, out height);
|
|
- set_size_request(width, height);
|
|
- if (m_scrolled_window != null) {
|
|
- m_scrolled_window.set_policy(Gtk.PolicyType.NEVER,
|
|
- Gtk.PolicyType.AUTOMATIC);
|
|
- }
|
|
- } else {
|
|
- resize(20, 1);
|
|
- if (m_scrolled_window != null) {
|
|
- m_scrolled_window.set_policy(Gtk.PolicyType.NEVER,
|
|
- Gtk.PolicyType.NEVER);
|
|
- }
|
|
- }
|
|
+ resize(20, 1);
|
|
}
|
|
|
|
+
|
|
private void remove_all_children() {
|
|
foreach (Gtk.Widget w in m_vbox.get_children()) {
|
|
if (w.name == "IBusEmojierEntry" ||
|
|
@@ -558,51 +508,16 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
- private void activated_language(EBoxRow row) {
|
|
- m_category_active_index = 0;
|
|
- if (m_current_lang_id != row.id) {
|
|
- m_current_lang_id = row.id;
|
|
- m_current_language = row.text;
|
|
- reload_emoji_dict();
|
|
- }
|
|
- m_current_category_type = CategoryType.EMOJI;
|
|
- show_category_list();
|
|
- }
|
|
|
|
private void show_category_list() {
|
|
remove_all_children();
|
|
m_scrolled_window = new EScrolledWindow();
|
|
set_fixed_size();
|
|
- EPaddedLabel label;
|
|
- if (m_current_category_type == CategoryType.EMOJI) {
|
|
- label = new EPaddedLabel(m_current_language, Gtk.Align.CENTER);
|
|
- } else if (m_current_category_type == CategoryType.LANG) {
|
|
- label = new EPaddedLabel(m_current_language,
|
|
- Gtk.Align.CENTER,
|
|
- TravelDirection.BACKWARD);
|
|
- } else {
|
|
- label = new EPaddedLabel("", Gtk.Align.CENTER);
|
|
- }
|
|
- Gtk.Button button = new Gtk.Button();
|
|
- button.add(label);
|
|
- m_vbox.add(button);
|
|
- button.show_all();
|
|
- if (m_current_category_type == CategoryType.EMOJI) {
|
|
- button.button_press_event.connect((e) => {
|
|
- m_category_active_index = 0;
|
|
- m_current_category_type = CategoryType.LANG;
|
|
- show_category_list();
|
|
- return true;
|
|
- });
|
|
- } else if (m_current_category_type == CategoryType.LANG) {
|
|
- button.button_press_event.connect((e) => {
|
|
- m_category_active_index = 0;
|
|
- m_current_category_type = CategoryType.EMOJI;
|
|
- show_category_list();
|
|
- return true;
|
|
- });
|
|
- }
|
|
|
|
+ string language = "%s (%s)".printf(
|
|
+ _("Emoji Dialog"),
|
|
+ IBus.get_language_name(m_current_lang_id));
|
|
+ m_title.set_label(language);
|
|
m_vbox.add(m_scrolled_window);
|
|
Gtk.Viewport viewport = new Gtk.Viewport(null, null);
|
|
m_scrolled_window.add(viewport);
|
|
@@ -611,59 +526,38 @@ class IBusEmojier : Gtk.Window {
|
|
viewport.add(m_list_box);
|
|
Gtk.Adjustment adjustment = m_scrolled_window.get_vadjustment();
|
|
m_list_box.set_adjustment(adjustment);
|
|
- if (m_current_category_type == CategoryType.EMOJI) {
|
|
- m_list_box.row_activated.connect((box, gtkrow) => {
|
|
- m_category_active_index = 0;
|
|
- EBoxRow row = gtkrow as EBoxRow;
|
|
- show_emoji_for_category(row);
|
|
- });
|
|
+ m_list_box.row_activated.connect((box, gtkrow) => {
|
|
+ m_category_active_index = 0;
|
|
+ EBoxRow row = gtkrow as EBoxRow;
|
|
+ show_emoji_for_category(row);
|
|
+ });
|
|
|
|
- uint n = 1;
|
|
- if (m_favorites.length > 0) {
|
|
- EBoxRow row = new EBoxRow("@favorites");
|
|
- EPaddedLabel widget =
|
|
- new EPaddedLabel(_("Favorites"), Gtk.Align.CENTER);
|
|
- row.add(widget);
|
|
- m_list_box.add(row);
|
|
- if (n++ == m_category_active_index)
|
|
- m_list_box.select_row(row);
|
|
- }
|
|
- GLib.List<unowned string> categories =
|
|
- m_category_to_emojis_dict.get_keys();
|
|
- categories.sort((a, b) => {
|
|
- return GLib.strcmp(_(a), _(b));
|
|
- });
|
|
- foreach (unowned string category in categories) {
|
|
- EBoxRow row = new EBoxRow(category);
|
|
- string locale_category = _(category);
|
|
- EPaddedLabel widget =
|
|
- new EPaddedLabel(utf8_title(locale_category),
|
|
- Gtk.Align.CENTER);
|
|
- row.add(widget);
|
|
- m_list_box.add(row);
|
|
- if (n++ == m_category_active_index)
|
|
- m_list_box.select_row(row);
|
|
- }
|
|
- } else if (m_current_category_type == CategoryType.LANG) {
|
|
- m_list_box.row_activated.connect((box, gtkrow) => {
|
|
- activated_language(gtkrow as EBoxRow);
|
|
- });
|
|
- uint n = 1;
|
|
- string prev_language = null;
|
|
- foreach (unowned string id in m_lang_list) {
|
|
- string language = IBus.get_language_name(id);
|
|
- if (prev_language == language)
|
|
- language = "%s (%s)".printf(language, id);
|
|
- else
|
|
- prev_language = language;
|
|
- EBoxRow row = new EBoxRow(language, id);
|
|
- EPaddedLabel widget =
|
|
- new EPaddedLabel(language, Gtk.Align.CENTER);
|
|
- row.add(widget);
|
|
- m_list_box.add(row);
|
|
- if (n++ == m_category_active_index)
|
|
- m_list_box.select_row(row);
|
|
- }
|
|
+ uint n = 1;
|
|
+ if (m_favorites.length > 0) {
|
|
+ EBoxRow row = new EBoxRow("@favorites");
|
|
+ EPaddedLabel widget =
|
|
+ new EPaddedLabel(_("Favorites"), Gtk.Align.CENTER);
|
|
+ row.add(widget);
|
|
+ m_list_box.add(row);
|
|
+ if (n++ == m_category_active_index)
|
|
+ m_list_box.select_row(row);
|
|
+ }
|
|
+ GLib.List<unowned string> categories =
|
|
+ m_category_to_emojis_dict.get_keys();
|
|
+ // FIXME: How to cast GLib.CompareFunc<string> to strcmp?
|
|
+ categories.sort((a, b) => {
|
|
+ return GLib.strcmp(_(a), _(b));
|
|
+ });
|
|
+ foreach (unowned string category in categories) {
|
|
+ EBoxRow row = new EBoxRow(category);
|
|
+ string locale_category = _(category);
|
|
+ EPaddedLabel widget =
|
|
+ new EPaddedLabel(utf8_title(locale_category),
|
|
+ Gtk.Align.CENTER);
|
|
+ row.add(widget);
|
|
+ m_list_box.add(row);
|
|
+ if (n++ == m_category_active_index)
|
|
+ m_list_box.select_row(row);
|
|
}
|
|
|
|
m_scrolled_window.show_all();
|
|
@@ -673,6 +567,7 @@ class IBusEmojier : Gtk.Window {
|
|
m_list_box.set_selection_mode(Gtk.SelectionMode.SINGLE);
|
|
}
|
|
|
|
+
|
|
private void show_emoji_for_category(EBoxRow row) {
|
|
if (row.text == "@favorites") {
|
|
m_lookup_table.clear();
|
|
@@ -694,6 +589,7 @@ class IBusEmojier : Gtk.Window {
|
|
show_candidate_panel();
|
|
}
|
|
|
|
+
|
|
private void show_arrow_buttons() {
|
|
Gtk.Button next_button = new Gtk.Button();
|
|
next_button.clicked.connect(() => {
|
|
@@ -729,6 +625,7 @@ class IBusEmojier : Gtk.Window {
|
|
buttons_hbox.show_all();
|
|
}
|
|
|
|
+
|
|
private bool check_unicode_point(string? annotation=null) {
|
|
bool check_xdigit_only = true;
|
|
if (annotation == null) {
|
|
@@ -758,6 +655,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
|
|
+
|
|
public void update_candidate_window() {
|
|
string annotation = m_entry.get_text();
|
|
if (annotation.length == 0) {
|
|
@@ -788,6 +686,7 @@ class IBusEmojier : Gtk.Window {
|
|
show_candidate_panel();
|
|
}
|
|
|
|
+
|
|
private void show_candidate_panel() {
|
|
remove_all_children();
|
|
set_fixed_size();
|
|
@@ -848,6 +747,8 @@ class IBusEmojier : Gtk.Window {
|
|
// enter_notify_event conflicts with keyboard operations.
|
|
if (!m_enter_notify_enable)
|
|
return true;
|
|
+ if (m_lookup_table.get_cursor_pos() == index)
|
|
+ return true;
|
|
m_lookup_table.set_cursor_pos(index);
|
|
if (m_entry_notify_show_id > 0) {
|
|
GLib.Source.remove(m_entry_notify_show_id);
|
|
@@ -927,6 +828,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+
|
|
private void hide_candidate_panel() {
|
|
m_enter_notify_enable = true;
|
|
m_candidate_panel_is_visible = false;
|
|
@@ -934,6 +836,7 @@ class IBusEmojier : Gtk.Window {
|
|
show_category_list();
|
|
}
|
|
|
|
+
|
|
private bool if_in_range_of_lookup(uint keyval) {
|
|
if (!m_candidate_panel_is_visible)
|
|
return false;
|
|
@@ -957,6 +860,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
|
|
+
|
|
private void set_number_on_lookup(uint keyval) {
|
|
if (keyval == Gdk.Key.@0)
|
|
keyval = Gdk.Key.@9 + 1;
|
|
@@ -969,6 +873,7 @@ class IBusEmojier : Gtk.Window {
|
|
m_result = text.text;
|
|
}
|
|
|
|
+
|
|
private void enter_notify_disable_with_timer() {
|
|
// Enable keyboard operation and disable mouse operation.
|
|
m_enter_notify_enable = false;
|
|
@@ -982,6 +887,7 @@ class IBusEmojier : Gtk.Window {
|
|
});
|
|
}
|
|
|
|
+
|
|
private void candidate_panel_cursor_down() {
|
|
enter_notify_disable_with_timer();
|
|
uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
@@ -996,6 +902,7 @@ class IBusEmojier : Gtk.Window {
|
|
show_candidate_panel();
|
|
}
|
|
|
|
+
|
|
private void candidate_panel_cursor_up() {
|
|
enter_notify_disable_with_timer();
|
|
int ncandidates = (int)m_lookup_table.get_number_of_candidates();
|
|
@@ -1013,6 +920,7 @@ class IBusEmojier : Gtk.Window {
|
|
show_candidate_panel();
|
|
}
|
|
|
|
+
|
|
private void category_list_cursor_move(uint keyval) {
|
|
GLib.List<weak Gtk.Widget> list = m_list_box.get_children();
|
|
if (keyval == Gdk.Key.Down) {
|
|
@@ -1027,6 +935,7 @@ class IBusEmojier : Gtk.Window {
|
|
show_category_list();
|
|
}
|
|
|
|
+
|
|
private bool key_press_cursor_horizontal(uint keyval,
|
|
uint modifiers) {
|
|
assert (keyval == Gdk.Key.Left || keyval == Gdk.Key.Right);
|
|
@@ -1061,6 +970,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
|
|
+
|
|
private bool key_press_cursor_vertical(uint keyval) {
|
|
assert (keyval == Gdk.Key.Down || keyval == Gdk.Key.Up);
|
|
|
|
@@ -1075,6 +985,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
|
|
+
|
|
private bool key_press_cursor_home_end(uint keyval,
|
|
uint modifiers) {
|
|
assert (keyval == Gdk.Key.Home || keyval == Gdk.Key.End);
|
|
@@ -1107,14 +1018,11 @@ class IBusEmojier : Gtk.Window {
|
|
return false;
|
|
}
|
|
|
|
+
|
|
private bool key_press_cursor_escape() {
|
|
if (m_candidate_panel_is_visible) {
|
|
hide_candidate_panel();
|
|
return true;
|
|
- } else if (m_current_category_type == CategoryType.LANG) {
|
|
- m_current_category_type = CategoryType.EMOJI;
|
|
- show_candidate_panel();
|
|
- return true;
|
|
} else if (m_entry.get_text().length == 0) {
|
|
m_loop.quit();
|
|
hide_candidate_panel();
|
|
@@ -1124,6 +1032,7 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
|
|
+
|
|
private void entry_enter_keyval(uint keyval) {
|
|
unichar ch = IBus.keyval_to_unicode(keyval);
|
|
if (ch.iscntrl())
|
|
@@ -1145,6 +1054,7 @@ class IBusEmojier : Gtk.Window {
|
|
m_entry.set_position(pos);
|
|
}
|
|
|
|
+
|
|
public string run(Gdk.Event event,
|
|
string input_context_path) {
|
|
assert (m_loop == null);
|
|
@@ -1178,7 +1088,6 @@ class IBusEmojier : Gtk.Window {
|
|
keyboard = device.get_associated_device();
|
|
}
|
|
|
|
- m_current_category_type = CategoryType.EMOJI;
|
|
show_category_list();
|
|
m_entry.set_activates_default(true);
|
|
show_all();
|
|
@@ -1229,12 +1138,14 @@ class IBusEmojier : Gtk.Window {
|
|
return m_result;
|
|
}
|
|
|
|
+
|
|
/* override virtual functions */
|
|
public override void show() {
|
|
base.show();
|
|
set_focus_visible(true);
|
|
}
|
|
|
|
+
|
|
public override bool key_press_event(Gdk.EventKey event) {
|
|
uint keyval = event.keyval;
|
|
uint modifiers = event.state;
|
|
@@ -1263,10 +1174,7 @@ class IBusEmojier : Gtk.Window {
|
|
} else if (m_category_active_index > 0) {
|
|
Gtk.ListBoxRow gtkrow = m_list_box.get_selected_row();
|
|
EBoxRow row = gtkrow as EBoxRow;
|
|
- if (m_current_category_type == CategoryType.EMOJI)
|
|
- show_emoji_for_category(row);
|
|
- else if (m_current_category_type == CategoryType.LANG)
|
|
- activated_language(row);
|
|
+ show_emoji_for_category(row);
|
|
}
|
|
return true;
|
|
case Gdk.Key.BackSpace:
|
|
@@ -1366,27 +1274,33 @@ class IBusEmojier : Gtk.Window {
|
|
return true;
|
|
}
|
|
|
|
+
|
|
public bool is_running() {
|
|
return m_is_running;
|
|
}
|
|
|
|
+
|
|
public string get_input_context_path() {
|
|
return m_input_context_path;
|
|
}
|
|
|
|
+
|
|
public string get_selected_string() {
|
|
return m_result;
|
|
}
|
|
|
|
+
|
|
public void reset() {
|
|
m_input_context_path = "";
|
|
m_result = null;
|
|
}
|
|
|
|
+
|
|
public void set_emoji_font(string emoji_font) {
|
|
m_emoji_font = emoji_font;
|
|
}
|
|
|
|
+
|
|
public void set_favorites(string[]? unowned_favorites) {
|
|
m_favorites = {};
|
|
foreach (string favorite in unowned_favorites) {
|
|
@@ -1394,6 +1308,7 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
}
|
|
|
|
+
|
|
public bool has_loaded_emoji_dict() {
|
|
if (m_emoji_to_data_dict == null)
|
|
return false;
|
|
@@ -1402,4 +1317,20 @@ class IBusEmojier : Gtk.Window {
|
|
return false;
|
|
return true;
|
|
}
|
|
+
|
|
+
|
|
+ public void set_annotation_lang(string lang) {
|
|
+ if (m_current_lang_id == lang)
|
|
+ return;
|
|
+ if (m_reload_emoji_dict_id > 0) {
|
|
+ GLib.Source.remove(m_reload_emoji_dict_id);
|
|
+ m_reload_emoji_dict_id = 0;
|
|
+ }
|
|
+ m_current_lang_id = lang;
|
|
+ m_reload_emoji_dict_id = GLib.Idle.add(() => {
|
|
+ reload_emoji_dict();
|
|
+ m_reload_emoji_dict_id = 0;
|
|
+ return false;
|
|
+ });
|
|
+ }
|
|
}
|
|
diff --git a/ui/gtk3/ibusemojidialog.h b/ui/gtk3/ibusemojidialog.h
|
|
index c36060c..0f84a48 100644
|
|
--- a/ui/gtk3/ibusemojidialog.h
|
|
+++ b/ui/gtk3/ibusemojidialog.h
|
|
@@ -149,5 +149,16 @@ void ibus_emojier_set_favorites (IBusEmojier* self,
|
|
*/
|
|
gboolean ibus_emojier_has_loaded_emoji_dict (IBusEmojier* self);
|
|
|
|
+/**
|
|
+ * ibus_emojier_set_annotation_lang:
|
|
+ * @self: An #IBusEmojier
|
|
+ * @lang: A langauge id for emoji annotations.
|
|
+ *
|
|
+ * Set a language id for emoji annotations. #IBusEmojier will load
|
|
+ * $PKGDATADIR/dicts/emoji-@lang.dict. The default is "en".
|
|
+ */
|
|
+void ibus_emojier_set_annotation_lang (IBusEmojier* self,
|
|
+ const gchar* lang);
|
|
+
|
|
G_END_DECLS
|
|
#endif
|
|
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
|
index 0982134..7350dcc 100644
|
|
--- a/ui/gtk3/panel.vala
|
|
+++ b/ui/gtk3/panel.vala
|
|
@@ -54,6 +54,7 @@ class Panel : IBus.PanelService {
|
|
private GLib.Settings m_settings_general = null;
|
|
private GLib.Settings m_settings_hotkey = null;
|
|
private GLib.Settings m_settings_panel = null;
|
|
+ private GLib.Settings m_settings_emoji = null;
|
|
private IconType m_icon_type = IconType.STATUS_ICON;
|
|
private Indicator m_indicator;
|
|
#if INDICATOR
|
|
@@ -161,6 +162,7 @@ class Panel : IBus.PanelService {
|
|
m_settings_hotkey =
|
|
new GLib.Settings("org.freedesktop.ibus.general.hotkey");
|
|
m_settings_panel = new GLib.Settings("org.freedesktop.ibus.panel");
|
|
+ m_settings_emoji = new GLib.Settings("org.freedesktop.ibus.panel.emoji");
|
|
|
|
m_settings_general.changed["preload-engines"].connect((key) => {
|
|
update_engines(m_settings_general.get_strv(key),
|
|
@@ -193,19 +195,10 @@ class Panel : IBus.PanelService {
|
|
bind_switch_shortcut();
|
|
});
|
|
|
|
- m_settings_hotkey.changed["emoji"].connect((key) => {
|
|
- unbind_switch_shortcut(KeyEventFuncType.EMOJI_TYPING);
|
|
- bind_emoji_shortcut();
|
|
- });
|
|
-
|
|
m_settings_panel.changed["custom-font"].connect((key) => {
|
|
set_custom_font();
|
|
});
|
|
|
|
- m_settings_panel.changed["emoji-font"].connect((key) => {
|
|
- set_custom_font();
|
|
- });
|
|
-
|
|
m_settings_panel.changed["use-custom-font"].connect((key) => {
|
|
set_custom_font();
|
|
});
|
|
@@ -239,9 +232,22 @@ class Panel : IBus.PanelService {
|
|
set_property_icon_delay_time();
|
|
});
|
|
|
|
- m_settings_panel.changed["emoji-favorites"].connect((key) => {
|
|
+ m_settings_emoji.changed["hotkey"].connect((key) => {
|
|
+ unbind_switch_shortcut(KeyEventFuncType.EMOJI_TYPING);
|
|
+ bind_emoji_shortcut();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["font"].connect((key) => {
|
|
+ set_custom_font();
|
|
+ });
|
|
+
|
|
+ m_settings_emoji.changed["favorites"].connect((key) => {
|
|
set_emoji_favorites();
|
|
});
|
|
+
|
|
+ m_settings_emoji.changed["lang"].connect((key) => {
|
|
+ set_emoji_lang();
|
|
+ });
|
|
}
|
|
|
|
#if INDICATOR
|
|
@@ -398,7 +404,7 @@ class Panel : IBus.PanelService {
|
|
|
|
private void bind_emoji_shortcut() {
|
|
#if EMOJI_DICT
|
|
- string[] accelerators = m_settings_hotkey.get_strv("emoji");
|
|
+ string[] accelerators = m_settings_emoji.get_strv("hotkey");
|
|
|
|
var keybinding_manager = KeybindingManager.get_instance();
|
|
|
|
@@ -584,9 +590,9 @@ class Panel : IBus.PanelService {
|
|
return;
|
|
}
|
|
|
|
- string emoji_font = m_settings_panel.get_string("emoji-font");
|
|
+ string emoji_font = m_settings_emoji.get_string("font");
|
|
if (emoji_font == null) {
|
|
- warning("No config panel:emoji-font.");
|
|
+ warning("No config emoji:font.");
|
|
return;
|
|
}
|
|
m_emojier.set_emoji_font(emoji_font);
|
|
@@ -760,7 +766,11 @@ class Panel : IBus.PanelService {
|
|
}
|
|
|
|
private void set_emoji_favorites() {
|
|
- m_emojier.set_favorites(m_settings_panel.get_strv("emoji-favorites"));
|
|
+ m_emojier.set_favorites(m_settings_emoji.get_strv("favorites"));
|
|
+ }
|
|
+
|
|
+ private void set_emoji_lang() {
|
|
+ m_emojier.set_annotation_lang(m_settings_emoji.get_string("lang"));
|
|
}
|
|
|
|
private int compare_versions(string version1, string version2) {
|
|
@@ -877,6 +887,7 @@ class Panel : IBus.PanelService {
|
|
set_xkb_icon_rgba();
|
|
set_property_icon_delay_time();
|
|
set_emoji_favorites();
|
|
+ set_emoji_lang();
|
|
}
|
|
|
|
private void engine_contexts_insert(IBus.EngineDesc engine) {
|
|
--
|
|
2.9.3
|
|
|
|
From 164300758c70fd3a590788e038de31b6c53d458a Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Tue, 28 Mar 2017 12:15:26 +0900
|
|
Subject: [PATCH] data: Fix a typo
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/321800043
|
|
---
|
|
data/ibus.schemas.in | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
|
|
index c0bbd6f..096dd71 100644
|
|
--- a/data/ibus.schemas.in
|
|
+++ b/data/ibus.schemas.in
|
|
@@ -386,7 +386,7 @@
|
|
<short>Default language for emoji dictionary</short>
|
|
<long>Choose a default language of emoji dictionaries on
|
|
the emoji dialog. The value $lang is applied to
|
|
- /usr/share/unicode/cldr/common/annotations/$lang.xml
|
|
+ /usr/share/ibus/dicts/emoji-$lang.dict
|
|
</long>
|
|
</locale>
|
|
</schema>
|
|
--
|
|
2.9.3
|
|
|
|
From c3168d4701eb4e89094249abaa4f0f83ab24149b Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Wed, 29 Mar 2017 13:01:28 +0900
|
|
Subject: [PATCH] Fix IBusEmojiDialog_1_0_gir_LIBS for --as-needed LDFLAGS
|
|
|
|
The order gets omitted libibus-1.0.la
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/1917
|
|
|
|
Review URL: https://codereview.appspot.com/324720043
|
|
---
|
|
ui/gtk3/Makefile.am | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
|
|
index b055f67..7122ff3 100644
|
|
--- a/ui/gtk3/Makefile.am
|
|
+++ b/ui/gtk3/Makefile.am
|
|
@@ -205,7 +205,7 @@ IBusEmojiDialog_1_0_gir_SCANNERFLAGS = \
|
|
$(NULL)
|
|
IBusEmojiDialog-1.0.gir: $(libibus_emoji_dialog) Makefile
|
|
IBusEmojiDialog_1_0_gir_INCLUDES = Gtk-3.0 GLib-2.0 GObject-2.0 Gio-2.0
|
|
-IBusEmojiDialog_1_0_gir_LIBS = $(libibus) $(libibus_emoji_dialog)
|
|
+IBusEmojiDialog_1_0_gir_LIBS = $(libibus_emoji_dialog) $(libibus)
|
|
IBusEmojiDialog_1_0_gir_FILES = \
|
|
$(addprefix $(srcdir)/,$(introspection_sources)) \
|
|
$(NULL)
|
|
--
|
|
2.9.3
|
|
|
|
From 8b6f9fa531aa9d9b5d6c0184b2294d071f920d7f Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 30 Mar 2017 12:08:39 +0900
|
|
Subject: [PATCH] ui/gtk3: Enable to type multiple code points on Emojier
|
|
|
|
- Can type multiple Unicode characters with digits and Shift-space
|
|
keys. E.g. "1f468 1f468 1f466"
|
|
- Always show Unicode points of the selected emoji
|
|
- Removed a function to commit an emoji by typing a digit char since
|
|
it conflicts with digit annotations, code points but it had enabled
|
|
with single digits only so not so useful.
|
|
|
|
R=Shawn.P.Huang@gmail.com
|
|
|
|
Review URL: https://codereview.appspot.com/321820043
|
|
---
|
|
ui/gtk3/emojier.vala | 207 ++++++++++++++++++++++++---------------------------
|
|
1 file changed, 98 insertions(+), 109 deletions(-)
|
|
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 20c1378..8a2726c 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -97,12 +97,27 @@ class IBusEmojier : Gtk.Window {
|
|
set_label(text);
|
|
}
|
|
}
|
|
- private class EPaddedLabel : Gtk.Box {
|
|
+ private class EPaddedLabel : Gtk.Label {
|
|
public EPaddedLabel(string text,
|
|
- Gtk.Align align,
|
|
- TravelDirection direction=TravelDirection.NONE) {
|
|
+ Gtk.Align align) {
|
|
GLib.Object(
|
|
name : "IBusEmojierPaddedLabel",
|
|
+ halign : align,
|
|
+ valign : Gtk.Align.CENTER,
|
|
+ margin_start : 20,
|
|
+ margin_end : 20,
|
|
+ margin_top : 6,
|
|
+ margin_bottom : 6
|
|
+ );
|
|
+ set_text(text);
|
|
+ }
|
|
+ }
|
|
+ private class EPaddedLabelBox : Gtk.Box {
|
|
+ public EPaddedLabelBox(string text,
|
|
+ Gtk.Align align,
|
|
+ TravelDirection direction=TravelDirection.NONE) {
|
|
+ GLib.Object(
|
|
+ name : "IBusEmojierPaddedLabelBox",
|
|
orientation : Gtk.Orientation.HORIZONTAL,
|
|
spacing : 0
|
|
);
|
|
@@ -118,36 +133,29 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
pack_start(icon, false, true, 0);
|
|
}
|
|
- Gtk.Label label = new Gtk.Label(text);
|
|
- label.set_halign(align);
|
|
- label.set_valign(Gtk.Align.CENTER);
|
|
- label.set_margin_start(20);
|
|
- label.set_margin_end(20);
|
|
- label.set_margin_top(6);
|
|
- label.set_margin_bottom(6);
|
|
+ EPaddedLabel label = new EPaddedLabel(text, align);
|
|
pack_start(label, true, true, 0);
|
|
}
|
|
}
|
|
- private class ETitleLabel : Gtk.Box {
|
|
- private Gtk.Label m_label;
|
|
+ private class ETitleLabelBox : Gtk.Box {
|
|
+ EPaddedLabel m_lang_label;
|
|
private Gtk.Button m_close_button;
|
|
private ulong m_close_handler;
|
|
|
|
- public ETitleLabel(string text,
|
|
- Gtk.Align align) {
|
|
+ public ETitleLabelBox(string text,
|
|
+ Gtk.Align align) {
|
|
GLib.Object(
|
|
- name : "IBusEmojierTitleLabel",
|
|
+ name : "IBusEmojierTitleLabelBox",
|
|
orientation : Gtk.Orientation.HORIZONTAL,
|
|
spacing : 0
|
|
);
|
|
- m_label = new Gtk.Label(text);
|
|
- m_label.set_halign(align);
|
|
- m_label.set_valign(align);
|
|
- m_label.set_margin_start(20);
|
|
- m_label.set_margin_end(20);
|
|
- m_label.set_margin_top(6);
|
|
- m_label.set_margin_bottom(6);
|
|
- pack_start(m_label, true, true, 0);
|
|
+ EPaddedLabel label = new EPaddedLabel(text, align);
|
|
+ pack_start(label, true, true, 0);
|
|
+ Gtk.Separator separator =
|
|
+ new Gtk.Separator (Gtk.Orientation.VERTICAL);
|
|
+ pack_start(separator, false, true, 0);
|
|
+ m_lang_label = new EPaddedLabel("", align);
|
|
+ pack_start(m_lang_label, false, true, 0);
|
|
IconWidget icon = new IconWidget("window-close", Gtk.IconSize.MENU);
|
|
m_close_button = new Gtk.Button();
|
|
m_close_button.add(icon);
|
|
@@ -168,8 +176,8 @@ class IBusEmojier : Gtk.Window {
|
|
m_close_handler = 0;
|
|
}
|
|
}
|
|
- public void set_label(string str) {
|
|
- m_label.set_label(str);
|
|
+ public void set_lang_label(string str) {
|
|
+ m_lang_label.set_label(str);
|
|
}
|
|
}
|
|
|
|
@@ -181,7 +189,7 @@ class IBusEmojier : Gtk.Window {
|
|
private const uint EMOJI_GRID_PAGE = 10;
|
|
private ThemedRGBA m_rgba;
|
|
private Gtk.Box m_vbox;
|
|
- private ETitleLabel m_title;
|
|
+ private ETitleLabelBox m_title;
|
|
private EEntry m_entry;
|
|
private string? m_backward;
|
|
private EScrolledWindow? m_scrolled_window = null;
|
|
@@ -278,8 +286,8 @@ class IBusEmojier : Gtk.Window {
|
|
m_vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
|
|
add(m_vbox);
|
|
|
|
- m_title = new ETitleLabel(_("Emoji Dialog"),
|
|
- Gtk.Align.CENTER);
|
|
+ m_title = new ETitleLabelBox(_("Emoji Dialog"),
|
|
+ Gtk.Align.CENTER);
|
|
m_vbox.add(m_title);
|
|
m_entry = new EEntry();
|
|
m_entry.set_placeholder_text(_("Type annotation or choose emoji"));
|
|
@@ -419,6 +427,21 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
|
|
+ private string utf8_code_point(string str) {
|
|
+ StringBuilder buff = new StringBuilder();
|
|
+ int length = str.char_count();
|
|
+ for (int i = 0; i < length; i++) {
|
|
+ unichar ch = str.get_char(0);
|
|
+ if (i == 0)
|
|
+ buff.append("U+%04X".printf(ch));
|
|
+ else
|
|
+ buff.append(" %04X".printf(ch));
|
|
+ str = str.next_char();
|
|
+ }
|
|
+ return buff.str;
|
|
+ }
|
|
+
|
|
+
|
|
private void update_emoji_to_data_dict(IBus.EmojiData data,
|
|
string lang) {
|
|
string emoji = data.get_emoji();
|
|
@@ -501,7 +524,7 @@ class IBusEmojier : Gtk.Window {
|
|
private void remove_all_children() {
|
|
foreach (Gtk.Widget w in m_vbox.get_children()) {
|
|
if (w.name == "IBusEmojierEntry" ||
|
|
- w.name == "IBusEmojierTitleLabel") {
|
|
+ w.name == "IBusEmojierTitleLabelBox") {
|
|
continue;
|
|
}
|
|
w.destroy();
|
|
@@ -514,10 +537,9 @@ class IBusEmojier : Gtk.Window {
|
|
m_scrolled_window = new EScrolledWindow();
|
|
set_fixed_size();
|
|
|
|
- string language = "%s (%s)".printf(
|
|
- _("Emoji Dialog"),
|
|
- IBus.get_language_name(m_current_lang_id));
|
|
- m_title.set_label(language);
|
|
+ string language =
|
|
+ IBus.get_language_name(m_current_lang_id);
|
|
+ m_title.set_lang_label(language);
|
|
m_vbox.add(m_scrolled_window);
|
|
Gtk.Viewport viewport = new Gtk.Viewport(null, null);
|
|
m_scrolled_window.add(viewport);
|
|
@@ -535,8 +557,8 @@ class IBusEmojier : Gtk.Window {
|
|
uint n = 1;
|
|
if (m_favorites.length > 0) {
|
|
EBoxRow row = new EBoxRow("@favorites");
|
|
- EPaddedLabel widget =
|
|
- new EPaddedLabel(_("Favorites"), Gtk.Align.CENTER);
|
|
+ EPaddedLabelBox widget =
|
|
+ new EPaddedLabelBox(_("Favorites"), Gtk.Align.CENTER);
|
|
row.add(widget);
|
|
m_list_box.add(row);
|
|
if (n++ == m_category_active_index)
|
|
@@ -551,9 +573,9 @@ class IBusEmojier : Gtk.Window {
|
|
foreach (unowned string category in categories) {
|
|
EBoxRow row = new EBoxRow(category);
|
|
string locale_category = _(category);
|
|
- EPaddedLabel widget =
|
|
- new EPaddedLabel(utf8_title(locale_category),
|
|
- Gtk.Align.CENTER);
|
|
+ EPaddedLabelBox widget =
|
|
+ new EPaddedLabelBox(utf8_title(locale_category),
|
|
+ Gtk.Align.CENTER);
|
|
row.add(widget);
|
|
m_list_box.add(row);
|
|
if (n++ == m_category_active_index)
|
|
@@ -626,18 +648,23 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
|
|
- private bool check_unicode_point(string? annotation=null) {
|
|
- bool check_xdigit_only = true;
|
|
- if (annotation == null) {
|
|
- annotation = m_entry.get_text();
|
|
- m_unicode_point = null;
|
|
- check_xdigit_only = false;
|
|
- }
|
|
+ private bool check_unicode_point() {
|
|
+ string annotation = m_entry.get_text();
|
|
+ m_unicode_point = null;
|
|
GLib.StringBuilder buff = new GLib.StringBuilder();
|
|
+ GLib.StringBuilder retval = new GLib.StringBuilder();
|
|
for (int i = 0; i < annotation.char_count(); i++) {
|
|
unichar ch = annotation.get_char(i);
|
|
if (ch == 0)
|
|
return false;
|
|
+ if (ch.isspace()) {
|
|
+ unichar code = (unichar)buff.str.to_ulong(null, 16);
|
|
+ buff.erase();
|
|
+ if (!code.validate())
|
|
+ return false;
|
|
+ retval.append(code.to_string());
|
|
+ continue;
|
|
+ }
|
|
if (!ch.isxdigit())
|
|
return false;
|
|
buff.append_unichar(ch);
|
|
@@ -645,9 +672,8 @@ class IBusEmojier : Gtk.Window {
|
|
unichar code = (unichar)buff.str.to_ulong(null, 16);
|
|
if (!code.validate())
|
|
return false;
|
|
- if (check_xdigit_only)
|
|
- return true;
|
|
- m_unicode_point = code.to_string();
|
|
+ retval.append(code.to_string());
|
|
+ m_unicode_point = retval.str;
|
|
if (m_unicode_point == null)
|
|
return true;
|
|
IBus.Text text = new IBus.Text.from_string(m_unicode_point);
|
|
@@ -699,9 +725,10 @@ class IBusEmojier : Gtk.Window {
|
|
if (m_backward != null) {
|
|
string backward_desc =
|
|
"%s (%u / %u)".printf(m_backward, cursor, ncandidates - 1);
|
|
- EPaddedLabel label = new EPaddedLabel(backward_desc,
|
|
- Gtk.Align.CENTER,
|
|
- TravelDirection.BACKWARD);
|
|
+ EPaddedLabelBox label =
|
|
+ new EPaddedLabelBox(backward_desc,
|
|
+ Gtk.Align.CENTER,
|
|
+ TravelDirection.BACKWARD);
|
|
Gtk.Button button = new Gtk.Button();
|
|
button.add(label);
|
|
m_vbox.add(button);
|
|
@@ -776,27 +803,24 @@ class IBusEmojier : Gtk.Window {
|
|
IBus.Text candidate = m_lookup_table.get_candidate(cursor);
|
|
unowned IBus.EmojiData? data =
|
|
m_emoji_to_data_dict.lookup(candidate.text);
|
|
- if (cursor == 0 && candidate.text == m_unicode_point) {
|
|
- EPaddedLabel widget = new EPaddedLabel(
|
|
- _("Description: Unicode point U+%04X").printf(
|
|
- m_unicode_point.get_char(0)),
|
|
- Gtk.Align.START);
|
|
- m_vbox.add(widget);
|
|
- widget.show_all();
|
|
- if (data == null)
|
|
- return;
|
|
- } else if (data == null) {
|
|
+ if (data == null) {
|
|
// TODO: Provide a custom description and annotation for
|
|
// the favorite emojis.
|
|
- EPaddedLabel widget = new EPaddedLabel(
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
_("Description: %s").printf(_("None")),
|
|
Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
widget.show_all();
|
|
+ EPaddedLabelBox widget_code = new EPaddedLabelBox(
|
|
+ _("Code point: %s").printf(
|
|
+ utf8_code_point(candidate.text)),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget_code);
|
|
+ widget_code.show_all();
|
|
return;
|
|
} else {
|
|
unowned string description = data.get_description();
|
|
- EPaddedLabel widget = new EPaddedLabel(
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
_("Description: %s").printf(description),
|
|
Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
@@ -812,19 +836,26 @@ class IBusEmojier : Gtk.Window {
|
|
else
|
|
buff.append_printf(" | %s", annotation);
|
|
if (buff.str.char_count() > 30) {
|
|
- EPaddedLabel widget = new EPaddedLabel(buff.str,
|
|
- Gtk.Align.START);
|
|
+ EPaddedLabelBox widget =
|
|
+ new EPaddedLabelBox(buff.str,
|
|
+ Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
widget.show_all();
|
|
buff.erase();
|
|
}
|
|
}
|
|
if (buff.str != "") {
|
|
- EPaddedLabel widget = new EPaddedLabel(buff.str,
|
|
- Gtk.Align.START);
|
|
+ EPaddedLabelBox widget = new EPaddedLabelBox(buff.str,
|
|
+ Gtk.Align.START);
|
|
m_vbox.add(widget);
|
|
widget.show_all();
|
|
}
|
|
+ EPaddedLabelBox widget_code = new EPaddedLabelBox(
|
|
+ _("Code point: %s").printf(
|
|
+ utf8_code_point(candidate.text)),
|
|
+ Gtk.Align.START);
|
|
+ m_vbox.add(widget_code);
|
|
+ widget_code.show_all();
|
|
}
|
|
}
|
|
|
|
@@ -837,43 +868,6 @@ class IBusEmojier : Gtk.Window {
|
|
}
|
|
|
|
|
|
- private bool if_in_range_of_lookup(uint keyval) {
|
|
- if (!m_candidate_panel_is_visible)
|
|
- return false;
|
|
- StringBuilder buffer_string = new StringBuilder(m_entry.get_text());
|
|
- unichar ch = IBus.keyval_to_unicode (keyval);
|
|
- buffer_string.append_unichar(ch);
|
|
- if (check_unicode_point(buffer_string.str))
|
|
- return false;
|
|
- if (keyval < Gdk.Key.@0 || keyval > Gdk.Key.@9)
|
|
- return false;
|
|
- if (keyval == Gdk.Key.@0)
|
|
- keyval = Gdk.Key.@9 + 1;
|
|
- uint index = keyval - Gdk.Key.@1 + 1;
|
|
- uint candidates = m_lookup_table.get_number_of_candidates();
|
|
- uint cursor_pos = m_lookup_table.get_cursor_pos();
|
|
- uint page_size = m_lookup_table.get_page_size();
|
|
- if (index > uint.min(candidates - (cursor_pos / page_size) * page_size,
|
|
- page_size)) {
|
|
- return false;
|
|
- }
|
|
- return true;
|
|
- }
|
|
-
|
|
-
|
|
- private void set_number_on_lookup(uint keyval) {
|
|
- if (keyval == Gdk.Key.@0)
|
|
- keyval = Gdk.Key.@9 + 1;
|
|
- uint index = keyval - Gdk.Key.@1;
|
|
- uint cursor_pos = m_lookup_table.get_cursor_pos();
|
|
- uint cursor_in_page= m_lookup_table.get_cursor_in_page();
|
|
- uint real_index = cursor_pos - cursor_in_page + index;
|
|
- m_lookup_table.set_cursor_pos(real_index);
|
|
- IBus.Text text = m_lookup_table.get_candidate(real_index);
|
|
- m_result = text.text;
|
|
- }
|
|
-
|
|
-
|
|
private void enter_notify_disable_with_timer() {
|
|
// Enable keyboard operation and disable mouse operation.
|
|
m_enter_notify_enable = false;
|
|
@@ -1154,11 +1148,6 @@ class IBusEmojier : Gtk.Window {
|
|
* key_release_event() so that this can know if the event
|
|
* was handled by IME.
|
|
*/
|
|
- if (if_in_range_of_lookup(keyval)) {
|
|
- set_number_on_lookup(keyval);
|
|
- m_loop.quit();
|
|
- return true;
|
|
- }
|
|
switch (keyval) {
|
|
case Gdk.Key.Escape:
|
|
if (key_press_cursor_escape())
|
|
--
|
|
2.9.3
|
|
|
|
From cb0a36c254dc7a96b2a984e715f96cc2ec32e2d5 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 3 Apr 2017 12:24:27 +0900
|
|
Subject: [PATCH] src: Enable unicode_alt in EmojiOne json file
|
|
|
|
EmojiOne json file has unicode_alt property which includes
|
|
emoji modifer characters.
|
|
|
|
Review URL: https://codereview.appspot.com/316420043
|
|
---
|
|
src/emoji-parser.c | 20 +++++++++++++++++---
|
|
src/ibusemoji.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
|
|
src/ibusemoji.h | 14 ++++++++++++++
|
|
ui/gtk3/emojier.vala | 9 ++++++---
|
|
4 files changed, 81 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/src/emoji-parser.c b/src/emoji-parser.c
|
|
index f9e3470..e5dce3f 100644
|
|
--- a/src/emoji-parser.c
|
|
+++ b/src/emoji-parser.c
|
|
@@ -40,6 +40,7 @@
|
|
typedef struct _EmojiData EmojiData;
|
|
struct _EmojiData {
|
|
gchar *emoji;
|
|
+ gchar *emoji_alternates;
|
|
GSList *annotations;
|
|
gboolean is_annotation;
|
|
gchar *description;
|
|
@@ -54,6 +55,7 @@ reset_emoji_element (EmojiData *data)
|
|
g_assert (data != NULL);
|
|
|
|
g_clear_pointer (&data->emoji, g_free);
|
|
+ g_clear_pointer (&data->emoji_alternates, g_free);
|
|
g_slist_free_full (data->annotations, g_free);
|
|
data->annotations = NULL;
|
|
g_clear_pointer (&data->description, g_free);
|
|
@@ -112,6 +114,10 @@ update_emoji_list (EmojiData *data)
|
|
"category",
|
|
data->category ? data->category
|
|
: g_strdup (""),
|
|
+ "emoji-alternates",
|
|
+ data->emoji_alternates
|
|
+ ? data->emoji_alternates
|
|
+ : g_strdup (""),
|
|
NULL);
|
|
data->list = g_slist_append (data->list, emoji);
|
|
}
|
|
@@ -271,7 +277,8 @@ failed_to_parse_unicode_annotations:
|
|
|
|
static gboolean
|
|
parse_emojione_unicode (JsonNode *node,
|
|
- EmojiData *data)
|
|
+ EmojiData *data,
|
|
+ gboolean is_alternates)
|
|
{
|
|
const gchar *str, *unicode;
|
|
gchar *endptr = NULL;
|
|
@@ -305,7 +312,10 @@ parse_emojione_unicode (JsonNode *node,
|
|
endptr = NULL;
|
|
}
|
|
|
|
- data->emoji = g_string_free (emoji, FALSE);
|
|
+ if (is_alternates)
|
|
+ data->emoji_alternates = g_string_free (emoji, FALSE);
|
|
+ else
|
|
+ data->emoji = g_string_free (emoji, FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
@@ -480,7 +490,11 @@ parse_emojione_emoji_data (JsonNode *node,
|
|
EmojiData *data)
|
|
{
|
|
if (g_strcmp0 (member, "unicode") == 0)
|
|
- return parse_emojione_unicode (node, data);
|
|
+ return parse_emojione_unicode (node, data, FALSE);
|
|
+ else if (g_strcmp0 (member, "unicode_alt") == 0)
|
|
+ return parse_emojione_unicode (node, data, TRUE);
|
|
+ else if (g_strcmp0 (member, "unicode_alternates") == 0)
|
|
+ return parse_emojione_unicode (node, data, TRUE);
|
|
else if (g_strcmp0 (member, "shortname") == 0)
|
|
return parse_emojione_shortname (node, data);
|
|
else if (g_strcmp0 (member, "name") == 0)
|
|
diff --git a/src/ibusemoji.c b/src/ibusemoji.c
|
|
index c61cd70..4be092a 100644
|
|
--- a/src/ibusemoji.c
|
|
+++ b/src/ibusemoji.c
|
|
@@ -29,14 +29,15 @@
|
|
#include "ibusinternal.h"
|
|
|
|
#define IBUS_EMOJI_DATA_MAGIC "IBusEmojiData"
|
|
-#define IBUS_EMOJI_DATA_VERSION (2)
|
|
+#define IBUS_EMOJI_DATA_VERSION (3)
|
|
|
|
enum {
|
|
PROP_0 = 0,
|
|
PROP_EMOJI,
|
|
PROP_ANNOTATIONS,
|
|
PROP_DESCRIPTION,
|
|
- PROP_CATEGORY
|
|
+ PROP_CATEGORY,
|
|
+ PROP_EMOJI_ALTERNATES
|
|
};
|
|
|
|
struct _IBusEmojiDataPrivate {
|
|
@@ -44,6 +45,7 @@ struct _IBusEmojiDataPrivate {
|
|
GSList *annotations;
|
|
gchar *description;
|
|
gchar *category;
|
|
+ gchar *emoji_alternates;
|
|
};
|
|
|
|
#define IBUS_EMOJI_DATA_GET_PRIVATE(o) \
|
|
@@ -142,6 +144,19 @@ ibus_emoji_data_class_init (IBusEmojiDataClass *class)
|
|
"The emoji category",
|
|
"",
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ /**
|
|
+ * IBusEmojiData:emoji_alternates:
|
|
+ *
|
|
+ * The emoji alternate characters
|
|
+ */
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_EMOJI_ALTERNATES,
|
|
+ g_param_spec_string ("emoji-alternates",
|
|
+ "emoji alternate charasters",
|
|
+ "The emoji alternate characters UTF-8",
|
|
+ "",
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
}
|
|
|
|
static void
|
|
@@ -180,19 +195,24 @@ ibus_emoji_data_set_property (IBusEmojiData *emoji,
|
|
emoji->priv->emoji = g_value_dup_string (value);
|
|
break;
|
|
case PROP_ANNOTATIONS:
|
|
- g_assert (emoji->priv->annotations == NULL);
|
|
+ if (emoji->priv->annotations)
|
|
+ g_slist_free_full (emoji->priv->annotations, g_free);
|
|
emoji->priv->annotations =
|
|
g_slist_copy_deep (g_value_get_pointer (value),
|
|
(GCopyFunc) g_strdup, NULL);
|
|
break;
|
|
case PROP_DESCRIPTION:
|
|
- g_assert (emoji->priv->description == NULL);
|
|
+ g_free (emoji->priv->description);
|
|
emoji->priv->description = g_value_dup_string (value);
|
|
break;
|
|
case PROP_CATEGORY:
|
|
g_assert (emoji->priv->category == NULL);
|
|
emoji->priv->category = g_value_dup_string (value);
|
|
break;
|
|
+ case PROP_EMOJI_ALTERNATES:
|
|
+ g_assert (emoji->priv->emoji_alternates == NULL);
|
|
+ emoji->priv->emoji_alternates = g_value_dup_string (value);
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (emoji, prop_id, pspec);
|
|
}
|
|
@@ -220,6 +240,9 @@ ibus_emoji_data_get_property (IBusEmojiData *emoji,
|
|
case PROP_CATEGORY:
|
|
g_value_set_string (value, ibus_emoji_data_get_category (emoji));
|
|
break;
|
|
+ case PROP_EMOJI_ALTERNATES:
|
|
+ g_value_set_string (value, ibus_emoji_data_get_emoji_alternates(emoji));
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (emoji, prop_id, pspec);
|
|
}
|
|
@@ -247,6 +270,9 @@ ibus_emoji_data_serialize (IBusEmojiData *emoji,
|
|
}
|
|
g_variant_builder_add (builder, "s", NOTNULL (emoji->priv->description));
|
|
g_variant_builder_add (builder, "s", NOTNULL (emoji->priv->category));
|
|
+ g_variant_builder_add (builder, "s",
|
|
+ NOTNULL (emoji->priv->emoji_alternates));
|
|
+#undef NOTNULL
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -277,6 +303,10 @@ ibus_emoji_data_deserialize (IBusEmojiData *emoji,
|
|
&emoji->priv->description);
|
|
ibus_g_variant_get_child_string (variant, retval++,
|
|
&emoji->priv->category);
|
|
+ if (g_variant_n_children (variant) < retval + 1)
|
|
+ return retval;
|
|
+ ibus_g_variant_get_child_string (variant, retval++,
|
|
+ &emoji->priv->emoji_alternates);
|
|
return retval;
|
|
}
|
|
|
|
@@ -295,6 +325,7 @@ ibus_emoji_data_copy (IBusEmojiData *dest,
|
|
NULL);
|
|
dest->priv->description = g_strdup (src->priv->description);
|
|
dest->priv->category = g_strdup (src->priv->category);
|
|
+ dest->priv->emoji_alternates = g_strdup (src->priv->emoji_alternates);
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -314,6 +345,7 @@ ibus_emoji_data_new (const gchar *first_property_name, ...)
|
|
g_assert (emoji->priv->emoji != NULL);
|
|
g_assert (emoji->priv->description != NULL);
|
|
g_assert (emoji->priv->category != NULL);
|
|
+ g_assert (emoji->priv->emoji_alternates != NULL);
|
|
return emoji;
|
|
}
|
|
|
|
@@ -370,6 +402,14 @@ ibus_emoji_data_get_category (IBusEmojiData *emoji)
|
|
return emoji->priv->category;
|
|
}
|
|
|
|
+const gchar *
|
|
+ibus_emoji_data_get_emoji_alternates (IBusEmojiData *emoji)
|
|
+{
|
|
+ g_return_val_if_fail (IBUS_IS_EMOJI_DATA (emoji), NULL);
|
|
+
|
|
+ return emoji->priv->emoji_alternates;
|
|
+}
|
|
+
|
|
|
|
static void
|
|
variant_foreach_add_emoji (IBusEmojiData *emoji,
|
|
diff --git a/src/ibusemoji.h b/src/ibusemoji.h
|
|
index eb24fdd..233cadd 100644
|
|
--- a/src/ibusemoji.h
|
|
+++ b/src/ibusemoji.h
|
|
@@ -156,6 +156,20 @@ const gchar * ibus_emoji_data_get_category (IBusEmojiData *emoji);
|
|
|
|
|
|
/**
|
|
+ * ibus_emoji_data_get_emoji_alternates:
|
|
+ * @emoji : An #IBusEmojiData
|
|
+ *
|
|
+ * Gets the emoji alternate characters in #IBusEmojiData. It should not be
|
|
+ * freed. The alternates are defined in "unicode_alt" in EmojiOne json.
|
|
+ *
|
|
+ * Returns: emoji alternates property in #IBusEmojiData
|
|
+ *
|
|
+ */
|
|
+const gchar * ibus_emoji_data_get_emoji_alternates
|
|
+ (IBusEmojiData *emoji);
|
|
+
|
|
+
|
|
+/**
|
|
* ibus_emoji_dict_save:
|
|
* @path: A path of the saved dictionary file.
|
|
* @dict: (element-type utf8 gpointer) (transfer none): An Emoji dictionary
|
|
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
|
|
index 8a2726c..7b6107f 100644
|
|
--- a/ui/gtk3/emojier.vala
|
|
+++ b/ui/gtk3/emojier.vala
|
|
@@ -381,7 +381,8 @@ class IBusEmojier : Gtk.Window {
|
|
|
|
|
|
private void update_annotation_to_emojis_dict(IBus.EmojiData data) {
|
|
- string emoji = data.get_emoji();
|
|
+ string emoji = (data.get_emoji_alternates() != "") ?
|
|
+ data.get_emoji_alternates() : data.get_emoji();
|
|
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
foreach (string annotation in annotations) {
|
|
bool has_emoji = false;
|
|
@@ -444,7 +445,8 @@ class IBusEmojier : Gtk.Window {
|
|
|
|
private void update_emoji_to_data_dict(IBus.EmojiData data,
|
|
string lang) {
|
|
- string emoji = data.get_emoji();
|
|
+ string emoji = (data.get_emoji_alternates() != "") ?
|
|
+ data.get_emoji_alternates() : data.get_emoji();
|
|
if (lang == "en") {
|
|
string description = utf8_down(data.get_description());
|
|
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
@@ -496,7 +498,8 @@ class IBusEmojier : Gtk.Window {
|
|
|
|
private void update_category_to_emojis_dict(IBus.EmojiData data,
|
|
string lang) {
|
|
- string emoji = data.get_emoji();
|
|
+ string emoji = (data.get_emoji_alternates() != "") ?
|
|
+ data.get_emoji_alternates() : data.get_emoji();
|
|
string category = data.get_category();
|
|
if (lang == "en" && category != "") {
|
|
bool has_emoji = false;
|
|
--
|
|
2.9.3
|
|
|