|
Packit |
3ff832 |
/* vim:set et sts=4 sw=4:
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* ibus - The Input Bus
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* Copyright (c) 2017-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
3ff832 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
3ff832 |
* License as published by the Free Software Foundation; either
|
|
Packit |
3ff832 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
3ff832 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
3ff832 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
3ff832 |
* Lesser General Public License for more details.
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
3ff832 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
3ff832 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
Packit |
3ff832 |
* USA
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public class IBusEmojier : Gtk.ApplicationWindow {
|
|
Packit |
3ff832 |
private class EEntry : Gtk.SearchEntry {
|
|
Packit |
3ff832 |
public EEntry() {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
name : "IBusEmojierEntry",
|
|
Packit |
3ff832 |
margin_start : 6,
|
|
Packit |
3ff832 |
margin_end : 6,
|
|
Packit |
3ff832 |
margin_top : 6,
|
|
Packit |
3ff832 |
margin_bottom : 6
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EListBox : Gtk.ListBox {
|
|
Packit |
3ff832 |
public EListBox() {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
vexpand : true,
|
|
Packit |
3ff832 |
halign : Gtk.Align.FILL,
|
|
Packit |
3ff832 |
valign : Gtk.Align.FILL
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
this.motion_notify_event.connect((e) => {
|
|
Packit |
3ff832 |
#if VALA_0_24
|
|
Packit |
3ff832 |
Gdk.EventMotion pe = e;
|
|
Packit |
3ff832 |
#else
|
|
Packit |
3ff832 |
Gdk.EventMotion *pe = &e;
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
if (m_mouse_x == pe.x_root && m_mouse_y == pe.y_root)
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
m_mouse_x = pe.x_root;
|
|
Packit |
3ff832 |
m_mouse_y = pe.y_root;
|
|
Packit |
3ff832 |
var row = this.get_row_at_y((int)e.y);
|
|
Packit |
3ff832 |
if (row != null)
|
|
Packit |
3ff832 |
this.select_row(row);
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
this.enter_notify_event.connect((e) => {
|
|
Packit |
3ff832 |
// avoid gtk_button_update_state()
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EBoxRow : Gtk.ListBoxRow {
|
|
Packit |
3ff832 |
public EBoxRow(string text) {
|
|
Packit |
3ff832 |
this.text = text;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public string text { get; set; }
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EScrolledWindow : Gtk.ScrolledWindow {
|
|
Packit |
3ff832 |
public EScrolledWindow(Gtk.Adjustment? hadjustment=null,
|
|
Packit |
3ff832 |
Gtk.Adjustment? vadjustment=null) {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
hscrollbar_policy : Gtk.PolicyType.NEVER,
|
|
Packit |
3ff832 |
vscrollbar_policy : Gtk.PolicyType.NEVER,
|
|
Packit |
3ff832 |
shadow_type : Gtk.ShadowType.IN,
|
|
Packit |
3ff832 |
margin_start : 6,
|
|
Packit |
3ff832 |
margin_end : 6,
|
|
Packit |
3ff832 |
margin_top : 6,
|
|
Packit |
3ff832 |
margin_bottom : 6
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
if (hadjustment != null)
|
|
Packit |
3ff832 |
set_hadjustment(hadjustment);
|
|
Packit |
3ff832 |
if (vadjustment != null)
|
|
Packit |
3ff832 |
set_hadjustment(vadjustment);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EGrid : Gtk.Grid {
|
|
Packit |
3ff832 |
public EGrid() {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
row_homogeneous : false,
|
|
Packit |
3ff832 |
vexpand : true,
|
|
Packit |
3ff832 |
halign : Gtk.Align.FILL,
|
|
Packit |
3ff832 |
valign : Gtk.Align.FILL,
|
|
Packit |
3ff832 |
row_spacing : 5,
|
|
Packit |
3ff832 |
column_spacing : 5,
|
|
Packit |
3ff832 |
border_width : 2
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EWhiteLabel : Gtk.Label {
|
|
Packit |
3ff832 |
private int m_minimum_width = 0;
|
|
Packit |
3ff832 |
private int m_natural_width = 0;
|
|
Packit |
3ff832 |
private int m_minimum_height = 0;
|
|
Packit |
3ff832 |
private int m_natural_height = 0;
|
|
Packit |
3ff832 |
public EWhiteLabel(string text) {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
name : "IBusEmojierWhiteLabel"
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
set_label(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
public override void get_preferred_width(out int minimum_width,
|
|
Packit |
3ff832 |
out int natural_width) {
|
|
Packit |
3ff832 |
if (m_minimum_height == 0 && m_natural_height == 0) {
|
|
Packit |
3ff832 |
base.get_preferred_height(out m_minimum_height,
|
|
Packit |
3ff832 |
out m_natural_height);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
var text = get_label();
|
|
Packit |
3ff832 |
var ch = text.get_char();
|
|
Packit |
3ff832 |
if (text.length == 1 && ch == '\t') {
|
|
Packit |
3ff832 |
m_minimum_width = minimum_width = m_minimum_height;
|
|
Packit |
3ff832 |
m_natural_width = natural_width = m_natural_height;
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
base.get_preferred_width(out minimum_width, out natural_width);
|
|
Packit |
3ff832 |
if (text.length == 1 && (ch == '\n' || ch == '\r')) {
|
|
Packit |
3ff832 |
minimum_width /= 2;
|
|
Packit |
3ff832 |
natural_width /= 2;
|
|
Packit |
3ff832 |
m_minimum_width = minimum_width;
|
|
Packit |
3ff832 |
m_natural_width = natural_width;
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (minimum_width < m_minimum_height)
|
|
Packit |
3ff832 |
minimum_width = m_minimum_height;
|
|
Packit |
3ff832 |
if (natural_width < m_natural_height)
|
|
Packit |
3ff832 |
natural_width = m_natural_height;
|
|
Packit |
3ff832 |
m_minimum_width = minimum_width;
|
|
Packit |
3ff832 |
m_natural_width = natural_width;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
public override void get_preferred_height(out int minimum_height,
|
|
Packit |
3ff832 |
out int natural_height) {
|
|
Packit |
3ff832 |
if (m_minimum_width == 0 && m_natural_width == 0) {
|
|
Packit |
3ff832 |
base.get_preferred_width(out m_minimum_width,
|
|
Packit |
3ff832 |
out m_natural_width);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
var text = get_label();
|
|
Packit |
3ff832 |
var ch = text.get_char();
|
|
Packit |
3ff832 |
if (text.length == 1 && ch == '\v') {
|
|
Packit |
3ff832 |
m_minimum_height = minimum_height = m_minimum_width;
|
|
Packit |
3ff832 |
m_natural_height = natural_height = m_natural_width;
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
base.get_preferred_height(out minimum_height, out natural_height);
|
|
Packit |
3ff832 |
if (text.length == 1 && (ch == '\n' || ch == '\r')) {
|
|
Packit |
3ff832 |
minimum_height /= 2;
|
|
Packit |
3ff832 |
natural_height /= 2;
|
|
Packit |
3ff832 |
m_minimum_height = minimum_height;
|
|
Packit |
3ff832 |
m_natural_height = natural_height;
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_minimum_height = minimum_height;
|
|
Packit |
3ff832 |
m_natural_height = natural_height;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class ESelectedLabel : EWhiteLabel {
|
|
Packit |
3ff832 |
public ESelectedLabel(string text) {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
name : "IBusEmojierSelectedLabel"
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
if (text != "")
|
|
Packit |
3ff832 |
set_label(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EGoldLabel : EWhiteLabel {
|
|
Packit |
3ff832 |
public EGoldLabel(string text) {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
name : "IBusEmojierGoldLabel"
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
if (text != "")
|
|
Packit |
3ff832 |
set_label(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EPaddedLabel : Gtk.Label {
|
|
Packit |
3ff832 |
public EPaddedLabel(string text,
|
|
Packit |
3ff832 |
Gtk.Align align) {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
name : "IBusEmojierPaddedLabel",
|
|
Packit |
3ff832 |
halign : align,
|
|
Packit |
3ff832 |
valign : Gtk.Align.CENTER,
|
|
Packit |
3ff832 |
margin_start : 20,
|
|
Packit |
3ff832 |
margin_end : 20,
|
|
Packit |
3ff832 |
margin_top : 6,
|
|
Packit |
3ff832 |
margin_bottom : 6
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
set_text(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class EPaddedLabelBox : Gtk.Box {
|
|
Packit |
3ff832 |
public EPaddedLabelBox(string text,
|
|
Packit |
3ff832 |
Gtk.Align align,
|
|
Packit |
3ff832 |
TravelDirection direction=TravelDirection.NONE,
|
|
Packit |
3ff832 |
string? caption=null) {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
name : "IBusEmojierPaddedLabelBox",
|
|
Packit |
3ff832 |
orientation : Gtk.Orientation.HORIZONTAL,
|
|
Packit |
3ff832 |
spacing : 0
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
if (direction == TravelDirection.BACKWARD) {
|
|
Packit |
3ff832 |
IconWidget icon;
|
|
Packit |
3ff832 |
if (Gtk.Widget.get_default_direction() ==
|
|
Packit |
3ff832 |
Gtk.TextDirection.RTL) {
|
|
Packit |
3ff832 |
icon = new IconWidget("go-previous-rtl-symbolic",
|
|
Packit |
3ff832 |
Gtk.IconSize.MENU);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
icon = new IconWidget("go-previous-symbolic",
|
|
Packit |
3ff832 |
Gtk.IconSize.MENU);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
pack_start(icon, false, true, 0);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
EPaddedLabel label = new EPaddedLabel(text, align);
|
|
Packit |
3ff832 |
pack_start(label, true, true, 0);
|
|
Packit |
3ff832 |
if (caption != null) {
|
|
Packit |
3ff832 |
EPaddedLabel label_r = new EPaddedLabel(caption,
|
|
Packit |
3ff832 |
Gtk.Align.END);
|
|
Packit |
3ff832 |
pack_end(label_r, true, true, 0);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
private class LoadProgressObject : GLib.Object {
|
|
Packit |
3ff832 |
public LoadProgressObject() {
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
public signal void deserialize_unicode(uint done, uint total);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private enum TravelDirection {
|
|
Packit |
3ff832 |
NONE,
|
|
Packit |
3ff832 |
BACKWARD,
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public const uint BUTTON_CLOSE_BUTTON = 1000;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private const uint EMOJI_GRID_PAGE = 10;
|
|
Packit |
3ff832 |
private const string EMOJI_CATEGORY_FAVORITES = N_("Favorites");
|
|
Packit |
3ff832 |
private const string EMOJI_CATEGORY_OTHERS = N_("Others");
|
|
Packit |
3ff832 |
private const string EMOJI_CATEGORY_UNICODE = N_("Open Unicode choice");
|
|
Packit |
3ff832 |
private const unichar[] EMOJI_VARIANT_LIST = {
|
|
Packit |
3ff832 |
0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff, 0x200d };
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
// Set the actual default values in the constructor
|
|
Packit |
3ff832 |
// because these fields are used for class_init() and static functions,
|
|
Packit |
3ff832 |
// e.g. set_emoji_font(), can be called before class_init() is called.
|
|
Packit |
3ff832 |
private static string m_current_lang_id;
|
|
Packit |
3ff832 |
private static string m_emoji_font_family;
|
|
Packit |
3ff832 |
private static int m_emoji_font_size;
|
|
Packit |
3ff832 |
private static bool m_emoji_font_changed = false;
|
|
Packit |
3ff832 |
private static string[] m_favorites;
|
|
Packit |
3ff832 |
private static string[] m_favorite_annotations;
|
|
Packit |
3ff832 |
private static int m_emoji_max_seq_len;
|
|
Packit |
3ff832 |
private static bool m_has_partial_match;
|
|
Packit |
3ff832 |
private static uint m_partial_match_length;
|
|
Packit |
3ff832 |
private static uint m_partial_match_condition;
|
|
Packit |
3ff832 |
private static bool m_show_emoji_variant = false;
|
|
Packit |
3ff832 |
private static int m_default_window_width;
|
|
Packit |
3ff832 |
private static int m_default_window_height;
|
|
Packit |
3ff832 |
private static GLib.HashTable<string, GLib.SList<string>>?
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict;
|
|
Packit |
3ff832 |
private static GLib.HashTable<string, IBus.EmojiData>?
|
|
Packit |
3ff832 |
m_emoji_to_data_dict;
|
|
Packit |
3ff832 |
private static GLib.HashTable<string, GLib.SList<string>>?
|
|
Packit |
3ff832 |
m_category_to_emojis_dict;
|
|
Packit |
3ff832 |
private static GLib.HashTable<string, GLib.SList<string>>?
|
|
Packit |
3ff832 |
m_emoji_to_emoji_variants_dict;
|
|
Packit |
3ff832 |
private static GLib.HashTable<unichar, IBus.UnicodeData>?
|
|
Packit |
3ff832 |
m_unicode_to_data_dict;
|
|
Packit |
3ff832 |
private static GLib.HashTable<string, GLib.SList<unichar>>?
|
|
Packit |
3ff832 |
m_name_to_unicodes_dict;
|
|
Packit |
3ff832 |
private static GLib.SList<IBus.UnicodeBlock> m_unicode_block_list;
|
|
Packit |
3ff832 |
private static bool m_show_unicode = false;
|
|
Packit |
3ff832 |
private static LoadProgressObject m_unicode_progress_object;
|
|
Packit |
3ff832 |
private static bool m_loaded_unicode = false;
|
|
Packit |
3ff832 |
private static string m_warning_message = "";
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private ThemedRGBA m_rgba;
|
|
Packit |
3ff832 |
private Gtk.Box m_vbox;
|
|
Packit |
3ff832 |
private EEntry m_entry;
|
|
Packit |
3ff832 |
/* If emojier is emoji category list or Unicode category list,
|
|
Packit |
3ff832 |
* m_annotation is "" and preedit is also "".
|
|
Packit |
3ff832 |
* If emojier is candidate mode, m_annotation is an annotation and
|
|
Packit |
3ff832 |
* get_current_candidate() returns the current emoji.
|
|
Packit |
3ff832 |
* But the current preedit can be "" in candidate mode in case that
|
|
Packit |
3ff832 |
* Unicode candidate window has U+0000.
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
private string m_annotation = "";
|
|
Packit |
3ff832 |
private string? m_backward;
|
|
Packit |
3ff832 |
private int m_backward_index = -1;
|
|
Packit |
3ff832 |
private EScrolledWindow? m_scrolled_window = null;
|
|
Packit |
3ff832 |
private EListBox m_list_box;
|
|
Packit |
3ff832 |
private bool m_is_running = false;
|
|
Packit |
3ff832 |
private string m_input_context_path = "";
|
|
Packit |
3ff832 |
private GLib.MainLoop? m_loop;
|
|
Packit |
3ff832 |
private string? m_result;
|
|
Packit |
3ff832 |
/* If m_candidate_panel_is_visible is true, emojier is candidate mode and
|
|
Packit |
3ff832 |
* the emoji lookup window is visible.
|
|
Packit |
3ff832 |
* If m_candidate_panel_is_visible is false, the emoji lookup window is
|
|
Packit |
3ff832 |
* not visible but the mode is not clear.
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
private bool m_candidate_panel_is_visible;
|
|
Packit |
3ff832 |
/* If m_candidate_panel_mode is true, emojier is candidate mode and
|
|
Packit |
3ff832 |
* it does not depend on whether the window is visible or not.
|
|
Packit |
3ff832 |
* I.E. the first candidate does not show the lookup window and the
|
|
Packit |
3ff832 |
* second one shows the window.
|
|
Packit |
3ff832 |
* If m_candidate_panel_mode is false, emojier is emoji category list or
|
|
Packit |
3ff832 |
* Unicode category list.
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
private bool m_candidate_panel_mode;
|
|
Packit |
3ff832 |
private int m_category_active_index = -1;
|
|
Packit |
3ff832 |
private IBus.LookupTable m_lookup_table;
|
|
Packit |
3ff832 |
private Gtk.Label[] m_candidates;
|
|
Packit |
3ff832 |
private bool m_enter_notify_enable = true;
|
|
Packit |
3ff832 |
private uint m_entry_notify_show_id;
|
|
Packit |
3ff832 |
private uint m_entry_notify_disable_id;
|
|
Packit |
3ff832 |
protected static double m_mouse_x;
|
|
Packit |
3ff832 |
protected static double m_mouse_y;
|
|
Packit |
3ff832 |
private Gtk.ProgressBar m_unicode_progress_bar;
|
|
Packit |
3ff832 |
private uint m_unicode_progress_id;
|
|
Packit |
3ff832 |
private Gtk.Label m_unicode_percent_label;
|
|
Packit |
3ff832 |
private double m_unicode_percent;
|
|
Packit |
3ff832 |
private Gdk.Rectangle m_cursor_location;
|
|
Packit |
3ff832 |
private bool m_is_up_side_down = false;
|
|
Packit |
3ff832 |
private uint m_redraw_window_id;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public signal void candidate_clicked(uint index, uint button, uint state);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public IBusEmojier() {
|
|
Packit |
3ff832 |
GLib.Object(
|
|
Packit |
3ff832 |
type : Gtk.WindowType.POPUP
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
// GLib.ActionEntry accepts const variables only.
|
|
Packit |
3ff832 |
var action = new GLib.SimpleAction.stateful(
|
|
Packit |
3ff832 |
"variant",
|
|
Packit |
3ff832 |
null,
|
|
Packit |
3ff832 |
new GLib.Variant.boolean(m_show_emoji_variant));
|
|
Packit |
3ff832 |
action.activate.connect(check_action_variant_cb);
|
|
Packit |
3ff832 |
add_action(action);
|
|
Packit |
3ff832 |
action = new GLib.SimpleAction("close", null);
|
|
Packit |
3ff832 |
action.activate.connect(action_close_cb);
|
|
Packit |
3ff832 |
add_action(action);
|
|
Packit |
3ff832 |
if (m_current_lang_id == null)
|
|
Packit |
3ff832 |
m_current_lang_id = "en";
|
|
Packit |
3ff832 |
if (m_emoji_font_family == null) {
|
|
Packit |
3ff832 |
m_emoji_font_family = "Monospace";
|
|
Packit |
3ff832 |
m_emoji_font_changed = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_emoji_font_size == 0) {
|
|
Packit |
3ff832 |
m_emoji_font_size = 16;
|
|
Packit |
3ff832 |
m_emoji_font_changed = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_favorites == null)
|
|
Packit |
3ff832 |
m_favorites = {};
|
|
Packit |
3ff832 |
if (m_favorite_annotations == null)
|
|
Packit |
3ff832 |
m_favorite_annotations = {};
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
set_css_data();
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
|
|
Packit |
3ff832 |
add(m_vbox);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_entry = new EEntry();
|
|
Packit |
3ff832 |
m_entry.set_placeholder_text(_("Type annotation or choose emoji"));
|
|
Packit |
3ff832 |
//m_vbox.add(m_entry);
|
|
Packit |
3ff832 |
m_entry.changed.connect(() => {
|
|
Packit |
3ff832 |
update_candidate_window();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
m_entry.icon_release.connect((icon_pos, event) => {
|
|
Packit |
3ff832 |
hide_candidate_panel();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* Set the accessible role of the label to a status bar so it
|
|
Packit |
3ff832 |
* will emit name changed events that can be used by screen
|
|
Packit |
3ff832 |
* readers.
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
Atk.Object obj = m_entry.get_accessible();
|
|
Packit |
3ff832 |
obj.set_role (Atk.Role.STATUSBAR);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
// The constructor of IBus.LookupTable does not support more than
|
|
Packit |
3ff832 |
// 16 pages.
|
|
Packit |
3ff832 |
m_lookup_table = new IBus.LookupTable(1, 0, true, true);
|
|
Packit |
3ff832 |
m_lookup_table.set_page_size(EMOJI_GRID_PAGE * EMOJI_GRID_PAGE);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
hide.connect(() => {
|
|
Packit |
3ff832 |
if (m_loop != null && m_loop.is_running())
|
|
Packit |
3ff832 |
m_loop.quit();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
size_allocate.connect((w, a) => {
|
|
Packit |
3ff832 |
adjust_window_position();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
candidate_clicked.connect((i, b, s) => {
|
|
Packit |
3ff832 |
if (m_input_context_path != "")
|
|
Packit |
3ff832 |
candidate_panel_select_index(i, b);
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (m_annotation_to_emojis_dict == null) {
|
|
Packit |
3ff832 |
reload_emoji_dict();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
get_load_progress_object();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void reload_emoji_dict() {
|
|
Packit |
3ff832 |
init_emoji_dict();
|
|
Packit |
3ff832 |
make_emoji_dict("en");
|
|
Packit |
3ff832 |
if (m_current_lang_id != "en") {
|
|
Packit |
3ff832 |
var lang_ids = m_current_lang_id.split("_");
|
|
Packit |
3ff832 |
if (lang_ids.length > 1) {
|
|
Packit |
3ff832 |
string sub_id = lang_ids[0];
|
|
Packit |
3ff832 |
make_emoji_dict(sub_id);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
make_emoji_dict(m_current_lang_id);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
update_favorite_emoji_dict();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void init_emoji_dict() {
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict =
|
|
Packit |
3ff832 |
new GLib.HashTable<string, GLib.SList<string>>(GLib.str_hash,
|
|
Packit |
3ff832 |
GLib.str_equal);
|
|
Packit |
3ff832 |
m_emoji_to_data_dict =
|
|
Packit |
3ff832 |
new GLib.HashTable<string, IBus.EmojiData>(GLib.str_hash,
|
|
Packit |
3ff832 |
GLib.str_equal);
|
|
Packit |
3ff832 |
m_category_to_emojis_dict =
|
|
Packit |
3ff832 |
new GLib.HashTable<string, GLib.SList<string>>(GLib.str_hash,
|
|
Packit |
3ff832 |
GLib.str_equal);
|
|
Packit |
3ff832 |
m_emoji_to_emoji_variants_dict =
|
|
Packit |
3ff832 |
new GLib.HashTable<string, GLib.SList<string>>(GLib.str_hash,
|
|
Packit |
3ff832 |
GLib.str_equal);
|
|
Packit |
3ff832 |
m_unicode_to_data_dict =
|
|
Packit |
3ff832 |
new GLib.HashTable<unichar, IBus.UnicodeData>(
|
|
Packit |
3ff832 |
GLib.direct_hash,
|
|
Packit |
3ff832 |
GLib.direct_equal);
|
|
Packit |
3ff832 |
m_name_to_unicodes_dict =
|
|
Packit |
3ff832 |
new GLib.HashTable<string, GLib.SList<unichar>>(GLib.str_hash,
|
|
Packit |
3ff832 |
GLib.str_equal);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void make_emoji_dict(string lang) {
|
|
Packit |
3ff832 |
GLib.SList<IBus.EmojiData> emoji_list = IBus.EmojiData.load(
|
|
Packit |
3ff832 |
Config.PKGDATADIR + "/dicts/emoji-" + lang + ".dict");
|
|
Packit |
3ff832 |
if (emoji_list == null)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
foreach (IBus.EmojiData data in emoji_list) {
|
|
Packit |
3ff832 |
update_emoji_to_data_dict(data, lang);
|
|
Packit |
3ff832 |
update_annotation_to_emojis_dict(data);
|
|
Packit |
3ff832 |
update_category_to_emojis_dict(data, lang);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
GLib.List<unowned string> annotations =
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict.get_keys();
|
|
Packit |
3ff832 |
foreach (unowned string annotation in annotations) {
|
|
Packit |
3ff832 |
if (m_emoji_max_seq_len < annotation.length)
|
|
Packit |
3ff832 |
m_emoji_max_seq_len = annotation.length;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void update_annotation_to_emojis_dict(IBus.EmojiData data) {
|
|
Packit |
3ff832 |
string emoji = data.get_emoji();
|
|
Packit |
3ff832 |
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
Packit |
3ff832 |
foreach (string annotation in annotations) {
|
|
Packit |
3ff832 |
bool has_emoji = false;
|
|
Packit |
3ff832 |
GLib.SList<string> hits =
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict.lookup(annotation).copy_deep(
|
|
Packit |
3ff832 |
GLib.strdup);
|
|
Packit |
3ff832 |
foreach (string hit_emoji in hits) {
|
|
Packit |
3ff832 |
if (hit_emoji == emoji) {
|
|
Packit |
3ff832 |
has_emoji = true;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (!has_emoji) {
|
|
Packit |
3ff832 |
hits.append(emoji);
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict.replace(
|
|
Packit |
3ff832 |
annotation,
|
|
Packit |
3ff832 |
hits.copy_deep(GLib.strdup));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static string utf8_code_point(string str) {
|
|
Packit |
3ff832 |
var buff = new GLib.StringBuilder();
|
|
Packit |
3ff832 |
int length = str.char_count();
|
|
Packit |
3ff832 |
if (length == 0) {
|
|
Packit |
3ff832 |
buff.append("U+%04X".printf(0));
|
|
Packit |
3ff832 |
return buff.str;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
for (int i = 0; i < length; i++) {
|
|
Packit |
3ff832 |
unichar ch = str.get_char(0);
|
|
Packit |
3ff832 |
if (i == 0)
|
|
Packit |
3ff832 |
buff.append("U+%04X".printf(ch));
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
buff.append(" %04X".printf(ch));
|
|
Packit |
3ff832 |
str = str.next_char();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return buff.str;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static string utf8_entity(string str) {
|
|
Packit |
3ff832 |
var buff = new GLib.StringBuilder();
|
|
Packit |
3ff832 |
int length = str.char_count();
|
|
Packit |
3ff832 |
for (int i = 0; i < length; i++) {
|
|
Packit |
3ff832 |
unichar ch = str.get_char(0);
|
|
Packit |
3ff832 |
switch(ch) {
|
|
Packit |
3ff832 |
case '<':
|
|
Packit |
3ff832 |
buff.append("<");
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case '>':
|
|
Packit |
3ff832 |
buff.append(">");
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case '&':
|
|
Packit |
3ff832 |
buff.append("&");
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
default:
|
|
Packit |
3ff832 |
buff.append_unichar(ch);
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
str = str.next_char();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return buff.str;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void
|
|
Packit |
3ff832 |
update_annotations_with_description (IBus.EmojiData data,
|
|
Packit |
3ff832 |
string description) {
|
|
Packit |
3ff832 |
GLib.SList<string> annotations =
|
|
Packit |
3ff832 |
data.get_annotations().copy_deep(GLib.strdup);
|
|
Packit |
3ff832 |
bool update_annotations = false;
|
|
Packit |
3ff832 |
string former = null;
|
|
Packit |
3ff832 |
string later = null;
|
|
Packit |
3ff832 |
int index = description.index_of(": ");
|
|
Packit |
3ff832 |
if (index > 0) {
|
|
Packit |
3ff832 |
former = description.substring(0, index);
|
|
Packit |
3ff832 |
if (annotations.find_custom(former, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
annotations.append(former);
|
|
Packit |
3ff832 |
update_annotations = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
later = description.substring(index + 2);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
later = description.dup();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
var words = later.split(" ");
|
|
Packit |
3ff832 |
// If the description has less than 3 words, add it to annotations
|
|
Packit |
3ff832 |
// FIXME: How to cast GLib.CompareFunc<string> to strcmp?
|
|
Packit |
3ff832 |
if (words.length < 3 &&
|
|
Packit |
3ff832 |
annotations.find_custom(
|
|
Packit |
3ff832 |
later,
|
|
Packit |
3ff832 |
GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
annotations.append(later);
|
|
Packit |
3ff832 |
update_annotations = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (update_annotations)
|
|
Packit |
3ff832 |
data.set_annotations(annotations.copy_deep(GLib.strdup));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void update_emoji_to_data_dict(IBus.EmojiData data,
|
|
Packit |
3ff832 |
string lang) {
|
|
Packit |
3ff832 |
string emoji = data.get_emoji();
|
|
Packit |
3ff832 |
if (lang == "en") {
|
|
Packit |
3ff832 |
string description = data.get_description().down();
|
|
Packit |
3ff832 |
update_annotations_with_description (data, description);
|
|
Packit |
3ff832 |
m_emoji_to_data_dict.replace(emoji, data);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
unowned IBus.EmojiData? en_data = null;
|
|
Packit |
3ff832 |
en_data = m_emoji_to_data_dict.lookup(emoji);
|
|
Packit |
3ff832 |
if (en_data == null) {
|
|
Packit |
3ff832 |
m_emoji_to_data_dict.insert(emoji, data);
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
string trans_description = data.get_description();
|
|
Packit |
3ff832 |
en_data.set_description(trans_description);
|
|
Packit |
3ff832 |
trans_description = trans_description.down();
|
|
Packit |
3ff832 |
update_annotations_with_description (data, trans_description);
|
|
Packit |
3ff832 |
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
Packit |
3ff832 |
unowned GLib.SList<string> en_annotations
|
|
Packit |
3ff832 |
= en_data.get_annotations();
|
|
Packit |
3ff832 |
foreach (string annotation in en_annotations) {
|
|
Packit |
3ff832 |
// FIXME: How to cast GLib.CompareFunc<string> to strcmp?
|
|
Packit |
3ff832 |
if (annotations.find_custom(
|
|
Packit |
3ff832 |
annotation,
|
|
Packit |
3ff832 |
GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
annotations.append(annotation.dup());
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
en_data.set_annotations(annotations.copy_deep(GLib.strdup));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void update_category_to_emojis_dict(IBus.EmojiData data,
|
|
Packit |
3ff832 |
string lang) {
|
|
Packit |
3ff832 |
string emoji = data.get_emoji();
|
|
Packit |
3ff832 |
string category = data.get_category();
|
|
Packit |
3ff832 |
if (category == "")
|
|
Packit |
3ff832 |
category = EMOJI_CATEGORY_OTHERS;
|
|
Packit |
3ff832 |
if (lang == "en") {
|
|
Packit |
3ff832 |
bool has_variant = false;
|
|
Packit |
3ff832 |
foreach (unichar ch in EMOJI_VARIANT_LIST) {
|
|
Packit |
3ff832 |
if (emoji.index_of_char(ch) >= 0) {
|
|
Packit |
3ff832 |
has_variant = true;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
// If emoji includes variants (skin colors and items),
|
|
Packit |
3ff832 |
// it's escaped in m_emoji_to_emoji_variants_dict and
|
|
Packit |
3ff832 |
// not shown by default.
|
|
Packit |
3ff832 |
if (has_variant) {
|
|
Packit |
3ff832 |
unichar base_ch = emoji.get_char();
|
|
Packit |
3ff832 |
string base_emoji = base_ch.to_string();
|
|
Packit |
3ff832 |
var buff = new GLib.StringBuilder();
|
|
Packit |
3ff832 |
buff.append_unichar(base_ch);
|
|
Packit |
3ff832 |
buff.append_unichar(0xfe0f);
|
|
Packit |
3ff832 |
if (m_emoji_to_data_dict.lookup(buff.str) != null)
|
|
Packit |
3ff832 |
base_emoji = buff.str;
|
|
Packit |
3ff832 |
GLib.SList<string>? variants =
|
|
Packit |
3ff832 |
m_emoji_to_emoji_variants_dict.lookup(
|
|
Packit |
3ff832 |
base_emoji).copy_deep(GLib.strdup);
|
|
Packit |
3ff832 |
if (variants.find_custom(emoji, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
if (variants == null)
|
|
Packit |
3ff832 |
variants.append(base_emoji);
|
|
Packit |
3ff832 |
variants.append(emoji);
|
|
Packit |
3ff832 |
m_emoji_to_emoji_variants_dict.replace(
|
|
Packit |
3ff832 |
base_emoji,
|
|
Packit |
3ff832 |
variants.copy_deep(GLib.strdup));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
bool has_emoji = false;
|
|
Packit |
3ff832 |
GLib.SList<string> hits =
|
|
Packit |
3ff832 |
m_category_to_emojis_dict.lookup(category).copy_deep(
|
|
Packit |
3ff832 |
GLib.strdup);
|
|
Packit |
3ff832 |
foreach (string hit_emoji in hits) {
|
|
Packit |
3ff832 |
if (hit_emoji == emoji) {
|
|
Packit |
3ff832 |
has_emoji = true;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (!has_emoji) {
|
|
Packit |
3ff832 |
hits.append(emoji);
|
|
Packit |
3ff832 |
m_category_to_emojis_dict.replace(category,
|
|
Packit |
3ff832 |
hits.copy_deep(GLib.strdup));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void make_unicode_block_dict() {
|
|
Packit |
3ff832 |
m_unicode_block_list = IBus.UnicodeBlock.load(
|
|
Packit |
3ff832 |
Config.PKGDATADIR + "/dicts/unicode-blocks.dict");
|
|
Packit |
3ff832 |
foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
Packit |
3ff832 |
unowned string name = block.get_name();
|
|
Packit |
3ff832 |
if (m_emoji_max_seq_len < name.length)
|
|
Packit |
3ff832 |
m_emoji_max_seq_len = name.length;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void make_unicode_name_dict(Object source_object) {
|
|
Packit |
3ff832 |
IBus.UnicodeData.load_async(
|
|
Packit |
3ff832 |
Config.PKGDATADIR + "/dicts/unicode-names.dict",
|
|
Packit |
3ff832 |
source_object,
|
|
Packit |
3ff832 |
null,
|
|
Packit |
3ff832 |
(IBus.UnicodeDataLoadAsyncFinish)make_unicode_name_dict_finish);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void
|
|
Packit |
3ff832 |
make_unicode_name_dict_finish(GLib.SList<IBus.UnicodeData> unicode_list) {
|
|
Packit |
3ff832 |
if (unicode_list == null)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
foreach (IBus.UnicodeData data in unicode_list) {
|
|
Packit |
3ff832 |
update_unicode_to_data_dict(data);
|
|
Packit |
3ff832 |
update_name_to_unicodes_dict(data);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
GLib.List<unowned string> names =
|
|
Packit |
3ff832 |
m_name_to_unicodes_dict.get_keys();
|
|
Packit |
3ff832 |
foreach (unowned string name in names) {
|
|
Packit |
3ff832 |
if (m_emoji_max_seq_len < name.length)
|
|
Packit |
3ff832 |
m_emoji_max_seq_len = name.length;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_loaded_unicode = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void update_unicode_to_data_dict(IBus.UnicodeData data) {
|
|
Packit |
3ff832 |
unichar code = data.get_code();
|
|
Packit |
3ff832 |
m_unicode_to_data_dict.replace(code, data);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static void update_name_to_unicodes_dict(IBus.UnicodeData data) {
|
|
Packit |
3ff832 |
unichar code = data.get_code();
|
|
Packit |
3ff832 |
string[] names = {data.get_name().down(), data.get_alias().down()};
|
|
Packit |
3ff832 |
foreach (unowned string name in names) {
|
|
Packit |
3ff832 |
if (name == "")
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
bool has_code = false;
|
|
Packit |
3ff832 |
GLib.SList<unichar> hits =
|
|
Packit |
3ff832 |
m_name_to_unicodes_dict.lookup(name).copy();
|
|
Packit |
3ff832 |
foreach (unichar hit_code in hits) {
|
|
Packit |
3ff832 |
if (hit_code == code) {
|
|
Packit |
3ff832 |
has_code = true;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (!has_code) {
|
|
Packit |
3ff832 |
hits.append(code);
|
|
Packit |
3ff832 |
m_name_to_unicodes_dict.replace(name, hits.copy());
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void set_css_data() {
|
|
Packit |
3ff832 |
Gdk.Display display = Gdk.Display.get_default();
|
|
Packit |
3ff832 |
Gdk.Screen screen = (display != null) ?
|
|
Packit |
3ff832 |
display.get_default_screen() : null;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (screen == null) {
|
|
Packit |
3ff832 |
warning("Could not open display.");
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
// Set en locale because de_DE's decimal_point is ',' instead of '.'
|
|
Packit |
3ff832 |
string? backup_locale =
|
|
Packit |
3ff832 |
Intl.setlocale(LocaleCategory.NUMERIC, null).dup();
|
|
Packit |
3ff832 |
if (Intl.setlocale(LocaleCategory.NUMERIC, "en_US.UTF-8") == null) {
|
|
Packit |
3ff832 |
if (Intl.setlocale(LocaleCategory.NUMERIC, "C.UTF-8") == null) {
|
|
Packit |
3ff832 |
if (Intl.setlocale(LocaleCategory.NUMERIC, "C") == null) {
|
|
Packit |
3ff832 |
warning("You don't install either en_US.UTF-8 or C.UTF-8 " +
|
|
Packit |
3ff832 |
"or C locale");
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_rgba == null)
|
|
Packit |
3ff832 |
m_rgba = new ThemedRGBA(this);
|
|
Packit |
3ff832 |
uint bg_red = (uint)(m_rgba.normal_bg.red * 255);
|
|
Packit |
3ff832 |
uint bg_green = (uint)(m_rgba.normal_bg.green * 255);
|
|
Packit |
3ff832 |
uint bg_blue = (uint)(m_rgba.normal_bg.blue * 255);
|
|
Packit |
3ff832 |
double bg_alpha = m_rgba.normal_bg.alpha;
|
|
Packit |
3ff832 |
string data =
|
|
Packit |
3ff832 |
"#IBusEmojierWhiteLabel { background-color: " +
|
|
Packit |
3ff832 |
"rgba(%u, %u, %u, %lf); ".printf(
|
|
Packit |
3ff832 |
bg_red, bg_green, bg_blue, bg_alpha) +
|
|
Packit |
3ff832 |
"font-family: %s; font-size: %dpt; ".printf(
|
|
Packit |
3ff832 |
m_emoji_font_family, m_emoji_font_size) +
|
|
Packit |
3ff832 |
"border-width: 4px; border-radius: 3px; } ";
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
uint fg_red = (uint)(m_rgba.selected_fg.red * 255);
|
|
Packit |
3ff832 |
uint fg_green = (uint)(m_rgba.selected_fg.green * 255);
|
|
Packit |
3ff832 |
uint fg_blue = (uint)(m_rgba.selected_fg.blue * 255);
|
|
Packit |
3ff832 |
double fg_alpha = m_rgba.selected_fg.alpha;
|
|
Packit |
3ff832 |
bg_red = (uint)(m_rgba.selected_bg.red * 255);
|
|
Packit |
3ff832 |
bg_green = (uint)(m_rgba.selected_bg.green * 255);
|
|
Packit |
3ff832 |
bg_blue = (uint)(m_rgba.selected_bg.blue * 255);
|
|
Packit |
3ff832 |
bg_alpha = m_rgba.selected_bg.alpha;
|
|
Packit |
3ff832 |
data += "#IBusEmojierSelectedLabel { color: " +
|
|
Packit |
3ff832 |
"rgba(%u, %u, %u, %lf); ".printf(
|
|
Packit |
3ff832 |
fg_red, fg_green, fg_blue, fg_alpha) +
|
|
Packit |
3ff832 |
"font-family: %s; font-size: %dpt; ".printf(
|
|
Packit |
3ff832 |
m_emoji_font_family, m_emoji_font_size) +
|
|
Packit |
3ff832 |
"background-color: " +
|
|
Packit |
3ff832 |
"rgba(%u, %u, %u, %lf); ".printf(
|
|
Packit |
3ff832 |
bg_red, bg_green, bg_blue, bg_alpha) +
|
|
Packit |
3ff832 |
"border-width: 4px; border-radius: 3px; }";
|
|
Packit |
3ff832 |
data += "#IBusEmojierGoldLabel { color: " +
|
|
Packit |
3ff832 |
"rgba(%u, %u, %u, %lf); ".printf(
|
|
Packit |
3ff832 |
fg_red, fg_green, fg_blue, fg_alpha) +
|
|
Packit |
3ff832 |
"font-family: %s; font-size: %dpt; ".printf(
|
|
Packit |
3ff832 |
m_emoji_font_family, m_emoji_font_size) +
|
|
Packit |
3ff832 |
"background-color: #b09c5f; " +
|
|
Packit |
3ff832 |
"border-width: 4px; border-radius: 3px; }";
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gtk.CssProvider css_provider = new Gtk.CssProvider();
|
|
Packit |
3ff832 |
try {
|
|
Packit |
3ff832 |
css_provider.load_from_data(data, -1);
|
|
Packit |
3ff832 |
} catch (GLib.Error e) {
|
|
Packit |
3ff832 |
warning("Failed css_provider_from_data: %s", e.message);
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (backup_locale != null)
|
|
Packit |
3ff832 |
Intl.setlocale(LocaleCategory.NUMERIC, backup_locale);
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
Intl.setlocale(LocaleCategory.NUMERIC, "");
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gtk.StyleContext.add_provider_for_screen(
|
|
Packit |
3ff832 |
screen,
|
|
Packit |
3ff832 |
css_provider,
|
|
Packit |
3ff832 |
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void set_fixed_size() {
|
|
Packit |
3ff832 |
resize(20, 1);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void remove_all_children() {
|
|
Packit |
3ff832 |
if (m_list_box != null) {
|
|
Packit |
3ff832 |
foreach (Gtk.Widget w in m_list_box.get_children()) {
|
|
Packit |
3ff832 |
w.destroy();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_list_box = null;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
foreach (Gtk.Widget w in m_vbox.get_children()) {
|
|
Packit |
3ff832 |
if (w.name == "IBusEmojierEntry" ||
|
|
Packit |
3ff832 |
w.name == "IBusEmojierTitleLabelBox") {
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
w.destroy();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void clamp_page() {
|
|
Packit |
3ff832 |
Gtk.ListBoxRow row;
|
|
Packit |
3ff832 |
if (m_category_active_index >= 0) {
|
|
Packit |
3ff832 |
row = m_list_box.get_row_at_index(m_category_active_index);
|
|
Packit |
3ff832 |
m_list_box.select_row(row);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
row = m_list_box.get_row_at_index(0);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
Gtk.Allocation alloc = { 0, 0, 0, 0 };
|
|
Packit |
3ff832 |
row.get_allocation(out alloc);
|
|
Packit |
3ff832 |
var adjustment = m_scrolled_window.get_vadjustment();
|
|
Packit |
3ff832 |
adjustment.clamp_page(alloc.y, alloc.y + alloc.height);
|
|
Packit |
3ff832 |
return_val_if_fail(m_category_active_index >= 0, false);
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos((uint)m_category_active_index);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_category_list() {
|
|
Packit |
3ff832 |
// Do not call remove_all_children() to work adjustment.clamp_page()
|
|
Packit |
3ff832 |
// with PageUp/Down.
|
|
Packit |
3ff832 |
// After show_candidate_panel() is called, m_category_active_index
|
|
Packit |
3ff832 |
// is saved for Escape key but m_list_box is null by
|
|
Packit |
3ff832 |
// remove_all_children().
|
|
Packit |
3ff832 |
if (m_category_active_index >= 0 && m_list_box != null) {
|
|
Packit |
3ff832 |
var row = m_list_box.get_row_at_index(m_category_active_index);
|
|
Packit |
3ff832 |
m_list_box.select_row(row);
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_category_active_index < 0)
|
|
Packit |
3ff832 |
m_category_active_index = 0;
|
|
Packit |
3ff832 |
remove_all_children();
|
|
Packit |
3ff832 |
m_scrolled_window = new EScrolledWindow();
|
|
Packit |
3ff832 |
set_fixed_size();
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_vbox.add(m_scrolled_window);
|
|
Packit |
3ff832 |
Gtk.Viewport viewport = new Gtk.Viewport(null, null);
|
|
Packit |
3ff832 |
m_scrolled_window.add(viewport);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_list_box = new EListBox();
|
|
Packit |
3ff832 |
viewport.add(m_list_box);
|
|
Packit |
3ff832 |
Gtk.Adjustment adjustment = m_scrolled_window.get_vadjustment();
|
|
Packit |
3ff832 |
m_list_box.set_adjustment(adjustment);
|
|
Packit |
3ff832 |
m_list_box.row_activated.connect((box, gtkrow) => {
|
|
Packit |
3ff832 |
m_category_active_index = gtkrow.get_index();
|
|
Packit |
3ff832 |
EBoxRow row = gtkrow as EBoxRow;
|
|
Packit |
3ff832 |
show_emoji_for_category(row.text);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
Packit |
3ff832 |
for (uint i = 0; i < ncandidates; i++) {
|
|
Packit |
3ff832 |
string category = m_lookup_table.get_candidate(i).text;
|
|
Packit |
3ff832 |
EBoxRow row = new EBoxRow(category);
|
|
Packit |
3ff832 |
EPaddedLabelBox widget =
|
|
Packit |
3ff832 |
new EPaddedLabelBox(_(category), Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
row.add(widget);
|
|
Packit |
3ff832 |
m_list_box.add(row);
|
|
Packit |
3ff832 |
if (i == m_category_active_index)
|
|
Packit |
3ff832 |
m_list_box.select_row(row);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_scrolled_window.show_all();
|
|
Packit |
3ff832 |
if (m_category_active_index == -1)
|
|
Packit |
3ff832 |
m_list_box.unselect_all();
|
|
Packit |
3ff832 |
m_list_box.invalidate_filter();
|
|
Packit |
3ff832 |
m_list_box.set_selection_mode(Gtk.SelectionMode.SINGLE);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_emoji_for_category(string category) {
|
|
Packit |
3ff832 |
if (category == EMOJI_CATEGORY_FAVORITES) {
|
|
Packit |
3ff832 |
m_lookup_table.clear();
|
|
Packit |
3ff832 |
m_candidate_panel_mode = true;
|
|
Packit |
3ff832 |
foreach (unowned string favorate in m_favorites) {
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_string(favorate);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_backward = category;
|
|
Packit |
3ff832 |
} else if (category == EMOJI_CATEGORY_UNICODE) {
|
|
Packit |
3ff832 |
m_category_active_index = -1;
|
|
Packit |
3ff832 |
m_show_unicode = true;
|
|
Packit |
3ff832 |
update_unicode_blocks();
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
unowned GLib.SList<unowned string> emojis =
|
|
Packit |
3ff832 |
m_category_to_emojis_dict.lookup(category);
|
|
Packit |
3ff832 |
m_lookup_table.clear();
|
|
Packit |
3ff832 |
m_candidate_panel_mode = true;
|
|
Packit |
3ff832 |
foreach (unowned string emoji in emojis) {
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_string(emoji);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_backward = category;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_annotation = m_lookup_table.get_candidate(0).text;
|
|
Packit |
3ff832 |
// Restore the cursor position before the special table of
|
|
Packit |
3ff832 |
// emoji variants is shown.
|
|
Packit |
3ff832 |
if (m_backward_index >= 0) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos((uint)m_backward_index);
|
|
Packit |
3ff832 |
m_backward_index = -1;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_emoji_variants(GLib.SList<string>? emojis) {
|
|
Packit |
3ff832 |
m_backward_index = (int)m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
m_lookup_table.clear();
|
|
Packit |
3ff832 |
foreach (unowned string emoji in emojis) {
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_string(emoji);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_unicode_blocks() {
|
|
Packit |
3ff832 |
// Do not call remove_all_children() to work adjustment.clamp_page()
|
|
Packit |
3ff832 |
// with PageUp/Down.
|
|
Packit |
3ff832 |
// After show_candidate_panel() is called, m_category_active_index
|
|
Packit |
3ff832 |
// is saved for Escape key but m_list_box is null by
|
|
Packit |
3ff832 |
// remove_all_children().
|
|
Packit |
3ff832 |
if (m_category_active_index >= 0 && m_list_box != null) {
|
|
Packit |
3ff832 |
var row = m_list_box.get_row_at_index(m_category_active_index);
|
|
Packit |
3ff832 |
m_list_box.select_row(row);
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_category_active_index < 0)
|
|
Packit |
3ff832 |
m_category_active_index = 0;
|
|
Packit |
3ff832 |
m_show_unicode = true;
|
|
Packit |
3ff832 |
if (m_default_window_width == 0 && m_default_window_height == 0)
|
|
Packit |
3ff832 |
get_size(out m_default_window_width, out m_default_window_height);
|
|
Packit |
3ff832 |
remove_all_children();
|
|
Packit |
3ff832 |
set_fixed_size();
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
EPaddedLabelBox label =
|
|
Packit |
3ff832 |
new EPaddedLabelBox(_("Bring back emoji choice"),
|
|
Packit |
3ff832 |
Gtk.Align.CENTER,
|
|
Packit |
3ff832 |
TravelDirection.BACKWARD);
|
|
Packit |
3ff832 |
Gtk.Button button = new Gtk.Button();
|
|
Packit |
3ff832 |
button.add(label);
|
|
Packit |
3ff832 |
m_vbox.add(button);
|
|
Packit |
3ff832 |
button.show_all();
|
|
Packit |
3ff832 |
button.button_press_event.connect((w, e) => {
|
|
Packit |
3ff832 |
m_category_active_index = -1;
|
|
Packit |
3ff832 |
m_show_unicode = false;
|
|
Packit |
3ff832 |
hide_candidate_panel();
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
m_scrolled_window = new EScrolledWindow();
|
|
Packit |
3ff832 |
m_vbox.add(m_scrolled_window);
|
|
Packit |
3ff832 |
Gtk.Viewport viewport = new Gtk.Viewport(null, null);
|
|
Packit |
3ff832 |
m_scrolled_window.add(viewport);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_list_box = new EListBox();
|
|
Packit |
3ff832 |
viewport.add(m_list_box);
|
|
Packit |
3ff832 |
Gtk.Adjustment adjustment = m_scrolled_window.get_vadjustment();
|
|
Packit |
3ff832 |
m_list_box.set_adjustment(adjustment);
|
|
Packit |
3ff832 |
m_list_box.row_activated.connect((box, gtkrow) => {
|
|
Packit |
3ff832 |
m_category_active_index = gtkrow.get_index();
|
|
Packit |
3ff832 |
EBoxRow row = gtkrow as EBoxRow;
|
|
Packit |
3ff832 |
show_unicode_for_block(row.text);
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
uint n = 0;
|
|
Packit |
3ff832 |
foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
Packit |
3ff832 |
string name = block.get_name();
|
|
Packit |
3ff832 |
string caption = "U+%08X".printf(block.get_start());
|
|
Packit |
3ff832 |
EBoxRow row = new EBoxRow(name);
|
|
Packit |
3ff832 |
EPaddedLabelBox widget =
|
|
Packit |
3ff832 |
new EPaddedLabelBox(_(name),
|
|
Packit |
3ff832 |
Gtk.Align.CENTER,
|
|
Packit |
3ff832 |
TravelDirection.NONE,
|
|
Packit |
3ff832 |
caption);
|
|
Packit |
3ff832 |
row.add(widget);
|
|
Packit |
3ff832 |
m_list_box.add(row);
|
|
Packit |
3ff832 |
if (n++ == m_category_active_index) {
|
|
Packit |
3ff832 |
m_list_box.select_row(row);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
set_size_request(-1, m_default_window_height + 100);
|
|
Packit |
3ff832 |
m_scrolled_window.set_policy(Gtk.PolicyType.NEVER,
|
|
Packit |
3ff832 |
Gtk.PolicyType.AUTOMATIC);
|
|
Packit |
3ff832 |
m_scrolled_window.show_all();
|
|
Packit |
3ff832 |
if (m_category_active_index == -1)
|
|
Packit |
3ff832 |
m_list_box.unselect_all();
|
|
Packit |
3ff832 |
m_list_box.invalidate_filter();
|
|
Packit |
3ff832 |
m_list_box.set_selection_mode(Gtk.SelectionMode.SINGLE);
|
|
Packit |
3ff832 |
Gtk.ListBoxRow row = m_list_box.get_row_at_index((int)n - 1);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
// If clamp_page() would be called without the allocation signal,
|
|
Packit |
3ff832 |
// the jumping page could be failed when returns from
|
|
Packit |
3ff832 |
// show_unicode_for_block() with Escape key.
|
|
Packit |
3ff832 |
row.size_allocate.connect((w, a) => {
|
|
Packit |
3ff832 |
clamp_page();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_unicode_for_block(string block_name) {
|
|
Packit |
3ff832 |
unichar start = 0;
|
|
Packit |
3ff832 |
unichar end = 0;
|
|
Packit |
3ff832 |
foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
Packit |
3ff832 |
string name = block.get_name();
|
|
Packit |
3ff832 |
if (block_name == name) {
|
|
Packit |
3ff832 |
start = block.get_start();
|
|
Packit |
3ff832 |
end = block.get_end();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_lookup_table.clear();
|
|
Packit |
3ff832 |
m_candidate_panel_mode = true;
|
|
Packit |
3ff832 |
for (unichar ch = start; ch < end; ch++) {
|
|
Packit |
3ff832 |
unowned IBus.UnicodeData? data =
|
|
Packit |
3ff832 |
m_unicode_to_data_dict.lookup(ch);
|
|
Packit |
3ff832 |
if (data == null)
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_unichar(ch);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_backward = block_name;
|
|
Packit |
3ff832 |
if (m_lookup_table.get_number_of_candidates() > 0)
|
|
Packit |
3ff832 |
m_annotation = m_lookup_table.get_candidate(0).text;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_arrow_buttons() {
|
|
Packit |
3ff832 |
Gtk.Button next_button = new Gtk.Button();
|
|
Packit |
3ff832 |
next_button.clicked.connect(() => {
|
|
Packit |
3ff832 |
m_lookup_table.page_down();
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
next_button.set_image(new Gtk.Image.from_icon_name(
|
|
Packit |
3ff832 |
"go-down",
|
|
Packit |
3ff832 |
Gtk.IconSize.MENU));
|
|
Packit |
3ff832 |
next_button.set_relief(Gtk.ReliefStyle.NONE);
|
|
Packit |
3ff832 |
next_button.set_tooltip_text(_("Page Down"));
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gtk.Button prev_button = new Gtk.Button();
|
|
Packit |
3ff832 |
prev_button.clicked.connect(() => {
|
|
Packit |
3ff832 |
m_lookup_table.page_up();
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
prev_button.set_image(new Gtk.Image.from_icon_name(
|
|
Packit |
3ff832 |
"go-up",
|
|
Packit |
3ff832 |
Gtk.IconSize.MENU));
|
|
Packit |
3ff832 |
prev_button.set_relief(Gtk.ReliefStyle.NONE);
|
|
Packit |
3ff832 |
prev_button.set_tooltip_text(_("Page Up"));
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
var menu = new GLib.Menu();
|
|
Packit |
3ff832 |
menu.append(_("Show emoji variants"), "win.variant");
|
|
Packit |
3ff832 |
menu.append(_("Close"), "win.close");
|
|
Packit |
3ff832 |
var menu_button = new Gtk.MenuButton();
|
|
Packit |
3ff832 |
menu_button.set_direction(Gtk.ArrowType.NONE);
|
|
Packit |
3ff832 |
menu_button.set_valign(Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
menu_button.set_menu_model(menu);
|
|
Packit |
3ff832 |
menu_button.set_relief(Gtk.ReliefStyle.NONE);
|
|
Packit |
3ff832 |
menu_button.set_tooltip_text(_("Menu"));
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
IBus.Text text = this.get_title_text();
|
|
Packit |
3ff832 |
Pango.AttrList attrs = get_pango_attr_list_from_ibus_text(text);
|
|
Packit |
3ff832 |
Gtk.Label title_label = new Gtk.Label(text.get_text());
|
|
Packit |
3ff832 |
title_label.set_attributes(attrs);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gtk.Button? warning_button = null;
|
|
Packit |
3ff832 |
if (m_warning_message != "") {
|
|
Packit |
3ff832 |
warning_button = new Gtk.Button();
|
|
Packit |
3ff832 |
warning_button.set_tooltip_text(
|
|
Packit |
3ff832 |
_("Click to view a warning message"));
|
|
Packit |
3ff832 |
warning_button.set_image(new Gtk.Image.from_icon_name(
|
|
Packit |
3ff832 |
"dialog-warning",
|
|
Packit |
3ff832 |
Gtk.IconSize.MENU));
|
|
Packit |
3ff832 |
warning_button.set_relief(Gtk.ReliefStyle.NONE);
|
|
Packit |
3ff832 |
warning_button.clicked.connect(() => {
|
|
Packit |
3ff832 |
Gtk.Label warning_label = new Gtk.Label(m_warning_message);
|
|
Packit |
3ff832 |
warning_label.set_line_wrap(true);
|
|
Packit |
3ff832 |
warning_label.set_max_width_chars(40);
|
|
Packit |
3ff832 |
Gtk.Popover popover = new Gtk.Popover(warning_button);
|
|
Packit |
3ff832 |
popover.add(warning_label);
|
|
Packit |
3ff832 |
popover.show_all();
|
|
Packit |
3ff832 |
popover.popup();
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gtk.Box buttons_hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
|
|
Packit |
3ff832 |
Gtk.Label state_label = new Gtk.Label(null);
|
|
Packit |
3ff832 |
state_label.set_size_request(10, -1);
|
|
Packit |
3ff832 |
state_label.set_halign(Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
state_label.set_valign(Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
buttons_hbox.pack_start(state_label, false, true, 0);
|
|
Packit |
3ff832 |
buttons_hbox.pack_start(prev_button, false, false, 0);
|
|
Packit |
3ff832 |
buttons_hbox.pack_start(next_button, false, false, 0);
|
|
Packit |
3ff832 |
buttons_hbox.pack_start(title_label, false, false, 0);
|
|
Packit |
3ff832 |
if (warning_button != null)
|
|
Packit |
3ff832 |
buttons_hbox.pack_start(warning_button, false, false, 0);
|
|
Packit |
3ff832 |
buttons_hbox.pack_end(menu_button, false, false, 0);
|
|
Packit |
3ff832 |
m_vbox.pack_start(buttons_hbox, false, false, 0);
|
|
Packit |
3ff832 |
buttons_hbox.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_unicode_progress_bar() {
|
|
Packit |
3ff832 |
m_unicode_progress_bar = new Gtk.ProgressBar();
|
|
Packit |
3ff832 |
m_unicode_progress_bar.set_ellipsize(Pango.EllipsizeMode.MIDDLE);
|
|
Packit |
3ff832 |
m_unicode_progress_bar.set_halign(Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
m_unicode_progress_bar.set_valign(Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
m_vbox.add(m_unicode_progress_bar);
|
|
Packit |
3ff832 |
m_unicode_progress_bar.show();
|
|
Packit |
3ff832 |
var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
|
|
Packit |
3ff832 |
hbox.set_halign(Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
hbox.set_valign(Gtk.Align.CENTER);
|
|
Packit |
3ff832 |
m_vbox.add(hbox);
|
|
Packit |
3ff832 |
var label = new Gtk.Label(_("Loading a Unicode dictionary:"));
|
|
Packit |
3ff832 |
hbox.pack_start(label, false, true, 0);
|
|
Packit |
3ff832 |
m_unicode_percent_label = new Gtk.Label("");
|
|
Packit |
3ff832 |
hbox.pack_start(m_unicode_percent_label, false, true, 0);
|
|
Packit |
3ff832 |
hbox.show_all();
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_unicode_progress_object.deserialize_unicode.connect((i, n) => {
|
|
Packit |
3ff832 |
m_unicode_percent = (double)i / n;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
if (m_unicode_progress_id > 0) {
|
|
Packit |
3ff832 |
GLib.Source.remove(m_unicode_progress_id);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_unicode_progress_id = GLib.Timeout.add(100, () => {
|
|
Packit |
3ff832 |
m_unicode_progress_id = 0;
|
|
Packit |
3ff832 |
m_unicode_progress_bar.set_fraction(m_unicode_percent);
|
|
Packit |
3ff832 |
m_unicode_percent_label.set_text(
|
|
Packit |
3ff832 |
"%.0f%%\n".printf(m_unicode_percent * 100));
|
|
Packit |
3ff832 |
m_unicode_progress_bar.show();
|
|
Packit |
3ff832 |
m_unicode_percent_label.show();
|
|
Packit |
3ff832 |
if (m_loaded_unicode) {
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return !m_loaded_unicode;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static string? check_unicode_point(string annotation) {
|
|
Packit |
3ff832 |
string unicode_point = null;
|
|
Packit |
3ff832 |
// Add "0x" because uint64.ascii_strtoull() is not accessible
|
|
Packit |
3ff832 |
// and need to use uint64.parse()
|
|
Packit |
3ff832 |
var buff = new GLib.StringBuilder("0x");
|
|
Packit |
3ff832 |
var retval = new GLib.StringBuilder();
|
|
Packit |
3ff832 |
for (int i = 0; i < annotation.char_count(); i++) {
|
|
Packit |
3ff832 |
unichar ch = annotation.get_char(i);
|
|
Packit |
3ff832 |
if (ch == 0)
|
|
Packit |
3ff832 |
return null;
|
|
Packit |
3ff832 |
if (ch.isspace()) {
|
|
Packit |
3ff832 |
unichar code = (unichar)uint64.parse(buff.str);
|
|
Packit |
3ff832 |
buff.assign("0x");
|
|
Packit |
3ff832 |
if (!code.validate())
|
|
Packit |
3ff832 |
return null;
|
|
Packit |
3ff832 |
retval.append(code.to_string());
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (!ch.isxdigit())
|
|
Packit |
3ff832 |
return null;
|
|
Packit |
3ff832 |
buff.append_unichar(ch);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
unichar code = (unichar)uint64.parse(buff.str);
|
|
Packit |
3ff832 |
if (!code.validate())
|
|
Packit |
3ff832 |
return null;
|
|
Packit |
3ff832 |
retval.append(code.to_string());
|
|
Packit |
3ff832 |
unicode_point = retval.str;
|
|
Packit |
3ff832 |
if (unicode_point == null)
|
|
Packit |
3ff832 |
return null;
|
|
Packit |
3ff832 |
return unicode_point;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static GLib.SList<string>?
|
|
Packit |
3ff832 |
lookup_emojis_from_annotation(string annotation) {
|
|
Packit |
3ff832 |
GLib.SList<string>? total_emojis = null;
|
|
Packit |
3ff832 |
unowned GLib.SList<string>? sub_emojis = null;
|
|
Packit |
3ff832 |
unowned GLib.SList<unichar>? sub_exact_unicodes = null;
|
|
Packit |
3ff832 |
unowned GLib.SList<unichar>? sub_unicodes = null;
|
|
Packit |
3ff832 |
int length = annotation.length;
|
|
Packit |
3ff832 |
if (m_has_partial_match && length >= m_partial_match_length) {
|
|
Packit |
3ff832 |
GLib.SList<string>? sorted_emojis = null;
|
|
Packit |
3ff832 |
foreach (unowned string key in
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict.get_keys()) {
|
|
Packit |
3ff832 |
if (key.length < length)
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
bool matched = false;
|
|
Packit |
3ff832 |
switch(m_partial_match_condition) {
|
|
Packit |
3ff832 |
case 0:
|
|
Packit |
3ff832 |
if (key.has_prefix(annotation))
|
|
Packit |
3ff832 |
matched = true;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case 1:
|
|
Packit |
3ff832 |
if (key.has_suffix(annotation))
|
|
Packit |
3ff832 |
matched = true;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case 2:
|
|
Packit |
3ff832 |
if (key.index_of(annotation) >= 0)
|
|
Packit |
3ff832 |
matched = true;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
default:
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (!matched)
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
sub_emojis = m_annotation_to_emojis_dict.lookup(key);
|
|
Packit |
3ff832 |
foreach (unowned string emoji in sub_emojis) {
|
|
Packit |
3ff832 |
if (total_emojis.find_custom(emoji, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
sorted_emojis.insert_sorted(emoji, GLib.strcmp);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
foreach (string emoji in sorted_emojis) {
|
|
Packit |
3ff832 |
if (total_emojis.find_custom(emoji, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
total_emojis.append(emoji);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
sub_emojis = m_annotation_to_emojis_dict.lookup(annotation);
|
|
Packit |
3ff832 |
foreach (unowned string emoji in sub_emojis)
|
|
Packit |
3ff832 |
total_emojis.append(emoji);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
sub_exact_unicodes = m_name_to_unicodes_dict.lookup(annotation);
|
|
Packit |
3ff832 |
foreach (unichar code in sub_exact_unicodes) {
|
|
Packit |
3ff832 |
string ch = code.to_string();
|
|
Packit |
3ff832 |
if (total_emojis.find_custom(ch, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
total_emojis.append(ch);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (length >= m_partial_match_length) {
|
|
Packit |
3ff832 |
GLib.SList<string>? sorted_unicodes = null;
|
|
Packit |
3ff832 |
foreach (unowned string key in m_name_to_unicodes_dict.get_keys()) {
|
|
Packit |
3ff832 |
bool matched = false;
|
|
Packit |
3ff832 |
if (key.index_of(annotation) >= 0)
|
|
Packit |
3ff832 |
matched = true;
|
|
Packit |
3ff832 |
if (!matched)
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
sub_unicodes = m_name_to_unicodes_dict.lookup(key);
|
|
Packit |
3ff832 |
foreach (unichar code in sub_unicodes) {
|
|
Packit |
3ff832 |
string ch = code.to_string();
|
|
Packit |
3ff832 |
if (sorted_unicodes.find_custom(ch, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
sorted_unicodes.insert_sorted(ch, GLib.strcmp);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
foreach (string ch in sorted_unicodes) {
|
|
Packit |
3ff832 |
if (total_emojis.find_custom(ch, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
total_emojis.append(ch);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return total_emojis;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void update_candidate_window() {
|
|
Packit |
3ff832 |
string annotation = m_annotation;
|
|
Packit |
3ff832 |
if (annotation.length == 0) {
|
|
Packit |
3ff832 |
m_backward = null;
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_lookup_table.clear();
|
|
Packit |
3ff832 |
m_category_active_index = -1;
|
|
Packit |
3ff832 |
if (annotation.length > m_emoji_max_seq_len) {
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
string? unicode_point = check_unicode_point(annotation);
|
|
Packit |
3ff832 |
GLib.SList<string>? total_emojis = null;
|
|
Packit |
3ff832 |
if (annotation.ascii_casecmp("history") == 0) {
|
|
Packit |
3ff832 |
for (int i = 0; i < m_favorites.length; i++) {
|
|
Packit |
3ff832 |
total_emojis.append(m_favorites[i].dup());
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (total_emojis == null)
|
|
Packit |
3ff832 |
total_emojis = lookup_emojis_from_annotation(annotation);
|
|
Packit |
3ff832 |
if (total_emojis == null) {
|
|
Packit |
3ff832 |
/* Users can type title strings against lower case.
|
|
Packit |
3ff832 |
* E.g. "Smile" against "smile"
|
|
Packit |
3ff832 |
* But the dictionary has the case sensitive annotations.
|
|
Packit |
3ff832 |
* E.g. ":D" and ":q"
|
|
Packit |
3ff832 |
* So need to call lookup_emojis_from_annotation() twice.
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
annotation = annotation.down();
|
|
Packit |
3ff832 |
total_emojis = lookup_emojis_from_annotation(annotation);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (total_emojis == null && unicode_point == null) {
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (unicode_point != null) {
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_string(unicode_point);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
foreach (unowned string emoji in total_emojis) {
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_string(emoji);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_candidate_panel_is_visible =
|
|
Packit |
3ff832 |
(m_lookup_table.get_number_of_candidates() > 0) ? true : false;
|
|
Packit |
3ff832 |
m_candidate_panel_mode = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void update_category_list() {
|
|
Packit |
3ff832 |
// Always update m_lookup_table even if the contents are same
|
|
Packit |
3ff832 |
// because m_category_active_index needs to be kept after
|
|
Packit |
3ff832 |
// bring back this API from show_emoji_for_category().
|
|
Packit |
3ff832 |
reset_window_mode();
|
|
Packit |
3ff832 |
m_lookup_table.clear();
|
|
Packit |
3ff832 |
IBus.Text text;
|
|
Packit |
3ff832 |
if (m_favorites.length > 0) {
|
|
Packit |
3ff832 |
text = new IBus.Text.from_string(EMOJI_CATEGORY_FAVORITES);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
GLib.List<unowned string> categories =
|
|
Packit |
3ff832 |
m_category_to_emojis_dict.get_keys();
|
|
Packit |
3ff832 |
// FIXME: How to cast GLib.CompareFunc<string> to strcmp?
|
|
Packit |
3ff832 |
categories.sort((a, b) => {
|
|
Packit |
3ff832 |
if (a == EMOJI_CATEGORY_OTHERS && b != EMOJI_CATEGORY_OTHERS)
|
|
Packit |
3ff832 |
return 1;
|
|
Packit |
3ff832 |
else if (a != EMOJI_CATEGORY_OTHERS && b == EMOJI_CATEGORY_OTHERS)
|
|
Packit |
3ff832 |
return -1;
|
|
Packit |
3ff832 |
return GLib.strcmp(_(a), _(b));
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
foreach (unowned string category in categories) {
|
|
Packit |
3ff832 |
// "Others" category includes next unicode chars and fonts do not
|
|
Packit |
3ff832 |
// support the base and varints yet.
|
|
Packit |
3ff832 |
if (category == EMOJI_CATEGORY_OTHERS)
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
text = new IBus.Text.from_string(category);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_unicode_block_list.length() > 0) {
|
|
Packit |
3ff832 |
text = new IBus.Text.from_string(EMOJI_CATEGORY_UNICODE);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
// Do not set m_category_active_index to 0 here so that
|
|
Packit |
3ff832 |
// show_category_list() handles it.
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void update_unicode_blocks() {
|
|
Packit |
3ff832 |
// Always update m_lookup_table even if the contents are same
|
|
Packit |
3ff832 |
// because m_category_active_index needs to be kept after
|
|
Packit |
3ff832 |
// bring back this API from show_emoji_for_category().
|
|
Packit |
3ff832 |
reset_window_mode();
|
|
Packit |
3ff832 |
m_lookup_table.clear();
|
|
Packit |
3ff832 |
m_show_unicode = true;
|
|
Packit |
3ff832 |
foreach (unowned IBus.UnicodeBlock block in m_unicode_block_list) {
|
|
Packit |
3ff832 |
string name = block.get_name();
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_string(name);
|
|
Packit |
3ff832 |
m_lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
// Do not set m_category_active_index to 0 here so that
|
|
Packit |
3ff832 |
// show_unicode_blocks() handles it.
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_code_point_description(string text) {
|
|
Packit |
3ff832 |
EPaddedLabelBox widget_code = new EPaddedLabelBox(
|
|
Packit |
3ff832 |
_("Code point: %s").printf(utf8_code_point(text)),
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget_code);
|
|
Packit |
3ff832 |
widget_code.show_all();
|
|
Packit |
3ff832 |
if (m_emoji_to_emoji_variants_dict.lookup(text) != null) {
|
|
Packit |
3ff832 |
EPaddedLabelBox widget_has_variant = new EPaddedLabelBox(
|
|
Packit |
3ff832 |
_("Has emoji variants"),
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget_has_variant);
|
|
Packit |
3ff832 |
widget_has_variant.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_candidate_panel() {
|
|
Packit |
3ff832 |
remove_all_children();
|
|
Packit |
3ff832 |
set_fixed_size();
|
|
Packit |
3ff832 |
if (m_emoji_font_changed) {
|
|
Packit |
3ff832 |
set_css_data();
|
|
Packit |
3ff832 |
m_emoji_font_changed = false;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
uint page_size = m_lookup_table.get_page_size();
|
|
Packit |
3ff832 |
uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
Packit |
3ff832 |
uint cursor = m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
uint page_start_pos = cursor / page_size * page_size;
|
|
Packit |
3ff832 |
uint page_end_pos = uint.min(page_start_pos + page_size, ncandidates);
|
|
Packit |
3ff832 |
Gtk.Button? backward_button = null;
|
|
Packit |
3ff832 |
if (m_backward != null) {
|
|
Packit |
3ff832 |
string backward_desc = _(m_backward);
|
|
Packit |
3ff832 |
EPaddedLabelBox label =
|
|
Packit |
3ff832 |
new EPaddedLabelBox(backward_desc,
|
|
Packit |
3ff832 |
Gtk.Align.CENTER,
|
|
Packit |
3ff832 |
TravelDirection.BACKWARD);
|
|
Packit |
3ff832 |
backward_button = new Gtk.Button();
|
|
Packit |
3ff832 |
backward_button.add(label);
|
|
Packit |
3ff832 |
backward_button.button_press_event.connect((w, e) => {
|
|
Packit |
3ff832 |
// Bring back to emoji candidate panel in case
|
|
Packit |
3ff832 |
// m_show_emoji_variant is enabled and shows variants.
|
|
Packit |
3ff832 |
if (m_backward_index >= 0 && m_backward != null) {
|
|
Packit |
3ff832 |
show_emoji_for_category(m_backward);
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
hide_candidate_panel();
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
EGrid grid = new EGrid();
|
|
Packit |
3ff832 |
int n = 0;
|
|
Packit |
3ff832 |
for (uint i = page_start_pos; i < page_end_pos; i++) {
|
|
Packit |
3ff832 |
string text = m_lookup_table.get_candidate(i).text;
|
|
Packit |
3ff832 |
bool has_variant =
|
|
Packit |
3ff832 |
(m_emoji_to_emoji_variants_dict.lookup(text) != null);
|
|
Packit |
3ff832 |
Gtk.Label label;
|
|
Packit |
3ff832 |
// If 'i' is the cursor position, use the selected color.
|
|
Packit |
3ff832 |
// If the emoji has emoji variants, use the gold color.
|
|
Packit |
3ff832 |
// Otherwise the white color.
|
|
Packit |
3ff832 |
if (i == cursor) {
|
|
Packit |
3ff832 |
label = new ESelectedLabel(text) as Gtk.Label;
|
|
Packit |
3ff832 |
} else if (m_show_emoji_variant && has_variant &&
|
|
Packit |
3ff832 |
m_backward_index < 0) {
|
|
Packit |
3ff832 |
label = new EGoldLabel(text) as Gtk.Label;
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
label = new EWhiteLabel(text) as Gtk.Label;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (text.char_count() > 2) {
|
|
Packit |
3ff832 |
string font_family = m_emoji_font_family;
|
|
Packit |
3ff832 |
int font_size = m_emoji_font_size - 2;
|
|
Packit |
3ff832 |
string emoji_font = "%s %d".printf(font_family, font_size);
|
|
Packit |
3ff832 |
string markup = "%s".
|
|
Packit |
3ff832 |
printf(emoji_font, utf8_entity(text));
|
|
Packit |
3ff832 |
label.set_markup(markup);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
label.set_halign(Gtk.Align.FILL);
|
|
Packit |
3ff832 |
label.set_valign(Gtk.Align.FILL);
|
|
Packit |
3ff832 |
Gtk.EventBox candidate_ebox = new Gtk.EventBox();
|
|
Packit |
3ff832 |
candidate_ebox.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
|
|
Packit |
3ff832 |
candidate_ebox.add(label);
|
|
Packit |
3ff832 |
// Make a copy of i to workaround a bug in vala.
|
|
Packit |
3ff832 |
// https://bugzilla.gnome.org/show_bug.cgi?id=628336
|
|
Packit |
3ff832 |
uint index = i;
|
|
Packit |
3ff832 |
candidate_ebox.button_press_event.connect((w, e) => {
|
|
Packit |
3ff832 |
candidate_clicked(index, e.button, e.state);
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
candidate_ebox.motion_notify_event.connect((e) => {
|
|
Packit |
3ff832 |
// m_enter_notify_enable is added because
|
|
Packit |
3ff832 |
// enter_notify_event conflicts with keyboard operations.
|
|
Packit |
3ff832 |
if (!m_enter_notify_enable)
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
if (m_lookup_table.get_cursor_pos() == index)
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
#if VALA_0_24
|
|
Packit |
3ff832 |
Gdk.EventMotion pe = e;
|
|
Packit |
3ff832 |
#else
|
|
Packit |
3ff832 |
Gdk.EventMotion *pe = &e;
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
if (m_mouse_x == pe.x_root && m_mouse_y == pe.y_root)
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
m_mouse_x = pe.x_root;
|
|
Packit |
3ff832 |
m_mouse_y = pe.y_root;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(index);
|
|
Packit |
3ff832 |
if (m_entry_notify_show_id > 0 &&
|
|
Packit |
3ff832 |
GLib.MainContext.default().find_source_by_id(
|
|
Packit |
3ff832 |
m_entry_notify_show_id) != null) {
|
|
Packit |
3ff832 |
GLib.Source.remove(m_entry_notify_show_id);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
// If timeout is not added, memory leak happens and
|
|
Packit |
3ff832 |
// button_press_event signal does not work above.
|
|
Packit |
3ff832 |
m_entry_notify_show_id = GLib.Timeout.add(100, () => {
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
grid.attach(candidate_ebox,
|
|
Packit |
3ff832 |
n % (int)EMOJI_GRID_PAGE, n / (int)EMOJI_GRID_PAGE,
|
|
Packit |
3ff832 |
1, 1);
|
|
Packit |
3ff832 |
n++;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_candidates += label;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_candidate_panel_is_visible = true;
|
|
Packit |
3ff832 |
if (!m_is_up_side_down) {
|
|
Packit |
3ff832 |
show_arrow_buttons();
|
|
Packit |
3ff832 |
if (backward_button != null) {
|
|
Packit |
3ff832 |
m_vbox.add(backward_button);
|
|
Packit |
3ff832 |
backward_button.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (n > 0) {
|
|
Packit |
3ff832 |
m_vbox.add(grid);
|
|
Packit |
3ff832 |
grid.show_all();
|
|
Packit |
3ff832 |
show_description();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (!m_loaded_unicode)
|
|
Packit |
3ff832 |
show_unicode_progress_bar();
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
if (!m_loaded_unicode)
|
|
Packit |
3ff832 |
show_unicode_progress_bar();
|
|
Packit |
3ff832 |
if (n > 0) {
|
|
Packit |
3ff832 |
show_description();
|
|
Packit |
3ff832 |
m_vbox.add(grid);
|
|
Packit |
3ff832 |
grid.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (backward_button != null) {
|
|
Packit |
3ff832 |
m_vbox.add(backward_button);
|
|
Packit |
3ff832 |
backward_button.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
show_arrow_buttons();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_description() {
|
|
Packit |
3ff832 |
uint cursor = m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
string text = m_lookup_table.get_candidate(cursor).text;
|
|
Packit |
3ff832 |
unowned IBus.EmojiData? data = m_emoji_to_data_dict.lookup(text);
|
|
Packit |
3ff832 |
if (data != null) {
|
|
Packit |
3ff832 |
show_emoji_description(data, text);
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (text.char_count() <= 1) {
|
|
Packit |
3ff832 |
unichar code = text.get_char();
|
|
Packit |
3ff832 |
unowned IBus.UnicodeData? udata =
|
|
Packit |
3ff832 |
m_unicode_to_data_dict.lookup(code);
|
|
Packit |
3ff832 |
if (udata != null) {
|
|
Packit |
3ff832 |
show_unicode_description(udata, text);
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
Packit |
3ff832 |
_("Description: %s").printf(_("None")),
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget);
|
|
Packit |
3ff832 |
widget.show_all();
|
|
Packit |
3ff832 |
show_code_point_description(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_emoji_description(IBus.EmojiData data,
|
|
Packit |
3ff832 |
string text) {
|
|
Packit |
3ff832 |
unowned string description = data.get_description();
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
Packit |
3ff832 |
_("Description: %s").printf(description),
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget);
|
|
Packit |
3ff832 |
widget.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
unowned GLib.SList<unowned string>? annotations =
|
|
Packit |
3ff832 |
data.get_annotations();
|
|
Packit |
3ff832 |
var buff = new GLib.StringBuilder();
|
|
Packit |
3ff832 |
int i = 0;
|
|
Packit |
3ff832 |
foreach (unowned string annotation in annotations) {
|
|
Packit |
3ff832 |
if (i++ == 0)
|
|
Packit |
3ff832 |
buff.append_printf(_("Annotations: %s"), annotation);
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
buff.append_printf(" | %s", annotation);
|
|
Packit |
3ff832 |
if (buff.str.char_count() > 30) {
|
|
Packit |
3ff832 |
EPaddedLabelBox widget =
|
|
Packit |
3ff832 |
new EPaddedLabelBox(buff.str,
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget);
|
|
Packit |
3ff832 |
widget.show_all();
|
|
Packit |
3ff832 |
buff.erase();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (buff.str != "") {
|
|
Packit |
3ff832 |
EPaddedLabelBox widget = new EPaddedLabelBox(buff.str,
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget);
|
|
Packit |
3ff832 |
widget.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
show_code_point_description(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void show_unicode_description(IBus.UnicodeData data,
|
|
Packit |
3ff832 |
string text) {
|
|
Packit |
3ff832 |
unowned string name = data.get_name();
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
Packit |
3ff832 |
_("Name: %s").printf(name),
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget);
|
|
Packit |
3ff832 |
widget.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
unowned string alias = data.get_alias();
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
EPaddedLabelBox widget = new EPaddedLabelBox(
|
|
Packit |
3ff832 |
_("Alias: %s").printf(alias),
|
|
Packit |
3ff832 |
Gtk.Align.START);
|
|
Packit |
3ff832 |
m_vbox.add(widget);
|
|
Packit |
3ff832 |
widget.show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
show_code_point_description(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void hide_candidate_panel() {
|
|
Packit |
3ff832 |
hide();
|
|
Packit |
3ff832 |
m_enter_notify_enable = true;
|
|
Packit |
3ff832 |
m_annotation = "";
|
|
Packit |
3ff832 |
// Call remove_all_children() instead of show_category_list()
|
|
Packit |
3ff832 |
// so that show_category_list do not remove children with
|
|
Packit |
3ff832 |
// PageUp/PageDown.
|
|
Packit |
3ff832 |
remove_all_children();
|
|
Packit |
3ff832 |
if (m_show_unicode)
|
|
Packit |
3ff832 |
update_unicode_blocks();
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
update_category_list();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void enter_notify_disable_with_timer() {
|
|
Packit |
3ff832 |
// Enable keyboard operation and disable mouse operation.
|
|
Packit |
3ff832 |
m_enter_notify_enable = false;
|
|
Packit |
3ff832 |
if (m_entry_notify_disable_id > 0) {
|
|
Packit |
3ff832 |
GLib.Source.remove(m_entry_notify_disable_id);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
// Bring back the mouse operation after a timeout.
|
|
Packit |
3ff832 |
m_entry_notify_show_id = GLib.Timeout.add(100, () => {
|
|
Packit |
3ff832 |
m_enter_notify_enable = true;
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void candidate_panel_select_index(uint index,
|
|
Packit |
3ff832 |
uint button) {
|
|
Packit |
3ff832 |
if (button == BUTTON_CLOSE_BUTTON) {
|
|
Packit |
3ff832 |
hide();
|
|
Packit |
3ff832 |
if (m_candidate_panel_mode &&
|
|
Packit |
3ff832 |
m_lookup_table.get_number_of_candidates() > 0) {
|
|
Packit |
3ff832 |
// Call remove_all_children() instead of show_category_list()
|
|
Packit |
3ff832 |
// so that show_category_list do not remove children with
|
|
Packit |
3ff832 |
// PageUp/PageDown.
|
|
Packit |
3ff832 |
remove_all_children();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
m_result = "";
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
string text = m_lookup_table.get_candidate(index).text;
|
|
Packit |
3ff832 |
unowned GLib.SList<string>? emojis =
|
|
Packit |
3ff832 |
m_emoji_to_emoji_variants_dict.lookup(text);
|
|
Packit |
3ff832 |
if (m_show_emoji_variant && emojis != null &&
|
|
Packit |
3ff832 |
m_backward_index < 0) {
|
|
Packit |
3ff832 |
show_emoji_variants(emojis);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
m_result = text;
|
|
Packit |
3ff832 |
hide();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void candidate_panel_cursor_down() {
|
|
Packit |
3ff832 |
enter_notify_disable_with_timer();
|
|
Packit |
3ff832 |
uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
Packit |
3ff832 |
uint cursor = m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
if ((cursor + EMOJI_GRID_PAGE) < ncandidates) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(cursor + EMOJI_GRID_PAGE);
|
|
Packit |
3ff832 |
} else if (cursor % EMOJI_GRID_PAGE < ncandidates) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(cursor % EMOJI_GRID_PAGE);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(0);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void candidate_panel_cursor_up() {
|
|
Packit |
3ff832 |
enter_notify_disable_with_timer();
|
|
Packit |
3ff832 |
int ncandidates = (int)m_lookup_table.get_number_of_candidates();
|
|
Packit |
3ff832 |
int cursor = (int)m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
int highest_pos =
|
|
Packit |
3ff832 |
((ncandidates - 1)/ (int)EMOJI_GRID_PAGE * (int)EMOJI_GRID_PAGE)
|
|
Packit |
3ff832 |
+ (cursor % (int)EMOJI_GRID_PAGE);
|
|
Packit |
3ff832 |
if ((cursor - (int)EMOJI_GRID_PAGE) >= 0) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(cursor - (int)EMOJI_GRID_PAGE);
|
|
Packit |
3ff832 |
} else if (highest_pos < ncandidates) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(highest_pos);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(0);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private int get_page_num() {
|
|
Packit |
3ff832 |
if (m_category_active_index < 0)
|
|
Packit |
3ff832 |
m_category_active_index = 0;
|
|
Packit |
3ff832 |
var row = m_list_box.get_row_at_index(m_category_active_index);
|
|
Packit |
3ff832 |
Gtk.Allocation alloc = { 0, 0, 0, 0 };
|
|
Packit |
3ff832 |
row.get_allocation(out alloc);
|
|
Packit |
3ff832 |
var adjustment = m_scrolled_window.get_vadjustment();
|
|
Packit |
3ff832 |
var page_size = (int)adjustment.get_page_size();
|
|
Packit |
3ff832 |
int page_num = page_size / alloc.height;
|
|
Packit |
3ff832 |
page_num += ((page_size % alloc.height) > 0) ? 1 : 0;
|
|
Packit |
3ff832 |
return page_num;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private bool category_list_cursor_move(uint keyval) {
|
|
Packit |
3ff832 |
return_val_if_fail (m_list_box != null, false);
|
|
Packit |
3ff832 |
GLib.List<weak Gtk.Widget> list = m_list_box.get_children();
|
|
Packit |
3ff832 |
int length = (int)list.length();
|
|
Packit |
3ff832 |
if (length == 0)
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
switch(keyval) {
|
|
Packit |
3ff832 |
case Gdk.Key.Down:
|
|
Packit |
3ff832 |
if (++m_category_active_index == length)
|
|
Packit |
3ff832 |
m_category_active_index = 0;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Up:
|
|
Packit |
3ff832 |
if (--m_category_active_index < 0)
|
|
Packit |
3ff832 |
m_category_active_index = length - 1;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Home:
|
|
Packit |
3ff832 |
m_category_active_index = 0;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.End:
|
|
Packit |
3ff832 |
m_category_active_index = length - 1;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Page_Down:
|
|
Packit |
3ff832 |
var page_num = get_page_num();
|
|
Packit |
3ff832 |
if (m_category_active_index + 1 == length)
|
|
Packit |
3ff832 |
m_category_active_index = 0;
|
|
Packit |
3ff832 |
else if (m_category_active_index + page_num >= length)
|
|
Packit |
3ff832 |
m_category_active_index = length - 1;
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
m_category_active_index += page_num;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Page_Up:
|
|
Packit |
3ff832 |
var page_num = get_page_num();
|
|
Packit |
3ff832 |
if (m_category_active_index == 0)
|
|
Packit |
3ff832 |
m_category_active_index = length - 1;
|
|
Packit |
3ff832 |
else if (m_category_active_index - page_num < 0)
|
|
Packit |
3ff832 |
m_category_active_index = 0;
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
m_category_active_index -= page_num;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
var row = m_list_box.get_selected_row();
|
|
Packit |
3ff832 |
if (row != null)
|
|
Packit |
3ff832 |
m_list_box.unselect_row(row);
|
|
Packit |
3ff832 |
clamp_page ();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool has_variants(uint index) {
|
|
Packit |
3ff832 |
if (index >= m_lookup_table.get_number_of_candidates())
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
string text = m_lookup_table.get_candidate(index).text;
|
|
Packit |
3ff832 |
unowned GLib.SList<string>? emojis =
|
|
Packit |
3ff832 |
m_emoji_to_emoji_variants_dict.lookup(text);
|
|
Packit |
3ff832 |
if (m_show_emoji_variant && emojis != null &&
|
|
Packit |
3ff832 |
m_backward_index < 0) {
|
|
Packit |
3ff832 |
show_emoji_variants(emojis);
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool key_press_cursor_horizontal(uint keyval,
|
|
Packit |
3ff832 |
uint modifiers) {
|
|
Packit |
3ff832 |
assert (keyval == Gdk.Key.Left || keyval == Gdk.Key.Right);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (m_candidate_panel_mode &&
|
|
Packit |
3ff832 |
m_lookup_table.get_number_of_candidates() > 0) {
|
|
Packit |
3ff832 |
enter_notify_disable_with_timer();
|
|
Packit |
3ff832 |
if (keyval == Gdk.Key.Left)
|
|
Packit |
3ff832 |
m_lookup_table.cursor_up();
|
|
Packit |
3ff832 |
else if (keyval == Gdk.Key.Right)
|
|
Packit |
3ff832 |
m_lookup_table.cursor_down();
|
|
Packit |
3ff832 |
} else if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
int step = 0;
|
|
Packit |
3ff832 |
if (keyval == Gdk.Key.Left)
|
|
Packit |
3ff832 |
step = -1;
|
|
Packit |
3ff832 |
else if (keyval == Gdk.Key.Right)
|
|
Packit |
3ff832 |
step = 1;
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(
|
|
Packit |
3ff832 |
m_entry, "move-cursor",
|
|
Packit |
3ff832 |
Gtk.MovementStep.VISUAL_POSITIONS,
|
|
Packit |
3ff832 |
step,
|
|
Packit |
3ff832 |
(modifiers & Gdk.ModifierType.SHIFT_MASK) != 0
|
|
Packit |
3ff832 |
? true : false);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
// For Gdk.Key.f and Gdk.Key.b
|
|
Packit |
3ff832 |
if (keyval == Gdk.Key.Left)
|
|
Packit |
3ff832 |
keyval = Gdk.Key.Up;
|
|
Packit |
3ff832 |
else if (keyval == Gdk.Key.Right)
|
|
Packit |
3ff832 |
keyval = Gdk.Key.Down;
|
|
Packit |
3ff832 |
return category_list_cursor_move(keyval);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool key_press_cursor_vertical(uint keyval,
|
|
Packit |
3ff832 |
uint modifiers) {
|
|
Packit |
3ff832 |
assert (keyval == Gdk.Key.Down || keyval == Gdk.Key.Up ||
|
|
Packit |
3ff832 |
keyval == Gdk.Key.Page_Down || keyval == Gdk.Key.Page_Up);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
|
|
Packit |
3ff832 |
if (keyval == Gdk.Key.Down)
|
|
Packit |
3ff832 |
keyval = Gdk.Key.Page_Down;
|
|
Packit |
3ff832 |
else if (keyval == Gdk.Key.Up)
|
|
Packit |
3ff832 |
keyval = Gdk.Key.Page_Up;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if ((m_candidate_panel_is_visible || m_annotation.length > 0)
|
|
Packit |
3ff832 |
&& m_lookup_table.get_number_of_candidates() > 0) {
|
|
Packit |
3ff832 |
switch (keyval) {
|
|
Packit |
3ff832 |
case Gdk.Key.Down:
|
|
Packit |
3ff832 |
candidate_panel_cursor_down();
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Up:
|
|
Packit |
3ff832 |
candidate_panel_cursor_up();
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Page_Down:
|
|
Packit |
3ff832 |
enter_notify_disable_with_timer();
|
|
Packit |
3ff832 |
m_lookup_table.page_down();
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Page_Up:
|
|
Packit |
3ff832 |
enter_notify_disable_with_timer();
|
|
Packit |
3ff832 |
m_lookup_table.page_up();
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
return category_list_cursor_move(keyval);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool key_press_cursor_home_end(uint keyval,
|
|
Packit |
3ff832 |
uint modifiers) {
|
|
Packit |
3ff832 |
assert (keyval == Gdk.Key.Home || keyval == Gdk.Key.End);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
uint ncandidates = m_lookup_table.get_number_of_candidates();
|
|
Packit |
3ff832 |
if (m_candidate_panel_mode && ncandidates > 0) {
|
|
Packit |
3ff832 |
enter_notify_disable_with_timer();
|
|
Packit |
3ff832 |
if (keyval == Gdk.Key.Home) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(0);
|
|
Packit |
3ff832 |
} else if (keyval == Gdk.Key.End) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(ncandidates - 1);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
int step = 0;
|
|
Packit |
3ff832 |
if (keyval == Gdk.Key.Home)
|
|
Packit |
3ff832 |
step = -1;
|
|
Packit |
3ff832 |
else if (keyval == Gdk.Key.End)
|
|
Packit |
3ff832 |
step = 1;
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(
|
|
Packit |
3ff832 |
m_entry, "move-cursor",
|
|
Packit |
3ff832 |
Gtk.MovementStep.DISPLAY_LINE_ENDS,
|
|
Packit |
3ff832 |
step,
|
|
Packit |
3ff832 |
(modifiers & Gdk.ModifierType.SHIFT_MASK) != 0
|
|
Packit |
3ff832 |
? true : false);
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return category_list_cursor_move(keyval);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool key_press_escape() {
|
|
Packit |
3ff832 |
if (m_show_unicode) {
|
|
Packit |
3ff832 |
if (!m_candidate_panel_is_visible) {
|
|
Packit |
3ff832 |
m_show_unicode = false;
|
|
Packit |
3ff832 |
m_category_active_index = -1;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
hide_candidate_panel();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
} else if (m_backward_index >= 0 && m_backward != null) {
|
|
Packit |
3ff832 |
show_emoji_for_category(m_backward);
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
} else if (m_candidate_panel_is_visible && m_backward != null) {
|
|
Packit |
3ff832 |
hide_candidate_panel();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
hide();
|
|
Packit |
3ff832 |
if (m_candidate_panel_mode &&
|
|
Packit |
3ff832 |
m_lookup_table.get_number_of_candidates() > 0) {
|
|
Packit |
3ff832 |
// Call remove_all_children() instead of show_category_list()
|
|
Packit |
3ff832 |
// so that show_category_list do not remove children with
|
|
Packit |
3ff832 |
// PageUp/PageDown.
|
|
Packit |
3ff832 |
remove_all_children();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool key_press_enter() {
|
|
Packit |
3ff832 |
if (m_candidate_panel_is_visible) {
|
|
Packit |
3ff832 |
uint index = m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
return has_variants(index);
|
|
Packit |
3ff832 |
} else if (m_category_active_index >= 0) {
|
|
Packit |
3ff832 |
Gtk.ListBoxRow gtkrow = m_list_box.get_selected_row();
|
|
Packit |
3ff832 |
EBoxRow row = gtkrow as EBoxRow;
|
|
Packit |
3ff832 |
if (m_show_unicode)
|
|
Packit |
3ff832 |
show_unicode_for_block(row.text);
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
show_emoji_for_category(row.text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void entry_enter_keyval(uint keyval) {
|
|
Packit |
3ff832 |
unichar ch = IBus.keyval_to_unicode(keyval);
|
|
Packit |
3ff832 |
if (ch.iscntrl())
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
string str = ch.to_string();
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
// what gtk_entry_commit_cb() do
|
|
Packit |
3ff832 |
if (m_entry.get_selection_bounds(null, null)) {
|
|
Packit |
3ff832 |
m_entry.delete_selection();
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
if (m_entry.get_overwrite_mode()) {
|
|
Packit |
3ff832 |
uint text_length = m_entry.get_buffer().get_length();
|
|
Packit |
3ff832 |
if (m_entry.cursor_position < text_length)
|
|
Packit |
3ff832 |
m_entry.delete_from_cursor(Gtk.DeleteType.CHARS, 1);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
int pos = m_entry.get_position();
|
|
Packit |
3ff832 |
m_entry.insert_text(str, -1, ref pos);
|
|
Packit |
3ff832 |
m_entry.set_position(pos);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private Gdk.Rectangle get_monitor_geometry() {
|
|
Packit |
3ff832 |
Gdk.Rectangle monitor_area = { 0, };
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
// Use get_monitor_geometry() instead of get_monitor_area().
|
|
Packit |
3ff832 |
// get_monitor_area() excludes docks, but the lookup window should be
|
|
Packit |
3ff832 |
// shown over them.
|
|
Packit |
3ff832 |
#if VALA_0_34
|
|
Packit |
3ff832 |
Gdk.Monitor monitor = Gdk.Display.get_default().get_monitor_at_point(
|
|
Packit |
3ff832 |
m_cursor_location.x,
|
|
Packit |
3ff832 |
m_cursor_location.y);
|
|
Packit |
3ff832 |
monitor_area = monitor.get_geometry();
|
|
Packit |
3ff832 |
#else
|
|
Packit |
3ff832 |
Gdk.Screen screen = Gdk.Screen.get_default();
|
|
Packit |
3ff832 |
int monitor_num = screen.get_monitor_at_point(m_cursor_location.x,
|
|
Packit |
3ff832 |
m_cursor_location.y);
|
|
Packit |
3ff832 |
screen.get_monitor_geometry(monitor_num, out monitor_area);
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
return monitor_area;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void adjust_window_position() {
|
|
Packit |
3ff832 |
Gdk.Point cursor_right_bottom = {
|
|
Packit |
3ff832 |
m_cursor_location.x + m_cursor_location.width,
|
|
Packit |
3ff832 |
m_cursor_location.y + m_cursor_location.height
|
|
Packit |
3ff832 |
};
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gtk.Allocation allocation;
|
|
Packit |
3ff832 |
get_allocation(out allocation);
|
|
Packit |
3ff832 |
Gdk.Point window_right_bottom = {
|
|
Packit |
3ff832 |
cursor_right_bottom.x + allocation.width,
|
|
Packit |
3ff832 |
cursor_right_bottom.y + allocation.height
|
|
Packit |
3ff832 |
};
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gdk.Rectangle monitor_area = get_monitor_geometry();
|
|
Packit |
3ff832 |
int monitor_right = monitor_area.x + monitor_area.width;
|
|
Packit |
3ff832 |
int monitor_bottom = monitor_area.y + monitor_area.height;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
int x, y;
|
|
Packit |
3ff832 |
if (window_right_bottom.x > monitor_right)
|
|
Packit |
3ff832 |
x = monitor_right - allocation.width;
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
x = cursor_right_bottom.x;
|
|
Packit |
3ff832 |
if (x < 0)
|
|
Packit |
3ff832 |
x = 0;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
bool changed = false;
|
|
Packit |
3ff832 |
if (window_right_bottom.y > monitor_bottom) {
|
|
Packit |
3ff832 |
y = m_cursor_location.y - allocation.height;
|
|
Packit |
3ff832 |
// Do not up side down in Wayland
|
|
Packit |
3ff832 |
if (m_input_context_path == "") {
|
|
Packit |
3ff832 |
changed = (m_is_up_side_down == false);
|
|
Packit |
3ff832 |
m_is_up_side_down = true;
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
changed = (m_is_up_side_down == true);
|
|
Packit |
3ff832 |
m_is_up_side_down = false;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
y = cursor_right_bottom.y;
|
|
Packit |
3ff832 |
changed = (m_is_up_side_down == true);
|
|
Packit |
3ff832 |
m_is_up_side_down = false;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (y < 0)
|
|
Packit |
3ff832 |
y = 0;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
move(x, y);
|
|
Packit |
3ff832 |
if (changed) {
|
|
Packit |
3ff832 |
if (m_redraw_window_id > 0)
|
|
Packit |
3ff832 |
GLib.Source.remove(m_redraw_window_id);
|
|
Packit |
3ff832 |
m_redraw_window_id = GLib.Timeout.add(100, () => {
|
|
Packit |
3ff832 |
m_redraw_window_id = 0;
|
|
Packit |
3ff832 |
this.show_all();
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
});
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
#if 0
|
|
Packit |
3ff832 |
private void check_action_variant_cb(Gtk.MenuItem item) {
|
|
Packit |
3ff832 |
Gtk.CheckMenuItem check = item as Gtk.CheckMenuItem;
|
|
Packit |
3ff832 |
m_show_emoji_variant = check.get_active();
|
|
Packit |
3ff832 |
// Redraw emoji candidate panel for m_show_emoji_variant
|
|
Packit |
3ff832 |
if (m_candidate_panel_is_visible) {
|
|
Packit |
3ff832 |
// DOTO: queue_draw() does not effect at the real time.
|
|
Packit |
3ff832 |
this.queue_draw();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
#else
|
|
Packit |
3ff832 |
private void check_action_variant_cb(GLib.SimpleAction action,
|
|
Packit |
3ff832 |
GLib.Variant? parameter) {
|
|
Packit |
3ff832 |
m_show_emoji_variant = !action.get_state().get_boolean();
|
|
Packit |
3ff832 |
action.set_state(new GLib.Variant.boolean(m_show_emoji_variant));
|
|
Packit |
3ff832 |
// Redraw emoji candidate panel for m_show_emoji_variant
|
|
Packit |
3ff832 |
if (m_candidate_panel_is_visible) {
|
|
Packit |
3ff832 |
// DOTO: queue_draw() does not effect at the real time.
|
|
Packit |
3ff832 |
this.queue_draw();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void action_close_cb(GLib.SimpleAction action,
|
|
Packit |
3ff832 |
GLib.Variant? parameter) {
|
|
Packit |
3ff832 |
candidate_clicked(0, BUTTON_CLOSE_BUTTON, 0);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void update_favorite_emoji_dict() {
|
|
Packit |
3ff832 |
if (m_emoji_to_data_dict == null ||
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict == null)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
for(int i = 0; i < m_favorites.length; i++) {
|
|
Packit |
3ff832 |
var favorite = m_favorites[i];
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
string? annotation = "";
|
|
Packit |
3ff832 |
if (i < m_favorite_annotations.length) {
|
|
Packit |
3ff832 |
annotation = m_favorite_annotations[i];
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (annotation == "")
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
unowned IBus.EmojiData? data =
|
|
Packit |
3ff832 |
m_emoji_to_data_dict.lookup(favorite);
|
|
Packit |
3ff832 |
if (data == null) {
|
|
Packit |
3ff832 |
GLib.SList<string> new_annotations = new GLib.SList<string>();
|
|
Packit |
3ff832 |
new_annotations.append(annotation);
|
|
Packit |
3ff832 |
IBus.EmojiData new_data = GLib.Object.new(
|
|
Packit |
3ff832 |
typeof(IBus.EmojiData),
|
|
Packit |
3ff832 |
"emoji", favorite.dup(),
|
|
Packit |
3ff832 |
"annotations", new_annotations,
|
|
Packit |
3ff832 |
"description", annotation.dup()
|
|
Packit |
3ff832 |
) as IBus.EmojiData;
|
|
Packit |
3ff832 |
m_emoji_to_data_dict.insert(favorite, new_data);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
unowned GLib.SList<string> annotations = data.get_annotations();
|
|
Packit |
3ff832 |
if (annotations.find_custom(annotation, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
annotations.append(annotation);
|
|
Packit |
3ff832 |
data.set_annotations(annotations.copy());
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
unowned GLib.SList<string> emojis =
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict.lookup(annotation);
|
|
Packit |
3ff832 |
if (emojis.find_custom(favorite, GLib.strcmp) == null) {
|
|
Packit |
3ff832 |
emojis.append(favorite);
|
|
Packit |
3ff832 |
m_annotation_to_emojis_dict.replace(annotation, emojis.copy());
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public void set_annotation(string annotation) {
|
|
Packit |
3ff832 |
m_annotation = annotation;
|
|
Packit |
3ff832 |
remove_all_children();
|
|
Packit |
3ff832 |
if (annotation.length > 0) {
|
|
Packit |
3ff832 |
update_candidate_window();
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
if (m_show_unicode)
|
|
Packit |
3ff832 |
update_unicode_blocks();
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
update_category_list();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public IBus.LookupTable get_one_dimension_lookup_table() {
|
|
Packit |
3ff832 |
var lookup_table = new IBus.LookupTable(EMOJI_GRID_PAGE, 0, true, true);
|
|
Packit |
3ff832 |
uint i = 0;
|
|
Packit |
3ff832 |
for (; i < m_lookup_table.get_number_of_candidates(); i++) {
|
|
Packit |
3ff832 |
IBus.Text text = new IBus.Text.from_string("");
|
|
Packit |
3ff832 |
text.copy(m_lookup_table.get_candidate(i));
|
|
Packit |
3ff832 |
lookup_table.append_candidate(text);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (i > 0)
|
|
Packit |
3ff832 |
lookup_table.set_cursor_pos(m_lookup_table.get_cursor_pos());
|
|
Packit |
3ff832 |
return lookup_table;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public uint get_number_of_candidates() {
|
|
Packit |
3ff832 |
return m_lookup_table.get_number_of_candidates();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public uint get_cursor_pos() {
|
|
Packit |
3ff832 |
return m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public void set_cursor_pos(uint cursor_pos) {
|
|
Packit |
3ff832 |
m_lookup_table.set_cursor_pos(cursor_pos);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public string get_current_candidate() {
|
|
Packit |
3ff832 |
// If category_list mode, do not show the category name on preedit.
|
|
Packit |
3ff832 |
// If candidate_panel mode, the first space key does not show the
|
|
Packit |
3ff832 |
// lookup table but the first candidate is avaiable on preedit.
|
|
Packit |
3ff832 |
if (!m_candidate_panel_mode)
|
|
Packit |
3ff832 |
return "";
|
|
Packit |
3ff832 |
uint cursor = m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
return m_lookup_table.get_candidate(cursor).text;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public IBus.Text get_title_text() {
|
|
Packit |
3ff832 |
var language = _(IBus.get_language_name(m_current_lang_id));
|
|
Packit |
3ff832 |
uint ncandidates = this.get_number_of_candidates();
|
|
Packit |
3ff832 |
string main_title = _("Emoji Choice");
|
|
Packit |
3ff832 |
if (m_show_unicode)
|
|
Packit |
3ff832 |
main_title = _("Unicode Choice");
|
|
Packit |
3ff832 |
var text = new IBus.Text.from_string(
|
|
Packit |
3ff832 |
"%s (%s) (%u / %u)".printf(
|
|
Packit |
3ff832 |
main_title,
|
|
Packit |
3ff832 |
language,
|
|
Packit |
3ff832 |
this.get_cursor_pos() + 1,
|
|
Packit |
3ff832 |
ncandidates));
|
|
Packit |
3ff832 |
int char_count = text.text.char_count();
|
|
Packit |
3ff832 |
int start_index = -1;
|
|
Packit |
3ff832 |
for (int i = 0; i < char_count; i++) {
|
|
Packit |
3ff832 |
if (text.text.utf8_offset(i).has_prefix(language)) {
|
|
Packit |
3ff832 |
start_index = i;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (start_index >= 0) {
|
|
Packit |
3ff832 |
var attr = new IBus.Attribute(
|
|
Packit |
3ff832 |
IBus.AttrType.FOREGROUND,
|
|
Packit |
3ff832 |
0x808080,
|
|
Packit |
3ff832 |
start_index,
|
|
Packit |
3ff832 |
start_index + language.char_count());
|
|
Packit |
3ff832 |
var attrs = new IBus.AttrList();
|
|
Packit |
3ff832 |
attrs.append(attr);
|
|
Packit |
3ff832 |
text.set_attributes(attrs);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return text;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
#if 0
|
|
Packit |
3ff832 |
public GLib.SList<string>? get_candidates() {
|
|
Packit |
3ff832 |
if (m_annotation.length == 0) {
|
|
Packit |
3ff832 |
return null;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_annotation.length > m_emoji_max_seq_len) {
|
|
Packit |
3ff832 |
return null;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
string? unicode_point = check_unicode_point(m_annotation);
|
|
Packit |
3ff832 |
GLib.SList<string>? total_emojis =
|
|
Packit |
3ff832 |
lookup_emojis_from_annotation(m_annotation);
|
|
Packit |
3ff832 |
if (total_emojis == null) {
|
|
Packit |
3ff832 |
/* Users can type title strings against lower case.
|
|
Packit |
3ff832 |
* E.g. "Smile" against "smile"
|
|
Packit |
3ff832 |
* But the dictionary has the case sensitive annotations.
|
|
Packit |
3ff832 |
* E.g. ":D" and ":q"
|
|
Packit |
3ff832 |
* So need to call lookup_emojis_from_annotation() twice.
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
string lower_annotation = m_annotation.down();
|
|
Packit |
3ff832 |
total_emojis = lookup_emojis_from_annotation(lower_annotation);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (unicode_point != null)
|
|
Packit |
3ff832 |
total_emojis.prepend(unicode_point);
|
|
Packit |
3ff832 |
return total_emojis;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
#if 0
|
|
Packit |
3ff832 |
public string run(string input_context_path,
|
|
Packit |
3ff832 |
Gdk.Event event) {
|
|
Packit |
3ff832 |
assert (m_loop == null);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_is_running = true;
|
|
Packit |
3ff832 |
m_input_context_path = input_context_path;
|
|
Packit |
3ff832 |
m_candidate_panel_is_visible = false;
|
|
Packit |
3ff832 |
m_result = null;
|
|
Packit |
3ff832 |
m_enter_notify_enable = true;
|
|
Packit |
3ff832 |
m_show_unicode = false;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* Let gtk recalculate the window size. */
|
|
Packit |
3ff832 |
resize(1, 1);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_entry.set_text("");
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
show_category_list();
|
|
Packit |
3ff832 |
m_entry.set_activates_default(true);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* Some window managers, e.g. MATE, GNOME, Plasma desktops,
|
|
Packit |
3ff832 |
* does not give the keyboard focus when Emojier is lauched
|
|
Packit |
3ff832 |
* twice with Ctrl-Shift-e via XIEvent, if present_with_time()
|
|
Packit |
3ff832 |
* is not applied.
|
|
Packit |
3ff832 |
* But XFCE4 desktop does not effect this bug.
|
|
Packit |
3ff832 |
* Seems this is caused by the window manager's focus stealing
|
|
Packit |
3ff832 |
* prevention logic:
|
|
Packit |
3ff832 |
* https://mail.gnome.org/archives/gtk-devel-list/2017-May/msg00026.html
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
present_centralize(event);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
Gdk.Device pointer;
|
|
Packit |
3ff832 |
#if VALA_0_34
|
|
Packit |
3ff832 |
Gdk.Seat seat = event.get_seat();
|
|
Packit |
3ff832 |
if (seat == null) {
|
|
Packit |
3ff832 |
var display = get_display();
|
|
Packit |
3ff832 |
seat = display.get_default_seat();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
pointer = seat.get_pointer();
|
|
Packit |
3ff832 |
#else
|
|
Packit |
3ff832 |
Gdk.Device device = event.get_device();
|
|
Packit |
3ff832 |
if (device == null) {
|
|
Packit |
3ff832 |
var display = get_display();
|
|
Packit |
3ff832 |
device = display.list_devices().data;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (device.get_source() == Gdk.InputSource.KEYBOARD)
|
|
Packit |
3ff832 |
pointer = device.get_associated_device();
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
pointer = device;
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
pointer.get_position_double(null,
|
|
Packit |
3ff832 |
out m_mouse_x,
|
|
Packit |
3ff832 |
out m_mouse_y);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
m_loop = new GLib.MainLoop();
|
|
Packit |
3ff832 |
m_loop.run();
|
|
Packit |
3ff832 |
m_loop = null;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
// Need focus-out on Gtk.Entry to send the emoji to applications.
|
|
Packit |
3ff832 |
Gdk.Event fevent = new Gdk.Event(Gdk.EventType.FOCUS_CHANGE);
|
|
Packit |
3ff832 |
fevent.focus_change.in = 0;
|
|
Packit |
3ff832 |
fevent.focus_change.window = get_window();
|
|
Packit |
3ff832 |
m_entry.send_focus_change(fevent);
|
|
Packit |
3ff832 |
fevent.focus_change.window = null;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
hide();
|
|
Packit |
3ff832 |
// Make sure the switcher is hidden before returning from this function.
|
|
Packit |
3ff832 |
while (Gtk.events_pending())
|
|
Packit |
3ff832 |
Gtk.main_iteration();
|
|
Packit |
3ff832 |
m_is_running = false;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
return m_result;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* override virtual functions */
|
|
Packit |
3ff832 |
public override void show_all() {
|
|
Packit |
3ff832 |
base.show_all();
|
|
Packit |
3ff832 |
if (m_candidate_panel_mode)
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
else if (m_show_unicode)
|
|
Packit |
3ff832 |
show_unicode_blocks();
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
show_category_list();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public override void hide() {
|
|
Packit |
3ff832 |
base.hide();
|
|
Packit |
3ff832 |
m_candidate_panel_is_visible = false;
|
|
Packit |
3ff832 |
// m_candidate_panel_mode is not false in when you type something
|
|
Packit |
3ff832 |
// during enabling the candidate panel.
|
|
Packit |
3ff832 |
if (m_redraw_window_id > 0) {
|
|
Packit |
3ff832 |
GLib.Source.remove(m_redraw_window_id);
|
|
Packit |
3ff832 |
m_redraw_window_id = 0;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (m_unicode_progress_id > 0) {
|
|
Packit |
3ff832 |
GLib.Source.remove(m_unicode_progress_id);
|
|
Packit |
3ff832 |
m_unicode_progress_id = 0;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public override bool key_press_event(Gdk.EventKey event) {
|
|
Packit |
3ff832 |
uint keyval = event.keyval;
|
|
Packit |
3ff832 |
uint modifiers = event.state;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* Need to handle events in key_press_event() instead of
|
|
Packit |
3ff832 |
* key_release_event() so that this can know if the event
|
|
Packit |
3ff832 |
* was handled by IME.
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
switch (keyval) {
|
|
Packit |
3ff832 |
case Gdk.Key.Escape:
|
|
Packit |
3ff832 |
if (key_press_escape())
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Return:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Enter:
|
|
Packit |
3ff832 |
if (key_press_enter()) {
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
m_result = get_current_candidate();
|
|
Packit |
3ff832 |
hide();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.BackSpace:
|
|
Packit |
3ff832 |
if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
|
|
Packit |
3ff832 |
Gtk.DeleteType.WORD_ENDS, -1);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "backspace");
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.Delete:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Delete:
|
|
Packit |
3ff832 |
if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
|
|
Packit |
3ff832 |
Gtk.DeleteType.WORD_ENDS, 1);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
|
|
Packit |
3ff832 |
Gtk.DeleteType.CHARS, 1);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.space:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Space:
|
|
Packit |
3ff832 |
if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
|
|
Packit |
3ff832 |
if (m_entry.get_text().length > 0)
|
|
Packit |
3ff832 |
entry_enter_keyval(keyval);
|
|
Packit |
3ff832 |
} else if (m_candidate_panel_is_visible) {
|
|
Packit |
3ff832 |
enter_notify_disable_with_timer();
|
|
Packit |
3ff832 |
m_lookup_table.cursor_down();
|
|
Packit |
3ff832 |
show_candidate_panel();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
else {
|
|
Packit |
3ff832 |
category_list_cursor_move(Gdk.Key.Down);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Right:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Right:
|
|
Packit |
3ff832 |
key_press_cursor_horizontal(Gdk.Key.Right, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Left:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Left:
|
|
Packit |
3ff832 |
key_press_cursor_horizontal(Gdk.Key.Left, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Down:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Down:
|
|
Packit |
3ff832 |
key_press_cursor_vertical(Gdk.Key.Down, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Up:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Up:
|
|
Packit |
3ff832 |
key_press_cursor_vertical(Gdk.Key.Up, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Page_Down:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Page_Down:
|
|
Packit |
3ff832 |
key_press_cursor_vertical(Gdk.Key.Page_Down, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Page_Up:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Page_Up:
|
|
Packit |
3ff832 |
key_press_cursor_vertical(Gdk.Key.Page_Up, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Home:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Home:
|
|
Packit |
3ff832 |
key_press_cursor_home_end(Gdk.Key.Home, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.End:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_End:
|
|
Packit |
3ff832 |
key_press_cursor_home_end(Gdk.Key.End, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.Insert:
|
|
Packit |
3ff832 |
case Gdk.Key.KP_Insert:
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "toggle-overwrite");
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
|
|
Packit |
3ff832 |
switch (keyval) {
|
|
Packit |
3ff832 |
case Gdk.Key.f:
|
|
Packit |
3ff832 |
key_press_cursor_horizontal(Gdk.Key.Right, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.b:
|
|
Packit |
3ff832 |
key_press_cursor_horizontal(Gdk.Key.Left, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.n:
|
|
Packit |
3ff832 |
case Gdk.Key.N:
|
|
Packit |
3ff832 |
key_press_cursor_vertical(Gdk.Key.Down, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.p:
|
|
Packit |
3ff832 |
case Gdk.Key.P:
|
|
Packit |
3ff832 |
key_press_cursor_vertical(Gdk.Key.Up, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.h:
|
|
Packit |
3ff832 |
key_press_cursor_home_end(Gdk.Key.Home, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.e:
|
|
Packit |
3ff832 |
key_press_cursor_home_end(Gdk.Key.End, modifiers);
|
|
Packit |
3ff832 |
show_all();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
case Gdk.Key.u:
|
|
Packit |
3ff832 |
if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry,
|
|
Packit |
3ff832 |
"delete-from-cursor",
|
|
Packit |
3ff832 |
Gtk.DeleteType.PARAGRAPH_ENDS,
|
|
Packit |
3ff832 |
-1);
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.a:
|
|
Packit |
3ff832 |
if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
m_entry.select_region(0, -1);
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.x:
|
|
Packit |
3ff832 |
if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "cut-clipboard");
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.C:
|
|
Packit |
3ff832 |
case Gdk.Key.c:
|
|
Packit |
3ff832 |
if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
|
|
Packit |
3ff832 |
if (m_candidate_panel_is_visible) {
|
|
Packit |
3ff832 |
uint index = m_lookup_table.get_cursor_pos();
|
|
Packit |
3ff832 |
var text = m_lookup_table.get_candidate(index).text;
|
|
Packit |
3ff832 |
Gtk.Clipboard clipboard =
|
|
Packit |
3ff832 |
Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
|
|
Packit |
3ff832 |
clipboard.set_text(text, -1);
|
|
Packit |
3ff832 |
clipboard.store();
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
} else if (m_entry.get_text().length > 0) {
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "copy-clipboard");
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case Gdk.Key.v:
|
|
Packit |
3ff832 |
GLib.Signal.emit_by_name(m_entry, "paste-clipboard");
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
entry_enter_keyval(keyval);
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool is_running() {
|
|
Packit |
3ff832 |
return m_is_running;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public string get_input_context_path() {
|
|
Packit |
3ff832 |
return m_input_context_path;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public void set_input_context_path(string input_context_path) {
|
|
Packit |
3ff832 |
m_input_context_path = input_context_path;
|
|
Packit |
3ff832 |
if (input_context_path == "") {
|
|
Packit |
3ff832 |
m_warning_message = _("" +
|
|
Packit |
3ff832 |
"Failed to get the current text application. " +
|
|
Packit |
3ff832 |
"Please re-focus your application. E.g. Press Esc key " +
|
|
Packit |
3ff832 |
"several times to release the emoji typing mode, " +
|
|
Packit |
3ff832 |
"click your desktop and click your text application again."
|
|
Packit |
3ff832 |
);
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
m_warning_message = "";
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public string get_selected_string() {
|
|
Packit |
3ff832 |
return m_result;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private void reset_window_mode() {
|
|
Packit |
3ff832 |
m_backward_index = -1;
|
|
Packit |
3ff832 |
m_backward = null;
|
|
Packit |
3ff832 |
m_candidate_panel_is_visible = false;
|
|
Packit |
3ff832 |
m_candidate_panel_mode = false;
|
|
Packit |
3ff832 |
// Do not clear m_lookup_table to work with space key later.
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public void reset() {
|
|
Packit |
3ff832 |
reset_window_mode();
|
|
Packit |
3ff832 |
m_input_context_path = "";
|
|
Packit |
3ff832 |
m_result = null;
|
|
Packit |
3ff832 |
m_category_active_index = -1;
|
|
Packit |
3ff832 |
m_show_unicode = false;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public void present_centralize(Gdk.Event event) {
|
|
Packit |
3ff832 |
Gtk.Allocation allocation;
|
|
Packit |
3ff832 |
get_allocation(out allocation);
|
|
Packit |
3ff832 |
Gdk.Rectangle monitor_area;
|
|
Packit |
3ff832 |
Gdk.Rectangle work_area;
|
|
Packit |
3ff832 |
#if VALA_0_34
|
|
Packit |
3ff832 |
Gdk.Display display = Gdk.Display.get_default();
|
|
Packit |
3ff832 |
Gdk.Monitor monitor = display.get_monitor_at_window(this.get_window());
|
|
Packit |
3ff832 |
monitor_area = monitor.get_geometry();
|
|
Packit |
3ff832 |
work_area = monitor.get_workarea();
|
|
Packit |
3ff832 |
#else
|
|
Packit |
3ff832 |
Gdk.Screen screen = Gdk.Screen.get_default();
|
|
Packit |
3ff832 |
int monitor_num = screen.get_monitor_at_window(this.get_window());
|
|
Packit |
3ff832 |
screen.get_monitor_geometry(monitor_num, out monitor_area);
|
|
Packit |
3ff832 |
work_area = screen.get_monitor_workarea(monitor_num);
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
int x = (monitor_area.x + monitor_area.width - allocation.width)/2;
|
|
Packit |
3ff832 |
int y = (monitor_area.y + monitor_area.height
|
|
Packit |
3ff832 |
- allocation.height)/2;
|
|
Packit |
3ff832 |
// Do not hide a bottom panel in XFCE4
|
|
Packit |
3ff832 |
if (work_area.y < y)
|
|
Packit |
3ff832 |
y = work_area.y;
|
|
Packit |
3ff832 |
// FIXME: move() does not work in Wayland
|
|
Packit |
3ff832 |
move(x, y);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
uint32 timestamp = event.get_time();
|
|
Packit |
3ff832 |
present_with_time(timestamp);
|
|
Packit |
3ff832 |
m_entry.set_activates_default(true);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public void set_cursor_location(int x,
|
|
Packit |
3ff832 |
int y,
|
|
Packit |
3ff832 |
int width,
|
|
Packit |
3ff832 |
int height) {
|
|
Packit |
3ff832 |
Gdk.Rectangle location = Gdk.Rectangle(){
|
|
Packit |
3ff832 |
x = x, y = y, width = width, height = height };
|
|
Packit |
3ff832 |
if (m_cursor_location == location)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
m_cursor_location = location;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public bool is_candidate_panel_mode() {
|
|
Packit |
3ff832 |
return m_candidate_panel_mode;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static bool has_loaded_emoji_dict() {
|
|
Packit |
3ff832 |
if (m_emoji_to_data_dict == null)
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
GLib.List keys = m_emoji_to_data_dict.get_keys();
|
|
Packit |
3ff832 |
if (keys.length() == 0)
|
|
Packit |
3ff832 |
return false;
|
|
Packit |
3ff832 |
return true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void set_annotation_lang(string? lang) {
|
|
Packit |
3ff832 |
if (lang == null || lang == "")
|
|
Packit |
3ff832 |
lang = "en";
|
|
Packit |
3ff832 |
if (m_current_lang_id == lang)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
m_current_lang_id = lang;
|
|
Packit |
3ff832 |
reload_emoji_dict();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static string get_annotation_lang() {
|
|
Packit |
3ff832 |
return m_current_lang_id;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void set_emoji_font(string? emoji_font) {
|
|
Packit |
3ff832 |
return_if_fail(emoji_font != null && emoji_font != "");
|
|
Packit |
3ff832 |
Pango.FontDescription font_desc =
|
|
Packit |
3ff832 |
Pango.FontDescription.from_string(emoji_font);
|
|
Packit |
3ff832 |
string font_family = font_desc.get_family();
|
|
Packit |
3ff832 |
if (font_family != null) {
|
|
Packit |
3ff832 |
m_emoji_font_family = font_family;
|
|
Packit |
3ff832 |
m_emoji_font_changed = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
int font_size = font_desc.get_size() / Pango.SCALE;
|
|
Packit |
3ff832 |
if (font_size != 0) {
|
|
Packit |
3ff832 |
m_emoji_font_size = font_size;
|
|
Packit |
3ff832 |
m_emoji_font_changed = true;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void set_partial_match(bool has_partial_match) {
|
|
Packit |
3ff832 |
m_has_partial_match = has_partial_match;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void set_partial_match_length(int length) {
|
|
Packit |
3ff832 |
if (length < 1)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
m_partial_match_length = length;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void set_partial_match_condition(int condition) {
|
|
Packit |
3ff832 |
if (condition < 0)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
m_partial_match_condition = condition;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void set_favorites(string[]? unowned_favorites,
|
|
Packit |
3ff832 |
string[]? unowned_favorite_annotations) {
|
|
Packit |
3ff832 |
m_favorites = {};
|
|
Packit |
3ff832 |
m_favorite_annotations = {};
|
|
Packit |
3ff832 |
for(int i = 0; i < unowned_favorites.length; i++) {
|
|
Packit |
3ff832 |
string? favorite = unowned_favorites[i];
|
|
Packit |
3ff832 |
// Avoid gsetting value error by manual setting
|
|
Packit |
3ff832 |
GLib.return_if_fail(favorite != null);
|
|
Packit |
3ff832 |
m_favorites += favorite;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
for(int i = 0; i < unowned_favorite_annotations.length; i++) {
|
|
Packit |
3ff832 |
string? favorite_annotation = unowned_favorite_annotations[i];
|
|
Packit |
3ff832 |
GLib.return_if_fail(favorite_annotation != null);
|
|
Packit |
3ff832 |
m_favorite_annotations += favorite_annotation;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
update_favorite_emoji_dict();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
private static GLib.Object get_load_progress_object() {
|
|
Packit |
3ff832 |
if (m_unicode_progress_object == null)
|
|
Packit |
3ff832 |
m_unicode_progress_object = new LoadProgressObject();
|
|
Packit |
3ff832 |
return m_unicode_progress_object as GLib.Object;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
public static void load_unicode_dict() {
|
|
Packit |
3ff832 |
if (m_unicode_block_list.length() == 0)
|
|
Packit |
3ff832 |
make_unicode_block_dict();
|
|
Packit |
3ff832 |
if (m_name_to_unicodes_dict.size() == 0)
|
|
Packit |
3ff832 |
make_unicode_name_dict(IBusEmojier.get_load_progress_object());
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|