Blame setup/emojilang.py

Packit 3ff832
# vim:set et sts=4 sw=4:
Packit 3ff832
# -*- coding: utf-8 -*-
Packit 3ff832
#
Packit 3ff832
# ibus - The Input Bus
Packit 3ff832
#
Packit 3ff832
# Copyright (c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
Packit 3ff832
# Copyright (c) 2017 Red Hat, Inc.
Packit 3ff832
#
Packit 3ff832
# This program is free software; you can redistribute it and/or
Packit 3ff832
# modify it under the terms of the GNU General Public License as
Packit 3ff832
# published by the Free Software Foundation; either version 2 of the
Packit 3ff832
# License, or (at your option) any later version.
Packit 3ff832
#
Packit 3ff832
# This program is distributed in the hope that it will be useful, but
Packit 3ff832
# WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 3ff832
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 3ff832
# General Public License for more details.
Packit 3ff832
#
Packit 3ff832
# You should have received a copy of the GNU General Public License
Packit 3ff832
# along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit 3ff832
Packit 3ff832
# for python2
Packit 3ff832
from __future__ import print_function
Packit 3ff832
Packit 3ff832
__all__ = (
Packit 3ff832
    "EmojiLangButton",
Packit 3ff832
);
Packit 3ff832
Packit 3ff832
from gi.repository import Gtk
Packit 3ff832
from gi.repository import GLib
Packit 3ff832
from gi.repository import GObject
Packit 3ff832
from gi.repository import IBus
Packit 3ff832
Packit 3ff832
import functools
Packit 3ff832
import gettext
Packit 3ff832
import i18n
Packit 3ff832
import locale
Packit 3ff832
import os
Packit 3ff832
Packit 3ff832
from icon import load_icon
Packit 3ff832
from i18n import _, N_
Packit 3ff832
Packit 3ff832
ROW_TRAVEL_DIRECTION_NONE,      \
Packit 3ff832
ROW_TRAVEL_DIRECTION_FORWARD,   \
Packit 3ff832
ROW_TRAVEL_DIRECTION_BACKWARD = list(range(3))
Packit 3ff832
Packit 3ff832
class LanguageString:
Packit 3ff832
    def __init__(self, id, trans = ""):
Packit 3ff832
        self.id = id
Packit 3ff832
        self.trans = trans
Packit 3ff832
Packit 3ff832
class EmojiLangChooser(Gtk.Dialog):
Packit 3ff832
    __gtype_name__ = 'EmojiLangChooser'
Packit 3ff832
    __initial_languages = [ IBus.get_language_name('en_US'),
Packit 3ff832
                            IBus.get_language_name('en_GB'),
Packit 3ff832
                            IBus.get_language_name('de_DE'),
Packit 3ff832
                            IBus.get_language_name('fr_FR'),
Packit 3ff832
                            IBus.get_language_name('es_ES'),
Packit 3ff832
                            IBus.get_language_name('zh_CN'),
Packit 3ff832
                            IBus.get_language_name('ja_JP'),
Packit 3ff832
                            IBus.get_language_name('ru_RU'),
Packit 3ff832
                            IBus.get_language_name('ar_EG') ]
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __init__(self, id = None, transient_for = None):
Packit 3ff832
        super(EmojiLangChooser, self).__init__(
Packit 3ff832
                title = _("Select a language"),
Packit 3ff832
                transient_for = transient_for,
Packit 3ff832
                resizable = True)
Packit 3ff832
        buttons = (_("_Cancel"), Gtk.ResponseType.CANCEL,
Packit 3ff832
                   _("_OK"), Gtk.ResponseType.APPLY)
Packit 3ff832
        self.add_buttons(*buttons)
Packit 3ff832
Packit 3ff832
        if id == None:
Packit 3ff832
            id = 'en'
Packit 3ff832
        self.__id = id
Packit 3ff832
        self.__engines_for_lang = {}
Packit 3ff832
        self.__untrans_for_lang = {}
Packit 3ff832
        self.__langs = {}
Packit 3ff832
        self.__lang_list = []
Packit 3ff832
Packit 3ff832
        self.__scrolled = Gtk.ScrolledWindow(
Packit 3ff832
                hscrollbar_policy = Gtk.PolicyType.NEVER,
Packit 3ff832
                vscrollbar_policy = Gtk.PolicyType.NEVER,
Packit 3ff832
                shadow_type = Gtk.ShadowType.IN,
Packit 3ff832
                margin_left = 6,
Packit 3ff832
                margin_right = 6,
Packit 3ff832
                margin_top = 6,
Packit 3ff832
                margin_bottom = 6)
Packit 3ff832
        self.vbox.add(self.__scrolled)
Packit 3ff832
        viewport = Gtk.Viewport()
Packit 3ff832
        self.__scrolled.add(viewport)
Packit 3ff832
        self.__list = Gtk.ListBox(vexpand = True,
Packit 3ff832
                                  halign = Gtk.Align.FILL,
Packit 3ff832
                                  valign = Gtk.Align.FILL)
Packit 3ff832
        viewport.add(self.__list)
Packit 3ff832
Packit 3ff832
        self.__adjustment = self.__scrolled.get_vadjustment()
Packit 3ff832
        self.__list.set_adjustment(self.__adjustment)
Packit 3ff832
        self.__list.set_filter_func(self.__list_filter, None)
Packit 3ff832
        self.__list.connect('row-activated', self.__row_activated)
Packit 3ff832
Packit 3ff832
        self.__showing_extra = False
Packit 3ff832
        self.__more_row = self.__more_row_new()
Packit 3ff832
        self.__load_lang_list()
Packit 3ff832
        self.__show_lang_rows()
Packit 3ff832
        self.show_all()
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __load_lang_list(self):
Packit 3ff832
        dictdir = os.path.dirname(__file__) + '/../dicts'
Packit 3ff832
        for filename in os.listdir(dictdir):
Packit 3ff832
            suffix = '.dict'
Packit 3ff832
            if not filename.endswith(suffix):
Packit 3ff832
                continue
Packit 3ff832
            lang_id = filename[0:len(filename) - len(suffix)]
Packit 3ff832
            prefix = 'emoji-'
Packit 3ff832
            if not lang_id.startswith(prefix):
Packit 3ff832
                continue
Packit 3ff832
            lang_id = lang_id[len(prefix):]
Packit 3ff832
            lang = LanguageString(lang_id, IBus.get_language_name(lang_id))
Packit 3ff832
            self.__lang_list.append(lang)
Packit 3ff832
        if len(self.__lang_list) == 0:
Packit 3ff832
            print("Not found dicts in %s" % dictdir, file=sys.stderr)
Packit 3ff832
            lang = LanguageString('en', IBus.get_language_name('en'))
Packit 3ff832
            self.__lang_list.append(lang)
Packit 3ff832
            return
Packit 3ff832
Packit 3ff832
        def cmp_lang(a, b):
Packit 3ff832
            label_a = a.trans + a.id
Packit 3ff832
            label_b = b.trans + b.id
Packit 3ff832
            return (label_a > label_b) - (label_a < label_b)
Packit 3ff832
Packit 3ff832
        self.__lang_list.sort(key = functools.cmp_to_key(cmp_lang))
Packit 3ff832
Packit 3ff832
        loc = locale.getlocale()[0]
Packit 3ff832
        # None on C locale
Packit 3ff832
        if loc == None or loc == 'C':
Packit 3ff832
            loc = 'en_US'
Packit 3ff832
        index = 0
Packit 3ff832
        for lang in self.__lang_list:
Packit 3ff832
            # move current language to the first place
Packit 3ff832
            if lang.trans == IBus.get_language_name(loc):
Packit 3ff832
                self.__lang_list.remove(lang)
Packit 3ff832
                self.__lang_list.insert(index, lang)
Packit 3ff832
                index += 1
Packit 3ff832
Packit 3ff832
        for lang in self.__lang_list:
Packit 3ff832
            # move English to the second place
Packit 3ff832
            if lang.trans == IBus.get_language_name('en'):
Packit 3ff832
                self.__lang_list.remove(lang)
Packit 3ff832
                self.__lang_list.insert(index, lang)
Packit 3ff832
                index += 1
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __list_filter(self, row, data):
Packit 3ff832
        if row.id == self.__id:
Packit 3ff832
            self.__list.select_row(row)
Packit 3ff832
        if row == self.__more_row:
Packit 3ff832
            return not self.__showing_extra
Packit 3ff832
        if not self.__showing_extra and row.is_extra:
Packit 3ff832
            return False
Packit 3ff832
        return True
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __row_activated(self, box, row):
Packit 3ff832
        if row == self.__more_row:
Packit 3ff832
            self.__show_more()
Packit 3ff832
            return
Packit 3ff832
        self.__id = row.id
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __padded_label_new(self, text, icon, alignment, direction):
Packit 3ff832
        hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL)
Packit 3ff832
Packit 3ff832
        if direction == ROW_TRAVEL_DIRECTION_BACKWARD:
Packit 3ff832
            rtl = (Gtk.Widget.get_default_direction() == \
Packit 3ff832
                   Gtk.TextDirection.RTL)
Packit 3ff832
            if rtl:
Packit 3ff832
                arrow = Gtk.Image.new_from_icon_name(
Packit 3ff832
                    'go-previous-rtl-symbolic', Gtk.IconSize.MENU)
Packit 3ff832
            else:
Packit 3ff832
                arrow = Gtk.Image.new_from_icon_name(
Packit 3ff832
                    'go-previous-symbolic', Gtk.IconSize.MENU)
Packit 3ff832
            hbox.pack_start(arrow, False, True, 0)
Packit 3ff832
Packit 3ff832
        if icon != None:
Packit 3ff832
            pixbuf = load_icon(icon, Gtk.IconSize.LARGE_TOOLBAR)
Packit 3ff832
            image = Gtk.Image(pixbuf = pixbuf)
Packit 3ff832
            hbox.pack_start(image, False, True, 0)
Packit 3ff832
Packit 3ff832
        label = Gtk.Label(label = text)
Packit 3ff832
        label.set_halign(alignment)
Packit 3ff832
        label.set_valign(Gtk.Align.CENTER)
Packit 3ff832
        label.set_margin_left(20)
Packit 3ff832
        label.set_margin_right(20)
Packit 3ff832
        label.set_margin_top(6)
Packit 3ff832
        label.set_margin_bottom(6)
Packit 3ff832
        hbox.pack_start(label, True, True, 0)
Packit 3ff832
        return hbox
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __list_box_row_new(self, lang):
Packit 3ff832
        row = Gtk.ListBoxRow()
Packit 3ff832
        row.trans = lang.trans
Packit 3ff832
        row.id = lang.id
Packit 3ff832
        row.is_extra = False
Packit 3ff832
        return row
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __lang_row_new(self, lang, prev_lang):
Packit 3ff832
        row = self.__list_box_row_new(lang)
Packit 3ff832
        label = lang.trans
Packit 3ff832
        if lang.id == self.__id:
Packit 3ff832
            row.is_extra = False
Packit 3ff832
        elif prev_lang != None and label == prev_lang.trans:
Packit 3ff832
            label = "%s (%s)" % (lang.trans, lang.id)
Packit 3ff832
            row.is_extra = True
Packit 3ff832
        elif not self.__showing_extra and \
Packit 3ff832
           lang.trans not in self.__initial_languages:
Packit 3ff832
            row.is_extra = True
Packit 3ff832
        widget = self.__padded_label_new(label,
Packit 3ff832
                                         None,
Packit 3ff832
                                         Gtk.Align.CENTER,
Packit 3ff832
                                         ROW_TRAVEL_DIRECTION_NONE)
Packit 3ff832
        row.add(widget)
Packit 3ff832
        return row
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __more_row_new(self):
Packit 3ff832
        row = Gtk.ListBoxRow()
Packit 3ff832
        row.id = None
Packit 3ff832
        hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL)
Packit 3ff832
        row.add(hbox)
Packit 3ff832
        row.set_tooltip_text(_("Moreā€¦"))
Packit 3ff832
        arrow = Gtk.Image.new_from_icon_name('view-more-symbolic',
Packit 3ff832
                                             Gtk.IconSize.MENU)
Packit 3ff832
        arrow.set_margin_left(20)
Packit 3ff832
        arrow.set_margin_right(20)
Packit 3ff832
        arrow.set_margin_top(6)
Packit 3ff832
        arrow.set_margin_bottom(6)
Packit 3ff832
        arrow.set_halign(Gtk.Align.CENTER)
Packit 3ff832
        arrow.set_valign(Gtk.Align.CENTER)
Packit 3ff832
        hbox.pack_start(arrow, True, True, 0)
Packit 3ff832
        return row
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __set_fixed_size(self):
Packit 3ff832
        if self.__scrolled.get_policy()[0] == Gtk.PolicyType.AUTOMATIC:
Packit 3ff832
            return
Packit 3ff832
        (width, height) = self.get_size()
Packit 3ff832
        self.set_size_request(width, height)
Packit 3ff832
        self.__scrolled.set_policy(Gtk.PolicyType.AUTOMATIC,
Packit 3ff832
                                   Gtk.PolicyType.AUTOMATIC)
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __remove_all_children(self):
Packit 3ff832
        for l in self.__list.get_children():
Packit 3ff832
            self.__list.remove(l)
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __show_lang_rows(self):
Packit 3ff832
        self.__remove_all_children()
Packit 3ff832
        prev_lang = None
Packit 3ff832
        for lang in self.__lang_list:
Packit 3ff832
            row = self.__lang_row_new(lang, prev_lang)
Packit 3ff832
            self.__list.add(row)
Packit 3ff832
            prev_lang = lang
Packit 3ff832
        self.__list.add(self.__more_row)
Packit 3ff832
        self.__list.show_all()
Packit 3ff832
        self.__adjustment.set_value(self.__adjustment.get_lower())
Packit 3ff832
        self.__list.invalidate_filter()
Packit 3ff832
        self.__list.set_selection_mode(Gtk.SelectionMode.SINGLE)
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __show_more(self):
Packit 3ff832
        self.__set_fixed_size()
Packit 3ff832
        self.__showing_extra = True
Packit 3ff832
        self.__list.invalidate_filter()
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def get_selected_lang(self):
Packit 3ff832
        return self.__id
Packit 3ff832
Packit 3ff832
Packit 3ff832
class EmojiLangButton(Gtk.Button):
Packit 3ff832
    __gtype_name__ = 'EmojiLangButton'
Packit 3ff832
    __gproperties__ = {
Packit 3ff832
        'lang' : (
Packit 3ff832
            str,
Packit 3ff832
            'lang',
Packit 3ff832
            'lang for emojo-*.dict',
Packit 3ff832
            'en',
Packit 3ff832
            GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE)
Packit 3ff832
    }
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def __init__(self):
Packit 3ff832
        super(EmojiLangButton, self).__init__()
Packit 3ff832
        self.__lang = ''
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def do_get_property(self, prop):
Packit 3ff832
        if prop.name == 'lang':
Packit 3ff832
            return self.__lang
Packit 3ff832
        else:
Packit 3ff832
            raise AttributeError('unknown property %s' % prop.name)
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def do_set_property(self, prop, value):
Packit 3ff832
        if prop.name == 'lang':
Packit 3ff832
            self.set_lang(value)
Packit 3ff832
        else:
Packit 3ff832
            raise AttributeError('unknown property %s' % prop.name)
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def do_clicked(self):
Packit 3ff832
        dialog = EmojiLangChooser(id = self.__lang,
Packit 3ff832
                                  transient_for = self.get_toplevel())
Packit 3ff832
        id = dialog.run()
Packit 3ff832
        if id != Gtk.ResponseType.APPLY:
Packit 3ff832
            dialog.destroy()
Packit 3ff832
            return
Packit 3ff832
        self.set_lang(dialog.get_selected_lang())
Packit 3ff832
        dialog.destroy()
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def set_lang(self, lang):
Packit 3ff832
        self.__lang = lang
Packit 3ff832
        self.notify("lang")
Packit 3ff832
        self.set_label(IBus.get_language_name(lang))
Packit 3ff832
Packit 3ff832
Packit 3ff832
    def get_lang(self, lang):
Packit 3ff832
        return self.__lang
Packit 3ff832
Packit 3ff832
Packit 3ff832
GObject.type_register(EmojiLangButton)
Packit 3ff832
Packit 3ff832
Packit 3ff832
if __name__ == "__main__":
Packit 3ff832
        dialog = EmojiLangChooser()
Packit 3ff832
        id = dialog.run()
Packit 3ff832
        if id != Gtk.ResponseType.APPLY:
Packit 3ff832
            dialog.destroy()
Packit 3ff832
            import sys
Packit 3ff832
            sys.exit(0)
Packit 3ff832
        print("Selected language:", dialog.get_selected_lang())