Ticket #1686: 0001-virtualkeyboard.patch

File 0001-virtualkeyboard.patch, 32.1 KB (added by earias, 14 years ago)
  • extensions/globalkey/Makefile.am

    From 6781e1bec2c387a740aafe0943c0aa9250482e1a Mon Sep 17 00:00:00 2001
    From: Esteban <earias@localhost.localdomain>
    Date: Mon, 25 Jan 2010 14:52:17 -0200
    Subject: [PATCH] virtualkeyboard
    
    ---
     extensions/globalkey/Makefile.am        |    4 +-
     extensions/globalkey/virtualkeyboard.py |   12 +
     src/jarabe/model/Makefile.am            |    3 +-
     src/jarabe/model/virtualkeyboard.py     |  184 +++++++
     src/jarabe/view/Makefile.am             |    3 +-
     src/jarabe/view/virtualkeyboard.py      |  865 +++++++++++++++++++++++++++++++
     6 files changed, 1068 insertions(+), 3 deletions(-)
     create mode 100644 extensions/globalkey/virtualkeyboard.py
     create mode 100755 src/jarabe/model/virtualkeyboard.py
     create mode 100755 src/jarabe/view/virtualkeyboard.py
    
    diff --git a/extensions/globalkey/Makefile.am b/extensions/globalkey/Makefile.am
    index 69afac2..dff13fb 100644
    a b sugardir = $(pkgdatadir)/extensions/globalkey 
    33sugar_PYTHON =          \
    44        __init__.py     \
    55        screenshot.py   \
    6         viewsource.py
     6        viewsource.py   \
     7        virtualkeyboard.py
     8
  • new file extensions/globalkey/virtualkeyboard.py

    diff --git a/extensions/globalkey/virtualkeyboard.py b/extensions/globalkey/virtualkeyboard.py
    new file mode 100644
    index 0000000..9291142
    - +  
     1import os
     2import gtk
     3import logging
     4
     5from jarabe.model import shell
     6import jarabe.view.virtualkeyboard
     7
     8BOUND_KEYS = ['<alt>k']
     9
     10def handle_key_press(key):
     11        logging.debug('load virtual keyboard')
     12        jarabe.view.virtualkeyboard.Teclado()
  • src/jarabe/model/Makefile.am

    diff --git a/src/jarabe/model/Makefile.am b/src/jarabe/model/Makefile.am
    index 18d44da..ae3dce9 100644
    a b sugar_PYTHON = \ 
    1414        shell.py                \
    1515        screen.py               \
    1616        session.py              \
    17         sound.py
     17        sound.py                \
     18        virtualkeyboard.py
  • new file src/jarabe/model/virtualkeyboard.py

    diff --git a/src/jarabe/model/virtualkeyboard.py b/src/jarabe/model/virtualkeyboard.py
    new file mode 100755
    index 0000000..6867f10
    - +  
     1#!/usr/bin/env python
     2# -*- coding: iso-8859-1 -*-
     3# virtualkeyboard
     4# Copyright (C) 2009 Plan Ceibal
     5#
     6# This program is free software: you can redistribute it and/or modify
     7# it under the terms of the GNU General Public License as published by
     8# the Free Software Foundation, either version 3 of the License, or
     9# (at your option) any later version.
     10#
     11# This program is distributed in the hope that it will be useful,
     12# but WITHOUT ANY WARRANTY; without even the implied warranty of
     13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14# GNU General Public License for more details.
     15#
     16# You should have received a copy of the GNU General Public License
     17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18#
     19# Contact information: comunidad@plan.ceibal.edu.uy
     20# Plan Ceibal http://www.ceibal.edu.uy
     21
     22import pygtk
     23pygtk.require('2.0')
     24import gtk
     25import sys, os
     26import time
     27import pango
     28import Xlib.display
     29import Xlib.X
     30import Xlib.XK
     31import Xlib.protocol.event
     32
     33class Teclado:
     34    special_X_keysyms = {
     35            ' ' : "space",
     36            '\t' : "Tab",
     37            '\n' : "Return",
     38            '\r' : "BackSpace",
     39            '\e' : "Escape",
     40            '!' : "exclam",
     41            '#' : "numbersign",
     42            '%' : "percent",
     43            '$' : "dollar",
     44            '&' : "ampersand",
     45            '"' : "quotedbl",
     46            '\'' : "apostrophe",
     47            '(' : "parenleft",
     48            ')' : "parenright",
     49            '*' : "asterisk",
     50            '=' : "equal",
     51            '+' : "plus",
     52            ',' : "comma",
     53            '-' : "minus",
     54            '.' : "period",
     55            '/' : "slash",
     56            ':' : "colon",
     57            ';' : "semicolon",
     58            '<' : "less",
     59            '>' : "greater",
     60            '?' : "question",
     61            '@' : "at",
     62            '[' : "bracketleft",
     63            ']' : "bracketright",
     64            '\\' : "backslash",
     65            '^' : "asciicircum",
     66            '_' : "underscore",
     67            '`' : "grave",
     68            '{' : "braceleft",
     69            '|' : "bar",
     70            '}' : "braceright",
     71            '~' : "asciitilde",
     72            'ñ' : "ntilde",
     73            'Ñ' : "Ntilde"
     74    };
     75
     76    def __init__(self):
     77            self.display = Xlib.display.Display()
     78            self.window = self.display.get_input_focus()._data["focus"];
     79
     80    def get_keysym(self, ch) :
     81            keysym = Xlib.XK.string_to_keysym(ch)
     82            if keysym == 0 :
     83
     84                keysym = Xlib.XK.string_to_keysym(self.special_X_keysyms[ch])
     85            return keysym
     86
     87    def is_shifted(self, ch) :
     88            if ch.isupper() :
     89                return True
     90            if "/=~!@#$%^&()_*{}|:;\">?Ñ".find(ch) >= 0 :
     91                return True
     92            return False
     93
     94    def char_to_keycode(self, ch) :
     95            keysym = self.get_keysym(ch)
     96            keycode = self.display.keysym_to_keycode(keysym)
     97            if keycode == 0 :
     98                print "Sorry, can't map", ch
     99
     100            if (self.is_shifted(ch)) :
     101                shift_mask = Xlib.X.ShiftMask
     102            else :
     103                shift_mask = 0
     104
     105            return keycode, shift_mask
     106
     107
     108    def send_string(self, ch):
     109                keycode, shift_mask = self.char_to_keycode(ch)
     110                self.escribir(keycode, shift_mask)
     111
     112    def escribir(self, keycode, shift_mask):
     113                event = Xlib.protocol.event.KeyPress(
     114                    time = int(time.time()),
     115                    root = self.display.screen().root,
     116                    window = self.window,
     117                    same_screen = 0, child = Xlib.X.NONE,
     118                    root_x = 0, root_y = 0, event_x = 0, event_y = 0,
     119                    state = shift_mask,
     120                    detail = keycode
     121                    )
     122                self.window.send_event(event, propagate = True)
     123                event = Xlib.protocol.event.KeyRelease(
     124                    time = int(time.time()),
     125                    root = self.display.screen().root,
     126                    window = self.window,
     127                    same_screen = 0, child = Xlib.X.NONE,
     128                    root_x = 0, root_y = 0, event_x = 0, event_y = 0,
     129                    state = shift_mask,
     130                    detail = keycode
     131                    )
     132                self.window.send_event(event, propagate = True)
     133
     134
     135    def escribir_txt(self, txt):
     136        self.display = Xlib.display.Display()
     137        self.window = self.display.get_input_focus()._data["focus"];
     138
     139        if (txt == "ÃŒ"):
     140                self.escribir(34, 1)
     141                self.send_string("u")
     142        elif (txt == "Ü"):
     143                self.escribir(34, 1)
     144                self.send_string("U")
     145        elif (txt == "|"):
     146                self.escribir(10, Xlib.X.Mod5Mask)
     147        elif (txt == "@"):
     148                self.escribir(11, Xlib.X.Mod5Mask)
     149        elif (txt == "#"):
     150                self.escribir(12, Xlib.X.Mod5Mask)
     151        elif (txt == "º"):
     152                self.escribir(49, 0)
     153        elif (txt == "ª"):
     154                self.escribir(49, 1)
     155        elif (txt == "'"):
     156                self.escribir(20, 0)
     157        elif (txt == "¿"):
     158                self.escribir(21, 1)
     159        elif (txt == "¡"):
     160                self.escribir(21, 0)
     161        elif (txt == "'"):
     162                self.escribir(34, 0)
     163        elif (self.tieneTilde(txt)):           
     164                self.escribir(34, 0)
     165                self.escribirVocal(txt)
     166        else:
     167                self.send_string(txt)
     168
     169        self.display.sync()
     170
     171    def tieneTilde(self, txt):
     172        return "ÁÉÍÓÚáéíóú".find(txt) >= 0
     173
     174    def escribirVocal(self, txt):
     175        if txt=="Á": self.send_string("A")
     176        if txt=="É": self.send_string("E")
     177        if txt=="Í": self.send_string("I")
     178        if txt=="Ó": self.send_string("O")
     179        if txt=="Ú": self.send_string("U")
     180        if txt=="á": self.send_string("a")
     181        if txt=="é": self.send_string("e")
     182        if txt=="í": self.send_string("i")
     183        if txt=="ó": self.send_string("o")
     184        if txt=="ú": self.send_string("u")
  • src/jarabe/view/Makefile.am

    diff --git a/src/jarabe/view/Makefile.am b/src/jarabe/view/Makefile.am
    index 1abea6d..4dbd815 100644
    a b sugar_PYTHON = \ 
    99        pulsingicon.py                  \
    1010        service.py                      \
    1111        tabbinghandler.py               \
    12         viewsource.py
     12        viewsource.py                   \
     13        virtualkeyboard.py
  • new file src/jarabe/view/virtualkeyboard.py

    diff --git a/src/jarabe/view/virtualkeyboard.py b/src/jarabe/view/virtualkeyboard.py
    new file mode 100755
    index 0000000..e7697cc
    - +  
     1#!/usr/bin/env python
     2# -*- coding: iso-8859-1 -*-
     3# virtualkeyboard
     4# Copyright (C) 2009 Plan Ceibal
     5#
     6# This program is free software: you can redistribute it and/or modify
     7# it under the terms of the GNU General Public License as published by
     8# the Free Software Foundation, either version 3 of the License, or
     9# (at your option) any later version.
     10#
     11# This program is distributed in the hope that it will be useful,
     12# but WITHOUT ANY WARRANTY; without even the implied warranty of
     13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14# GNU General Public License for more details.
     15#
     16# You should have received a copy of the GNU General Public License
     17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18#
     19# Contact information: comunidad@plan.ceibal.edu.uy
     20# Plan Ceibal http://www.ceibal.edu.uy
     21
     22import pygtk
     23pygtk.require('2.0')
     24import gtk
     25import sys, os
     26import time
     27import pango
     28import gconf
     29import logging
     30import threading
     31import gobject
     32
     33import jarabe.model.virtualkeyboard
     34from sugar.graphics.icon import Icon, get_icon_file_name
     35
     36gobject.threads_init()
     37
     38velocidades = {'lenta': 3, 'media': 2, 'rapida':1}
     39
     40class Teclado:
     41
     42    def delete_event(self, widget, event=None):
     43        self.BOTONESxBARRIDOxFILA = False
     44        self.BOTONESxBARRIDO = False
     45
     46        os.environ['virtualkeyboard'] = 'False'
     47        logging.debug('close virtual keyboard')
     48        return False
     49
     50    def __init__(self):
     51        self.fila_1 = [];
     52        self.fila_2 = [];
     53        self.fila_3 = [];
     54        self.fila_4 = [];
     55        self.fila_5 = [];
     56        self.fila_6 = [];
     57        self.BOTONESxBARRIDO = False;
     58        self.BOTONESxBARRIDOxFILA = False;
     59        self.MAYUSCULA = True;
     60        self.fila_actual = None;
     61        self.btn_actual = None;
     62        self.fila_actual_nro = -1;
     63        self.seg = 2;
     64
     65        if os.environ.has_key('virtualkeyboard'):
     66                self.visible = os.environ['virtualkeyboard']
     67                if self.visible == 'True':
     68                        return
     69                else:
     70                        if self.visible == 'False':                     
     71                                self.desplegar()
     72        else:
     73                self.desplegar()   
     74
     75    def desplegar(self):
     76        self._mTeclado=jarabe.model.virtualkeyboard.Teclado()
     77
     78        self.dialog = gtk.Dialog()
     79        self.dialog.set_title("TECLADO VIRTUAL")
     80        try:
     81                self.dialog.set_icon_from_file(get_icon_file_name('teclado'))
     82        except:
     83                logging.debug('dont show virtual keyboard icon')
     84
     85        self.dialog.set_resizable(True)
     86        self.dialog.set_accept_focus(False)
     87        #gtk.Window.move(self.dialog, 0, 0)
     88
     89        self.dialog.connect("delete_event", self.delete_event)
     90
     91        self.vbox_teclado = self.mostrar_teclado()
     92
     93        self.event_box = gtk.EventBox()
     94        self.event_box.add(self.vbox_teclado)
     95        self.event_box.set_events(gtk.gdk.BUTTON_PRESS)
     96        self.event_box.show()
     97
     98
     99        self.ebc = self.event_box.connect("button_press_event", self.mouse_boton)
     100
     101        self.dialog.vbox.pack_start(self.event_box, False, False, 5)
     102
     103        self.vbox_teclado.show_all()
     104        self.dialog.show()   
     105
     106        os.environ['virtualkeyboard'] = 'True'
     107
     108
     109    def mostrar_teclado(self):
     110        child = gtk.VBox(False, 2)
     111
     112        self.btn_BACK_SPACE = self.new_button_borrar()
     113
     114        self.btn_SPACE = self.new_button_espacio()
     115
     116        self.btn_CAPS_LOCK = self.new_button_mayuscula()
     117        self.fila_3.append(self.btn_CAPS_LOCK)
     118
     119        self.btn_ENTER = self.new_button_enter()
     120        self.fila_2.append(self.btn_ENTER)
     121
     122        self.btn_TAB = self.new_button_tab()
     123        self.fila_2.append(self.btn_TAB)
     124
     125        self.btn_do = self.new_button_escribir("º")
     126        self.fila_1.append(self.btn_do)
     127
     128        self.btn_1 = self.new_button_escribir("1")
     129        self.fila_1.append(self.btn_1)
     130
     131        self.btn_2 = self.new_button_escribir("2")
     132        self.fila_1.append(self.btn_2)
     133
     134        self.btn_3 = self.new_button_escribir("3")
     135        self.fila_1.append(self.btn_3)
     136
     137        self.btn_4 = self.new_button_escribir("4")
     138        self.fila_1.append(self.btn_4)
     139
     140        self.btn_5 = self.new_button_escribir("5")
     141        self.fila_1.append(self.btn_5)
     142
     143        self.btn_6 = self.new_button_escribir("6")
     144        self.fila_1.append(self.btn_6)
     145
     146        self.btn_7 = self.new_button_escribir("7")
     147        self.fila_1.append(self.btn_7)
     148       
     149        self.btn_8 = self.new_button_escribir("8")
     150        self.fila_1.append(self.btn_8)
     151
     152        self.btn_9 = self.new_button_escribir("9")
     153        self.fila_1.append(self.btn_9)
     154
     155        self.btn_0 = self.new_button_escribir("0")
     156        self.fila_1.append(self.btn_0)
     157
     158        self.btn_finPreg = self.new_button_escribir("'")
     159        self.fila_1.append(self.btn_finPreg)
     160
     161        self.btn_inicioPreg = self.new_button_escribir("¡")
     162        self.fila_1.append(self.btn_inicioPreg)
     163
     164        self.btn_Q = self.new_button_escribir("Q")
     165        self.fila_2.append(self.btn_Q)
     166
     167        self.btn_W = self.new_button_escribir("W")
     168        self.fila_2.append(self.btn_W)
     169
     170        self.btn_E = self.new_button_escribir("E")
     171        self.fila_2.append(self.btn_E)
     172
     173        self.btn_R = self.new_button_escribir("R")
     174        self.fila_2.append(self.btn_R)
     175
     176        self.btn_T = self.new_button_escribir("T")
     177        self.fila_2.append(self.btn_T)
     178
     179        self.btn_Y = self.new_button_escribir("Y")
     180        self.fila_2.append(self.btn_Y)
     181
     182        self.btn_U = self.new_button_escribir("U")     
     183        self.fila_2.append(self.btn_U)
     184
     185        self.btn_I = self.new_button_escribir("I")
     186        self.fila_2.append(self.btn_I)
     187
     188        self.btn_O = self.new_button_escribir("O")
     189        self.fila_2.append(self.btn_O)
     190
     191        self.btn_P = self.new_button_escribir("P")
     192        self.fila_2.append(self.btn_P)
     193
     194        self.btn_asterisco = self.new_button_escribir("*")
     195        self.fila_2.append(self.btn_asterisco)
     196
     197        self.btn_cierra_llave = self.new_button_escribir("]")
     198
     199        self.btn_A = self.new_button_escribir("A")
     200        self.fila_3.append(self.btn_A)
     201
     202        self.btn_S = self.new_button_escribir("S")
     203        self.fila_3.append(self.btn_S)
     204
     205        self.btn_D = self.new_button_escribir("D")
     206        self.fila_3.append(self.btn_D)
     207
     208        self.btn_F = self.new_button_escribir("F")
     209        self.fila_3.append(self.btn_F)
     210
     211        self.btn_G = self.new_button_escribir("G")
     212        self.fila_3.append(self.btn_G)
     213
     214        self.btn_H = self.new_button_escribir("H")
     215        self.fila_3.append(self.btn_H)
     216
     217        self.btn_J = self.new_button_escribir("J")
     218        self.fila_3.append(self.btn_J)
     219
     220        self.btn_K = self.new_button_escribir("K")
     221        self.fila_3.append(self.btn_K)
     222
     223        self.btn_L = self.new_button_escribir("L")
     224        self.fila_3.append(self.btn_L)
     225
     226        self.btn_enie = self.new_button_escribir("Ñ")
     227        self.fila_3.append(self.btn_enie)
     228
     229        self.btn_mas = self.new_button_escribir("+")
     230        self.fila_3.append(self.btn_mas)
     231
     232        self.fila_3.append(self.btn_cierra_llave)
     233
     234        self.btn_abre_llave = self.new_button_escribir("[")
     235        self.fila_2.append(self.btn_abre_llave)
     236
     237        self.btn_Z = self.new_button_escribir("Z")
     238        self.fila_4.append(self.btn_Z)
     239
     240        self.btn_X = self.new_button_escribir("X")
     241        self.fila_4.append(self.btn_X)
     242
     243        self.btn_C = self.new_button_escribir("C")
     244        self.fila_4.append(self.btn_C)
     245
     246        self.btn_V = self.new_button_escribir("V")
     247        self.fila_4.append(self.btn_V)
     248
     249        self.btn_B = self.new_button_escribir("B")
     250        self.fila_4.append(self.btn_B)
     251
     252        self.btn_N = self.new_button_escribir("N")
     253        self.fila_4.append(self.btn_N)
     254
     255        self.btn_M = self.new_button_escribir("M")
     256        self.fila_4.append(self.btn_M)
     257
     258        self.btn_coma = self.new_button_escribir(",")
     259        self.fila_4.append(self.btn_coma)
     260
     261        self.btn_punto = self.new_button_escribir(".")
     262        self.fila_4.append(self.btn_punto)
     263
     264        self.btn_guion = self.new_button_escribir("-")
     265        self.fila_4.append(self.btn_guion)
     266
     267        self.btn_A_tilde = self.new_button_escribir("Á")
     268        self.fila_5.append(self.btn_A_tilde)
     269
     270        self.btn_E_tilde = self.new_button_escribir("É")
     271        self.fila_5.append(self.btn_E_tilde)
     272
     273        self.btn_I_tilde = self.new_button_escribir("Í")
     274        self.fila_5.append(self.btn_I_tilde)
     275
     276        self.btn_O_tilde = self.new_button_escribir("Ó")
     277        self.fila_5.append(self.btn_O_tilde)
     278
     279        self.btn_U_tilde = self.new_button_escribir("Ú")
     280        self.fila_5.append(self.btn_U_tilde)
     281
     282        self.btn_U_puntos = self.new_button_escribir("Ü")
     283        self.fila_5.append(self.btn_U_puntos)
     284
     285        self.btn_pite = self.new_button_escribir("|")
     286        self.fila_5.append(self.btn_pite)
     287
     288        self.btn_arroba = self.new_button_escribir("@")
     289        self.fila_5.append(self.btn_arroba)
     290
     291        self.btn_menor = self.new_button_escribir("<")
     292        self.fila_5.append(self.btn_menor)
     293
     294        self.chk_activarBarrido_botones = gtk.CheckButton("BOTONES")
     295        self.chk_activarBarrido_botones.connect("toggled", self.set_botonesXbarridoXfila)
     296
     297        self.cbo_time_btn = self.combo_tiempos_botones()
     298
     299        #dibujo tabla
     300        table = gtk.Table(7, 15, False)
     301
     302        table.set_row_spacing(0, 15)
     303        table.set_row_spacing(3, 15)
     304        table.set_col_spacing(12, 15)   
     305        table.set_row_spacing(4, 10)
     306
     307        table.attach(self.btn_do, 0, 1, 0, 1)
     308        table.attach(self.btn_1, 1, 2, 0, 1)
     309        table.attach(self.btn_2, 2, 3, 0, 1)
     310        table.attach(self.btn_3, 3, 4, 0, 1)
     311        table.attach(self.btn_4, 4, 5, 0, 1)
     312        table.attach(self.btn_5, 5, 6, 0, 1)
     313        table.attach(self.btn_6, 6, 7, 0, 1)
     314        table.attach(self.btn_7, 7, 8, 0, 1)
     315        table.attach(self.btn_8, 8, 9, 0, 1)
     316        table.attach(self.btn_9, 9, 10, 0, 1)
     317        table.attach(self.btn_0, 10, 11, 0, 1)
     318        table.attach(self.btn_finPreg, 11 ,12, 0, 1)
     319        table.attach(self.btn_inicioPreg, 12, 13, 0, 1)
     320        table.attach(self.btn_TAB, 0, 1, 1, 2)
     321        table.attach(self.btn_Q, 1, 2, 1, 2)
     322        table.attach(self.btn_W, 2, 3, 1, 2)
     323        table.attach(self.btn_E, 3, 4, 1, 2)
     324        table.attach(self.btn_R, 4, 5, 1, 2)
     325        table.attach(self.btn_T, 5, 6, 1, 2)
     326        table.attach(self.btn_Y, 6, 7, 1, 2)
     327        table.attach(self.btn_U, 7, 8, 1, 2)
     328        table.attach(self.btn_I, 8, 9, 1, 2)
     329        table.attach(self.btn_O, 9, 10, 1, 2)
     330        table.attach(self.btn_P, 10, 11, 1, 2)
     331        table.attach(self.btn_asterisco, 11, 12, 1, 2)
     332        table.attach(self.btn_abre_llave, 12, 13, 1, 2)
     333        table.attach(self.btn_A, 1, 2, 2, 3)
     334        table.attach(self.btn_S, 2, 3, 2, 3)
     335        table.attach(self.btn_D, 3, 4, 2, 3)
     336        table.attach(self.btn_F, 4, 5, 2, 3)
     337        table.attach(self.btn_G, 5, 6, 2, 3)
     338        table.attach(self.btn_H, 6, 7, 2, 3)
     339        table.attach(self.btn_J, 7, 8, 2, 3)
     340        table.attach(self.btn_K, 8, 9, 2, 3)
     341        table.attach(self.btn_L, 9, 10, 2, 3)
     342        table.attach(self.btn_enie, 10, 11, 2, 3)
     343        table.attach(self.btn_mas, 11, 12, 2, 3)
     344        table.attach(self.btn_cierra_llave, 12, 13, 2, 3)
     345        table.attach(self.btn_Z, 1, 2, 3, 4)
     346        table.attach(self.btn_X, 2, 3, 3, 4)
     347        table.attach(self.btn_C, 3, 4, 3, 4)
     348        table.attach(self.btn_V, 4, 5, 3, 4)
     349        table.attach(self.btn_B, 5, 6, 3, 4)
     350        table.attach(self.btn_N, 6, 7, 3, 4)
     351        table.attach(self.btn_M, 7, 8, 3, 4)
     352        table.attach(self.btn_coma, 8, 9, 3, 4)
     353        table.attach(self.btn_punto, 9, 10, 3, 4)
     354        table.attach(self.btn_guion, 10, 11, 3, 4)
     355
     356        table.attach(self.btn_BACK_SPACE, 13, 15, 0, 1)
     357        table.attach(self.btn_ENTER, 13, 15, 1, 2)
     358        table.attach(self.btn_CAPS_LOCK, 13, 15, 2, 3)
     359        table.attach(self.cbo_time_btn, 13, 14, 4, 5)
     360        table.attach(self.chk_activarBarrido_botones, 13, 14, 3, 4)
     361        table.attach(self.btn_SPACE, 1, 13, 5, 6)
     362
     363        table.attach(self.btn_A_tilde, 1, 2, 4, 5)
     364        table.attach(self.btn_E_tilde, 2, 3, 4, 5)
     365        table.attach(self.btn_I_tilde, 3, 4, 4, 5)
     366        table.attach(self.btn_O_tilde, 4, 5, 4, 5)
     367        table.attach(self.btn_U_tilde, 5, 6, 4, 5)
     368        table.attach(self.btn_U_puntos, 8, 9, 4, 5)
     369        table.attach(self.btn_pite, 9, 10, 4, 5)
     370        table.attach(self.btn_arroba, 10, 11, 4, 5)
     371        table.attach(self.btn_menor, 11, 12, 4, 5)
     372
     373        child.pack_end(table, True, True, 0)     
     374
     375        return child
     376
     377####################################################################################
     378       
     379    def escribir(self, widget, *arg):
     380        hbox = widget.get_children()[0]
     381        label = hbox.get_children()[0]
     382        txt = label.get_text()
     383
     384        self._mTeclado.escribir_txt(txt)
     385
     386    def espacio(self, *arg):
     387        self._mTeclado.escribir_txt(" ")
     388
     389    def tab(self, *arg):
     390        self._mTeclado.escribir_txt("\t")
     391
     392    def enter(self, *arg):
     393        self._mTeclado.escribir_txt("\n")
     394
     395    def borrar(self, *arg):
     396        self._mTeclado.escribir_txt("\r")
     397
     398    def new_button_escribir(self, plabel):
     399        btn = Boton(plabel)
     400        btn.connect("pressed", self.escribir, plabel)
     401        btn.connect("activate", self.escribir, plabel)
     402        return btn
     403
     404
     405    def new_button_enter(self):
     406        btn = Boton("ENTER")
     407        btn.connect("pressed", self.enter)
     408        btn.connect("activate", self.enter)
     409        return btn
     410
     411    def new_button_espacio(self):
     412        btn = Boton("ESPACIO")
     413        btn.connect("pressed", self.espacio)
     414        btn.connect("activate", self.espacio)
     415        return btn
     416
     417    def new_button_borrar(self):
     418        btn = Boton("BORRAR")
     419        btn.connect("pressed", self.borrar)
     420        btn.connect("activate", self.borrar)
     421        return btn
     422
     423    def new_button_tab(self):
     424        btn = Boton("TAB")
     425        btn.connect("pressed", self.tab)
     426        btn.connect("activate", self.tab)
     427        return btn
     428
     429    def new_button_mayuscula(self):
     430        btn = Boton("MINÚSCULAS")
     431        btn.connect("pressed", self.set_mayuscula)
     432        btn.connect("activate", self.set_mayuscula)
     433        return btn
     434
     435    def set_mayuscula(self, *arg):
     436        if (self.MAYUSCULA):
     437                self.btn_do.set_text("ª")
     438                self.btn_1.set_text("!")
     439                self.btn_2.set_text("\"")
     440                self.btn_3.set_text("#")
     441                self.btn_4.set_text("$")
     442                self.btn_5.set_text("%")
     443                self.btn_6.set_text("&")
     444                self.btn_7.set_text("/")
     445                self.btn_8.set_text("(")
     446                self.btn_9.set_text(")")
     447                self.btn_0.set_text("=")
     448                self.btn_finPreg.set_text("?")
     449                self.btn_inicioPreg.set_text("¿")
     450                self.btn_Q.set_text("q")
     451                self.btn_W.set_text("w")
     452                self.btn_E.set_text("e")
     453                self.btn_R.set_text("r")
     454                self.btn_T.set_text("t")
     455                self.btn_Y.set_text("y")
     456                self.btn_U.set_text("u")
     457                self.btn_I.set_text("i")
     458                self.btn_O.set_text("o")
     459                self.btn_P.set_text("p")
     460                self.btn_A.set_text("a")
     461                self.btn_S.set_text("s")
     462                self.btn_D.set_text("d")
     463                self.btn_F.set_text("f")
     464                self.btn_G.set_text("g")
     465                self.btn_H.set_text("h")
     466                self.btn_J.set_text("j")
     467                self.btn_K.set_text("k")
     468                self.btn_L.set_text("l")
     469                self.btn_enie.set_text("ñ")
     470                self.btn_menor.set_text(">")
     471                self.btn_Z.set_text("z")
     472                self.btn_X.set_text("x")
     473                self.btn_C.set_text("c")
     474                self.btn_V.set_text("v")
     475                self.btn_B.set_text("b")
     476                self.btn_N.set_text("n")
     477                self.btn_M.set_text("m")
     478                self.btn_coma.set_text(";")
     479                self.btn_punto.set_text(":")
     480                self.btn_guion.set_text("_")
     481                self.btn_A_tilde.set_text("á")
     482                self.btn_E_tilde.set_text("é")
     483                self.btn_I_tilde.set_text("í")
     484                self.btn_O_tilde.set_text("ó")
     485                self.btn_U_tilde.set_text("ú")
     486                self.btn_U_puntos.set_text("ÃŒ")
     487                self.btn_abre_llave.set_text("{")
     488                self.btn_cierra_llave.set_text("}")
     489
     490                self.MAYUSCULA = False
     491                self.btn_CAPS_LOCK.set_text("MAYÚSCULAS")
     492        else:
     493                self.btn_do.set_text("º")
     494                self.btn_1.set_text("1")
     495                self.btn_2.set_text("2")
     496                self.btn_3.set_text("3")
     497                self.btn_4.set_text("4")
     498                self.btn_5.set_text("5")
     499                self.btn_6.set_text("6")
     500                self.btn_7.set_text("7")
     501                self.btn_8.set_text("8")
     502                self.btn_9.set_text("9")
     503                self.btn_0.set_text("0")
     504                self.btn_finPreg.set_text("'")
     505                self.btn_inicioPreg.set_text("¡")
     506                self.btn_Q.set_text("Q")
     507                self.btn_W.set_text("W")
     508                self.btn_E.set_text("E")
     509                self.btn_R.set_text("R")
     510                self.btn_T.set_text("T")
     511                self.btn_Y.set_text("Y")
     512                self.btn_U.set_text("U")
     513                self.btn_I.set_text("I")
     514                self.btn_O.set_text("O")
     515                self.btn_P.set_text("P")
     516                self.btn_A.set_text("A")
     517                self.btn_S.set_text("S")
     518                self.btn_D.set_text("D")
     519                self.btn_F.set_text("F")
     520                self.btn_G.set_text("G")
     521                self.btn_H.set_text("H")
     522                self.btn_J.set_text("J")
     523                self.btn_K.set_text("K")
     524                self.btn_L.set_text("L")
     525                self.btn_enie.set_text("Ñ")
     526                self.btn_menor.set_text("<")
     527                self.btn_Z.set_text("Z")
     528                self.btn_X.set_text("X")
     529                self.btn_C.set_text("C")
     530                self.btn_V.set_text("V")
     531                self.btn_B.set_text("B")
     532                self.btn_N.set_text("N")
     533                self.btn_M.set_text("M")
     534                self.btn_coma.set_text(",")
     535                self.btn_punto.set_text(".")
     536                self.btn_guion.set_text("-")
     537                self.btn_A_tilde.set_text("Á")
     538                self.btn_E_tilde.set_text("É")
     539                self.btn_I_tilde.set_text("Í")
     540                self.btn_O_tilde.set_text("Ó")
     541                self.btn_U_tilde.set_text("Ú")
     542                self.btn_U_puntos.set_text("Ü")
     543                self.btn_abre_llave.set_text("[")
     544                self.btn_cierra_llave.set_text("]")
     545
     546                self.MAYUSCULA = True
     547                self.btn_CAPS_LOCK.set_text("MINÚSCULAS")
     548
     549
     550########################################################################
     551
     552    def set_botonesXbarridoXfila(self, widget):
     553        state = widget.get_active()
     554        if state:       
     555                self.BOTONESxBARRIDOxFILA = True
     556                self.botonesXbarridoXfila()
     557        else:
     558                if (self.BOTONESxBARRIDOxFILA):
     559                        self.iluminarFila(self.fila_actual_nro, "white")
     560                self.BOTONESxBARRIDOxFILA = False
     561                self.iluminarBoton(self.btn_actual, "white")
     562                self.BOTONESxBARRIDO = False
     563
     564    def botonesXbarridoXfila(self):
     565        gobject.timeout_add(self.seg*1000, self.barrerFocusXfila1)
     566
     567    def barrerFocusXfila1(self, *arg):
     568        if not self.BOTONESxBARRIDOxFILA:
     569                return False
     570        self.fila_actual_nro = 1
     571        self.fila_actual = self.fila_1
     572        self.iluminarBoton(self.btn_actual, "white")
     573        if not self.BOTONESxBARRIDOxFILA:
     574                return False
     575        self.iluminarFila(1, "Yellow")
     576        if not self.BOTONESxBARRIDOxFILA:
     577                return False
     578        if self.BOTONESxBARRIDOxFILA:
     579                gobject.timeout_add(self.seg*1000, self.barrer_el_boton, self.btn_BACK_SPACE,1, 2)
     580
     581    def barrer_el_boton(self, btn , fila_anterior, fila_a_seguir):
     582        if not self.BOTONESxBARRIDOxFILA:
     583                return False
     584        self.fila_actual_nro = -1
     585        self.fila_actual = None
     586        self.btn_actual = btn
     587        self.iluminarFila(fila_anterior, "white")
     588        if not self.BOTONESxBARRIDOxFILA:
     589                return False
     590        self.iluminarBoton(self.btn_actual, "Yellow")
     591        if not self.BOTONESxBARRIDOxFILA:
     592                return False
     593        if self.BOTONESxBARRIDOxFILA:
     594                if fila_a_seguir==1:
     595                        gobject.timeout_add(self.seg*1000, self.barrerFocusXfila1)
     596                if fila_a_seguir==2:
     597                        gobject.timeout_add(self.seg*1000, self.barrerFocusXfila2)
     598                if fila_a_seguir==3:
     599                        gobject.timeout_add(self.seg*1000, self.barrerFocusXfila3)
     600                if fila_a_seguir==4:
     601                        gobject.timeout_add(self.seg*1000, self.barrerFocusXfila4)
     602                if fila_a_seguir==5:
     603                        gobject.timeout_add(self.seg*1000, self.barrerFocusXfila5)             
     604
     605
     606    def barrerFocusXfila2(self, *arg):
     607        if not self.BOTONESxBARRIDOxFILA:
     608                return False
     609
     610        self.fila_actual_nro = 2
     611        self.fila_actual = self.fila_2
     612        self.iluminarBoton(self.btn_actual, "white")
     613        if not self.BOTONESxBARRIDOxFILA:
     614                return False
     615        self.iluminarFila(2, "Yellow")
     616        if not self.BOTONESxBARRIDOxFILA:
     617                return False
     618
     619        if self.BOTONESxBARRIDOxFILA:
     620                gobject.timeout_add(self.seg*1000, self.barrer_el_boton, self.btn_BACK_SPACE, 2, 3)
     621
     622    def barrerFocusXfila3(self, *arg):
     623        if not self.BOTONESxBARRIDOxFILA:
     624                return False
     625        self.fila_actual_nro = 3
     626        self.fila_actual = self.fila_3
     627        self.iluminarBoton(self.btn_actual, "white")
     628        if not self.BOTONESxBARRIDOxFILA:
     629                return False
     630        self.iluminarFila(3, "Yellow")
     631        if not self.BOTONESxBARRIDOxFILA:
     632                return False
     633
     634        if self.BOTONESxBARRIDOxFILA:
     635                gobject.timeout_add(self.seg*1000, self.barrer_el_boton, self.btn_BACK_SPACE, 3, 4)
     636
     637    def barrerFocusXfila4(self, *arg):
     638        if not self.BOTONESxBARRIDOxFILA:
     639                return False
     640        self.fila_actual_nro = 4
     641        self.fila_actual = self.fila_4
     642        self.iluminarBoton(self.btn_actual, "white")
     643        if not self.BOTONESxBARRIDOxFILA:
     644                return False
     645        self.iluminarFila(4, "Yellow")
     646        if not self.BOTONESxBARRIDOxFILA:
     647                return False
     648        if self.BOTONESxBARRIDOxFILA:
     649                gobject.timeout_add(self.seg*1000, self.barrer_el_boton, self.btn_BACK_SPACE, 4, 5)
     650
     651    def barrerFocusXfila5(self, *arg):
     652        if not self.BOTONESxBARRIDOxFILA:
     653                return False
     654        self.fila_actual_nro = 5
     655        self.fila_actual = self.fila_5
     656        self.iluminarBoton(self.btn_actual, "white")
     657        if not self.BOTONESxBARRIDOxFILA:
     658                return False
     659        self.iluminarFila(5, "Yellow")
     660        if not self.BOTONESxBARRIDOxFILA:
     661                return False
     662        if self.BOTONESxBARRIDOxFILA:
     663                gobject.timeout_add(self.seg*1000, self.barrer_el_boton, self.btn_SPACE, 5, 1)
     664
     665
     666########################################################################
     667
     668    def iluminarFila(self, fila, color):
     669        if fila == 1:
     670                for f in range(0,len(self.fila_1)):
     671                        gobject.idle_add(self.pintarControl,self.fila_1[f], color)
     672        if fila == 2:
     673                for f in range(0,len(self.fila_2)):
     674                        gobject.idle_add(self.pintarControl,self.fila_2[f], color)
     675        if fila == 3:
     676                for f in range(0,len(self.fila_3)):
     677                        gobject.idle_add(self.pintarControl,self.fila_3[f], color)
     678        if fila == 4:
     679                for f in range(0,len(self.fila_4)):
     680                        gobject.idle_add(self.pintarControl,self.fila_4[f], color)
     681        if fila == 5:
     682                for f in range(0,len(self.fila_5)):
     683                        gobject.idle_add(self.pintarControl,self.fila_5[f], color)
     684        if fila == 6:
     685                for f in range(0,len(self.fila_6)):
     686                        gobject.idle_add(self.pintarControl,self.fila_6[f], color)
     687
     688    def pintarControl(self, w, color):
     689        if not w == None:
     690                w.modify_bg( gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
     691
     692    def mouse_boton(self, widget, event):
     693        #evita repeticion
     694        self.bloquearHandler()
     695
     696        if self.BOTONESxBARRIDO:
     697                self.BOTONESxBARRIDO=False
     698                self.btn_actual.emit("pressed")
     699                #voler a empezar...
     700                self.iluminarBoton(self.btn_actual, "white")
     701                self.BOTONESxBARRIDOxFILA = True
     702                self.botonesXbarridoXfila()
     703                return
     704        if self.BOTONESxBARRIDOxFILA:
     705                if self.fila_actual_nro==-1: #es un boton                       
     706                        self.btn_actual.emit("pressed")
     707                else:
     708                        self.BOTONESxBARRIDOxFILA = False;
     709                        self.iluminarFila(self.fila_actual_nro, "white")
     710                        self.BOTONESxBARRIDO = True;
     711                        self.botonesXbarridoEnFila()
     712
     713    def iluminarBoton(self, btn, color):
     714        gobject.idle_add(self.pintarControl,btn, color)
     715
     716    def bloquearHandler(self):
     717        HILO_A = threading.Thread(target = self.bloquearHandler_aux_obj)
     718        HILO_A.start()
     719        HILO_A.quit = True
     720
     721    def bloquearHandler_aux_obj(self):
     722        self.event_box.handler_block(self.ebc)
     723        try:
     724                seg=self.get_time_barrido_botones()
     725        except:
     726                seg = velocidades['media']     
     727        if seg == velocidades['rapida']:
     728                time.sleep(seg-0.15)
     729        if seg == velocidades['media']:
     730                time.sleep(seg-0.30)
     731        if seg == velocidades['lenta']:
     732                time.sleep(seg-0.75)
     733        self.event_box.handler_unblock(self.ebc)
     734
     735
     736    def botonesXbarridoEnFila(self):   
     737        gobject.idle_add(self.barrerEnFila)
     738
     739    def barrerEnFila(self):
     740        if self.BOTONESxBARRIDO:       
     741                i=0
     742                gobject.timeout_add(self.seg*1000, self.barrerEnFila_aux, i)
     743
     744
     745    def barrerEnFila_aux(self, i):
     746        if not self.BOTONESxBARRIDO:
     747                return False
     748        try:
     749                self.btn_ant = self.fila_actual[i-1]
     750        except:
     751                return False
     752        try:
     753                self.btn_actual = self.fila_actual[i]
     754        except:
     755                self.BOTONESxBARRIDO = False
     756                self.BOTONESxBARRIDOxFILA = True
     757                self.botonesXbarridoXfila()
     758                return False
     759        if not self.BOTONESxBARRIDO:
     760                return False
     761        self.iluminarBoton(self.btn_ant, "white")
     762        if not self.BOTONESxBARRIDO:
     763                return False
     764        self.iluminarBoton(self.btn_actual, "Yellow")
     765        if not self.BOTONESxBARRIDO:
     766                return False
     767        else:
     768                gobject.timeout_add(self.seg*1000, self.barrerEnFila_aux, i+1)
     769
     770    def combo_tiempos_botones(self):
     771        cb = gtk.combo_box_new_text()
     772        cb.connect("changed", self.on_changed_cbo_time_btn)
     773        cb.append_text("RÁPIDO")
     774        cb.append_text("MEDIO")
     775        cb.append_text("LENTO")
     776        seg = velocidades['media']
     777        try:
     778                seg = self.get_time_barrido_botones()                                                                   
     779        except:
     780                seg=velocidades['media']
     781
     782        if seg==velocidades['rapida']:
     783                cb.set_active(0)
     784        if seg==velocidades['media']:
     785                cb.set_active(1)               
     786        if seg==velocidades['lenta']:
     787                cb.set_active(2)
     788                       
     789        return cb
     790
     791
     792    def on_changed_cbo_time_btn(self, widget):
     793        s = widget.get_active()
     794
     795        if s==0:
     796                seg = velocidades['rapida']
     797        if s==1:
     798                seg = velocidades['media']
     799        if s==2:
     800                seg = velocidades['lenta']
     801       
     802        self.set_time_barrido_botones(seg)
     803        self.seg=seg
     804
     805
     806    def get_time_barrido_botones(self):
     807            client = gconf.client_get_default()
     808            return client.get_int("/desktop/sugar/virtualkeyboard/time")
     809
     810    def set_time_barrido_botones(self, seg):
     811            client = gconf.client_get_default()
     812            client.set_int("/desktop/sugar/virtualkeyboard/time", seg)
     813
     814class Boton(gtk.Button):
     815        font_desc = ''
     816        font_color = ''
     817        fondo_color = ''
     818        text = ''
     819
     820        def __init__(self, nom=None):
     821                gtk.Button.__init__(self)
     822
     823                self.hbox = gtk.HBox(False, 0)
     824                self.add(self.hbox)
     825                self.label = gtk.Label(nom)
     826
     827                self.set_text(nom)
     828                self.set_font_desc('sans bold 13')
     829                self.set_font_color('black')
     830                self.set_fondo_color('white')
     831
     832                self.label.set_use_underline(True)
     833                self.hbox.add(self.label)
     834
     835        def set_font_desc(self, pfont_desc):
     836                self.font_desc = pfont_desc
     837                self.label.modify_font(pango.FontDescription(pfont_desc))
     838
     839        def set_font_color(self, pfont_color):
     840                self.font_color = pfont_color
     841                self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(pfont_color))
     842
     843        def set_fondo_color(self, pfondo_color):
     844                self.fondo_color = pfondo_color
     845                self.modify_bg( gtk.STATE_NORMAL, gtk.gdk.color_parse(pfondo_color))
     846
     847        def set_text(self, ptext):
     848                if not ptext == None:
     849                        self.text = ptext
     850                self.label.set_text(self.text)
     851
     852        def get_font_desc(self):
     853                return self.font_desc
     854
     855        def get_font_color(self):
     856                return self.font_color
     857
     858        def get_fondo_color(self):
     859                return self.fondo_color
     860
     861        def get_text(self):
     862                return self.text
     863
     864        def is_visible(self):
     865                self.get_property('visible')