Blame setup/enginetreeview.py

Packit Service 1d8f1c
# vim:set et sts=4 sw=4:
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# ibus - The Input Bus
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
Packit Service 1d8f1c
# Copyright (c) 2014-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
Packit Service 1d8f1c
# Copyright (c) 2007-2018 Red Hat, Inc.
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# This library is free software; you can redistribute it and/or
Packit Service 1d8f1c
# modify it under the terms of the GNU Lesser General Public
Packit Service 1d8f1c
# License as published by the Free Software Foundation; either
Packit Service 1d8f1c
# version 2.1 of the License, or (at your option) any later version.
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# This library is distributed in the hope that it will be useful,
Packit Service 1d8f1c
# but 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
# Lesser General Public License for more details.
Packit Service 1d8f1c
#
Packit Service 1d8f1c
# You should have received a copy of the GNU Lesser General Public
Packit Service 1d8f1c
# License along with this library; if not, write to the Free Software
Packit Service 1d8f1c
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit Service 1d8f1c
# USA
Packit Service 1d8f1c
Packit Service 1d8f1c
from gi.repository import GLib
Packit Service 1d8f1c
from gi.repository import GObject
Packit Service 1d8f1c
from gi.repository import Gtk
Packit Service 1d8f1c
from gi.repository import IBus
Packit Service 1d8f1c
from gi.repository import Pango
Packit Service 1d8f1c
Packit Service 1d8f1c
import i18n
Packit Service 1d8f1c
Packit Service 1d8f1c
from icon import load_icon
Packit Service 1d8f1c
from i18n import _, N_
Packit Service 1d8f1c
Packit Service 1d8f1c
class EngineTreeView(Gtk.TreeView):
Packit Service 1d8f1c
    __gtype_name__ = 'EngineTreeView'
Packit Service 1d8f1c
    __gproperties__ = {
Packit Service 1d8f1c
        'active-engine' : (
Packit Service 1d8f1c
            object,
Packit Service 1d8f1c
            'selected engine',
Packit Service 1d8f1c
            'selected engine',
Packit Service 1d8f1c
            GObject.ParamFlags.READABLE),
Packit Service 1d8f1c
        'engines' : (
Packit Service 1d8f1c
            object,
Packit Service 1d8f1c
            'engines',
Packit Service 1d8f1c
            'engines',
Packit Service 1d8f1c
            GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE)
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __init__(self):
Packit Service 1d8f1c
        super(EngineTreeView, self).__init__()
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__engines = []
Packit Service 1d8f1c
        self.__changed = False
Packit Service 1d8f1c
Packit Service 1d8f1c
        # self.set_headers_visible(True)
Packit Service 1d8f1c
        self.set_reorderable(True)
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.__model = Gtk.ListStore(GObject.TYPE_PYOBJECT, GObject.TYPE_STRING)
Packit Service 1d8f1c
        self.set_model(self.__model)
Packit Service 1d8f1c
        self.__model.connect("row-changed", self.__emit_changed_delay_cb, "row-changed")
Packit Service 1d8f1c
        self.__model.connect("row-deleted", self.__emit_changed_delay_cb, "row-deleted")
Packit Service 1d8f1c
        self.__model.connect("row-inserted", self.__emit_changed_delay_cb, "row-inserted")
Packit Service 1d8f1c
        self.__model.connect("rows-reordered", self.__emit_changed_delay_cb, "rows-reordered")
Packit Service 1d8f1c
        self.__model.set_default_sort_func(self.__sort_engines, None)
Packit Service 1d8f1c
        self.__model.set_sort_column_id(-1, Gtk.SortType.ASCENDING)
Packit Service 1d8f1c
Packit Service 1d8f1c
        # create im name & icon column
Packit Service 1d8f1c
        column = Gtk.TreeViewColumn(_("Input Method"))
Packit Service 1d8f1c
        column.set_min_width(220)
Packit Service 1d8f1c
Packit Service 1d8f1c
        renderer = Gtk.CellRendererPixbuf()
Packit Service 1d8f1c
        renderer.set_property("xalign", 0)
Packit Service 1d8f1c
        column.pack_start(renderer, False)
Packit Service 1d8f1c
        column.set_cell_data_func(renderer, self.__icon_cell_data_cb)
Packit Service 1d8f1c
Packit Service 1d8f1c
        renderer = Gtk.CellRendererText()
Packit Service 1d8f1c
        renderer.set_property("xalign", 0)
Packit Service 1d8f1c
        renderer.set_property("ellipsize", Pango.EllipsizeMode.END)
Packit Service 1d8f1c
        column.pack_start(renderer, True)
Packit Service 1d8f1c
        column.set_cell_data_func(renderer, self.__name_cell_data_cb)
Packit Service 1d8f1c
        self.append_column(column)
Packit Service 1d8f1c
Packit Service 1d8f1c
        # create im keyboard layout column
Packit Service 1d8f1c
        renderer = Gtk.CellRendererCombo()
Packit Service 1d8f1c
        model = Gtk.ListStore(GObject.TYPE_STRING)
Packit Service 1d8f1c
        model.append(("us",))
Packit Service 1d8f1c
        model.append(("jp",))
Packit Service 1d8f1c
        model.append(("xkb",))
Packit Service 1d8f1c
        renderer.set_property("xalign", 0)
Packit Service 1d8f1c
        renderer.set_property("model", model)
Packit Service 1d8f1c
        renderer.set_property("text-column", 0)
Packit Service 1d8f1c
        renderer.set_property("has-entry", False)
Packit Service 1d8f1c
        renderer.set_property("editable", True)
Packit Service 1d8f1c
Packit Service 1d8f1c
        column = Gtk.TreeViewColumn(_("Kbd"))
Packit Service 1d8f1c
        column.set_expand(False)
Packit Service 1d8f1c
        column.set_fixed_width(32)
Packit Service 1d8f1c
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
Packit Service 1d8f1c
        column.pack_start(renderer, False)
Packit Service 1d8f1c
        column.set_cell_data_func(renderer, self.__layout_cell_data_cb)
Packit Service 1d8f1c
        # self.append_column(column)
Packit Service 1d8f1c
Packit Service 1d8f1c
        self.get_selection().connect("changed", self.__selection_changed_cb)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __sort_engines(self, model, a, b, data):
Packit Service 1d8f1c
        engine_a = model[a][0]
Packit Service 1d8f1c
        engine_b = model[b][0]
Packit Service 1d8f1c
        language_a = IBus.get_language_name(engine_a.get_language())
Packit Service 1d8f1c
        language_b = IBus.get_language_name(engine_b.get_language())
Packit Service 1d8f1c
        longname_a = i18n.gettext_engine_longname(engine_a)
Packit Service 1d8f1c
        longname_b = i18n.gettext_engine_longname(engine_b)
Packit Service 1d8f1c
        label_a = "%s - %s" % (language_a, longname_a)
Packit Service 1d8f1c
        label_b = "%s - %s" % (language_b, longname_b)
Packit Service 1d8f1c
        # http://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
Packit Service 1d8f1c
        return (label_a > label_b) - (label_a < label_b)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __selection_changed_cb(self, *args):
Packit Service 1d8f1c
        self.notify("active-engine");
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __emit_changed(self, *args):
Packit Service 1d8f1c
        if self.__changed:
Packit Service 1d8f1c
            self.__changed = False
Packit Service 1d8f1c
            self.notify("engines")
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __emit_changed_delay_cb(self, *args):
Packit Service 1d8f1c
        if not self.__changed:
Packit Service 1d8f1c
            self.__changed = True
Packit Service 1d8f1c
            GLib.idle_add(self.__emit_changed)
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __icon_cell_data_cb(self, celllayout, renderer, model, it, data):
Packit Service 1d8f1c
        engine = self.__model.get_value(it, 0)
Packit Service 1d8f1c
Packit Service 1d8f1c
        # When append_engine() is called, self.__model.append(None)
Packit Service 1d8f1c
        # is called internally and engine == None could happen in
Packit Service 1d8f1c
        # a slow system.
Packit Service 1d8f1c
        if engine == None:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
Packit Service 1d8f1c
        icon_size = Gtk.icon_size_lookup(Gtk.IconSize.LARGE_TOOLBAR)[0]
Packit Service 1d8f1c
        pixbuf = load_icon(engine.get_icon(), Gtk.IconSize.LARGE_TOOLBAR)
Packit Service 1d8f1c
        renderer.set_property("pixbuf", pixbuf)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __name_cell_data_cb(self, celllayout, renderer, model, it, data):
Packit Service 1d8f1c
        engine = self.__model.get_value(it, 0)
Packit Service 1d8f1c
Packit Service 1d8f1c
        # When append_engine() is called, self.__model.append(None)
Packit Service 1d8f1c
        # is called internally and engine == None could happen in
Packit Service 1d8f1c
        # a slow system.
Packit Service 1d8f1c
        if engine == None:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
Packit Service 1d8f1c
        renderer.set_property("sensitive", True)
Packit Service 1d8f1c
        language = IBus.get_language_name(engine.get_language())
Packit Service 1d8f1c
        longname = i18n.gettext_engine_longname(engine)
Packit Service 1d8f1c
        renderer.set_property("text",
Packit Service 1d8f1c
                "%s - %s" % (language, longname))
Packit Service 1d8f1c
        renderer.set_property("weight", Pango.Weight.NORMAL)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def __layout_cell_data_cb(self, celllayout, renderer, model, it, data):
Packit Service 1d8f1c
        engine = self.__model.get_value(it, 0)
Packit Service 1d8f1c
        layout = self.__model.get_value(it, 1)
Packit Service 1d8f1c
        renderer.set_property("sensitive", True)
Packit Service 1d8f1c
        if not layout:
Packit Service 1d8f1c
            layout = engine.layout
Packit Service 1d8f1c
        renderer.set_property("text", layout)
Packit Service 1d8f1c
        renderer.set_property("weight", Pango.Weight.NORMAL)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def do_get_property(self, prop):
Packit Service 1d8f1c
        if prop.name == "active-engine":
Packit Service 1d8f1c
            it = self.get_selected_iter()
Packit Service 1d8f1c
            if it == None:
Packit Service 1d8f1c
                return None
Packit Service 1d8f1c
            row = self.__model.get(it, 0)
Packit Service 1d8f1c
            return row[0]
Packit Service 1d8f1c
        elif prop.name == "engines":
Packit Service 1d8f1c
            engines = [ r[0] for r in self.__model if r[0] != None]
Packit Service 1d8f1c
            return engines
Packit Service 1d8f1c
        else:
Packit Service 1d8f1c
            raise AttributeError('unknown property %s' % prop.name)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def do_set_property(self, prop, value):
Packit Service 1d8f1c
        if prop.name == "active-engine":
Packit Service 1d8f1c
            raise AttributeError("active-engine is readonly")
Packit Service 1d8f1c
        elif prop.name == "engines":
Packit Service 1d8f1c
            set_engines(value)
Packit Service 1d8f1c
        else:
Packit Service 1d8f1c
            raise AttributeError('unknown property %s' % prop.name)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def set_engines(self, engines):
Packit Service 1d8f1c
        self.__model.clear()
Packit Service 1d8f1c
        self.__engines = []
Packit Service 1d8f1c
        for e in engines:
Packit Service 1d8f1c
            if e in self.__engines:
Packit Service 1d8f1c
                continue
Packit Service 1d8f1c
            it = self.__model.append(None)
Packit Service 1d8f1c
            i18n.init_textdomain(e.get_textdomain())
Packit Service 1d8f1c
            self.__model.set(it, 0, e)
Packit Service 1d8f1c
            self.__engines.append(e)
Packit Service 1d8f1c
        self.__emit_changed()
Packit Service 1d8f1c
Packit Service 1d8f1c
    def get_selected_iter(self):
Packit Service 1d8f1c
        selection = self.get_selection()
Packit Service 1d8f1c
        if selection:
Packit Service 1d8f1c
            return selection.get_selected()[1]
Packit Service 1d8f1c
Packit Service 1d8f1c
    def get_engines(self):
Packit Service 1d8f1c
        return self.__engines
Packit Service 1d8f1c
Packit Service 1d8f1c
    def get_sorted_engines(self):
Packit Service 1d8f1c
        return self.get_property("engines")
Packit Service 1d8f1c
Packit Service 1d8f1c
    def get_active_engine(self):
Packit Service 1d8f1c
        return self.get_property("active-engine")
Packit Service 1d8f1c
Packit Service 1d8f1c
    def prepend_engine(self, engine):
Packit Service 1d8f1c
        if engine == None or engine in self.__engines:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        it = self.__model.prepend(None)
Packit Service 1d8f1c
        self.__model.set(it, 0, engine)
Packit Service 1d8f1c
        self.__engines = [engine] + self.__engines
Packit Service 1d8f1c
Packit Service 1d8f1c
    def append_engine(self, engine):
Packit Service 1d8f1c
        if engine == None or engine in self.__engines:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        it = self.__model.append(None)
Packit Service 1d8f1c
        self.__model.set(it, 0, engine)
Packit Service 1d8f1c
        self.__engines.append(engine)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def remove_engine(self):
Packit Service 1d8f1c
        it = self.get_selected_iter()
Packit Service 1d8f1c
        if it == None:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        row = self.__model[it]
Packit Service 1d8f1c
        engine = row[0]
Packit Service 1d8f1c
        self.__engines.remove(engine)
Packit Service 1d8f1c
        index = row.path.get_indices()[0]
Packit Service 1d8f1c
        self.__model.remove(it)
Packit Service 1d8f1c
        try:
Packit Service 1d8f1c
            row = self.__model[index]
Packit Service 1d8f1c
            selection = self.get_selection()
Packit Service 1d8f1c
            selection.select_path(row.path)
Packit Service 1d8f1c
        except:
Packit Service 1d8f1c
            pass
Packit Service 1d8f1c
Packit Service 1d8f1c
    def move_up_engine(self):
Packit Service 1d8f1c
        it = self.get_selected_iter()
Packit Service 1d8f1c
        if it == None:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        row = self.__model[it]
Packit Service 1d8f1c
        index = row.path.get_indices()[0]
Packit Service 1d8f1c
        if index == 0:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        self.__model.swap(it, self.__model[index - 1].iter)
Packit Service 1d8f1c
        self.scroll_to_cell(row.path, None)
Packit Service 1d8f1c
Packit Service 1d8f1c
    def move_down_engine(self):
Packit Service 1d8f1c
        it = self.get_selected_iter()
Packit Service 1d8f1c
        if it == None:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        row = self.__model[it]
Packit Service 1d8f1c
        index = row.path.get_indices()[0]
Packit Service 1d8f1c
        last_row = self.__model[-1]
Packit Service 1d8f1c
        last_index = last_row.path.get_indices()[0]
Packit Service 1d8f1c
        if index == last_index:
Packit Service 1d8f1c
            return
Packit Service 1d8f1c
        self.__model.swap(it, self.__model[index + 1].iter)
Packit Service 1d8f1c
        self.scroll_to_cell(row.path, None)
Packit Service 1d8f1c
Packit Service 1d8f1c
GObject.type_register(EngineTreeView)
Packit Service 1d8f1c
Packit Service 1d8f1c
if __name__ == "__main__":
Packit Service 1d8f1c
    tree = EngineTreeView()
Packit Service 1d8f1c
    tree.set_engines([IBus.EngineDesc(language="zh")])
Packit Service 1d8f1c
    w = Gtk.Window()
Packit Service 1d8f1c
    w.add(tree)
Packit Service 1d8f1c
    w.show_all()
Packit Service 1d8f1c
    Gtk.main()