/* vim:set et sts=4 sw=4:
*
* ibus - The Input Bus
*
* Copyright (c) 2017 Peng Wu <alexepico@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
string emoji_font = null;
string annotation_lang = null;
bool partial_match = false;
int partial_match_length = -1;
int partial_match_condition = -1;
public class EmojiApplication : Gtk.Application {
private IBusEmojier? m_emojier;
private GLib.Settings m_settings_emoji =
new GLib.Settings("org.freedesktop.ibus.panel.emoji");
private ApplicationCommandLine? m_command_line = null;
private EmojiApplication() {
Object(application_id: "org.freedesktop.IBus.Panel.Emojier",
flags: ApplicationFlags.HANDLES_COMMAND_LINE);
set_inactivity_timeout(100000);
}
private void show_dialog(ApplicationCommandLine command_line) {
m_command_line = command_line;
m_emojier.reset();
m_emojier.set_annotation("");
m_emojier.show_all();
}
public void candidate_clicked_lookup_table(uint index,
uint button,
uint state) {
if (m_command_line == null)
return;
if (button == IBusEmojier.BUTTON_CLOSE_BUTTON) {
m_emojier.hide();
m_command_line.print("%s\n", _("Canceled to choose an emoji."));
m_command_line = null;
return;
}
if (m_emojier == null)
return;
bool show_candidate = false;
uint ncandidates = m_emojier.get_number_of_candidates();
if (ncandidates > 0 && ncandidates >= index) {
m_emojier.set_cursor_pos(index);
show_candidate = m_emojier.has_variants(index, false);
} else {
return;
}
if (show_candidate) {
return;
}
string emoji = m_emojier.get_current_candidate();
m_emojier.hide();
Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
clipboard.set_text(emoji, -1);
clipboard.store();
var emojier_favorites = m_settings_emoji.get_strv("favorites");
bool has_favorite = false;
foreach (unowned string favorite in emojier_favorites) {
if (favorite == emoji) {
has_favorite = true;
break;
}
}
if (!has_favorite) {
emojier_favorites += emoji;
m_settings_emoji.set_strv("favorites", emojier_favorites);
}
m_command_line.print("%s\n", _("Copied an emoji to your clipboard."));
m_command_line = null;
}
public void activate_dialog(ApplicationCommandLine command_line) {
this.hold ();
show_dialog(command_line);
this.release ();
}
private int _command_line(ApplicationCommandLine command_line) {
// Set default font size
IBusEmojier.set_emoji_font(m_settings_emoji.get_string("font"));
const OptionEntry[] options = {
{ "font", 0, 0, OptionArg.STRING, out emoji_font,
/* TRANSLATORS: "FONT" should be capital and translatable.
* It's used for an argument command --font=FONT
*/
N_("\"FONT\" for emoji characters on emoji dialog"),
N_("FONT") },
{ "lang", 0, 0, OptionArg.STRING, out annotation_lang,
/* TRANSLATORS: "LANG" should be capital and translatable.
* It's used for an argument command --lang=LANG
*/
N_("\"LANG\" for annotations on emoji dialog. E.g. \"en\""),
N_("LANG") },
{ "partial-match", 0, 0, OptionArg.NONE, out partial_match,
N_("Emoji annotations can be match partially"),
null },
{ "partial-match-length", 0, 0, OptionArg.INT,
out partial_match_length,
N_("Match with the length of the specified integer"),
null },
{ "partial-match-condition", 0, 0, OptionArg.INT,
out partial_match_condition,
N_("Match with the condition of the specified integer"),
null },
{ null }
};
var option = new OptionContext();
option.add_main_entries(options, Config.GETTEXT_PACKAGE);
// We have to make an extra copy of the array,
// since .parse assumes that it can remove strings
// from the array without freeing them.
string[] args = command_line.get_arguments();
string*[] _args = new string[args.length];
for (int i = 0; i < args.length; i++) {
_args[i] = args[i];
}
// Need to initialize for the second instance.
emoji_font = null;
annotation_lang = null;
try {
unowned string[] tmp = _args;
option.parse(ref tmp);
} catch (OptionError e) {
stderr.printf("%s\n", e.message);
return Posix.EXIT_FAILURE;
}
if (m_emojier != null && m_emojier.is_running()) {
Gdk.Event event = new Gdk.Event(Gdk.EventType.KEY_PRESS);
event.key.time = Gdk.CURRENT_TIME;
m_emojier.present_centralize(event);
return Posix.EXIT_SUCCESS;
}
if (annotation_lang == null)
annotation_lang = m_settings_emoji.get_string("lang");
IBusEmojier.set_annotation_lang(annotation_lang);
IBusEmojier.set_partial_match(partial_match);
if (partial_match_length > 0) {
IBusEmojier.set_partial_match_length(partial_match_length);
} else {
IBusEmojier.set_partial_match_length(
m_settings_emoji.get_int("partial-match-length"));
}
if (partial_match_condition > 2) {
warning("Need condition between 0 and 2.");
IBusEmojier.set_partial_match_condition(
m_settings_emoji.get_int("partial-match-condition"));
}
else if (partial_match_condition >= 0) {
IBusEmojier.set_partial_match_condition(partial_match_condition);
} else {
IBusEmojier.set_partial_match_condition(
m_settings_emoji.get_int("partial-match-condition"));
}
if (emoji_font != null)
IBusEmojier.set_emoji_font(emoji_font);
IBusEmojier.set_favorites(
m_settings_emoji.get_strv("favorites"),
m_settings_emoji.get_strv("favorite-annotations"));
IBusEmojier.load_unicode_dict();
if (m_emojier == null) {
m_emojier = new IBusEmojier();
// For title handling in gnome-shell
add_window(m_emojier);
m_emojier.candidate_clicked.connect((i, b, s) => {
candidate_clicked_lookup_table(i, b, s);
});
}
activate_dialog(command_line);
return Posix.EXIT_SUCCESS;
}
public override int command_line(ApplicationCommandLine command_line) {
// keep the application running until we are done with this commandline
this.hold();
int result = _command_line(command_line);
this.release();
return result;
}
public override void shutdown() {
base.shutdown();
remove_window(m_emojier);
m_emojier = null;
}
public static int main (string[] args) {
GLib.Intl.bindtextdomain(Config.GETTEXT_PACKAGE,
Config.GLIB_LOCALE_DIR);
GLib.Intl.bind_textdomain_codeset(Config.GETTEXT_PACKAGE, "UTF-8");
GLib.Intl.textdomain(Config.GETTEXT_PACKAGE);
IBus.init();
Gtk.init(ref args);
EmojiApplication app = new EmojiApplication();
int status = app.run(args);
return status;
}
}