plugin.py 5.47 KB
Newer Older
Dicson's avatar
Dicson committed
1 2
from gi.repository import Gtk
from gi.repository import Gdk
3

4
from gajim.common import app
Dicson's avatar
Dicson committed
5

6 7
from gajim.plugins import GajimPlugin
from gajim.plugins.helpers import log_calls
Dicson's avatar
Dicson committed
8

9 10 11 12 13
# Since Gajim 1.1.0 _() has to be imported
try:
    from gajim.common.i18n import _
except ImportError:
    pass
Dicson's avatar
Dicson committed
14 15 16 17

class WrongLayoutPlugin(GajimPlugin):
    @log_calls('WrongLayoutPlugin')
    def init(self):
18
        self.description = _('Press alt+r to convert chars typed in '
19
            'wrong layout Rus<>Eng')
Dicson's avatar
Dicson committed
20 21
        self.config_dialog = None
        self.gui_extension_points = {
Dicson's avatar
Dicson committed
22 23
                'chat_control_base': (self.connect_with_chat_control,
                                       self.disconnect_from_chat_control)}
Dicson's avatar
Dicson committed
24 25
        self.chat_control = None
        self.controls = []
Dicson's avatar
Dicson committed
26
        self.dict_eng = {'`': 'ё', 'q': 'й', 'w': 'ц', 'e': 'у', 'r': 'к',
Dicson's avatar
Dicson committed
27 28 29 30 31 32 33 34 35 36 37 38 39
                't': 'е',
                'y': 'н', 'u': 'г', 'i': 'ш', 'o': 'щ', 'p': 'з', '[': 'х',
                ']': 'ъ', 'a': 'ф', 's': 'ы', 'd': 'в', 'f': 'а', 'g': 'п',
                'h': 'р', 'j': 'о', 'k': 'л', 'l': 'д', ';': 'ж', '\'': 'э',
                'z': 'я', 'x': 'ч', 'c': 'с', 'v': 'м', 'b': 'и', 'n': 'т',
                'm': 'ь', ',': 'б', '.': 'ю', '/': '.',
                '\\': '\\', '~': 'Ё', '@': '"', '$': ';', '^': ':', '&': '?',
                'Q': 'Й', 'W': 'Ц', 'E': 'У', 'R': 'К', 'T': 'Е', 'Y': 'Н',
                'U': 'Г', 'I': 'Ш', 'O': 'Щ', 'P': 'З', '{': 'Х', '}': 'Ъ',
                '|': '/', 'A': 'Ф', 'S': 'Ы', 'D': 'В', 'F': 'А', 'G': 'П',
                'H': 'Р', 'J': 'О', 'K': 'Л', 'L': 'Д', '"': 'Э', 'Z': 'Я',
                'X': 'Ч', 'C': 'С', 'V': 'М', 'B': 'И', 'N': 'Т', 'M': 'Ь',
                '<': 'Б', '>': 'Ю', '?': ',', ':': 'Ж'}
Dicson's avatar
Dicson committed
40
        self.dict_ru = {}
Dicson's avatar
Dicson committed
41
        for key in list(self.dict_eng.keys()):
Dicson's avatar
Dicson committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
            self.dict_ru[self.dict_eng[key]] = key

    @log_calls('WrongLayoutPlugin')
    def activate(self):
        pass

    @log_calls('WrongLayoutPlugin')
    def deactivate(self):
        pass

    @log_calls('WrongLayoutPlugin')
    def connect_with_chat_control(self, chat_control):
        self.chat_control = chat_control
        control = Base(self, self.chat_control)
        self.controls.append(control)

    @log_calls('WrongLayoutPlugin')
    def disconnect_from_chat_control(self, chat_control):
        for control in self.controls:
            control.disconnect_from_chat_control()
        self.controls = []

Dicson's avatar
Dicson committed
64

Dicson's avatar
Dicson committed
65 66 67 68 69 70 71 72 73 74 75
class Base(object):
    def __init__(self, plugin, chat_control):
        self.plugin = plugin
        self.chat_control = chat_control
        self.textview = self.chat_control.conv_textview

        self.id_ = self.chat_control.msg_textview.connect('key_press_event',
                                                        self.mykeypress_event)
        self.chat_control.handlers[self.id_] = self.chat_control.msg_textview

    def disconnect_from_chat_control(self):
76 77
        if self.chat_control.msg_textview.handler_is_connected(self.id_):
            self.chat_control.msg_textview.disconnect(self.id_)
Dicson's avatar
Dicson committed
78 79

    def mykeypress_event(self, widget, event):
Dicson's avatar
Dicson committed
80 81
        if event.keyval == Gdk.KEY_r or event.keyval == 1739:
            if event.state & Gdk.ModifierType.MOD1_MASK:  # alt+r
Dicson's avatar
Dicson committed
82 83
                start, end, iter_ = self.get_start_end()
                count_eng = count_rus = 0
Dicson's avatar
Dicson committed
84
                c = iter_.get_char()
Dicson's avatar
Dicson committed
85 86 87 88 89 90 91 92 93 94 95
                while ((c != 0) & iter_.in_range(start, end)):
                    if ((ord(c) > 65) & (ord(c) < 122)) | \
                        (c == '@') | (c == '#') | (c == '$') | (c == '^') | \
                        (c == '&') | (c == '|') | (c == '~') | \
                        (c == '{') | (c == '}') | (c == '[') | (c == ']') | \
                        (c == '<') | (c == '>'):
                        count_eng += 1
                    if ((ord(c) > 1040) & (ord(c) < 1103)) | (c == 'ё') | \
                        (c == 'Ё') | (c == '№'):
                        count_rus += 1
                    iter_.forward_char()
Dicson's avatar
Dicson committed
96
                    c = iter_.get_char()
Dicson's avatar
Dicson committed
97 98
                is_russian = (count_rus >= count_eng)
                start, end, iter_ = self.get_start_end()
Dicson's avatar
Dicson committed
99
                c = iter_.get_char()
Dicson's avatar
Dicson committed
100 101 102 103 104 105 106 107
                text = ''
                while ((c != 0) & iter_.in_range(start, end)):
                    if not is_russian:
                        conv = self.plugin.dict_eng.get(c, c)
                    else:
                        conv = self.plugin.dict_ru.get(c.encode('utf-8'), c)
                    text = text + conv
                    iter_.forward_char()
Dicson's avatar
Dicson committed
108
                    c = iter_.get_char()
Dicson's avatar
Dicson committed
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
                start, end, iter_ = self.get_start_end()
                message_buffer = self.chat_control.msg_textview.get_buffer()
                message_buffer.delete(start, end)
                message_buffer.insert_at_cursor(text)
                self.chat_control.msg_textview.grab_focus()
                return True

    def get_start_end(self):
        message_buffer = self.chat_control.msg_textview.get_buffer()
        sel = message_buffer.get_selection_bounds()
        if sel != ():
            start, end = sel
        else:
            start = message_buffer.get_start_iter()
            end = message_buffer.get_end_iter()
124
            stext = app.config.get('gc_refer_to_nick_char')
Dicson's avatar
Dicson committed
125
            res = start.forward_search(stext, Gtk.TextSearchFlags.TEXT_ONLY, None)
Dicson's avatar
Dicson committed
126 127 128 129 130
            if res:
                first, start = res
        start.order(end)
        iter_ = start
        return start, end, iter_