def do_create_engine(self, engine_name): if DEBUG_LEVEL > 1: sys.stderr.write("EngineFactory.do_create_engine(engine_name=%s)\n" % engine_name) engine_base_path = "/com/redhat/IBus/engines/table/%s/engine/" engine_path = engine_base_path % re.sub( r'[^a-zA-Z0-9_/]', '_', engine_name) try: if engine_name in self.dbdict: self.db = self.dbdict[engine_name] else: self.db = tabsqlitedb.tabsqlitedb() self.dbdict[engine_name] = self.db if engine_name in self.enginedict: engine = self.enginedict[engine_name] else: engine = hunspell_table.TypingBoosterEngine( self.bus, engine_path + str(self.engine_id), self.db) self.enginedict[engine_name] = engine self.engine_id += 1 return engine except: print("failed to create engine %s" %engine_name) import traceback traceback.print_exc () raise Exception("Cannot create engine %s" % engine_name)
def create_engine(self, engine_name): # because we need db to be past to Engine # the type (engine_name) == dbus.String name = engine_name.encode("utf8") self.engine_path = engine_base_path % path_patt.sub("_", name) try: if not self.db: # first check self.dbdict if not name in self.dbdict: try: db_dir = os.path.join(os.getenv("IBUS_TABLE_LOCATION"), "tables") except: db_dir = "/usr/share/ibus-table/tables" db = os.path.join(db_dir, name + ".db") udb = name + "-user.db" _sq_db = tabsqlitedb.tabsqlitedb(name=db, user_db=udb) _sq_db.db.commit() self.dbdict[name] = _sq_db else: name = self.dbusname engine = table.tabengine(self.bus, self.engine_path + str(self.engine_id), self.dbdict[name]) self.engine_id += 1 # return engine.get_dbus_object() return engine except: print "fail to create engine %s" % engine_name import traceback traceback.print_exc() raise IBusException("Can not create engine %s" % engine_name)
def do_create_engine(self, engine_name): # because we need db to be past to Engine # the type (engine_name) == dbus.String name = engine_name.encode ('utf8') self.engine_path = engine_base_path % path_patt.sub ('_', name) try: if not self.db: # first check self.dbdict if not name in self.dbdict: try: db_dir = os.path.join (os.getenv('IBUS_TABLE_LOCATION'),'tables') except: db_dir = "/usr/share/ibus-table/tables" db = os.path.join (db_dir,name+'.db') udb = name+'-user.db' if not os.path.exists(db): byo_db_dir = os.path.join(os.getenv('HOME'), '.ibus/byo-tables') db = os.path.join(byo_db_dir, name + '.db') _sq_db = tabsqlitedb.tabsqlitedb( name = db,user_db = udb ) _sq_db.db.commit() self.dbdict[name] = _sq_db else: name = self.dbusname engine = table.tabengine(self.bus, self.engine_path \ + str(self.engine_id), self.dbdict[name]) self.engine_id += 1 #return engine.get_dbus_object() return engine except: print "fail to create engine %s" % engine_name import traceback traceback.print_exc () raise Exception("Can not create engine %s" % engine_name)
def __init__(self, bus, db="", icon=""): # here the db should be the abs path to sql db # this is the backend sql db we need for our IME # we need get lots of IME property from this db :) # self.db = tabsqlitedb.tabsqlitedb( name = database ) if db: self.dbusname = os.path.basename(db).replace(".db", "") udb = os.path.basename(db).replace(".db", "-user.db") self.db = tabsqlitedb.tabsqlitedb(name=db, user_db=udb) self.db.db.commit() self.dbdict = {self.dbusname: self.db} else: self.db = None self.dbdict = {} # init factory self.bus = bus super(EngineFactory, self).__init__(bus) self.engine_id = 0 try: bus = dbus.Bus() user = os.path.basename(os.path.expanduser("~")) self._sm_bus = bus.get_object("org.ibus.table.SpeedMeter.%s" % user, "/org/ibus/table/SpeedMeter") self._sm = dbus.Interface(self._sm_bus, "org.ibus.table.SpeedMeter") except: self._sm = None
def create_engine(self, engine_name): # because we need db to be past to Engine # the type (engine_name) == dbus.String name = engine_name.encode('utf8') self.engine_path = engine_base_path % path_patt.sub('_', name) try: if not self.db: # first check self.dbdict if not name in self.dbdict: try: db_dir = os.path.join( os.getenv('IBUS_EUROPEAN_TABLE_LOCATION'), 'european-tables') except: db_dir = "/usr/share/ibus-european-table/european-tables" db = os.path.join(db_dir, name + '.db') udb = name + '-user.db' _sq_db = tabsqlitedb.tabsqlitedb(name=db, user_db=udb) _sq_db.db.commit() self.dbdict[name] = _sq_db else: name = self.dbusname engine = european_table.tabengine(self.bus, self.engine_path \ + str(self.engine_id), self.dbdict[name]) self.engine_id += 1 #return engine.get_dbus_object() return engine except: print "fail to create engine %s" % engine_name import traceback traceback.print_exc() raise IBusException("Can not create engine %s" % engine_name)
def __init__(self, bus, db="", icon=""): # here the db should be the abs path to sql db # this is the backend sql db we need for our IME # we need get lots of IME property from this db :) #self.db = tabsqlitedb.tabsqlitedb( name = database ) if db: self.dbusname = os.path.basename(db).replace('.db', '') udb = os.path.basename(db).replace('.db', '-user.db') self.db = tabsqlitedb.tabsqlitedb(name=db, user_db=udb) self.db.db.commit() self.dbdict = {self.dbusname: self.db} else: self.db = None self.dbdict = {} # init factory self.bus = bus super(EngineFactory, self).__init__(bus) self.engine_id = 0 try: bus = dbus.Bus() user = os.path.basename(os.path.expanduser('~')) self._sm_bus = bus.get_object ("org.ibus.table.SpeedMeter.%s"\ % user, "/org/ibus/table/SpeedMeter") self._sm = dbus.Interface(self._sm_bus,\ "org.ibus.table.SpeedMeter") except: self._sm = None
def setUp(self): self.bus = IBus.Bus() self.db = tabsqlitedb.tabsqlitedb(user_db_file = ':memory:') self.engine = TypingBoosterEngine( self.bus, '/com/redhat/IBus/engines/table/typing_booster/engine/0', self.db, unit_test = True) self.backup_original_settings() self.set_default_settings()
def setUp(self): self.bus = IBus.Bus() # it doesn’t really matter which config file for which language is used self.db = tabsqlitedb.tabsqlitedb( config_filename ='../hunspell-tables/de_DE.conf', user_db_file = ':memory:') self.engine = TypingBoosterEngine( self.bus, '/com/redhat/IBus/engines/table/typing_booster_de_DE/engine/0', self.db, unit_test = True) self.backup_original_settings() self.set_default_settings()
def __init__(self, bus, db="", icon=""): # db is the full path to the sql database if db: self.dbusname = os.path.basename(db).replace('.db', '') udb = os.path.basename(db).replace('.db', '-user.db') self.db = tabsqlitedb.tabsqlitedb(filename=db, user_db=udb) self.db.db.commit() self.dbdict = {self.dbusname: self.db} else: self.db = None self.dbdict = {} # init factory self.bus = bus super(EngineFactory, self).__init__(connection=bus.get_connection(), object_path=IBus.PATH_FACTORY) self.engine_id = 0 self.engine_path = ''
def __init__ (self, bus, db="", icon=""): # db is the full path to the sql database if db: self.dbusname = os.path.basename(db).replace('.db','') udb = os.path.basename(db).replace('.db','-user.db') self.db = tabsqlitedb.tabsqlitedb(filename = db, user_db = udb) self.db.db.commit() self.dbdict = {self.dbusname:self.db} else: self.db = None self.dbdict = {} # init factory self.bus = bus super(EngineFactory, self).__init__(connection=bus.get_connection(), object_path=IBus.PATH_FACTORY) self.engine_id = 0 self.engine_path = ''
def __init__(self, bus, db="", icon=""): # here the db should be the abs path to sql db # this is the backend sql db we need for our IME # we need get lots of IME property from this db :) #self.db = tabsqlitedb.tabsqlitedb(name=database) if db: self.dbbasename = os.path.basename(db).replace('.db', '') udb = os.path.basename(db).replace('.db', '-user.db') self.db = tabsqlitedb.tabsqlitedb(name=db, user_db=udb) self.db.db.commit() self.dbdict = {self.dbbasename: self.db} else: self.db = None self.dbdict = {} # init factory self.bus = bus super(EngineFactory, self).__init__(connection=bus.get_connection(), object_path=IBus.PATH_FACTORY) self.engine_id = 0
def __init__ (self, bus, db="", icon=""): # here the db should be the abs path to sql db # this is the backend sql db we need for our IME # we need get lots of IME property from this db :) #self.db = tabsqlitedb.tabsqlitedb( name = database ) if db: self.dbusname = os.path.basename(db).replace('.db','') udb = os.path.basename(db).replace('.db','-user.db') self.db = tabsqlitedb.tabsqlitedb( name = db,user_db = udb ) self.db.db.commit() self.dbdict = {self.dbusname:self.db} else: self.db = None self.dbdict = {} # init factory self.bus = bus super(EngineFactory,self).__init__ (connection=bus.get_connection(), object_path=IBus.PATH_FACTORY) self.engine_id=0
def do_create_engine(self, engine_name): engine_name = re.sub(r'^table:', '', engine_name) engine_base_path = "/com/redhat/IBus/engines/table/%s/engine/" path_patt = re.compile(r'[^a-zA-Z0-9_/]') self.engine_path = engine_base_path % path_patt.sub ('_', engine_name) try: if not self.db: # first check self.dbdict if not engine_name in self.dbdict: try: db_dir = os.path.join( os.getenv('IBUS_TABLE_LOCATION'),'tables') except: db_dir = "/usr/share/ibus-table/tables" db = os.path.join (db_dir, engine_name+'.db') udb = engine_name+'-user.db' if not os.path.exists(db): byo_db_dir = os.path.join( os.getenv('HOME'), '.ibus/byo-tables') db = os.path.join(byo_db_dir, engine_name + '.db') _sq_db = tabsqlitedb.tabsqlitedb( filename = db, user_db = udb) _sq_db.db.commit() self.dbdict[engine_name] = _sq_db else: name = self.dbusname engine = table.tabengine(self.bus, self.engine_path + str(self.engine_id), self.dbdict[engine_name]) self.engine_id += 1 #return engine.get_dbus_object() return engine except: print("failed to create engine %s" %engine_name) import traceback traceback.print_exc () raise Exception("Cannot create engine %s" %engine_name)
def do_create_engine(self, engine_name): engine_name = re.sub(r'^table:', '', engine_name) engine_base_path = "/com/redhat/IBus/engines/table/%s/engine/" path_patt = re.compile(r'[^a-zA-Z0-9_/]') self.engine_path = engine_base_path % path_patt.sub('_', engine_name) try: if not self.db: # first check self.dbdict if not engine_name in self.dbdict: try: db_dir = os.path.join(os.getenv('IBUS_TABLE_LOCATION'), 'tables') except: db_dir = "/usr/share/ibus-table/tables" db = os.path.join(db_dir, engine_name + '.db') udb = engine_name + '-user.db' if not os.path.exists(db): byo_db_dir = os.path.join(os.getenv('HOME'), '.ibus/byo-tables') db = os.path.join(byo_db_dir, engine_name + '.db') _sq_db = tabsqlitedb.tabsqlitedb(filename=db, user_db=udb) _sq_db.db.commit() self.dbdict[engine_name] = _sq_db else: name = self.dbusname engine = table.tabengine(self.bus, self.engine_path + str(self.engine_id), self.dbdict[engine_name]) self.engine_id += 1 #return engine.get_dbus_object() return engine except: print("failed to create engine %s" % engine_name) import traceback traceback.print_exc() raise Exception("Cannot create engine %s" % engine_name)
def main(): if options.xml: from locale import getdefaultlocale from xml.etree.ElementTree import Element, SubElement, tostring # we will output the engines xml and return. # 1. we find all dbs in db_dir and extract the infos into # Elements dbs = os.listdir(db_dir) dbs = filter(lambda x: x.endswith('.db'), dbs) byo_dbs = os.listdir(byo_db_dir) byo_dbs = filter(lambda x: x.endswith('.db'), byo_dbs) _all_dbs = [] for _db in dbs: _all_dbs.append(os.path.join(db_dir, _db)) for _db in byo_dbs: _all_dbs.append(os.path.join(byo_db_dir, _db)) egs = Element('engines') for _db in _all_dbs: _sq_db = tabsqlitedb.tabsqlitedb(_db) _engine = SubElement(egs, 'engine') _name = SubElement(_engine, 'name') _name.text = os.path.basename(_db).replace('.db', '') _longname = SubElement(_engine, 'longname') _longname.text = '' try: _locale = getdefaultlocale()[0].lower() _longname.text = _sq_db.get_ime_property ( \ '.'.join(['name',_locale]) ) except: pass if not _longname.text: _longname.text = _name.text _language = SubElement(_engine, 'language') _langs = _sq_db.get_ime_property('languages') if _langs: _langs = _langs.split(',') if len(_langs) == 1: _language.text = _langs[0].strip() else: # we ignore the place _language.text = _langs[0].strip().split('_')[0] _license = SubElement(_engine, 'license') _license.text = _sq_db.get_ime_property('license') _author = SubElement(_engine, 'author') _author.text = _sq_db.get_ime_property('author') _icon = SubElement(_engine, 'icon') _icon_basename = _sq_db.get_ime_property('icon') if _icon_basename: _icon.text = os.path.join(icon_dir, _icon_basename) _layout = SubElement(_engine, 'layout') _layout.text = _sq_db.get_ime_property('layout') _desc = SubElement(_engine, 'description') _desc.text = _sq_db.get_ime_property('description') # now format the xmlout pretty indent(egs) egsout = tostring(egs, encoding='utf8') egsout = patt.sub('', egsout) print egsout return 0 if options.daemon: if os.fork(): sys.exit() if options.db: if os.access(options.db, os.F_OK): db = options.db else: db = '%s%s%s' % (db_dir, os.path.sep, os.path.basename(options.db)) else: db = "" ima = IMApp(db, options.ibus) signal(SIGTERM, lambda signum, stack_frame: cleanup(ima)) signal(SIGINT, lambda signum, stack_frame: cleanup(ima)) try: ima.run() except KeyboardInterrupt: ima.quit()
def main(): if options.xml: from locale import getdefaultlocale from xml.etree.ElementTree import Element, SubElement, tostring # we will output the engines xml and return. # 1. we find all dbs in db_dir and extract the infos into # Elements dbs = os.listdir(db_dir) dbs = filter (lambda x: x.endswith('.db'), dbs) #if not dbs: # return egs = Element('engines') for _db in dbs: _sq_db = tabsqlitedb.tabsqlitedb (os.path.join (db_dir, _db)) _engine = SubElement (egs,'engine') _name = SubElement (_engine, 'name') _name.text = _db.replace ('.db','') _longname = SubElement (_engine, 'longname') _longname.text = '' try: _locale = getdefaultlocale()[0].lower() _longname.text = _sq_db.get_ime_property ( \ '.'.join(['name',_locale]) ) except: pass if not _longname.text: _longname.text = _name.text _language = SubElement (_engine, 'language') _langs = _sq_db.get_ime_property ('languages') if _langs: _langs = _langs.split (',') if len (_langs) == 1: _language.text = _langs[0].strip() else: # we ignore the place _language.text = _langs[0].strip().split('_')[0] _license = SubElement (_engine, 'license') _license.text = _sq_db.get_ime_property ('license') _author = SubElement (_engine, 'author') _author.text = _sq_db.get_ime_property ('author') _icon = SubElement (_engine, 'icon') _icon_basename = _sq_db.get_ime_property ('icon') if _icon_basename: _icon.text = os.path.join (icon_dir, _icon_basename) _layout = SubElement (_engine, 'layout') _layout.text = _sq_db.get_ime_property ('layout') _desc = SubElement (_engine, 'description') _desc.text = _sq_db.get_ime_property ('description') # now format the xmlout pretty indent (egs) egsout = tostring (egs, encoding='utf8') egsout = patt.sub ('',egsout) print egsout return 0 if options.daemon : if os.fork(): sys.exit() if options.db: if os.access( options.db, os.F_OK): db = options.db else: db = '%s%s%s' % (db_dir,os.path.sep, os.path.basename(options.db) ) else: db="" ima=IMApp(db, options.ibus) signal (SIGTERM, lambda signum, stack_frame: cleanup(ima)) signal (SIGINT, lambda signum, stack_frame: cleanup(ima)) try: ima.run() except KeyboardInterrupt: ima.quit()
def main(): if options.xml: from locale import getdefaultlocale from xml.etree.ElementTree import Element, SubElement, tostring # we will output the engines xml and return. # 1. we find all dbs in db_dir and extract the infos into # Elements dbs = os.listdir(db_dir) dbs = filter (lambda x: x.endswith('.db'), dbs) _all_dbs = [] for _db in dbs: _all_dbs.append(os.path.join (db_dir, _db)) try: byo_dbs = os.listdir(byo_db_dir) byo_dbs = filter (lambda x: x.endswith('.db'), byo_dbs) for _db in byo_dbs: _all_dbs.append(os.path.join (byo_db_dir, _db)) except OSError: # byo_db_dir does not exist or is not accessible pass egs = Element('engines') for _db in _all_dbs: _sq_db = tabsqlitedb.tabsqlitedb (_db, user_db=None) _engine = SubElement (egs,'engine') _name = SubElement (_engine, 'name') engine_name = os.path.basename(_db).replace ('.db','') _name.text = 'table:'+engine_name setup_arg = "{} --engine-name {}".format(setup_cmd, _name.text) _longname = SubElement (_engine, 'longname') _longname.text = '' # getdefaultlocale() returns something like ('ja_JP', 'UTF-8'). # In case of C/POSIX locale it returns (None, None) _locale = getdefaultlocale()[0] if _locale: _locale = _locale.lower() else: _locale = 'en' _longname.text = _sq_db.ime_properties.get( '.'.join(['name', _locale])) if not _longname.text: _longname.text = _sq_db.ime_properties.get( '.'.join(['name', _locale.split('_')[0]])) if not _longname.text: _longname.text = _sq_db.ime_properties.get('name') if not _longname.text: _longname.text = engine_name _language = SubElement (_engine, 'language') _langs = _sq_db.ime_properties.get('languages') if _langs: _langs = _langs.split (',') if len (_langs) == 1: _language.text = _langs[0].strip() else: # we ignore the place _language.text = _langs[0].strip().split('_')[0] _license = SubElement (_engine, 'license') _license.text = _sq_db.ime_properties.get('license') _author = SubElement (_engine, 'author') _author.text = _sq_db.ime_properties.get('author') _icon = SubElement (_engine, 'icon') _icon_basename = _sq_db.ime_properties.get('icon') if _icon_basename: _icon.text = os.path.join (icon_dir, _icon_basename) _layout = SubElement (_engine, 'layout') _layout.text = _sq_db.ime_properties.get('layout') _symbol = SubElement (_engine, 'symbol') _symbol.text = _sq_db.ime_properties.get('symbol') _desc = SubElement (_engine, 'description') _desc.text = _sq_db.ime_properties.get('description') _setup = SubElement (_engine, 'setup') _setup.text = setup_arg # now format the xmlout pretty indent (egs) egsout = tostring (egs, encoding='utf8').decode('utf-8') patt = re.compile (r'<\?.*\?>\n') egsout = patt.sub ('', egsout) sys.stdout.buffer.write((egsout+'\n').encode('utf-8')) return 0 if options.daemon : if os.fork(): sys.exit() if options.db: if os.access( options.db, os.F_OK): db = options.db else: db = '%s%s%s' % (db_dir, os.path.sep, os.path.basename(options.db)) else: db = "" ima = IMApp(db, options.ibus) signal (SIGTERM, lambda signum, stack_frame: cleanup(ima)) signal (SIGINT, lambda signum, stack_frame: cleanup(ima)) try: ima.run() except KeyboardInterrupt: ima.quit()
def __init__(self, bus): filename = path.join(path.dirname(__file__), "setup.glade") self.builder = Gtk.Builder() self.builder.set_translation_domain(DOMAINNAME) self.builder.add_from_file(filename) event_handler = EventHandler() self.builder.connect_signals(event_handler) if not self.check_instance(): dummy_service = SetupService() # Try to figure out the config file name: self.config_file = None if _ARGS.config_file: # If the config file is specified on the command line, use that: self.config_file = _ARGS.config_file else: # If the config file is not specified on the command line, # try to get it from the environment. This is necessary # in gnome-shell on Fedora 18 because the setup tool is # called without command line options there but the # environment variable IBUS_ENGINE_NAME is set: try: ibus_engine_name = os.environ['IBUS_ENGINE_NAME'] if ibus_engine_name.startswith('typing-booster:'): self.config_file = ( ibus_engine_name.replace('typing-booster:', '') + '.conf') else: self.__run_message_dialog( _('Unknown format of engine name: ' + 'IBUS_ENGINE_NAME=%(name)s') %{'name': ibus_engine_name}, Gtk.MessageType.WARNING) except: self.__run_message_dialog( _("IBUS_ENGINE_NAME environment variable is not set."), Gtk.MessageType.WARNING) if self.config_file is None: self.__run_message_dialog( _('Cannot determine the config file for this engine. ' + 'Please use the --config-file option.'), Gtk.MessageType.ERROR) sys.exit(1) return self.config_file_full_path = ( '/usr/share/ibus-typing-booster/hunspell-tables/' + self.config_file) if not os.path.isfile(self.config_file_full_path): self.__run_message_dialog( _("Config file %(file)s does not exist.") %{'file': self.config_file_full_path}, Gtk.MessageType.ERROR) sys.exit(1) return self.tabsqlitedb = tabsqlitedb.tabsqlitedb( config_filename=self.config_file_full_path) self.name = self.tabsqlitedb.ime_properties.get('name') self.config_section = "engine/typing-booster/%s" % self.name self.hunspell_dict_package = self.tabsqlitedb.ime_properties.get( 'hunspell_dict_package') self.symbol = self.tabsqlitedb.ime_properties.get('symbol') self.bus = bus self.config = self.bus.get_config() maindialog = self.builder.get_object("main_dialog") maindialog.set_title( _("Preferences for ibus-typing-booster \"%(symbol)s\"") %{'symbol': self.symbol}) # https://tronche.com/gui/x/icccm/sec-4.html#WM_CLASS # gnome-shell seems to use the first argument of set_wmclass() # to find the .desktop file. If the .desktop file can be # found, the name shown by gnome-shell in the top bar comes # from that .desktop file and the icon to show is also read # from that .desktop file. If the .desktop file cannot be # found, the second argument of set_wmclass() is shown by # gnome-shell in the top bar. maindialog.set_wmclass('ibus-setup-typing-booster', 'Typing Booster Preferences') maindialog.show() name_version = self.builder.get_object("name_version_label") name_version.set_markup( '<span font_size="large"><b>ibus-typing-booster %s</b></span>' %version.get_version()) self.shortcut_entry = self.builder.get_object( "shortcut_entry") self.shortcut_expansion_entry = self.builder.get_object( "shortcut_expansion_entry") shortcut_clear_button = self.builder.get_object( "shortcut_clear_button") shortcut_clear_button.connect( 'clicked', event_handler.on_shortcut_clear_clicked) shortcut_delete_button = self.builder.get_object( "shortcut_delete_button") shortcut_delete_button.connect( 'clicked', event_handler.on_shortcut_delete_clicked) shortcut_add_button = self.builder.get_object( "shortcut_add_button") shortcut_add_button.connect( 'clicked', event_handler.on_shortcut_add_clicked) self.shortcut_treeview = self.builder.get_object( "shortcut_treeview") self.shortcut_treeview_model = Gtk.ListStore(str, str) self.shortcut_treeview.set_model(self.shortcut_treeview_model) current_shortcuts = self.tabsqlitedb.list_user_shortcuts() for i, shortcut in enumerate(current_shortcuts): self.shortcut_treeview_model.append(shortcut) self.shortcut_treeview.append_column( Gtk.TreeViewColumn( # Translators: Column heading of the table listing the existing shortcuts _('Shortcut'), Gtk.CellRendererText(), text=0)) self.shortcut_treeview.append_column( Gtk.TreeViewColumn( # Translators: Column heading of the table listing the existing shortcuts _('Shortcut expansion'), Gtk.CellRendererText(), text=1)) self.shortcut_treeview.get_selection().connect( 'changed', event_handler.on_shortcut_selected) self.install_dictionary_button = self.builder.get_object( "install_dictionary_button") self.install_dictionary_button.connect( 'clicked', event_handler.on_install_dictionary_clicked) self.learn_from_file_button = self.builder.get_object( "learn_from_file_button") self.learn_from_file_button.connect( 'clicked', event_handler.on_learn_from_file_clicked) self.delete_learned_data_button = self.builder.get_object( "delete_learned_data_button") self.delete_learned_data_button.connect( 'clicked', event_handler.on_delete_learned_data_clicked) close_button = self.builder.get_object("close_button") close_button.connect('clicked', event_handler.onCloseClicked) tab_enable_checkbox = self.builder.get_object("tab_enable_checkbox") self.tab_enable = itb_util.variant_to_value( self.config.get_value(self.config_section, 'tabenable')) if self.tab_enable is None: self.tab_enable = False if self.tab_enable is True: tab_enable_checkbox.set_active(True) tab_enable_checkbox.connect( 'clicked', event_handler.on_tab_enable_checkbox) show_number_of_candidates_checkbox = self.builder.get_object( "show_number_of_candidates_checkbox") self.show_number_of_candidates = itb_util.variant_to_value( self.config.get_value( self.config_section, 'shownumberofcandidates')) if self.show_number_of_candidates is None: self.show_number_of_candidates = False if self.show_number_of_candidates is True: show_number_of_candidates_checkbox.set_active(True) show_number_of_candidates_checkbox.connect( 'clicked', event_handler.on_show_number_of_candidates_checkbox) use_digits_as_select_keys_checkbox = self.builder.get_object( "use_digits_as_select_keys_checkbox") self.use_digits_as_select_keys = itb_util.variant_to_value( self.config.get_value( self.config_section, 'usedigitsasselectkeys')) if self.use_digits_as_select_keys is None: self.use_digits_as_select_keys = True if self.use_digits_as_select_keys is True: use_digits_as_select_keys_checkbox.set_active(True) use_digits_as_select_keys_checkbox.connect( 'clicked', event_handler.on_use_digits_as_select_keys_checkbox) emoji_predictions_checkbox = self.builder.get_object( "emoji_predictions_checkbox") self.emoji_predictions = itb_util.variant_to_value( self.config.get_value( self.config_section, 'emojipredictions')) if self.emoji_predictions is None: self.emoji_predictions = True if self.emoji_predictions is True: emoji_predictions_checkbox.set_active(True) emoji_predictions_checkbox.connect( 'clicked', event_handler.on_emoji_predictions_checkbox) off_the_record_checkbox = self.builder.get_object( "off_the_record_checkbox") self.off_the_record = itb_util.variant_to_value( self.config.get_value( self.config_section, 'offtherecord')) if self.off_the_record is None: self.off_the_record = False if self.off_the_record is True: off_the_record_checkbox.set_active(True) off_the_record_checkbox.connect( 'clicked', event_handler.on_off_the_record_checkbox) show_status_info_in_auxiliary_text_checkbox = self.builder.get_object( "show_status_info_in_auxiliary_text_checkbox") self.show_status_info_in_auxiliary_text = itb_util.variant_to_value( self.config.get_value( self.config_section, 'showstatusinfoinaux')) if self.show_status_info_in_auxiliary_text is None: self.show_status_info_in_auxiliary_text = True if self.show_status_info_in_auxiliary_text is True: show_status_info_in_auxiliary_text_checkbox.set_active(True) show_status_info_in_auxiliary_text_checkbox.connect( 'clicked', event_handler.on_show_status_info_in_auxiliary_text_checkbox) add_direct_input_checkbox = self.builder.get_object( "add_direct_input_checkbox") self.add_direct_input = itb_util.variant_to_value( self.config.get_value( self.config_section, 'adddirectinput')) if self.add_direct_input is None: self.add_direct_input = False if self.add_direct_input is True: add_direct_input_checkbox.set_active(True) add_direct_input_checkbox.connect( 'clicked', event_handler.on_add_direct_input_checkbox) remember_last_used_preedit_ime_checkbox = self.builder.get_object( "remember_last_used_preedit_ime_checkbox") self.remember_last_used_predit_ime = itb_util.variant_to_value( self.config.get_value( self.config_section, 'rememberlastusedpreeditime')) if self.remember_last_used_predit_ime is None: self.remember_last_used_predit_ime = False if self.remember_last_used_predit_ime is True: remember_last_used_preedit_ime_checkbox.set_active(True) remember_last_used_preedit_ime_checkbox.connect( 'clicked', event_handler.on_remember_last_used_preedit_ime_checkbox) auto_commit_characters_entry = self.builder.get_object( "auto_commit_characters_entry") self.auto_commit_characters = itb_util.variant_to_value( self.config.get_value( self.config_section, 'autocommitcharacters')) if not self.auto_commit_characters: self.auto_commit_characters = '' auto_commit_characters_entry.set_text(self.auto_commit_characters) auto_commit_characters_entry.connect( 'notify::text', event_handler.on_auto_commit_characters_entry) self.page_size_adjustment = self.builder.get_object( "page_size_adjustment") self.page_size = itb_util.variant_to_value(self.config.get_value( self.config_section, 'pagesize')) if self.page_size: self.page_size_adjustment.set_value(int(self.page_size)) else: self.page_size_adjustment.set_value(6) self.page_size_adjustment.connect( 'value-changed', event_handler.on_page_size_adjustment_value_changed) self.min_char_complete_adjustment = self.builder.get_object( "min_char_complete_adjustment") self.min_char_complete = itb_util.variant_to_value( self.config.get_value(self.config_section, 'mincharcomplete')) if self.min_char_complete: self.min_char_complete_adjustment.set_value( int(self.min_char_complete)) else: self.min_char_complete_adjustment.set_value(1) self.min_char_complete_adjustment.connect( 'value-changed', event_handler.on_min_char_complete_adjustment_value_changed) self.lookup_table_orientation_combobox = self.builder.get_object( "lookup_table_orientation_combobox") lookup_table_orientation_store = Gtk.ListStore(str, int) lookup_table_orientation_store.append( [_('Horizontal'), IBus.Orientation.HORIZONTAL]) lookup_table_orientation_store.append( [_('Vertical'), IBus.Orientation.VERTICAL]) lookup_table_orientation_store.append( [_('System default'), IBus.Orientation.SYSTEM]) self.lookup_table_orientation_combobox.set_model( lookup_table_orientation_store) renderer_text = Gtk.CellRendererText() self.lookup_table_orientation_combobox.pack_start( renderer_text, True) self.lookup_table_orientation_combobox.add_attribute( renderer_text, "text", 0) lookup_table_orientation = itb_util.variant_to_value( self.config.get_value( self.config_section, 'lookuptableorientation')) if lookup_table_orientation is None: lookup_table_orientation = IBus.Orientation.VERTICAL for i, item in enumerate(lookup_table_orientation_store): if lookup_table_orientation == item[1]: self.lookup_table_orientation_combobox.set_active(i) self.lookup_table_orientation_combobox.connect( "changed", event_handler.on_lookup_table_orientation_combobox_changed) self.ime_combobox = self.builder.get_object("input_method_combobox") self.input_method_help_button = self.builder.get_object( "input_method_help_button") ime_store = Gtk.ListStore(str, str) self.supported_imes = [] imes = self.tabsqlitedb.ime_properties.get('imes').split(',') if not imes: imes = ['Native Keyboard:NoIme'] for item in imes: ime_store.append([item.split(':')[0], item.split(':')[1]]) self.supported_imes.append(item.split(':')[1]) self.ime_combobox.set_model(ime_store) self.ime_combobox.pack_start(renderer_text, True) self.ime_combobox.add_attribute(renderer_text, "text", 0) self.current_imes = [] inputmethod = itb_util.variant_to_value(self.config.get_value( self.config_section, 'inputmethod')) if inputmethod: inputmethods = [x.strip() for x in inputmethod.split(',')] for ime in inputmethods: self.current_imes.append(ime) if self.current_imes == []: # There is no ime set in dconf, use the first value from # the combobox as the default: self.current_imes = [ime_store[0][1]] if self.add_direct_input and 'NoIme' not in self.current_imes: self.current_imes.append('NoIme') if len(self.current_imes) == 1: self.main_ime = self.current_imes[0] else: self.main_ime = ( [x for x in self.current_imes if x in self.supported_imes][0]) combobox_has_ime = False for i, dummy_item in enumerate(ime_store): if ime_store[i][1] == self.main_ime: self.ime_combobox.set_active(i) combobox_has_ime = True if combobox_has_ime is False: # the combobox did not have the ime from the settings # take the ime from the first row of # the combobox as the fallback: self.main_ime = ime_store[0][1] self.ime_combobox.set_active(0) self.ime_combobox.connect( "changed", event_handler.on_ime_combobox_changed) if len(ime_store) < 2: self.ime_combobox.set_sensitive(False) self.input_method_help_button.connect( 'clicked', event_handler.on_input_method_help_button_clicked) if self.main_ime == 'NoIme': self.input_method_help_button.set_sensitive(False)
def get_default_options_from_database(self): self.tabsqlitedb = tabsqlitedb.tabsqlitedb( filename = os.path.join( db_dir, re.sub(r'^table:', '', self.__engine_name)+'.db'), user_db = None, create_database = False) self.__is_chinese = False self.__is_cjk = False languages = self.tabsqlitedb.ime_properties.get('languages') if languages: languages = languages.split(',') for language in languages: if language.strip().startswith('zh'): self.__is_chinese = True for lang in ['zh', 'ja', 'ko']: if language.strip().startswith(lang): self.__is_cjk = True self.__user_can_define_phrase = False user_can_define_phrase = self.tabsqlitedb.ime_properties.get( 'user_can-define_phrase') if user_can_define_phrase: self.__user_can_define_phrase = ( user_can_define_phrase.lower() == u'true') self.__rules = self.tabsqlitedb.ime_properties.get('rules') language_filter = self.tabsqlitedb.ime_properties.get('language_filter') if language_filter in ['cm0', 'cm1', 'cm2', 'cm3', 'cm4']: OPTION_DEFAULTS['chinesemode'] = int(language_filter[-1]) def_full_width_punct = self.tabsqlitedb.ime_properties.get( 'def_full_width_punct') if (def_full_width_punct and type(def_full_width_punct) == type(u'') and def_full_width_punct.lower() in [u'true', u'false']): OPTION_DEFAULTS['tabdeffullwidthpunct'] = ( def_full_width_punct.lower() == u'true') OPTION_DEFAULTS['endeffullwidthpunct'] = ( def_full_width_punct.lower() == u'true') def_full_width_letter = self.tabsqlitedb.ime_properties.get( 'def_full_width_letter') if (def_full_width_letter and type(def_full_width_letter) == type(u'') and def_full_width_letter.lower() in [u'true', u'false']): OPTION_DEFAULTS['tabdeffullwidthletter'] = ( def_full_width_letter.lower() == u'true') OPTION_DEFAULTS['endeffullwidthletter'] = ( def_full_width_letter.lower() == u'true') always_show_lookup = self.tabsqlitedb.ime_properties.get( 'always_show_lookup') if (always_show_lookup and type(always_show_lookup) == type(u'') and always_show_lookup.lower() in [u'true', u'false']): OPTION_DEFAULTS['alwaysshowlookup'] = ( always_show_lookup.lower() == u'true') select_keys_csv = self.tabsqlitedb.ime_properties.get('select_keys') if select_keys_csv: # select_keys_csv is something like: "1,2,3,4,5,6,7,8,9,0" OPTION_DEFAULTS['lookuptablepagesize'] = len( select_keys_csv.split(",")) auto_select = self.tabsqlitedb.ime_properties.get('auto_select') if (auto_select and type(auto_select) == type(u'') and auto_select.lower() in [u'true', u'false']): OPTION_DEFAULTS['autoselect'] = auto_select.lower() == u'true' auto_commit = self.tabsqlitedb.ime_properties.get('auto_commit') if (auto_commit and type(auto_commit) == type(u'') and auto_commit.lower() in [u'true', u'false']): OPTION_DEFAULTS['autocommit'] = auto_commit.lower() == u'true' orientation = self.tabsqlitedb.ime_properties.get('orientation') if (orientation and type(orientation) == type(u'') and orientation.lower() in [u'true', u'false']): OPTION_DEFAULTS['lookuptableorientation'] = ( orientation.lower() == u'true') # if space is a page down key, set the option # “spacekeybehavior” to “True”: page_down_keys_csv = self.tabsqlitedb.ime_properties.get( 'page_down_keys') if page_down_keys_csv: self._page_down_keys = [ IBus.keyval_from_name(x) for x in page_down_keys_csv.split(',')] if IBus.KEY_space in self._page_down_keys: OPTION_DEFAULTS['spacekeybehavior'] = True # if space is a commit key, set the option # “spacekeybehavior” to “False” (overrides if space is # also a page down key): commit_keys_csv = self.tabsqlitedb.ime_properties.get('commit_keys') if commit_keys_csv: self._commit_keys = [ IBus.keyval_from_name(x) for x in commit_keys_csv.split(',')] if IBus.KEY_space in self._commit_keys: OPTION_DEFAULTS['spacekeybehavior'] = False auto_wildcard = self.tabsqlitedb.ime_properties.get('auto_wildcard') if (auto_wildcard and type(auto_wildcard) == type(u'') and auto_wildcard.lower() in [u'true', u'false']): OPTION_DEFAULTS['autowildcard'] = auto_wildcard.lower() == u'true' single_wildcard_char = self.tabsqlitedb.ime_properties.get( 'single_wildcard_char') if (single_wildcard_char and type(single_wildcard_char) == type(u'') and len(single_wildcard_char) == 1): OPTION_DEFAULTS['singlewildcardchar'] = single_wildcard_char multi_wildcard_char = self.tabsqlitedb.ime_properties.get( 'multi_wildcard_char') if (multi_wildcard_char and type(multi_wildcard_char) == type(u'') and len(multi_wildcard_char) == 1): OPTION_DEFAULTS['multiwildcardchar'] = multi_wildcard_char
def main (): def debug_print ( message ): if opts.debug: print message if not opts.only_index: try: os.unlink (opts.name) except: pass debug_print ("Processing Database") db = tabsqlitedb.tabsqlitedb ( filename = opts.name) #db.db.execute( 'PRAGMA synchronous = FULL; ' ) def parse_source (f): _attri = [] _table = [] _gouci = [] patt_com = re.compile(r'^###.*') patt_blank = re.compile(r'^[ \t]*$') patt_conf = re.compile(r'[^\t]*=[^\t]*') patt_table = re.compile(r'([^\t]+)\t([^\t]+)\t([^t]+)(\t.*)?$') patt_gouci = re.compile(r' *[^\s]+ *\t *[^\s]+ *$') patt_s = re.compile(r' *([^\s]+) *\t *([\x00-\xff]{3}) *\t *[^\s]+ *$') for l in f: if ( not patt_com.match(l) ) and ( not patt_blank.match(l) ): for _patt, _list in ( (patt_table,_table),(patt_gouci,_gouci),(patt_conf,_attri) ): if _patt.match(l): _list.append(l) break if not _gouci: #user didn't provide goucima, so we use the longest single character encode as the goucima. gouci_dict = {} for line in _table: res = patt_s.match(line) if res: if gouci_dict.has_key(res.group(2)): if len(res.group(1)) > len(gouci_dict[res.group(2)]): gouci_dict[res.group(2)] = res.group(1) else: gouci_dict[res.group(2)] = res.group(1) for key in gouci_dict: _gouci.append('%s\t%s' %(key,gouci_dict[key] ) ) _gouci.sort() return (_attri, _table, _gouci) def parse_pinyin (f): _pinyins = [] patt_com = re.compile(r'^#.*') patt_blank = re.compile(r'^[ \t]*$') patt_py = re.compile(r'(.*)\t(.*)\t(.*)') patt_yin = re.compile(r'[a-z]+[1-5]') for l in f: if ( not patt_com.match(l) ) and ( not patt_blank.match(l) ): res = patt_py.match(l) if res: yins = patt_yin.findall(res.group(2)) for yin in yins: _pinyins.append("%s\t%s\t%s" \ % (res.group(1), yin, res.group(3))) return _pinyins[:] def parse_extra (f): _extra = [] patt_com = re.compile(r'^###.*') patt_blank = re.compile(r'^[ \t]*$') patt_extra = re.compile(r'(.*)\t(.*)') patt_s = re.compile(r'(.*)\t([\x00-\xff]{3})\t.*') for l in f: if ( not patt_com.match(l) ) and ( not patt_blank.match(l) ): if patt_extra.match(l): _extra.append(l) return _extra def pinyin_parser (f): for py in f: _zi, _pinyin, _freq = unicode (py,'utf-8').strip ().split() yield (_pinyin, _zi, _freq) def phrase_parser (f): list=[] for l in f: xingma, phrase, freq = unicode (l, "utf-8").strip ().split ('\t')[:3] if phrase == 'NOSYMBOL': phrase = u'' list.append ( (xingma, phrase, int(freq), 0) ) return list def goucima_parser (f): for l in f: zi,gcm = unicode (l, "utf-8").strip ().split () yield (zi, gcm) def attribute_parser (f): for l in f: try: attr,val = unicode (l,"utf-8").strip().split ('=') except: attr,val = unicode (l,"utf-8").strip().split ('==') attr = attr.strip().lower() val = val.strip() if attr == 'name' and not gconf_valid_keyname(val): raise InvalidTableName(val) yield (attr,val) def extra_parser (f): list = [] for l in f: phrase, freq = unicode (l, "utf-8").strip ().split () try: _tabkey = db.parse_phrase_to_tabkeys(phrase) list.append( (_tabkey,phrase,freq,0) ) except: print '\"%s\" would not been added' % phrase.encode('utf-8') return list if opts.only_index: debug_print ('Only create Indexes') debug_print ( "Optimizing database " ) db.optimize_database () debug_print ('Create Indexes ') db.create_indexes ('main') debug_print ('Done! :D') return 0 # now we parse the ime source file debug_print ("\tLoad sources \"%s\"" % opts.source) patt_s = re.compile( r'.*\.bz2' ) _bz2s = patt_s.match(opts.source) if _bz2s: source = bz2.BZ2File ( opts.source, "r" ) else: source = file ( opts.source, 'r' ) # first get config line and table line and goucima line respectively debug_print ('\tParsing table source file ') attri,table,gouci = parse_source ( source ) debug_print ('\t get attribute of IME :)') attributes = attribute_parser ( attri ) debug_print ('\t add attributes into DB ') db.update_ime ( attributes ) db.create_tables ('main') # second, we use generators for database generating: debug_print ('\t get phrases of IME :)') phrases = phrase_parser ( table) # now we add things into db debug_print ('\t add phrases into DB ') db.add_phrases ( phrases ) if db.get_ime_property ('user_can_define_phrase').lower() == u'true': debug_print ('\t get goucima of IME :)') goucima = goucima_parser (gouci) debug_print ('\t add goucima into DB ') db.add_goucima ( goucima ) if db.get_ime_property ('pinyin_mode').lower() == u'true': debug_print ('\tLoad pinyin source \"%s\"' % opts.pinyin) _bz2p = patt_s.match(opts.pinyin) if _bz2p: pinyin_s = bz2.BZ2File ( opts.pinyin, "r" ) else: pinyin_s = file ( opts.pinyin, 'r' ) debug_print ('\tParsing pinyin source file ') pyline = parse_pinyin (pinyin_s) debug_print ('\tPreapring pinyin entries') pinyin = pinyin_parser (pyline) debug_print ('\t add pinyin into DB ') db.add_pinyin ( pinyin ) debug_print ("Optimizing database ") db.optimize_database () if db.get_ime_property ('user_can_define_phrase').lower() == u'true' and opts.extra: debug_print( '\tPreparing for adding extra words' ) db.create_indexes ('main') debug_print ('\tLoad extra words source \"%s\"' % opts.extra) _bz2p = patt_s.match(opts.extra) if _bz2p: extra_s = bz2.BZ2File ( opts.extra, "r" ) else: extra_s = file ( opts.extra, 'r' ) debug_print ('\tParsing extra words source file ') extraline = parse_extra (extra_s) debug_print ('\tPreparing extra words lines') db.cache_goucima() debug_print ('\t Goucima has been cache to memory') extrawds = extra_parser (extraline) debug_print( '\t we have %d extra phrases from source' % len(extrawds)) # first get the entry of original phrases from # phrases-[(xingma, phrase, int(freq), 0)] orig_phrases = {} map (lambda x: orig_phrases.update({"%s\t%s"%(x[0],x[1]):x}), phrases ) debug_print( '\t the len of orig_phrases is: %d' % len(orig_phrases) ) extra_phrases = {} map (lambda x: extra_phrases.update({"%s\t%s" %(x[0],x[1]):x}), extrawds ) debug_print ( '\t the len of extra_phrases is: %d' % len(extra_phrases) ) # pop duplicated keys map (lambda x: extra_phrases.pop(x) if orig_phrases.has_key(x) else 0, extra_phrases.keys() ) debug_print( '\t %d extra phrases will be added' % len(extra_phrases)) new_phrases = extra_phrases.values() debug_print ('\tAdding extra words into DB ') db.add_phrases (new_phrases) debug_print ("Optimizing database ") db.optimize_database () if opts.index: debug_print ('Create Indexes ') db.create_indexes ('main') else: debug_print ("We don't create index on database, you should only active this function only for distribution purpose") db.drop_indexes ('main') debug_print ('Done! :D')
def get_default_options_from_database(self): self.tabsqlitedb = tabsqlitedb.tabsqlitedb(filename=os.path.join( db_dir, re.sub(r'^table:', '', self.__engine_name) + '.db'), user_db=None, create_database=False) self.__is_chinese = False self.__is_cjk = False languages = self.tabsqlitedb.ime_properties.get('languages') if languages: languages = languages.split(',') for language in languages: if language.strip().startswith('zh'): self.__is_chinese = True for lang in ['zh', 'ja', 'ko']: if language.strip().startswith(lang): self.__is_cjk = True self.__user_can_define_phrase = False user_can_define_phrase = self.tabsqlitedb.ime_properties.get( 'user_can-define_phrase') if user_can_define_phrase: self.__user_can_define_phrase = ( user_can_define_phrase.lower() == u'true') self.__rules = self.tabsqlitedb.ime_properties.get('rules') language_filter = self.tabsqlitedb.ime_properties.get( 'language_filter') if language_filter in ['cm0', 'cm1', 'cm2', 'cm3', 'cm4']: OPTION_DEFAULTS['chinesemode'] = int(language_filter[-1]) def_full_width_punct = self.tabsqlitedb.ime_properties.get( 'def_full_width_punct') if (def_full_width_punct and type(def_full_width_punct) == type(u'') and def_full_width_punct.lower() in [u'true', u'false']): OPTION_DEFAULTS['tabdeffullwidthpunct'] = ( def_full_width_punct.lower() == u'true') OPTION_DEFAULTS['endeffullwidthpunct'] = ( def_full_width_punct.lower() == u'true') def_full_width_letter = self.tabsqlitedb.ime_properties.get( 'def_full_width_letter') if (def_full_width_letter and type(def_full_width_letter) == type(u'') and def_full_width_letter.lower() in [u'true', u'false']): OPTION_DEFAULTS['tabdeffullwidthletter'] = ( def_full_width_letter.lower() == u'true') OPTION_DEFAULTS['endeffullwidthletter'] = ( def_full_width_letter.lower() == u'true') always_show_lookup = self.tabsqlitedb.ime_properties.get( 'always_show_lookup') if (always_show_lookup and type(always_show_lookup) == type(u'') and always_show_lookup.lower() in [u'true', u'false']): OPTION_DEFAULTS['alwaysshowlookup'] = ( always_show_lookup.lower() == u'true') select_keys_csv = self.tabsqlitedb.ime_properties.get('select_keys') if select_keys_csv: # select_keys_csv is something like: "1,2,3,4,5,6,7,8,9,0" OPTION_DEFAULTS['lookuptablepagesize'] = len( select_keys_csv.split(",")) auto_select = self.tabsqlitedb.ime_properties.get('auto_select') if (auto_select and type(auto_select) == type(u'') and auto_select.lower() in [u'true', u'false']): OPTION_DEFAULTS['autoselect'] = auto_select.lower() == u'true' auto_commit = self.tabsqlitedb.ime_properties.get('auto_commit') if (auto_commit and type(auto_commit) == type(u'') and auto_commit.lower() in [u'true', u'false']): OPTION_DEFAULTS['autocommit'] = auto_commit.lower() == u'true' orientation = self.tabsqlitedb.ime_properties.get('orientation') if (orientation and type(orientation) == type(u'') and orientation.lower() in [u'true', u'false']): OPTION_DEFAULTS['lookuptableorientation'] = ( orientation.lower() == u'true') # if space is a page down key, set the option # “spacekeybehavior” to “True”: page_down_keys_csv = self.tabsqlitedb.ime_properties.get( 'page_down_keys') if page_down_keys_csv: self._page_down_keys = [ IBus.keyval_from_name(x) for x in page_down_keys_csv.split(',') ] if IBus.KEY_space in self._page_down_keys: OPTION_DEFAULTS['spacekeybehavior'] = True # if space is a commit key, set the option # “spacekeybehavior” to “False” (overrides if space is # also a page down key): commit_keys_csv = self.tabsqlitedb.ime_properties.get('commit_keys') if commit_keys_csv: self._commit_keys = [ IBus.keyval_from_name(x) for x in commit_keys_csv.split(',') ] if IBus.KEY_space in self._commit_keys: OPTION_DEFAULTS['spacekeybehavior'] = False auto_wildcard = self.tabsqlitedb.ime_properties.get('auto_wildcard') if (auto_wildcard and type(auto_wildcard) == type(u'') and auto_wildcard.lower() in [u'true', u'false']): OPTION_DEFAULTS['autowildcard'] = auto_wildcard.lower() == u'true' single_wildcard_char = self.tabsqlitedb.ime_properties.get( 'single_wildcard_char') if (single_wildcard_char and type(single_wildcard_char) == type(u'') and len(single_wildcard_char) == 1): OPTION_DEFAULTS['singlewildcardchar'] = single_wildcard_char multi_wildcard_char = self.tabsqlitedb.ime_properties.get( 'multi_wildcard_char') if (multi_wildcard_char and type(multi_wildcard_char) == type(u'') and len(multi_wildcard_char) == 1): OPTION_DEFAULTS['multiwildcardchar'] = multi_wildcard_char
def main (): def debug_print ( message ): if opts.debug: print(message) if not opts.only_index: try: os.unlink (opts.name) except: pass debug_print ("Processing Database") db = tabsqlitedb.tabsqlitedb(filename = opts.name, user_db = None, create_database = True) def parse_source (f): _attri = [] _table = [] _gouci = [] patt_com = re.compile(r'^###.*') patt_blank = re.compile(r'^[ \t]*$') patt_conf = re.compile(r'[^\t]*=[^\t]*') patt_table = re.compile(r'([^\t]+)\t([^\t]+)\t([0-9]+)(\t.*)?$') patt_gouci = re.compile(r' *[^\s]+ *\t *[^\s]+ *$') for l in f: if (not patt_com.match(l)) and (not patt_blank.match(l)): for _patt, _list in ( (patt_table, _table), (patt_gouci, _gouci), (patt_conf, _attri)): if _patt.match(l): _list.append(l) break if not _gouci: # The user didn’t provide goucima (goucima = 構詞碼 = # “word formation keys”) in the table source, so we use # the longest encoding for a single character as the # goucima for that character. # # Example: # # wubi-jidian86.txt contains: # # a 工 99454797 # aaa 工 551000000 # aaaa 工 551000000 # aaad 工期 5350000 # ... and more matches for compounds containing 工 # # The longest key sequence to type 工 as a single # character is “aaaa”. Therefore, the goucima of 工 is # “aaaa” (There is one other character with the same goucima # in wubi-jidian86.txt, 㠭 also has the goucima “aaaa”). gouci_dict = {} for line in _table: res = patt_table.match(line) if res and len(res.group(2)) == 1: if res.group(2) in gouci_dict: if len(res.group(1)) > len(gouci_dict[res.group(2)]): gouci_dict[res.group(2)] = res.group(1) else: gouci_dict[res.group(2)] = res.group(1) for key in gouci_dict: _gouci.append('%s\t%s' %(key, gouci_dict[key])) _gouci.sort() return (_attri, _table, _gouci) def parse_pinyin (f): _pinyins = [] patt_com = re.compile(r'^#.*') patt_blank = re.compile(r'^[ \t]*$') patt_py = re.compile(r'(.*)\t(.*)\t(.*)') patt_yin = re.compile(r'[a-z]+[1-5]') for l in f: if type(l) != type(u''): l = l.decode('utf-8') if ( not patt_com.match(l) ) and ( not patt_blank.match(l) ): res = patt_py.match(l) if res: yins = patt_yin.findall(res.group(2)) for yin in yins: _pinyins.append("%s\t%s\t%s" \ % (res.group(1), yin, res.group(3))) return _pinyins[:] def parse_extra (f): _extra = [] patt_com = re.compile(r'^###.*') patt_blank = re.compile(r'^[ \t]*$') patt_extra = re.compile(r'(.*)\t(.*)') for l in f: if ( not patt_com.match(l) ) and ( not patt_blank.match(l) ): if patt_extra.match(l): _extra.append(l) return _extra def pinyin_parser (f): for py in f: if type(py) != type(u''): py = py.decode('utf-8') _zi, _pinyin, _freq = py.strip().split() yield (_pinyin, _zi, _freq) def phrase_parser (f): phrase_list = [] for l in f: if type(l) != type(u''): l = l.decode('utf-8') xingma, phrase, freq = l.split('\t')[:3] if phrase == 'NOSYMBOL': phrase = u'' phrase_list.append((xingma, phrase, int(freq), 0)) return phrase_list def goucima_parser (f): for l in f: if type(l) != type(u''): l = l.decode('utf-8') zi, gcm = l.strip().split() yield (zi, gcm) def attribute_parser (f): for l in f: if type(l) != type(u''): l = l.decode('utf-8') try: attr, val = l.strip().split('=') except: attr, val = l.strip().split('==') attr = attr.strip().lower() val = val.strip() yield (attr, val) def extra_parser (f): extra_list = [] for l in f: if type(l) != type(u''): l = l.decode('utf-8') phrase, freq = l.strip().split () _tabkey = db.parse_phrase(phrase) if _tabkey: extra_list.append((_tabkey, phrase, freq, 0)) else: print('No tabkeys found for “%s”, not adding.\n' %phrase) return extra_list def get_char_prompts(f): ''' Returns something like ("char_prompts", "{'a': '日', 'b': '日', 'c': '金', ...}") i.e. the attribute name "char_prompts" and as its value the string representation of a Python dictionary. ''' char_prompts = {} start = False for l in f: if type(l) != type(u''): l = l.decode('utf-8') if re.match(r'^BEGIN_CHAR_PROMPTS_DEFINITION', l): start = True continue if not start: continue if re.match(r'^END_CHAR_PROMPTS_DEFINITION', l): break match = re.search(r'^(?P<char>[^\s]+)[\s]+(?P<prompt>[^\s]+)', l) if match: char_prompts[match.group('char')] = match.group('prompt') return ("char_prompts", repr(char_prompts)) if opts.only_index: debug_print ('Only create Indexes') debug_print ( "Optimizing database " ) db.optimize_database () debug_print ('Create Indexes ') db.create_indexes ('main') debug_print ('Done! :D') return 0 # now we parse the ime source file debug_print ("\tLoad sources \"%s\"" % opts.source) patt_s = re.compile( r'.*\.bz2' ) _bz2s = patt_s.match(opts.source) if _bz2s: source = bz2.BZ2File(opts.source, "r").read() else: source = open(opts.source, mode='r', encoding='UTF-8').read() source = source.replace('\r\n', '\n') source = source.split('\n') # first get config line and table line and goucima line respectively debug_print ('\tParsing table source file ') attri, table, gouci = parse_source(source) debug_print('\t get attribute of IME :)') attributes = list(attribute_parser(attri)) attributes.append(get_char_prompts(source)) debug_print('\t add attributes into DB ') db.update_ime( attributes ) db.create_tables('main') # second, we use generators for database generating: debug_print ('\t get phrases of IME :)') phrases = phrase_parser ( table) # now we add things into db debug_print('\t add phrases into DB ') db.add_phrases(phrases) if db.ime_properties.get('user_can_define_phrase').lower() == u'true': debug_print ('\t get goucima of IME :)') goucima = goucima_parser (gouci) debug_print ('\t add goucima into DB ') db.add_goucima ( goucima ) if db.ime_properties.get('pinyin_mode').lower() == u'true': debug_print ('\tLoad pinyin source \"%s\"' % opts.pinyin) _bz2p = patt_s.match(opts.pinyin) if _bz2p: pinyin_s = bz2.BZ2File ( opts.pinyin, "r" ) else: pinyin_s = file ( opts.pinyin, 'r' ) debug_print ('\tParsing pinyin source file ') pyline = parse_pinyin (pinyin_s) debug_print ('\tPreapring pinyin entries') pinyin = pinyin_parser (pyline) debug_print ('\t add pinyin into DB ') db.add_pinyin ( pinyin ) debug_print ("Optimizing database ") db.optimize_database () if (db.ime_properties.get('user_can_define_phrase').lower() == u'true' and opts.extra): debug_print( '\tPreparing for adding extra words' ) db.create_indexes ('main') debug_print ('\tLoad extra words source \"%s\"' % opts.extra) _bz2p = patt_s.match(opts.extra) if _bz2p: extra_s = bz2.BZ2File ( opts.extra, "r" ) else: extra_s = file ( opts.extra, 'r' ) debug_print ('\tParsing extra words source file ') extraline = parse_extra (extra_s) debug_print ('\tPreparing extra words lines') extrawds = extra_parser (extraline) debug_print( '\t we have %d extra phrases from source' % len(extrawds)) # first get the entry of original phrases from # phrases-[(xingma, phrase, int(freq), 0)] orig_phrases = {} for x in phrases: orig_phrases.update({"%s\t%s" % (x[0], x[1]):x}) debug_print('\t the len of orig_phrases is: %d' % len(orig_phrases)) extra_phrases = {} for x in extrawds: extra_phrases.update({"%s\t%s" % (x[0], x[1]):x}) debug_print('\t the len of extra_phrases is: %d' % len(extra_phrases)) # pop duplicated keys for x in extra_phrases: if x in orig_phrases: extra_phrases.pop(x) debug_print('\t %d extra phrases will be added' % len(extra_phrases)) new_phrases = list(extra_phrases.values()) debug_print('\tAdding extra words into DB ') db.add_phrases (new_phrases) debug_print('Optimizing database ') db.optimize_database () if opts.index: debug_print ('Create Indexes ') db.create_indexes ('main') else: debug_print( "We don't create an index on the database, " + "you should only activate this function " + "for distribution purposes.") db.drop_indexes ('main') debug_print ('Done! :D')
def main(): def debug_print(message): if opts.debug: print message if not opts.only_index: try: os.unlink(opts.name) except: pass debug_print("Processing Database") db = tabsqlitedb.tabsqlitedb(filename=opts.name) #db.db.execute( 'PRAGMA synchronous = FULL; ' ) def parse_source(f): _attri = [] _table = [] _gouci = [] patt_com = re.compile(r'^###.*') patt_blank = re.compile(r'^[ \t]*$') patt_conf = re.compile(r'.*=.*') patt_table = re.compile(r'(.*)\t(.*)\t.*') patt_gouci = re.compile(r'.*\t.*') patt_s = re.compile(r'(.*)\t([\x00-\xff]{3})\t.*') for l in f: if (not patt_com.match(l)) and (not patt_blank.match(l)): for _patt, _list in ((patt_table, _table), (patt_gouci, _gouci), (patt_conf, _attri)): if _patt.match(l): _list.append(l) break if not _gouci: #user didn't provide goucima, so we use the longest single character encode as the goucima. gouci_dict = {} for line in _table: res = patt_s.match(line) if res: if gouci_dict.has_key(res.group(2)): if len(res.group(1)) > len(gouci_dict[res.group(2)]): gouci_dict[res.group(2)] = res.group(1) else: gouci_dict[res.group(2)] = res.group(1) for key in gouci_dict: _gouci.append('%s\t%s' % (key, gouci_dict[key])) _gouci.sort() return (_attri, _table, _gouci) def parse_extra(f): _extra = [] patt_com = re.compile(r'^###.*') patt_blank = re.compile(r'^[ \t]*$') patt_extra = re.compile(r'(.*)\t(.*)') patt_s = re.compile(r'(.*)\t([\x00-\xff]{3})\t.*') for l in f: if (not patt_com.match(l)) and (not patt_blank.match(l)): if patt_extra.match(l): _extra.append(l) return _extra def phrase_parser(f): list = [] for l in f: xingma, phrase, freq = unicode(l, "utf-8").strip().split('\t')[:3] list.append((xingma, phrase, int(freq), 0)) return list def goucima_parser(f): for l in f: zi, gcm = unicode(l, "utf-8").strip().split() yield (zi, gcm) def attribute_parser(f): for l in f: try: if len(unicode(l, "utf-8").strip().split('=')) == 3: attr, val, dum = unicode(l, "utf-8").strip().split('=') val = ''.join([val, "=", dum]) else: attr, val = unicode(l, "utf-8").strip().split('=') except: attr, val = unicode(l, "utf-8").strip().split('==') attr = attr.strip() origin_attr = attr attr = attr.lower() val = val.strip() yield (attr, val) def extra_parser(f): list = [] for l in f: phrase, freq = unicode(l, "utf-8").strip().split() try: _tabkey = db.parse_phrase_to_tabkeys(phrase) list.append((_tabkey, phrase, freq, 0)) except: print '\"%s\" would not been added' % phrase.encode('utf-8') return list if opts.only_index: debug_print('Only create Indexes') debug_print("Optimizing database ") db.optimize_database() debug_print('Create Indexes ') db.create_indexes('main') debug_print('Done! :D') return 0 # now we parse the ime source file debug_print("\tLoad sources \"%s\"" % opts.source) patt_s = re.compile(r'.*\.bz2') _bz2s = patt_s.match(opts.source) if _bz2s: source = bz2.BZ2File(opts.source, "r") else: source = file(opts.source, 'r') # first get config line and table line and goucima line respectively debug_print('\tParsing table source file ') attri, table, gouci = parse_source(source) debug_print('\t get attribute of IME :)') attributes = attribute_parser(attri) debug_print('\t add attributes into DB ') db.update_ime(attributes) db.create_tables('main') # second, we use generators for database generating: debug_print('\t get phrases of IME :)') phrases = phrase_parser(table) # now we add things into db debug_print('\t add phrases into DB ') db.add_phrases(phrases) if db.get_ime_property('user_can_define_phrase').lower() == u'true': debug_print('\t get goucima of IME :)') goucima = goucima_parser(gouci) debug_print('\t add goucima into DB ') db.add_goucima(goucima) debug_print("Optimizing database ") db.optimize_database() if db.get_ime_property( 'user_can_define_phrase').lower() == u'true' and opts.extra: debug_print('\tPreparing for adding extra words') db.create_indexes('main') debug_print('\tLoad extra words source \"%s\"' % opts.extra) _bz2p = patt_s.match(opts.extra) if _bz2p: extra_s = bz2.BZ2File(opts.extra, "r") else: extra_s = file(opts.extra, 'r') debug_print('\tParsing extra words source file ') extraline = parse_extra(extra_s) debug_print('\tPreparing extra words lines') db.cache_goucima() debug_print('\t Goucima has been cache to memory') extrawds = extra_parser(extraline) debug_print('\t we have %d extra phrases from source' % len(extrawds)) # first get the entry of original phrases from # phrases-[(xingma, phrase, int(freq), 0)] orig_phrases = {} map(lambda x: orig_phrases.update({"%s\t%s" % (x[0], x[1]): x}), phrases) debug_print('\t the len of orig_phrases is: %d' % len(orig_phrases)) extra_phrases = {} map(lambda x: extra_phrases.update({"%s\t%s" % (x[0], x[1]): x}), extrawds) debug_print('\t the len of extra_phrases is: %d' % len(extra_phrases)) # pop duplicated keys map(lambda x: extra_phrases.pop(x) if orig_phrases.has_key(x) else 0, extra_phrases.keys()) debug_print('\t %d extra phrases will be added' % len(extra_phrases)) new_phrases = extra_phrases.values() debug_print('\tAdding extra words into DB ') db.add_phrases(new_phrases) debug_print("Optimizing database ") db.optimize_database() if opts.index: debug_print('Create Indexes ') db.create_indexes('main') else: debug_print( "We don't create index on database, you should only active this function only for distribution purpose" ) db.drop_indexes('main') debug_print('Done! :D')
def __init__(self, bus): filename = path.join(path.dirname(__file__), "setup.glade") self.builder = Gtk.Builder() self.builder.set_translation_domain(DOMAINNAME) self.builder.add_from_file(filename) event_handler = EventHandler() self.builder.connect_signals(event_handler) if not self.check_instance(): service = SetupService() # Try to figure out the config file name: self.config_file = None if _ARGS.config_file: # If the config file is specified on the command line, use that: self.config_file = _ARGS.config_file else: # If the config file is not specified on the command line, # try to get it from the environment. This is necessary # in gnome-shell on Fedora 18 because the setup tool is # called without command line options there but the # environment variable IBUS_ENGINE_NAME is set: try: ibus_engine_name = os.environ['IBUS_ENGINE_NAME'] if ibus_engine_name.startswith('typing-booster:'): self.config_file = ( ibus_engine_name.replace('typing-booster:', '') + '.conf') else: self.__run_message_dialog( _('Unknown format of engine name: ' + 'IBUS_ENGINE_NAME=%(name)s') % {'name': ibus_engine_name}, Gtk.MessageType.WARNING) except: self.__run_message_dialog( _("IBUS_ENGINE_NAME environment variable is not set."), Gtk.MessageType.WARNING) if self.config_file == None: self.__run_message_dialog( _('Cannot determine the config file for this engine. ' + 'Please use the --config-file option.'), Gtk.MessageType.ERROR) sys.exit(1) return self.config_file_full_path = ( '/usr/share/ibus-typing-booster/hunspell-tables/' + self.config_file) if not os.path.isfile(self.config_file_full_path): self.__run_message_dialog( _("Config file %(file)s does not exist.") % {'file': self.config_file_full_path}, Gtk.MessageType.ERROR) sys.exit(1) return self.tabsqlitedb = tabsqlitedb.tabsqlitedb( config_filename=self.config_file_full_path) self.name = self.tabsqlitedb.ime_properties.get('name') self.config_section = "engine/typing-booster/%s" % self.name self.hunspell_dict_package = self.tabsqlitedb.ime_properties.get( 'hunspell_dict_package') self.symbol = self.tabsqlitedb.ime_properties.get('symbol') self.bus = bus self.config = self.bus.get_config() maindialog = self.builder.get_object("main_dialog") maindialog.set_title( _("Preferences for ibus-typing-booster \"%(symbol)s\"") % {'symbol': self.symbol}) maindialog.show() name_version = self.builder.get_object("name_version_label") name_version.set_markup( '<span font_size="large"><b>ibus-typing-booster %s</b></span>' % version.get_version()) self.install_dictionary_button = self.builder.get_object( "install_dictionary_button") self.install_dictionary_button.connect( 'clicked', event_handler.onInstallDictionaryClicked) self.learn_from_file_button = self.builder.get_object( "learn_from_file_button") self.learn_from_file_button.connect( 'clicked', event_handler.onLearnFromFileClicked) self.delete_learned_data_button = self.builder.get_object( "delete_learned_data_button") self.delete_learned_data_button.connect( 'clicked', event_handler.onDeleteLearnedDataClicked) close_button = self.builder.get_object("close_button") close_button.connect('clicked', event_handler.onCloseClicked) tab_enable_checkbox = self.builder.get_object("tab_enable_checkbox") self.tab_enable = self.variant_to_value( self.config.get_value(self.config_section, 'tabenable')) if self.tab_enable == None: self.tab_enable = False if self.tab_enable == True: tab_enable_checkbox.set_active(True) tab_enable_checkbox.connect('clicked', event_handler.onTabEnableCheckbox) show_number_of_candidates_checkbox = self.builder.get_object( "show_number_of_candidates_checkbox") self.show_number_of_candidates = self.variant_to_value( self.config.get_value(self.config_section, 'shownumberofcandidates')) if self.show_number_of_candidates == None: self.show_number_of_candidates = False if self.show_number_of_candidates == True: show_number_of_candidates_checkbox.set_active(True) show_number_of_candidates_checkbox.connect( 'clicked', event_handler.onShowNumberOfCandidatesCheckbox) use_digits_as_select_keys_checkbox = self.builder.get_object( "use_digits_as_select_keys_checkbox") self.use_digits_as_select_keys = self.variant_to_value( self.config.get_value(self.config_section, 'usedigitsasselectkeys')) if self.use_digits_as_select_keys == None: self.use_digits_as_select_keys = True if self.use_digits_as_select_keys == True: use_digits_as_select_keys_checkbox.set_active(True) use_digits_as_select_keys_checkbox.connect( 'clicked', event_handler.onUseDigitsAsSelectKeysCheckbox) emoji_predictions_checkbox = self.builder.get_object( "emoji_predictions_checkbox") self.emoji_predictions = self.variant_to_value( self.config.get_value(self.config_section, 'emojipredictions')) if self.emoji_predictions == None: self.emoji_predictions = True if self.emoji_predictions == True: emoji_predictions_checkbox.set_active(True) emoji_predictions_checkbox.connect( 'clicked', event_handler.onEmojiPredictionsCheckbox) off_the_record_checkbox = self.builder.get_object( "off_the_record_checkbox") self.off_the_record = self.variant_to_value( self.config.get_value(self.config_section, 'offtherecord')) if self.off_the_record == None: self.off_the_record = False if self.off_the_record == True: off_the_record_checkbox.set_active(True) off_the_record_checkbox.connect('clicked', event_handler.onOffTheRecordCheckbox) add_direct_input_checkbox = self.builder.get_object( "add_direct_input_checkbox") self.add_direct_input = self.variant_to_value( self.config.get_value(self.config_section, 'adddirectinput')) if self.add_direct_input == None: self.add_direct_input = False if self.add_direct_input == True: add_direct_input_checkbox.set_active(True) add_direct_input_checkbox.connect( 'clicked', event_handler.onAddDirectInputCheckbox) remember_last_used_preedit_ime_checkbox = self.builder.get_object( "remember_last_used_preedit_ime_checkbox") self.remember_last_used_predit_ime = self.variant_to_value( self.config.get_value(self.config_section, 'rememberlastusedpreeditime')) if self.remember_last_used_predit_ime == None: self.remember_last_used_predit_ime = False if self.remember_last_used_predit_ime == True: remember_last_used_preedit_ime_checkbox.set_active(True) remember_last_used_preedit_ime_checkbox.connect( 'clicked', event_handler.onRememberLastUsedPreeditImeCheckbox) auto_commit_characters_entry = self.builder.get_object( "auto_commit_characters_entry") self.auto_commit_characters = self.variant_to_value( self.config.get_value(self.config_section, 'autocommitcharacters')) if not self.auto_commit_characters: self.auto_commit_characters = '' auto_commit_characters_entry.set_text(self.auto_commit_characters) auto_commit_characters_entry.connect( 'notify::text', event_handler.onAutoCommitCharactersEntry) self.page_size_adjustment = self.builder.get_object( "page_size_adjustment") self.page_size = self.variant_to_value( self.config.get_value(self.config_section, 'pagesize')) if self.page_size: self.page_size_adjustment.set_value(int(self.page_size)) else: self.page_size_adjustment.set_value(6) self.page_size_adjustment.connect( 'value-changed', event_handler.onPageSizeAdjustmentValueChanged) self.min_char_complete_adjustment = self.builder.get_object( "min_char_complete_adjustment") self.min_char_complete = self.variant_to_value( self.config.get_value(self.config_section, 'mincharcomplete')) if self.min_char_complete: self.min_char_complete_adjustment.set_value( int(self.min_char_complete)) else: self.min_char_complete_adjustment.set_value(1) self.min_char_complete_adjustment.connect( 'value-changed', event_handler.onMinCharCompleteAdjustmentValueChanged) self.ime_combobox = self.builder.get_object("input_method_combobox") ime_label = self.builder.get_object("input_method_label") self.input_method_help_button = self.builder.get_object( "input_method_help_button") ime_store = Gtk.ListStore(str, str) self.supported_imes = [] imes = self.tabsqlitedb.ime_properties.get('imes').split(',') if not imes: imes = ['Native Keyboard:NoIme'] for item in imes: ime_store.append([item.split(':')[0], item.split(':')[1]]) self.supported_imes.append(item.split(':')[1]) self.ime_combobox.set_model(ime_store) renderer_text = Gtk.CellRendererText() self.ime_combobox.pack_start(renderer_text, True) self.ime_combobox.add_attribute(renderer_text, "text", 0) self.current_imes = [] inputmethod = self.variant_to_value( self.config.get_value(self.config_section, 'inputmethod')) if inputmethod: inputmethods = [x.strip() for x in inputmethod.split(',')] for ime in inputmethods: self.current_imes.append(ime) if self.current_imes == []: # There is no ime set in dconf, use the first value from # the combobox as the default: self.current_imes = [ime_store[0][1]] if self.add_direct_input and 'NoIme' not in self.current_imes: self.current_imes.append('NoIme') if len(self.current_imes) == 1: self.main_ime = self.current_imes[0] else: self.main_ime = ([ x for x in self.current_imes if x in self.supported_imes ][0]) combobox_has_ime = False for i in range(len(ime_store)): if ime_store[i][1] == self.main_ime: self.ime_combobox.set_active(i) combobox_has_ime = True if combobox_has_ime == False: # the combobox did not have the ime from the settings # take the ime from the first row of # the combobox as the fallback: self.main_ime = ime_store[0][1] self.ime_combobox.set_active(0) self.ime_combobox.connect("changed", event_handler.onImeComboboxChanged) if len(ime_store) < 2: self.ime_combobox.set_sensitive(False) self.input_method_help_button.connect( 'clicked', event_handler.onInputMethodHelpButtonClicked) if self.main_ime == 'NoIme': self.input_method_help_button.set_sensitive(False)