Blame setup/main.py

Packit 3ff832
# vim:set et sts=4 sw=4:
Packit 3ff832
# -*- coding: utf-8 -*-
Packit 3ff832
#
Packit 3ff832
# ibus - The Input Bus
Packit 3ff832
#
Packit 3ff832
# Copyright (c) 2007-2016 Peng Huang <shawn.p.huang@gmail.com>
Packit 3ff832
# Copyright (c) 2010-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
Packit 3ff832
# Copyright (c) 2007-2016 Red Hat, Inc.
Packit 3ff832
#
Packit 3ff832
# This library is free software; you can redistribute it and/or
Packit 3ff832
# modify it under the terms of the GNU Lesser General Public
Packit 3ff832
# License as published by the Free Software Foundation; either
Packit 3ff832
# version 2.1 of the License, or (at your option) any later version.
Packit 3ff832
#
Packit 3ff832
# This library is distributed in the hope that it will be useful,
Packit 3ff832
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 3ff832
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 3ff832
# Lesser General Public License for more details.
Packit 3ff832
#
Packit 3ff832
# You should have received a copy of the GNU Lesser General Public
Packit 3ff832
# License along with this library; if not, write to the Free Software
Packit 3ff832
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit 3ff832
# USA
Packit 3ff832
Packit 3ff832
# for python2
Packit 3ff832
from __future__ import print_function
Packit 3ff832
Packit 3ff832
import os
Packit 3ff832
import signal
Packit 3ff832
import sys
Packit 3ff832
import time
Packit 3ff832
Packit 3ff832
from gi import require_version as gi_require_version
Packit 3ff832
gi_require_version('GLib', '2.0')
Packit 3ff832
gi_require_version('GdkX11', '3.0')
Packit 3ff832
gi_require_version('Gio', '2.0')
Packit 3ff832
gi_require_version('Gtk', '3.0')
Packit 3ff832
gi_require_version('IBus', '1.0')
Packit 3ff832
Packit 3ff832
from gi.repository import GLib
Packit 3ff832
# set_prgname before importing other modules to show the name in warning
Packit 3ff832
# messages when import modules are failed.
Packit 3ff832
GLib.set_prgname('ibus-setup')
Packit 3ff832
Packit 3ff832
from gi.repository import GdkX11
Packit 3ff832
from gi.repository import Gio
Packit 3ff832
from gi.repository import Gtk
Packit 3ff832
from gi.repository import IBus
Packit 3ff832
from os import path
Packit 3ff832
Packit 3ff832
import i18n
Packit 3ff832
import keyboardshortcut
Packit 3ff832
import locale
Packit 3ff832
from emojilang import EmojiLangButton
Packit 3ff832
from enginecombobox import EngineComboBox
Packit 3ff832
from enginedialog import EngineDialog
Packit 3ff832
from enginetreeview import EngineTreeView
Packit 3ff832
from engineabout import EngineAbout
Packit 3ff832
from i18n import DOMAINNAME, _, N_
Packit 3ff832
Packit 3ff832
(
Packit 3ff832
    COLUMN_NAME,
Packit 3ff832
    COLUMN_ENABLE,
Packit 3ff832
    COLUMN_PRELOAD,
Packit 3ff832
    COLUMN_VISIBLE,
Packit 3ff832
    COLUMN_ICON,
Packit 3ff832
    COLUMN_DATA,
Packit 3ff832
) = list(range(6))
Packit 3ff832
Packit 3ff832
(
Packit 3ff832
    DATA_NAME,
Packit 3ff832
    DATA_LOCAL_NAME,
Packit 3ff832
    DATA_LANG,
Packit 3ff832
    DATA_ICON,
Packit 3ff832
    DATA_AUTHOR,
Packit 3ff832
    DATA_CREDITS,
Packit 3ff832
    DATA_EXEC,
Packit 3ff832
    DATA_STARTED,
Packit 3ff832
    DATA_PRELOAD
Packit 3ff832
) = list(range(9))
Packit 3ff832
Packit 3ff832
class Setup(object):
Packit 3ff832
    def __flush_gtk_events(self):
Packit 3ff832
        while Gtk.events_pending():
Packit 3ff832
            Gtk.main_iteration()
Packit 3ff832
Packit 3ff832
    def __init__(self):
Packit 3ff832
        super(Setup, self).__init__()
Packit 3ff832
Packit 3ff832
        self.__settings_general = Gio.Settings(
Packit 3ff832
                schema = "org.freedesktop.ibus.general");
Packit 3ff832
        self.__settings_hotkey = Gio.Settings(
Packit 3ff832
                schema = "org.freedesktop.ibus.general.hotkey");
Packit 3ff832
        self.__settings_panel = Gio.Settings(
Packit 3ff832
                schema = "org.freedesktop.ibus.panel");
Packit 3ff832
        self.__settings_emoji = Gio.Settings(
Packit 3ff832
                schema = "org.freedesktop.ibus.panel.emoji");
Packit 3ff832
Packit 3ff832
        # IBus.Bus() calls ibus_bus_new().
Packit 3ff832
        # Gtk.Builder().add_from_file() also calls ibus_bus_new_async()
Packit 3ff832
        # via ibus_im_context_new().
Packit 3ff832
        # Then if IBus.Bus() is called after Gtk.Builder().add_from_file(),
Packit 3ff832
        # the connection delay would be happened without an async
Packit 3ff832
        # finish function.
Packit 3ff832
        self.__bus = None
Packit 3ff832
        self.__init_bus()
Packit 3ff832
Packit 3ff832
        # Gtk.ListBox has been available since gtk 3.10
Packit 3ff832
        self.__has_list_box = hasattr(Gtk, 'ListBox')
Packit 3ff832
Packit 3ff832
        gtk_builder_file = path.join(path.dirname(__file__), "./setup.ui")
Packit 3ff832
        self.__builder = Gtk.Builder()
Packit 3ff832
        self.__builder.set_translation_domain(DOMAINNAME)
Packit 3ff832
        self.__builder.add_from_file(gtk_builder_file);
Packit 3ff832
        self.__init_ui()
Packit 3ff832
Packit 3ff832
    def __init_hotkeys(self):
Packit 3ff832
        name = 'triggers'
Packit 3ff832
        label = 'switch_engine'
Packit 3ff832
        comment = \
Packit 3ff832
            _("Use shortcut with shift to switch to the previous input method") 
Packit 3ff832
        self.__init_hotkey(name, label, comment)
Packit 3ff832
        name = 'emoji'
Packit 3ff832
        label = 'emoji_dialog'
Packit 3ff832
        self.__init_hotkey(name, label)
Packit 3ff832
        name = 'unicode'
Packit 3ff832
        label = 'unicode_dialog'
Packit 3ff832
        self.__init_hotkey(name, label)
Packit 3ff832
Packit 3ff832
    def __init_hotkey(self, name, label, comment=None):
Packit 3ff832
        if name == 'emoji':
Packit 3ff832
            shortcuts = self.__settings_emoji.get_strv('hotkey')
Packit 3ff832
        elif name == 'unicode':
Packit 3ff832
            shortcuts = self.__settings_emoji.get_strv('unicode-hotkey')
Packit 3ff832
        else:
Packit 3ff832
            shortcuts = self.__settings_hotkey.get_strv(name)
Packit 3ff832
        button = self.__builder.get_object("button_%s" % label)
Packit 3ff832
        entry = self.__builder.get_object("entry_%s" % label)
Packit 3ff832
        entry.set_text("; ".join(shortcuts))
Packit 3ff832
        tooltip = "\n".join(shortcuts)
Packit 3ff832
        if comment != None:
Packit 3ff832
            tooltip += "\n" + comment
Packit 3ff832
        entry.set_tooltip_text(tooltip)
Packit 3ff832
        if name == 'emoji':
Packit 3ff832
            button.connect("clicked", self.__shortcut_button_clicked_cb,
Packit 3ff832
                    'hotkey', 'panel/' + name, label, entry)
Packit 3ff832
        elif name == 'unicode':
Packit 3ff832
            button.connect("clicked", self.__shortcut_button_clicked_cb,
Packit 3ff832
                    'unicode-hotkey', 'panel/emoji', label, entry)
Packit 3ff832
        else:
Packit 3ff832
            button.connect("clicked", self.__shortcut_button_clicked_cb,
Packit 3ff832
                    name, "general/hotkey", label, entry)
Packit 3ff832
Packit 3ff832
    def __init_panel(self):
Packit 3ff832
        # lookup table orientation
Packit 3ff832
        self.__combobox_lookup_table_orientation = self.__builder.get_object(
Packit 3ff832
                "combobox_lookup_table_orientation")
Packit 3ff832
        self.__settings_panel.bind('lookup-table-orientation',
Packit 3ff832
                                   self.__combobox_lookup_table_orientation,
Packit 3ff832
                                   'active',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        # auto hide
Packit 3ff832
        self.__combobox_panel_show = self.__builder.get_object(
Packit 3ff832
                "combobox_panel_show")
Packit 3ff832
        self.__settings_panel.bind('show',
Packit 3ff832
                                   self.__combobox_panel_show,
Packit 3ff832
                                   'active',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        # panel position
Packit 3ff832
        self.__combobox_panel_position = self.__builder.get_object(
Packit 3ff832
                "combobox_panel_position")
Packit 3ff832
        self.__combobox_panel_position.set_active(3)
Packit 3ff832
        #self.__settings_panel.bind('position',
Packit 3ff832
        #                           self.__combobox_panel_position,
Packit 3ff832
        #                           'active',
Packit 3ff832
        #                           Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        # custom font
Packit 3ff832
        self.__checkbutton_custom_font = self.__builder.get_object(
Packit 3ff832
                "checkbutton_custom_font")
Packit 3ff832
        self.__settings_panel.bind('use-custom-font',
Packit 3ff832
                                   self.__checkbutton_custom_font,
Packit 3ff832
                                   'active',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        self.__fontbutton_custom_font = self.__builder.get_object(
Packit 3ff832
                "fontbutton_custom_font")
Packit 3ff832
        self.__settings_panel.bind('custom-font',
Packit 3ff832
                                    self.__fontbutton_custom_font,
Packit 3ff832
                                   'font-name',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
        self.__settings_panel.bind('use-custom-font',
Packit 3ff832
                                    self.__fontbutton_custom_font,
Packit 3ff832
                                   'sensitive',
Packit 3ff832
                                   Gio.SettingsBindFlags.GET)
Packit 3ff832
Packit 3ff832
        # show icon on system tray
Packit 3ff832
        self.__checkbutton_show_icon_on_systray = self.__builder.get_object(
Packit 3ff832
                "checkbutton_show_icon_on_systray")
Packit 3ff832
        self.__settings_panel.bind('show-icon-on-systray',
Packit 3ff832
                                   self.__checkbutton_show_icon_on_systray,
Packit 3ff832
                                   'active',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        # show ime name
Packit 3ff832
        self.__checkbutton_show_im_name = self.__builder.get_object(
Packit 3ff832
                "checkbutton_show_im_name")
Packit 3ff832
        self.__settings_panel.bind('show-im-name',
Packit 3ff832
                                   self.__checkbutton_show_im_name,
Packit 3ff832
                                   'active',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
    def __init_general(self):
Packit 3ff832
        # embed preedit text
Packit 3ff832
        self.__checkbutton_embed_preedit_text = self.__builder.get_object(
Packit 3ff832
                "checkbutton_embed_preedit_text")
Packit 3ff832
        self.__settings_general.bind('embed-preedit-text',
Packit 3ff832
                                    self.__checkbutton_embed_preedit_text,
Packit 3ff832
                                    'active',
Packit 3ff832
                                    Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        # use system keyboard layout setting
Packit 3ff832
        self.__checkbutton_use_sys_layout = self.__builder.get_object(
Packit 3ff832
                "checkbutton_use_sys_layout")
Packit 3ff832
        self.__settings_general.bind('use-system-keyboard-layout',
Packit 3ff832
                                    self.__checkbutton_use_sys_layout,
Packit 3ff832
                                    'active',
Packit 3ff832
                                    Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        # use global ime setting
Packit 3ff832
        self.__checkbutton_use_global_engine = self.__builder.get_object(
Packit 3ff832
                "checkbutton_use_global_engine")
Packit 3ff832
        self.__settings_general.bind('use-global-engine',
Packit 3ff832
                                    self.__checkbutton_use_global_engine,
Packit 3ff832
                                    'active',
Packit 3ff832
                                    Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
Packit 3ff832
        # init engine page
Packit 3ff832
        self.__engines = self.__bus.list_engines()
Packit 3ff832
        self.__combobox = self.__builder.get_object("combobox_engines")
Packit 3ff832
        if self.__has_list_box:
Packit 3ff832
            self.__combobox.set_no_show_all(True)
Packit 3ff832
            self.__combobox.hide()
Packit 3ff832
        else:
Packit 3ff832
            self.__combobox.set_engines(self.__engines)
Packit 3ff832
Packit 3ff832
        tmp_dict = {}
Packit 3ff832
        for e in self.__engines:
Packit 3ff832
            tmp_dict[e.get_name()] = e
Packit 3ff832
        engine_names = self.__settings_general.get_strv('preload-engines')
Packit 3ff832
        engines = [tmp_dict[name] for name in engine_names if name in tmp_dict]
Packit 3ff832
Packit 3ff832
        self.__treeview = self.__builder.get_object("treeview_engines")
Packit 3ff832
        self.__treeview.set_engines(engines)
Packit 3ff832
Packit 3ff832
        button = self.__builder.get_object("button_engine_add")
Packit 3ff832
        if self.__has_list_box:
Packit 3ff832
            button.set_sensitive(True)
Packit 3ff832
            button.connect("clicked", self.__button_engine_add_cb)
Packit 3ff832
        else:
Packit 3ff832
            button.connect("clicked", self.__button_engine_add_cb_deprecate)
Packit 3ff832
        button = self.__builder.get_object("button_engine_remove")
Packit 3ff832
        button.connect("clicked", lambda *args:self.__treeview.remove_engine())
Packit 3ff832
        button = self.__builder.get_object("button_engine_up")
Packit 3ff832
        button.connect("clicked", lambda *args:self.__treeview.move_up_engine())
Packit 3ff832
Packit 3ff832
        button = self.__builder.get_object("button_engine_down")
Packit 3ff832
        button.connect("clicked",
Packit 3ff832
                lambda *args:self.__treeview.move_down_engine())
Packit 3ff832
Packit 3ff832
        button = self.__builder.get_object("button_engine_about")
Packit 3ff832
        button.connect("clicked", self.__button_engine_about_cb)
Packit 3ff832
Packit 3ff832
        self.__engine_setup_exec_list = {}
Packit 3ff832
        button = self.__builder.get_object("button_engine_preferences")
Packit 3ff832
        button.connect("clicked", self.__button_engine_preferences_cb)
Packit 3ff832
Packit 3ff832
        self.__combobox.connect("notify::active-engine",
Packit 3ff832
                self.__combobox_notify_active_engine_cb)
Packit 3ff832
        self.__treeview.connect("notify::active-engine", self.__treeview_notify_cb)
Packit 3ff832
        self.__treeview.connect("notify::engines", self.__treeview_notify_cb)
Packit 3ff832
Packit 3ff832
    def __init_emoji(self):
Packit 3ff832
        self.__fontbutton_emoji_font = self.__builder.get_object(
Packit 3ff832
                'fontbutton_emoji_font')
Packit 3ff832
        self.__fontbutton_emoji_font.set_preview_text('🙂🍎🚃💓📧⚽🐳');
Packit 3ff832
        self.__settings_emoji.bind('font',
Packit 3ff832
                                    self.__fontbutton_emoji_font,
Packit 3ff832
                                   'font-name',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
        self.__button_emoji_lang = self.__builder.get_object(
Packit 3ff832
                'button_emoji_lang')
Packit 3ff832
        self.__settings_emoji.bind('lang',
Packit 3ff832
                                    self.__button_emoji_lang,
Packit 3ff832
                                   'lang',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
        self.__checkbutton_emoji_partial_match = self.__builder.get_object(
Packit 3ff832
                'checkbutton_emoji_partial_match')
Packit 3ff832
        checkbutton_label = self.__checkbutton_emoji_partial_match.get_child()
Packit 3ff832
        if type(checkbutton_label) == Gtk.Label:
Packit 3ff832
            checkbutton_label.set_property('wrap', True)
Packit 3ff832
            checkbutton_label.set_property('max-width-chars', 74)
Packit 3ff832
        self.__spinbutton_emoji_partial_match = self.__builder.get_object(
Packit 3ff832
                'spinbutton_emoji_partial_match')
Packit 3ff832
        self.__settings_emoji.bind('has-partial-match',
Packit 3ff832
                                   self.__checkbutton_emoji_partial_match,
Packit 3ff832
                                   'active',
Packit 3ff832
                                   Gio.SettingsBindFlags.DEFAULT)
Packit 3ff832
        self.__settings_emoji.bind('has-partial-match',
Packit 3ff832
                                   self.__spinbutton_emoji_partial_match,
Packit 3ff832
                                   'sensitive',
Packit 3ff832
                                   Gio.SettingsBindFlags.GET)
Packit 3ff832
Packit 3ff832
        def adjustment_value_changed_cb(obj):
Packit 3ff832
            key = 'partial-match-length'
Packit 3ff832
            value = int(adjustment.get_value())
Packit 3ff832
            if value == self.__settings_emoji.get_int(key):
Packit 3ff832
                return
Packit 3ff832
            self.__settings_emoji.set_int(key, value)
Packit 3ff832
        def settings_emoji_partial_match_length_cb(settings, key):
Packit 3ff832
            value = self.__settings_emoji.get_int(key)
Packit 3ff832
            old_value = int(self.__spinbutton_emoji_partial_match.get_value())
Packit 3ff832
            if value == old_value:
Packit 3ff832
                return
Packit 3ff832
            self.__spinbutton_emoji_partial_match.set_value(value)
Packit 3ff832
        settings_emoji_partial_match_length_cb(None, 'partial-match-length')
Packit 3ff832
        adjustment = self.__spinbutton_emoji_partial_match.get_adjustment()
Packit 3ff832
        adjustment.connect('value-changed', adjustment_value_changed_cb)
Packit 3ff832
        self.__settings_emoji.connect('changed::partial-match-length',
Packit 3ff832
                                      settings_emoji_partial_match_length_cb)
Packit 3ff832
Packit 3ff832
        self.__hbox_emoji_partial_match = self.__builder.get_object(
Packit 3ff832
                'hbox_emoji_partial_match')
Packit 3ff832
        self.__settings_emoji.bind('has-partial-match',
Packit 3ff832
                                   self.__hbox_emoji_partial_match,
Packit 3ff832
                                   'sensitive',
Packit 3ff832
                                   Gio.SettingsBindFlags.GET)
Packit 3ff832
        self.__radiobutton_emoji_prefix_match = self.__builder.get_object(
Packit 3ff832
                'radiobutton_emoji_prefix_match')
Packit 3ff832
        self.__radiobutton_emoji_suffix_match = self.__builder.get_object(
Packit 3ff832
                'radiobutton_emoji_suffix_match')
Packit 3ff832
        self.__radiobutton_emoji_contain_match = self.__builder.get_object(
Packit 3ff832
                'radiobutton_emoji_contain_match')
Packit 3ff832
Packit 3ff832
        def radiobuton_emoji_partial_match_cb(obj):
Packit 3ff832
            key = 'partial-match-condition'
Packit 3ff832
            condition = 0
Packit 3ff832
            if not obj.get_active():
Packit 3ff832
                return
Packit 3ff832
            if obj == self.__radiobutton_emoji_prefix_match:
Packit 3ff832
                condition = 0
Packit 3ff832
            elif obj == self.__radiobutton_emoji_suffix_match:
Packit 3ff832
                condition = 1
Packit 3ff832
            elif obj == self.__radiobutton_emoji_contain_match:
Packit 3ff832
                condition = 2
Packit 3ff832
            else:
Packit 3ff832
                print('Wrong emoji partial match object')
Packit 3ff832
                return
Packit 3ff832
            self.__settings_emoji.set_int(key, condition)
Packit 3ff832
        def settings_emoji_partial_match_condition_cb(settings, key):
Packit 3ff832
            value = self.__settings_emoji.get_int(key)
Packit 3ff832
            obj = None
Packit 3ff832
            if value == 0:
Packit 3ff832
                obj = self.__radiobutton_emoji_prefix_match
Packit 3ff832
            elif value == 1:
Packit 3ff832
                obj = self.__radiobutton_emoji_suffix_match
Packit 3ff832
            elif value == 2:
Packit 3ff832
                obj = self.__radiobutton_emoji_contain_match
Packit 3ff832
            else:
Packit 3ff832
                print('Wrong emoji partial match condition')
Packit 3ff832
                return
Packit 3ff832
            if obj.get_active():
Packit 3ff832
                return
Packit 3ff832
            obj.set_active(True)
Packit 3ff832
Packit 3ff832
        settings_emoji_partial_match_condition_cb(None,
Packit 3ff832
                                                  'partial-match-condition')
Packit 3ff832
        self.__radiobutton_emoji_prefix_match.connect(
Packit 3ff832
                'toggled',
Packit 3ff832
                radiobuton_emoji_partial_match_cb)
Packit 3ff832
        self.__radiobutton_emoji_suffix_match.connect(
Packit 3ff832
                'toggled',
Packit 3ff832
                radiobuton_emoji_partial_match_cb)
Packit 3ff832
        self.__radiobutton_emoji_contain_match.connect(
Packit 3ff832
                'toggled',
Packit 3ff832
                radiobuton_emoji_partial_match_cb)
Packit 3ff832
        self.__settings_emoji.connect('changed::partial-match-condition',
Packit 3ff832
                                      settings_emoji_partial_match_condition_cb)
Packit 3ff832
Packit 3ff832
    def __init_ui(self):
Packit 3ff832
        # add icon search path
Packit 3ff832
        self.__window = self.__builder.get_object("window_preferences")
Packit 3ff832
        self.__window.connect("delete-event", Gtk.main_quit)
Packit 3ff832
        self.__window.connect("notify::window", self.__gdk_window_set_cb)
Packit 3ff832
Packit 3ff832
        self.__button_close = self.__builder.get_object("button_close")
Packit 3ff832
        self.__button_close.connect("clicked", Gtk.main_quit)
Packit 3ff832
Packit 3ff832
        # auto start ibus
Packit 3ff832
        self.__checkbutton_auto_start = self.__builder.get_object(
Packit 3ff832
                "checkbutton_auto_start")
Packit 3ff832
        self.__checkbutton_auto_start.set_active(self.__is_auto_start())
Packit 3ff832
        self.__checkbutton_auto_start.connect("toggled",
Packit 3ff832
                self.__checkbutton_auto_start_toggled_cb)
Packit 3ff832
Packit 3ff832
        self.__init_hotkeys()
Packit 3ff832
        self.__init_panel()
Packit 3ff832
        self.__init_general()
Packit 3ff832
        self.__init_emoji()
Packit 3ff832
Packit 3ff832
    def __gdk_window_set_cb(self, object, pspec):
Packit 3ff832
        window = object.get_window()
Packit 3ff832
        if type(window) != GdkX11.X11Window:
Packit 3ff832
            return
Packit 3ff832
        s = '%u' % GdkX11.X11Window.get_xid(window)
Packit 3ff832
        GLib.setenv('IBUS_SETUP_XID', s, True)
Packit 3ff832
Packit 3ff832
    def __combobox_notify_active_engine_cb(self, combobox, property):
Packit 3ff832
        engine = self.__combobox.get_active_engine()
Packit 3ff832
        button = self.__builder.get_object("button_engine_add")
Packit 3ff832
        button.set_sensitive(
Packit 3ff832
                engine != None and engine not in self.__treeview.get_engines())
Packit 3ff832
Packit 3ff832
    def __get_engine_setup_exec_args(self, engine):
Packit 3ff832
        args = []
Packit 3ff832
        if engine == None:
Packit 3ff832
           return args
Packit 3ff832
        setup = str(engine.get_setup())
Packit 3ff832
        if len(setup) != 0:
Packit 3ff832
            args = setup.split()
Packit 3ff832
            args.insert(1, path.basename(args[0]))
Packit 3ff832
            return args
Packit 3ff832
        name = str(engine.get_name())
Packit 3ff832
        libexecdir = os.environ['IBUS_LIBEXECDIR']
Packit 3ff832
        setup_path = (libexecdir + '/' + 'ibus-setup-' if libexecdir != None \
Packit 3ff832
            else 'ibus-setup-') + name.split(':')[0]
Packit 3ff832
        if path.exists(setup_path):
Packit 3ff832
            args.append(setup_path)
Packit 3ff832
            args.append(path.basename(setup_path))
Packit 3ff832
        return args
Packit 3ff832
Packit 3ff832
    def __treeview_notify_cb(self, treeview, prop):
Packit 3ff832
        if prop.name not in ("active-engine", "engines"):
Packit 3ff832
            return
Packit 3ff832
Packit 3ff832
        engines = self.__treeview.get_sorted_engines()
Packit 3ff832
        engine = self.__treeview.get_active_engine()
Packit 3ff832
Packit 3ff832
        self.__builder.get_object("button_engine_remove").set_sensitive(engine != None)
Packit 3ff832
        self.__builder.get_object("button_engine_about").set_sensitive(engine != None)
Packit 3ff832
        self.__builder.get_object("button_engine_up").set_sensitive(engine not in engines[:1])
Packit 3ff832
        self.__builder.get_object("button_engine_down").set_sensitive(engine not in engines[-1:])
Packit 3ff832
Packit 3ff832
        obj = self.__builder.get_object("button_engine_preferences")
Packit 3ff832
        if len(self.__get_engine_setup_exec_args(engine)) != 0:
Packit 3ff832
            obj.set_sensitive(True)
Packit 3ff832
        else:
Packit 3ff832
            obj.set_sensitive(False)
Packit 3ff832
Packit 3ff832
        if prop.name == "engines":
Packit 3ff832
            engines = self.__treeview.get_engines()
Packit 3ff832
            engine_names = [e.get_name() for e in engines]
Packit 3ff832
            self.__settings_general.set_strv('preload-engines', engine_names)
Packit 3ff832
Packit 3ff832
    def __button_engine_add_cb(self, button):
Packit 3ff832
        dialog = EngineDialog(transient_for = self.__window)
Packit 3ff832
        dialog.set_engines(self.__engines)
Packit 3ff832
        id = dialog.run()
Packit 3ff832
Packit 3ff832
        if id != Gtk.ResponseType.APPLY:
Packit 3ff832
            dialog.destroy()
Packit 3ff832
            return
Packit 3ff832
Packit 3ff832
        engine = dialog.get_selected_engine()
Packit 3ff832
        dialog.destroy()
Packit 3ff832
Packit 3ff832
        self.__treeview.append_engine(engine)
Packit 3ff832
Packit 3ff832
    def __button_engine_add_cb_deprecate(self, button):
Packit 3ff832
        engine = self.__combobox.get_active_engine()
Packit 3ff832
        self.__treeview.append_engine(engine)
Packit 3ff832
Packit 3ff832
    def __button_engine_about_cb(self, button):
Packit 3ff832
        engine = self.__treeview.get_active_engine()
Packit 3ff832
        if engine:
Packit 3ff832
            about = EngineAbout(engine = engine, transient_for = self.__window)
Packit 3ff832
            about.run()
Packit 3ff832
            about.destroy()
Packit 3ff832
Packit 3ff832
    def __button_engine_preferences_cb(self, button):
Packit 3ff832
        engine = self.__treeview.get_active_engine()
Packit 3ff832
        args = self.__get_engine_setup_exec_args(engine)
Packit 3ff832
        if len(args) == 0:
Packit 3ff832
            return
Packit 3ff832
        name = engine.get_name()
Packit 3ff832
        if name in list(self.__engine_setup_exec_list.keys()):
Packit 3ff832
            try:
Packit 3ff832
                wpid, sts = os.waitpid(self.__engine_setup_exec_list[name],
Packit 3ff832
                                       os.WNOHANG)
Packit 3ff832
                # the setup is still running.
Packit 3ff832
                if wpid == 0:
Packit 3ff832
                    return
Packit 3ff832
            except OSError:
Packit 3ff832
                pass
Packit 3ff832
            del self.__engine_setup_exec_list[name]
Packit 3ff832
        self.__engine_setup_exec_list[name] = os.spawnl(os.P_NOWAIT, *args)
Packit 3ff832
Packit 3ff832
    def __init_bus(self):
Packit 3ff832
        self.__bus = IBus.Bus()
Packit 3ff832
        if self.__bus.is_connected():
Packit 3ff832
            return
Packit 3ff832
Packit 3ff832
        message = _("The IBus daemon is not running. Do you wish to start it?")
Packit 3ff832
        dlg = Gtk.MessageDialog(message_type = Gtk.MessageType.QUESTION,
Packit 3ff832
                                buttons = Gtk.ButtonsType.YES_NO,
Packit 3ff832
                                text = message)
Packit 3ff832
        id = dlg.run()
Packit 3ff832
        dlg.destroy()
Packit 3ff832
        self.__flush_gtk_events()
Packit 3ff832
        if id != Gtk.ResponseType.YES:
Packit 3ff832
            sys.exit(0)
Packit 3ff832
Packit 3ff832
        main_loop = GLib.MainLoop()
Packit 3ff832
Packit 3ff832
        timeout = 5
Packit 3ff832
        GLib.timeout_add_seconds(timeout, lambda *args: main_loop.quit())
Packit 3ff832
        self.__bus.connect("connected", lambda *args: main_loop.quit())
Packit 3ff832
Packit 3ff832
        os.spawnlp(os.P_NOWAIT, "ibus-daemon", "ibus-daemon", "--xim")
Packit 3ff832
Packit 3ff832
        main_loop.run()
Packit 3ff832
Packit 3ff832
        if self.__bus.is_connected():
Packit 3ff832
            message = _("IBus has been started! "
Packit 3ff832
                "If you cannot use IBus, add the following lines to your $HOME/.bashrc; then relog into your desktop.\n"
Packit 3ff832
                "  export GTK_IM_MODULE=ibus\n"
Packit 3ff832
                "  export XMODIFIERS=@im=ibus\n"
Packit 3ff832
                "  export QT_IM_MODULE=ibus"
Packit 3ff832
                )
Packit 3ff832
            dlg = Gtk.MessageDialog(message_type = Gtk.MessageType.INFO,
Packit 3ff832
                                    buttons = Gtk.ButtonsType.OK,
Packit 3ff832
                                    text = message)
Packit 3ff832
            id = dlg.run()
Packit 3ff832
            dlg.destroy()
Packit 3ff832
            self.__flush_gtk_events()
Packit 3ff832
        else:
Packit 3ff832
            # Translators: %d == 5 currently
Packit 3ff832
            message = _("IBus daemon could not be started in %d seconds")
Packit 3ff832
            dlg = Gtk.MessageDialog(message_type = Gtk.MessageType.INFO,
Packit 3ff832
                                    buttons = Gtk.ButtonsType.OK,
Packit 3ff832
                                    text = message % timeout)
Packit 3ff832
            id = dlg.run()
Packit 3ff832
            dlg.destroy()
Packit 3ff832
            self.__flush_gtk_events()
Packit 3ff832
            sys.exit(0)
Packit 3ff832
Packit 3ff832
    def __shortcut_button_clicked_cb(self, button, name, section, _name, entry):
Packit 3ff832
        buttons = (_("_Cancel"), Gtk.ResponseType.CANCEL,
Packit 3ff832
                   _("_OK"), Gtk.ResponseType.OK)
Packit 3ff832
        title1 = _("Select keyboard shortcut for %s")
Packit 3ff832
        # Translators: Title of the window
Packit 3ff832
        title2 = _("switching input methods")
Packit 3ff832
        title = title1 % title2
Packit 3ff832
        dialog = keyboardshortcut.KeyboardShortcutSelectionDialog(
Packit 3ff832
                title = title, transient_for = self.__window)
Packit 3ff832
        dialog.add_buttons(*buttons)
Packit 3ff832
        text = entry.get_text()
Packit 3ff832
        if text:
Packit 3ff832
            shortcuts = text.split("; ")
Packit 3ff832
        else:
Packit 3ff832
            shortcuts = None
Packit 3ff832
        dialog.set_shortcuts(shortcuts)
Packit 3ff832
        id = dialog.run()
Packit 3ff832
        shortcuts = dialog.get_shortcuts()
Packit 3ff832
        dialog.destroy()
Packit 3ff832
        if id != Gtk.ResponseType.OK:
Packit 3ff832
            return
Packit 3ff832
        if section == 'panel/emoji':
Packit 3ff832
            self.__settings_emoji.set_strv(name, shortcuts)
Packit 3ff832
        else:
Packit 3ff832
            self.__settings_hotkey.set_strv(name, shortcuts)
Packit 3ff832
        text = "; ".join(shortcuts)
Packit 3ff832
        entry.set_text(text)
Packit 3ff832
        tooltip = "\n".join(shortcuts)
Packit 3ff832
        tooltip += "\n" + \
Packit 3ff832
            _("Use shortcut with shift to switch to the previous input method") 
Packit 3ff832
        entry.set_tooltip_text(tooltip)
Packit 3ff832
Packit 3ff832
    def __item_started_column_toggled_cb(self, cell, path_str, model):
Packit 3ff832
Packit 3ff832
        # get toggled iter
Packit 3ff832
        iter = model.get_iter_from_string(path_str)
Packit 3ff832
        data = model.get_value(iter, COLUMN_DATA)
Packit 3ff832
Packit 3ff832
        # do something with the value
Packit 3ff832
        if data[DATA_STARTED] == False:
Packit 3ff832
            try:
Packit 3ff832
                self.__bus.register_start_engine(data[DATA_LANG], data[DATA_NAME])
Packit 3ff832
            except Exception as e:
Packit 3ff832
                dlg = Gtk.MessageDialog(message_type = Gtk.MessageType.ERROR,
Packit 3ff832
                        transient_for = self.__window,
Packit 3ff832
                        buttons = Gtk.ButtonsType.CLOSE,
Packit 3ff832
                        text = str(e))
Packit 3ff832
                dlg.run()
Packit 3ff832
                dlg.destroy()
Packit 3ff832
                self.__flush_gtk_events()
Packit 3ff832
                return
Packit 3ff832
        else:
Packit 3ff832
            try:
Packit 3ff832
                self.__bus.register_stop_engine(data[DATA_LANG], data[DATA_NAME])
Packit 3ff832
            except Exception as e:
Packit 3ff832
                dlg = Gtk.MessageDialog(message_type = Gtk.MessageType.ERROR,
Packit 3ff832
                        transient_for = self.__window,
Packit 3ff832
                        buttons = Gtk.ButtonsType.CLOSE,
Packit 3ff832
                        text = str(e))
Packit 3ff832
                dlg.run()
Packit 3ff832
                dlg.destroy()
Packit 3ff832
                self.__flush_gtk_events()
Packit 3ff832
                return
Packit 3ff832
        data[DATA_STARTED] = not data[DATA_STARTED]
Packit 3ff832
Packit 3ff832
        # set new value
Packit 3ff832
        model.set(iter, COLUMN_ENABLE, data[DATA_STARTED])
Packit 3ff832
Packit 3ff832
    def __item_preload_column_toggled_cb(self, cell, path_str, model):
Packit 3ff832
Packit 3ff832
        # get toggled iter
Packit 3ff832
        iter = model.get_iter_from_string(path_str)
Packit 3ff832
        data = model.get_value(iter, COLUMN_DATA)
Packit 3ff832
Packit 3ff832
        data[DATA_PRELOAD] = not data[DATA_PRELOAD]
Packit 3ff832
        engine = "%s:%s" % (data[DATA_LANG], data[DATA_NAME])
Packit 3ff832
Packit 3ff832
        if data[DATA_PRELOAD]:
Packit 3ff832
            if engine not in self.__preload_engines:
Packit 3ff832
                self.__preload_engines.add(engine)
Packit 3ff832
                self.__settings_general.set_strv('preload-engines',
Packit 3ff832
                                                 list(self.__preload_engines))
Packit 3ff832
        else:
Packit 3ff832
            if engine in self.__preload_engines:
Packit 3ff832
                self.__preload_engines.remove(engine)
Packit 3ff832
                self.__settings_general.set_strv('preload-engines',
Packit 3ff832
                                                 list(self.__preload_engines))
Packit 3ff832
Packit 3ff832
        # set new value
Packit 3ff832
        model.set(iter, COLUMN_PRELOAD, data[DATA_PRELOAD])
Packit 3ff832
Packit 3ff832
    def __is_auto_start(self):
Packit 3ff832
        link_file = path.join(GLib.get_user_config_dir(),
Packit 3ff832
                              "autostart/ibus.desktop")
Packit 3ff832
        ibus_desktop = path.join(os.getenv("IBUS_PREFIX"),
Packit 3ff832
                                 "share/applications/ibus.desktop")
Packit 3ff832
Packit 3ff832
        if not path.exists(link_file):
Packit 3ff832
            return False
Packit 3ff832
        if not path.islink(link_file):
Packit 3ff832
            return False
Packit 3ff832
        if path.realpath(link_file) != ibus_desktop:
Packit 3ff832
            return False
Packit 3ff832
        return True
Packit 3ff832
Packit 3ff832
    def __checkbutton_auto_start_toggled_cb(self, button):
Packit 3ff832
        auto_start_dir = path.join(GLib.get_user_config_dir(), "autostart")
Packit 3ff832
        if not path.isdir(auto_start_dir):
Packit 3ff832
            os.makedirs(auto_start_dir)
Packit 3ff832
Packit 3ff832
        link_file = path.join(GLib.get_user_config_dir(),
Packit 3ff832
                              "autostart/ibus.desktop")
Packit 3ff832
        ibus_desktop = path.join(os.getenv("IBUS_PREFIX"),
Packit 3ff832
                                 "share/applications/ibus.desktop")
Packit 3ff832
        # unlink file
Packit 3ff832
        try:
Packit 3ff832
            os.unlink(link_file)
Packit 3ff832
        except:
Packit 3ff832
            pass
Packit 3ff832
        if self.__checkbutton_auto_start.get_active():
Packit 3ff832
            os.symlink(ibus_desktop, link_file)
Packit 3ff832
Packit 3ff832
    def __sigusr1_cb(self, *args):
Packit 3ff832
        self.__window.present()
Packit 3ff832
Packit 3ff832
    def run(self):
Packit 3ff832
        self.__window.show_all()
Packit 3ff832
        signal.signal(signal.SIGUSR1, self.__sigusr1_cb)
Packit 3ff832
        Gtk.main()
Packit 3ff832
Packit 3ff832
if __name__ == "__main__":
Packit 3ff832
    try:
Packit 3ff832
        locale.setlocale(locale.LC_ALL, '')
Packit 3ff832
    except locale.Error:
Packit 3ff832
        print("Using the fallback 'C' locale", file=sys.stderr)
Packit 3ff832
        locale.setlocale(locale.LC_ALL, 'C')
Packit 3ff832
Packit 3ff832
    i18n.init_textdomain(DOMAINNAME)
Packit 3ff832
    i18n.init_textdomain('xkeyboard-config')
Packit 3ff832
    setup = Setup()
Packit 3ff832
    setup.run()