Blame setup/enginedialog.py

Packit Service 1d8f1c
# vim:set et sts=4 sw=4:
Packit Service 1d8f1c
# -*- coding: utf-8 -*-
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# ibus - The Input Bus
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# Copyright (c) 2015 Peng Huang <shawn.p.huang@gmail.com>
Packit Service 1d8f1c
# Copyright (c) 2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
Packit Service 1d8f1c
# Copyright (c) 2013-2015 Red Hat, Inc.
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# This program is free software; you can redistribute it and/or
Packit Service 1d8f1c
# modify it under the terms of the GNU General Public License as
Packit Service 1d8f1c
# published by the Free Software Foundation; either version 2 of the
Packit Service 1d8f1c
# License, or (at your option) any later version.
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# This program is distributed in the hope that it will be useful, but
Packit Service 1d8f1c
# WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 1d8f1c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 1d8f1c
# General Public License for more details.
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# You should have received a copy of the GNU General Public License
Packit Service 1d8f1c
# along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit Service 1d8f1c
Packit Service 1d8f1c
# This file is ported from
Packit Service 1d8f1c
# gnome-control-center/panels/region/cc-input-chooser.c
Packit Service 1d8f1c
Packit Service 1d8f1c
from gi.repository import Gtk
Packit Service 1d8f1c
from gi.repository import GLib
Packit Service 1d8f1c
from gi.repository import IBus
Packit Service 1d8f1c
Packit Service 1d8f1c
import functools
Packit Service 1d8f1c
import gettext
Packit Service 1d8f1c
import i18n
Packit Service 1d8f1c
import locale
Packit Service 1d8f1c
Packit Service 1d8f1c
from icon import load_icon
Packit Service 1d8f1c
from i18n import _, N_
Packit Service 1d8f1c
Packit Service 1d8f1c
ROW_TRAVEL_DIRECTION_NONE,      \
Packit Service 1d8f1c
ROW_TRAVEL_DIRECTION_FORWARD,   \
Packit Service 1d8f1c
ROW_TRAVEL_DIRECTION_BACKWARD = list(range(3))
Packit Service 1d8f1c
Packit Service 1d8f1c
class EngineDialog(Gtk.Dialog):
Packit Service 1d8f1c
    __gtype_name__ = 'EngineDialog'
Packit Service 1d8f1c
    __initial_languages = [ IBus.get_language_name('en_US'),
Packit Service 1d8f1c
                            IBus.get_language_name('en_GB'),
Packit Service 1d8f1c
                            IBus.get_language_name('de_DE'),
Packit Service 1d8f1c
                            IBus.get_language_name('fr_FR'),
Packit Service 1d8f1c
                            IBus.get_language_name('es_ES'),
Packit Service 1d8f1c
                            IBus.get_language_name('zh_CN'),
Packit Service 1d8f1c
                            IBus.get_language_name('ja_JP'),
Packit Service 1d8f1c
                            IBus.get_language_name('ru_RU'),
Packit Service 1d8f1c
                            IBus.get_language_name('ar_EG') ]
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __init__(self, transient_for = None):
Packit Service 1d8f1c
        super(EngineDialog, self).__init__(
Packit Service 1d8f1c
                title = _("Select an input method"),
Packit Service 1d8f1c
                transient_for = transient_for,
Packit Service 1d8f1c
                resizable = True)
Packit Service 1d8f1c
        buttons = (_("_Cancel"), Gtk.ResponseType.CANCEL,
Packit Service 1d8f1c
                   _("_Add"), Gtk.ResponseType.APPLY)
Packit Service 1d8f1c
        self.add_buttons(*buttons)
Packit Service 1d8f1c
        self.set_response_sensitive(Gtk.ResponseType.APPLY, False)
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__engines_for_lang = {}
Packit Service 1d8f1c
        self.__untrans_for_lang = {}
Packit Service 1d8f1c
        self.__langs = {}
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__scrolled = Gtk.ScrolledWindow(
Packit Service 1d8f1c
                hscrollbar_policy = Gtk.PolicyType.NEVER,
Packit Service 1d8f1c
                vscrollbar_policy = Gtk.PolicyType.NEVER,
Packit Service 1d8f1c
                shadow_type = Gtk.ShadowType.IN,
Packit Service 1d8f1c
                margin_left = 6,
Packit Service 1d8f1c
                margin_right = 6,
Packit Service 1d8f1c
                margin_top = 6,
Packit Service 1d8f1c
                margin_bottom = 6)
Packit Service 1d8f1c
        self.vbox.add(self.__scrolled)
Packit Service 1d8f1c
        viewport = Gtk.Viewport()
Packit Service 1d8f1c
        self.__scrolled.add(viewport)
Packit Service 1d8f1c
        self.__list = Gtk.ListBox(vexpand = True,
Packit Service 1d8f1c
                                  halign = Gtk.Align.FILL,
Packit Service 1d8f1c
                                  valign = Gtk.Align.FILL)
Packit Service 1d8f1c
        viewport.add(self.__list)
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__adjustment = self.__scrolled.get_vadjustment()
Packit Service 1d8f1c
        self.__list.set_adjustment(self.__adjustment)
Packit Service 1d8f1c
        self.__list.set_filter_func(self.__list_filter, None)
Packit Service 1d8f1c
        self.__list.connect('row-activated', self.__row_activated)
Packit Service 1d8f1c
        self.__list.connect('row-selected', self.__row_selected)
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__showing_extra = False
Packit Service 1d8f1c
        self.__more_row = self.__more_row_new()
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__filter_timeout_id = 0
Packit Service 1d8f1c
        self.__filter_word = None
Packit Service 1d8f1c
        self.__filter_entry = Gtk.SearchEntry(hexpand = True,
Packit Service 1d8f1c
                                              margin_left = 6,
Packit Service 1d8f1c
                                              margin_right = 6,
Packit Service 1d8f1c
                                              margin_top = 6,
Packit Service 1d8f1c
                                              margin_bottom = 6)
Packit Service 1d8f1c
        self.__filter_entry.set_no_show_all(True)
Packit Service 1d8f1c
        self.__filter_entry.connect('search-changed', self.__filter_changed)
Packit Service 1d8f1c
        self.vbox.add(self.__filter_entry)
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.show_all()
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __list_filter(self, row, data):
Packit Service 1d8f1c
        if row == self.__more_row:
Packit Service 1d8f1c
            return not self.__showing_extra
Packit Service 1d8f1c
        if not self.__showing_extra and row.is_extra:
Packit Service 1d8f1c
            return False
Packit Service 1d8f1c
        if self.__filter_word == None:
Packit Service 1d8f1c
            return True
Packit Service 1d8f1c
Packit Service 1d8f1c
        name = row.name.lower()
Packit Service 1d8f1c
        untrans = row.untrans.lower()
Packit Service 1d8f1c
        if self.__filter_word != None:
Packit Service 1d8f1c
            word = self.__filter_word.lower()
Packit Service 1d8f1c
            if name.startswith(word):
Packit Service 1d8f1c
                return True
Packit Service 1d8f1c
            if untrans.startswith(word):
Packit Service 1d8f1c
                return True
Packit Service 1d8f1c
        return False
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __row_activated(self, box, row):
Packit Service 1d8f1c
        if row == self.__more_row:
Packit Service 1d8f1c
            self.__show_more()
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        if row.back:
Packit Service 1d8f1c
            self.__filter_entry.set_text('')
Packit Service 1d8f1c
            self.__show_lang_rows()
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        if row.lang_info:
Packit Service 1d8f1c
            self.__filter_entry.set_text('')
Packit Service 1d8f1c
            self.__show_engines_for_lang(row)
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __row_selected(self, box, row):
Packit Service 1d8f1c
        self.set_response_sensitive(Gtk.ResponseType.APPLY, row != None)
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __padded_label_new(self, text, icon, alignment, direction):
Packit Service 1d8f1c
        hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL)
Packit Service 1d8f1c
Packit Service 1d8f1c
        if direction == ROW_TRAVEL_DIRECTION_BACKWARD:
Packit Service 1d8f1c
            rtl = (Gtk.Widget.get_default_direction() == \
Packit Service 1d8f1c
                   Gtk.TextDirection.RTL)
Packit Service 1d8f1c
            if rtl:
Packit Service 1d8f1c
                arrow = Gtk.Image.new_from_icon_name(
Packit Service 1d8f1c
                    'go-previous-rtl-symbolic', Gtk.IconSize.MENU)
Packit Service 1d8f1c
            else:
Packit Service 1d8f1c
                arrow = Gtk.Image.new_from_icon_name(
Packit Service 1d8f1c
                    'go-previous-symbolic', Gtk.IconSize.MENU)
Packit Service 1d8f1c
            hbox.pack_start(arrow, False, True, 0)
Packit Service 1d8f1c
Packit Service 1d8f1c
        if icon != None:
Packit Service 1d8f1c
            pixbuf = load_icon(icon, Gtk.IconSize.LARGE_TOOLBAR)
Packit Service 1d8f1c
            image = Gtk.Image(pixbuf = pixbuf)
Packit Service 1d8f1c
            hbox.pack_start(image, False, True, 0)
Packit Service 1d8f1c
Packit Service 1d8f1c
        label = Gtk.Label(label = text)
Packit Service 1d8f1c
        label.set_halign(alignment)
Packit Service 1d8f1c
        label.set_valign(Gtk.Align.CENTER)
Packit Service 1d8f1c
        label.set_margin_left(20)
Packit Service 1d8f1c
        label.set_margin_right(20)
Packit Service 1d8f1c
        label.set_margin_top(6)
Packit Service 1d8f1c
        label.set_margin_bottom(6)
Packit Service 1d8f1c
        hbox.pack_start(label, True, True, 0)
Packit Service 1d8f1c
        return hbox
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __list_box_row_new(self, text):
Packit Service 1d8f1c
        row = Gtk.ListBoxRow()
Packit Service 1d8f1c
        row.name = text
Packit Service 1d8f1c
        row.is_extra = False
Packit Service 1d8f1c
        row.lang_info = False
Packit Service 1d8f1c
        row.back = False
Packit Service 1d8f1c
        row.untrans = ''
Packit Service 1d8f1c
        row.engine = None
Packit Service 1d8f1c
        return row
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __lang_row_new(self, text):
Packit Service 1d8f1c
        row = self.__list_box_row_new(text)
Packit Service 1d8f1c
        row.lang_info = True
Packit Service 1d8f1c
        if len(self.__untrans_for_lang) != 0:
Packit Service 1d8f1c
            row.untrans = self.__untrans_for_lang[text]
Packit Service 1d8f1c
        if not self.__showing_extra and text not in self.__initial_languages:
Packit Service 1d8f1c
            row.is_extra = True
Packit Service 1d8f1c
        widget = self.__padded_label_new(text,
Packit Service 1d8f1c
                                         None,
Packit Service 1d8f1c
                                         Gtk.Align.CENTER,
Packit Service 1d8f1c
                                         ROW_TRAVEL_DIRECTION_NONE)
Packit Service 1d8f1c
        row.add(widget)
Packit Service 1d8f1c
        return row
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __more_row_new(self):
Packit Service 1d8f1c
        row = Gtk.ListBoxRow()
Packit Service 1d8f1c
        hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL)
Packit Service 1d8f1c
        row.add(hbox)
Packit Service 1d8f1c
        row.set_tooltip_text(_("Moreā€¦"))
Packit Service 1d8f1c
        arrow = Gtk.Image.new_from_icon_name('view-more-symbolic',
Packit Service 1d8f1c
                                             Gtk.IconSize.MENU)
Packit Service 1d8f1c
        arrow.set_margin_left(20)
Packit Service 1d8f1c
        arrow.set_margin_right(20)
Packit Service 1d8f1c
        arrow.set_margin_top(6)
Packit Service 1d8f1c
        arrow.set_margin_bottom(6)
Packit Service 1d8f1c
        arrow.set_halign(Gtk.Align.CENTER)
Packit Service 1d8f1c
        arrow.set_valign(Gtk.Align.CENTER)
Packit Service 1d8f1c
        hbox.pack_start(arrow, True, True, 0)
Packit Service 1d8f1c
        return row
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __back_row_new(self, text):
Packit Service 1d8f1c
        row = self.__list_box_row_new(text)
Packit Service 1d8f1c
        row.lang_info = True
Packit Service 1d8f1c
        row.back = True
Packit Service 1d8f1c
        widget = self.__padded_label_new(text,
Packit Service 1d8f1c
                                         None,
Packit Service 1d8f1c
                                         Gtk.Align.CENTER,
Packit Service 1d8f1c
                                         ROW_TRAVEL_DIRECTION_BACKWARD)
Packit Service 1d8f1c
        row.add(widget)
Packit Service 1d8f1c
        return row
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __engine_row_new(self, engine):
Packit Service 1d8f1c
        longname = i18n.gettext_engine_longname(engine)
Packit Service 1d8f1c
        description = i18n.gettext_engine_description(engine)
Packit Service 1d8f1c
        row = self.__list_box_row_new(longname)
Packit Service 1d8f1c
        row.untrans = engine.get_longname()
Packit Service 1d8f1c
        row.set_tooltip_text(description)
Packit Service 1d8f1c
        row.engine = engine
Packit Service 1d8f1c
        widget = self.__padded_label_new(longname,
Packit Service 1d8f1c
                                         engine.get_icon(),
Packit Service 1d8f1c
                                         Gtk.Align.START,
Packit Service 1d8f1c
                                         ROW_TRAVEL_DIRECTION_NONE)
Packit Service 1d8f1c
        row.add(widget)
Packit Service 1d8f1c
        return row
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __set_fixed_size(self):
Packit Service 1d8f1c
        if self.__scrolled.get_policy()[0] == Gtk.PolicyType.AUTOMATIC:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        (width, height) = self.get_size()
Packit Service 1d8f1c
        self.set_size_request(width, height)
Packit Service 1d8f1c
        self.__scrolled.set_policy(Gtk.PolicyType.AUTOMATIC,
Packit Service 1d8f1c
                                   Gtk.PolicyType.AUTOMATIC)
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __remove_all_children(self):
Packit Service 1d8f1c
        for l in self.__list.get_children():
Packit Service 1d8f1c
            self.__list.remove(l)
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __add_engine_rows_for_lang(self, row):
Packit Service 1d8f1c
        lang = row.name
Packit Service 1d8f1c
Packit Service 1d8f1c
        def cmp_engine(a, b):
Packit Service 1d8f1c
            if a.get_rank() == b.get_rank():
Packit Service 1d8f1c
                a_longname = i18n.gettext_engine_longname(a)
Packit Service 1d8f1c
                b_longname = i18n.gettext_engine_longname(b)
Packit Service 1d8f1c
                return locale.strcoll(a_longname, b_longname)
Packit Service 1d8f1c
            return int(b.get_rank() - a.get_rank())
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__engines_for_lang[lang].sort(
Packit Service 1d8f1c
                key = functools.cmp_to_key(cmp_engine))
Packit Service 1d8f1c
        for e in self.__engines_for_lang[lang]:
Packit Service 1d8f1c
            row = self.__engine_row_new(e)
Packit Service 1d8f1c
            self.__list.add(row)
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __show_lang_rows(self):
Packit Service 1d8f1c
        self.__remove_all_children()
Packit Service 1d8f1c
        for lang in self.__langs:
Packit Service 1d8f1c
            row = self.__lang_row_new(lang)
Packit Service 1d8f1c
            self.__list.add(row)
Packit Service 1d8f1c
        self.__list.add(self.__more_row)
Packit Service 1d8f1c
        self.__list.show_all()
Packit Service 1d8f1c
        self.__adjustment.set_value(self.__adjustment.get_lower())
Packit Service 1d8f1c
        self.__list.invalidate_filter()
Packit Service 1d8f1c
        self.__list.set_selection_mode(Gtk.SelectionMode.SINGLE)
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __show_more(self):
Packit Service 1d8f1c
        self.__set_fixed_size()
Packit Service 1d8f1c
        self.__filter_entry.show()
Packit Service 1d8f1c
        self.__showing_extra = True
Packit Service 1d8f1c
        self.__list.invalidate_filter()
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __show_engines_for_lang(self, row):
Packit Service 1d8f1c
        text = row.name
Packit Service 1d8f1c
        self.__set_fixed_size()
Packit Service 1d8f1c
        self.__remove_all_children()
Packit Service 1d8f1c
        row = self.__back_row_new(text)
Packit Service 1d8f1c
        self.__list.add(row)
Packit Service 1d8f1c
        self.__add_engine_rows_for_lang(row)
Packit Service 1d8f1c
        self.__list.show_all()
Packit Service 1d8f1c
        self.__adjustment.set_value(self.__adjustment.get_lower())
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __do_filter(self):
Packit Service 1d8f1c
        text = self.__filter_entry.get_text()
Packit Service 1d8f1c
        if text == '':
Packit Service 1d8f1c
            self.__filter_word = None
Packit Service 1d8f1c
        else:
Packit Service 1d8f1c
            self.__filter_word = text
Packit Service 1d8f1c
        self.__list.invalidate_filter()
Packit Service 1d8f1c
        self.__filter_timeout_id = 0
Packit Service 1d8f1c
        return False
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __filter_changed(self, entry):
Packit Service 1d8f1c
        if self.__filter_timeout_id == 0:
Packit Service 1d8f1c
            self.__filter_timeout_id = GLib.timeout_add(150, self.__do_filter)
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def set_engines(self, engines):
Packit Service 1d8f1c
        self.__engines_for_lang = {}
Packit Service 1d8f1c
        self.__untrans_for_lang = {}
Packit Service 1d8f1c
        for e in engines:
Packit Service 1d8f1c
            l = IBus.get_language_name(e.get_language())
Packit Service 1d8f1c
            if l == None:
Packit Service 1d8f1c
                l = ''
Packit Service 1d8f1c
            if l not in self.__engines_for_lang:
Packit Service 1d8f1c
                self.__engines_for_lang[l] = []
Packit Service 1d8f1c
            i18n.init_textdomain(e.get_textdomain())
Packit Service 1d8f1c
            self.__engines_for_lang[l].append(e)
Packit Service 1d8f1c
Packit Service 1d8f1c
            # Retrieve Untranslated language names.
Packit Service 1d8f1c
            untrans = IBus.get_untranslated_language_name(e.get_language())
Packit Service 1d8f1c
            if untrans == None:
Packit Service 1d8f1c
                untrans = ''
Packit Service 1d8f1c
            self.__untrans_for_lang[l] = untrans
Packit Service 1d8f1c
Packit Service 1d8f1c
        keys = list(self.__engines_for_lang.keys())
Packit Service 1d8f1c
        keys.sort(key=functools.cmp_to_key(locale.strcoll))
Packit Service 1d8f1c
        loc = locale.getlocale()[0]
Packit Service 1d8f1c
        # None on C locale
Packit Service 1d8f1c
        if loc == None or loc == 'C':
Packit Service 1d8f1c
            loc = 'en_US'
Packit Service 1d8f1c
        current_lang = IBus.get_language_name(loc)
Packit Service 1d8f1c
        # move current language to the first place
Packit Service 1d8f1c
        if current_lang in keys:
Packit Service 1d8f1c
            keys.remove(current_lang)
Packit Service 1d8f1c
            keys.insert(0, current_lang)
Packit Service 1d8f1c
Packit Service 1d8f1c
        # move English to the second place
Packit Service 1d8f1c
        en_lang = IBus.get_language_name('en_US')
Packit Service 1d8f1c
        if en_lang != current_lang and en_lang in keys:
Packit Service 1d8f1c
            keys.remove(en_lang)
Packit Service 1d8f1c
            keys.insert(1, en_lang)
Packit Service 1d8f1c
Packit Service 1d8f1c
        #add 'Others' to the end of the combo box
Packit Service 1d8f1c
        if IBus.get_language_name('Other') in keys:
Packit Service 1d8f1c
            keys.remove(IBus.get_language_name('Other'))
Packit Service 1d8f1c
            keys += [IBus.get_language_name('Other')]
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__langs = keys
Packit Service 1d8f1c
        self.__show_lang_rows()
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def get_selected_engine(self):
Packit Service 1d8f1c
        row = self.__list.get_selected_row()
Packit Service 1d8f1c
        if row == None:
Packit Service 1d8f1c
            return None
Packit Service 1d8f1c
        return row.engine