# vim:set et sts=4 sw=4: # # ibus - The Input Bus # # Copyright (c) 2007-2014 Peng Huang # Copyright (c) 2007-2014 Red Hat, Inc. # # 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 import locale import functools import sys from gi.repository import GObject from gi.repository import Gtk from gi.repository import IBus from gi.repository import Pango from icon import load_icon from i18n import _, N_ class EngineComboBox(Gtk.ComboBox): __gtype_name__ = 'EngineComboBox' __gproperties__ = { 'active-engine' : ( object, 'selected engine', 'selected engine', GObject.ParamFlags.READABLE) } def __init__(self): super(EngineComboBox, self).__init__() self.connect("notify::active", self.__notify_active_cb) self.__model = None renderer = Gtk.CellRendererPixbuf() renderer.set_property("xalign", 0) renderer.set_property("xpad", 2) self.pack_start(renderer, False) self.set_cell_data_func(renderer, self.__icon_cell_data_cb, None) renderer = Gtk.CellRendererText() renderer.set_property("xalign", 0) renderer.set_property("xpad", 2) self.pack_start(renderer, True) self.set_cell_data_func(renderer, self.__name_cell_data_cb, None) def set_engines(self, engines): self.__model = Gtk.TreeStore(object) iter1 = self.__model.append(None) self.__model.set(iter1, 0, 0) langs = {} for e in engines: l = IBus.get_language_name(e.get_language()) if l == None: l = "" if l not in langs: langs[l] = [] langs[l].append(e) keys = list(langs.keys()) keys.sort(key=functools.cmp_to_key(locale.strcoll)) loc = locale.getlocale()[0] # None on C locale if loc == None or loc == 'C': loc = 'en_US' current_lang = IBus.get_language_name(loc) # move current language to the first place if current_lang in keys: keys.remove(current_lang) keys.insert(0, current_lang) #add "Others" to the end of the combo box if IBus.get_language_name("Other") in keys: keys.remove(IBus.get_language_name("Other")) keys += [IBus.get_language_name("Other")] for l in keys: iter1 = self.__model.append(None) self.__model.set(iter1, 0, l) def cmp_engine(a, b): if a.get_rank() == b.get_rank(): return locale.strcoll(a.get_longname(), b.get_longname()) return int(b.get_rank() - a.get_rank()) langs[l].sort(key=functools.cmp_to_key(cmp_engine)) for e in langs[l]: iter2 = self.__model.append(iter1) self.__model.set(iter2, 0, e) self.set_model(self.__model) self.set_active(0) def __icon_cell_data_cb(self, celllayout, renderer, model, iter, data): engine = self.__model.get_value(iter, 0) if isinstance(engine, str): renderer.set_property("visible", False) renderer.set_property("sensitive", False) elif sys.version < '3' and isinstance (engine, unicode): renderer.set_property("visible", False) renderer.set_property("sensitive", False) elif isinstance(engine, int): renderer.set_property("visible", False) renderer.set_property("sensitive", False) else: renderer.set_property("visible", True) renderer.set_property("sensitive", True) pixbuf = load_icon(engine.get_icon(), Gtk.IconSize.LARGE_TOOLBAR) renderer.set_property("pixbuf", pixbuf) def __name_cell_data_cb(self, celllayout, renderer, model, iter, data): engine = self.__model.get_value(iter, 0) if isinstance (engine, str): renderer.set_property("sensitive", False) renderer.set_property("text", engine) renderer.set_property("weight", Pango.Weight.NORMAL) elif sys.version < '3' and isinstance (engine, unicode): renderer.set_property("sensitive", False) renderer.set_property("text", engine) renderer.set_property("weight", Pango.Weight.NORMAL) elif isinstance(engine, int): renderer.set_property("sensitive", True) renderer.set_property("text", _("Select an input method")) renderer.set_property("weight", Pango.Weight.NORMAL) else: renderer.set_property("sensitive", True) renderer.set_property("text", engine.get_longname()) renderer.set_property("weight", Pango.Weight.BOLD if engine.get_rank() > 0 else Pango.Weight.NORMAL) def __notify_active_cb(self, combobox, property): self.notify("active-engine") def do_get_property(self, property): if property.name == "active-engine": i = self.get_active() if i == 0 or i == -1: return None iter = self.get_active_iter() return self.get_model()[iter][0] else: raise AttributeError('unknown property %s' % property.name) def get_active_engine(self): return self.get_property("active-engine") if __name__ == "__main__": combo = EngineComboBox() combo.set_engines([IBus.EngineDesc(language="zh")]) w = Gtk.Window() w.add(combo) w.show_all() Gtk.main()