ibus/ibus-HEAD.patch
Takao Fujiwara c46a197882 Enabled unicode_alt in EmojiOne json file
- Enabled to type multiple code points on Emojier
- Fixed IBusEmojiDialog_1_0_gir_LIBS for --as-needed LDFLAGS
2017-04-05 18:28:56 +09:00

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>[&lt;Control&gt;&lt;Shift&gt;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>[&lt;Control&gt;&lt;Shift&gt;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